@spavn/ui 0.0.1 → 0.0.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cli/registry.d.ts.map +1 -1
- package/cli/registry.js +43 -16
- package/cli/registry.js.map +1 -1
- package/dist/index.js +3001 -2308
- package/dist/index.umd.cjs +80 -2
- package/mcp-server/index.js +74 -39
- package/mcp-server/index.js.map +1 -1
- package/package.json +1 -1
- package/src/index.ts +4 -0
- package/src/lib/alert/Alert.vue +17 -1
- package/src/lib/alert/variants.ts +3 -0
- package/src/lib/avatar/Avatar.vue +27 -3
- package/src/lib/avatar/AvatarFallback.vue +14 -1
- package/src/lib/avatar-group/AvatarGroup.vue +27 -0
- package/src/lib/avatar-group/index.ts +1 -0
- package/src/lib/badge/Badge.vue +30 -1
- package/src/lib/badge/variants.ts +3 -0
- package/src/lib/button/Button.vue +79 -24
- package/src/lib/button/variants.ts +15 -0
- package/src/lib/card/Card.vue +15 -2
- package/src/lib/checkbox/Checkbox.vue +32 -3
- package/src/lib/input/Input.vue +91 -39
- package/src/lib/progress/Progress.vue +13 -3
- package/src/lib/radio-group/RadioGroupItem.vue +32 -3
- package/src/lib/separator/Separator.vue +37 -8
- package/src/lib/skeleton/Skeleton.vue +27 -2
- package/src/lib/slider/Slider.vue +16 -3
- package/src/lib/styles.ts +78 -0
- package/src/lib/switch/Switch.vue +28 -5
- package/src/lib/tabs/TabsList.vue +37 -7
- package/src/lib/tabs/TabsTrigger.vue +36 -6
- package/src/lib/textarea/Textarea.vue +29 -3
- package/src/lib/toggle/Toggle.vue +9 -1
- package/src/lib/types.ts +370 -0
- package/src/lib/utils.ts +23 -2
- package/src/theme.css +39 -0
|
@@ -8,11 +8,13 @@ import {
|
|
|
8
8
|
} from 'radix-vue'
|
|
9
9
|
import { computed } from 'vue'
|
|
10
10
|
import { cn } from '@/lib/utils'
|
|
11
|
+
import { type SpavnColor, colorBg, colorBorder } from '@/lib/types'
|
|
11
12
|
|
|
12
13
|
interface Props {
|
|
13
14
|
class?: string
|
|
14
15
|
modelValue?: number[]
|
|
15
16
|
showValue?: boolean
|
|
17
|
+
color?: SpavnColor
|
|
16
18
|
}
|
|
17
19
|
|
|
18
20
|
const props = withDefaults(defineProps<Props>(), {
|
|
@@ -20,6 +22,16 @@ const props = withDefaults(defineProps<Props>(), {
|
|
|
20
22
|
})
|
|
21
23
|
|
|
22
24
|
const thumbCount = computed(() => (props.modelValue ?? [0]).length)
|
|
25
|
+
|
|
26
|
+
const rangeColor = computed(() => {
|
|
27
|
+
if (!props.color || props.color === 'default') return 'bg-primary'
|
|
28
|
+
return colorBg[props.color as Exclude<SpavnColor, 'default'>]
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
const thumbBorderColor = computed(() => {
|
|
32
|
+
if (!props.color || props.color === 'default') return 'border-primary'
|
|
33
|
+
return colorBorder[props.color as Exclude<SpavnColor, 'default'>]
|
|
34
|
+
})
|
|
23
35
|
</script>
|
|
24
36
|
|
|
25
37
|
<template>
|
|
@@ -37,14 +49,15 @@ const thumbCount = computed(() => (props.modelValue ?? [0]).length)
|
|
|
37
49
|
<SliderTrack
|
|
38
50
|
class="relative h-1.5 w-full grow overflow-hidden rounded-full bg-muted shadow-depth-1"
|
|
39
51
|
>
|
|
40
|
-
<SliderRange class="absolute h-full
|
|
52
|
+
<SliderRange :class="cn('absolute h-full transition-all duration-150 ease-out', rangeColor)" />
|
|
41
53
|
</SliderTrack>
|
|
42
54
|
<SliderThumb
|
|
43
55
|
v-for="(_, i) in thumbCount"
|
|
44
56
|
:key="i"
|
|
45
57
|
:class="
|
|
46
58
|
cn(
|
|
47
|
-
'block h-5 w-5 rounded-full border-2
|
|
59
|
+
'block h-5 w-5 rounded-full border-2 bg-background',
|
|
60
|
+
thumbBorderColor,
|
|
48
61
|
'ring-offset-background transition-all duration-150 ease-out',
|
|
49
62
|
'shadow-depth-2 hover:shadow-depth-3 hover:scale-105',
|
|
50
63
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
@@ -53,7 +66,7 @@ const thumbCount = computed(() => (props.modelValue ?? [0]).length)
|
|
|
53
66
|
"
|
|
54
67
|
/>
|
|
55
68
|
</SliderRoot>
|
|
56
|
-
|
|
69
|
+
|
|
57
70
|
<!-- Value Display Slot -->
|
|
58
71
|
<slot name="value" :value="modelValue">
|
|
59
72
|
<span
|
package/src/lib/styles.ts
CHANGED
|
@@ -48,6 +48,45 @@ export const baseStyles = `
|
|
|
48
48
|
--input: 0 0% 90%;
|
|
49
49
|
--ring: 0 0% 9%;
|
|
50
50
|
|
|
51
|
+
/* Extended palette */
|
|
52
|
+
--info: 217 91% 60%;
|
|
53
|
+
--info-foreground: 0 0% 98%;
|
|
54
|
+
--info-soft: 217 91% 95%;
|
|
55
|
+
|
|
56
|
+
--warning: 38 92% 50%;
|
|
57
|
+
--warning-foreground: 0 0% 9%;
|
|
58
|
+
--warning-soft: 38 92% 95%;
|
|
59
|
+
|
|
60
|
+
--amber: 45 93% 47%;
|
|
61
|
+
--amber-foreground: 0 0% 9%;
|
|
62
|
+
--amber-soft: 45 93% 95%;
|
|
63
|
+
|
|
64
|
+
--blue: 221 83% 53%;
|
|
65
|
+
--blue-foreground: 0 0% 98%;
|
|
66
|
+
--blue-soft: 221 83% 95%;
|
|
67
|
+
|
|
68
|
+
--green: 142 71% 45%;
|
|
69
|
+
--green-foreground: 0 0% 98%;
|
|
70
|
+
--green-soft: 142 71% 95%;
|
|
71
|
+
|
|
72
|
+
--purple: 262 83% 58%;
|
|
73
|
+
--purple-foreground: 0 0% 98%;
|
|
74
|
+
--purple-soft: 262 83% 95%;
|
|
75
|
+
|
|
76
|
+
--pink: 330 81% 60%;
|
|
77
|
+
--pink-foreground: 0 0% 98%;
|
|
78
|
+
--pink-soft: 330 81% 95%;
|
|
79
|
+
|
|
80
|
+
--orange: 25 95% 53%;
|
|
81
|
+
--orange-foreground: 0 0% 98%;
|
|
82
|
+
--orange-soft: 25 95% 95%;
|
|
83
|
+
|
|
84
|
+
/* Soft variants for semantic colors */
|
|
85
|
+
--primary-soft: 0 0% 93%;
|
|
86
|
+
--secondary-soft: 0 0% 96%;
|
|
87
|
+
--destructive-soft: 0 84% 95%;
|
|
88
|
+
--success-soft: 142 76% 95%;
|
|
89
|
+
|
|
51
90
|
/* Radius - updated to match design system */
|
|
52
91
|
--radius: 1rem;
|
|
53
92
|
|
|
@@ -110,6 +149,45 @@ export const baseStyles = `
|
|
|
110
149
|
--input: 0 0% 20%;
|
|
111
150
|
--ring: 0 0% 80%;
|
|
112
151
|
|
|
152
|
+
/* Extended palette - dark mode (reduced saturation) */
|
|
153
|
+
--info: 217 80% 55%;
|
|
154
|
+
--info-foreground: 0 0% 98%;
|
|
155
|
+
--info-soft: 217 50% 15%;
|
|
156
|
+
|
|
157
|
+
--warning: 38 80% 50%;
|
|
158
|
+
--warning-foreground: 0 0% 9%;
|
|
159
|
+
--warning-soft: 38 50% 15%;
|
|
160
|
+
|
|
161
|
+
--amber: 45 80% 50%;
|
|
162
|
+
--amber-foreground: 0 0% 9%;
|
|
163
|
+
--amber-soft: 45 50% 15%;
|
|
164
|
+
|
|
165
|
+
--blue: 221 75% 55%;
|
|
166
|
+
--blue-foreground: 0 0% 98%;
|
|
167
|
+
--blue-soft: 221 50% 15%;
|
|
168
|
+
|
|
169
|
+
--green: 142 65% 45%;
|
|
170
|
+
--green-foreground: 0 0% 98%;
|
|
171
|
+
--green-soft: 142 40% 15%;
|
|
172
|
+
|
|
173
|
+
--purple: 262 75% 60%;
|
|
174
|
+
--purple-foreground: 0 0% 98%;
|
|
175
|
+
--purple-soft: 262 50% 15%;
|
|
176
|
+
|
|
177
|
+
--pink: 330 70% 55%;
|
|
178
|
+
--pink-foreground: 0 0% 98%;
|
|
179
|
+
--pink-soft: 330 50% 15%;
|
|
180
|
+
|
|
181
|
+
--orange: 25 85% 55%;
|
|
182
|
+
--orange-foreground: 0 0% 98%;
|
|
183
|
+
--orange-soft: 25 50% 15%;
|
|
184
|
+
|
|
185
|
+
/* Soft variants for semantic colors - dark mode */
|
|
186
|
+
--primary-soft: 0 0% 15%;
|
|
187
|
+
--secondary-soft: 0 0% 12%;
|
|
188
|
+
--destructive-soft: 0 60% 15%;
|
|
189
|
+
--success-soft: 142 50% 15%;
|
|
190
|
+
|
|
113
191
|
/* Elevation opacity overlays for depth perception (inverted for dark mode) */
|
|
114
192
|
--elevation-overlay-1: rgba(255, 255, 255, 0.03);
|
|
115
193
|
--elevation-overlay-2: rgba(255, 255, 255, 0.06);
|
|
@@ -4,14 +4,33 @@ import {
|
|
|
4
4
|
SwitchRoot,
|
|
5
5
|
SwitchThumb,
|
|
6
6
|
} from 'radix-vue'
|
|
7
|
+
import { computed } from 'vue'
|
|
7
8
|
import { cn } from '@/lib/utils'
|
|
9
|
+
import { type SpavnColor, colorCheckedBg } from '@/lib/types'
|
|
8
10
|
|
|
9
11
|
interface Props {
|
|
10
12
|
class?: string
|
|
11
13
|
checked?: boolean
|
|
14
|
+
size?: 'sm' | 'default' | 'lg'
|
|
15
|
+
color?: SpavnColor
|
|
12
16
|
}
|
|
13
17
|
|
|
14
|
-
const props = defineProps<Props>()
|
|
18
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
19
|
+
size: 'default',
|
|
20
|
+
})
|
|
21
|
+
|
|
22
|
+
const sizeConfig = {
|
|
23
|
+
sm: { track: 'h-4 w-8', thumb: 'h-3 w-3', translate: 'data-[state=checked]:translate-x-4' },
|
|
24
|
+
default: { track: 'h-6 w-11', thumb: 'h-5 w-5', translate: 'data-[state=checked]:translate-x-5' },
|
|
25
|
+
lg: { track: 'h-7 w-14', thumb: 'h-6 w-6', translate: 'data-[state=checked]:translate-x-7' },
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
const currentSize = computed(() => sizeConfig[props.size || 'default'])
|
|
29
|
+
|
|
30
|
+
const checkedColor = computed(() => {
|
|
31
|
+
if (!props.color || props.color === 'default') return 'data-[state=checked]:bg-primary'
|
|
32
|
+
return colorCheckedBg[props.color as Exclude<SpavnColor, 'default'>]
|
|
33
|
+
})
|
|
15
34
|
</script>
|
|
16
35
|
|
|
17
36
|
<template>
|
|
@@ -20,8 +39,10 @@ const props = defineProps<Props>()
|
|
|
20
39
|
:checked="checked"
|
|
21
40
|
:class="
|
|
22
41
|
cn(
|
|
23
|
-
'peer inline-flex
|
|
24
|
-
|
|
42
|
+
'peer inline-flex shrink-0 cursor-pointer items-center rounded-full border-2 border-transparent shadow-depth-1',
|
|
43
|
+
currentSize.track,
|
|
44
|
+
'bg-muted',
|
|
45
|
+
checkedColor,
|
|
25
46
|
'ring-offset-background transition-all duration-150 ease-out',
|
|
26
47
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
27
48
|
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
@@ -33,9 +54,11 @@ const props = defineProps<Props>()
|
|
|
33
54
|
<SwitchThumb
|
|
34
55
|
:class="
|
|
35
56
|
cn(
|
|
36
|
-
'pointer-events-none block
|
|
57
|
+
'pointer-events-none block rounded-full bg-background shadow-depth-2',
|
|
58
|
+
currentSize.thumb,
|
|
37
59
|
'ring-0 transition-transform duration-150 ease-out',
|
|
38
|
-
|
|
60
|
+
currentSize.translate,
|
|
61
|
+
'data-[state=unchecked]:translate-x-0'
|
|
39
62
|
)
|
|
40
63
|
"
|
|
41
64
|
/>
|
|
@@ -1,20 +1,50 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
defineOptions({ inheritAttrs: false })
|
|
3
3
|
import { TabsList } from 'radix-vue'
|
|
4
|
+
import { computed, provide } from 'vue'
|
|
4
5
|
import { cn } from '@/lib/utils'
|
|
6
|
+
import { type SpavnColor } from '@/lib/types'
|
|
5
7
|
|
|
6
|
-
|
|
8
|
+
interface Props {
|
|
9
|
+
class?: string
|
|
10
|
+
variant?: 'default' | 'underline' | 'pills' | 'enclosed'
|
|
11
|
+
size?: 'sm' | 'default' | 'lg'
|
|
12
|
+
color?: SpavnColor
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
16
|
+
variant: 'default',
|
|
17
|
+
size: 'default',
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
// Provide variant and color to TabsTrigger children
|
|
21
|
+
provide('tabs-variant', props.variant)
|
|
22
|
+
provide('tabs-color', props.color)
|
|
23
|
+
|
|
24
|
+
const sizeClasses = {
|
|
25
|
+
sm: 'h-8 text-xs',
|
|
26
|
+
default: 'h-10 text-sm',
|
|
27
|
+
lg: 'h-12 text-base',
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
const variantClasses = computed(() => {
|
|
31
|
+
switch (props.variant) {
|
|
32
|
+
case 'underline':
|
|
33
|
+
return 'inline-flex items-center justify-center bg-transparent border-b border-border p-0 gap-0 rounded-none shadow-none'
|
|
34
|
+
case 'pills':
|
|
35
|
+
return 'inline-flex items-center justify-center bg-transparent p-0 gap-1 rounded-none shadow-none'
|
|
36
|
+
case 'enclosed':
|
|
37
|
+
return 'inline-flex items-center justify-center bg-muted p-1 rounded-lg shadow-depth-1 border border-border'
|
|
38
|
+
default:
|
|
39
|
+
return 'inline-flex items-center justify-center rounded-md bg-muted p-1 shadow-depth-1'
|
|
40
|
+
}
|
|
41
|
+
})
|
|
7
42
|
</script>
|
|
8
43
|
|
|
9
44
|
<template>
|
|
10
45
|
<TabsList
|
|
11
46
|
v-bind="$attrs"
|
|
12
|
-
:class="
|
|
13
|
-
cn(
|
|
14
|
-
'inline-flex h-10 items-center justify-center rounded-md bg-muted p-1 text-muted-foreground shadow-depth-1',
|
|
15
|
-
props.class
|
|
16
|
-
)
|
|
17
|
-
"
|
|
47
|
+
:class="cn(variantClasses, sizeClasses[props.size], 'text-muted-foreground', props.class)"
|
|
18
48
|
>
|
|
19
49
|
<slot />
|
|
20
50
|
</TabsList>
|
|
@@ -1,20 +1,50 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
defineOptions({ inheritAttrs: false })
|
|
3
3
|
import { TabsTrigger } from 'radix-vue'
|
|
4
|
+
import { inject, computed } from 'vue'
|
|
4
5
|
import { cn } from '@/lib/utils'
|
|
6
|
+
import { type SpavnColor, colorActiveUnderline, colorActivePill } from '@/lib/types'
|
|
5
7
|
|
|
6
8
|
const props = defineProps<{ class?: string }>()
|
|
9
|
+
|
|
10
|
+
const variant = inject<string>('tabs-variant', 'default')
|
|
11
|
+
const color = inject<SpavnColor | undefined>('tabs-color', undefined)
|
|
12
|
+
|
|
13
|
+
const activeColorClass = computed(() => {
|
|
14
|
+
if (!color || color === 'default') return ''
|
|
15
|
+
const c = color as Exclude<SpavnColor, 'default'>
|
|
16
|
+
|
|
17
|
+
switch (variant) {
|
|
18
|
+
case 'underline':
|
|
19
|
+
return colorActiveUnderline[c]
|
|
20
|
+
case 'pills':
|
|
21
|
+
case 'enclosed':
|
|
22
|
+
return colorActivePill[c]
|
|
23
|
+
default:
|
|
24
|
+
return colorActivePill[c]
|
|
25
|
+
}
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
const variantClasses = computed(() => {
|
|
29
|
+
const base = 'inline-flex items-center justify-center whitespace-nowrap px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50'
|
|
30
|
+
|
|
31
|
+
switch (variant) {
|
|
32
|
+
case 'underline':
|
|
33
|
+
return `${base} rounded-none border-b-2 border-transparent data-[state=active]:border-primary data-[state=active]:text-foreground`
|
|
34
|
+
case 'pills':
|
|
35
|
+
return `${base} rounded-full data-[state=active]:bg-primary data-[state=active]:text-primary-foreground data-[state=active]:shadow-depth-1`
|
|
36
|
+
case 'enclosed':
|
|
37
|
+
return `${base} rounded-md data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm`
|
|
38
|
+
default:
|
|
39
|
+
return `${base} rounded-sm data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm`
|
|
40
|
+
}
|
|
41
|
+
})
|
|
7
42
|
</script>
|
|
8
43
|
|
|
9
44
|
<template>
|
|
10
45
|
<TabsTrigger
|
|
11
46
|
v-bind="$attrs"
|
|
12
|
-
:class="
|
|
13
|
-
cn(
|
|
14
|
-
'inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm',
|
|
15
|
-
props.class
|
|
16
|
-
)
|
|
17
|
-
"
|
|
47
|
+
:class="cn(variantClasses, activeColorClass, props.class)"
|
|
18
48
|
>
|
|
19
49
|
<slot />
|
|
20
50
|
</TabsTrigger>
|
|
@@ -1,30 +1,56 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
|
+
import { computed } from 'vue'
|
|
2
3
|
import { cn } from '@/lib/utils'
|
|
4
|
+
import { type SpavnRadius, radiusMap } from '@/lib/types'
|
|
3
5
|
|
|
4
6
|
interface Props {
|
|
5
7
|
class?: string
|
|
6
8
|
disabled?: boolean
|
|
7
9
|
placeholder?: string
|
|
8
10
|
modelValue?: string
|
|
11
|
+
variant?: 'outline' | 'filled' | 'underline' | 'plain'
|
|
12
|
+
size?: 'sm' | 'default' | 'lg'
|
|
13
|
+
radius?: SpavnRadius
|
|
9
14
|
}
|
|
10
15
|
|
|
11
|
-
const props = defineProps<Props>()
|
|
16
|
+
const props = withDefaults(defineProps<Props>(), {
|
|
17
|
+
variant: 'outline',
|
|
18
|
+
size: 'default',
|
|
19
|
+
})
|
|
12
20
|
|
|
13
21
|
defineEmits<{
|
|
14
22
|
'update:modelValue': [value: string]
|
|
15
23
|
}>()
|
|
24
|
+
|
|
25
|
+
const sizeClasses = {
|
|
26
|
+
sm: 'min-h-[60px] text-sm',
|
|
27
|
+
default: 'min-h-[80px] text-sm',
|
|
28
|
+
lg: 'min-h-[120px] text-base',
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const variantClasses = {
|
|
32
|
+
outline: 'border border-input bg-background shadow-depth-1 focus-visible:shadow-depth-2',
|
|
33
|
+
filled: 'border-transparent bg-muted',
|
|
34
|
+
underline: 'border-b border-input bg-transparent rounded-none',
|
|
35
|
+
plain: 'border-transparent bg-transparent focus-visible:shadow-none',
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
const radiusClass = computed(() => props.radius ? radiusMap[props.radius] : '')
|
|
16
39
|
</script>
|
|
17
40
|
|
|
18
41
|
<template>
|
|
19
42
|
<textarea
|
|
20
43
|
:class="
|
|
21
44
|
cn(
|
|
22
|
-
'flex
|
|
45
|
+
'flex w-full rounded-md px-3 py-2',
|
|
46
|
+
variantClasses[props.variant],
|
|
47
|
+
sizeClasses[props.size],
|
|
23
48
|
'ring-offset-background',
|
|
24
49
|
'placeholder:text-muted-foreground',
|
|
25
50
|
'focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2',
|
|
26
51
|
'disabled:cursor-not-allowed disabled:opacity-50',
|
|
27
|
-
'
|
|
52
|
+
'transition-elevation',
|
|
53
|
+
radiusClass,
|
|
28
54
|
props.class
|
|
29
55
|
)
|
|
30
56
|
"
|
|
@@ -1,20 +1,28 @@
|
|
|
1
1
|
<script setup lang="ts">
|
|
2
2
|
defineOptions({ inheritAttrs: false })
|
|
3
3
|
import { Toggle } from 'radix-vue'
|
|
4
|
+
import { computed } from 'vue'
|
|
4
5
|
import { cn } from '@/lib/utils'
|
|
6
|
+
import { type SpavnColor, colorOnState } from '@/lib/types'
|
|
5
7
|
import { toggleVariants } from './variants'
|
|
6
8
|
|
|
7
9
|
const props = defineProps<{
|
|
8
10
|
class?: string
|
|
9
11
|
variant?: 'default' | 'outline'
|
|
10
12
|
size?: 'default' | 'sm' | 'lg'
|
|
13
|
+
color?: SpavnColor
|
|
11
14
|
}>()
|
|
15
|
+
|
|
16
|
+
const activeColorClass = computed(() => {
|
|
17
|
+
if (!props.color || props.color === 'default') return ''
|
|
18
|
+
return colorOnState[props.color as Exclude<SpavnColor, 'default'>]
|
|
19
|
+
})
|
|
12
20
|
</script>
|
|
13
21
|
|
|
14
22
|
<template>
|
|
15
23
|
<Toggle
|
|
16
24
|
v-bind="$attrs"
|
|
17
|
-
:class="cn(toggleVariants({ variant: props.variant, size: props.size }), props.class)"
|
|
25
|
+
:class="cn(toggleVariants({ variant: props.variant, size: props.size }), activeColorClass, props.class)"
|
|
18
26
|
>
|
|
19
27
|
<slot />
|
|
20
28
|
</Toggle>
|