@catalystsoftware/ui 1.0.4 → 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.
- package/data/tailwind.config.js +261 -3821
- package/dist/components/catalyst-ui/buttons/burger.tsx +207 -0
- package/dist/components/catalyst-ui/core/data-display/timeline.tsx +210 -0
- package/dist/components/catalyst-ui/core/feedback/alert.tsx +491 -0
- package/dist/components/catalyst-ui/core/feedback/spinner-1.tsx +65 -0
- package/dist/components/catalyst-ui/core/feedback/toast.tsx +1857 -0
- package/dist/components/catalyst-ui/core/navigation/menu.tsx +164 -0
- package/dist/components/catalyst-ui/forms/toggle-class.tsx +176 -0
- package/dist/components/catalyst-ui/hooks/use-copy-to-clipboard.tsx +419 -0
- package/dist/components/catalyst-ui/hooks/use-counter.tsx +13 -0
- package/dist/components/catalyst-ui/hooks/use-event-listener.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-export-markdown.tsx +47 -0
- package/dist/components/catalyst-ui/hooks/use-focus.tsx +17 -0
- package/dist/components/catalyst-ui/hooks/use-interval.tsx +23 -0
- package/dist/components/catalyst-ui/hooks/use-is-client.tsx +16 -0
- package/dist/components/catalyst-ui/hooks/use-media-query.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-mobile.tsx +19 -0
- package/dist/components/catalyst-ui/hooks/use-resize-observer.tsx +81 -0
- package/dist/components/catalyst-ui/hooks/use-timeout.tsx +21 -0
- package/dist/components/catalyst-ui/hooks/use-timer.tsx +209 -0
- package/dist/components/catalyst-ui/hooks/use-toggle.tsx +12 -0
- package/dist/components/catalyst-ui/media/image.tsx +13 -0
- package/dist/components/catalyst-ui/overlays/dual-sidebar.tsx +4142 -0
- package/dist/components/catalyst-ui/overlays/sidebar-original.tsx +726 -0
- package/dist/components/catalyst-ui/primitives/accordion.tsx +250 -0
- package/dist/components/catalyst-ui/primitives/alert-dialog.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/aspect-ratio.tsx +9 -0
- package/dist/components/catalyst-ui/primitives/avatar.tsx +296 -0
- package/dist/components/catalyst-ui/primitives/badge.tsx +57 -0
- package/dist/components/catalyst-ui/primitives/breadcrumb.tsx +101 -0
- package/dist/components/catalyst-ui/primitives/button.tsx +265 -0
- package/dist/components/catalyst-ui/primitives/calendar-v4.tsx +208 -0
- package/dist/components/catalyst-ui/primitives/calendar.tsx +295 -0
- package/dist/components/catalyst-ui/primitives/card.tsx +618 -0
- package/dist/components/catalyst-ui/primitives/carousel.tsx +238 -0
- package/dist/components/catalyst-ui/primitives/chart.tsx +347 -0
- package/dist/components/catalyst-ui/primitives/checkbox.tsx +225 -0
- package/dist/components/catalyst-ui/primitives/collapsible.tsx +212 -0
- package/dist/components/catalyst-ui/primitives/command.tsx +393 -0
- package/dist/components/catalyst-ui/primitives/context-menu.tsx +236 -0
- package/dist/components/catalyst-ui/primitives/dialog.tsx +471 -0
- package/dist/components/catalyst-ui/primitives/drawer.tsx +761 -0
- package/dist/components/catalyst-ui/primitives/dropdown-menu.tsx +290 -0
- package/dist/components/catalyst-ui/primitives/empty.tsx +104 -0
- package/dist/components/catalyst-ui/primitives/field.tsx +244 -0
- package/dist/components/catalyst-ui/primitives/hover-card.tsx +124 -0
- package/dist/components/catalyst-ui/primitives/input-otp.tsx +76 -0
- package/dist/components/catalyst-ui/primitives/input.tsx +64 -0
- package/dist/components/catalyst-ui/primitives/item.tsx +196 -0
- package/dist/components/catalyst-ui/primitives/kbd.tsx +75 -0
- package/dist/components/catalyst-ui/primitives/label.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/navigation-menu.tsx +150 -0
- package/dist/components/catalyst-ui/primitives/pagination.tsx +198 -0
- package/dist/components/catalyst-ui/primitives/popover.tsx +232 -0
- package/dist/components/catalyst-ui/primitives/progress.tsx +34 -0
- package/dist/components/catalyst-ui/primitives/radio-group.tsx +43 -0
- package/dist/components/catalyst-ui/primitives/resizable.tsx +56 -0
- package/dist/components/catalyst-ui/primitives/select.tsx +155 -0
- package/dist/components/catalyst-ui/primitives/separator.tsx +74 -0
- package/dist/components/catalyst-ui/primitives/sheet.tsx +126 -0
- package/dist/components/catalyst-ui/primitives/skeleton.tsx +15 -0
- package/dist/components/catalyst-ui/primitives/slider.tsx +27 -0
- package/dist/components/catalyst-ui/primitives/switch.tsx +187 -0
- package/dist/components/catalyst-ui/primitives/tabs.tsx +335 -0
- package/dist/components/catalyst-ui/primitives/textarea.tsx +24 -0
- package/dist/components/catalyst-ui/primitives/toggle-group.tsx +55 -0
- package/dist/components/catalyst-ui/primitives/toggle.tsx +42 -0
- package/dist/components/catalyst-ui/primitives/tooltip.tsx +116 -0
- package/dist/components/catalyst-ui/utils/basic-auth.tsx +40 -0
- package/dist/components/catalyst-ui/utils/context-storage.tsx +19 -0
- package/dist/components/catalyst-ui/utils/cors-middleware.tsx +71 -0
- package/dist/components/catalyst-ui/utils/deferred-content.tsx +595 -0
- package/dist/components/catalyst-ui/utils/honeypot-middleware.tsx +38 -0
- package/dist/components/catalyst-ui/utils/incId.tsx +75 -0
- package/dist/components/catalyst-ui/utils/jwk-auth.tsx +36 -0
- package/dist/components/catalyst-ui/utils/request-id.tsx +14 -0
- package/dist/components/catalyst-ui/utils/secure-headers.tsx +37 -0
- package/dist/components/catalyst-ui/utils/server-timing.tsx +23 -0
- package/dist/components/catalyst-ui/utils/utils.ts +43 -0
- package/dist/components/catalyst-ui/utils/with-cookie.tsx +43 -0
- package/dist/components/catalyst-ui/x/accordian-x.tsx +428 -0
- package/dist/components/catalyst-ui/x/alert-x.tsx +413 -0
- package/dist/components/catalyst-ui/x/animated-text-x.tsx +2242 -0
- package/dist/components/catalyst-ui/x/avatar-x.tsx +515 -0
- package/dist/components/catalyst-ui/x/badge-x.tsx +670 -0
- package/dist/components/catalyst-ui/x/button-X.tsx +2857 -0
- package/dist/components/catalyst-ui/x/button-group-x.tsx +847 -0
- package/dist/components/catalyst-ui/x/calendar-x.tsx +1910 -0
- package/dist/components/catalyst-ui/x/card-x.tsx +2597 -0
- package/dist/components/catalyst-ui/x/checkbox-x.tsx +656 -0
- package/dist/components/catalyst-ui/x/collapsible-x.tsx +1360 -0
- package/dist/components/catalyst-ui/x/combobox-x.tsx +911 -0
- package/dist/components/catalyst-ui/x/data-table-x.tsx +1753 -0
- package/dist/components/catalyst-ui/x/date-picker-x.tsx +648 -0
- package/dist/components/catalyst-ui/x/dialog-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/dropdown-menu-x.tsx +612 -0
- package/dist/components/catalyst-ui/x/hover-card-x.tsx +375 -0
- package/dist/components/catalyst-ui/x/icon-x.tsx +840 -0
- package/dist/components/catalyst-ui/x/input-mask-x.tsx +981 -0
- package/dist/components/catalyst-ui/x/input-otp-x.tsx +659 -0
- package/dist/components/catalyst-ui/x/loader-x.tsx +1757 -0
- package/dist/components/catalyst-ui/x/pagination-x.tsx +622 -0
- package/dist/components/catalyst-ui/x/popover-x.tsx +744 -0
- package/dist/components/catalyst-ui/x/radio-group-x.tsx +499 -0
- package/dist/components/catalyst-ui/x/select-x.tsx +1127 -0
- package/dist/components/catalyst-ui/x/sheet-x.tsx +668 -0
- package/dist/components/catalyst-ui/x/switch-x.tsx +681 -0
- package/dist/components/catalyst-ui/x/table-x.tsx +574 -0
- package/dist/components/catalyst-ui/x/tabs-x.tsx +839 -0
- package/dist/components/catalyst-ui/x/textarea-x.tsx +1263 -0
- package/dist/components/catalyst-ui/x/tooltip-x.tsx +396 -0
- package/dist/components/catalyst-ui/x/tracker-x.tsx +560 -0
- package/dist/data/bg-data.tsx +901 -0
- package/dist/data/buttons-data.tsx +2327 -0
- package/dist/data/charts-data.tsx +102 -0
- package/dist/data/chat-data.tsx +83 -0
- package/dist/data/code-data.tsx +1040 -0
- package/dist/data/comboboxes-data.tsx +1843 -0
- package/dist/data/command-data.tsx +1381 -0
- package/dist/data/core-data.tsx +15953 -0
- package/dist/data/crm-data.tsx +47 -0
- package/dist/data/data.tsx +159 -0
- package/dist/data/date-and-time-data.tsx +554 -0
- package/dist/data/dependencies.tsx +7 -0
- package/dist/data/ecommerce-data.tsx +1387 -0
- package/dist/data/forms-data.tsx +7890 -0
- package/dist/data/hooks-data.tsx +5487 -0
- package/dist/data/index.ts +34 -0
- package/dist/data/inputs-data.tsx +557 -0
- package/dist/data/interactive-data.tsx +5394 -0
- package/dist/data/lofi-data.tsx +18295 -0
- package/dist/data/marketing-data.tsx +2546 -0
- package/dist/data/media-data.tsx +1510 -0
- package/dist/data/motion-data.tsx +5801 -0
- package/dist/data/overlay-data.tsx +4136 -0
- package/dist/data/pdf-data.tsx +124 -0
- package/dist/data/pos-data.tsx +213 -0
- package/dist/data/postcss.config.js +6 -0
- package/dist/data/primitive-data.tsx +5170 -0
- package/dist/data/prompt-data.tsx +1226 -0
- package/dist/data/requiredLibs.ts +4 -0
- package/dist/data/sandbox-data.tsx +1 -0
- package/dist/data/sidebars-data.tsx +5421 -0
- package/dist/data/stacks-data.tsx +32 -0
- package/dist/data/table-data.tsx +706 -0
- package/dist/data/tailwind.config.js +270 -0
- package/dist/data/tailwind.config.ngin.js +3830 -0
- package/dist/data/tailwind.css +431 -0
- package/dist/data/tools-data.tsx +6910 -0
- package/dist/data/typography-data.tsx +2050 -0
- package/dist/data/utils-data.tsx +6500 -0
- package/dist/data/x-data.tsx +1171 -0
- package/dist/data.tsx +159 -0
- package/package.json +1 -1
- package/dist/index.d.ts +0 -3
- package/dist/index.d.ts.map +0 -1
- 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
|
+
];
|