Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
17 changes: 13 additions & 4 deletions resources/js/components/ui/Button/Button.vue
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { Link } from '@inertiajs/vue3';
const props = defineProps({
/** The element or component this component should render as */
as: { type: String, default: null },
disabled: { type: Boolean, default: false },
/** The URL to link to */
href: { type: String, default: null },
/** When `href` is provided, this prop controls the link's `target` attribute */
Expand Down Expand Up @@ -43,21 +44,23 @@ const tag = computed(() => {
}
return 'button';
});

const isDisabled = computed(() => props.disabled || props.loading);
const iconOnly = computed(() => (props.icon && !hasDefaultSlot && !props.text) || props.iconOnly);

const buttonClasses = computed(() => {
const classes = cva({
base: 'relative inline-flex items-center justify-center whitespace-nowrap shrink-0 font-medium antialiased cursor-pointer no-underline disabled:text-gray-400 dark:disabled:text-gray-600 disabled:[&_svg]:opacity-30 disabled:cursor-not-allowed [&_svg]:shrink-0 [&_svg]:text-gray-925 [&_svg]:opacity-60 dark:[&_svg]:text-white',
base: 'relative inline-flex items-center justify-center whitespace-nowrap shrink-0 font-medium antialiased cursor-pointer no-underline aria-disabled:text-gray-400 dark:aria-disabled:text-gray-600 aria-disabled:[&_svg]:opacity-30 aria-disabled:pointer-events-none [&_svg]:shrink-0 [&_svg]:text-gray-925 [&_svg]:opacity-60 dark:[&_svg]:text-white',
variants: {
variant: {
default: [
'bg-linear-to-b from-white to-gray-50 hover:to-gray-100 hover:bg-gray-50 text-gray-900 border border-gray-300 with-contrast:border-gray-500 shadow-ui-sm',
'dark:from-gray-850 dark:to-gray-900 dark:hover:to-gray-850 dark:hover:bg-gray-900 dark:border-gray-700/80 dark:text-gray-300 dark:shadow-ui-md',
],
primary: [
'bg-linear-to-b from-primary/90 to-primary hover:bg-primary-hover text-white disabled:opacity-60 disabled:text-white dark:disabled:text-white border border-primary-border shadow-ui-md inset-shadow-2xs inset-shadow-white/25 disabled:inset-shadow-none dark:disabled:inset-shadow-none [&_svg]:text-white [&_svg]:opacity-60',
'bg-linear-to-b from-primary/90 to-primary hover:bg-primary-hover text-white aria-disabled:opacity-60 aria-disabled:text-white dark:aria-disabled:text-white border border-primary-border shadow-ui-md inset-shadow-2xs inset-shadow-white/25 aria-disabled:inset-shadow-none dark:aria-disabled:inset-shadow-none [&_svg]:text-white [&_svg]:opacity-60',
],
danger: 'bg-linear-to-b from-red-600/90 to-red-600 hover:bg-red-600/90 text-white border border-red-600 inset-shadow-xs inset-shadow-red-300 [&_svg]:text-red-200 disabled:text-white! disabled:opacity-60 disabled:inset-shadow-none',
danger: 'bg-linear-to-b from-red-600/90 to-red-600 hover:bg-red-600/90 text-white border border-red-600 inset-shadow-xs inset-shadow-red-300 [&_svg]:text-red-200 aria-disabled:text-white! aria-disabled:opacity-60 aria-disabled:inset-shadow-none',
filled: 'bg-gray-950/5 hover:bg-gray-950/10 hover:text-gray-900 dark:hover:text-white dark:bg-white/15 dark:hover:bg-white/20 [&_svg]:opacity-70',
ghost: 'bg-transparent hover:bg-gray-400/10 text-gray-900 dark:text-gray-300 dark:hover:bg-white/7 dark:hover:text-gray-200',
'ghost-pressed': 'bg-transparent hover:bg-gray-400/10 text-gray-925 dark:text-white dark:hover:bg-white/7 dark:hover:text-white [&_svg]:opacity-100',
Expand Down Expand Up @@ -110,17 +113,23 @@ const buttonClasses = computed(() => {

return twMerge(classes);
});

const preventWhenDisabled = (event) => {
if (isDisabled.value) event.preventDefault();
};
</script>

<template>
<component
:is="tag"
:class="buttonClasses"
:disabled="loading"
:aria-disabled="isDisabled || undefined"
:data-ui-group-target="['subtle', 'ghost'].includes(props.variant) ? null : true"
:href
:target
:type="props.href ? null : type"
@click="preventWhenDisabled"
@keydown.enter="preventWhenDisabled"
>
<Icon v-if="icon" :name="icon" />
<Icon v-if="loading" name="loading" :size />
Expand Down