gladvn 0.2.35 → 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 +2 -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
|
@@ -30,15 +30,12 @@ import {
|
|
|
30
30
|
DocsH3,
|
|
31
31
|
DocsP,
|
|
32
32
|
ExampleGrid,
|
|
33
|
-
|
|
33
|
+
ShowcaseExample,
|
|
34
34
|
Showcase,
|
|
35
35
|
ShowcaseDocs
|
|
36
36
|
} from "../../dev/components/showcase";
|
|
37
37
|
import { type Size } from "../../lib/types";
|
|
38
38
|
|
|
39
|
-
// ──────────────────────────────────────────────────────────
|
|
40
|
-
// RHF Form Demo (Macro)
|
|
41
|
-
// ──────────────────────────────────────────────────────────
|
|
42
39
|
const formSchema = z.object({
|
|
43
40
|
language: z.string().min(1, "Vui lòng chọn một ngôn ngữ.") });
|
|
44
41
|
type FormValues = z.infer<typeof formSchema>;
|
|
@@ -112,17 +109,11 @@ function SelectForm({ size }: { size: Size }) {
|
|
|
112
109
|
);
|
|
113
110
|
}`;
|
|
114
111
|
|
|
115
|
-
// ──────────────────────────────────────────────────────────
|
|
116
|
-
// SECTION 1: Macro Content
|
|
117
|
-
// ──────────────────────────────────────────────────────────
|
|
118
112
|
function SelectMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
119
113
|
return (
|
|
120
|
-
<div className="space-y-10
|
|
114
|
+
<div className="space-y-10">
|
|
121
115
|
<ExampleGrid>
|
|
122
|
-
<
|
|
123
|
-
label="Tiêu chuẩn"
|
|
124
|
-
description="Trình thả xuống cơ bản với mảng options."
|
|
125
|
-
codeString={`<SelectPreset
|
|
116
|
+
<ShowcaseExample title="Tiêu chuẩn" description="Trình thả xuống cơ bản với mảng options." code={`<SelectPreset
|
|
126
117
|
className="w-full"
|
|
127
118
|
label="Trái cây yêu thích"
|
|
128
119
|
description="Chọn một loại trái cây bạn thích nhất."
|
|
@@ -132,26 +123,24 @@ function SelectMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
132
123
|
{ value: "banana", label: "Chuối (Banana)" },
|
|
133
124
|
{ value: "cherry", label: "Anh đào (Cherry)" },
|
|
134
125
|
]}
|
|
135
|
-
/>`}
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
126
|
+
/>`} preview={
|
|
127
|
+
<>
|
|
128
|
+
<SelectPreset
|
|
129
|
+
className="w-full"
|
|
130
|
+
size={globalSize}
|
|
131
|
+
label="Trái cây yêu thích"
|
|
132
|
+
description="Chọn một loại trái cây bạn thích nhất."
|
|
133
|
+
placeholder="Chọn trái cây..."
|
|
134
|
+
options={[
|
|
135
|
+
{ value: "apple", label: "Táo (Apple)" },
|
|
136
|
+
{ value: "banana", label: "Chuối (Banana)" },
|
|
137
|
+
{ value: "cherry", label: "Anh đào (Cherry)" },
|
|
138
|
+
]}
|
|
139
|
+
/>
|
|
140
|
+
</>
|
|
141
|
+
} />
|
|
150
142
|
|
|
151
|
-
<
|
|
152
|
-
label="Trạng thái Lỗi (Error)"
|
|
153
|
-
description="Báo lỗi khi form submit mà user chưa chọn."
|
|
154
|
-
codeString={`<div className="w-full flex flex-col gap-6">
|
|
143
|
+
<ShowcaseExample title="Trạng thái Lỗi (Error)" description="Báo lỗi khi form submit mà user chưa chọn." code={`<div className="w-full flex flex-col gap-6">
|
|
155
144
|
<SelectPreset
|
|
156
145
|
label="Framework (Lỗi)"
|
|
157
146
|
placeholder="Chọn một framework..."
|
|
@@ -161,28 +150,26 @@ function SelectMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
161
150
|
]}
|
|
162
151
|
errorMessage="Vui lòng chọn một framework để tiếp tục."
|
|
163
152
|
/>
|
|
164
|
-
</div>`}
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
153
|
+
</div>`} preview={
|
|
154
|
+
<>
|
|
155
|
+
<div className="w-full flex flex-col gap-6">
|
|
156
|
+
<SelectPreset
|
|
157
|
+
size={globalSize}
|
|
158
|
+
label="Framework (Lỗi)"
|
|
159
|
+
placeholder="Chọn một framework..."
|
|
160
|
+
options={[
|
|
161
|
+
{ value: "react", label: "React" },
|
|
162
|
+
{ value: "vue", label: "Vue" },
|
|
163
|
+
]}
|
|
164
|
+
errorMessage="Vui lòng chọn một framework để tiếp tục."
|
|
165
|
+
/>
|
|
166
|
+
</div>
|
|
167
|
+
</>
|
|
168
|
+
} />
|
|
179
169
|
</ExampleGrid>
|
|
180
170
|
|
|
181
171
|
<ExampleGrid>
|
|
182
|
-
<
|
|
183
|
-
label="Khóa / Bất hoạt (Disabled)"
|
|
184
|
-
description="Người dùng không thể mở danh sách."
|
|
185
|
-
codeString={`<SelectPreset
|
|
172
|
+
<ShowcaseExample title="Khóa / Bất hoạt (Disabled)" description="Người dùng không thể mở danh sách." code={`<SelectPreset
|
|
186
173
|
className="w-full"
|
|
187
174
|
label="Gói tài khoản"
|
|
188
175
|
description="Bạn không thể thay đổi gói cước khi chưa thanh toán nợ."
|
|
@@ -193,27 +180,25 @@ function SelectMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
193
180
|
{ value: "pro", label: "Chuyên nghiệp (Pro)" },
|
|
194
181
|
]}
|
|
195
182
|
disabled
|
|
196
|
-
/>`}
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
183
|
+
/>`} preview={
|
|
184
|
+
<>
|
|
185
|
+
<SelectPreset
|
|
186
|
+
className="w-full"
|
|
187
|
+
size={globalSize}
|
|
188
|
+
label="Gói tài khoản"
|
|
189
|
+
description="Bạn không thể thay đổi gói cước khi chưa thanh toán nợ."
|
|
190
|
+
placeholder="Chọn gói..."
|
|
191
|
+
value="pro"
|
|
192
|
+
options={[
|
|
193
|
+
{ value: "basic", label: "Cơ bản (Free)" },
|
|
194
|
+
{ value: "pro", label: "Chuyên nghiệp (Pro)" },
|
|
195
|
+
]}
|
|
196
|
+
disabled
|
|
197
|
+
/>
|
|
198
|
+
</>
|
|
199
|
+
} />
|
|
212
200
|
|
|
213
|
-
<
|
|
214
|
-
label="Nhãn phức tạp (Custom Content)"
|
|
215
|
-
description="Truyền React Node vào Label để tạo giao diện phong phú."
|
|
216
|
-
codeString={`<SelectPreset
|
|
201
|
+
<ShowcaseExample title="Nhãn phức tạp (Custom Content)" description="Truyền React Node vào Label để tạo giao diện phong phú." code={`<SelectPreset
|
|
217
202
|
label={
|
|
218
203
|
<span className="flex items-center gap-2">
|
|
219
204
|
Quốc gia cư trú
|
|
@@ -227,50 +212,43 @@ function SelectMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
227
212
|
{ value: "vn", label: "Việt Nam" },
|
|
228
213
|
]}
|
|
229
214
|
/>
|
|
230
|
-
`}
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
215
|
+
`} preview={
|
|
216
|
+
<>
|
|
217
|
+
<SelectPreset
|
|
218
|
+
size={globalSize}
|
|
219
|
+
label={
|
|
220
|
+
<span className="flex items-center gap-2">
|
|
221
|
+
Quốc gia cư trú
|
|
222
|
+
<span className="text-destructive">*</span>
|
|
223
|
+
</span>
|
|
224
|
+
}
|
|
225
|
+
description="Thông tin này được sử dụng cho mục đích tính thuế, phải khớp với địa chỉ thanh toán."
|
|
226
|
+
placeholder="Chọn quốc gia..."
|
|
227
|
+
options={[
|
|
228
|
+
{ value: "us", label: "United States" },
|
|
229
|
+
{ value: "vn", label: "Việt Nam" },
|
|
230
|
+
]}
|
|
231
|
+
/>
|
|
232
|
+
</>
|
|
233
|
+
} />
|
|
248
234
|
</ExampleGrid>
|
|
249
235
|
|
|
250
236
|
<ExampleGrid>
|
|
251
|
-
<
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
<SelectForm size={globalSize} />
|
|
257
|
-
</ExampleSection>
|
|
237
|
+
<ShowcaseExample title="Tích hợp React Hook Form" description="Sử dụng Controller để bắt giá trị." code={rhfCode} preview={
|
|
238
|
+
<>
|
|
239
|
+
<SelectForm size={globalSize} />
|
|
240
|
+
</>
|
|
241
|
+
} />
|
|
258
242
|
</ExampleGrid>
|
|
259
243
|
</div>
|
|
260
244
|
);
|
|
261
245
|
}
|
|
262
246
|
|
|
263
|
-
// ──────────────────────────────────────────────────────────
|
|
264
|
-
// SECTION 2: Micro Content
|
|
265
|
-
// ──────────────────────────────────────────────────────────
|
|
266
247
|
function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
267
248
|
return (
|
|
268
|
-
<div className="space-y-10
|
|
249
|
+
<div className="space-y-10">
|
|
269
250
|
<ExampleGrid>
|
|
270
|
-
<
|
|
271
|
-
label="Cơ bản (Primitive)"
|
|
272
|
-
description="Ghép nối thủ công bằng cách bọc Field."
|
|
273
|
-
codeString={`<Field className="w-full">
|
|
251
|
+
<ShowcaseExample title="Cơ bản (Primitive)" description="Ghép nối thủ công bằng cách bọc Field." code={`<Field className="w-full">
|
|
274
252
|
<FieldLabel>Framework</FieldLabel>
|
|
275
253
|
<FieldContent>
|
|
276
254
|
<Select
|
|
@@ -296,36 +274,34 @@ function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
296
274
|
<FieldDescription>
|
|
297
275
|
Chọn công nghệ bạn muốn sử dụng.
|
|
298
276
|
</FieldDescription>
|
|
299
|
-
</Field>`}
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
277
|
+
</Field>`} preview={
|
|
278
|
+
<>
|
|
279
|
+
<Field size={globalSize} className="w-full">
|
|
280
|
+
<FieldLabel>Framework</FieldLabel>
|
|
281
|
+
<FieldContent>
|
|
282
|
+
<Select items={{ next: "Next.js", vite: "Vite", remix: "Remix" }}>
|
|
283
|
+
<SelectTrigger size={globalSize}>
|
|
284
|
+
<SelectValue placeholder="Chọn framework..." />
|
|
285
|
+
</SelectTrigger>
|
|
308
286
|
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
287
|
+
<SelectContent>
|
|
288
|
+
<SelectScrollUpButton />
|
|
289
|
+
<SelectItem value="next">Next.js</SelectItem>
|
|
290
|
+
<SelectItem value="vite">Vite</SelectItem>
|
|
291
|
+
<SelectItem value="remix">Remix</SelectItem>
|
|
292
|
+
<SelectScrollDownButton />
|
|
293
|
+
</SelectContent>
|
|
294
|
+
|
|
295
|
+
</Select>
|
|
296
|
+
</FieldContent>
|
|
297
|
+
<FieldDescription>
|
|
298
|
+
Chọn công nghệ bạn muốn sử dụng.
|
|
299
|
+
</FieldDescription>
|
|
300
|
+
</Field>
|
|
301
|
+
</>
|
|
302
|
+
} />
|
|
324
303
|
|
|
325
|
-
<
|
|
326
|
-
label="Phân nhóm (Grouped)"
|
|
327
|
-
description="Sử dụng SelectGroup, SelectLabel và SelectSeparator."
|
|
328
|
-
codeString={`<Field className="w-full">
|
|
304
|
+
<ShowcaseExample title="Phân nhóm (Grouped)" description="Sử dụng SelectGroup, SelectLabel và SelectSeparator." code={`<Field className="w-full">
|
|
329
305
|
<FieldLabel>Trái cây</FieldLabel>
|
|
330
306
|
<FieldContent>
|
|
331
307
|
<Select
|
|
@@ -333,7 +309,7 @@ function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
333
309
|
orange: "Orange",
|
|
334
310
|
lemon: "Lemon",
|
|
335
311
|
strawberry: "Strawberry",
|
|
336
|
-
blueberry: "
|
|
312
|
+
blueberry: "Việt quất" }}
|
|
337
313
|
>
|
|
338
314
|
<SelectTrigger>
|
|
339
315
|
<SelectValue placeholder="Chọn loại quả..." />
|
|
@@ -361,47 +337,45 @@ function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
361
337
|
|
|
362
338
|
</Select>
|
|
363
339
|
</FieldContent>
|
|
364
|
-
</Field>`}
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
340
|
+
</Field>`} preview={
|
|
341
|
+
<>
|
|
342
|
+
<Field size={globalSize} className="w-full">
|
|
343
|
+
<FieldLabel>Trái cây</FieldLabel>
|
|
344
|
+
<FieldContent>
|
|
345
|
+
<Select
|
|
346
|
+
items={{
|
|
347
|
+
orange: "Orange",
|
|
348
|
+
lemon: "Lemon",
|
|
349
|
+
strawberry: "Strawberry",
|
|
350
|
+
blueberry: "Việt quất" }}
|
|
351
|
+
>
|
|
352
|
+
<SelectTrigger size={globalSize}>
|
|
353
|
+
<SelectValue placeholder="Chọn loại quả..." />
|
|
354
|
+
</SelectTrigger>
|
|
355
|
+
|
|
356
|
+
<SelectContent>
|
|
357
|
+
<SelectGroup>
|
|
358
|
+
<SelectLabel>Họ cam chanh (Citrus)</SelectLabel>
|
|
359
|
+
<SelectItem value="orange">Orange</SelectItem>
|
|
360
|
+
<SelectItem value="lemon">Lemon</SelectItem>
|
|
361
|
+
</SelectGroup>
|
|
362
|
+
<SelectSeparator />
|
|
363
|
+
<SelectGroup>
|
|
364
|
+
<SelectLabel>Họ dâu (Berry)</SelectLabel>
|
|
365
|
+
<SelectItem value="strawberry">Strawberry</SelectItem>
|
|
366
|
+
<SelectItem value="blueberry">Blueberry</SelectItem>
|
|
367
|
+
</SelectGroup>
|
|
368
|
+
</SelectContent>
|
|
369
|
+
|
|
370
|
+
</Select>
|
|
371
|
+
</FieldContent>
|
|
372
|
+
</Field>
|
|
373
|
+
</>
|
|
374
|
+
} />
|
|
398
375
|
</ExampleGrid>
|
|
399
376
|
|
|
400
377
|
<ExampleGrid>
|
|
401
|
-
<
|
|
402
|
-
label="Trạng thái Lỗi thủ công"
|
|
403
|
-
description="Tự gắn aria-invalid vào Select."
|
|
404
|
-
codeString={`<Field data-invalid={true} className="w-full">
|
|
378
|
+
<ShowcaseExample title="Trạng thái Lỗi thủ công" description="Tự gắn aria-invalid vào Select." code={`<Field data-invalid={true} className="w-full">
|
|
405
379
|
<FieldLabel>Dự án</FieldLabel>
|
|
406
380
|
<FieldContent>
|
|
407
381
|
<Select items={{ p1: "Project 1" }}>
|
|
@@ -416,30 +390,28 @@ function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
416
390
|
</Select>
|
|
417
391
|
</FieldContent>
|
|
418
392
|
<FieldError>Vui lòng chọn một dự án hợp lệ.</FieldError>
|
|
419
|
-
</Field>`}
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
393
|
+
</Field>`} preview={
|
|
394
|
+
<>
|
|
395
|
+
<Field size={globalSize} data-invalid={true} className="w-full">
|
|
396
|
+
<FieldLabel>Dự án</FieldLabel>
|
|
397
|
+
<FieldContent>
|
|
398
|
+
<Select items={{ p1: "Project 1" }}>
|
|
399
|
+
<SelectTrigger size={globalSize} aria-invalid={true}>
|
|
400
|
+
<SelectValue placeholder="Chọn dự án..." />
|
|
401
|
+
</SelectTrigger>
|
|
402
|
+
|
|
403
|
+
<SelectContent>
|
|
404
|
+
<SelectItem value="p1">Project 1</SelectItem>
|
|
405
|
+
</SelectContent>
|
|
406
|
+
|
|
407
|
+
</Select>
|
|
408
|
+
</FieldContent>
|
|
409
|
+
<FieldError>Vui lòng chọn một dự án hợp lệ.</FieldError>
|
|
410
|
+
</Field>
|
|
411
|
+
</>
|
|
412
|
+
} />
|
|
438
413
|
|
|
439
|
-
<
|
|
440
|
-
label="Disabled thủ công"
|
|
441
|
-
description="Khóa SelectTrigger."
|
|
442
|
-
codeString={`<Field className="w-full">
|
|
414
|
+
<ShowcaseExample title="Disabled thủ công" description="Khóa SelectTrigger." code={`<Field className="w-full">
|
|
443
415
|
<FieldLabel>Múi giờ</FieldLabel>
|
|
444
416
|
<FieldContent>
|
|
445
417
|
<Select items={{ gmt: "GMT+7" }}>
|
|
@@ -458,34 +430,31 @@ function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
458
430
|
<FieldDescription>
|
|
459
431
|
Múi giờ tự động lấy theo hệ thống.
|
|
460
432
|
</FieldDescription>
|
|
461
|
-
</Field>`}
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
433
|
+
</Field>`} preview={
|
|
434
|
+
<>
|
|
435
|
+
<Field size={globalSize} className="w-full">
|
|
436
|
+
<FieldLabel>Múi giờ</FieldLabel>
|
|
437
|
+
<FieldContent>
|
|
438
|
+
<Select items={{ gmt: "GMT+7" }}>
|
|
439
|
+
<SelectTrigger size={globalSize} disabled>
|
|
440
|
+
<SelectValue placeholder="Chọn múi giờ..." />
|
|
441
|
+
</SelectTrigger>
|
|
442
|
+
|
|
443
|
+
<SelectContent>
|
|
444
|
+
<SelectItem value="gmt">GMT+7 (Indochina Time)</SelectItem>
|
|
445
|
+
</SelectContent>
|
|
446
|
+
|
|
447
|
+
</Select>
|
|
448
|
+
</FieldContent>
|
|
449
|
+
<FieldDescription>
|
|
450
|
+
Múi giờ tự động lấy theo hệ thống.
|
|
451
|
+
</FieldDescription>
|
|
452
|
+
</Field>
|
|
453
|
+
</>
|
|
454
|
+
} />
|
|
482
455
|
</ExampleGrid>
|
|
483
456
|
|
|
484
|
-
<
|
|
485
|
-
label="🧭 Use Case Comparison"
|
|
486
|
-
description="So sánh nhanh khi nào dùng Micro và Macro."
|
|
487
|
-
fullWidth
|
|
488
|
-
codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
457
|
+
<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">
|
|
489
458
|
{/* Story 1: Macro wins */}
|
|
490
459
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
491
460
|
<div className="flex items-start gap-3">
|
|
@@ -556,120 +525,91 @@ function SelectMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
556
525
|
<DocsCode>SelectItem</DocsCode>.
|
|
557
526
|
</p>
|
|
558
527
|
</div>
|
|
559
|
-
</div>`}
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
570
|
-
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
</div>
|
|
528
|
+
</div>`} preview={
|
|
529
|
+
<>
|
|
530
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
531
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
532
|
+
<div className="flex items-start gap-3">
|
|
533
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
534
|
+
<svg
|
|
535
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
536
|
+
className="size-4"
|
|
537
|
+
viewBox="0 0 24 24"
|
|
538
|
+
fill="none"
|
|
539
|
+
stroke="currentColor"
|
|
540
|
+
strokeWidth="2"
|
|
541
|
+
strokeLinecap="round"
|
|
542
|
+
strokeLinejoin="round"
|
|
543
|
+
aria-hidden="true"
|
|
544
|
+
>
|
|
545
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
|
546
|
+
</svg>
|
|
547
|
+
</span>
|
|
548
|
+
<div>
|
|
549
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
550
|
+
Story 1 · Dùng Macro
|
|
551
|
+
</p>
|
|
552
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
553
|
+
Form nhập Quốc tịch
|
|
554
|
+
</h3>
|
|
555
|
+
</div>
|
|
556
|
+
</div>
|
|
557
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
558
|
+
Bạn có 195 quốc gia để chọn, tất cả đều chỉ là chữ. Thay vì viết
|
|
559
|
+
195 thẻ <DocsCode>SelectItem</DocsCode>, bạn vứt mảng JSON 195
|
|
560
|
+
phần tử đó vào thuộc tính <DocsCode>options</DocsCode> của Macro.
|
|
561
|
+
</p>
|
|
562
|
+
</div>
|
|
595
563
|
|
|
596
|
-
|
|
597
|
-
|
|
598
|
-
|
|
599
|
-
|
|
600
|
-
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
|
|
604
|
-
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
618
|
-
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
|
|
564
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
565
|
+
<div className="flex items-start gap-3">
|
|
566
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
567
|
+
<svg
|
|
568
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
569
|
+
className="size-4"
|
|
570
|
+
viewBox="0 0 24 24"
|
|
571
|
+
fill="none"
|
|
572
|
+
stroke="currentColor"
|
|
573
|
+
strokeWidth="2"
|
|
574
|
+
strokeLinecap="round"
|
|
575
|
+
strokeLinejoin="round"
|
|
576
|
+
aria-hidden="true"
|
|
577
|
+
>
|
|
578
|
+
<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" />
|
|
579
|
+
</svg>
|
|
580
|
+
</span>
|
|
581
|
+
<div>
|
|
582
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
583
|
+
Story 2 · Dùng Micro
|
|
584
|
+
</p>
|
|
585
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
586
|
+
Menu Chọn Tài khoản
|
|
587
|
+
</h3>
|
|
588
|
+
</div>
|
|
589
|
+
</div>
|
|
590
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
591
|
+
Bạn muốn trong danh sách thả xuống, mỗi dòng không chỉ là Tên, mà
|
|
592
|
+
còn có cả Avatar (ảnh tròn) và Email (chữ mờ ở dưới). Bạn bắt buộc
|
|
593
|
+
phải dùng Micro để tự thiết kế nội dung bên trong{" "}
|
|
594
|
+
<DocsCode>SelectItem</DocsCode>.
|
|
595
|
+
</p>
|
|
596
|
+
</div>
|
|
597
|
+
</div>
|
|
598
|
+
</>
|
|
599
|
+
} />
|
|
632
600
|
</div>
|
|
633
601
|
);
|
|
634
602
|
}
|
|
635
603
|
|
|
636
|
-
// ──────────────────────────────────────────────────────────
|
|
637
|
-
// SECTION 3: Entry point
|
|
638
|
-
// ──────────────────────────────────────────────────────────
|
|
639
604
|
export default function SelectShowcase() {
|
|
640
605
|
const { size: globalSize } = useDevContext();
|
|
641
606
|
return (
|
|
642
607
|
<Showcase
|
|
643
608
|
title="Select"
|
|
644
609
|
description="Thành phần điều khiển hiển thị danh sách các tùy chọn thả xuống để người dùng chọn."
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
<DocsP>
|
|
649
|
-
<DocsCode>SelectPreset</DocsCode> đóng gói sẵn cấu trúc 8 thẻ của
|
|
650
|
-
Select nguyên thuỷ thành 1 Component duy nhất. Nó dùng prop{" "}
|
|
651
|
-
<DocsCode>options</DocsCode> để render danh sách thả xuống. Dùng
|
|
652
|
-
Macro cho 90% trường hợp form nhập liệu chọn 1 giá trị thông thường.
|
|
653
|
-
</DocsP>
|
|
654
|
-
<DocsH3>Khi nào nên dùng Micro</DocsH3>
|
|
655
|
-
<DocsP>
|
|
656
|
-
Dùng <DocsCode>Select</DocsCode> và các thành phần con nguyên thuỷ
|
|
657
|
-
khi bạn cần một danh sách thả xuống có phân nhóm (
|
|
658
|
-
<DocsCode>SelectGroup</DocsCode>, <DocsCode>SelectLabel</DocsCode>)
|
|
659
|
-
hoặc khi mỗi tuỳ chọn (<DocsCode>SelectItem</DocsCode>) có thiết kế
|
|
660
|
-
phức tạp (chứa icon, ảnh đại diện, subtext) thay vì chỉ là text đơn
|
|
661
|
-
thuần.
|
|
662
|
-
</DocsP>
|
|
663
|
-
</ShowcaseDocs>
|
|
664
|
-
}
|
|
665
|
-
tabs={[
|
|
666
|
-
{
|
|
667
|
-
label: "Micro (Primitive)",
|
|
668
|
-
content: <SelectMicroShowcase globalSize={globalSize} /> },
|
|
669
|
-
{
|
|
670
|
-
label: "Macro (Preset)",
|
|
671
|
-
content: <SelectMacroShowcase globalSize={globalSize} /> },
|
|
672
|
-
]}
|
|
610
|
+
|
|
611
|
+
micro={{ content: <SelectMicroShowcase globalSize={globalSize} /> }}
|
|
612
|
+
macro={{ content: <SelectMacroShowcase globalSize={globalSize} /> }}
|
|
673
613
|
/>
|
|
674
614
|
);
|
|
675
615
|
}
|