From 1ccd14ee0e4ad6abd4c2103647f7023c4e50e7e2 Mon Sep 17 00:00:00 2001 From: Benjamin Canac Date: Sat, 9 Mar 2024 19:58:44 +0100 Subject: [PATCH] chore(Button): update --- src/runtime/components/Button.vue | 29 ++++++++------- src/theme/button.ts | 62 ++++++++++++++++++------------- 2 files changed, 51 insertions(+), 40 deletions(-) diff --git a/src/runtime/components/Button.vue b/src/runtime/components/Button.vue index 4befbbd7..c4e2e273 100644 --- a/src/runtime/components/Button.vue +++ b/src/runtime/components/Button.vue @@ -30,9 +30,9 @@ export interface ButtonProps extends LinkProps { } export interface ButtonSlots { - leading(props?: { disabled?: boolean; loading?: boolean, ui?: string }): any + leading(props: { disabled?: boolean; loading?: boolean, icon?: string, class: string }): any default(): any - trailing(props?: { disabled?: boolean; loading?: boolean, ui?: string }): any + trailing(props: { disabled?: boolean; loading?: boolean, icon?: string, class: string }): any } @@ -43,8 +43,6 @@ import { reactiveOmit } from '@vueuse/core' import { useAppConfig } from '#app' import UIcon from './Icon.vue' -defineOptions({ inheritAttrs: false }) - const props = defineProps() const slots = defineSlots() @@ -53,6 +51,9 @@ const forward = useForwardProps(reactiveOmit(props, 'type', 'label', 'color', 'v // Computed +const isLeading = computed(() => (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing) || !!props.leadingIcon) +const isTrailing = computed(() => (props.icon && props.trailing) || (props.loading && props.trailing) || !!props.trailingIcon) + // FIXME: Cannot extend multiple times // const ui = computed(() => tv({ extend: button, slots: props.ui })({ const ui = computed(() => button({ @@ -62,13 +63,11 @@ const ui = computed(() => button({ loading: props.loading, truncate: props.truncate, block: props.block, - square: props.square || (!slots.default && !props.label) + square: props.square || (!slots.default && !props.label), + leading: isLeading.value, + trailing: isTrailing.value })) -const isLeading = computed(() => (props.icon && props.leading) || (props.icon && !props.trailing) || (props.loading && !props.trailing) || props.leadingIcon) - -const isTrailing = computed(() => (props.icon && props.trailing) || (props.loading && props.trailing) || props.trailingIcon) - const leadingIconName = computed(() => { if (props.loading) { return props.loadingIcon || appConfig.ui.icons.loading @@ -76,6 +75,7 @@ const leadingIconName = computed(() => { return props.leadingIcon || props.icon }) +const leadingIconClass = computed(() => ui.value.leadingIcon()) const trailingIconName = computed(() => { if (props.loading && !isLeading.value) { @@ -84,6 +84,7 @@ const trailingIconName = computed(() => { return props.trailingIcon || props.icon }) +const trailingIconClass = computed(() => ui.value.trailingIcon()) \ No newline at end of file diff --git a/src/theme/button.ts b/src/theme/button.ts index 56013bf7..7ef13f00 100644 --- a/src/theme/button.ts +++ b/src/theme/button.ts @@ -1,8 +1,9 @@ export default (config: { colors: string[] }) => ({ slots: { - base: 'rounded-md font-medium inline-flex items-center focus:outline-none focus-visible:outline-0 disabled:cursor-not-allowed disabled:opacity-75 shrink-0', + base: 'rounded-md font-medium inline-flex items-center focus:outline-none focus-visible:outline-0 disabled:cursor-not-allowed disabled:opacity-75', label: '', - icon: 'shrink-0' + leadingIcon: 'shrink-0', + trailingIcon: 'shrink-0' }, variants: { color: { @@ -21,27 +22,33 @@ export default (config: { colors: string[] }) => ({ size: { '2xs': { base: 'px-2 py-1 text-xs gap-x-1', - icon: 'h-4 w-4' + leadingIcon: 'h-4 w-4', + trailingIcon: 'h-4 w-4' }, xs: { base: 'px-2.5 py-1.5 text-xs gap-x-1.5', - icon: 'h-4 w-4' + leadingIcon: 'h-4 w-4', + trailingIcon: 'h-4 w-4' }, sm: { base: 'px-2.5 py-1.5 text-sm gap-x-1.5', - icon: 'h-5 w-5' + leadingIcon: 'h-5 w-5', + trailingIcon: 'h-5 w-5' }, md: { base: 'px-3 py-2 text-sm gap-x-2', - icon: 'h-5 w-5' + leadingIcon: 'h-5 w-5', + trailingIcon: 'h-5 w-5' }, lg: { base: 'px-3.5 py-2.5 text-sm gap-x-2.5', - icon: 'h-6 w-6' + leadingIcon: 'h-6 w-6', + trailingIcon: 'h-6 w-6' }, xl: { base: 'px-3.5 py-2.5 text-base gap-x-2.5', - icon: 'h-6 w-6' + leadingIcon: 'h-6 w-6', + trailingIcon: 'h-6 w-6' } }, truncate: { @@ -51,14 +58,23 @@ export default (config: { colors: string[] }) => ({ }, loading: { true: { - icon: 'animate-spin' + leadingIcon: 'animate-spin' } }, block: { - true: 'w-full justify-center' + true: { + base: 'w-full', + trailingIcon: 'ms-auto' + } }, square: { true: '' + }, + leading: { + true: '' + }, + trailing: { + true: '' } }, compoundVariants: [...config.colors.map((color: string) => ({ @@ -112,38 +128,32 @@ export default (config: { colors: string[] }) => ({ }, { size: '2xs', square: true, - class: { - base: 'p-1' - } + class: 'p-1' }, { size: 'xs', square: true, - class: { - base: 'p-1' - } + class: 'p-1.5' }, { size: 'sm', square: true, - class: { - base: 'p-1' - } + class: 'p-1.5' }, { size: 'md', square: true, - class: { - base: 'p-2' - } + class: 'p-2' }, { size: 'lg', square: true, - class: { - base: 'p-2' - } + class: 'p-2.5' }, { size: 'xl', square: true, + class: 'p-2.5' + }, { + loading: true, + leading: false, class: { - base: 'p-2' + trailingIcon: 'animate-spin' } }], defaultVariants: {