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
|
@@ -23,44 +23,36 @@ import {
|
|
|
23
23
|
DocsP,
|
|
24
24
|
DocsUl,
|
|
25
25
|
ExampleGrid,
|
|
26
|
-
|
|
26
|
+
ShowcaseExample,
|
|
27
27
|
Showcase,
|
|
28
28
|
ShowcaseDocs
|
|
29
29
|
} from "../../dev/components/showcase";
|
|
30
30
|
import { type Size } from "../../lib/types";
|
|
31
31
|
|
|
32
|
-
// ──────────────────────────────────────────────────────────
|
|
33
|
-
// SECTION 1: Macro Content
|
|
34
|
-
// ──────────────────────────────────────────────────────────
|
|
35
32
|
function InputMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
36
33
|
return (
|
|
37
|
-
<div className="space-y-10
|
|
34
|
+
<div className="space-y-10">
|
|
38
35
|
<ExampleGrid>
|
|
39
|
-
<
|
|
40
|
-
label="Tiêu chuẩn"
|
|
41
|
-
description="Trường nhập văn bản hoàn chỉnh có nhãn và mô tả."
|
|
42
|
-
codeString={`<InputPreset
|
|
36
|
+
<ShowcaseExample title="Tiêu chuẩn" description="Trường nhập văn bản hoàn chỉnh có nhãn và mô tả." code={`<InputPreset
|
|
43
37
|
size="${globalSize}"
|
|
44
38
|
label="Tên đăng nhập"
|
|
45
39
|
description="Đây sẽ là tên hiển thị công khai của bạn."
|
|
46
40
|
placeholder="johndoe"
|
|
47
41
|
className="w-full"
|
|
48
42
|
/>
|
|
49
|
-
`}
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
43
|
+
`} preview={
|
|
44
|
+
<>
|
|
45
|
+
<InputPreset
|
|
46
|
+
size={globalSize}
|
|
47
|
+
label="Tên đăng nhập"
|
|
48
|
+
description="Đây sẽ là tên hiển thị công khai của bạn."
|
|
49
|
+
placeholder="johndoe"
|
|
50
|
+
className="w-full"
|
|
51
|
+
/>
|
|
52
|
+
</>
|
|
53
|
+
} />
|
|
59
54
|
|
|
60
|
-
<
|
|
61
|
-
label="Lỗi xác thực (Validation Error)"
|
|
62
|
-
description="Hiển thị thông báo lỗi và viền đỏ báo hiệu khi truyền errorMessage."
|
|
63
|
-
codeString={`<InputPreset
|
|
55
|
+
<ShowcaseExample title="Lỗi xác thực (Validation Error)" description="Hiển thị thông báo lỗi và viền đỏ báo hiệu khi truyền errorMessage." code={`<InputPreset
|
|
64
56
|
size="${globalSize}"
|
|
65
57
|
label="Mật khẩu"
|
|
66
58
|
type="password"
|
|
@@ -68,24 +60,22 @@ function InputMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
68
60
|
errorMessage="Mật khẩu phải chứa ít nhất 8 ký tự."
|
|
69
61
|
className="w-full"
|
|
70
62
|
/>
|
|
71
|
-
`}
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
63
|
+
`} preview={
|
|
64
|
+
<>
|
|
65
|
+
<InputPreset
|
|
66
|
+
size={globalSize}
|
|
67
|
+
label="Mật khẩu"
|
|
68
|
+
type="password"
|
|
69
|
+
placeholder="Nhập mật khẩu..."
|
|
70
|
+
errorMessage="Mật khẩu phải chứa ít nhất 8 ký tự."
|
|
71
|
+
className="w-full"
|
|
72
|
+
/>
|
|
73
|
+
</>
|
|
74
|
+
} />
|
|
82
75
|
</ExampleGrid>
|
|
83
76
|
|
|
84
77
|
<ExampleGrid>
|
|
85
|
-
<
|
|
86
|
-
label="Với Tiền tố / Hậu tố (Adornments)"
|
|
87
|
-
description="Tự động bọc bằng InputGroup, có thể truyền chuỗi hoặc icon."
|
|
88
|
-
codeString={`<InputPreset
|
|
78
|
+
<ShowcaseExample title="Với Tiền tố / Hậu tố (Adornments)" description="Tự động bọc bằng InputGroup, có thể truyền chuỗi hoặc icon." code={`<InputPreset
|
|
89
79
|
size="${globalSize}"
|
|
90
80
|
label="Website URL"
|
|
91
81
|
type="url"
|
|
@@ -94,23 +84,21 @@ function InputMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
94
84
|
endAdornment=".com"
|
|
95
85
|
className="w-full"
|
|
96
86
|
/>
|
|
97
|
-
`}
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
87
|
+
`} preview={
|
|
88
|
+
<>
|
|
89
|
+
<InputPreset
|
|
90
|
+
size={globalSize}
|
|
91
|
+
label="Website URL"
|
|
92
|
+
type="url"
|
|
93
|
+
placeholder="example"
|
|
94
|
+
startAdornment="https://"
|
|
95
|
+
endAdornment=".com"
|
|
96
|
+
className="w-full"
|
|
97
|
+
/>
|
|
98
|
+
</>
|
|
99
|
+
} />
|
|
109
100
|
|
|
110
|
-
<
|
|
111
|
-
label="Khóa / Bất hoạt (Disabled)"
|
|
112
|
-
description="Người dùng không thể tương tác với form."
|
|
113
|
-
codeString={`<InputPreset
|
|
101
|
+
<ShowcaseExample title="Khóa / Bất hoạt (Disabled)" description="Người dùng không thể tương tác với form." code={`<InputPreset
|
|
114
102
|
size="${globalSize}"
|
|
115
103
|
label="Tên dự án"
|
|
116
104
|
description="Tên dự án không thể thay đổi sau khi khởi tạo."
|
|
@@ -118,24 +106,21 @@ function InputMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
118
106
|
disabled
|
|
119
107
|
className="w-full"
|
|
120
108
|
/>
|
|
121
|
-
`}
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
109
|
+
`} preview={
|
|
110
|
+
<>
|
|
111
|
+
<InputPreset
|
|
112
|
+
size={globalSize}
|
|
113
|
+
label="Tên dự án"
|
|
114
|
+
description="Tên dự án không thể thay đổi sau khi khởi tạo."
|
|
115
|
+
defaultValue="my-awesome-project"
|
|
116
|
+
disabled
|
|
117
|
+
className="w-full"
|
|
118
|
+
/>
|
|
119
|
+
</>
|
|
120
|
+
} />
|
|
132
121
|
</ExampleGrid>
|
|
133
122
|
|
|
134
|
-
<
|
|
135
|
-
label="Thực tế sử dụng (Real-world Snippets)"
|
|
136
|
-
description="Tuỳ biến Label với ReactNode để tạo các nhãn phức tạp."
|
|
137
|
-
fullWidth
|
|
138
|
-
codeString={`<InputPreset
|
|
123
|
+
<ShowcaseExample title="Thực tế sử dụng (Real-world Snippets)" description="Tuỳ biến Label với ReactNode để tạo các nhãn phức tạp." code={`<InputPreset
|
|
139
124
|
size="${globalSize}"
|
|
140
125
|
label={
|
|
141
126
|
<span className="flex items-center gap-2">
|
|
@@ -159,39 +144,40 @@ function InputMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
159
144
|
</kbd>
|
|
160
145
|
}
|
|
161
146
|
className="w-full"
|
|
162
|
-
/>`}
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
147
|
+
/>`} preview={
|
|
148
|
+
<>
|
|
149
|
+
<div className="grid grid-cols-1 md:grid-cols-2 gap-6">
|
|
150
|
+
<InputPreset
|
|
151
|
+
size={globalSize}
|
|
152
|
+
label={
|
|
153
|
+
<span className="flex items-center gap-2">
|
|
154
|
+
Mã API (API Key){" "}
|
|
155
|
+
<span className="rounded bg-destructive/20 px-1.5 py-0.5 text-[10px] font-semibold text-destructive uppercase">
|
|
156
|
+
Bảo mật
|
|
157
|
+
</span>
|
|
158
|
+
</span>
|
|
159
|
+
}
|
|
160
|
+
type="password"
|
|
161
|
+
description="Tuyệt đối không chia sẻ mã này với bất kỳ ai."
|
|
162
|
+
defaultValue="sk_test_1234567890abcdef"
|
|
163
|
+
className="w-full"
|
|
164
|
+
/>
|
|
180
165
|
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
166
|
+
<InputPreset
|
|
167
|
+
size={globalSize}
|
|
168
|
+
label="Tìm kiếm nhanh"
|
|
169
|
+
placeholder="Gõ từ khoá..."
|
|
170
|
+
startAdornment={<SearchIcon className="size-4" />}
|
|
171
|
+
endAdornment={
|
|
172
|
+
<kbd className="pointer-events-none inline-flex h-5 select-none items-center gap-1 rounded border border-border bg-muted px-1.5 font-mono text-[10px] font-medium text-muted-foreground">
|
|
173
|
+
<span className="text-xs">⌘</span>K
|
|
174
|
+
</kbd>
|
|
175
|
+
}
|
|
176
|
+
className="w-full"
|
|
177
|
+
/>
|
|
178
|
+
</div>
|
|
179
|
+
</>
|
|
180
|
+
} />
|
|
195
181
|
</div>
|
|
196
182
|
);
|
|
197
183
|
}
|
|
@@ -201,29 +187,24 @@ function InputMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
201
187
|
// ──────────────────────────────────────────────────────────
|
|
202
188
|
function InputMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
203
189
|
return (
|
|
204
|
-
<div className="space-y-10
|
|
190
|
+
<div className="space-y-10">
|
|
205
191
|
<ExampleGrid>
|
|
206
|
-
<
|
|
207
|
-
label="Cơ bản (Primitive)"
|
|
208
|
-
description="Thẻ input đơn giản không có nhãn."
|
|
209
|
-
codeString={`<Input
|
|
192
|
+
<ShowcaseExample title="Cơ bản (Primitive)" description="Thẻ input đơn giản không có nhãn." code={`<Input
|
|
210
193
|
size="${globalSize}"
|
|
211
194
|
placeholder="Nhập địa chỉ email..."
|
|
212
195
|
className="w-full"
|
|
213
196
|
/>
|
|
214
|
-
`}
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
197
|
+
`} preview={
|
|
198
|
+
<>
|
|
199
|
+
<Input
|
|
200
|
+
size={globalSize}
|
|
201
|
+
placeholder="Nhập địa chỉ email..."
|
|
202
|
+
className="w-full"
|
|
203
|
+
/>
|
|
204
|
+
</>
|
|
205
|
+
} />
|
|
222
206
|
|
|
223
|
-
<
|
|
224
|
-
label="Ghép nối với Field"
|
|
225
|
-
description="Lắp ráp thủ công các thành phần Field để tạo form control."
|
|
226
|
-
codeString={`<Field size="${globalSize}" className="w-full">
|
|
207
|
+
<ShowcaseExample title="Ghép nối với Field" description="Lắp ráp thủ công các thành phần Field để tạo form control." code={`<Field size="${globalSize}" className="w-full">
|
|
227
208
|
<FieldLabel htmlFor="tf-input">Email</FieldLabel>
|
|
228
209
|
<FieldDescription>
|
|
229
210
|
Chúng tôi sẽ không bao giờ chia sẻ email của bạn.
|
|
@@ -236,29 +217,27 @@ function InputMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
236
217
|
/>
|
|
237
218
|
</FieldContent>
|
|
238
219
|
</Field>
|
|
239
|
-
`}
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
220
|
+
`} preview={
|
|
221
|
+
<>
|
|
222
|
+
<Field size={globalSize} className="w-full">
|
|
223
|
+
<FieldLabel htmlFor="tf-input">Email</FieldLabel>
|
|
224
|
+
<FieldDescription>
|
|
225
|
+
Chúng tôi sẽ không bao giờ chia sẻ email của bạn.
|
|
226
|
+
</FieldDescription>
|
|
227
|
+
<FieldContent>
|
|
228
|
+
<Input
|
|
229
|
+
id="tf-input"
|
|
230
|
+
size={globalSize}
|
|
231
|
+
placeholder="you@example.com"
|
|
232
|
+
/>
|
|
233
|
+
</FieldContent>
|
|
234
|
+
</Field>
|
|
235
|
+
</>
|
|
236
|
+
} />
|
|
255
237
|
</ExampleGrid>
|
|
256
238
|
|
|
257
239
|
<ExampleGrid>
|
|
258
|
-
<
|
|
259
|
-
label="Trạng thái Lỗi (Error)"
|
|
260
|
-
description="Sử dụng thuộc tính aria-invalid để báo lỗi."
|
|
261
|
-
codeString={`<Field size="${globalSize}" className="w-full">
|
|
240
|
+
<ShowcaseExample title="Trạng thái Lỗi (Error)" description="Sử dụng thuộc tính aria-invalid để báo lỗi." code={`<Field size="${globalSize}" className="w-full">
|
|
262
241
|
<FieldLabel htmlFor="tf-error">Tên tài khoản</FieldLabel>
|
|
263
242
|
<FieldContent>
|
|
264
243
|
<Input
|
|
@@ -272,28 +251,26 @@ function InputMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
272
251
|
Tên tài khoản không được chứa ký tự đặc biệt.
|
|
273
252
|
</FieldError>
|
|
274
253
|
</Field>
|
|
275
|
-
`}
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
254
|
+
`} preview={
|
|
255
|
+
<>
|
|
256
|
+
<Field size={globalSize} className="w-full">
|
|
257
|
+
<FieldLabel htmlFor="tf-error">Tên tài khoản</FieldLabel>
|
|
258
|
+
<FieldContent>
|
|
259
|
+
<Input
|
|
260
|
+
id="tf-error"
|
|
261
|
+
size={globalSize}
|
|
262
|
+
defaultValue="admin!@#"
|
|
263
|
+
aria-invalid="true"
|
|
264
|
+
/>
|
|
265
|
+
</FieldContent>
|
|
266
|
+
<FieldError>
|
|
267
|
+
Tên tài khoản không được chứa ký tự đặc biệt.
|
|
268
|
+
</FieldError>
|
|
269
|
+
</Field>
|
|
270
|
+
</>
|
|
271
|
+
} />
|
|
292
272
|
|
|
293
|
-
<
|
|
294
|
-
label="Input Group"
|
|
295
|
-
description="Ghép nối với các Addon linh hoạt (Slot tuỳ ý)."
|
|
296
|
-
codeString={`<Field size="${globalSize}" className="w-full">
|
|
273
|
+
<ShowcaseExample title="Input Group" description="Ghép nối với các Addon linh hoạt (Slot tuỳ ý)." code={`<Field size="${globalSize}" className="w-full">
|
|
297
274
|
<FieldLabel htmlFor="tf-group">Trang cá nhân</FieldLabel>
|
|
298
275
|
<FieldContent>
|
|
299
276
|
<InputGroup size="${globalSize}">
|
|
@@ -307,57 +284,49 @@ function InputMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
307
284
|
</InputGroup>
|
|
308
285
|
</FieldContent>
|
|
309
286
|
</Field>
|
|
310
|
-
`}
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
287
|
+
`} preview={
|
|
288
|
+
<>
|
|
289
|
+
<Field size={globalSize} className="w-full">
|
|
290
|
+
<FieldLabel htmlFor="tf-group">Trang cá nhân</FieldLabel>
|
|
291
|
+
<FieldContent>
|
|
292
|
+
<InputGroup size={globalSize}>
|
|
293
|
+
<InputGroupAddon>
|
|
294
|
+
<LinkIcon className="size-4 text-muted-foreground" />
|
|
295
|
+
</InputGroupAddon>
|
|
296
|
+
<InputGroupAddon>
|
|
297
|
+
<InputGroupText>github.com/</InputGroupText>
|
|
298
|
+
</InputGroupAddon>
|
|
299
|
+
<InputGroupInput id="tf-group" placeholder="username" />
|
|
300
|
+
</InputGroup>
|
|
301
|
+
</FieldContent>
|
|
302
|
+
</Field>
|
|
303
|
+
</>
|
|
304
|
+
} />
|
|
327
305
|
</ExampleGrid>
|
|
328
|
-
<
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
<Input size={globalSize} type="file" className="w-full pt-0.5" />
|
|
335
|
-
</ExampleSection>
|
|
306
|
+
<ShowcaseExample title="Input Kiểu Tệp (File)" description="Input có hỗ trợ style gốc cho type file." code={`<Input size="${globalSize}" type="file" className="w-full pt-0.5" />
|
|
307
|
+
`} preview={
|
|
308
|
+
<>
|
|
309
|
+
<Input size={globalSize} type="file" className="w-full pt-0.5" />
|
|
310
|
+
</>
|
|
311
|
+
} />
|
|
336
312
|
|
|
337
|
-
<
|
|
338
|
-
label="Khóa (Disabled)"
|
|
339
|
-
description="Trạng thái không thể tương tác."
|
|
340
|
-
codeString={`<Input
|
|
313
|
+
<ShowcaseExample title="Khóa (Disabled)" description="Trạng thái không thể tương tác." code={`<Input
|
|
341
314
|
size="${globalSize}"
|
|
342
315
|
disabled
|
|
343
316
|
defaultValue="Chỉ đọc"
|
|
344
317
|
className="w-full"
|
|
345
318
|
/>
|
|
346
|
-
`}
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
description="So sánh nhanh khi nào dùng Micro và Macro."
|
|
358
|
-
fullWidth
|
|
359
|
-
codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
360
|
-
{/* Story 1: Macro wins */}
|
|
319
|
+
`} preview={
|
|
320
|
+
<>
|
|
321
|
+
<Input
|
|
322
|
+
size={globalSize}
|
|
323
|
+
disabled
|
|
324
|
+
defaultValue="Chỉ đọc"
|
|
325
|
+
className="w-full"
|
|
326
|
+
/>
|
|
327
|
+
</>
|
|
328
|
+
} />
|
|
329
|
+
<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">
|
|
361
330
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
362
331
|
<div className="flex items-start gap-3">
|
|
363
332
|
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
@@ -392,7 +361,6 @@ function InputMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
392
361
|
</p>
|
|
393
362
|
</div>
|
|
394
363
|
|
|
395
|
-
{/* Story 2: Micro wins */}
|
|
396
364
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
397
365
|
<div className="flex items-start gap-3">
|
|
398
366
|
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
@@ -426,76 +394,77 @@ function InputMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
426
394
|
khác.
|
|
427
395
|
</p>
|
|
428
396
|
</div>
|
|
429
|
-
</div>`}
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
397
|
+
</div>`} preview={
|
|
398
|
+
<>
|
|
399
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
400
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
401
|
+
<div className="flex items-start gap-3">
|
|
402
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
403
|
+
<svg
|
|
404
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
405
|
+
className="size-4"
|
|
406
|
+
viewBox="0 0 24 24"
|
|
407
|
+
fill="none"
|
|
408
|
+
stroke="currentColor"
|
|
409
|
+
strokeWidth="2"
|
|
410
|
+
strokeLinecap="round"
|
|
411
|
+
strokeLinejoin="round"
|
|
412
|
+
aria-hidden="true"
|
|
413
|
+
>
|
|
414
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
|
415
|
+
</svg>
|
|
416
|
+
</span>
|
|
417
|
+
<div>
|
|
418
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
419
|
+
Story 1 · Dùng Macro
|
|
420
|
+
</p>
|
|
421
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
422
|
+
Form nhập liệu tiêu chuẩn
|
|
423
|
+
</h3>
|
|
424
|
+
</div>
|
|
425
|
+
</div>
|
|
426
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
427
|
+
Khi bạn cần một trường nhập liệu đầy đủ nhãn (Label), mô tả
|
|
428
|
+
(Description), báo lỗi (Error) mà không muốn phải lắp ráp thủ công
|
|
429
|
+
bằng <DocsCode>Field</DocsCode>.
|
|
430
|
+
</p>
|
|
431
|
+
</div>
|
|
464
432
|
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
433
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
434
|
+
<div className="flex items-start gap-3">
|
|
435
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
436
|
+
<svg
|
|
437
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
438
|
+
className="size-4"
|
|
439
|
+
viewBox="0 0 24 24"
|
|
440
|
+
fill="none"
|
|
441
|
+
stroke="currentColor"
|
|
442
|
+
strokeWidth="2"
|
|
443
|
+
strokeLinecap="round"
|
|
444
|
+
strokeLinejoin="round"
|
|
445
|
+
aria-hidden="true"
|
|
446
|
+
>
|
|
447
|
+
<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" />
|
|
448
|
+
</svg>
|
|
449
|
+
</span>
|
|
450
|
+
<div>
|
|
451
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
452
|
+
Story 2 · Dùng Micro
|
|
453
|
+
</p>
|
|
454
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
455
|
+
Input nằm trong Navbar hoặc Toolbar
|
|
456
|
+
</h3>
|
|
457
|
+
</div>
|
|
458
|
+
</div>
|
|
459
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
460
|
+
Chỉ cần một thẻ <DocsCode>Input</DocsCode> đơn giản để tìm kiếm
|
|
461
|
+
nhanh, không cần nhãn hay mô tả cầu kỳ, hoặc khi phải nhúng nó vào
|
|
462
|
+
một component phức tạp khác.
|
|
463
|
+
</p>
|
|
464
|
+
</div>
|
|
465
|
+
</div>
|
|
466
|
+
</>
|
|
467
|
+
} />
|
|
499
468
|
</div>
|
|
500
469
|
);
|
|
501
470
|
}
|
|
@@ -507,58 +476,10 @@ export default function InputShowcase() {
|
|
|
507
476
|
<Showcase
|
|
508
477
|
title="Input"
|
|
509
478
|
description="Trường nhập văn bản cho phép người dùng điền dữ liệu."
|
|
510
|
-
|
|
511
|
-
<ShowcaseDocs>
|
|
512
|
-
<DocsH3>Khi nào nên dùng Macro</DocsH3>
|
|
513
|
-
<DocsP>
|
|
514
|
-
Bản Macro (<DocsCode>InputPreset</DocsCode>) đóng gói sẵn toàn bộ
|
|
515
|
-
các thành phần thường thấy của một Form Control: Nhãn (Label), Mô tả
|
|
516
|
-
(Description), Lỗi (Error Message) và phần trang trí (Adornments).
|
|
517
|
-
Việc này giúp giảm thiểu lượng code lặp đi lặp lại khi xây dựng
|
|
518
|
-
form.
|
|
519
|
-
</DocsP>
|
|
520
|
-
|
|
521
|
-
<DocsH3>Tự động hoá Layout (Macro)</DocsH3>
|
|
522
|
-
<DocsUl>
|
|
523
|
-
<DocsLi>
|
|
524
|
-
Tự động bọc Input vào trong <DocsCode>InputGroup</DocsCode> nếu
|
|
525
|
-
bạn truyền <DocsCode>startAdornment</DocsCode> hoặc{" "}
|
|
526
|
-
<DocsCode>endAdornment</DocsCode>.
|
|
527
|
-
</DocsLi>
|
|
528
|
-
<DocsLi>
|
|
529
|
-
Tự động hiện Icon con mắt (Toggle ẩn/hiện) nếu{" "}
|
|
530
|
-
<DocsCode>type="password"</DocsCode>.
|
|
531
|
-
</DocsLi>
|
|
532
|
-
<DocsLi>
|
|
533
|
-
Tự động thêm class <DocsCode>aria-invalid</DocsCode> vào input nếu
|
|
534
|
-
bạn truyền <DocsCode>errorMessage</DocsCode>.
|
|
535
|
-
</DocsLi>
|
|
536
|
-
</DocsUl>
|
|
537
|
-
|
|
538
|
-
<DocsH3>Khi nào nên dùng Micro</DocsH3>
|
|
539
|
-
<DocsP>
|
|
540
|
-
Thành phần <DocsCode>Input</DocsCode> nguyên thuỷ chỉ là một thẻ{" "}
|
|
541
|
-
<DocsCode>input</DocsCode> duy nhất. Để có được một Form Control
|
|
542
|
-
đúng chuẩn WCAG, bạn cần phải tự bọc nó bằng{" "}
|
|
543
|
-
<DocsCode>Field</DocsCode>, kết nối <DocsCode>FieldLabel</DocsCode>{" "}
|
|
544
|
-
và <DocsCode>FieldDescription</DocsCode>.
|
|
545
|
-
</DocsP>
|
|
546
|
-
<DocsP>
|
|
547
|
-
Dùng Micro khi bạn cần layout form dị biệt (ví dụ: label nằm ngang
|
|
548
|
-
bên trái input) hoặc khi cần nhúng Input vào một component phức tạp
|
|
549
|
-
(như dropdown tìm kiếm).
|
|
550
|
-
</DocsP>
|
|
551
|
-
</ShowcaseDocs>
|
|
552
|
-
}
|
|
479
|
+
|
|
553
480
|
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
label: "Micro (Primitive)",
|
|
557
|
-
content: <InputMicroShowcase globalSize={globalSize} /> },
|
|
558
|
-
{
|
|
559
|
-
label: "Macro (Preset)",
|
|
560
|
-
content: <InputMacroShowcase globalSize={globalSize} /> },
|
|
561
|
-
]}
|
|
481
|
+
micro={{ content: <InputMicroShowcase globalSize={globalSize} /> }}
|
|
482
|
+
macro={{ content: <InputMacroShowcase globalSize={globalSize} /> }}
|
|
562
483
|
/>
|
|
563
484
|
);
|
|
564
485
|
}
|