@polymarbot/nuxt-layer-shadcn-ui 0.3.10 → 0.4.1

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.
Files changed (61) hide show
  1. package/app/components/ui/Accordion/index.stories.ts +43 -15
  2. package/app/components/ui/AdminLayout/index.stories.ts +6 -14
  3. package/app/components/ui/Alert/index.stories.ts +32 -2
  4. package/app/components/ui/AlertDialog/index.stories.ts +114 -5
  5. package/app/components/ui/AsyncDataTable/index.stories.ts +36 -2
  6. package/app/components/ui/Avatar/index.stories.ts +58 -4
  7. package/app/components/ui/Badge/index.stories.ts +48 -3
  8. package/app/components/ui/Breadcrumb/index.stories.ts +8 -19
  9. package/app/components/ui/Button/index.stories.ts +116 -7
  10. package/app/components/ui/ButtonGroup/index.stories.ts +63 -4
  11. package/app/components/ui/Card/index.stories.ts +40 -14
  12. package/app/components/ui/Checkbox/index.stories.ts +53 -3
  13. package/app/components/ui/CopyButton/index.stories.ts +77 -5
  14. package/app/components/ui/DataTable/index.stories.ts +184 -11
  15. package/app/components/ui/DatePicker/index.stories.ts +56 -7
  16. package/app/components/ui/DateRangePicker/index.stories.ts +40 -5
  17. package/app/components/ui/Divider/index.stories.ts +18 -15
  18. package/app/components/ui/Drawer/index.stories.ts +115 -16
  19. package/app/components/ui/Drawer/index.vue +27 -12
  20. package/app/components/ui/Dropdown/index.stories.ts +72 -54
  21. package/app/components/ui/Dropdown/index.vue +5 -8
  22. package/app/components/ui/Dropdown/types.ts +3 -8
  23. package/app/components/ui/FormItem/index.stories.ts +33 -45
  24. package/app/components/ui/Help/index.stories.ts +34 -2
  25. package/app/components/ui/Icon/index.stories.ts +41 -2
  26. package/app/components/ui/Input/index.stories.ts +73 -14
  27. package/app/components/ui/InputCurrency/index.stories.ts +20 -65
  28. package/app/components/ui/InputNumber/index.stories.ts +31 -58
  29. package/app/components/ui/InputOtp/index.stories.ts +41 -9
  30. package/app/components/ui/InputPercent/index.stories.ts +3 -7
  31. package/app/components/ui/InputRange/index.stories.ts +51 -4
  32. package/app/components/ui/Loading/index.stories.ts +16 -1
  33. package/app/components/ui/Markdown/index.stories.ts +9 -0
  34. package/app/components/ui/Modal/index.stories.ts +133 -16
  35. package/app/components/ui/Modal/index.vue +27 -12
  36. package/app/components/ui/ModalContent/index.stories.ts +35 -11
  37. package/app/components/ui/PageCard/index.stories.ts +154 -56
  38. package/app/components/ui/Pagination/index.stories.ts +79 -18
  39. package/app/components/ui/Pagination/index.vue +4 -1
  40. package/app/components/ui/Popover/index.stories.ts +73 -3
  41. package/app/components/ui/Popover/index.vue +67 -4
  42. package/app/components/ui/Popover/types.ts +5 -2
  43. package/app/components/ui/Qrcode/index.stories.ts +32 -2
  44. package/app/components/ui/RadioCardGroup/index.stories.ts +45 -6
  45. package/app/components/ui/RadioGroup/index.stories.ts +64 -35
  46. package/app/components/ui/ScrollArea/index.stories.ts +21 -23
  47. package/app/components/ui/SearchSelect/index.stories.ts +73 -24
  48. package/app/components/ui/Select/index.stories.ts +121 -6
  49. package/app/components/ui/Skeleton/index.stories.ts +34 -2
  50. package/app/components/ui/Slider/index.stories.ts +67 -4
  51. package/app/components/ui/Surface/index.stories.ts +86 -5
  52. package/app/components/ui/Surface/index.vue +115 -2
  53. package/app/components/ui/Surface/types.ts +2 -0
  54. package/app/components/ui/Switch/index.stories.ts +46 -0
  55. package/app/components/ui/Tabs/index.stories.ts +61 -47
  56. package/app/components/ui/Tag/index.stories.ts +45 -3
  57. package/app/components/ui/Textarea/index.stories.ts +61 -15
  58. package/app/components/ui/Toast/index.stories.ts +77 -3
  59. package/app/components/ui/Tooltip/index.stories.ts +60 -2
  60. package/app/components/ui/WebLink/index.stories.ts +53 -15
  61. package/package.json +2 -2
