@polymarbot/nuxt-layer-shadcn-ui 0.3.9 → 0.4.0
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/app/components/ui/Accordion/index.stories.ts +43 -15
- package/app/components/ui/AdminLayout/index.stories.ts +6 -14
- package/app/components/ui/Alert/index.stories.ts +32 -2
- package/app/components/ui/AlertDialog/index.stories.ts +114 -5
- package/app/components/ui/AsyncDataTable/index.stories.ts +36 -2
- package/app/components/ui/Avatar/index.stories.ts +58 -4
- package/app/components/ui/Badge/index.stories.ts +48 -3
- package/app/components/ui/Breadcrumb/index.stories.ts +8 -19
- package/app/components/ui/Button/index.stories.ts +116 -7
- package/app/components/ui/ButtonGroup/index.stories.ts +63 -4
- package/app/components/ui/Card/index.stories.ts +40 -14
- package/app/components/ui/Checkbox/index.stories.ts +53 -3
- package/app/components/ui/CopyButton/index.stories.ts +77 -5
- package/app/components/ui/DataTable/index.stories.ts +184 -11
- package/app/components/ui/DatePicker/index.stories.ts +56 -7
- package/app/components/ui/DateRangePicker/index.stories.ts +40 -5
- package/app/components/ui/Divider/index.stories.ts +18 -15
- package/app/components/ui/Drawer/index.stories.ts +115 -16
- package/app/components/ui/Drawer/index.vue +27 -12
- package/app/components/ui/Dropdown/index.stories.ts +72 -54
- package/app/components/ui/Dropdown/index.vue +5 -8
- package/app/components/ui/Dropdown/types.ts +3 -8
- package/app/components/ui/FormItem/index.stories.ts +33 -45
- package/app/components/ui/Help/index.stories.ts +34 -2
- package/app/components/ui/Icon/index.stories.ts +41 -2
- package/app/components/ui/Input/index.stories.ts +73 -31
- package/app/components/ui/Input/index.vue +1 -0
- package/app/components/ui/InputCurrency/index.stories.ts +20 -65
- package/app/components/ui/InputNumber/index.stories.ts +31 -58
- package/app/components/ui/InputOtp/index.stories.ts +41 -9
- package/app/components/ui/InputPercent/index.stories.ts +3 -7
- package/app/components/ui/InputRange/index.stories.ts +51 -4
- package/app/components/ui/Loading/index.stories.ts +16 -1
- package/app/components/ui/Markdown/index.stories.ts +9 -0
- package/app/components/ui/Modal/index.stories.ts +133 -16
- package/app/components/ui/Modal/index.vue +27 -12
- package/app/components/ui/ModalContent/index.stories.ts +35 -11
- package/app/components/ui/PageCard/index.stories.ts +154 -56
- package/app/components/ui/Pagination/index.stories.ts +75 -41
- package/app/components/ui/Pagination/index.vue +4 -1
- package/app/components/ui/Popover/index.stories.ts +73 -27
- package/app/components/ui/Popover/index.vue +67 -4
- package/app/components/ui/Popover/types.ts +5 -2
- package/app/components/ui/Qrcode/index.stories.ts +32 -2
- package/app/components/ui/RadioCardGroup/index.stories.ts +45 -6
- package/app/components/ui/RadioGroup/index.stories.ts +64 -52
- package/app/components/ui/ScrollArea/index.stories.ts +21 -23
- package/app/components/ui/SearchSelect/index.stories.ts +73 -24
- package/app/components/ui/Select/index.stories.ts +121 -6
- package/app/components/ui/Select/index.vue +7 -6
- package/app/components/ui/Skeleton/index.stories.ts +34 -2
- package/app/components/ui/Slider/index.stories.ts +67 -4
- package/app/components/ui/Surface/index.stories.ts +86 -5
- package/app/components/ui/Surface/index.vue +115 -2
- package/app/components/ui/Surface/types.ts +2 -0
- package/app/components/ui/Switch/index.stories.ts +46 -0
- package/app/components/ui/Tabs/index.stories.ts +61 -64
- package/app/components/ui/Tag/index.stories.ts +45 -3
- package/app/components/ui/Textarea/index.stories.ts +61 -32
- package/app/components/ui/Toast/index.stories.ts +77 -3
- package/app/components/ui/Tooltip/index.stories.ts +60 -2
- package/app/components/ui/WebLink/index.stories.ts +53 -15
- package/package.json +2 -2
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import EventLog from '#storybook/EventLog.vue'
|
|
2
3
|
import Select from './index.vue'
|
|
3
4
|
|
|
4
5
|
const frameworks = [
|
|
@@ -71,7 +72,23 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
71
72
|
export const Default: Story = {}
|
|
72
73
|
|
|
73
74
|
export const WithFilter: Story = {
|
|
74
|
-
parameters:
|
|
75
|
+
parameters: {
|
|
76
|
+
...noControls,
|
|
77
|
+
docs: {
|
|
78
|
+
source: {
|
|
79
|
+
code: `
|
|
80
|
+
<template>
|
|
81
|
+
<Select
|
|
82
|
+
v-model="value"
|
|
83
|
+
:options="manyOptions"
|
|
84
|
+
placeholder="Search and select"
|
|
85
|
+
filter
|
|
86
|
+
/>
|
|
87
|
+
</template>
|
|
88
|
+
`.trim(),
|
|
89
|
+
},
|
|
90
|
+
},
|
|
91
|
+
},
|
|
75
92
|
render: () => ({
|
|
76
93
|
components: { Select },
|
|
77
94
|
setup () {
|
|
@@ -93,7 +110,23 @@ export const WithFilter: Story = {
|
|
|
93
110
|
}
|
|
94
111
|
|
|
95
112
|
export const Multiple: Story = {
|
|
96
|
-
parameters:
|
|
113
|
+
parameters: {
|
|
114
|
+
...noControls,
|
|
115
|
+
docs: {
|
|
116
|
+
source: {
|
|
117
|
+
code: `
|
|
118
|
+
<template>
|
|
119
|
+
<Select
|
|
120
|
+
v-model="value"
|
|
121
|
+
:options="frameworks"
|
|
122
|
+
placeholder="Select frameworks"
|
|
123
|
+
multiple
|
|
124
|
+
/>
|
|
125
|
+
</template>
|
|
126
|
+
`.trim(),
|
|
127
|
+
},
|
|
128
|
+
},
|
|
129
|
+
},
|
|
97
130
|
render: () => ({
|
|
98
131
|
components: { Select },
|
|
99
132
|
setup () {
|
|
@@ -115,7 +148,21 @@ export const Multiple: Story = {
|
|
|
115
148
|
}
|
|
116
149
|
|
|
117
150
|
export const WithDisabledOptions: Story = {
|
|
118
|
-
parameters:
|
|
151
|
+
parameters: {
|
|
152
|
+
...noControls,
|
|
153
|
+
docs: {
|
|
154
|
+
source: {
|
|
155
|
+
code: `
|
|
156
|
+
<template>
|
|
157
|
+
<Select
|
|
158
|
+
:options="withDisabled"
|
|
159
|
+
placeholder="Select a framework"
|
|
160
|
+
/>
|
|
161
|
+
</template>
|
|
162
|
+
`.trim(),
|
|
163
|
+
},
|
|
164
|
+
},
|
|
165
|
+
},
|
|
119
166
|
render: () => ({
|
|
120
167
|
components: { Select },
|
|
121
168
|
setup () {
|
|
@@ -133,7 +180,22 @@ export const WithDisabledOptions: Story = {
|
|
|
133
180
|
}
|
|
134
181
|
|
|
135
182
|
export const Scrollable: Story = {
|
|
136
|
-
parameters:
|
|
183
|
+
parameters: {
|
|
184
|
+
...noControls,
|
|
185
|
+
docs: {
|
|
186
|
+
source: {
|
|
187
|
+
code: `
|
|
188
|
+
<template>
|
|
189
|
+
<Select
|
|
190
|
+
v-model="value"
|
|
191
|
+
:options="manyOptions"
|
|
192
|
+
placeholder="Select an option"
|
|
193
|
+
/>
|
|
194
|
+
</template>
|
|
195
|
+
`.trim(),
|
|
196
|
+
},
|
|
197
|
+
},
|
|
198
|
+
},
|
|
137
199
|
render: () => ({
|
|
138
200
|
components: { Select },
|
|
139
201
|
setup () {
|
|
@@ -154,7 +216,22 @@ export const Scrollable: Story = {
|
|
|
154
216
|
}
|
|
155
217
|
|
|
156
218
|
export const Grouped: Story = {
|
|
157
|
-
parameters:
|
|
219
|
+
parameters: {
|
|
220
|
+
...noControls,
|
|
221
|
+
docs: {
|
|
222
|
+
source: {
|
|
223
|
+
code: `
|
|
224
|
+
<template>
|
|
225
|
+
<Select
|
|
226
|
+
v-model="value"
|
|
227
|
+
:options="withGroups"
|
|
228
|
+
placeholder="Select a framework"
|
|
229
|
+
/>
|
|
230
|
+
</template>
|
|
231
|
+
`.trim(),
|
|
232
|
+
},
|
|
233
|
+
},
|
|
234
|
+
},
|
|
158
235
|
render: () => ({
|
|
159
236
|
components: { Select },
|
|
160
237
|
setup () {
|
|
@@ -175,7 +252,18 @@ export const Grouped: Story = {
|
|
|
175
252
|
}
|
|
176
253
|
|
|
177
254
|
export const Disabled: Story = {
|
|
178
|
-
parameters:
|
|
255
|
+
parameters: {
|
|
256
|
+
...noControls,
|
|
257
|
+
docs: {
|
|
258
|
+
source: {
|
|
259
|
+
code: `
|
|
260
|
+
<template>
|
|
261
|
+
<Select :options="frameworks" placeholder="Disabled select" disabled />
|
|
262
|
+
</template>
|
|
263
|
+
`.trim(),
|
|
264
|
+
},
|
|
265
|
+
},
|
|
266
|
+
},
|
|
179
267
|
render: () => ({
|
|
180
268
|
components: { Select },
|
|
181
269
|
setup () {
|
|
@@ -188,3 +276,30 @@ export const Disabled: Story = {
|
|
|
188
276
|
`,
|
|
189
277
|
}),
|
|
190
278
|
}
|
|
279
|
+
|
|
280
|
+
export const EventHandling: Story = {
|
|
281
|
+
parameters: noControls,
|
|
282
|
+
render: () => ({
|
|
283
|
+
components: { Select, EventLog },
|
|
284
|
+
setup () {
|
|
285
|
+
const value = ref<string>()
|
|
286
|
+
return { value, frameworks }
|
|
287
|
+
},
|
|
288
|
+
template: `
|
|
289
|
+
<EventLog v-slot="{ record }">
|
|
290
|
+
<div class="max-w-sm">
|
|
291
|
+
<Select
|
|
292
|
+
v-model="value"
|
|
293
|
+
:options="frameworks"
|
|
294
|
+
filter
|
|
295
|
+
placeholder="Pick a framework"
|
|
296
|
+
@update:modelValue="(v) => record('update:modelValue', v)"
|
|
297
|
+
@search="(q) => record('search', q)"
|
|
298
|
+
@open="record('open')"
|
|
299
|
+
@close="record('close')"
|
|
300
|
+
/>
|
|
301
|
+
</div>
|
|
302
|
+
</EventLog>
|
|
303
|
+
`,
|
|
304
|
+
}),
|
|
305
|
+
}
|
|
@@ -156,16 +156,16 @@ function handleClear (event: MouseEvent) {
|
|
|
156
156
|
:data-disabled="disabled || undefined"
|
|
157
157
|
:data-state="open ? 'open' : 'closed'"
|
|
158
158
|
class="
|
|
159
|
+
data-[state=open]:border-ring data-[state=open]:ring-ring/50
|
|
159
160
|
cursor-pointer
|
|
160
|
-
data-[state=open]:
|
|
161
|
-
data-[state=open]:ring-ring/50
|
|
161
|
+
data-[state=open]:ring-[3px]
|
|
162
162
|
"
|
|
163
163
|
>
|
|
164
164
|
<span
|
|
165
165
|
class="
|
|
166
|
-
|
|
167
|
-
whitespace-nowrap
|
|
166
|
+
gap-2 px-3 py-1 text-base
|
|
168
167
|
md:text-sm
|
|
168
|
+
line-clamp-1 flex flex-1 items-center whitespace-nowrap
|
|
169
169
|
"
|
|
170
170
|
>
|
|
171
171
|
<template v-if="multiple && selectedOptions.length > 0">
|
|
@@ -196,6 +196,7 @@ function handleClear (event: MouseEvent) {
|
|
|
196
196
|
align="inline-end"
|
|
197
197
|
>
|
|
198
198
|
<InputGroupButton
|
|
199
|
+
type="button"
|
|
199
200
|
size="icon-xs"
|
|
200
201
|
@click="handleClear"
|
|
201
202
|
>
|
|
@@ -210,7 +211,7 @@ function handleClear (event: MouseEvent) {
|
|
|
210
211
|
</InputGroupAddon>
|
|
211
212
|
</InputGroup>
|
|
212
213
|
</PopoverTrigger>
|
|
213
|
-
<PopoverContent class="w-(--reka-popover-trigger-width)
|
|
214
|
+
<PopoverContent class="p-0 w-(--reka-popover-trigger-width)">
|
|
214
215
|
<Command
|
|
215
216
|
:modelValue="commandModelValue"
|
|
216
217
|
:filterFunction="commandFilterFunction"
|
|
@@ -250,7 +251,7 @@ function handleClear (event: MouseEvent) {
|
|
|
250
251
|
<Icon
|
|
251
252
|
name="check"
|
|
252
253
|
:class="cn(
|
|
253
|
-
'ml-auto
|
|
254
|
+
'size-4 ml-auto shrink-0',
|
|
254
255
|
isSelected(option.value) ? 'opacity-100' : 'opacity-0',
|
|
255
256
|
)"
|
|
256
257
|
/>
|
|
@@ -27,7 +27,22 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
27
27
|
export const Default: Story = {}
|
|
28
28
|
|
|
29
29
|
export const VariousSizes: Story = {
|
|
30
|
-
parameters:
|
|
30
|
+
parameters: {
|
|
31
|
+
...noControls,
|
|
32
|
+
docs: {
|
|
33
|
+
source: {
|
|
34
|
+
code: `
|
|
35
|
+
<template>
|
|
36
|
+
<div class="space-y-3">
|
|
37
|
+
<Skeleton width="100%" height="12px" />
|
|
38
|
+
<Skeleton width="80%" height="12px" />
|
|
39
|
+
<Skeleton width="60%" height="12px" />
|
|
40
|
+
</div>
|
|
41
|
+
</template>
|
|
42
|
+
`.trim(),
|
|
43
|
+
},
|
|
44
|
+
},
|
|
45
|
+
},
|
|
31
46
|
render: () => ({
|
|
32
47
|
components: { Skeleton },
|
|
33
48
|
template: `
|
|
@@ -41,7 +56,24 @@ export const VariousSizes: Story = {
|
|
|
41
56
|
}
|
|
42
57
|
|
|
43
58
|
export const CardSkeleton: Story = {
|
|
44
|
-
parameters:
|
|
59
|
+
parameters: {
|
|
60
|
+
...noControls,
|
|
61
|
+
docs: {
|
|
62
|
+
source: {
|
|
63
|
+
code: `
|
|
64
|
+
<template>
|
|
65
|
+
<div class="flex items-center gap-4">
|
|
66
|
+
<Skeleton width="48px" height="48px" class="rounded-full" />
|
|
67
|
+
<div class="space-y-2">
|
|
68
|
+
<Skeleton width="160px" height="16px" />
|
|
69
|
+
<Skeleton width="120px" height="12px" />
|
|
70
|
+
</div>
|
|
71
|
+
</div>
|
|
72
|
+
</template>
|
|
73
|
+
`.trim(),
|
|
74
|
+
},
|
|
75
|
+
},
|
|
76
|
+
},
|
|
45
77
|
render: () => ({
|
|
46
78
|
components: { Skeleton },
|
|
47
79
|
template: `
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import type { Meta, StoryObj } from '@storybook/vue3'
|
|
2
|
+
import EventLog from '#storybook/EventLog.vue'
|
|
2
3
|
import Slider from './index.vue'
|
|
3
4
|
|
|
4
5
|
const meta = {
|
|
@@ -41,7 +42,18 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
41
42
|
export const Default: Story = {}
|
|
42
43
|
|
|
43
44
|
export const Range: Story = {
|
|
44
|
-
parameters:
|
|
45
|
+
parameters: {
|
|
46
|
+
...noControls,
|
|
47
|
+
docs: {
|
|
48
|
+
source: {
|
|
49
|
+
code: `
|
|
50
|
+
<template>
|
|
51
|
+
<Slider v-model="range" />
|
|
52
|
+
</template>
|
|
53
|
+
`.trim(),
|
|
54
|
+
},
|
|
55
|
+
},
|
|
56
|
+
},
|
|
45
57
|
render: () => ({
|
|
46
58
|
components: { Slider },
|
|
47
59
|
setup () {
|
|
@@ -58,7 +70,18 @@ export const Range: Story = {
|
|
|
58
70
|
}
|
|
59
71
|
|
|
60
72
|
export const WithStep: Story = {
|
|
61
|
-
parameters:
|
|
73
|
+
parameters: {
|
|
74
|
+
...noControls,
|
|
75
|
+
docs: {
|
|
76
|
+
source: {
|
|
77
|
+
code: `
|
|
78
|
+
<template>
|
|
79
|
+
<Slider v-model="value" :step="25" />
|
|
80
|
+
</template>
|
|
81
|
+
`.trim(),
|
|
82
|
+
},
|
|
83
|
+
},
|
|
84
|
+
},
|
|
62
85
|
render: () => ({
|
|
63
86
|
components: { Slider },
|
|
64
87
|
setup () {
|
|
@@ -75,7 +98,18 @@ export const WithStep: Story = {
|
|
|
75
98
|
}
|
|
76
99
|
|
|
77
100
|
export const CustomMinMax: Story = {
|
|
78
|
-
parameters:
|
|
101
|
+
parameters: {
|
|
102
|
+
...noControls,
|
|
103
|
+
docs: {
|
|
104
|
+
source: {
|
|
105
|
+
code: `
|
|
106
|
+
<template>
|
|
107
|
+
<Slider v-model="value" :min="0" :max="1000" />
|
|
108
|
+
</template>
|
|
109
|
+
`.trim(),
|
|
110
|
+
},
|
|
111
|
+
},
|
|
112
|
+
},
|
|
79
113
|
render: () => ({
|
|
80
114
|
components: { Slider },
|
|
81
115
|
setup () {
|
|
@@ -92,7 +126,18 @@ export const CustomMinMax: Story = {
|
|
|
92
126
|
}
|
|
93
127
|
|
|
94
128
|
export const Disabled: Story = {
|
|
95
|
-
parameters:
|
|
129
|
+
parameters: {
|
|
130
|
+
...noControls,
|
|
131
|
+
docs: {
|
|
132
|
+
source: {
|
|
133
|
+
code: `
|
|
134
|
+
<template>
|
|
135
|
+
<Slider v-model="value" disabled />
|
|
136
|
+
</template>
|
|
137
|
+
`.trim(),
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
},
|
|
96
141
|
render: () => ({
|
|
97
142
|
components: { Slider },
|
|
98
143
|
setup () {
|
|
@@ -106,3 +151,21 @@ export const Disabled: Story = {
|
|
|
106
151
|
`,
|
|
107
152
|
}),
|
|
108
153
|
}
|
|
154
|
+
|
|
155
|
+
export const EventHandling: Story = {
|
|
156
|
+
parameters: noControls,
|
|
157
|
+
render: () => ({
|
|
158
|
+
components: { Slider, EventLog },
|
|
159
|
+
setup: () => ({ value: ref(50) }),
|
|
160
|
+
template: `
|
|
161
|
+
<EventLog v-slot="{ record }">
|
|
162
|
+
<div class="max-w-sm">
|
|
163
|
+
<Slider
|
|
164
|
+
v-model="value"
|
|
165
|
+
@update:modelValue="(v) => record('update:modelValue', v)"
|
|
166
|
+
/>
|
|
167
|
+
</div>
|
|
168
|
+
</EventLog>
|
|
169
|
+
`,
|
|
170
|
+
}),
|
|
171
|
+
}
|
|
@@ -11,10 +11,14 @@ const meta = {
|
|
|
11
11
|
argTypes: {
|
|
12
12
|
color: { control: 'select', options: colors },
|
|
13
13
|
variant: { control: 'select', options: variants },
|
|
14
|
+
active: { control: 'boolean' },
|
|
15
|
+
selectable: { control: 'boolean' },
|
|
14
16
|
},
|
|
15
17
|
args: {
|
|
16
18
|
color: 'default',
|
|
17
19
|
variant: 'soft',
|
|
20
|
+
active: false,
|
|
21
|
+
selectable: false,
|
|
18
22
|
},
|
|
19
23
|
render: args => ({
|
|
20
24
|
components: { Surface },
|
|
@@ -31,7 +35,22 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
|
|
|
31
35
|
export const Default: Story = {}
|
|
32
36
|
|
|
33
37
|
export const Colors: Story = {
|
|
34
|
-
parameters:
|
|
38
|
+
parameters: {
|
|
39
|
+
...noControls,
|
|
40
|
+
docs: {
|
|
41
|
+
source: {
|
|
42
|
+
code: `
|
|
43
|
+
<template>
|
|
44
|
+
<div class="grid grid-cols-2 gap-3 md:grid-cols-3">
|
|
45
|
+
<Surface v-for="c in colors" :key="c" :color="c" class="p-4">
|
|
46
|
+
<strong>{{ c }}</strong> surface
|
|
47
|
+
</Surface>
|
|
48
|
+
</div>
|
|
49
|
+
</template>
|
|
50
|
+
`.trim(),
|
|
51
|
+
},
|
|
52
|
+
},
|
|
53
|
+
},
|
|
35
54
|
render: () => ({
|
|
36
55
|
components: { Surface },
|
|
37
56
|
setup: () => ({ colors }),
|
|
@@ -46,7 +65,22 @@ export const Colors: Story = {
|
|
|
46
65
|
}
|
|
47
66
|
|
|
48
67
|
export const Variants: Story = {
|
|
49
|
-
parameters:
|
|
68
|
+
parameters: {
|
|
69
|
+
...noControls,
|
|
70
|
+
docs: {
|
|
71
|
+
source: {
|
|
72
|
+
code: `
|
|
73
|
+
<template>
|
|
74
|
+
<div class="grid grid-cols-2 gap-3 md:grid-cols-4">
|
|
75
|
+
<Surface v-for="v in variants" :key="v" :variant="v" class="p-4">
|
|
76
|
+
<strong>{{ v }}</strong> surface
|
|
77
|
+
</Surface>
|
|
78
|
+
</div>
|
|
79
|
+
</template>
|
|
80
|
+
`.trim(),
|
|
81
|
+
},
|
|
82
|
+
},
|
|
83
|
+
},
|
|
50
84
|
render: () => ({
|
|
51
85
|
components: { Surface },
|
|
52
86
|
setup: () => ({ variants }),
|
|
@@ -61,16 +95,63 @@ export const Variants: Story = {
|
|
|
61
95
|
}
|
|
62
96
|
|
|
63
97
|
export const VariantColorMatrix: Story = {
|
|
64
|
-
parameters:
|
|
98
|
+
parameters: {
|
|
99
|
+
...noControls,
|
|
100
|
+
docs: {
|
|
101
|
+
source: {
|
|
102
|
+
code: `
|
|
103
|
+
<template>
|
|
104
|
+
<div class="space-y-6">
|
|
105
|
+
<div v-for="v in variants" :key="v">
|
|
106
|
+
<div class="mb-2 text-sm text-muted-foreground">{{ v }}</div>
|
|
107
|
+
<div class="grid grid-cols-2 gap-3 md:grid-cols-3">
|
|
108
|
+
<Surface
|
|
109
|
+
v-for="c in colors"
|
|
110
|
+
:key="c"
|
|
111
|
+
:variant="v"
|
|
112
|
+
:color="c"
|
|
113
|
+
selectable
|
|
114
|
+
:active="selected === keyFor(v, c)"
|
|
115
|
+
class="p-4"
|
|
116
|
+
@click="selected = keyFor(v, c)"
|
|
117
|
+
>
|
|
118
|
+
<strong>{{ c }}</strong> surface
|
|
119
|
+
</Surface>
|
|
120
|
+
</div>
|
|
121
|
+
</div>
|
|
122
|
+
</div>
|
|
123
|
+
</template>
|
|
124
|
+
|
|
125
|
+
<script setup lang="ts">
|
|
126
|
+
const selected = ref('')
|
|
127
|
+
const keyFor = (v: string, c: string) => \`\${v}:\${c}\`
|
|
128
|
+
</script>
|
|
129
|
+
`.trim(),
|
|
130
|
+
},
|
|
131
|
+
},
|
|
132
|
+
},
|
|
65
133
|
render: () => ({
|
|
66
134
|
components: { Surface },
|
|
67
|
-
setup
|
|
135
|
+
setup () {
|
|
136
|
+
const selected = ref('')
|
|
137
|
+
const keyFor = (v: string, c: string) => `${v}:${c}`
|
|
138
|
+
return { colors, variants, selected, keyFor }
|
|
139
|
+
},
|
|
68
140
|
template: `
|
|
69
141
|
<div class="space-y-6">
|
|
70
142
|
<div v-for="v in variants" :key="v">
|
|
71
143
|
<div class="mb-2 text-sm text-muted-foreground">{{ v }}</div>
|
|
72
144
|
<div class="grid grid-cols-2 gap-3 md:grid-cols-3">
|
|
73
|
-
<Surface
|
|
145
|
+
<Surface
|
|
146
|
+
v-for="c in colors"
|
|
147
|
+
:key="c"
|
|
148
|
+
:variant="v"
|
|
149
|
+
:color="c"
|
|
150
|
+
selectable
|
|
151
|
+
:active="selected === keyFor(v, c)"
|
|
152
|
+
class="p-4"
|
|
153
|
+
@click="selected = keyFor(v, c)"
|
|
154
|
+
>
|
|
74
155
|
<strong>{{ c }}</strong> surface
|
|
75
156
|
</Surface>
|
|
76
157
|
</div>
|
|
@@ -21,11 +21,19 @@ const surfaceVariants = cva(
|
|
|
21
21
|
warn: '',
|
|
22
22
|
danger: '',
|
|
23
23
|
},
|
|
24
|
+
active: {
|
|
25
|
+
true: 'ring-[3px]',
|
|
26
|
+
false: '',
|
|
27
|
+
},
|
|
28
|
+
selectable: {
|
|
29
|
+
true: 'cursor-pointer transition-colors',
|
|
30
|
+
false: '',
|
|
31
|
+
},
|
|
24
32
|
},
|
|
25
33
|
compoundVariants: [
|
|
26
34
|
// solid — full color background
|
|
27
35
|
{ variant: 'solid', color: 'default', class: `
|
|
28
|
-
|
|
36
|
+
bg-accent text-accent-foreground border-transparent
|
|
29
37
|
` },
|
|
30
38
|
{ variant: 'solid', color: 'primary', class: `
|
|
31
39
|
border-primary bg-primary text-primary-foreground
|
|
@@ -93,10 +101,105 @@ const surfaceVariants = cva(
|
|
|
93
101
|
{ variant: 'flat', color: 'help', class: 'bg-help/10 text-help' },
|
|
94
102
|
{ variant: 'flat', color: 'warn', class: 'bg-warn/10 text-warn' },
|
|
95
103
|
{ variant: 'flat', color: 'danger', class: 'bg-danger/10 text-danger' },
|
|
104
|
+
// active — color-matched border + soft ring (mirrors Input focus)
|
|
105
|
+
{ active: true, color: 'default', class: 'border-ring ring-ring/50' },
|
|
106
|
+
{ active: true, color: 'primary', class: 'border-primary ring-primary/50' },
|
|
107
|
+
{ active: true, color: 'success', class: 'border-success ring-success/50' },
|
|
108
|
+
{ active: true, color: 'info', class: 'border-info ring-info/50' },
|
|
109
|
+
{ active: true, color: 'help', class: 'border-help ring-help/50' },
|
|
110
|
+
{ active: true, color: 'warn', class: 'border-warn ring-warn/50' },
|
|
111
|
+
{ active: true, color: 'danger', class: 'border-danger ring-danger/50' },
|
|
112
|
+
// selectable — hover bg, one step up the variant's intensity ladder
|
|
113
|
+
{ selectable: true, variant: 'solid', color: 'default', class: `
|
|
114
|
+
hover:bg-accent/80
|
|
115
|
+
` },
|
|
116
|
+
{ selectable: true, variant: 'solid', color: 'primary', class: `
|
|
117
|
+
hover:bg-primary/90
|
|
118
|
+
` },
|
|
119
|
+
{ selectable: true, variant: 'solid', color: 'success', class: `
|
|
120
|
+
hover:bg-success/90
|
|
121
|
+
` },
|
|
122
|
+
{ selectable: true, variant: 'solid', color: 'info', class: `
|
|
123
|
+
hover:bg-info/90
|
|
124
|
+
` },
|
|
125
|
+
{ selectable: true, variant: 'solid', color: 'help', class: `
|
|
126
|
+
hover:bg-help/90
|
|
127
|
+
` },
|
|
128
|
+
{ selectable: true, variant: 'solid', color: 'warn', class: `
|
|
129
|
+
hover:bg-warn/90
|
|
130
|
+
` },
|
|
131
|
+
{ selectable: true, variant: 'solid', color: 'danger', class: `
|
|
132
|
+
hover:bg-danger/90
|
|
133
|
+
` },
|
|
134
|
+
{ selectable: true, variant: 'soft', color: 'default', class: `
|
|
135
|
+
hover:bg-secondary/70
|
|
136
|
+
` },
|
|
137
|
+
{ selectable: true, variant: 'soft', color: 'primary', class: `
|
|
138
|
+
hover:bg-primary/20
|
|
139
|
+
` },
|
|
140
|
+
{ selectable: true, variant: 'soft', color: 'success', class: `
|
|
141
|
+
hover:bg-success/20
|
|
142
|
+
` },
|
|
143
|
+
{ selectable: true, variant: 'soft', color: 'info', class: `
|
|
144
|
+
hover:bg-info/20
|
|
145
|
+
` },
|
|
146
|
+
{ selectable: true, variant: 'soft', color: 'help', class: `
|
|
147
|
+
hover:bg-help/20
|
|
148
|
+
` },
|
|
149
|
+
{ selectable: true, variant: 'soft', color: 'warn', class: `
|
|
150
|
+
hover:bg-warn/20
|
|
151
|
+
` },
|
|
152
|
+
{ selectable: true, variant: 'soft', color: 'danger', class: `
|
|
153
|
+
hover:bg-danger/20
|
|
154
|
+
` },
|
|
155
|
+
{ selectable: true, variant: 'bordered', color: 'default', class: `
|
|
156
|
+
hover:bg-accent
|
|
157
|
+
` },
|
|
158
|
+
{ selectable: true, variant: 'bordered', color: 'primary', class: `
|
|
159
|
+
hover:bg-primary/10
|
|
160
|
+
` },
|
|
161
|
+
{ selectable: true, variant: 'bordered', color: 'success', class: `
|
|
162
|
+
hover:bg-success/10
|
|
163
|
+
` },
|
|
164
|
+
{ selectable: true, variant: 'bordered', color: 'info', class: `
|
|
165
|
+
hover:bg-info/10
|
|
166
|
+
` },
|
|
167
|
+
{ selectable: true, variant: 'bordered', color: 'help', class: `
|
|
168
|
+
hover:bg-help/10
|
|
169
|
+
` },
|
|
170
|
+
{ selectable: true, variant: 'bordered', color: 'warn', class: `
|
|
171
|
+
hover:bg-warn/10
|
|
172
|
+
` },
|
|
173
|
+
{ selectable: true, variant: 'bordered', color: 'danger', class: `
|
|
174
|
+
hover:bg-danger/10
|
|
175
|
+
` },
|
|
176
|
+
{ selectable: true, variant: 'flat', color: 'default', class: `
|
|
177
|
+
hover:bg-secondary/70
|
|
178
|
+
` },
|
|
179
|
+
{ selectable: true, variant: 'flat', color: 'primary', class: `
|
|
180
|
+
hover:bg-primary/20
|
|
181
|
+
` },
|
|
182
|
+
{ selectable: true, variant: 'flat', color: 'success', class: `
|
|
183
|
+
hover:bg-success/20
|
|
184
|
+
` },
|
|
185
|
+
{ selectable: true, variant: 'flat', color: 'info', class: `
|
|
186
|
+
hover:bg-info/20
|
|
187
|
+
` },
|
|
188
|
+
{ selectable: true, variant: 'flat', color: 'help', class: `
|
|
189
|
+
hover:bg-help/20
|
|
190
|
+
` },
|
|
191
|
+
{ selectable: true, variant: 'flat', color: 'warn', class: `
|
|
192
|
+
hover:bg-warn/20
|
|
193
|
+
` },
|
|
194
|
+
{ selectable: true, variant: 'flat', color: 'danger', class: `
|
|
195
|
+
hover:bg-danger/20
|
|
196
|
+
` },
|
|
96
197
|
],
|
|
97
198
|
defaultVariants: {
|
|
98
199
|
variant: 'soft',
|
|
99
200
|
color: 'default',
|
|
201
|
+
active: false,
|
|
202
|
+
selectable: false,
|
|
100
203
|
},
|
|
101
204
|
},
|
|
102
205
|
)
|
|
@@ -104,11 +207,21 @@ const surfaceVariants = cva(
|
|
|
104
207
|
const props = withDefaults(defineProps<SurfaceProps>(), {
|
|
105
208
|
color: 'default',
|
|
106
209
|
variant: 'soft',
|
|
210
|
+
active: false,
|
|
211
|
+
selectable: false,
|
|
107
212
|
class: undefined,
|
|
108
213
|
})
|
|
109
214
|
|
|
110
215
|
const mergedClass = computed(() =>
|
|
111
|
-
cn(
|
|
216
|
+
cn(
|
|
217
|
+
surfaceVariants({
|
|
218
|
+
color: props.color,
|
|
219
|
+
variant: props.variant,
|
|
220
|
+
active: props.active,
|
|
221
|
+
selectable: props.selectable,
|
|
222
|
+
}),
|
|
223
|
+
props.class,
|
|
224
|
+
),
|
|
112
225
|
)
|
|
113
226
|
</script>
|
|
114
227
|
|