11<script lang="ts">
22import { tv , type VariantProps } from ' tailwind-variants'
3- import type { LinkProps } from ' ./Link.vue'
43// import appConfig from '#build/app.config'
4+ import { getLinkProps , type LinkProps } from ' #ui/components/Link.vue'
5+ import theme from ' #ui/theme/button'
56
6- export const theme = {
7- slots: {
8- base: ' inline-flex items-center focus:outline-none rounded-md font-medium' ,
9- label: ' ' ,
10- icon: ' flex-shrink-0'
11- },
12- variants: {
13- color: {
14- blue: ' bg-blue-500 hover:bg-blue-700' ,
15- red: ' bg-red-500 hover:bg-red-700' ,
16- green: ' bg-green-500 hover:bg-green-700'
17- },
18- size: {
19- ' 2xs' : {
20- base: ' px-2 py-1 text-xs gap-x-1'
21- },
22- xs: {
23- base: ' px-2.5 py-1.5 text-xs gap-x-1.5'
24- },
25- sm: {
26- base: ' px-2.5 py-1.5 text-sm gap-x-1.5'
27- },
28- md: ' px-3 py-2 text-sm gap-x-2' ,
29- lg: ' px-3.5 py-2.5 text-sm gap-x-2.5' ,
30- xl: ' px-3.5 py-2.5 text-base gap-x-2.5'
31- },
32- truncate: {
33- true: {
34- label: ' text-left break-all line-clamp-1'
35- }
36- }
37- },
38- defaultVariants: {
39- color: ' blue' ,
40- size: ' md'
41- }
42- } as const
43-
44- // export const button = tv({ extend: tv(theme), ...appConfig.ui.button })
45- export const button = tv (theme )
7+ const appButton = tv (theme )
8+ // const appButton = tv({ extend: button, ...(appConfig.ui?.button || {}) })
469
47- type ButtonVariants = VariantProps <typeof button >
48-
49- export interface ButtonProps extends ButtonVariants , LinkProps {
10+ export interface ButtonProps extends VariantProps <typeof appButton >, LinkProps {
5011 label? : string
5112 icon? : string
5213 leading? : boolean
@@ -61,12 +22,12 @@ export interface ButtonProps extends ButtonVariants, LinkProps {
6122 padded? : boolean
6223 truncate? : boolean
6324 class? : any
64- ui? : Partial <typeof button >
25+ ui? : Partial <typeof appButton >
6526}
6627 </script >
6728
6829<script setup lang="ts">
69- import type { PropType } from ' vue'
30+ import { useSlots , computed , type PropType } from ' vue'
7031import { linkProps } from ' ./Link.vue'
7132import UIcon from ' ./Icon.vue'
7233
@@ -144,53 +105,56 @@ const props = defineProps({
144105 }
145106})
146107
147-
148108const slots = useSlots ()
109+ const appConfig = useAppConfig ()
149110
150111// Computed
151112
152- const isLeading = computed (() => (props .icon && props .leading ) || (props .icon && ! props .trailing ) || (props .loading && ! props .trailing ) || props .leadingIcon )
153-
154- const isTrailing = computed (() => (props .icon && props .trailing ) || (props .loading && props .trailing ) || props .trailingIcon )
155-
156- const ui = computed (() => tv ({ extend: button , ... props .ui })({
113+ const ui = computed (() => tv ({ extend: appButton , ... props .ui })({
157114 color: props .color ,
158115 size: props .size ,
159- square: props .square || (! slots .default && ! props .label ),
160- class: props .class
116+ loading: props .loading ,
117+ truncate: props .truncate ,
118+ block: props .block ,
119+ padded: props .padded ,
120+ square: props .square || (! slots .default && ! props .label )
161121}))
162122
123+ const isLeading = computed (() => (props .icon && props .leading ) || (props .icon && ! props .trailing ) || (props .loading && ! props .trailing ) || props .leadingIcon )
124+
125+ const isTrailing = computed (() => (props .icon && props .trailing ) || (props .loading && props .trailing ) || props .trailingIcon )
126+
163127const leadingIconName = computed (() => {
164128 if (props .loading ) {
165- return props .loadingIcon
129+ return props .loadingIcon || appConfig . ui . icons . loading
166130 }
167131
168132 return props .leadingIcon || props .icon
169133})
170134
171135const trailingIconName = computed (() => {
172136 if (props .loading && ! isLeading .value ) {
173- return props .loadingIcon
137+ return props .loadingIcon || appConfig . ui . icons . loading
174138 }
175139
176140 return props .trailingIcon || props .icon
177141})
178142 </script >
179143
180144<template >
181- <ULink :type =" type" :disabled =" disabled || loading" :class =" ui.base()" v-bind =" $ attrs" >
145+ <ULink :type =" type" :disabled =" disabled || loading" :class =" ui.base({ class: $props.class } )" v-bind =" { ...getLinkProps($props), ...$ attrs } " >
182146 <slot name =" leading" :disabled =" disabled" :loading =" loading" >
183- <UIcon v-if =" isLeading && leadingIconName" :name =" leadingIconName" :class =" ui.icon({ isLeading } )" aria-hidden =" true" />
147+ <UIcon v-if =" isLeading && leadingIconName" :name =" leadingIconName" :class =" ui.icon()" aria-hidden =" true" />
184148 </slot >
185149
186- <span v-if =" label || $slots.default" :class =" ui.label({ truncate } )" >
150+ <span v-if =" label || $slots.default" :class =" ui.label()" >
187151 <slot >
188152 {{ label }}
189153 </slot >
190154 </span >
191155
192- <!-- < slot name="trailing" :disabled="disabled" :loading="loading">
193- <UIcon v-if="isTrailing && trailingIconName" :name="trailingIconName" :class="trailingIconClass " aria-hidden="true" />
194- </slot> -->
156+ <slot name =" trailing" :disabled =" disabled" :loading =" loading" >
157+ <UIcon v-if =" isTrailing && trailingIconName" :name =" trailingIconName" :class =" ui.icon() " aria-hidden =" true" />
158+ </slot >
195159 </ULink >
196160</template >
0 commit comments