@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,1843 @@
1
+ // EmojiPicker
2
+ export const comboboxes = [
3
+ {
4
+ name: "filter combobox",
5
+ value: "filter-combobox",
6
+ importPath: "~/components/catalyst-ui/comboboxes/filter-combobox",
7
+ path: "/components/catalyst-ui/comboboxes/filter-combobox.tsx",
8
+ premium: true,
9
+ source: null,
10
+ basicusage: `
11
+
12
+
13
+ const [selectedStatus, setSelectedStatus] = useState("");
14
+ const [error, setError] = useState("");
15
+
16
+ const statusOptions = [
17
+ { value: "active", label: "Active" },
18
+ { value: "inactive", label: "Inactive" },
19
+ { value: "pending", label: "Pending" },
20
+ { value: "completed", label: "Completed" },
21
+ { value: "cancelled", label: "Cancelled" }
22
+ ];
23
+
24
+ const handleChange = (value: string) => {
25
+ setSelectedStatus(value);
26
+
27
+ if (!value) {
28
+ setError("Please select a status");
29
+ } else {
30
+ setError("");
31
+ }
32
+ };
33
+
34
+ // Basic usage without validation
35
+ <Field>
36
+ <FieldLabel>Status</FieldLabel>
37
+ <FilterCombobox
38
+ placeholder="Select Status"
39
+ options={statusOptions}
40
+ value={selectedStatus}
41
+ onValueChange={setSelectedStatus}
42
+ />
43
+ <FieldDescription>Choose a status option</FieldDescription>
44
+ </Field>
45
+
46
+ // With validation
47
+ <Field>
48
+ <FieldLabel>Status</FieldLabel>
49
+ <FilterCombobox
50
+ placeholder="Select Status"
51
+ options={statusOptions}
52
+ value={selectedStatus}
53
+ onValueChange={handleChange}
54
+ />
55
+ <FieldDescription>Choose a status option</FieldDescription>
56
+ {error && <FieldError>{error}</FieldError>}
57
+ </Field>`,
58
+ usage: `
59
+ const statusOptions = [
60
+ { value: "active", label: "Active" },
61
+ { value: "inactive", label: "Inactive" },
62
+ { value: "pending", label: "Pending" },
63
+ { value: "completed", label: "Completed" },
64
+ { value: "cancelled", label: "Cancelled" }
65
+ ];
66
+
67
+ <FilterCombobox
68
+ placeholder="Select Status"
69
+ options={statusOptions}
70
+ value={selectedStatus}
71
+ onValueChange={setSelectedStatus}
72
+ />
73
+
74
+ const categoryOptions = [
75
+ { value: "electronics", label: "Electronics" },
76
+ { value: "clothing", label: "Clothing" },
77
+ { value: "books", label: "Books" },
78
+ { value: "home", label: "Home & Garden" },
79
+ { value: "sports", label: "Sports" },
80
+ { value: "beauty", label: "Beauty" }
81
+ ];
82
+
83
+ <FilterCombobox
84
+ placeholder="Select Category"
85
+ options={categoryOptions}
86
+ value={selectedCategory}
87
+ onValueChange={setSelectedCategory}
88
+ />
89
+
90
+ const priorityOptions = [
91
+ { value: "high", label: "High Priority" },
92
+ { value: "medium", label: "Medium Priority" },
93
+ { value: "low", label: "Low Priority" },
94
+ { value: "urgent", label: "Urgent" }
95
+ ];
96
+
97
+ <FilterCombobox
98
+ placeholder="Select Priority"
99
+ options={priorityOptions}
100
+ value={selectedPriority}
101
+ onValueChange={setSelectedPriority}
102
+ />
103
+
104
+ const dateOptions = [
105
+ { value: "today", label: "Today" },
106
+ { value: "yesterday", label: "Yesterday" },
107
+ { value: "this_week", label: "This Week" },
108
+ { value: "last_week", label: "Last Week" },
109
+ { value: "this_month", label: "This Month" },
110
+ { value: "last_month", label: "Last Month" },
111
+ { value: "custom", label: "Custom Range" }
112
+ ];
113
+
114
+ <FilterCombobox
115
+ placeholder="Select Date Range"
116
+ options={dateOptions}
117
+ value={selectedDateRange}
118
+ onValueChange={setSelectedDateRange}
119
+ />
120
+
121
+ const sortOptions = [
122
+ { value: "newest", label: "Newest First" },
123
+ { value: "oldest", label: "Oldest First" },
124
+ { value: "name_asc", label: "Name (A-Z)" },
125
+ { value: "name_desc", label: "Name (Z-A)" },
126
+ { value: "price_low", label: "Price: Low to High" },
127
+ { value: "price_high", label: "Price: High to Low" }
128
+ ];
129
+
130
+ <FilterCombobox
131
+ placeholder="Sort By"
132
+ options={sortOptions}
133
+ value={selectedSort}
134
+ onValueChange={setSelectedSort}
135
+ />
136
+
137
+ const locationOptions = [
138
+ { value: "new_york", label: "New York" },
139
+ { value: "los_angeles", label: "Los Angeles" },
140
+ { value: "chicago", label: "Chicago" },
141
+ { value: "houston", label: "Houston" },
142
+ { value: "phoenix", label: "Phoenix" },
143
+ { value: "miami", label: "Miami" }
144
+ ];
145
+
146
+ <FilterCombobox
147
+ placeholder="Select Location"
148
+ options={locationOptions}
149
+ value={selectedLocation}
150
+ onValueChange={setSelectedLocation}
151
+ />
152
+
153
+ const booleanOptions = [
154
+ { value: "true", label: "Yes" },
155
+ { value: "false", label: "No" },
156
+ { value: "both", label: "Both" }
157
+ ];
158
+
159
+ <FilterCombobox
160
+ placeholder="Has Image?"
161
+ options={booleanOptions}
162
+ value={hasImage}
163
+ onValueChange={setHasImage}
164
+ />
165
+
166
+ export function FilterComboboxDemo() {
167
+ const [selectedStatus, setSelectedStatus] = useState("");
168
+ const [selectedCategory, setSelectedCategory] = useState("");
169
+
170
+ const statusOptions = [
171
+ { value: "active", label: "Active" },
172
+ { value: "inactive", label: "Inactive" },
173
+ { value: "pending", label: "Pending" }
174
+ ];
175
+
176
+ const categoryOptions = [
177
+ { value: "electronics", label: "Electronics" },
178
+ { value: "clothing", label: "Clothing" },
179
+ { value: "books", label: "Books" }
180
+ ];
181
+
182
+ return (
183
+ <div className="flex gap-4">
184
+ <FilterCombobox
185
+ placeholder="Select Status"
186
+ options={statusOptions}
187
+ value={selectedStatus}
188
+ onValueChange={setSelectedStatus}
189
+ />
190
+
191
+ <FilterCombobox
192
+ placeholder="Select Category"
193
+ options={categoryOptions}
194
+ value={selectedCategory}
195
+ onValueChange={setSelectedCategory}
196
+ className="w-[250px]"
197
+ />
198
+ </div>
199
+ );
200
+ }
201
+ `,
202
+ usagePath: null,
203
+ category: "Comboboxes",
204
+ tags: ["ui", "components", "interactive"],
205
+ features: ["Responsive", "TypeScript", "Accessible"],
206
+ dependencies: ["@radix-ui/react-aspect-ratio"],
207
+ props: {
208
+ "FilterCombobox": [
209
+ { name: "placeholder", type: "string", default: "null", required: true },
210
+ { name: "options", type: "Array<{ value: string; label: string }>", default: "null", required: true },
211
+ { name: "value", type: "string", default: "null", required: false },
212
+ { name: "onValueChange", type: "(value: string) => void", default: "null", required: false },
213
+ { name: "className", type: "string", default: "''", required: false },
214
+ ],
215
+ },
216
+ desc: null,
217
+ status: null,
218
+ lastUpdated: null
219
+ },
220
+ {
221
+ name: "Combobox0",
222
+ value: "combobox-0",
223
+ importPath: "~/components/catalyst-ui/comboboxes/combobox-0",
224
+ path: "/components/catalyst-ui/comboboxes/combobox-0.tsx",
225
+ premium: false,
226
+ source: "/components/catalyst-ui/comboboxes/combobox-0.tsx",
227
+ category: "Comboboxes",
228
+ tags: ["ui", "components", "interactive"],
229
+ features: ["Responsive", "TypeScript", "Accessible"],
230
+ dependencies: ["lucide-react", "cmdk", "@radix-ui/react-popover"],
231
+ basicusage: `
232
+
233
+
234
+
235
+
236
+
237
+
238
+
239
+ const frameworks = [
240
+ {
241
+ value: "next.js",
242
+ label: "Next.js",
243
+ },
244
+ {
245
+ value: "sveltekit",
246
+ label: "SvelteKit",
247
+ },
248
+ {
249
+ value: "nuxt.js",
250
+ label: "Nuxt.js",
251
+ },
252
+ {
253
+ value: "remix",
254
+ label: "Remix",
255
+ },
256
+ {
257
+ value: "astro",
258
+ label: "Astro",
259
+ },
260
+ ]
261
+
262
+ export function ComboboxDemo() {
263
+ const [open, setOpen] = React.useState(false)
264
+ const [value, setValue] = React.useState("")
265
+
266
+ return (
267
+ <Popover open={open} onOpenChange={setOpen}>
268
+ <PopoverTrigger asChild>
269
+ <Button
270
+ variant="outline"
271
+ role="combobox"
272
+ aria-expanded={open}
273
+ className="w-[200px] justify-between"
274
+ >
275
+ {value
276
+ ? frameworks.find((framework) => framework.value === value)?.label
277
+ : "Select framework..."}
278
+ <ChevronsUpDown className="opacity-50" />
279
+ </Button>
280
+ </PopoverTrigger>
281
+ <PopoverContent className="w-[200px] p-0">
282
+ <Command>
283
+ <CommandInput placeholder="Search framework..." className="h-9" />
284
+ <CommandList>
285
+ <CommandEmpty>No framework found.</CommandEmpty>
286
+ <CommandGroup>
287
+ {frameworks.map((framework) => (
288
+ <CommandItem
289
+ key={framework.value}
290
+ value={framework.value}
291
+ onSelect={(currentValue) => {
292
+ setValue(currentValue === value ? "" : currentValue)
293
+ setOpen(false)
294
+ }}
295
+ >
296
+ {framework.label}
297
+ <Check
298
+ className={cn(
299
+ "ml-auto",
300
+ value === framework.value ? "opacity-100" : "opacity-0"
301
+ )}
302
+ />
303
+ </CommandItem>
304
+ ))}
305
+ </CommandGroup>
306
+ </CommandList>
307
+ </Command>
308
+ </PopoverContent>
309
+ </Popover>
310
+ )
311
+ }
312
+ `,
313
+ usage: null,
314
+ usagePath: null,
315
+ props: {},
316
+ desc: 'Orginal shadCN component structure',
317
+ status: null,
318
+ lastUpdated: null
319
+ },
320
+ {
321
+ name: "Combobox V1",
322
+ value: "combobox-1",
323
+ importPath: "~/components/catalyst-ui/comboboxes/combobox-1",
324
+ path: "/components/catalyst-ui/comboboxes/combobox-1.tsx",
325
+ premium: true,
326
+ source: null,
327
+ category: "Comboboxes",
328
+ tags: ["ui", "forms", "core"],
329
+ features: ["Responsive", "TypeScript", "Accessible"],
330
+ dependencies: ["lucide-react"],
331
+ usage: `
332
+
333
+
334
+
335
+
336
+
337
+
338
+ export const meta: MetaFunction = () => {
339
+ return [
340
+ { title: "Comboboxes Demo" },
341
+ { name: "description", content: "Demo of combobox components with various styles and functionality" },
342
+ ]
343
+ }
344
+
345
+ export default function ComboboxesDemo() {
346
+ const [selectedCountry, setSelectedCountry] = useState("")
347
+ const [selectedCategory, setSelectedCategory] = useState("")
348
+ const [selectedStatus, setSelectedStatus] = useState("")
349
+ const [selectedTags, setSelectedTags] = useState<string[]>([])
350
+ const [selectedUsers, setSelectedUsers] = useState<string[]>([])
351
+ const [searchQuery, setSearchQuery] = useState("")
352
+
353
+ // Sample data
354
+ const countries = [
355
+ { value: "us", label: "United States" },
356
+ { value: "ca", label: "Canada" },
357
+ { value: "uk", label: "United Kingdom" },
358
+ { value: "au", label: "Australia" },
359
+ { value: "de", label: "Germany" },
360
+ { value: "fr", label: "France" },
361
+ { value: "jp", label: "Japan" },
362
+ { value: "br", label: "Brazil" },
363
+ ]
364
+
365
+ const categories = [
366
+ { value: "electronics", label: "Electronics" },
367
+ { value: "clothing", label: "Clothing" },
368
+ { value: "books", label: "Books" },
369
+ { value: "home", label: "Home & Garden" },
370
+ { value: "sports", label: "Sports & Outdoors" },
371
+ { value: "beauty", label: "Beauty & Personal Care" },
372
+ { value: "toys", label: "Toys & Games" },
373
+ ]
374
+
375
+ const statuses = [
376
+ { value: "active", label: "Active" },
377
+ { value: "pending", label: "Pending" },
378
+ { value: "draft", label: "Draft" },
379
+ { value: "archived", label: "Archived" },
380
+ ]
381
+
382
+ const tags = [
383
+ { value: "featured", label: "Featured" },
384
+ { value: "sale", label: "On Sale" },
385
+ { value: "new", label: "New Arrival" },
386
+ { value: "popular", label: "Popular" },
387
+ { value: "limited", label: "Limited Edition" },
388
+ { value: "clearance", label: "Clearance" },
389
+ ]
390
+
391
+ const users = [
392
+ { value: "alice", label: "Alice Johnson", email: "alice@example.com" },
393
+ { value: "bob", label: "Bob Smith", email: "bob@example.com" },
394
+ { value: "carol", label: "Carol Williams", email: "carol@example.com" },
395
+ { value: "dave", label: "Dave Brown", email: "dave@example.com" },
396
+ { value: "eve", label: "Eve Davis", email: "eve@example.com" },
397
+ { value: "frank", label: "Frank Miller", email: "frank@example.com" },
398
+ ]
399
+
400
+ // Sample products data
401
+ const products = [
402
+ { id: 1, name: "Wireless Headphones", category: "electronics", tags: ["featured", "new"], status: "active", country: "us" },
403
+ { id: 2, name: "Cotton T-Shirt", category: "clothing", tags: ["sale"], status: "active", country: "ca" },
404
+ { id: 3, name: "Programming Book", category: "books", tags: ["popular"], status: "draft", country: "uk" },
405
+ { id: 4, name: "Desk Lamp", category: "home", tags: ["new"], status: "active", country: "de" },
406
+ { id: 5, name: "Yoga Mat", category: "sports", tags: ["featured", "sale"], status: "active", country: "us" },
407
+ { id: 6, name: "Face Cream", category: "beauty", tags: ["new", "limited"], status: "pending", country: "fr" },
408
+ { id: 7, name: "Board Game", category: "toys", tags: ["popular", "clearance"], status: "active", country: "ca" },
409
+ { id: 8, name: "Smart Watch", category: "electronics", tags: ["featured", "new"], status: "archived", country: "jp" },
410
+ ]
411
+
412
+ // Filter products based on selected filters and search query
413
+ const filteredProducts = products.filter(product => {
414
+ // Filter by category if selected
415
+ if (selectedCategory && product.category !== selectedCategory) return false
416
+
417
+ // Filter by status if selected
418
+ if (selectedStatus && product.status !== selectedStatus) return false
419
+
420
+ // Filter by country if selected
421
+ if (selectedCountry && product.country !== selectedCountry) return false
422
+
423
+ // Filter by tags if selected
424
+ if (selectedTags.length > 0 && !selectedTags.some(tag => product.tags.includes(tag))) return false
425
+
426
+ // Filter by search query
427
+ if (searchQuery && !product.name.toLowerCase().includes(searchQuery.toLowerCase())) return false
428
+
429
+ return true
430
+ })
431
+
432
+ return (
433
+ <div className="container mx-auto py-10 px-4 max-w-6xl">
434
+ <div className="mb-10">
435
+ <h1 className="text-3xl font-bold text-foreground mb-2">Combobox Components</h1>
436
+ <p className="text-muted-foreground">
437
+ Various combobox styles and implementations with functional examples.
438
+ </p>
439
+ </div>
440
+
441
+ {/* Filterable Products Section */}
442
+ <div className="bg-card p-6 rounded-lg border mb-8">
443
+ <h2 className="text-xl font-semibold text-foreground mb-4">Product Filter with Comboboxes</h2>
444
+
445
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
446
+ {/* Search Input */}
447
+ <div className="lg:col-span-2">
448
+ <div className="relative">
449
+ <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
450
+ <input
451
+ type="text"
452
+ placeholder="Search products..."
453
+ className="w-full pl-10 pr-4 py-2 border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
454
+ value={searchQuery}
455
+ onChange={(e) => setSearchQuery(e.target.value)}
456
+ />
457
+ </div>
458
+ </div>
459
+
460
+ {/* Category Combobox */}
461
+ <div>
462
+ <Combobox
463
+ items={categories}
464
+ value={selectedCategory}
465
+ onValueChange={setSelectedCategory}
466
+ placeholder="Select category"
467
+ searchPlaceholder="Search categories..."
468
+ />
469
+ </div>
470
+
471
+ {/* Status Combobox */}
472
+ <div>
473
+ <Combobox
474
+ items={statuses}
475
+ value={selectedStatus}
476
+ onValueChange={setSelectedStatus}
477
+ placeholder="Select status"
478
+ searchPlaceholder="Search statuses..."
479
+ />
480
+ </div>
481
+
482
+ {/* Country Combobox */}
483
+ <div>
484
+ <Combobox
485
+ items={countries}
486
+ value={selectedCountry}
487
+ onValueChange={setSelectedCountry}
488
+ placeholder="Select country"
489
+ searchPlaceholder="Search countries..."
490
+ />
491
+ </div>
492
+
493
+ {/* Tags MultiCombobox */}
494
+ <div className="lg:col-span-2">
495
+ <MultiCombobox
496
+ items={tags}
497
+ value={selectedTags}
498
+ onValueChange={setSelectedTags}
499
+ placeholder="Select tags"
500
+ searchPlaceholder="Search tags..."
501
+ />
502
+ </div>
503
+ </div>
504
+
505
+ {/* Results */}
506
+ <div>
507
+ <h3 className="text-lg font-medium text-foreground mb-4">
508
+ Products ({filteredProducts.length} items)
509
+ </h3>
510
+
511
+ {filteredProducts.length === 0 ? (
512
+ <p className="text-muted-foreground">No products match your filters.</p>
513
+ ) : (
514
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
515
+ {filteredProducts.map(product => (
516
+ <div key={product.id} className="border rounded-lg p-4 bg-background">
517
+ <h4 className="font-medium text-foreground mb-2">{product.name}</h4>
518
+ <div className="grid grid-cols-2 gap-2 text-sm text-muted-foreground">
519
+ <div>
520
+ <span className="font-medium">Category:</span> {product.category}
521
+ </div>
522
+ <div>
523
+ <span className="font-medium">Status:</span> {product.status}
524
+ </div>
525
+ <div>
526
+ <span className="font-medium">Country:</span> {countries.find(c => c.value === product.country)?.label}
527
+ </div>
528
+ <div>
529
+ <span className="font-medium">Tags:</span> {product.tags.join(", ")}
530
+ </div>
531
+ </div>
532
+ </div>
533
+ ))}
534
+ </div>
535
+ )}
536
+ </div>
537
+ </div>
538
+
539
+ {/* Single Combobox Examples */}
540
+ <div className="bg-card p-6 rounded-lg border mb-8">
541
+ <h2 className="text-xl font-semibold text-foreground mb-4">Single Selection Comboboxes</h2>
542
+
543
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
544
+ <div className="space-y-2">
545
+ <label className="text-sm font-medium text-foreground">Country</label>
546
+ <Combobox
547
+ items={countries}
548
+ value={selectedCountry}
549
+ onValueChange={setSelectedCountry}
550
+ placeholder="Select a country"
551
+ />
552
+ </div>
553
+
554
+ <div className="space-y-2">
555
+ <label className="text-sm font-medium text-foreground">Status</label>
556
+ <Combobox
557
+ items={statuses}
558
+ value={selectedStatus}
559
+ onValueChange={setSelectedStatus}
560
+ placeholder="Select status"
561
+ />
562
+ </div>
563
+
564
+ <div className="space-y-2">
565
+ <label className="text-sm font-medium text-foreground">Category</label>
566
+ <Combobox
567
+ items={categories}
568
+ value={selectedCategory}
569
+ onValueChange={setSelectedCategory}
570
+ placeholder="Select category"
571
+ />
572
+ </div>
573
+ </div>
574
+ </div>
575
+
576
+ {/* Multi Combobox Examples */}
577
+ <div className="bg-card p-6 rounded-lg border mb-8">
578
+ <h2 className="text-xl font-semibold text-foreground mb-4">Multiple Selection Comboboxes</h2>
579
+
580
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
581
+ <div className="space-y-2">
582
+ <label className="text-sm font-medium text-foreground">Tags</label>
583
+ <MultiCombobox
584
+ items={tags}
585
+ value={selectedTags}
586
+ onValueChange={setSelectedTags}
587
+ placeholder="Select tags"
588
+ />
589
+ </div>
590
+
591
+ <div className="space-y-2">
592
+ <label className="text-sm font-medium text-foreground">Team Members</label>
593
+ <MultiCombobox
594
+ items={users}
595
+ value={selectedUsers}
596
+ onValueChange={setSelectedUsers}
597
+ placeholder="Select team members"
598
+ />
599
+ </div>
600
+ </div>
601
+
602
+ {selectedUsers.length > 0 && (
603
+ <div className="mt-4 p-4 bg-muted rounded-md">
604
+ <h3 className="font-medium text-foreground mb-2">Selected Team Members:</h3>
605
+ <div className="space-y-2">
606
+ {selectedUsers.map(userId => {
607
+ const user = users.find(u => u.value === userId)
608
+ return user ? (
609
+ <div key={user.value} className="flex items-center space-x-3 p-2 bg-background rounded-md">
610
+ <div className="flex items-center justify-center h-8 w-8 rounded-full bg-primary text-primary-foreground">
611
+ <User className="h-4 w-4" />
612
+ </div>
613
+ <div>
614
+ <div className="text-sm font-medium text-foreground">{user.label}</div>
615
+ <div className="text-xs text-muted-foreground">{user.email}</div>
616
+ </div>
617
+ </div>
618
+ ) : null
619
+ })}
620
+ </div>
621
+ </div>
622
+ )}
623
+ </div>
624
+
625
+ {/* Combobox with Icons */}
626
+ <div className="bg-card p-6 rounded-lg border">
627
+ <h2 className="text-xl font-semibold text-foreground mb-4">Combobox with Custom Items</h2>
628
+
629
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
630
+ <div className="space-y-2">
631
+ <label className="text-sm font-medium text-foreground">Payment Method</label>
632
+ <Combobox
633
+ items={[
634
+ { value: "credit-card", label: "Credit Card" },
635
+ { value: "paypal", label: "PayPal" },
636
+ { value: "bank-transfer", label: "Bank Transfer" },
637
+ ]}
638
+ placeholder="Select payment method"
639
+ />
640
+ </div>
641
+
642
+ <div className="space-y-2">
643
+ <label className="text-sm font-medium text-foreground">Shipping Method</label>
644
+ <Combobox
645
+ items={[
646
+ { value: "standard", label: "Standard Shipping" },
647
+ { value: "express", label: "Express Shipping" },
648
+ { value: "priority", label: "Priority Shipping" },
649
+ ]}
650
+ placeholder="Select shipping method"
651
+ />
652
+ </div>
653
+ </div>
654
+ </div>
655
+ </div>
656
+ )
657
+ }`,
658
+ basicusage: `
659
+ const [selectedCategory, setSelectedCategory] = useState("")
660
+
661
+
662
+ const categories = [
663
+ { value: "electronics", label: "Electronics" },
664
+ { value: "clothing", label: "Clothing" },
665
+ { value: "books", label: "Books" },
666
+ { value: "home", label: "Home & Garden" },
667
+ { value: "sports", label: "Sports & Outdoors" },
668
+ { value: "beauty", label: "Beauty & Personal Care" },
669
+ { value: "toys", label: "Toys & Games" },
670
+ ]
671
+
672
+ <ComboboxV1
673
+ items={categories}
674
+ value={selectedCategory}
675
+ onValueChange={setSelectedCategory}
676
+ placeholder="Select category"
677
+ searchPlaceholder="Search categories..."
678
+ />`,
679
+ usagePath: null,
680
+ desc: null,
681
+ customize: null,
682
+ props: {
683
+ "ComboboxV1": [
684
+ { name: "items", type: "ComboboxItem[]", default: "null" },
685
+ { name: "value", type: "string", default: "null" },
686
+ { name: "onValueChange", type: "(value: string) => void", default: "null" },
687
+ { name: "placeholder", type: "string", default: "Select an item..." },
688
+ { name: "disabled", type: "boolean", default: "false" },
689
+ { name: "className", type: "string", default: "null" },
690
+ { name: "searchPlaceholder", type: "string", default: "Search..." },
691
+ { name: "emptyText", type: "string", default: "No results found." },
692
+ ]
693
+ }
694
+ },
695
+ {
696
+ name: "multi combobox",
697
+ value: "multi-combobox",
698
+ importPath: "~/components/catalyst-ui/comboboxes/multi-combobox",
699
+ path: "/components/catalyst-ui/comboboxes/multi-combobox.tsx",
700
+ premium: true,
701
+ source: null,
702
+ category: "Comboboxes",
703
+ tags: ["ui", "forms", "core"],
704
+ features: ["Responsive", "TypeScript", "Accessible"],
705
+ dependencies: ["lucide-react"],
706
+ usage: `
707
+
708
+
709
+
710
+
711
+
712
+
713
+ export const meta: MetaFunction = () => {
714
+ return [
715
+ { title: "Comboboxes Demo" },
716
+ { name: "description", content: "Demo of combobox components with various styles and functionality" },
717
+ ]
718
+ }
719
+
720
+ export default function ComboboxesDemo() {
721
+ const [selectedCountry, setSelectedCountry] = useState("")
722
+ const [selectedCategory, setSelectedCategory] = useState("")
723
+ const [selectedStatus, setSelectedStatus] = useState("")
724
+ const [selectedTags, setSelectedTags] = useState<string[]>([])
725
+ const [selectedUsers, setSelectedUsers] = useState<string[]>([])
726
+ const [searchQuery, setSearchQuery] = useState("")
727
+
728
+ // Sample data
729
+ const countries = [
730
+ { value: "us", label: "United States" },
731
+ { value: "ca", label: "Canada" },
732
+ { value: "uk", label: "United Kingdom" },
733
+ { value: "au", label: "Australia" },
734
+ { value: "de", label: "Germany" },
735
+ { value: "fr", label: "France" },
736
+ { value: "jp", label: "Japan" },
737
+ { value: "br", label: "Brazil" },
738
+ ]
739
+
740
+ const categories = [
741
+ { value: "electronics", label: "Electronics" },
742
+ { value: "clothing", label: "Clothing" },
743
+ { value: "books", label: "Books" },
744
+ { value: "home", label: "Home & Garden" },
745
+ { value: "sports", label: "Sports & Outdoors" },
746
+ { value: "beauty", label: "Beauty & Personal Care" },
747
+ { value: "toys", label: "Toys & Games" },
748
+ ]
749
+
750
+ const statuses = [
751
+ { value: "active", label: "Active" },
752
+ { value: "pending", label: "Pending" },
753
+ { value: "draft", label: "Draft" },
754
+ { value: "archived", label: "Archived" },
755
+ ]
756
+
757
+ const tags = [
758
+ { value: "featured", label: "Featured" },
759
+ { value: "sale", label: "On Sale" },
760
+ { value: "new", label: "New Arrival" },
761
+ { value: "popular", label: "Popular" },
762
+ { value: "limited", label: "Limited Edition" },
763
+ { value: "clearance", label: "Clearance" },
764
+ ]
765
+
766
+ const users = [
767
+ { value: "alice", label: "Alice Johnson", email: "alice@example.com" },
768
+ { value: "bob", label: "Bob Smith", email: "bob@example.com" },
769
+ { value: "carol", label: "Carol Williams", email: "carol@example.com" },
770
+ { value: "dave", label: "Dave Brown", email: "dave@example.com" },
771
+ { value: "eve", label: "Eve Davis", email: "eve@example.com" },
772
+ { value: "frank", label: "Frank Miller", email: "frank@example.com" },
773
+ ]
774
+
775
+ // Sample products data
776
+ const products = [
777
+ { id: 1, name: "Wireless Headphones", category: "electronics", tags: ["featured", "new"], status: "active", country: "us" },
778
+ { id: 2, name: "Cotton T-Shirt", category: "clothing", tags: ["sale"], status: "active", country: "ca" },
779
+ { id: 3, name: "Programming Book", category: "books", tags: ["popular"], status: "draft", country: "uk" },
780
+ { id: 4, name: "Desk Lamp", category: "home", tags: ["new"], status: "active", country: "de" },
781
+ { id: 5, name: "Yoga Mat", category: "sports", tags: ["featured", "sale"], status: "active", country: "us" },
782
+ { id: 6, name: "Face Cream", category: "beauty", tags: ["new", "limited"], status: "pending", country: "fr" },
783
+ { id: 7, name: "Board Game", category: "toys", tags: ["popular", "clearance"], status: "active", country: "ca" },
784
+ { id: 8, name: "Smart Watch", category: "electronics", tags: ["featured", "new"], status: "archived", country: "jp" },
785
+ ]
786
+
787
+ // Filter products based on selected filters and search query
788
+ const filteredProducts = products.filter(product => {
789
+ // Filter by category if selected
790
+ if (selectedCategory && product.category !== selectedCategory) return false
791
+
792
+ // Filter by status if selected
793
+ if (selectedStatus && product.status !== selectedStatus) return false
794
+
795
+ // Filter by country if selected
796
+ if (selectedCountry && product.country !== selectedCountry) return false
797
+
798
+ // Filter by tags if selected
799
+ if (selectedTags.length > 0 && !selectedTags.some(tag => product.tags.includes(tag))) return false
800
+
801
+ // Filter by search query
802
+ if (searchQuery && !product.name.toLowerCase().includes(searchQuery.toLowerCase())) return false
803
+
804
+ return true
805
+ })
806
+
807
+ return (
808
+ <div className="container mx-auto py-10 px-4 max-w-6xl">
809
+ <div className="mb-10">
810
+ <h1 className="text-3xl font-bold text-foreground mb-2">Combobox Components</h1>
811
+ <p className="text-muted-foreground">
812
+ Various combobox styles and implementations with functional examples.
813
+ </p>
814
+ </div>
815
+
816
+ {/* Filterable Products Section */}
817
+ <div className="bg-card p-6 rounded-lg border mb-8">
818
+ <h2 className="text-xl font-semibold text-foreground mb-4">Product Filter with Comboboxes</h2>
819
+
820
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-4 gap-4 mb-6">
821
+ {/* Search Input */}
822
+ <div className="lg:col-span-2">
823
+ <div className="relative">
824
+ <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-muted-foreground" />
825
+ <input
826
+ type="text"
827
+ placeholder="Search products..."
828
+ className="w-full pl-10 pr-4 py-2 border rounded-md bg-background text-foreground focus:outline-none focus:ring-2 focus:ring-ring"
829
+ value={searchQuery}
830
+ onChange={(e) => setSearchQuery(e.target.value)}
831
+ />
832
+ </div>
833
+ </div>
834
+
835
+ {/* Category Combobox */}
836
+ <div>
837
+ <Combobox
838
+ items={categories}
839
+ value={selectedCategory}
840
+ onValueChange={setSelectedCategory}
841
+ placeholder="Select category"
842
+ searchPlaceholder="Search categories..."
843
+ />
844
+ </div>
845
+
846
+ {/* Status Combobox */}
847
+ <div>
848
+ <Combobox
849
+ items={statuses}
850
+ value={selectedStatus}
851
+ onValueChange={setSelectedStatus}
852
+ placeholder="Select status"
853
+ searchPlaceholder="Search statuses..."
854
+ />
855
+ </div>
856
+
857
+ {/* Country Combobox */}
858
+ <div>
859
+ <Combobox
860
+ items={countries}
861
+ value={selectedCountry}
862
+ onValueChange={setSelectedCountry}
863
+ placeholder="Select country"
864
+ searchPlaceholder="Search countries..."
865
+ />
866
+ </div>
867
+
868
+ {/* Tags MultiCombobox */}
869
+ <div className="lg:col-span-2">
870
+ <MultiCombobox
871
+ items={tags}
872
+ value={selectedTags}
873
+ onValueChange={setSelectedTags}
874
+ placeholder="Select tags"
875
+ searchPlaceholder="Search tags..."
876
+ />
877
+ </div>
878
+ </div>
879
+
880
+ {/* Results */}
881
+ <div>
882
+ <h3 className="text-lg font-medium text-foreground mb-4">
883
+ Products ({filteredProducts.length} items)
884
+ </h3>
885
+
886
+ {filteredProducts.length === 0 ? (
887
+ <p className="text-muted-foreground">No products match your filters.</p>
888
+ ) : (
889
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-4">
890
+ {filteredProducts.map(product => (
891
+ <div key={product.id} className="border rounded-lg p-4 bg-background">
892
+ <h4 className="font-medium text-foreground mb-2">{product.name}</h4>
893
+ <div className="grid grid-cols-2 gap-2 text-sm text-muted-foreground">
894
+ <div>
895
+ <span className="font-medium">Category:</span> {product.category}
896
+ </div>
897
+ <div>
898
+ <span className="font-medium">Status:</span> {product.status}
899
+ </div>
900
+ <div>
901
+ <span className="font-medium">Country:</span> {countries.find(c => c.value === product.country)?.label}
902
+ </div>
903
+ <div>
904
+ <span className="font-medium">Tags:</span> {product.tags.join(", ")}
905
+ </div>
906
+ </div>
907
+ </div>
908
+ ))}
909
+ </div>
910
+ )}
911
+ </div>
912
+ </div>
913
+
914
+ {/* Single Combobox Examples */}
915
+ <div className="bg-card p-6 rounded-lg border mb-8">
916
+ <h2 className="text-xl font-semibold text-foreground mb-4">Single Selection Comboboxes</h2>
917
+
918
+ <div className="grid grid-cols-1 md:grid-cols-2 lg:grid-cols-3 gap-6">
919
+ <div className="space-y-2">
920
+ <label className="text-sm font-medium text-foreground">Country</label>
921
+ <Combobox
922
+ items={countries}
923
+ value={selectedCountry}
924
+ onValueChange={setSelectedCountry}
925
+ placeholder="Select a country"
926
+ />
927
+ </div>
928
+
929
+ <div className="space-y-2">
930
+ <label className="text-sm font-medium text-foreground">Status</label>
931
+ <Combobox
932
+ items={statuses}
933
+ value={selectedStatus}
934
+ onValueChange={setSelectedStatus}
935
+ placeholder="Select status"
936
+ />
937
+ </div>
938
+
939
+ <div className="space-y-2">
940
+ <label className="text-sm font-medium text-foreground">Category</label>
941
+ <Combobox
942
+ items={categories}
943
+ value={selectedCategory}
944
+ onValueChange={setSelectedCategory}
945
+ placeholder="Select category"
946
+ />
947
+ </div>
948
+ </div>
949
+ </div>
950
+
951
+ {/* Multi Combobox Examples */}
952
+ <div className="bg-card p-6 rounded-lg border mb-8">
953
+ <h2 className="text-xl font-semibold text-foreground mb-4">Multiple Selection Comboboxes</h2>
954
+
955
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
956
+ <div className="space-y-2">
957
+ <label className="text-sm font-medium text-foreground">Tags</label>
958
+ <MultiCombobox
959
+ items={tags}
960
+ value={selectedTags}
961
+ onValueChange={setSelectedTags}
962
+ placeholder="Select tags"
963
+ />
964
+ </div>
965
+
966
+ <div className="space-y-2">
967
+ <label className="text-sm font-medium text-foreground">Team Members</label>
968
+ <MultiCombobox
969
+ items={users}
970
+ value={selectedUsers}
971
+ onValueChange={setSelectedUsers}
972
+ placeholder="Select team members"
973
+ />
974
+ </div>
975
+ </div>
976
+
977
+ {selectedUsers.length > 0 && (
978
+ <div className="mt-4 p-4 bg-muted rounded-md">
979
+ <h3 className="font-medium text-foreground mb-2">Selected Team Members:</h3>
980
+ <div className="space-y-2">
981
+ {selectedUsers.map(userId => {
982
+ const user = users.find(u => u.value === userId)
983
+ return user ? (
984
+ <div key={user.value} className="flex items-center space-x-3 p-2 bg-background rounded-md">
985
+ <div className="flex items-center justify-center h-8 w-8 rounded-full bg-primary text-primary-foreground">
986
+ <User className="h-4 w-4" />
987
+ </div>
988
+ <div>
989
+ <div className="text-sm font-medium text-foreground">{user.label}</div>
990
+ <div className="text-xs text-muted-foreground">{user.email}</div>
991
+ </div>
992
+ </div>
993
+ ) : null
994
+ })}
995
+ </div>
996
+ </div>
997
+ )}
998
+ </div>
999
+
1000
+ {/* Combobox with Icons */}
1001
+ <div className="bg-card p-6 rounded-lg border">
1002
+ <h2 className="text-xl font-semibold text-foreground mb-4">Combobox with Custom Items</h2>
1003
+
1004
+ <div className="grid grid-cols-1 md:grid-cols-2 gap-6">
1005
+ <div className="space-y-2">
1006
+ <label className="text-sm font-medium text-foreground">Payment Method</label>
1007
+ <Combobox
1008
+ items={[
1009
+ { value: "credit-card", label: "Credit Card" },
1010
+ { value: "paypal", label: "PayPal" },
1011
+ { value: "bank-transfer", label: "Bank Transfer" },
1012
+ ]}
1013
+ placeholder="Select payment method"
1014
+ />
1015
+ </div>
1016
+
1017
+ <div className="space-y-2">
1018
+ <label className="text-sm font-medium text-foreground">Shipping Method</label>
1019
+ <Combobox
1020
+ items={[
1021
+ { value: "standard", label: "Standard Shipping" },
1022
+ { value: "express", label: "Express Shipping" },
1023
+ { value: "priority", label: "Priority Shipping" },
1024
+ ]}
1025
+ placeholder="Select shipping method"
1026
+ />
1027
+ </div>
1028
+ </div>
1029
+ </div>
1030
+ </div>
1031
+ )
1032
+ }`,
1033
+ basicusage: `
1034
+
1035
+ const frameworks = [
1036
+ { value: "react", label: "React" },
1037
+ { value: "vue", label: "Vue.js" },
1038
+ { value: "angular", label: "Angular" },
1039
+ { value: "svelte", label: "Svelte" },
1040
+ { value: "nextjs", label: "Next.js" },
1041
+ { value: "nuxtjs", label: "Nuxt.js" },
1042
+ { value: "gatsby", label: "Gatsby" },
1043
+ { value: "remix", label: "Remix" },
1044
+ ];
1045
+ const [selectedFrameworks, setSelectedFrameworks] = useState(['react', 'nextjs']);
1046
+ <MultiCombobox
1047
+ items={frameworks}
1048
+ value={selectedFrameworks}
1049
+ onValueChange={setSelectedFrameworks}
1050
+ placeholder="Choose your frameworks..."
1051
+ searchPlaceholder="Search frameworks..."
1052
+ />`,
1053
+ usagePath: null,
1054
+ desc: null,
1055
+ customize: null,
1056
+ props: {
1057
+ "MultiCombobox": [
1058
+ { name: "items", type: "MultiComboboxItem[]", default: "null" },
1059
+ { name: "value", type: "string[]", default: "[]" },
1060
+ { name: "onValueChange", type: "(value: string[]) => void", default: "null" },
1061
+ { name: "placeholder", type: "string", default: "Select items..." },
1062
+ { name: "disabled", type: "boolean", default: "false" },
1063
+ { name: "className", type: "string", default: "null" },
1064
+ { name: "searchPlaceholder", type: "string", default: "Search..." },
1065
+ { name: "emptyText", type: "string", default: "No results found." },
1066
+ ]
1067
+ }
1068
+ },
1069
+ {
1070
+ name: "nested combobox",
1071
+ value: "nested-combobox",
1072
+ importPath: "~/components/catalyst-ui/comboboxes/nested-combobox",
1073
+ path: "/components/catalyst-ui/comboboxes/nested-combobox.tsx",
1074
+ premium: true,
1075
+ source: null,
1076
+ category: "Comboboxes",
1077
+ tags: ["utils", "auth", "user auth"],
1078
+ features: ["utils", "auth", "user auth"],
1079
+ dependencies: [],
1080
+ usage: `
1081
+
1082
+ export function NestedComboboxDemo() {
1083
+ const [frameworkValue, setFrameworkValue] = useState("");
1084
+ const [projectValue, setProjectValue] = useState("");
1085
+ const [settingsValue, setSettingsValue] = useState("");
1086
+
1087
+ const frameworkPages = [
1088
+ {
1089
+ id: 'root',
1090
+ items: [
1091
+ { id: 'next.js', label: 'Next.js', icon: <FolderOpen size={16} /> },
1092
+ { id: 'sveltekit', label: 'SvelteKit', icon: <FolderOpen size={16} /> },
1093
+ { id: 'nuxt.js', label: 'Nuxt.js', icon: <FolderOpen size={16} /> },
1094
+ { id: 'remix', label: 'Remix', icon: <FolderOpen size={16} /> },
1095
+ { id: 'astro', label: 'Astro', icon: <FolderOpen size={16} /> },
1096
+ ]
1097
+ }
1098
+ ];
1099
+
1100
+ const projectPages = [
1101
+ {
1102
+ id: 'main',
1103
+ title: 'Categories',
1104
+ items: [
1105
+ {
1106
+ id: 'projects-nav',
1107
+ label: 'Projects',
1108
+ icon: <FolderOpen size={16} />,
1109
+ navigateTo: 'projects'
1110
+ },
1111
+ {
1112
+ id: 'teams-nav',
1113
+ label: 'Teams',
1114
+ icon: <Users size={16} />,
1115
+ navigateTo: 'teams'
1116
+ }
1117
+ ]
1118
+ },
1119
+ {
1120
+ id: 'projects',
1121
+ title: 'Available Projects',
1122
+ items: [
1123
+ {
1124
+ id: 'project-alpha',
1125
+ label: 'Project Alpha',
1126
+ value: 'alpha',
1127
+ icon: <FolderOpen size={16} />
1128
+ },
1129
+ {
1130
+ id: 'project-beta',
1131
+ label: 'Project Beta',
1132
+ value: 'beta',
1133
+ icon: <FolderOpen size={16} />
1134
+ },
1135
+ {
1136
+ id: 'project-gamma',
1137
+ label: 'Project Gamma',
1138
+ value: 'gamma',
1139
+ icon: <FolderOpen size={16} />
1140
+ }
1141
+ ]
1142
+ },
1143
+ {
1144
+ id: 'teams',
1145
+ title: 'Available Teams',
1146
+ items: [
1147
+ {
1148
+ id: 'frontend-team',
1149
+ label: 'Frontend Team',
1150
+ value: 'frontend',
1151
+ icon: <Users size={16} />
1152
+ },
1153
+ {
1154
+ id: 'backend-team',
1155
+ label: 'Backend Team',
1156
+ value: 'backend',
1157
+ icon: <Users size={16} />
1158
+ },
1159
+ {
1160
+ id: 'design-team',
1161
+ label: 'Design Team',
1162
+ value: 'design',
1163
+ icon: <Users size={16} />
1164
+ }
1165
+ ]
1166
+ }
1167
+ ];
1168
+
1169
+ const settingsPages = [
1170
+ {
1171
+ id: 'main',
1172
+ title: 'Settings',
1173
+ items: [
1174
+ {
1175
+ id: 'general',
1176
+ label: 'General Settings',
1177
+ icon: <Settings size={16} />,
1178
+ navigateTo: 'general'
1179
+ },
1180
+ {
1181
+ id: 'appearance',
1182
+ label: 'Appearance',
1183
+ icon: <Palette size={16} />,
1184
+ navigateTo: 'themes'
1185
+ }
1186
+ ]
1187
+ },
1188
+ {
1189
+ id: 'general',
1190
+ title: 'General',
1191
+ items: [
1192
+ {
1193
+ id: 'notifications',
1194
+ label: 'Enable Notifications',
1195
+ value: 'notifications',
1196
+ icon: <Bell size={16} />
1197
+ },
1198
+ {
1199
+ id: 'security',
1200
+ label: 'Security Settings',
1201
+ value: 'security',
1202
+ icon: <Shield size={16} />
1203
+ }
1204
+ ]
1205
+ },
1206
+ {
1207
+ id: 'themes',
1208
+ title: 'Themes',
1209
+ items: [
1210
+ {
1211
+ id: 'light',
1212
+ label: 'Light Theme',
1213
+ value: 'light',
1214
+ icon: <Sun size={16} />
1215
+ },
1216
+ {
1217
+ id: 'dark',
1218
+ label: 'Dark Theme',
1219
+ value: 'dark',
1220
+ icon: <Moon size={16} />
1221
+ }
1222
+ ]
1223
+ }
1224
+ ];
1225
+
1226
+ return (
1227
+ <div className="max-w-4xl mx-auto p-6 space-y-8">
1228
+ <div className="text-center">
1229
+ <h1 className="text-3xl font-bold mb-2">NestedCombobox Component</h1>
1230
+ <p className="text-muted-foreground">Combobox with nested navigation support</p>
1231
+ </div>
1232
+
1233
+ <div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
1234
+ <div className="space-y-4">
1235
+ <h3 className="text-lg font-semibold">Simple Framework Selection</h3>
1236
+ <p className="text-sm text-muted-foreground">Basic combobox without nesting</p>
1237
+ <NestedCombobox
1238
+ pages={frameworkPages}
1239
+ placeholder="Select framework..."
1240
+ value={frameworkValue}
1241
+ onValueChange={setFrameworkValue}
1242
+ defaultPage="root"
1243
+ width="w-full"
1244
+ />
1245
+ {frameworkValue && (
1246
+ <p className="text-sm text-muted-foreground">Selected: {frameworkValue}</p>
1247
+ )}
1248
+ </div>
1249
+
1250
+ <div className="space-y-4">
1251
+ <h3 className="text-lg font-semibold">Project & Team Selection</h3>
1252
+ <p className="text-sm text-muted-foreground">Navigate through categories to select</p>
1253
+ <NestedCombobox
1254
+ pages={projectPages}
1255
+ placeholder="Choose project or team..."
1256
+ value={projectValue}
1257
+ onValueChange={setProjectValue}
1258
+ width="w-full"
1259
+ />
1260
+ {projectValue && (
1261
+ <p className="text-sm text-muted-foreground">Selected: {projectValue}</p>
1262
+ )}
1263
+ </div>
1264
+
1265
+ <div className="space-y-4">
1266
+ <h3 className="text-lg font-semibold">Settings Selection</h3>
1267
+ <p className="text-sm text-muted-foreground">Choose from nested settings options</p>
1268
+ <NestedCombobox
1269
+ pages={settingsPages}
1270
+ placeholder="Select setting..."
1271
+ value={settingsValue}
1272
+ onValueChange={setSettingsValue}
1273
+ width="w-full"
1274
+ />
1275
+ {settingsValue && (
1276
+ <p className="text-sm text-muted-foreground">Selected: {settingsValue}</p>
1277
+ )}
1278
+ </div>
1279
+ </div>
1280
+
1281
+ <div className="space-y-4">
1282
+ <h2 className="text-xl font-semibold">Navigation Instructions</h2>
1283
+ <div className="text-sm text-muted-foreground space-y-1">
1284
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">Escape</kbd> - Go back or close</p>
1285
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">Backspace</kbd> - Go back when search is empty</p>
1286
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">Enter</kbd> - Select item or navigate deeper</p>
1287
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">↑↓</kbd> - Navigate items</p>
1288
+ <p>Click "Back" button or use keyboard to navigate between levels</p>
1289
+ </div>
1290
+ </div>
1291
+
1292
+ <div className="space-y-4">
1293
+ <h2 className="text-xl font-semibold">Current Values</h2>
1294
+ <div className="grid gap-4 md:grid-cols-3">
1295
+ <div className="p-4 border rounded-lg">
1296
+ <h4 className="font-medium">Framework</h4>
1297
+ <p className="text-sm text-muted-foreground">{frameworkValue || 'None selected'}</p>
1298
+ </div>
1299
+ <div className="p-4 border rounded-lg">
1300
+ <h4 className="font-medium">Project/Team</h4>
1301
+ <p className="text-sm text-muted-foreground">{projectValue || 'None selected'}</p>
1302
+ </div>
1303
+ <div className="p-4 border rounded-lg">
1304
+ <h4 className="font-medium">Setting</h4>
1305
+ <p className="text-sm text-muted-foreground">{settingsValue || 'None selected'}</p>
1306
+ </div>
1307
+ </div>
1308
+ </div>
1309
+ </div>
1310
+ );
1311
+ }`,
1312
+ basicusage: `
1313
+
1314
+
1315
+ const [frameworkValue, setFrameworkValue] = useState("");
1316
+ const [projectValue, setProjectValue] = useState("");
1317
+ const [settingsValue, setSettingsValue] = useState("");
1318
+
1319
+ const frameworkPages = [
1320
+ {
1321
+ id: 'root',
1322
+ items: [
1323
+ { id: 'next.js', label: 'Next.js', icon: <FolderOpen size={16} /> },
1324
+ { id: 'sveltekit', label: 'SvelteKit', icon: <FolderOpen size={16} /> },
1325
+ { id: 'nuxt.js', label: 'Nuxt.js', icon: <FolderOpen size={16} /> },
1326
+ { id: 'remix', label: 'Remix', icon: <FolderOpen size={16} /> },
1327
+ { id: 'astro', label: 'Astro', icon: <FolderOpen size={16} /> },
1328
+ ]
1329
+ }
1330
+ ];
1331
+
1332
+ const projectPages = [
1333
+ {
1334
+ id: 'main',
1335
+ title: 'Categories',
1336
+ items: [
1337
+ {
1338
+ id: 'projects-nav',
1339
+ label: 'Projects',
1340
+ icon: <FolderOpen size={16} />,
1341
+ navigateTo: 'projects'
1342
+ },
1343
+ {
1344
+ id: 'teams-nav',
1345
+ label: 'Teams',
1346
+ icon: <Users size={16} />,
1347
+ navigateTo: 'teams'
1348
+ }
1349
+ ]
1350
+ },
1351
+ {
1352
+ id: 'projects',
1353
+ title: 'Available Projects',
1354
+ items: [
1355
+ {
1356
+ id: 'project-alpha',
1357
+ label: 'Project Alpha',
1358
+ value: 'alpha',
1359
+ icon: <FolderOpen size={16} />
1360
+ },
1361
+ {
1362
+ id: 'project-beta',
1363
+ label: 'Project Beta',
1364
+ value: 'beta',
1365
+ icon: <FolderOpen size={16} />
1366
+ },
1367
+ {
1368
+ id: 'project-gamma',
1369
+ label: 'Project Gamma',
1370
+ value: 'gamma',
1371
+ icon: <FolderOpen size={16} />
1372
+ }
1373
+ ]
1374
+ },
1375
+ {
1376
+ id: 'teams',
1377
+ title: 'Available Teams',
1378
+ items: [
1379
+ {
1380
+ id: 'frontend-team',
1381
+ label: 'Frontend Team',
1382
+ value: 'frontend',
1383
+ icon: <Users size={16} />
1384
+ },
1385
+ {
1386
+ id: 'backend-team',
1387
+ label: 'Backend Team',
1388
+ value: 'backend',
1389
+ icon: <Users size={16} />
1390
+ },
1391
+ {
1392
+ id: 'design-team',
1393
+ label: 'Design Team',
1394
+ value: 'design',
1395
+ icon: <Users size={16} />
1396
+ }
1397
+ ]
1398
+ }
1399
+ ];
1400
+
1401
+ const settingsPages = [
1402
+ {
1403
+ id: 'main',
1404
+ title: 'Settings',
1405
+ items: [
1406
+ {
1407
+ id: 'general',
1408
+ label: 'General Settings',
1409
+ icon: <Settings size={16} />,
1410
+ navigateTo: 'general'
1411
+ },
1412
+ {
1413
+ id: 'appearance',
1414
+ label: 'Appearance',
1415
+ icon: <Palette size={16} />,
1416
+ navigateTo: 'themes'
1417
+ }
1418
+ ]
1419
+ },
1420
+ {
1421
+ id: 'general',
1422
+ title: 'General',
1423
+ items: [
1424
+ {
1425
+ id: 'notifications',
1426
+ label: 'Enable Notifications',
1427
+ value: 'notifications',
1428
+ icon: <Bell size={16} />
1429
+ },
1430
+ {
1431
+ id: 'security',
1432
+ label: 'Security Settings',
1433
+ value: 'security',
1434
+ icon: <Shield size={16} />
1435
+ }
1436
+ ]
1437
+ },
1438
+ {
1439
+ id: 'themes',
1440
+ title: 'Themes',
1441
+ items: [
1442
+ {
1443
+ id: 'light',
1444
+ label: 'Light Theme',
1445
+ value: 'light',
1446
+ icon: <Sun size={16} />
1447
+ },
1448
+ {
1449
+ id: 'dark',
1450
+ label: 'Dark Theme',
1451
+ value: 'dark',
1452
+ icon: <Moon size={16} />
1453
+ }
1454
+ ]
1455
+ }
1456
+ ]
1457
+ <div className="max-w-4xl mx-auto p-6 space-y-8">
1458
+ <div className="text-center">
1459
+ <h1 className="text-3xl font-bold mb-2">NestedCombobox Component</h1>
1460
+ <p className="text-muted-foreground">Combobox with nested navigation support</p>
1461
+ </div>
1462
+
1463
+ <div className="grid gap-8 md:grid-cols-2 lg:grid-cols-3">
1464
+ <div className="space-y-4">
1465
+ <h3 className="text-lg font-semibold">Simple Framework Selection</h3>
1466
+ <p className="text-sm text-muted-foreground">Basic combobox without nesting</p>
1467
+ <NestedCombobox
1468
+ pages={frameworkPages}
1469
+ placeholder="Select framework..."
1470
+ value={frameworkValue}
1471
+ onValueChange={setFrameworkValue}
1472
+ defaultPage="root"
1473
+ width="w-full"
1474
+ />
1475
+ {frameworkValue && (
1476
+ <p className="text-sm text-muted-foreground">Selected: {frameworkValue}</p>
1477
+ )}
1478
+ </div>
1479
+
1480
+ <div className="space-y-4">
1481
+ <h3 className="text-lg font-semibold">Project & Team Selection</h3>
1482
+ <p className="text-sm text-muted-foreground">Navigate through categories to select</p>
1483
+ <NestedCombobox
1484
+ pages={projectPages}
1485
+ placeholder="Choose project or team..."
1486
+ value={projectValue}
1487
+ onValueChange={setProjectValue}
1488
+ width="w-full"
1489
+ />
1490
+ {projectValue && (
1491
+ <p className="text-sm text-muted-foreground">Selected: {projectValue}</p>
1492
+ )}
1493
+ </div>
1494
+
1495
+ <div className="space-y-4">
1496
+ <h3 className="text-lg font-semibold">Settings Selection</h3>
1497
+ <p className="text-sm text-muted-foreground">Choose from nested settings options</p>
1498
+ <NestedCombobox
1499
+ pages={settingsPages}
1500
+ placeholder="Select setting..."
1501
+ value={settingsValue}
1502
+ onValueChange={setSettingsValue}
1503
+ width="w-full"
1504
+ />
1505
+ {settingsValue && (
1506
+ <p className="text-sm text-muted-foreground">Selected: {settingsValue}</p>
1507
+ )}
1508
+ </div>
1509
+ </div>
1510
+
1511
+ <div className="space-y-4">
1512
+ <h2 className="text-xl font-semibold">Navigation Instructions</h2>
1513
+ <div className="text-sm text-muted-foreground space-y-1">
1514
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">Escape</kbd> - Go back or close</p>
1515
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">Backspace</kbd> - Go back when search is empty</p>
1516
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">Enter</kbd> - Select item or navigate deeper</p>
1517
+ <p><kbd className="px-1 py-0.5 bg-muted rounded text-xs">↑↓</kbd> - Navigate items</p>
1518
+ <p>Click "Back" button or use keyboard to navigate between levels</p>
1519
+ </div>
1520
+ </div>
1521
+
1522
+ <div className="space-y-4">
1523
+ <h2 className="text-xl font-semibold">Current Values</h2>
1524
+ <div className="grid gap-4 md:grid-cols-3">
1525
+ <div className="p-4 border rounded-lg">
1526
+ <h4 className="font-medium">Framework</h4>
1527
+ <p className="text-sm text-muted-foreground">{frameworkValue || 'None selected'}</p>
1528
+ </div>
1529
+ <div className="p-4 border rounded-lg">
1530
+ <h4 className="font-medium">Project/Team</h4>
1531
+ <p className="text-sm text-muted-foreground">{projectValue || 'None selected'}</p>
1532
+ </div>
1533
+ <div className="p-4 border rounded-lg">
1534
+ <h4 className="font-medium">Setting</h4>
1535
+ <p className="text-sm text-muted-foreground">{settingsValue || 'None selected'}</p>
1536
+ </div>
1537
+ </div>
1538
+ </div>
1539
+ </div> `,
1540
+ props: {
1541
+ "NestedCombobox": [
1542
+ { name: "pages", type: "CommandPage[]", default: "null", required: true },
1543
+ { name: "placeholder", type: "string", default: "Select option...", required: false },
1544
+ { name: "emptyMessage", type: "string", default: "No results found.", required: false },
1545
+ { name: "className", type: "string", default: "w-[300px]", required: false },
1546
+ { name: "defaultPage", type: "string", default: "null", required: false },
1547
+ { name: "value", type: "string", default: "''", required: false },
1548
+ { name: "onValueChange", type: "(value: string) => void", default: "null", required: false },
1549
+ { name: "onItemSelect", type: "(item: CommandItemData, pageId: string) => void", default: "null", required: false },
1550
+ { name: "displayValue", type: "(value: string) => string", default: "null", required: false },
1551
+ ],
1552
+ },
1553
+ usagePath: null,
1554
+ desc: null,
1555
+ customize: null
1556
+ },
1557
+ {
1558
+ name: "Combobox 2",
1559
+ value: "combobox-2",
1560
+ importPath: "~/components/catalyst-ui/comboboxes/combobox2",
1561
+ multiImport: "Combobox2, ComboboxTrigger2, ComboboxContent2, ComboboxInput2, ComboboxList2, ComboboxEmpty2, ComboboxGroup2, ComboboxItem2, ComboboxSeparator2, ComboboxCreateNew2",
1562
+ basicusage: `
1563
+ <Combobox2 data={data} type="item">
1564
+ <ComboboxTrigger2 />
1565
+ <ComboboxContent2>
1566
+ <ComboboxInput2 />
1567
+ <ComboboxList2>
1568
+ <ComboboxEmpty2 />
1569
+ <ComboboxGroup2>
1570
+ {data.map((item) => (
1571
+ <ComboboxItem2 key={item.value} value={item.value}>
1572
+ {item.label}
1573
+ </ComboboxItem2>
1574
+ ))}
1575
+ </ComboboxGroup2>
1576
+ </ComboboxList2>
1577
+ </ComboboxContent2>
1578
+ </Combobox2>
1579
+
1580
+ <Combobox2
1581
+ data={data}
1582
+ type="item"
1583
+ defaultValue=""
1584
+ value={value}
1585
+ onValueChange={setValue}
1586
+ open={open}
1587
+ onOpenChange={setOpen}
1588
+ defaultOpen={false}
1589
+ >
1590
+ <ComboboxTrigger2 className="" />
1591
+ <ComboboxContent2 popoverOptions={{}}>
1592
+ <ComboboxInput2
1593
+ value={inputValue}
1594
+ defaultValue=""
1595
+ onValueChange={setInputValue}
1596
+ />
1597
+ <ComboboxList2>
1598
+ <ComboboxEmpty2>No items found.</ComboboxEmpty2>
1599
+ <ComboboxGroup2>
1600
+ {data.map((item) => (
1601
+ <ComboboxItem2 key={item.value} value={item.value}>
1602
+ {item.label}
1603
+ </ComboboxItem2>
1604
+ ))}
1605
+ </ComboboxGroup2>
1606
+ <ComboboxSeparator2 />
1607
+ <ComboboxCreateNew2 onCreateNew={handleCreate}>
1608
+ {(inputValue) => <span>Create: {inputValue}</span>}
1609
+ </ComboboxCreateNew2>
1610
+ </ComboboxList2>
1611
+ </ComboboxContent2>
1612
+ </Combobox2>`,
1613
+ path: "/components/catalyst-ui/comboboxes/combobox2.tsx",
1614
+ source: null,
1615
+ usagePath: "/components/catalyst-ui/comboboxes/combobox2.tsx",
1616
+ usage: null,
1617
+ premium: true,
1618
+ category: "Comboboxes",
1619
+ tags: ["combobox", "select", "dropdown", "search", "filter"],
1620
+ features: ["Responsive", "TypeScript", "Accessible", "Searchable", "Create New"],
1621
+ dependencies: ["lucide-react", "react", "@radix-ui/react-use-controllable-state"],
1622
+ props: {
1623
+ "Combobox2": [
1624
+ { name: "data", type: "ComboboxData[]", default: "required" },
1625
+ { name: "type", type: "string", default: "required" },
1626
+ { name: "defaultValue", type: "string", default: "undefined" },
1627
+ { name: "value", type: "string", default: "undefined" },
1628
+ { name: "onValueChange", type: "(value: string) => void", default: "undefined" },
1629
+ { name: "open", type: "boolean", default: "undefined" },
1630
+ { name: "onOpenChange", type: "(open: boolean) => void", default: "undefined" },
1631
+ { name: "defaultOpen", type: "boolean", default: "false" },
1632
+ ],
1633
+ "ComboboxTrigger2": [
1634
+ { name: "className", type: "string", default: "undefined" },
1635
+ { name: "children", type: "ReactNode", default: "undefined" },
1636
+ ],
1637
+ "ComboboxContent2": [
1638
+ { name: "className", type: "string", default: "undefined" },
1639
+ { name: "popoverOptions", type: "ComponentProps<typeof PopoverContent>", default: "undefined" },
1640
+ ],
1641
+ "ComboboxInput2": [
1642
+ { name: "value", type: "string", default: "undefined" },
1643
+ { name: "defaultValue", type: "string", default: "undefined" },
1644
+ { name: "onValueChange", type: "(value: string) => void", default: "undefined" },
1645
+ ],
1646
+ "ComboboxItem2": [
1647
+ { name: "value", type: "string", default: "required" },
1648
+ { name: "children", type: "ReactNode", default: "required" },
1649
+ ],
1650
+ "ComboboxCreateNew2": [
1651
+ { name: "onCreateNew", type: "(value: string) => void", default: "required" },
1652
+ { name: "children", type: "(inputValue: string) => ReactNode", default: "undefined" },
1653
+ { name: "className", type: "string", default: "undefined" },
1654
+ ],
1655
+ },
1656
+ desc: null,
1657
+ status: null,
1658
+ lastUpdated: null
1659
+ },
1660
+ {
1661
+ name: "Choicebox",
1662
+ value: "choicebox",
1663
+ importPath: "~/components/catalyst-ui/comboboxes/choicebox",
1664
+ multiImport: "Choicebox, ChoiceboxItem, ChoiceboxItemHeader, ChoiceboxItemTitle, ChoiceboxItemSubtitle, ChoiceboxItemDescription, ChoiceboxItemContent, ChoiceboxItemIndicator",
1665
+ basicusage: `
1666
+ <Choicebox value="option1" onValueChange={setValue}>
1667
+ <ChoiceboxItem value="option1">
1668
+ <ChoiceboxItemHeader>
1669
+ <ChoiceboxItemTitle>Option 1</ChoiceboxItemTitle>
1670
+ <ChoiceboxItemDescription>Description</ChoiceboxItemDescription>
1671
+ </ChoiceboxItemHeader>
1672
+ <ChoiceboxItemContent>
1673
+ <ChoiceboxItemIndicator />
1674
+ </ChoiceboxItemContent>
1675
+ </ChoiceboxItem>
1676
+ </Choicebox>
1677
+
1678
+ <Choicebox
1679
+ value={selectedValue}
1680
+ onValueChange={handleChange}
1681
+ className="space-y-2"
1682
+ >
1683
+ <ChoiceboxItem value="premium" className="border-2">
1684
+ <ChoiceboxItemHeader>
1685
+ <ChoiceboxItemTitle className="text-lg">Premium Plan</ChoiceboxItemTitle>
1686
+ <ChoiceboxItemSubtitle>Most popular</ChoiceboxItemSubtitle>
1687
+ <ChoiceboxItemDescription>Full access to all features</ChoiceboxItemDescription>
1688
+ </ChoiceboxItemHeader>
1689
+ <ChoiceboxItemContent>
1690
+ <ChoiceboxItemIndicator />
1691
+ </ChoiceboxItemContent>
1692
+ </ChoiceboxItem>
1693
+ </Choicebox>`,
1694
+ path: "/components/catalyst-ui/comboboxes/choicebox.tsx",
1695
+ source: null,
1696
+ usagePath: "/components/catalyst-ui/comboboxes/choicebox.tsx",
1697
+ usage: null,
1698
+ premium: true,
1699
+ category: "Comboboxes",
1700
+ tags: ["radio", "selection", "cards", "forms"],
1701
+ features: ["Card-based UI", "Accessible", "Customizable", "TypeScript"],
1702
+ dependencies: ["lucide-react", "radix-ui", "react"],
1703
+ props: {
1704
+ "Choicebox": [
1705
+ { name: "className", type: "string", default: "null" },
1706
+ { name: "value", type: "string", default: "null" },
1707
+ { name: "onValueChange", type: "(value: string) => void", default: "null" }
1708
+ ],
1709
+ "ChoiceboxItem": [
1710
+ { name: "className", type: "string", default: "null" },
1711
+ { name: "value", type: "string", default: "null" }
1712
+ ],
1713
+ "ChoiceboxItemHeader": [
1714
+ { name: "className", type: "string", default: "null" }
1715
+ ],
1716
+ "ChoiceboxItemTitle": [
1717
+ { name: "className", type: "string", default: "null" }
1718
+ ],
1719
+ "ChoiceboxItemSubtitle": [
1720
+ { name: "className", type: "string", default: "null" }
1721
+ ],
1722
+ "ChoiceboxItemDescription": [
1723
+ { name: "className", type: "string", default: "null" }
1724
+ ],
1725
+ "ChoiceboxItemContent": [
1726
+ { name: "className", type: "string", default: "null" }
1727
+ ],
1728
+ "ChoiceboxItemIndicator": [
1729
+ { name: "className", type: "string", default: "null" }
1730
+ ]
1731
+ },
1732
+ desc: null,
1733
+ status: null,
1734
+ lastUpdated: null
1735
+ },
1736
+ {
1737
+ name: "Combobox",
1738
+ value: "combobox",
1739
+ importPath: "~/components/catalyst-ui/comboboxes/combobox",
1740
+ path: "/components/catalyst-ui/comboboxes/combobox.tsx",
1741
+ premium: true,
1742
+ source: null,
1743
+ category: "Comboboxes",
1744
+ tags: ["ui", "components", "interactive"],
1745
+ features: ["Responsive", "TypeScript", "Accessible"],
1746
+ dependencies: ["lucide-react", "cmdk", "@radix-ui/react-popover"],
1747
+ basicusage: `
1748
+ <Combobox
1749
+ options={options}
1750
+ value={value}
1751
+ onValueChange={setValue}
1752
+ // placeholder
1753
+ // emptyText
1754
+ // className
1755
+ />`,
1756
+ usage: `
1757
+
1758
+ <Combobox
1759
+ options={options}
1760
+ value={value}
1761
+ onValueChange={setValue}
1762
+ // placeholder
1763
+ // emptyText
1764
+ // className
1765
+ />
1766
+
1767
+ export function ComboboxDemo() {
1768
+ const [value, setValue] = React.useState("")
1769
+ const options = [
1770
+ {
1771
+ value: "next.js",
1772
+ label: "Next.js",
1773
+ },
1774
+ {
1775
+ value: "sveltekit",
1776
+ label: "SvelteKit",
1777
+ },
1778
+ {
1779
+ value: "nuxt.js",
1780
+ label: "Nuxt.js",
1781
+ },
1782
+ {
1783
+ value: "remix",
1784
+ label: "Remix",
1785
+ },
1786
+ {
1787
+ value: "astro",
1788
+ label: "Astro",
1789
+ },
1790
+ ]
1791
+ return (
1792
+ <div>
1793
+ <Combobox
1794
+ options={options}
1795
+ value={value}
1796
+ onValueChange={setValue}
1797
+ // placeholder
1798
+ // emptyText
1799
+ // className
1800
+ />
1801
+ </div>
1802
+ )
1803
+ }`,
1804
+ usagePath: null,
1805
+ props: {
1806
+ "Combobox": [
1807
+ { name: "options", type: "{ value: string; label: string }[]", default: "null", required: true },
1808
+ { name: "value", type: "string", default: "null", required: false },
1809
+ { name: "onValueChange", type: "(value: string) => void", default: "null", required: false },
1810
+ { name: "placeholder", type: "string", default: "Select option...", required: false },
1811
+ { name: "emptyText", type: "string", default: "No option found.", required: false },
1812
+ { name: "className", type: "string", default: "null", required: false },
1813
+ ],
1814
+ },
1815
+ desc: null,
1816
+ status: null,
1817
+ lastUpdated: null
1818
+ },
1819
+ {
1820
+ name: "Command W Combobox",
1821
+ value: "command-w-combobox",
1822
+ importPath: "~/components/catalyst-ui/comboboxes/command-w-combobox",
1823
+ multiImport: "CommandWCombobox",
1824
+ basicusage: null,
1825
+ path: "/components/catalyst-ui/comboboxes/command-w-combobox.tsx",
1826
+ source: null,
1827
+ usagePath: "/components/catalyst-ui/comboboxes/command-w-combobox.tsx",
1828
+ usage: null,
1829
+ premium: true,
1830
+ category: "Comboboxes",
1831
+ tags: ["command", "combobox", "search", "filter"],
1832
+ features: ["Responsive", "TypeScript", "Accessible", "Search", "Filter"],
1833
+ dependencies: ["lucide-react", "react", "@radix-ui/react-popover"],
1834
+ props: {
1835
+ "CommandWCombobox": [
1836
+ { name: "className", type: "string", default: "null" }
1837
+ ]
1838
+ },
1839
+ desc: null,
1840
+ status: null,
1841
+ lastUpdated: null
1842
+ },
1843
+ ];