@@ -6,15 +6,78 @@ import {
6
6
  } from '../../shadcn/popover'
7
7
  import type { PopoverProps } from './types'
8
8
 
9
- const props = defineProps<PopoverProps>()
9
+ defineOptions({ inheritAttrs: false })
10
+
11
+ const props = withDefaults(defineProps<PopoverProps>(), {
12
+ trigger: 'click',
13
+ class: undefined,
14
+ })
15
+
16
+ const { isMobile } = useDevice()
17
+
18
+ // Force click trigger on mobile devices for better touch experience
19
+ const effectiveTrigger = computed(() => isMobile.value ? 'click' : props.trigger)
20
+
21
+ const isOpen = ref(false)
22
+ let hideTimeout: ReturnType<typeof setTimeout> | null = null
23
+
24
+ const clearHideTimeout = () => {
25
+ if (hideTimeout) {
26
+ clearTimeout(hideTimeout)
27
+ hideTimeout = null
28
+ }
29
+ }
30
+
31
+ const hide = () => {
32
+ isOpen.value = false
33
+ }
34
+
35
+ const handleTriggerEnter = () => {
36
+ if (effectiveTrigger.value === 'hover') {
37
+ clearHideTimeout()
38
+ isOpen.value = true
39
+ }
40
+ }
41
+
42
+ const handleTriggerLeave = () => {
43
+ if (effectiveTrigger.value === 'hover') {
44
+ hideTimeout = setTimeout(hide, 100)
45
+ }
46
+ }
47
+
48
+ const handleContentEnter = () => {
49
+ if (effectiveTrigger.value === 'hover') {
50
+ clearHideTimeout()
51
+ }
52
+ }
53
+
54
+ const handleContentLeave = () => {
55
+ if (effectiveTrigger.value === 'hover') {
56
+ hideTimeout = setTimeout(hide, 100)
57
+ }
58
+ }
59
+
60
+ onBeforeUnmount(() => {
61
+ clearHideTimeout()
62
+ })
10
63
  </script>
11
64
 
12
65
  <template>
13
- <ShadcnPopover>
14
- <PopoverTrigger asChild>
66
+ <ShadcnPopover v-model:open="isOpen">
67
+ <PopoverTrigger
68
+ v-if="$slots.trigger"
69
+ asChild
70
+ @mouseenter="handleTriggerEnter"
71
+ @mouseleave="handleTriggerLeave"
72
+ >
15
73
  <slot name="trigger" />
16
74
  </PopoverTrigger>
17
- <PopoverContent :class="props.class">
75
+ <PopoverContent
76
+ v-bind="$attrs"
77
+ :class="props.class"
78
+ @mouseenter="handleContentEnter"
79
+ @mouseleave="handleContentLeave"
80
+ >
18
81
  <slot />
19
82
  </PopoverContent>
20
83
  </ShadcnPopover>
@@ -1,5 +1,8 @@
1
- import type { PopoverRootProps } from 'reka-ui'
1
+ import type { PopoverContentProps } from 'reka-ui'
2
2
 
