@catalystsoftware/ui 1.0.2 → 1.0.5

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 (157) hide show
  1. package/data/tailwind.config.js +261 -3821
  2. package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
  3. package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
  4. package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
  5. package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
  6. package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
  7. package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
  8. package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
  9. package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
  10. package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
  11. package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
  12. package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
  13. package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
  14. package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
  15. package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
  16. package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
  17. package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
  18. package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
  19. package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
  20. package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
  21. package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
  22. package/dist/components/catalyst-ui/media/image.tsx +13 -0
  23. package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
  24. package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
  25. package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
  26. package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
  27. package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
  28. package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
  29. package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
  30. package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
  31. package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
  32. package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
  33. package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
  34. package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
  35. package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
  36. package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
  37. package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
  38. package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
  39. package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
  40. package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
  41. package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
  42. package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
  43. package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
  44. package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
  45. package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
  46. package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
  47. package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
  48. package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
  49. package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
  50. package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
  51. package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
  52. package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
  53. package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
  54. package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
  55. package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
  56. package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
  57. package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
  58. package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
  59. package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
  60. package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
  61. package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
  62. package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
  63. package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
  64. package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
  65. package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
  66. package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
  67. package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
  68. package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
  69. package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
  70. package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
  71. package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
  72. package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
  73. package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
  74. package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
  75. package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
  76. package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
  77. package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
  78. package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
  79. package/dist/components/catalyst-ui/utils/utils.ts +43 -0
  80. package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
  81. package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
  82. package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
  83. package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
  84. package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
  85. package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
  86. package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
  87. package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
  88. package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
  89. package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
  90. package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
  91. package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
  92. package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
  93. package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
  94. package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
  95. package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
  96. package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
  97. package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
  98. package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
  99. package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
  100. package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
  101. package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
  102. package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
  103. package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
  104. package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
  105. package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
  106. package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
  107. package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
  108. package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
  109. package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
  110. package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
  111. package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
  112. package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
  113. package/dist/data/bg-data.tsx +901 -0
  114. package/dist/data/buttons-data.tsx +2327 -0
  115. package/dist/data/charts-data.tsx +102 -0
  116. package/dist/data/chat-data.tsx +83 -0
  117. package/dist/data/code-data.tsx +1040 -0
  118. package/dist/data/comboboxes-data.tsx +1843 -0
  119. package/dist/data/command-data.tsx +1381 -0
  120. package/dist/data/core-data.tsx +15953 -0
  121. package/dist/data/crm-data.tsx +47 -0
  122. package/dist/data/data.tsx +159 -0
  123. package/dist/data/date-and-time-data.tsx +554 -0
  124. package/dist/data/dependencies.tsx +7 -0
  125. package/dist/data/ecommerce-data.tsx +1387 -0
  126. package/dist/data/forms-data.tsx +7890 -0
  127. package/dist/data/hooks-data.tsx +5487 -0
  128. package/dist/data/index.ts +34 -0
  129. package/dist/data/inputs-data.tsx +557 -0
  130. package/dist/data/interactive-data.tsx +5394 -0
  131. package/dist/data/lofi-data.tsx +18295 -0
  132. package/dist/data/marketing-data.tsx +2546 -0
  133. package/dist/data/media-data.tsx +1510 -0
  134. package/dist/data/motion-data.tsx +5801 -0
  135. package/dist/data/overlay-data.tsx +4136 -0
  136. package/dist/data/pdf-data.tsx +124 -0
  137. package/dist/data/pos-data.tsx +213 -0
  138. package/dist/data/postcss.config.js +6 -0
  139. package/dist/data/primitive-data.tsx +5170 -0
  140. package/dist/data/prompt-data.tsx +1226 -0
  141. package/dist/data/requiredLibs.ts +4 -0
  142. package/dist/data/sandbox-data.tsx +1 -0
  143. package/dist/data/sidebars-data.tsx +5421 -0
  144. package/dist/data/stacks-data.tsx +32 -0
  145. package/dist/data/table-data.tsx +706 -0
  146. package/dist/data/tailwind.config.js +270 -0
  147. package/dist/data/tailwind.config.ngin.js +3830 -0
  148. package/dist/data/tailwind.css +431 -0
  149. package/dist/data/tools-data.tsx +6910 -0
  150. package/dist/data/typography-data.tsx +2050 -0
  151. package/dist/data/utils-data.tsx +6500 -0
  152. package/dist/data/x-data.tsx +1171 -0
  153. package/dist/data.tsx +159 -0
  154. package/package.json +1 -1
  155. package/dist/index.d.ts +0 -3
  156. package/dist/index.d.ts.map +0 -1
  157. package/dist/index.js.map +0 -362
