gladvn 0.2.36 → 0.2.37
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/README.md +1 -1
- package/package.json +1 -1
- package/scripts/strip-comments.ts +79 -0
- package/src/blocks/auth-form.tsx +34 -30
- package/src/blocks/auth-recovery.tsx +9 -13
- package/src/blocks/auth-split.tsx +46 -36
- package/src/blocks/settings.tsx +84 -117
- package/src/components/macro/alert-preset.tsx +3 -1
- package/src/components/macro/carousel-preset.tsx +0 -1
- package/src/components/macro/checkbox-preset.test.tsx +2 -2
- package/src/components/macro/checkbox-preset.tsx +1 -2
- package/src/components/macro/command-preset.tsx +1 -1
- package/src/components/macro/date-picker.tsx +5 -18
- package/src/components/macro/dialog-preset.tsx +5 -3
- package/src/components/macro/input-preset.tsx +0 -1
- package/src/components/macro/select-preset.tsx +1 -1
- package/src/components/macro/switch-preset.test.tsx +1 -1
- package/src/components/micro/accordion.test.tsx +6 -12
- package/src/components/micro/alert-dialog.tsx +0 -2
- package/src/components/micro/alert.test.tsx +5 -8
- package/src/components/micro/alert.tsx +0 -2
- package/src/components/micro/badge.test.tsx +5 -7
- package/src/components/micro/badge.tsx +1 -3
- package/src/components/micro/button.test.tsx +19 -26
- package/src/components/micro/button.tsx +3 -11
- package/src/components/micro/calendar.tsx +12 -13
- package/src/components/micro/card.test.tsx +3 -5
- package/src/components/micro/carousel.tsx +0 -1
- package/src/components/micro/chart.tsx +3 -2
- package/src/components/micro/checkbox.test.tsx +9 -18
- package/src/components/micro/combobox.tsx +1 -3
- package/src/components/micro/command.tsx +23 -11
- package/src/components/micro/context-menu.tsx +0 -2
- package/src/components/micro/dialog.test.tsx +6 -14
- package/src/components/micro/dialog.tsx +0 -2
- package/src/components/micro/drawer.tsx +0 -3
- package/src/components/micro/dropdown-menu.test.tsx +8 -14
- package/src/components/micro/dropdown-menu.tsx +0 -2
- package/src/components/micro/field.tsx +3 -3
- package/src/components/micro/hover-card.tsx +0 -2
- package/src/components/micro/input-group.tsx +9 -42
- package/src/components/micro/input.test.tsx +15 -24
- package/src/components/micro/navigation-menu.tsx +0 -2
- package/src/components/micro/popover.test.tsx +5 -9
- package/src/components/micro/progress.tsx +5 -1
- package/src/components/micro/select.test.tsx +5 -18
- package/src/components/micro/select.tsx +3 -5
- package/src/components/micro/separator.tsx +1 -1
- package/src/components/micro/sheet.test.tsx +6 -14
- package/src/components/micro/sheet.tsx +0 -2
- package/src/components/micro/sidebar.tsx +5 -6
- package/src/components/micro/sonner.tsx +0 -1
- package/src/components/micro/switch.test.tsx +9 -18
- package/src/components/micro/switch.tsx +1 -1
- package/src/components/micro/tabs.test.tsx +5 -11
- package/src/components/micro/theme-provider.tsx +0 -12
- package/src/components/micro/toggle-group.tsx +1 -12
- package/src/components/micro/tooltip.test.tsx +7 -12
- package/src/dev/App.tsx +6 -6
- package/src/dev/components/BlockViewer.tsx +15 -4
- package/src/dev/components/Container.tsx +20 -0
- package/src/dev/components/GladvnLogo.tsx +3 -9
- package/src/dev/components/code-highlighter.tsx +5 -3
- package/src/dev/components/showcase.tsx +116 -168
- package/src/dev/sections/buttons.tsx +4 -9
- package/src/dev/sections/display.tsx +68 -72
- package/src/dev/sections/feedback.tsx +304 -314
- package/src/dev/sections/forms.tsx +10 -14
- package/src/dev/sections/interactive.tsx +32 -32
- package/src/dev/sections/overview.tsx +2 -10
- package/src/dev/showcase/accordion.tsx +512 -554
- package/src/dev/showcase/alert-dialog.tsx +525 -565
- package/src/dev/showcase/alert.tsx +352 -402
- package/src/dev/showcase/aspect-ratio.tsx +167 -193
- package/src/dev/showcase/avatar.tsx +231 -269
- package/src/dev/showcase/badge.tsx +92 -140
- package/src/dev/showcase/breadcrumb.tsx +113 -135
- package/src/dev/showcase/button.tsx +140 -173
- package/src/dev/showcase/calendar.tsx +187 -237
- package/src/dev/showcase/card.tsx +229 -261
- package/src/dev/showcase/carousel.tsx +288 -315
- package/src/dev/showcase/chart.tsx +44 -50
- package/src/dev/showcase/checkbox.tsx +286 -330
- package/src/dev/showcase/collapsible.tsx +143 -160
- package/src/dev/showcase/combobox.tsx +327 -369
- package/src/dev/showcase/command.tsx +106 -120
- package/src/dev/showcase/context-menu.tsx +93 -107
- package/src/dev/showcase/dialog.tsx +585 -630
- package/src/dev/showcase/drawer.tsx +176 -196
- package/src/dev/showcase/dropdown-menu.tsx +183 -201
- package/src/dev/showcase/empty.tsx +232 -274
- package/src/dev/showcase/hover-card.tsx +153 -180
- package/src/dev/showcase/input-group.tsx +221 -253
- package/src/dev/showcase/input-otp.tsx +204 -250
- package/src/dev/showcase/input.tsx +246 -325
- package/src/dev/showcase/item.tsx +134 -152
- package/src/dev/showcase/kbd.tsx +149 -172
- package/src/dev/showcase/label.tsx +50 -68
- package/src/dev/showcase/menubar.tsx +194 -213
- package/src/dev/showcase/navigation-menu.tsx +119 -133
- package/src/dev/showcase/overview-components/ArchitectureSection.tsx +126 -0
- package/src/dev/showcase/overview-components/CodeBlock.tsx +50 -0
- package/src/dev/showcase/overview-components/ColorPaletteSection.tsx +44 -0
- package/src/dev/showcase/overview-components/DashboardPreview.tsx +159 -0
- package/src/dev/showcase/overview-components/FeatureGridSection.tsx +535 -0
- package/src/dev/showcase/overview-components/FooterCTA.tsx +137 -0
- package/src/dev/showcase/overview-components/HeroSection.tsx +65 -0
- package/src/dev/showcase/overview-components/PrinciplesSection.tsx +128 -0
- package/src/dev/showcase/overview.tsx +21 -1163
- package/src/dev/showcase/pagination.tsx +144 -190
- package/src/dev/showcase/popover.tsx +181 -196
- package/src/dev/showcase/progress.tsx +141 -189
- package/src/dev/showcase/radio-group.tsx +272 -332
- package/src/dev/showcase/resizable.tsx +119 -141
- package/src/dev/showcase/scroll-area.tsx +21 -36
- package/src/dev/showcase/select.tsx +262 -322
- package/src/dev/showcase/separator.tsx +75 -73
- package/src/dev/showcase/sheet.tsx +333 -361
- package/src/dev/showcase/sidebar.tsx +53 -59
- package/src/dev/showcase/skeleton.tsx +93 -112
- package/src/dev/showcase/slider.tsx +244 -296
- package/src/dev/showcase/sonner.tsx +251 -258
- package/src/dev/showcase/spinner.tsx +46 -67
- package/src/dev/showcase/switch.tsx +298 -362
- package/src/dev/showcase/table.tsx +76 -80
- package/src/dev/showcase/tabs.tsx +302 -355
- package/src/dev/showcase/textarea.tsx +240 -293
- package/src/dev/showcase/toast.tsx +48 -54
- package/src/dev/showcase/toggle-group.tsx +104 -129
- package/src/dev/showcase/toggle.tsx +82 -102
- package/src/dev/showcase/tooltip.tsx +173 -192
- package/src/dev/showcase/why.tsx +6 -12
- package/src/hooks/use-mobile.test.ts +3 -2
- package/src/lib/utils.test.ts +5 -4
|
@@ -40,7 +40,7 @@ import {
|
|
|
40
40
|
DocsCode,
|
|
41
41
|
DocsP,
|
|
42
42
|
ExampleGrid,
|
|
43
|
-
|
|
43
|
+
ShowcaseExample,
|
|
44
44
|
Showcase,
|
|
45
45
|
ShowcaseDocs
|
|
46
46
|
} from "../../dev/components/showcase";
|
|
@@ -52,9 +52,6 @@ const allFrameworks = [...frontendFrameworks, ...backendFrameworks];
|
|
|
52
52
|
const tagItems = ["bug", "feature", "enhancement", "docs"];
|
|
53
53
|
const engineItems = ["v8", "spidermonkey"];
|
|
54
54
|
|
|
55
|
-
// ──────────────────────────────────────────────────────────
|
|
56
|
-
// RHF Form Demo (Macro)
|
|
57
|
-
// ──────────────────────────────────────────────────────────
|
|
58
55
|
const formSchema = z.object({
|
|
59
56
|
framework: z.string().min(1, "Vui lòng chọn một framework.") });
|
|
60
57
|
type FormValues = z.infer<typeof formSchema>;
|
|
@@ -133,17 +130,11 @@ function ComboboxForm({ size }: { size: Size }) {
|
|
|
133
130
|
);
|
|
134
131
|
}`;
|
|
135
132
|
|
|
136
|
-
// ──────────────────────────────────────────────────────────
|
|
137
|
-
// SECTION 1: Macro Content
|
|
138
|
-
// ──────────────────────────────────────────────────────────
|
|
139
133
|
function ComboboxMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
140
134
|
return (
|
|
141
|
-
<div className="space-y-10
|
|
135
|
+
<div className="space-y-10">
|
|
142
136
|
<ExampleGrid>
|
|
143
|
-
<
|
|
144
|
-
label="Tiêu chuẩn"
|
|
145
|
-
description="Tương tự Select nhưng có thể gõ để tìm kiếm."
|
|
146
|
-
codeString={`<ComboboxPreset
|
|
137
|
+
<ShowcaseExample title="Tiêu chuẩn" description="Tương tự Select nhưng có thể gõ để tìm kiếm." code={`<ComboboxPreset
|
|
147
138
|
className="w-full"
|
|
148
139
|
label="Framework"
|
|
149
140
|
description="Hỗ trợ hàng ngàn bản ghi mà không lag."
|
|
@@ -156,29 +147,27 @@ function ComboboxMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
156
147
|
{ value: "angular", label: "Angular" },
|
|
157
148
|
{ value: "svelte", label: "Svelte" },
|
|
158
149
|
]}
|
|
159
|
-
/>`}
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
150
|
+
/>`} preview={
|
|
151
|
+
<>
|
|
152
|
+
<ComboboxPreset
|
|
153
|
+
className="w-full"
|
|
154
|
+
size={globalSize}
|
|
155
|
+
label="Framework"
|
|
156
|
+
description="Hỗ trợ hàng ngàn bản ghi mà không lag."
|
|
157
|
+
placeholder="Chọn framework..."
|
|
158
|
+
searchPlaceholder="Tìm kiếm framework..."
|
|
159
|
+
emptyText="Không tìm thấy framework nào."
|
|
160
|
+
options={[
|
|
161
|
+
{ value: "react", label: "React" },
|
|
162
|
+
{ value: "vue", label: "Vue" },
|
|
163
|
+
{ value: "angular", label: "Angular" },
|
|
164
|
+
{ value: "svelte", label: "Svelte" },
|
|
165
|
+
]}
|
|
166
|
+
/>
|
|
167
|
+
</>
|
|
168
|
+
} />
|
|
177
169
|
|
|
178
|
-
<
|
|
179
|
-
label="Trạng thái Lỗi (Error)"
|
|
180
|
-
description="Báo lỗi khi bỏ trống form."
|
|
181
|
-
codeString={`<div className="w-full flex flex-col gap-6">
|
|
170
|
+
<ShowcaseExample title="Trạng thái Lỗi (Error)" description="Báo lỗi khi bỏ trống form." code={`<div className="w-full flex flex-col gap-6">
|
|
182
171
|
<ComboboxPreset
|
|
183
172
|
label="Khu vực (Lỗi)"
|
|
184
173
|
placeholder="Chọn khu vực..."
|
|
@@ -187,25 +176,23 @@ function ComboboxMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
187
176
|
]}
|
|
188
177
|
errorMessage="Khu vực là bắt buộc."
|
|
189
178
|
/>
|
|
190
|
-
</div>`}
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
179
|
+
</div>`} preview={
|
|
180
|
+
<>
|
|
181
|
+
<div className="w-full flex flex-col gap-6">
|
|
182
|
+
<ComboboxPreset
|
|
183
|
+
size={globalSize}
|
|
184
|
+
label="Khu vực (Lỗi)"
|
|
185
|
+
placeholder="Chọn khu vực..."
|
|
186
|
+
options={[{ value: "ap", label: "Châu Á Thái Bình Dương" }]}
|
|
187
|
+
errorMessage="Khu vực là bắt buộc."
|
|
188
|
+
/>
|
|
189
|
+
</div>
|
|
190
|
+
</>
|
|
191
|
+
} />
|
|
202
192
|
</ExampleGrid>
|
|
203
193
|
|
|
204
194
|
<ExampleGrid>
|
|
205
|
-
<
|
|
206
|
-
label="Khóa / Bất hoạt (Disabled)"
|
|
207
|
-
description="Người dùng không thể click hay gõ vào ô."
|
|
208
|
-
codeString={`<ComboboxPreset
|
|
195
|
+
<ShowcaseExample title="Khóa / Bất hoạt (Disabled)" description="Người dùng không thể click hay gõ vào ô." code={`<ComboboxPreset
|
|
209
196
|
className="w-full"
|
|
210
197
|
label="Đội nhóm (Team)"
|
|
211
198
|
description="Bạn không có quyền thay đổi đội trong dự án này."
|
|
@@ -216,27 +203,25 @@ function ComboboxMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
216
203
|
]}
|
|
217
204
|
value="engineering"
|
|
218
205
|
disabled
|
|
219
|
-
/>`}
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
206
|
+
/>`} preview={
|
|
207
|
+
<>
|
|
208
|
+
<ComboboxPreset
|
|
209
|
+
className="w-full"
|
|
210
|
+
size={globalSize}
|
|
211
|
+
label="Đội nhóm (Team)"
|
|
212
|
+
description="Bạn không có quyền thay đổi đội trong dự án này."
|
|
213
|
+
placeholder="Chọn đội..."
|
|
214
|
+
options={[
|
|
215
|
+
{ value: "engineering", label: "Engineering" },
|
|
216
|
+
{ value: "design", label: "Design" },
|
|
217
|
+
]}
|
|
218
|
+
value="engineering"
|
|
219
|
+
disabled
|
|
220
|
+
/>
|
|
221
|
+
</>
|
|
222
|
+
} />
|
|
235
223
|
|
|
236
|
-
<
|
|
237
|
-
label="Cuộn danh sách dài (Long List)"
|
|
238
|
-
description="Trải nghiệm mượt mà với danh sách ảo hoá."
|
|
239
|
-
codeString={`<ComboboxPreset
|
|
224
|
+
<ShowcaseExample title="Cuộn danh sách dài (Long List)" description="Trải nghiệm mượt mà với danh sách ảo hoá." code={`<ComboboxPreset
|
|
240
225
|
className="w-full"
|
|
241
226
|
|
|
242
227
|
label="Múi giờ (Timezone)"
|
|
@@ -246,30 +231,29 @@ function ComboboxMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
246
231
|
options={Array.from({ length: 50 }).map((_, i) => ({
|
|
247
232
|
value: \`utc\${i - 12}\`,
|
|
248
233
|
label: \`UTC \${i - 12 > 0 ? "+" : ""}\${i - 12}:00\` }))}
|
|
249
|
-
/>`}
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
234
|
+
/>`} preview={
|
|
235
|
+
<>
|
|
236
|
+
<ComboboxPreset
|
|
237
|
+
className="w-full"
|
|
238
|
+
size={globalSize}
|
|
239
|
+
label="Múi giờ (Timezone)"
|
|
240
|
+
placeholder="Chọn múi giờ..."
|
|
241
|
+
searchPlaceholder="Tìm kiếm múi giờ..."
|
|
242
|
+
emptyText="Không tìm thấy múi giờ."
|
|
243
|
+
options={Array.from({ length: 50 }).map((_, i) => ({
|
|
244
|
+
value: `utc${i - 12}`,
|
|
245
|
+
label: `UTC ${i - 12 > 0 ? "+" : ""}${i - 12}:00` }))}
|
|
246
|
+
/>
|
|
247
|
+
</>
|
|
248
|
+
} />
|
|
263
249
|
</ExampleGrid>
|
|
264
250
|
|
|
265
251
|
<ExampleGrid>
|
|
266
|
-
<
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
<ComboboxForm size={globalSize} />
|
|
272
|
-
</ExampleSection>
|
|
252
|
+
<ShowcaseExample title="Tích hợp React Hook Form" description="Sử dụng Controller để bắt giá trị." code={rhfCode} preview={
|
|
253
|
+
<>
|
|
254
|
+
<ComboboxForm size={globalSize} />
|
|
255
|
+
</>
|
|
256
|
+
} />
|
|
273
257
|
</ExampleGrid>
|
|
274
258
|
</div>
|
|
275
259
|
);
|
|
@@ -280,12 +264,9 @@ function ComboboxMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
280
264
|
// ──────────────────────────────────────────────────────────
|
|
281
265
|
function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
282
266
|
return (
|
|
283
|
-
<div className="space-y-10
|
|
267
|
+
<div className="space-y-10">
|
|
284
268
|
<ExampleGrid>
|
|
285
|
-
<
|
|
286
|
-
label="Cơ bản & Phân nhóm"
|
|
287
|
-
description="Sử dụng InputGroup, ComboboxAnchor, ComboboxGroup."
|
|
288
|
-
codeString={`<Field className="w-full">
|
|
269
|
+
<ShowcaseExample title="Cơ bản & Phân nhóm" description="Sử dụng InputGroup, ComboboxAnchor, ComboboxGroup." code={`<Field className="w-full">
|
|
289
270
|
<FieldLabel>Tìm kiếm Framework</FieldLabel>
|
|
290
271
|
<FieldContent>
|
|
291
272
|
<Combobox items={allFrameworks}>
|
|
@@ -330,52 +311,50 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
330
311
|
|
|
331
312
|
</Combobox>
|
|
332
313
|
</FieldContent>
|
|
333
|
-
</Field>`}
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
314
|
+
</Field>`} preview={
|
|
315
|
+
<>
|
|
316
|
+
<Field size={globalSize} className="w-full">
|
|
317
|
+
<FieldLabel>Tìm kiếm Framework</FieldLabel>
|
|
318
|
+
<FieldContent>
|
|
319
|
+
<Combobox items={allFrameworks}>
|
|
320
|
+
<ComboboxAnchor className="w-full">
|
|
321
|
+
<InputGroup size={globalSize} className="w-full">
|
|
322
|
+
<ComboboxInput
|
|
323
|
+
placeholder="Tìm framework..."
|
|
324
|
+
render={<InputGroupInput />}
|
|
325
|
+
/>
|
|
326
|
+
<InputGroupAddon align="end">
|
|
327
|
+
<ComboboxTrigger className="flex h-full cursor-default items-center justify-center px-2.5 outline-none group-has-data-[slot=combobox-clear]/input-group:hidden disabled:cursor-not-allowed disabled:opacity-50" />
|
|
328
|
+
<ComboboxClear />
|
|
329
|
+
</InputGroupAddon>
|
|
330
|
+
</InputGroup>
|
|
331
|
+
</ComboboxAnchor>
|
|
351
332
|
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
333
|
+
<ComboboxContent>
|
|
334
|
+
<ComboboxEmpty>Không tìm thấy.</ComboboxEmpty>
|
|
335
|
+
<ComboboxList>
|
|
336
|
+
<ComboboxGroup>
|
|
337
|
+
<ComboboxLabel>Frontend</ComboboxLabel>
|
|
338
|
+
<ComboboxItem value="react">React</ComboboxItem>
|
|
339
|
+
<ComboboxItem value="vue">Vue</ComboboxItem>
|
|
340
|
+
<ComboboxItem value="svelte">Svelte</ComboboxItem>
|
|
341
|
+
</ComboboxGroup>
|
|
342
|
+
<ComboboxSeparator />
|
|
343
|
+
<ComboboxGroup>
|
|
344
|
+
<ComboboxLabel>Backend</ComboboxLabel>
|
|
345
|
+
<ComboboxItem value="express">Express</ComboboxItem>
|
|
346
|
+
<ComboboxItem value="nest">NestJS</ComboboxItem>
|
|
347
|
+
</ComboboxGroup>
|
|
348
|
+
</ComboboxList>
|
|
349
|
+
</ComboboxContent>
|
|
350
|
+
|
|
351
|
+
</Combobox>
|
|
352
|
+
</FieldContent>
|
|
353
|
+
</Field>
|
|
354
|
+
</>
|
|
355
|
+
} />
|
|
374
356
|
|
|
375
|
-
<
|
|
376
|
-
label="Chọn nhiều (Multi-select Chips)"
|
|
377
|
-
description="Sử dụng ComboboxChips và ComboboxChip thay cho Input."
|
|
378
|
-
codeString={`<Field className="w-full">
|
|
357
|
+
<ShowcaseExample title="Chọn nhiều (Multi-select Chips)" description="Sử dụng ComboboxChips và ComboboxChip thay cho Input." code={`<Field className="w-full">
|
|
379
358
|
<FieldLabel>Gán thẻ (Tags)</FieldLabel>
|
|
380
359
|
<FieldContent>
|
|
381
360
|
<Combobox items={tagItems} multiple>
|
|
@@ -412,46 +391,44 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
412
391
|
<FieldDescription>
|
|
413
392
|
Bạn có thể chọn nhiều thẻ cùng lúc.
|
|
414
393
|
</FieldDescription>
|
|
415
|
-
</Field>`}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
394
|
+
</Field>`} preview={
|
|
395
|
+
<>
|
|
396
|
+
<Field size={globalSize} className="w-full">
|
|
397
|
+
<FieldLabel>Gán thẻ (Tags)</FieldLabel>
|
|
398
|
+
<FieldContent>
|
|
399
|
+
<Combobox items={tagItems} multiple>
|
|
400
|
+
<ComboboxChips size={globalSize}>
|
|
401
|
+
<ComboboxChip value="bug">Lỗi (Bug)</ComboboxChip>
|
|
402
|
+
<ComboboxChip value="feature">
|
|
403
|
+
Tính năng (Feature)
|
|
404
|
+
</ComboboxChip>
|
|
405
|
+
<ComboboxChipsInput placeholder="Thêm thẻ..." />
|
|
406
|
+
</ComboboxChips>
|
|
428
407
|
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
408
|
+
<ComboboxContent>
|
|
409
|
+
<ComboboxEmpty>Không tìm thấy thẻ.</ComboboxEmpty>
|
|
410
|
+
<ComboboxList>
|
|
411
|
+
<ComboboxItem value="bug">Lỗi (Bug)</ComboboxItem>
|
|
412
|
+
<ComboboxItem value="feature">
|
|
413
|
+
Tính năng (Feature)
|
|
414
|
+
</ComboboxItem>
|
|
415
|
+
<ComboboxItem value="enhancement">Cải thiện</ComboboxItem>
|
|
416
|
+
<ComboboxItem value="docs">Tài liệu</ComboboxItem>
|
|
417
|
+
</ComboboxList>
|
|
418
|
+
</ComboboxContent>
|
|
419
|
+
|
|
420
|
+
</Combobox>
|
|
421
|
+
</FieldContent>
|
|
422
|
+
<FieldDescription>
|
|
423
|
+
Bạn có thể chọn nhiều thẻ cùng lúc.
|
|
424
|
+
</FieldDescription>
|
|
425
|
+
</Field>
|
|
426
|
+
</>
|
|
427
|
+
} />
|
|
448
428
|
</ExampleGrid>
|
|
449
429
|
|
|
450
430
|
<ExampleGrid>
|
|
451
|
-
<
|
|
452
|
-
label="Disabled thủ công"
|
|
453
|
-
description="Truyền disabled vào InputGroupInput và ComboboxTrigger."
|
|
454
|
-
codeString={`<Field className="w-full">
|
|
431
|
+
<ShowcaseExample title="Disabled thủ công" description="Truyền disabled vào InputGroupInput và ComboboxTrigger." code={`<Field className="w-full">
|
|
455
432
|
<FieldLabel>Tìm kiếm (Disabled)</FieldLabel>
|
|
456
433
|
<FieldContent>
|
|
457
434
|
<Combobox items={["react"]}>
|
|
@@ -481,43 +458,41 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
481
458
|
|
|
482
459
|
</Combobox>
|
|
483
460
|
</FieldContent>
|
|
484
|
-
</Field>`}
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
461
|
+
</Field>`} preview={
|
|
462
|
+
<>
|
|
463
|
+
<Field size={globalSize} className="w-full">
|
|
464
|
+
<FieldLabel>Tìm kiếm (Disabled)</FieldLabel>
|
|
465
|
+
<FieldContent>
|
|
466
|
+
<Combobox items={["react"]}>
|
|
467
|
+
<ComboboxAnchor className="w-full">
|
|
468
|
+
<InputGroup size={globalSize} className="w-full">
|
|
469
|
+
<ComboboxInput
|
|
470
|
+
placeholder="Tìm kiếm..."
|
|
471
|
+
disabled
|
|
472
|
+
render={<InputGroupInput disabled />}
|
|
473
|
+
/>
|
|
474
|
+
<InputGroupAddon align="end">
|
|
475
|
+
<ComboboxTrigger
|
|
476
|
+
className="flex h-full cursor-default items-center justify-center px-2.5 outline-none group-has-data-[slot=combobox-clear]/input-group:hidden disabled:cursor-not-allowed disabled:opacity-50"
|
|
477
|
+
disabled
|
|
478
|
+
/>
|
|
479
|
+
</InputGroupAddon>
|
|
480
|
+
</InputGroup>
|
|
481
|
+
</ComboboxAnchor>
|
|
505
482
|
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
483
|
+
<ComboboxContent>
|
|
484
|
+
<ComboboxList>
|
|
485
|
+
<ComboboxItem value="react">React</ComboboxItem>
|
|
486
|
+
</ComboboxList>
|
|
487
|
+
</ComboboxContent>
|
|
488
|
+
|
|
489
|
+
</Combobox>
|
|
490
|
+
</FieldContent>
|
|
491
|
+
</Field>
|
|
492
|
+
</>
|
|
493
|
+
} />
|
|
516
494
|
|
|
517
|
-
<
|
|
518
|
-
label="Trạng thái Lỗi (Invalid)"
|
|
519
|
-
description="Gắn aria-invalid vào ô nhập liệu."
|
|
520
|
-
codeString={`<Field data-invalid={true} className="w-full">
|
|
495
|
+
<ShowcaseExample title="Trạng thái Lỗi (Invalid)" description="Gắn aria-invalid vào ô nhập liệu." code={`<Field data-invalid={true} className="w-full">
|
|
521
496
|
<FieldLabel>Mã giảm giá</FieldLabel>
|
|
522
497
|
<FieldContent>
|
|
523
498
|
<Combobox items={["sale20", "sale50"]}>
|
|
@@ -552,46 +527,44 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
552
527
|
</Combobox>
|
|
553
528
|
</FieldContent>
|
|
554
529
|
<FieldError>Mã này đã hết hạn.</FieldError>
|
|
555
|
-
</Field>`}
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
530
|
+
</Field>`} preview={
|
|
531
|
+
<>
|
|
532
|
+
<Field size={globalSize} data-invalid={true} className="w-full">
|
|
533
|
+
<FieldLabel>Mã giảm giá</FieldLabel>
|
|
534
|
+
<FieldContent>
|
|
535
|
+
<Combobox items={["sale20", "sale50"]}>
|
|
536
|
+
<ComboboxAnchor className="w-full">
|
|
537
|
+
<InputGroup size={globalSize} className="w-full">
|
|
538
|
+
<ComboboxInput
|
|
539
|
+
placeholder="Nhập mã..."
|
|
540
|
+
aria-invalid={true}
|
|
541
|
+
render={<InputGroupInput />}
|
|
542
|
+
/>
|
|
543
|
+
<InputGroupAddon align="end">
|
|
544
|
+
<ComboboxTrigger className="flex h-full cursor-default items-center justify-center px-2.5 outline-none group-has-data-[slot=combobox-clear]/input-group:hidden disabled:cursor-not-allowed disabled:opacity-50" />
|
|
545
|
+
<ComboboxClear />
|
|
546
|
+
</InputGroupAddon>
|
|
547
|
+
</InputGroup>
|
|
548
|
+
</ComboboxAnchor>
|
|
574
549
|
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
550
|
+
<ComboboxContent>
|
|
551
|
+
<ComboboxEmpty>Không tìm thấy mã.</ComboboxEmpty>
|
|
552
|
+
<ComboboxList>
|
|
553
|
+
<ComboboxItem value="sale20">Giảm 20%</ComboboxItem>
|
|
554
|
+
<ComboboxItem value="sale50">Giảm 50%</ComboboxItem>
|
|
555
|
+
</ComboboxList>
|
|
556
|
+
</ComboboxContent>
|
|
557
|
+
|
|
558
|
+
</Combobox>
|
|
559
|
+
</FieldContent>
|
|
560
|
+
<FieldError>Mã này đã hết hạn.</FieldError>
|
|
561
|
+
</Field>
|
|
562
|
+
</>
|
|
563
|
+
} />
|
|
588
564
|
</ExampleGrid>
|
|
589
565
|
|
|
590
566
|
<ExampleGrid>
|
|
591
|
-
<
|
|
592
|
-
label="Giao diện Nút (With Trigger)"
|
|
593
|
-
description="Combobox dùng nút bấm (giống Select) thay vì ô nhập chữ (Input)."
|
|
594
|
-
codeString={`<Field className="w-full">
|
|
567
|
+
<ShowcaseExample title="Giao diện Nút (With Trigger)" description="Combobox dùng nút bấm (giống Select) thay vì ô nhập chữ (Input)." code={`<Field className="w-full">
|
|
595
568
|
<FieldLabel>Chọn Engine</FieldLabel>
|
|
596
569
|
<FieldContent>
|
|
597
570
|
<Combobox items={engineItems}>
|
|
@@ -621,46 +594,42 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
621
594
|
|
|
622
595
|
</Combobox>
|
|
623
596
|
</FieldContent>
|
|
624
|
-
</Field>`}
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
632
|
-
|
|
597
|
+
</Field>`} preview={
|
|
598
|
+
<>
|
|
599
|
+
<Field size={globalSize} className="w-full">
|
|
600
|
+
<FieldLabel>Chọn Engine</FieldLabel>
|
|
601
|
+
<FieldContent>
|
|
602
|
+
<Combobox items={engineItems}>
|
|
603
|
+
<ComboboxTrigger className="w-full justify-between flex items-center border border-border rounded-md p-2 hover:bg-accent focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring">
|
|
604
|
+
<ComboboxValue placeholder="Chọn một engine" />
|
|
605
|
+
</ComboboxTrigger>
|
|
633
606
|
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
637
|
-
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
607
|
+
<ComboboxContent>
|
|
608
|
+
<div className="p-1">
|
|
609
|
+
<InputGroup size={globalSize} className="w-full">
|
|
610
|
+
<ComboboxInput
|
|
611
|
+
placeholder="Tìm engine..."
|
|
612
|
+
render={<InputGroupInput />}
|
|
613
|
+
/>
|
|
614
|
+
</InputGroup>
|
|
615
|
+
</div>
|
|
616
|
+
<ComboboxEmpty>Không tìm thấy.</ComboboxEmpty>
|
|
617
|
+
<ComboboxList>
|
|
618
|
+
<ComboboxItem value="v8">V8 (Chrome)</ComboboxItem>
|
|
619
|
+
<ComboboxItem value="spidermonkey">
|
|
620
|
+
SpiderMonkey (Firefox)
|
|
621
|
+
</ComboboxItem>
|
|
622
|
+
</ComboboxList>
|
|
623
|
+
</ComboboxContent>
|
|
624
|
+
|
|
625
|
+
</Combobox>
|
|
626
|
+
</FieldContent>
|
|
627
|
+
</Field>
|
|
628
|
+
</>
|
|
629
|
+
} />
|
|
656
630
|
</ExampleGrid>
|
|
657
631
|
|
|
658
|
-
<
|
|
659
|
-
label="🧭 Use Case Comparison"
|
|
660
|
-
description="So sánh nhanh khi nào dùng Micro và Macro."
|
|
661
|
-
fullWidth
|
|
662
|
-
codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
663
|
-
{/* Story 1: Macro wins */}
|
|
632
|
+
<ShowcaseExample title="🧭 So sánh Use Case" description="So sánh nhanh khi nào dùng Micro và Macro." code={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
664
633
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
665
634
|
<div className="flex items-start gap-3">
|
|
666
635
|
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
@@ -696,7 +665,6 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
696
665
|
</p>
|
|
697
666
|
</div>
|
|
698
667
|
|
|
699
|
-
{/* Story 2: Micro wins */}
|
|
700
668
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
701
669
|
<div className="flex items-start gap-3">
|
|
702
670
|
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
@@ -730,93 +698,89 @@ function ComboboxMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
730
698
|
cụm <DocsCode>{\`<ComboboxChips />\`}</DocsCode>.
|
|
731
699
|
</p>
|
|
732
700
|
</div>
|
|
733
|
-
</div>`}
|
|
734
|
-
|
|
735
|
-
|
|
736
|
-
|
|
737
|
-
|
|
738
|
-
|
|
739
|
-
|
|
740
|
-
|
|
741
|
-
|
|
742
|
-
|
|
743
|
-
|
|
744
|
-
|
|
745
|
-
|
|
746
|
-
|
|
747
|
-
|
|
748
|
-
|
|
749
|
-
|
|
750
|
-
|
|
751
|
-
|
|
752
|
-
|
|
753
|
-
|
|
754
|
-
|
|
755
|
-
|
|
756
|
-
|
|
757
|
-
|
|
758
|
-
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
|
|
765
|
-
|
|
766
|
-
|
|
767
|
-
|
|
768
|
-
|
|
769
|
-
</div>
|
|
701
|
+
</div>`} preview={
|
|
702
|
+
<>
|
|
703
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
704
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
705
|
+
<div className="flex items-start gap-3">
|
|
706
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
707
|
+
<svg
|
|
708
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
709
|
+
className="size-4"
|
|
710
|
+
viewBox="0 0 24 24"
|
|
711
|
+
fill="none"
|
|
712
|
+
stroke="currentColor"
|
|
713
|
+
strokeWidth="2"
|
|
714
|
+
strokeLinecap="round"
|
|
715
|
+
strokeLinejoin="round"
|
|
716
|
+
aria-hidden="true"
|
|
717
|
+
>
|
|
718
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
|
719
|
+
</svg>
|
|
720
|
+
</span>
|
|
721
|
+
<div>
|
|
722
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
723
|
+
Story 1 · Dùng Macro
|
|
724
|
+
</p>
|
|
725
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
726
|
+
Single Select tự động hoàn thành
|
|
727
|
+
</h3>
|
|
728
|
+
</div>
|
|
729
|
+
</div>
|
|
730
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
731
|
+
Bạn cần một form chọn Thành phố. Số lượng thành phố quá lớn nên
|
|
732
|
+
không dùng Select được, phải dùng Combobox để gõ tìm.{" "}
|
|
733
|
+
<DocsCode>ComboboxPreset</DocsCode> sinh ra để giải quyết đúng bài
|
|
734
|
+
toán chọn 1 giá trị từ tập lớn này.
|
|
735
|
+
</p>
|
|
736
|
+
</div>
|
|
770
737
|
|
|
771
|
-
|
|
772
|
-
|
|
773
|
-
|
|
774
|
-
|
|
775
|
-
|
|
776
|
-
|
|
777
|
-
|
|
778
|
-
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
782
|
-
|
|
783
|
-
|
|
784
|
-
|
|
785
|
-
|
|
786
|
-
|
|
787
|
-
|
|
788
|
-
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
803
|
-
|
|
804
|
-
|
|
805
|
-
|
|
738
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
739
|
+
<div className="flex items-start gap-3">
|
|
740
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
741
|
+
<svg
|
|
742
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
743
|
+
className="size-4"
|
|
744
|
+
viewBox="0 0 24 24"
|
|
745
|
+
fill="none"
|
|
746
|
+
stroke="currentColor"
|
|
747
|
+
strokeWidth="2"
|
|
748
|
+
strokeLinecap="round"
|
|
749
|
+
strokeLinejoin="round"
|
|
750
|
+
aria-hidden="true"
|
|
751
|
+
>
|
|
752
|
+
<path d="M14.7 6.3a1 1 0 0 0 0 1.4l1.6 1.6a1 1 0 0 0 1.4 0l3.77-3.77a6 6 0 0 1-7.94 7.94l-6.91 6.91a2.12 2.12 0 0 1-3-3l6.91-6.91a6 6 0 0 1 7.94-7.94l-3.76 3.76z" />
|
|
753
|
+
</svg>
|
|
754
|
+
</span>
|
|
755
|
+
<div>
|
|
756
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
757
|
+
Story 2 · Dùng Micro
|
|
758
|
+
</p>
|
|
759
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
760
|
+
Gán thẻ (Multi-select)
|
|
761
|
+
</h3>
|
|
762
|
+
</div>
|
|
763
|
+
</div>
|
|
764
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
765
|
+
Bạn làm form tạo bài viết mới và cần gán nhiều Thẻ (Tags) cho bài
|
|
766
|
+
viết. Macro không hỗ trợ Multi-select. Bạn buộc phải dùng Micro
|
|
767
|
+
kết hợp với cụm <DocsCode>{`<ComboboxChips />`}</DocsCode>.
|
|
768
|
+
</p>
|
|
769
|
+
</div>
|
|
770
|
+
</div>
|
|
771
|
+
</>
|
|
772
|
+
} />
|
|
806
773
|
</div>
|
|
807
774
|
);
|
|
808
775
|
}
|
|
809
776
|
|
|
810
|
-
// ──────────────────────────────────────────────────────────
|
|
811
|
-
// SECTION 3: Entry point
|
|
812
|
-
// ──────────────────────────────────────────────────────────
|
|
813
777
|
export default function ComboboxShowcase() {
|
|
814
778
|
const { size: globalSize } = useDevContext();
|
|
815
779
|
return (
|
|
816
780
|
<Showcase
|
|
817
781
|
title="Combobox"
|
|
818
782
|
description="Thành phần mở rộng của Select, cho phép người dùng gõ phím để tìm kiếm và lọc qua các tập dữ liệu lớn."
|
|
819
|
-
|
|
783
|
+
guideline={
|
|
820
784
|
<ShowcaseDocs>
|
|
821
785
|
<DocsP>
|
|
822
786
|
Dùng để chọn một hoặc nhiều giá trị từ một danh sách lớn. Khác với
|
|
@@ -825,14 +789,8 @@ export default function ComboboxShowcase() {
|
|
|
825
789
|
</DocsP>
|
|
826
790
|
</ShowcaseDocs>
|
|
827
791
|
}
|
|
828
|
-
|
|
829
|
-
|
|
830
|
-
label: "Micro (Primitive)",
|
|
831
|
-
content: <ComboboxMicroShowcase globalSize={globalSize} /> },
|
|
832
|
-
{
|
|
833
|
-
label: "Macro (Preset)",
|
|
834
|
-
content: <ComboboxMacroShowcase globalSize={globalSize} /> },
|
|
835
|
-
]}
|
|
792
|
+
micro={{ content: <ComboboxMicroShowcase globalSize={globalSize} /> }}
|
|
793
|
+
macro={{ content: <ComboboxMacroShowcase globalSize={globalSize} /> }}
|
|
836
794
|
/>
|
|
837
795
|
);
|
|
838
796
|
}
|