3
- export interface PopoverProps extends /* @vue-ignore */ PopoverRootProps {
3
+ export interface PopoverProps extends /* @vue-ignore */ PopoverContentProps {
4
+ /** Trigger mode for showing the popover. Defaults to 'click'. */
5
+ trigger?: 'click' | 'hover'
6
+ /** Extra class for the popover content container. */
4
7
  class?: ClassValue
5
8
  }
@@ -29,7 +29,21 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
29
29
  export const Default: Story = {}
30
30
 
31
31
  export const DynamicContent: Story = {
32
- parameters: noControls,
32
+ parameters: {
33
+ ...noControls,
34
+ docs: {
35
+ source: {
36
+ code: `
37
+ <template>
38
+ <input v-model="url" placeholder="Enter URL or text" />
39
+ <div class="size-48">
40
+ <Qrcode :content="url" />
41
+ </div>
42
+ </template>
43
+ `.trim(),
44
+ },
45
+ },
46
+ },
33
47
  render: () => ({
34
48
  components: { Qrcode },
35
49
  setup () {
@@ -52,7 +66,23 @@ export const DynamicContent: Story = {
52
66
  }
53
67
 
54
68
  export const Sizes: Story = {
55
- parameters: noControls,
69
+ parameters: {
70
+ ...noControls,
71
+ docs: {
72
+ source: {
73
+ code: `
74
+ <template>
75
+ <div class="size-24">
76
+ <Qrcode content="https://example.com/small" />
77
+ </div>
78
+ <div class="size-48">
79
+ <Qrcode content="https://example.com/medium" />
80
+ </div>
81
+ </template>
82
+ `.trim(),
83
+ },
84
+ },
85
+ },
56
86
  render: () => ({
57
87
  components: { Qrcode },
58
88
  template: `
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import EventLog from '#storybook/EventLog.vue'
2
3
  import type { RadioCardGroupOption } from './types'
3
4
  import RadioCardGroup from './index.vue'
4
5
 
@@ -70,7 +71,18 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
70
71
  export const Default: Story = {}
71
72
 
72
73
  export const WithDisabledOption: Story = {
73
- parameters: noControls,
74
+ parameters: {
75
+ ...noControls,
76
+ docs: {
77
+ source: {
78
+ code: `
79
+ <template>
80
+ <RadioCardGroup v-model="selected" :options="planOptions" />
81
+ </template>
82
+ `.trim(),
83
+ },
84
+ },
85
+ },
74
86
  render: () => ({
75
87
  components: { RadioCardGroup },
76
88
  setup () {
@@ -88,17 +100,44 @@ export const WithDisabledOption: Story = {
88
100
 
89
101
  export const Disabled: Story = {
90
102
  parameters: noControls,
103
+ args: {
104
+ disabled: true,
105
+ },
106
+ }
107
+
108
+ export const EventHandling: Story = {
109
+ parameters: {
110
+ ...noControls,
111
+ docs: {
112
+ source: {
113
+ code: `
114
+ <template>
115
+ <RadioCardGroup
116
+ v-model="selected"
117
+ :options="options"
118
+ @update:modelValue="onUpdate"
119
+ />
120
+ </template>
121
+ `.trim(),
122
+ },
123
+ },
124
+ },
91
125
  render: () => ({
92
- components: { RadioCardGroup },
126
+ components: { RadioCardGroup, EventLog },
93
127
  setup () {
94
128
  const selected = ref('current')
95
129
  return { selected, options }
96
130
  },
97
131
  template: `
98
- <div class="max-w-md space-y-4">
99
- <RadioCardGroup v-model="selected" :options="options" disabled />
100
- <div class="text-sm text-muted-foreground">Selected: {{ selected }}</div>
101
- </div>
132
+ <EventLog v-slot="{ record }">
133
+ <div class="max-w-md">
134
+ <RadioCardGroup
135
+ v-model="selected"
136
+ :options="options"
137
+ @update:modelValue="(v) => record('update:modelValue', v)"
138
+ />
139
+ </div>
140
+ </EventLog>
102
141
  `,
103
142
  }),
104
143
  }
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import EventLog from '#storybook/EventLog.vue'
2
3
  import type { RadioGroupItem } from './types'
3
4
  import RadioGroup from './index.vue'
4
5
 
@@ -45,52 +46,45 @@ export const Default: Story = {}
45
46
 
46
47
  export const Horizontal: Story = {
47
48
  parameters: noControls,
48
- render: () => ({
49
- components: { RadioGroup },
50
- setup () {
51
- const selected = ref('option1')
52
- return { options, selected }
53
- },
54
- template: `
55
- <div class="space-y-2">
56
- <RadioGroup v-model="selected" :items="options" orientation="horizontal" />
57
- <div class="text-sm text-muted-foreground">Selected: {{ selected }}</div>
58
- </div>
59
- `,
60
- }),
49
+ args: {
50
+ orientation: 'horizontal',
51
+ },
61
52
  }
62
53
 
63
54
  export const WithDisabledItem: Story = {
64
55
  parameters: noControls,
65
- render: () => ({
66
- components: { RadioGroup },
67
- setup () {
68
- const plan = ref('pro')
69
- return { plans, plan }
70
- },
71
- template: `
72
- <div class="space-y-2">
73
- <RadioGroup v-model="plan" :items="plans" />
74
- <div class="text-sm text-muted-foreground">Plan: {{ plan }}</div>
75
- </div>
76
- `,
77
- }),
56
+ args: {
57
+ items: plans,
58
+ modelValue: 'pro',
59
+ },
78
60
  }
79
61
 
80
62
  export const Disabled: Story = {
81
63
  parameters: noControls,
82
- render: () => ({
83
- components: { RadioGroup },
84
- setup () {
85
- const selected = ref('option1')
86
- return { options, selected }
87
- },
88
- template: '<RadioGroup v-model="selected" :items="options" disabled />',
89
- }),
64
+ args: {
65
+ disabled: true,
66
+ },
90
67
  }
91
68
 
92
69
  export const CustomSlots: Story = {
93
- parameters: noControls,
70
+ parameters: {
71
+ ...noControls,
72
+ docs: {
73
+ source: {
74
+ code: `
75
+ <template>
76
+ <RadioGroup v-model="plan" :items="plans">
77
+ <template #label="{ item, checked }">
78
+ <span :class="checked ? 'font-semibold text-primary' : 'text-foreground'">
79
+ {{ item.label }}
80
+ </span>
81
+ </template>
82
+ </RadioGroup>
83
+ </template>
84
+ `.trim(),
85
+ },
86
+ },
87
+ },
94
88
  render: () => ({
95
89
  components: { RadioGroup },
96
90
  setup () {
@@ -111,3 +105,38 @@ export const CustomSlots: Story = {
111
105
  `,
112
106
  }),
113
107
  }
108
+
109
+ export const EventHandling: Story = {
110
+ parameters: {
111
+ ...noControls,
112
+ docs: {
113
+ source: {
114
+ code: `
115
+ <template>
116
+ <RadioGroup
117
+ v-model="selected"
118
+ :items="options"
119
+ @update:modelValue="onUpdate"
120
+ />
121
+ </template>
122
+ `.trim(),
123
+ },
124
+ },
125
+ },
126
+ render: () => ({
127
+ components: { RadioGroup, EventLog },
128
+ setup () {
129
+ const selected = ref('option1')
130
+ return { options, selected }
131
+ },
132
+ template: `
133
+ <EventLog v-slot="{ record }">
134
+ <RadioGroup
135
+ v-model="selected"
136
+ :items="options"
137
+ @update:modelValue="(v) => record('update:modelValue', v)"
138
+ />
139
+ </EventLog>
140
+ `,
141
+ }),
142
+ }
@@ -51,32 +51,30 @@ export const Default: Story = {}
51
51
 
52
52
  export const FadeMask: Story = {
53
53
  parameters: noControls,
54
- render: () => ({
55
- components: { ScrollArea },
56
- setup () {
57
- const items = Array.from({ length: 30 }, (_, i) => `Item ${i + 1}`)
58
- return { items }
59
- },
60
- template: `
61
- <div class="h-[250px] w-[250px] rounded-md border bg-card">
62
- <ScrollArea class="h-full" fadeMask>
63
- <div class="p-4 space-y-2">
64
- <div
65
- v-for="item in items"
66
- :key="item"
67
- class="rounded-md border bg-muted px-3 py-2 text-sm"
68
- >
69
- {{ item }}
70
- </div>
71
- </div>
72
- </ScrollArea>
73
- </div>
74
- `,
75
- }),
54
+ args: {
55
+ fadeMask: true,
56
+ },
76
57
  }
77
58
 
78
59
  export const NoOverflow: Story = {
79
- parameters: noControls,
60
+ parameters: {
61
+ ...noControls,
62
+ docs: {
63
+ source: {
64
+ code: `
65
+ <template>
66
+ <ScrollArea class="h-full" fadeMask>
67
+ <div class="p-4 space-y-2">
68
+ <div v-for="item in fewItems" :key="item" class="rounded-md border bg-muted px-3 py-2 text-sm">
69
+ {{ item }}
70
+ </div>
71
+ </div>
72
+ </ScrollArea>
73
+ </template>
74
+ `.trim(),
75
+ },
76
+ },
77
+ },
80
78
  render: () => ({
81
79
  components: { ScrollArea },
82
80
  setup () {
@@ -1,4 +1,5 @@
1
1
  import type { Meta, StoryObj } from '@storybook/vue3'
2
+ import EventLog from '#storybook/EventLog.vue'
2
3
  import type { SearchSelectLoadMethodParams, SearchSelectLoadMethodResult } from './types'
3
4
  import SearchSelect from './index.vue'
4
5
 
@@ -88,7 +89,23 @@ const noControls = { controls: { disable: true }} satisfies Story['parameters']
88
89
  export const Default: Story = {}
89
90
 
90
91
  export const Preselected: Story = {
91
- parameters: noControls,
92
+ parameters: {
93
+ ...noControls,
94
+ docs: {
95
+ source: {
96
+ code: `
97
+ <template>
98
+ <SearchSelect
99
+ v-model="value"
100
+ :loadMethod="loadMethod"
101
+ :loadValueOptionMethod="loadValueOptionMethod"
102
+ autoLoad
103
+ />
104
+ </template>
105
+ `.trim(),
106
+ },
107
+ },
108
+ },
92
109
  render: () => ({
93
110
  components: { SearchSelect },
94
111
  setup () {
@@ -110,7 +127,23 @@ export const Preselected: Story = {
110
127
  }
111
128
 
112
129
  export const WithDefaultOptions: Story = {
113
- parameters: noControls,
130
+ parameters: {
131
+ ...noControls,
132
+ docs: {
133
+ source: {
134
+ code: `
135
+ <template>
136
+ <SearchSelect
137
+ v-model="value"
138
+ :loadMethod="loadMethod"
139
+ :defaultOptions="defaultOptions"
140
+ autoLoad
141
+ />
142
+ </template>
143
+ `.trim(),
144
+ },
145
+ },
146
+ },
114
147
  render: () => ({
115
148
  components: { SearchSelect },
116
149
  setup () {
@@ -133,38 +166,54 @@ export const WithDefaultOptions: Story = {
133
166
 
134
167
  export const WithCreateNew: Story = {
135
168
  parameters: noControls,
136
- render: () => ({
137
- components: { SearchSelect },
138
- setup () {
139
- const value = ref<string>()
140
- return { value, mockLoadMethod }
141
- },
142
- template: `
143
- <div class="max-w-sm">
144
- <SearchSelect
145
- v-model="value"
146
- :loadMethod="mockLoadMethod"
147
- createNewTo="/create"
148
- autoLoad
149
- />
150
- <div class="mt-2 text-sm text-muted-foreground">Selected: {{ value ?? 'none' }}</div>
151
- </div>
152
- `,
153
- }),
169
+ args: {
170
+ createNewTo: '/create',
171
+ autoLoad: true,
172
+ },
154
173
  }
155
174
 
156
175
  export const Disabled: Story = {
157
176
  parameters: noControls,
177
+ args: {
178
+ disabled: true,
179
+ },
180
+ }
181
+
182
+ export const EventHandling: Story = {
183
+ parameters: {
184
+ ...noControls,
185
+ docs: {
186
+ source: {
187
+ code: `
188
+ <template>
189
+ <SearchSelect
190
+ v-model="value"
191
+ :loadMethod="loadMethod"
192
+ autoLoad
193
+ @update:modelValue="onUpdate"
194
+ />
195
+ </template>
196
+ `.trim(),
197
+ },
198
+ },
199
+ },
158
200
  render: () => ({
159
- components: { SearchSelect },
201
+ components: { SearchSelect, EventLog },
160
202
  setup () {
161
203
  const value = ref<string>()
162
204
  return { value, mockLoadMethod }
163
205
  },
164
206
  template: `
165
- <div class="max-w-sm">
166
- <SearchSelect v-model="value" :loadMethod="mockLoadMethod" disabled />
167
- </div>
207
+ <EventLog v-slot="{ record }">
208
+ <div class="max-w-sm">
209
+ <SearchSelect
210
+ v-model="value"
211
+ :loadMethod="mockLoadMethod"
212
+ autoLoad
213
+ @update:modelValue="(v) => record('update:modelValue', v)"
214
+ />
215
+ </div>
216
+ </EventLog>
168
217
  `,
169
218
  }),
170
219
  }
@@ -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: noControls,
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: noControls,
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: noControls,
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: noControls,
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: noControls,
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: noControls,
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
+ }