@@ -0,0 +1,1127 @@
1
+ /**
2
+
3
+
4
+ const SelectNativeDemo = () => {
5
+ const id = useId()
6
+
7
+ return (
8
+ <div className='w-full max-w-xs space-y-2'>
9
+ <Label htmlFor={id}>Native select default</Label>
10
+ <SelectNative id={id}>
11
+ <option value='1'>Male</option>
12
+ <option value='2'>Female</option>
13
+ <option value='3'>Other</option>
14
+ </SelectNative>
15
+ </div>
16
+ )
17
+ }
18
+
19
+ const SelectNativePlaceholderDemo = () => {
20
+ const id = useId()
21
+
22
+ return (
23
+ <div className='w-full max-w-xs space-y-2'>
24
+ <Label htmlFor={id}>Native select with placeholder</Label>
25
+ <SelectNative id={id} defaultValue=''>
26
+ <option value='' disabled>
27
+ Please select a gender
28
+ </option>
29
+ <option value='1'>Male</option>
30
+ <option value='2'>Female</option>
31
+ <option value='3'>Other</option>
32
+ </SelectNative>
33
+ </div>
34
+ )
35
+ }
36
+
37
+ const NativeSelectWithIconDemo = () => {
38
+ const id = useId()
39
+
40
+ return (
41
+ <div className='w-full max-w-xs space-y-2'>
42
+ <Label htmlFor={id}>Native select with icon</Label>
43
+ <div className='group relative'>
44
+ <SelectNative id={id} className='pl-9' defaultValue=''>
45
+ <option value='' disabled>
46
+ Pick your favorite movie
47
+ </option>
48
+ <option value='1'>Godfather</option>
49
+ <option value='2'>A Working Man</option>
50
+ <option value='3'>The Dark Knight</option>
51
+ <option value='4'>Inception</option>
52
+ </SelectNative>
53
+ <div className='text-muted-foreground/80 pointer-events-none absolute inset-y-0 left-0 flex items-center justify-center pl-3 group-has-[select[disabled]]:opacity-50'>
54
+ <FilmIcon size={16} aria-hidden='true' />
55
+ </div>
56
+ </div>
57
+ </div>
58
+ )
59
+ }
60
+
61
+ const NativeSelectWithHelperTextDemo = () => {
62
+ const id = useId()
63
+
64
+ return (
65
+ <div className='w-full max-w-xs space-y-2'>
66
+ <Label htmlFor={id}>Native select with helper text</Label>
67
+ <SelectNative id={id}>
68
+ <option value='1'>Florida</option>
69
+ <option value='2'>California</option>
70
+ <option value='3'>San Francisco</option>
71
+ <option value='4'>Alabama</option>
72
+ </SelectNative>
73
+ <p className='text-muted-foreground mt-2 text-xs' role='region' aria-live='polite'>
74
+ Could you share which city you&apos;re based in?
75
+ </p>
76
+ </div>
77
+ )
78
+ }
79
+
80
+ const NativeSelectWithErrorDemo = () => {
81
+ const id = useId()
82
+
83
+ return (
84
+ <div className='w-full max-w-xs space-y-2'>
85
+ <Label htmlFor={id}>Native select with error</Label>
86
+ <SelectNative id={id} aria-invalid>
87
+ <option value='1'>IST (Indian Standard Time)</option>
88
+ <option value='2'>EST (Eastern Standard Time)</option>
89
+ <option value='3'>PST (Pacific Standard Time)</option>
90
+ <option value='4'>GMT (Greenwich Mean Time)</option>
91
+ </SelectNative>
92
+ <p className='text-destructive mt-2 text-xs' role='alert' aria-live='polite'>
93
+ Selected option is invalid
94
+ </p>
95
+ </div>
96
+ )
97
+ }
98
+
99
+ const NativeSelectRequiredDemo = () => {
100
+ const id = useId()
101
+
102
+ return (
103
+ <div className='w-full max-w-xs space-y-2'>
104
+ <Label htmlFor={id} className='gap-1'>
105
+ Required native select <span className='text-destructive'>*</span>
106
+ </Label>
107
+ <SelectNative id={id} required>
108
+ <option value='1'>Action</option>
109
+ <option value='2'>Comedy</option>
110
+ <option value='3'>Romance</option>
111
+ <option value='4'>Thriller</option>
112
+ </SelectNative>
113
+ </div>
114
+ )
115
+ }
116
+
117
+ const NativeSelectWithOptionGroupsDemo = () => {
118
+ const id = useId()
119
+
120
+ return (
121
+ <div className='w-full max-w-xs space-y-2'>
122
+ <Label htmlFor={id}>Native select with option groups</Label>
123
+ <SelectNative id={id}>
124
+ <optgroup label='Frontend Technologies'>
125
+ <option value='1'>HTML</option>
126
+ <option value='2'>CSS</option>
127
+ <option value='3'>JavaScript</option>
128
+ </optgroup>
129
+ <optgroup label='Backend Technologies'>
130
+ <option value='4'>Node.js</option>
131
+ <option value='5'>Python</option>
132
+ <option value='6'>Java</option>
133
+ </optgroup>
134
+ </SelectNative>
135
+ </div>
136
+ )
137
+ }
138
+
139
+ const NativeSelectWithOverlappingLabelDemo = () => {
140
+ const id = useId()
141
+
142
+ return (
143
+ <div className='group relative w-full max-w-xs'>
144
+ <label
145
+ htmlFor={id}
146
+ className='bg-background text-foreground absolute top-0 left-2 z-10 block -translate-y-1/2 px-1 text-xs font-medium group-has-[select:disabled]:opacity-50'
147
+ >
148
+ Native select with overlapping label
149
+ </label>
150
+ <SelectNative id={id}>
151
+ <option value='1'>Developer</option>
152
+ <option value='2'>Designer</option>
153
+ <option value='3'>Manager</option>
154
+ <option value='4'>QA Engineer</option>
155
+ </SelectNative>
156
+ </div>
157
+ )
158
+ }
159
+
160
+ const NativeSelectWithInsetLabelDemo = () => {
161
+ const id = useId()
162
+
163
+ return (
164
+ <div className='border-input bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative w-full max-w-xs rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-[select:disabled]:cursor-not-allowed has-[select:disabled]:opacity-50 has-[select:is(:disabled)_*]:pointer-events-none'>
165
+ <label htmlFor={id} className='text-foreground block px-3 pt-1 text-xs font-medium'>
166
+ Native select with inset label
167
+ </label>
168
+ <SelectNative
169
+ id={id}
170
+ defaultValue=''
171
+ className='border-none bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0'
172
+ >
173
+ <option value='' disabled>
174
+ Pick your favorite movie
175
+ </option>
176
+ <option value='1'>Interstellar</option>
177
+ <option value='2'>Dune</option>
178
+ <option value='3'>The Matrix</option>
179
+ <option value='4'>Catch Me If You Can</option>
180
+ </SelectNative>
181
+ </div>
182
+ )
183
+ }
184
+
185
+ const SelectDemo = () => {
186
+ const id = useId()
187
+
188
+ return (
189
+ <div className='w-full max-w-xs space-y-2'>
190
+ <Label htmlFor={id}>Default select</Label>
191
+ <Select defaultValue='apple'>
192
+ <SelectTrigger id={id} className='w-full'>
193
+ <SelectValue placeholder='Select a fruit' />
194
+ </SelectTrigger>
195
+ <SelectContent>
196
+ <SelectGroup>
197
+ <SelectLabel>Fruits</SelectLabel>
198
+ <SelectItem value='apple'>Apple</SelectItem>
199
+ <SelectItem value='banana'>Banana</SelectItem>
200
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
201
+ <SelectItem value='grapes'>Grapes</SelectItem>
202
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
203
+ </SelectGroup>
204
+ </SelectContent>
205
+ </Select>
206
+ </div>
207
+ )
208
+ }
209
+
210
+ const SelectPlaceholderDemo = () => {
211
+ const id = useId()
212
+
213
+ return (
214
+ <div className='w-full max-w-xs space-y-2'>
215
+ <Label htmlFor={id}>Select with placeholder</Label>
216
+ <Select>
217
+ <SelectTrigger id={id} className='w-full'>
218
+ <SelectValue placeholder='Select a fruit' />
219
+ </SelectTrigger>
220
+ <SelectContent>
221
+ <SelectGroup>
222
+ <SelectLabel>Fruits</SelectLabel>
223
+ <SelectItem value='apple'>Apple</SelectItem>
224
+ <SelectItem value='banana'>Banana</SelectItem>
225
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
226
+ <SelectItem value='grapes'>Grapes</SelectItem>
227
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
228
+ </SelectGroup>
229
+ </SelectContent>
230
+ </Select>
231
+ </div>
232
+ )
233
+ }
234
+
235
+ const SelectWithIconDemo = () => {
236
+ const id = useId()
237
+
238
+ return (
239
+ <div className='w-full max-w-xs space-y-2'>
240
+ <Label htmlFor={id}>Select with icon</Label>
241
+ <Select defaultValue='god of wars'>
242
+ <SelectTrigger id={id} className='relative w-full pl-9'>
243
+ <div className='text-muted-foreground/80 pointer-events-none absolute inset-y-0 left-0 flex items-center justify-center pl-3 group-has-[select[disabled]]:opacity-50'>
244
+ <FilmIcon size={16} aria-hidden='true' />
245
+ </div>
246
+ <SelectValue placeholder='Select time' />
247
+ </SelectTrigger>
248
+ <SelectContent>
249
+ <SelectItem value='god of wars'>God of Wars</SelectItem>
250
+ <SelectItem value='ghost rider'>Ghost Rider</SelectItem>
251
+ <SelectItem value='the cloth'>The Cloth</SelectItem>
252
+ <SelectItem value='the possession'>The Possession</SelectItem>
253
+ </SelectContent>
254
+ </Select>
255
+ </div>
256
+ )
257
+ }
258
+
259
+ const SelectWithHelperTextDemo = () => {
260
+ const id = useId()
261
+
262
+ return (
263
+ <div className='w-full max-w-xs space-y-2'>
264
+ <Label htmlFor={id}>Select with helper text</Label>
265
+ <Select defaultValue='3'>
266
+ <SelectTrigger id={id} className='w-full'>
267
+ <SelectValue placeholder='Select framework' />
268
+ </SelectTrigger>
269
+ <SelectContent>
270
+ <SelectItem value='1'>Florida</SelectItem>
271
+ <SelectItem value='2'>New York</SelectItem>
272
+ <SelectItem value='3'>California</SelectItem>
273
+ <SelectItem value='4'>Texas</SelectItem>
274
+ </SelectContent>
275
+ </Select>
276
+ <p className='text-muted-foreground mt-2 text-xs' role='region' aria-live='polite'>
277
+ Could you share which city you&apos;re based in?
278
+ </p>
279
+ </div>
280
+ )
281
+ }
282
+
283
+ const SelectInvalidState = () => {
284
+ const id = useId()
285
+
286
+ return (
287
+ <div className='w-full max-w-xs space-y-2'>
288
+ <Label htmlFor={id}>Select with error</Label>
289
+ <Select defaultValue='1'>
290
+ <SelectTrigger id={id} aria-invalid className='w-full'>
291
+ <SelectValue />
292
+ </SelectTrigger>
293
+ <SelectContent>
294
+ <SelectItem value='1'>Tesla</SelectItem>
295
+ <SelectItem value='2'>BMW</SelectItem>
296
+ <SelectItem value='3'>Audi</SelectItem>
297
+ <SelectItem value='4'>Mercedes-Benz</SelectItem>
298
+ </SelectContent>
299
+ </Select>
300
+ <p className='text-destructive mt-2 text-xs' role='alert' aria-live='polite'>
301
+ Selected option is invalid
302
+ </p>
303
+ </div>
304
+ )
305
+ }
306
+
307
+ const SelectSizesDemo = () => {
308
+ return (
309
+ <div className='w-full max-w-xs space-y-2'>
310
+ <Select>
311
+ <SelectTrigger size='sm' className='w-full'>
312
+ <SelectValue placeholder='Small select' />
313
+ </SelectTrigger>
314
+ <SelectContent>
315
+ <SelectGroup>
316
+ <SelectLabel>Fruits</SelectLabel>
317
+ <SelectItem value='apple'>Apple</SelectItem>
318
+ <SelectItem value='banana'>Banana</SelectItem>
319
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
320
+ <SelectItem value='grapes'>Grapes</SelectItem>
321
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
322
+ </SelectGroup>
323
+ </SelectContent>
324
+ </Select>
325
+ <Select>
326
+ <SelectTrigger className='w-full'>
327
+ <SelectValue placeholder='Default select' />
328
+ </SelectTrigger>
329
+ <SelectContent>
330
+ <SelectGroup>
331
+ <SelectLabel>Fruits</SelectLabel>
332
+ <SelectItem value='apple'>Apple</SelectItem>
333
+ <SelectItem value='banana'>Banana</SelectItem>
334
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
335
+ <SelectItem value='grapes'>Grapes</SelectItem>
336
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
337
+ </SelectGroup>
338
+ </SelectContent>
339
+ </Select>
340
+ <Select>
341
+ <SelectTrigger className='!h-10 w-full'>
342
+ <SelectValue placeholder='Large select' />
343
+ </SelectTrigger>
344
+ <SelectContent>
345
+ <SelectGroup>
346
+ <SelectLabel>Fruits</SelectLabel>
347
+ <SelectItem value='apple'>Apple</SelectItem>
348
+ <SelectItem value='banana'>Banana</SelectItem>
349
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
350
+ <SelectItem value='grapes'>Grapes</SelectItem>
351
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
352
+ </SelectGroup>
353
+ </SelectContent>
354
+ </Select>
355
+ </div>
356
+ )
357
+ }
358
+
359
+ const SelectWithColorBorderAndRingDemo = () => {
360
+ const id = useId()
361
+
362
+ return (
363
+ <div className='w-full max-w-xs space-y-2'>
364
+ <Label htmlFor={id}>Select with colored border and ring</Label>
365
+ <Select defaultValue='1'>
366
+ <SelectTrigger
367
+ id={id}
368
+ className='w-full focus-visible:border-indigo-500 focus-visible:ring-indigo-500/20 dark:focus-visible:ring-indigo-500/40'
369
+ >
370
+ <SelectValue placeholder='Select framework' />
371
+ </SelectTrigger>
372
+ <SelectContent>
373
+ <SelectItem value='1'>Electronics</SelectItem>
374
+ <SelectItem value='2'>Clothing</SelectItem>
375
+ <SelectItem value='3'>Home Appliances</SelectItem>
376
+ <SelectItem value='4'>Books</SelectItem>
377
+ </SelectContent>
378
+ </Select>
379
+ </div>
380
+ )
381
+ }
382
+
383
+ const SelectBackgroundColorDemo = () => {
384
+ const id = useId()
385
+
386
+ return (
387
+ <div className='w-full max-w-xs space-y-2'>
388
+ <Label htmlFor={id}>Select with background color</Label>
389
+ <Select defaultValue='hindi'>
390
+ <SelectTrigger className='w-full border-sky-600 bg-sky-600/10 text-sky-600 shadow-none focus-visible:border-sky-600 focus-visible:ring-sky-600/20 dark:bg-sky-400/10 dark:text-sky-400 dark:hover:bg-sky-400/10 dark:focus-visible:ring-sky-400/40 [&_svg]:!text-sky-600 dark:[&_svg]:!text-sky-400'>
391
+ <SelectValue placeholder='Select a fruit' />
392
+ </SelectTrigger>
393
+ <SelectContent>
394
+ <SelectGroup className='[&_div:focus]:bg-sky-600/20 [&_div:focus]:text-sky-600 dark:[&_div:focus]:bg-sky-400/20 dark:[&_div:focus]:text-sky-400'>
395
+ <SelectLabel>Languages</SelectLabel>
396
+ <SelectItem value='hindi' className='focus:[&_svg]:!text-sky-600 dark:focus:[&_svg]:!text-sky-400'>
397
+ Hindi
398
+ </SelectItem>
399
+ <SelectItem value='english' className='focus:[&_svg]:!text-sky-600 dark:focus:[&_svg]:!text-sky-400'>
400
+ English
401
+ </SelectItem>
402
+ <SelectItem value='spanish' className='focus:[&_svg]:!text-sky-600 dark:focus:[&_svg]:!text-sky-400'>
403
+ Spanish
404
+ </SelectItem>
405
+ <SelectItem value='mandarin' className='focus:[&_svg]:!text-sky-600 dark:focus:[&_svg]:!text-sky-400'>
406
+ Mandarin
407
+ </SelectItem>
408
+ <SelectItem value='french' className='focus:[&_svg]:!text-sky-600 dark:focus:[&_svg]:!text-sky-400'>
409
+ French
410
+ </SelectItem>
411
+ </SelectGroup>
412
+ </SelectContent>
413
+ </Select>
414
+ </div>
415
+ )
416
+ }
417
+
418
+ const SelectGhostDemo = () => {
419
+ const id = useId()
420
+
421
+ return (
422
+ <div className='w-full max-w-xs space-y-2'>
423
+ <Label htmlFor={id}>Ghost Select</Label>
424
+ <Select defaultValue='apple'>
425
+ <SelectTrigger className='hover:bg-accent w-full border-none shadow-none dark:bg-transparent'>
426
+ <SelectValue placeholder='Select a fruit' />
427
+ </SelectTrigger>
428
+ <SelectContent>
429
+ <SelectGroup>
430
+ <SelectLabel>Fruits</SelectLabel>
431
+ <SelectItem value='apple'>Apple</SelectItem>
432
+ <SelectItem value='banana'>Banana</SelectItem>
433
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
434
+ <SelectItem value='grapes'>Grapes</SelectItem>
435
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
436
+ </SelectGroup>
437
+ </SelectContent>
438
+ </Select>
439
+ </div>
440
+ )
441
+ }
442
+
443
+ const SelectDisabledDemo = () => {
444
+ const id = useId()
445
+
446
+ return (
447
+ <div className='w-full max-w-xs space-y-2'>
448
+ <Label htmlFor={id}>Disabled select</Label>
449
+ <Select defaultValue='apple' disabled>
450
+ <SelectTrigger id={id} className='w-full'>
451
+ <SelectValue placeholder='Select a fruit' />
452
+ </SelectTrigger>
453
+ <SelectContent>
454
+ <SelectGroup>
455
+ <SelectLabel>Fruits</SelectLabel>
456
+ <SelectItem value='apple'>Apple</SelectItem>
457
+ <SelectItem value='banana'>Banana</SelectItem>
458
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
459
+ <SelectItem value='grapes'>Grapes</SelectItem>
460
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
461
+ </SelectGroup>
462
+ </SelectContent>
463
+ </Select>
464
+ </div>
465
+ )
466
+ }
467
+
468
+ const SelectDisabledOptionDemo = () => {
469
+ const id = useId()
470
+
471
+ return (
472
+ <div className='w-full max-w-xs space-y-2'>
473
+ <Label htmlFor={id}>Disabled options select</Label>
474
+ <Select defaultValue='apple'>
475
+ <SelectTrigger id={id} className='w-full'>
476
+ <SelectValue placeholder='Select a fruit' />
477
+ </SelectTrigger>
478
+ <SelectContent>
479
+ <SelectGroup>
480
+ <SelectLabel>Fruits</SelectLabel>
481
+ <SelectItem value='apple'>Apple</SelectItem>
482
+ <SelectItem value='banana' disabled>
483
+ Banana
484
+ </SelectItem>
485
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
486
+ <SelectItem value='grapes' disabled>
487
+ Grapes
488
+ </SelectItem>
489
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
490
+ </SelectGroup>
491
+ </SelectContent>
492
+ </Select>
493
+ </div>
494
+ )
495
+ }
496
+
497
+ const SelectRequiredDemo = () => {
498
+ const id = useId()
499
+
500
+ return (
501
+ <div className='w-full max-w-xs space-y-2'>
502
+ <Label htmlFor={id} className='gap-1'>
503
+ Required select <span className='text-destructive'>*</span>
504
+ </Label>
505
+ <Select defaultValue='2' required>
506
+ <SelectTrigger id={id} className='w-full'>
507
+ <SelectValue placeholder='Select framework' />
508
+ </SelectTrigger>
509
+ <SelectContent>
510
+ <SelectItem value='1'>United States</SelectItem>
511
+ <SelectItem value='2'>Japan</SelectItem>
512
+ <SelectItem value='3'>Australia</SelectItem>
513
+ <SelectItem value='4'>Brazil</SelectItem>
514
+ </SelectContent>
515
+ </Select>
516
+ </div>
517
+ )
518
+ }
519
+
520
+ const SelectWithOptionsGroupsDemo = () => {
521
+ const id = useId()
522
+
523
+ return (
524
+ <div className='w-full max-w-xs space-y-2'>
525
+ <Label htmlFor={id}>Select with options groups</Label>
526
+ <Select defaultValue='7'>
527
+ <SelectTrigger id={id} className='w-full'>
528
+ <SelectValue placeholder='Select framework' />
529
+ </SelectTrigger>
530
+ <SelectContent>
531
+ <SelectGroup>
532
+ <SelectLabel>North America</SelectLabel>
533
+ <SelectItem value='1'>United States</SelectItem>
534
+ <SelectItem value='2'>Canada</SelectItem>
535
+ <SelectItem value='3'>Mexico</SelectItem>
536
+ </SelectGroup>
537
+ <SelectGroup>
538
+ <SelectLabel>Europe</SelectLabel>
539
+ <SelectItem value='4'>United Kingdom</SelectItem>
540
+ <SelectItem value='5'>Germany</SelectItem>
541
+ <SelectItem value='6'>France</SelectItem>
542
+ </SelectGroup>
543
+ <SelectGroup>
544
+ <SelectLabel>Asia</SelectLabel>
545
+ <SelectItem value='7'>India</SelectItem>
546
+ <SelectItem value='8'>Japan</SelectItem>
547
+ <SelectItem value='9'>China</SelectItem>
548
+ </SelectGroup>
549
+ </SelectContent>
550
+ </Select>
551
+ </div>
552
+ )
553
+ }
554
+
555
+ const SelectWithSeparatorDemo = () => {
556
+ const id = useId()
557
+
558
+ return (
559
+ <div className='w-full max-w-xs space-y-2'>
560
+ <Label htmlFor={id}>Select with separator</Label>
561
+ <Select defaultValue='7'>
562
+ <SelectTrigger id={id} className='w-full'>
563
+ <SelectValue placeholder='Select framework' />
564
+ </SelectTrigger>
565
+ <SelectContent>
566
+ <SelectGroup>
567
+ <SelectLabel>North America</SelectLabel>
568
+ <SelectItem value='1'>United States</SelectItem>
569
+ <SelectItem value='2'>Canada</SelectItem>
570
+ <SelectItem value='3'>Mexico</SelectItem>
571
+ </SelectGroup>
572
+ <SelectSeparator />
573
+ <SelectGroup>
574
+ <SelectLabel>Europe</SelectLabel>
575
+ <SelectItem value='4'>United Kingdom</SelectItem>
576
+ <SelectItem value='5'>Germany</SelectItem>
577
+ <SelectItem value='6'>France</SelectItem>
578
+ </SelectGroup>
579
+ <SelectSeparator />
580
+ <SelectGroup>
581
+ <SelectLabel>Asia</SelectLabel>
582
+ <SelectItem value='7'>India</SelectItem>
583
+ <SelectItem value='8'>Japan</SelectItem>
584
+ <SelectItem value='9'>China</SelectItem>
585
+ </SelectGroup>
586
+ </SelectContent>
587
+ </Select>
588
+ </div>
589
+ )
590
+ }
591
+
592
+ const SelectWithOverlappingLabelDemo = () => {
593
+ const id = useId()
594
+
595
+ return (
596
+ <div className='group relative w-full max-w-xs'>
597
+ <label
598
+ htmlFor={id}
599
+ className='bg-background text-foreground absolute top-0 left-2 z-10 block -translate-y-1/2 px-1 text-xs font-medium group-has-disabled:opacity-50'
600
+ >
601
+ Select with overlapping label
602
+ </label>
603
+ <Select>
604
+ <SelectTrigger id={id} className='dark:!bg-background w-full'>
605
+ <SelectValue placeholder='Select city' />
606
+ </SelectTrigger>
607
+ <SelectContent>
608
+ <SelectItem value='1'>New York</SelectItem>
609
+ <SelectItem value='2'>London</SelectItem>
610
+ <SelectItem value='3'>Tokyo</SelectItem>
611
+ <SelectItem value='4'>Paris</SelectItem>
612
+ </SelectContent>
613
+ </Select>
614
+ </div>
615
+ )
616
+ }
617
+
618
+ const SelectWithInsetLabelDemo = () => {
619
+ const id = useId()
620
+
621
+ return (
622
+ <div className='border-input group bg-background focus-within:border-ring focus-within:ring-ring/50 has-aria-invalid:ring-destructive/20 dark:has-aria-invalid:ring-destructive/40 has-aria-invalid:border-destructive relative w-full max-w-xs rounded-md border shadow-xs transition-[color,box-shadow] outline-none focus-within:ring-[3px] has-disabled:pointer-events-none has-disabled:cursor-not-allowed has-disabled:opacity-50 has-[input:is(:disabled)]:*:pointer-events-none'>
623
+ <label
624
+ htmlFor={id}
625
+ className='text-foreground dark:bg-input/30 dark:group-hover:bg-input/50 block px-3 pt-1 text-xs font-medium'
626
+ >
627
+ Select with inset label
628
+ </label>
629
+ <Select>
630
+ <SelectTrigger
631
+ id={id}
632
+ className='dark:group-hover:bg-input/50 w-full rounded-t-none border-none bg-transparent shadow-none focus-visible:ring-0 focus-visible:ring-offset-0'
633
+ >
634
+ <SelectValue placeholder='Select payment method' />
635
+ </SelectTrigger>
636
+ <SelectContent>
637
+ <SelectItem value='1'>Credit Card</SelectItem>
638
+ <SelectItem value='2'>Google Pay</SelectItem>
639
+ <SelectItem value='3'>PayPal</SelectItem>
640
+ <SelectItem value='4'>Bitcoin</SelectItem>
641
+ </SelectContent>
642
+ </Select>
643
+ </div>
644
+ )
645
+ }
646
+
647
+ const SelectTimeZoneDemo = () => {
648
+ const id = useId()
649
+
650
+ return (
651
+ <div className='w-full max-w-xs space-y-2'>
652
+ <Label htmlFor={id}>Timezone Select</Label>
653
+ <Select>
654
+ <SelectTrigger id={id} className='w-full'>
655
+ <SelectValue placeholder='Select a timezone' />
656
+ </SelectTrigger>
657
+ <SelectContent className='max-h-100'>
658
+ <SelectGroup>
659
+ <SelectLabel>North America</SelectLabel>
660
+ <SelectItem value='est'>Eastern Standard Time (EST)</SelectItem>
661
+ <SelectItem value='cst'>Central Standard Time (CST)</SelectItem>
662
+ <SelectItem value='mst'>Mountain Standard Time (MST)</SelectItem>
663
+ <SelectItem value='pst'>Pacific Standard Time (PST)</SelectItem>
664
+ <SelectItem value='akst'>Alaska Standard Time (AKST)</SelectItem>
665
+ <SelectItem value='hst'>Hawaii Standard Time (HST)</SelectItem>
666
+ </SelectGroup>
667
+ <SelectGroup>
668
+ <SelectLabel>Europe & Africa</SelectLabel>
669
+ <SelectItem value='gmt'>Greenwich Mean Time (GMT)</SelectItem>
670
+ <SelectItem value='cet'>Central European Time (CET)</SelectItem>
671
+ <SelectItem value='eet'>Eastern European Time (EET)</SelectItem>
672
+ <SelectItem value='west'>Western European Summer Time (WEST)</SelectItem>
673
+ <SelectItem value='cat'>Central Africa Time (CAT)</SelectItem>
674
+ <SelectItem value='eat'>East Africa Time (EAT)</SelectItem>
675
+ </SelectGroup>
676
+ <SelectGroup>
677
+ <SelectLabel>Asia</SelectLabel>
678
+ <SelectItem value='msk'>Moscow Time (MSK)</SelectItem>
679
+ <SelectItem value='ist'>India Standard Time (IST)</SelectItem>
680
+ <SelectItem value='cst_china'>China Standard Time (CST)</SelectItem>
681
+ <SelectItem value='jst'>Japan Standard Time (JST)</SelectItem>
682
+ <SelectItem value='kst'>Korea Standard Time (KST)</SelectItem>
683
+ <SelectItem value='ist_indonesia'>Indonesia Central Standard Time (WITA)</SelectItem>
684
+ </SelectGroup>
685
+ <SelectGroup>
686
+ <SelectLabel>Australia & Pacific</SelectLabel>
687
+ <SelectItem value='awst'>Australian Western Standard Time (AWST)</SelectItem>
688
+ <SelectItem value='acst'>Australian Central Standard Time (ACST)</SelectItem>
689
+ <SelectItem value='aest'>Australian Eastern Standard Time (AEST)</SelectItem>
690
+ <SelectItem value='nzst'>New Zealand Standard Time (NZST)</SelectItem>
691
+ <SelectItem value='fjt'>Fiji Time (FJT)</SelectItem>
692
+ </SelectGroup>
693
+ <SelectGroup>
694
+ <SelectLabel>South America</SelectLabel>
695
+ <SelectItem value='art'>Argentina Time (ART)</SelectItem>
696
+ <SelectItem value='bot'>Bolivia Time (BOT)</SelectItem>
697
+ <SelectItem value='brt'>Brasilia Time (BRT)</SelectItem>
698
+ <SelectItem value='clt'>Chile Standard Time (CLT)</SelectItem>
699
+ </SelectGroup>
700
+ </SelectContent>
701
+ </Select>
702
+ </div>
703
+ )
704
+ }
705
+
706
+ const SelectDemo = () => {
707
+ const id = useId()
708
+
709
+ return (
710
+ <div className='w-full max-w-xs space-y-2'>
711
+ <Label htmlFor={id}>Select option with icon</Label>
712
+ <Select defaultValue='rock'>
713
+ <SelectTrigger id={id} className='w-full'>
714
+ <SelectValue placeholder='Select a music genre' />
715
+ </SelectTrigger>
716
+ <SelectContent>
717
+ <SelectGroup>
718
+ <SelectLabel>Music Genres</SelectLabel>
719
+ <SelectItem value='rock'>
720
+ <GuitarIcon />
721
+ Rock
722
+ </SelectItem>
723
+ <SelectItem value='electronic'>
724
+ <HeadphonesIcon />
725
+ Electronic
726
+ </SelectItem>
727
+ <SelectItem value='pop'>
728
+ <MicVocalIcon />
729
+ Pop
730
+ </SelectItem>
731
+ <SelectItem value='jazz'>
732
+ <MusicIcon />
733
+ Jazz
734
+ </SelectItem>
735
+ </SelectGroup>
736
+ </SelectContent>
737
+ </Select>
738
+ </div>
739
+ )
740
+ }
741
+
742
+ const SelectWithLeadingTextDemo = () => {
743
+ const id = useId()
744
+
745
+ return (
746
+ <div className='w-full max-w-xs space-y-2'>
747
+ <Label htmlFor={id}>Select with leading text</Label>
748
+ <Select defaultValue='1'>
749
+ <SelectTrigger id={id} className='w-full'>
750
+ <span>
751
+ Favorite Movie: <SelectValue placeholder='Select a movie' />
752
+ </span>
753
+ </SelectTrigger>
754
+ <SelectContent>
755
+ <SelectItem value='1'>Inception</SelectItem>
756
+ <SelectItem value='2'>Interstellar</SelectItem>
757
+ <SelectItem value='3'>The Dark Knight</SelectItem>
758
+ <SelectItem value='4'>Pulp Fiction</SelectItem>
759
+ </SelectContent>
760
+ </Select>
761
+ </div>
762
+ )
763
+ }
764
+
765
+ const SelectStatusDemo = () => {
766
+ const id = useId()
767
+
768
+ return (
769
+ <div className='w-full max-w-xs space-y-2'>
770
+ <Label htmlFor={id}>Status select</Label>
771
+ <Select defaultValue='1'>
772
+ <SelectTrigger
773
+ id={id}
774
+ className='w-full [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0'
775
+ >
776
+ <SelectValue placeholder='Select status' />
777
+ </SelectTrigger>
778
+ <SelectContent className='[&_*[role=option]>span>svg]:text-muted-foreground/80 [&_*[role=option]]:pr-8 [&_*[role=option]]:pl-2 [&_*[role=option]>span]:right-2 [&_*[role=option]>span]:left-auto [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0'>
779
+ <SelectItem value='1'>
780
+ <span className='flex items-center gap-2'>
781
+ <CircleIcon className='size-2 fill-violet-500 text-violet-500' />
782
+ <span className='truncate'>In Progress</span>
783
+ </span>
784
+ </SelectItem>
785
+ <SelectItem value='2'>
786
+ <span className='flex items-center gap-2'>
787
+ <CircleIcon className='size-2 fill-amber-500 text-amber-500' />
788
+ <span className='truncate'>Pending</span>
789
+ </span>
790
+ </SelectItem>
791
+ <SelectItem value='3'>
792
+ <span className='flex items-center gap-2'>
793
+ <CircleIcon className='size-2 fill-emerald-600 text-emerald-600' />
794
+ <span className='truncate'>Completed</span>
795
+ </span>
796
+ </SelectItem>
797
+ <SelectItem value='4'>
798
+ <span className='flex items-center gap-2'>
799
+ <CircleIcon className='size-2 fill-gray-500 text-gray-500' />
800
+ <span className='truncate'>Cancelled</span>
801
+ </span>
802
+ </SelectItem>
803
+ <SelectItem value='5'>
804
+ <span className='flex items-center gap-2'>
805
+ <CircleIcon className='size-2 fill-red-500 text-red-500' />
806
+ <span className='truncate'>Rejected</span>
807
+ </span>
808
+ </SelectItem>
809
+ </SelectContent>
810
+ </Select>
811
+ </div>
812
+ )
813
+ }
814
+
815
+ const SelectWithFlagsDemo = () => {
816
+ const id = useId()
817
+
818
+ return (
819
+ <div className='w-full max-w-xs space-y-2'>
820
+ <Label htmlFor={id}>Options with flag</Label>
821
+ <Select defaultValue='1'>
822
+ <SelectTrigger
823
+ id={id}
824
+ className='[&>span_svg]:text-muted-foreground/80 w-full [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_svg]:shrink-0'
825
+ >
826
+ <SelectValue placeholder='Select framework' />
827
+ </SelectTrigger>
828
+ <SelectContent className='[&_*[role=option]>span>svg]:text-muted-foreground/80 max-h-100 [&_*[role=option]]:pr-8 [&_*[role=option]]:pl-2 [&_*[role=option]>span]:right-2 [&_*[role=option]>span]:left-auto [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2 [&_*[role=option]>span>svg]:shrink-0'>
829
+ {countries.map(country => (
830
+ <SelectItem key={country.value} value={country.value}>
831
+ <img src={country.flag} alt={`${country.label} flag`} className='h-4 w-5' />{' '}
832
+ <span className='truncate'>{country.label}</span>
833
+ </SelectItem>
834
+ ))}
835
+ </SelectContent>
836
+ </Select>
837
+ </div>
838
+ )
839
+ }
840
+
841
+ const SelectWithAvatarsDemo = () => {
842
+ const id = useId()
843
+
844
+ return (
845
+ <div className='w-full max-w-xs space-y-2'>
846
+ <Label htmlFor={id}>Options with avatar</Label>
847
+ <Select defaultValue='1'>
848
+ <SelectTrigger
849
+ id={id}
850
+ className='w-full pl-2 [&>span]:flex [&>span]:items-center [&>span]:gap-2 [&>span_img]:shrink-0'
851
+ >
852
+ <SelectValue placeholder='Select framework' />
853
+ </SelectTrigger>
854
+ <SelectContent className='[&_*[role=option]]:pr-8 [&_*[role=option]]:pl-2 [&_*[role=option]>span]:right-2 [&_*[role=option]>span]:left-auto [&_*[role=option]>span]:flex [&_*[role=option]>span]:items-center [&_*[role=option]>span]:gap-2'>
855
+ <SelectGroup>
856
+ <SelectLabel className='pl-2'>Impersonate user</SelectLabel>
857
+ {users.map(item => (
858
+ <SelectItem key={item.id} value={item.id}>
859
+ <Avatar className='size-5'>
860
+ <AvatarImage src={item.src} alt={item.name} className='rounded-full' />
861
+ <AvatarFallback className='text-xs'>{item.fallback}</AvatarFallback>
862
+ </Avatar>
863
+ <span className='truncate'>{item.name}</span>
864
+ </SelectItem>
865
+ ))}
866
+ </SelectGroup>
867
+ </SelectContent>
868
+ </Select>
869
+ </div>
870
+ )
871
+ }
872
+
873
+ const MultipleSelectDemo = () => {
874
+ return (
875
+ <div className='w-full max-w-xs space-y-2'>
876
+ <Label>Multiselect</Label>
877
+ <MultipleSelector
878
+ commandProps={{
879
+ label: 'Select categories'
880
+ }}
881
+ value={categories.slice(0, 2)}
882
+ defaultOptions={categories}
883
+ placeholder='Select categories'
884
+ hideClearAllButton
885
+ hidePlaceholderWhenSelected
886
+ emptyIndicator={<p className='text-center text-sm'>No results found</p>}
887
+ className='w-full'
888
+ />
889
+ <p className='text-muted-foreground text-xs' role='region' aria-live='polite'>
890
+ Inspired by{' '}
891
+ <a
892
+ href='https://shadcnui-expansions.typeart.cc/docs/multiple-selector'
893
+ className='hover:text-primary underline'
894
+ target='_blank'
895
+ >
896
+ shadcn/ui expressions
897
+ </a>
898
+ </p>
899
+ </div>
900
+ )
901
+ }
902
+
903
+ const MultipleSelectWithPlaceholderDemo = () => {
904
+ return (
905
+ <div className='w-full max-w-xs space-y-2'>
906
+ <Label>Multiselect with placeholder and clear</Label>
907
+ <MultipleSelector
908
+ commandProps={{
909
+ label: 'Select categories'
910
+ }}
911
+ defaultOptions={categories}
912
+ placeholder='Select categories'
913
+ emptyIndicator={<p className='text-center text-sm'>No results found</p>}
914
+ className='w-full'
915
+ />
916
+ <p className='text-muted-foreground text-xs' role='region' aria-live='polite'>
917
+ Inspired by{' '}
918
+ <a
919
+ href='https://shadcnui-expansions.typeart.cc/docs/multiple-selector'
920
+ className='hover:text-primary underline'
921
+ target='_blank'
922
+ >
923
+ shadcn/ui expressions
924
+ </a>
925
+ </p>
926
+ </div>
927
+ )
928
+ }
929
+
930
+ const SelectNativeMultipleDemo = () => {
931
+ const id = useId()
932
+
933
+ return (
934
+ <div className='w-full max-w-xs space-y-2'>
935
+ <Label htmlFor={id}>Native multiple select</Label>
936
+ <div className='border-input overflow-hidden rounded-md border'>
937
+ <SelectNative id={id} multiple className='rounded-none border-none'>
938
+ <option value='1'>Vegetarian</option>
939
+ <option value='2'>Vegan</option>
940
+ <option value='3'>Gluten-Free</option>
941
+ <option value='4'>Halal</option>
942
+ <option value='5'>Kosher</option>
943
+ <option value='6'>Dairy-Free</option>
944
+ </SelectNative>
945
+ </div>
946
+ </div>
947
+ )
948
+ }
949
+
950
+ const ListboxSingleOptionDemo = () => {
951
+ return (
952
+ <div className='w-full max-w-xs space-y-2'>
953
+ <Label>Listbox with single option selectable</Label>
954
+ <div className='border-input overflow-hidden rounded-md border'>
955
+ <ListBox
956
+ className='bg-background space-y-1 p-1 text-sm shadow-xs transition-[color,box-shadow]'
957
+ aria-label='Select framework'
958
+ selectionMode='single'
959
+ defaultSelectedKeys={['svelte']}
960
+ >
961
+ {listitems.map(item => (
962
+ <ListBoxItem
963
+ key={item.id}
964
+ className='data-[disabled]:text-muted-foreground data-[selected]:bg-accent data-[selected]:text-accent-foreground flex items-center justify-between rounded-sm px-2 py-1.5'
965
+ textValue={item.label}
966
+ isDisabled={item.isDisabled}
967
+ >
968
+ {item.label}
969
+ </ListBoxItem>
970
+ ))}
971
+ </ListBox>
972
+ </div>
973
+ <p className='text-muted-foreground text-xs' role='region' aria-live='polite'>
974
+ Built using{' '}
975
+ <a
976
+ href='https://react-spectrum.adobe.com/react-aria/ListBox.html'
977
+ className='hover:text-primary underline'
978
+ target='_blank'
979
+ >
980
+ React Aria
981
+ </a>
982
+ </p>
983
+ </div>
984
+ )
985
+ }
986
+
987
+ const ListBoxWithOptionGroupsDemo = () => {
988
+ return (
989
+ <div className='w-full max-w-xs space-y-2'>
990
+ <Label>Listbox with option groups</Label>
991
+ <div className='border-input overflow-hidden rounded-md border'>
992
+ <ListBox
993
+ className='bg-background max-h-65 min-h-20 space-y-2 overflow-auto p-1 text-sm shadow-xs transition-[color,box-shadow]'
994
+ aria-label='Select some foods'
995
+ selectionMode='multiple'
996
+ defaultSelectedKeys={['english', 'tuna']}
997
+ >
998
+ <ListBoxSection className='space-y-1'>
999
+ <Header className='text-muted-foreground px-2 py-1.5 text-xs font-medium'>European Languages</Header>
1000
+ <ListBoxItem
1001
+ id='english'
1002
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1003
+ >
1004
+ English
1005
+ </ListBoxItem>
1006
+ <ListBoxItem
1007
+ id='french'
1008
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1009
+ >
1010
+ French
1011
+ </ListBoxItem>
1012
+ <ListBoxItem
1013
+ id='spanish'
1014
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1015
+ >
1016
+ Spanish
1017
+ </ListBoxItem>
1018
+ </ListBoxSection>
1019
+ <Separator className='bg-border -mx-1 my-2 h-px' />
1020
+ <ListBoxSection className='space-y-1'>
1021
+ <Header className='text-muted-foreground px-2 py-1.5 text-xs font-medium'>Asian Languages</Header>
1022
+ <ListBoxItem
1023
+ id='hindi'
1024
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1025
+ >
1026
+ Hindi
1027
+ </ListBoxItem>
1028
+ <ListBoxItem
1029
+ id='japanese'
1030
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1031
+ >
1032
+ Japanese
1033
+ </ListBoxItem>
1034
+ <ListBoxItem
1035
+ id='mandarin'
1036
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1037
+ >
1038
+ Mandarin
1039
+ </ListBoxItem>
1040
+ </ListBoxSection>
1041
+ <Separator className='bg-border -mx-1 my-2 h-px' />
1042
+ <ListBoxSection className='space-y-1'>
1043
+ <Header className='text-muted-foreground px-2 py-1.5 text-xs font-medium'>Other Languages</Header>
1044
+ <ListBoxItem
1045
+ id='swahili'
1046
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1047
+ >
1048
+ Swahili
1049
+ </ListBoxItem>
1050
+ <ListBoxItem
1051
+ id='arabic'
1052
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1053
+ >
1054
+ Arabic
1055
+ </ListBoxItem>
1056
+ <ListBoxItem
1057
+ id='russian'
1058
+ className='data-[selected=true]:bg-accent data-[selected=true]:text-accent-foreground data-focus-visible:border-ring data-focus-visible:ring-ring/50 relative rounded px-2 py-1.5 outline-none data-disabled:cursor-not-allowed data-disabled:opacity-50 data-focus-visible:ring-[3px]'
1059
+ >
1060
+ Russian
1061
+ </ListBoxItem>
1062
+ </ListBoxSection>
1063
+ </ListBox>
1064
+ </div>
1065
+ <p className='text-muted-foreground text-xs' role='region' aria-live='polite'>
1066
+ Built using{' '}
1067
+ <a
1068
+ href='https://react-spectrum.adobe.com/react-aria/ListBox.html'
1069
+ className='hover:text-primary underline'
1070
+ target='_blank'
1071
+ >
1072
+ React Aria
1073
+ </a>
1074
+ </p>
1075
+ </div>
1076
+ )
1077
+ }
1078
+
1079
+ const SelectMenuSlideInDemo = () => {
1080
+ const id = useId()
1081
+
1082
+ return (
1083
+ <div className='w-full max-w-xs space-y-2'>
1084
+ <Label htmlFor={id}>Select menu slide-in from bottom</Label>
1085
+ <Select defaultValue='apple'>
1086
+ <SelectTrigger id={id} className='w-full'>
1087
+ <SelectValue placeholder='Select a fruit' />
1088
+ </SelectTrigger>
1089
+ <SelectContent className='data-[state=open]:slide-in-from-bottom-8 data-[state=open]:zoom-in-100 duration-400'>
1090
+ <SelectGroup>
1091
+ <SelectLabel>Fruits</SelectLabel>
1092
+ <SelectItem value='apple'>Apple</SelectItem>
1093
+ <SelectItem value='banana'>Banana</SelectItem>
1094
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
1095
+ <SelectItem value='grapes'>Grapes</SelectItem>
1096
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
1097
+ </SelectGroup>
1098
+ </SelectContent>
1099
+ </Select>
1100
+ </div>
1101
+ )
1102
+ }
1103
+
1104
+ const SelectMenuZoomInDemo = () => {
1105
+ const id = useId()
1106
+
1107
+ return (
1108
+ <div className='w-full max-w-xs space-y-2'>
1109
+ <Label htmlFor={id}>Select menu zoom-in</Label>
1110
+ <Select defaultValue='apple'>
1111
+ <SelectTrigger id={id} className='w-full'>
1112
+ <SelectValue placeholder='Select a fruit' />
1113
+ </SelectTrigger>
1114
+ <SelectContent className='data-[state=open]:!zoom-in-0 origin-center duration-400'>
1115
+ <SelectGroup>
1116
+ <SelectLabel>Fruits</SelectLabel>
1117
+ <SelectItem value='apple'>Apple</SelectItem>
1118
+ <SelectItem value='banana'>Banana</SelectItem>
1119
+ <SelectItem value='blueberry'>Blueberry</SelectItem>
1120
+ <SelectItem value='grapes'>Grapes</SelectItem>
1121
+ <SelectItem value='pineapple'>Pineapple</SelectItem>
1122
+ </SelectGroup>
1123
+ </SelectContent>
1124
+ </Select>
1125
+ </div>
1126
+ )
1127
+ } */