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
|
@@ -21,49 +21,41 @@ import {
|
|
|
21
21
|
DocsH3,
|
|
22
22
|
DocsP,
|
|
23
23
|
ExampleGrid,
|
|
24
|
-
|
|
24
|
+
ShowcaseExample,
|
|
25
25
|
Showcase,
|
|
26
26
|
ShowcaseDocs
|
|
27
27
|
} from "../../dev/components/showcase";
|
|
28
28
|
import { type Size } from "../../lib/types";
|
|
29
29
|
|
|
30
|
-
// ──────────────────────────────────────────────────────────
|
|
31
|
-
// SECTION 1: Macro Content
|
|
32
|
-
// ──────────────────────────────────────────────────────────
|
|
33
30
|
function SliderMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
34
31
|
const [val, setVal] = useState([50]);
|
|
35
32
|
const [rangeVal, setRangeVal] = useState([20, 80]);
|
|
36
33
|
|
|
37
34
|
return (
|
|
38
|
-
<div className="space-y-10
|
|
35
|
+
<div className="space-y-10">
|
|
39
36
|
<ExampleGrid>
|
|
40
|
-
<
|
|
41
|
-
label="Tiêu chuẩn"
|
|
42
|
-
description="Thanh trượt cơ bản có nhãn và mô tả."
|
|
43
|
-
codeString={`<SliderPreset
|
|
37
|
+
<ShowcaseExample title="Tiêu chuẩn" description="Thanh trượt cơ bản có nhãn và mô tả." code={`<SliderPreset
|
|
44
38
|
className="w-full"
|
|
45
39
|
label="Âm lượng"
|
|
46
40
|
description="Điều chỉnh âm lượng hệ thống."
|
|
47
41
|
defaultValue={[50]}
|
|
48
42
|
max={100}
|
|
49
43
|
step={1}
|
|
50
|
-
/>`}
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
44
|
+
/>`} preview={
|
|
45
|
+
<>
|
|
46
|
+
<SliderPreset
|
|
47
|
+
className="w-full"
|
|
48
|
+
size={globalSize}
|
|
49
|
+
label="Âm lượng"
|
|
50
|
+
description="Điều chỉnh âm lượng hệ thống."
|
|
51
|
+
defaultValue={[50]}
|
|
52
|
+
max={100}
|
|
53
|
+
step={1}
|
|
54
|
+
/>
|
|
55
|
+
</>
|
|
56
|
+
} />
|
|
62
57
|
|
|
63
|
-
<
|
|
64
|
-
label="Trạng thái Lỗi (Error)"
|
|
65
|
-
description="Báo lỗi khi giá trị không hợp lệ."
|
|
66
|
-
codeString={`<div className="w-full flex flex-col gap-6">
|
|
58
|
+
<ShowcaseExample title="Trạng thái Lỗi (Error)" description="Báo lỗi khi giá trị không hợp lệ." code={`<div className="w-full flex flex-col gap-6">
|
|
67
59
|
<SliderPreset
|
|
68
60
|
label="Mức âm lượng (Lỗi)"
|
|
69
61
|
defaultValue={[110]}
|
|
@@ -71,26 +63,24 @@ function SliderMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
71
63
|
step={1}
|
|
72
64
|
errorMessage="Mức âm lượng không được vượt quá 100."
|
|
73
65
|
/>
|
|
74
|
-
</div>`}
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
66
|
+
</div>`} preview={
|
|
67
|
+
<>
|
|
68
|
+
<div className="w-full flex flex-col gap-6">
|
|
69
|
+
<SliderPreset
|
|
70
|
+
size={globalSize}
|
|
71
|
+
label="Mức âm lượng (Lỗi)"
|
|
72
|
+
defaultValue={[110]}
|
|
73
|
+
max={100}
|
|
74
|
+
step={1}
|
|
75
|
+
errorMessage="Mức âm lượng không được vượt quá 100."
|
|
76
|
+
/>
|
|
77
|
+
</div>
|
|
78
|
+
</>
|
|
79
|
+
} />
|
|
87
80
|
</ExampleGrid>
|
|
88
81
|
|
|
89
82
|
<ExampleGrid>
|
|
90
|
-
<
|
|
91
|
-
label="Thanh trượt Khoảng (Range Slider)"
|
|
92
|
-
description="Truyền mảng 2 giá trị vào defaultValue hoặc value để tạo Range Slider."
|
|
93
|
-
codeString={`const [rangeVal, setRangeVal] = useState([20, 80]); return
|
|
83
|
+
<ShowcaseExample title="Thanh trượt Khoảng (Range Slider)" description="Truyền mảng 2 giá trị vào defaultValue hoặc value để tạo Range Slider." code={`const [rangeVal, setRangeVal] = useState([20, 80]); return
|
|
94
84
|
(
|
|
95
85
|
<SliderPreset
|
|
96
86
|
label="Khoảng giá"
|
|
@@ -100,67 +90,64 @@ function SliderMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
100
90
|
step={5}
|
|
101
91
|
description={\`Từ $\${rangeVal[0]} đến $\${rangeVal[1]}\`}
|
|
102
92
|
/>
|
|
103
|
-
);`}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
93
|
+
);`} preview={
|
|
94
|
+
<>
|
|
95
|
+
<SliderPreset
|
|
96
|
+
className="w-full"
|
|
97
|
+
size={globalSize}
|
|
98
|
+
label="Khoảng giá"
|
|
99
|
+
description={`Hiển thị sản phẩm từ $${rangeVal[0]} đến $${rangeVal[1]}`}
|
|
100
|
+
value={rangeVal}
|
|
101
|
+
onValueChange={(v) => setRangeVal(v as number[])}
|
|
102
|
+
max={100}
|
|
103
|
+
step={5}
|
|
104
|
+
/>
|
|
105
|
+
</>
|
|
106
|
+
} />
|
|
116
107
|
|
|
117
|
-
<
|
|
118
|
-
label="Khóa / Bất hoạt (Disabled)"
|
|
119
|
-
description="Người dùng không thể tương tác với thanh trượt."
|
|
120
|
-
codeString={`<SliderPreset
|
|
108
|
+
<ShowcaseExample title="Khóa / Bất hoạt (Disabled)" description="Người dùng không thể tương tác với thanh trượt." code={`<SliderPreset
|
|
121
109
|
className="w-full"
|
|
122
110
|
label="Độ sáng màn hình"
|
|
123
111
|
description="Độ sáng đang được hệ thống điều khiển tự động (Auto-brightness)."
|
|
124
112
|
defaultValue={[75]}
|
|
125
113
|
max={100}
|
|
126
114
|
disabled
|
|
127
|
-
/>`}
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
115
|
+
/>`} preview={
|
|
116
|
+
<>
|
|
117
|
+
<SliderPreset
|
|
118
|
+
className="w-full"
|
|
119
|
+
size={globalSize}
|
|
120
|
+
label="Độ sáng màn hình"
|
|
121
|
+
description="Độ sáng đang được hệ thống điều khiển tự động (Auto-brightness)."
|
|
122
|
+
defaultValue={[75]}
|
|
123
|
+
max={100}
|
|
124
|
+
disabled
|
|
125
|
+
/>
|
|
126
|
+
</>
|
|
127
|
+
} />
|
|
139
128
|
</ExampleGrid>
|
|
140
129
|
|
|
141
130
|
<ExampleGrid>
|
|
142
|
-
<
|
|
143
|
-
label="Controlled Mode"
|
|
144
|
-
description="Sử dụng biến state của React để điều khiển."
|
|
145
|
-
codeString={`const [val, setVal] = useState([50]); return (
|
|
131
|
+
<ShowcaseExample title="Controlled Mode" description="Sử dụng biến state của React để điều khiển." code={`const [val, setVal] = useState([50]); return (
|
|
146
132
|
<SliderPreset
|
|
147
133
|
value={val}
|
|
148
134
|
onValueChange={setVal}
|
|
149
135
|
label="Giá trị có kiểm soát"
|
|
150
136
|
description={\`Giá trị hiện tại là: \${val[0]}\`}
|
|
151
137
|
/>
|
|
152
|
-
);`}
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
138
|
+
);`} preview={
|
|
139
|
+
<>
|
|
140
|
+
<div className="w-full max-w-sm flex flex-col gap-4">
|
|
141
|
+
<SliderPreset
|
|
142
|
+
size={globalSize}
|
|
143
|
+
value={val}
|
|
144
|
+
onValueChange={(v) => setVal(v as number[])}
|
|
145
|
+
label="Giá trị có kiểm soát"
|
|
146
|
+
description={`Giá trị hiện tại là: ${val[0]}`}
|
|
147
|
+
/>
|
|
148
|
+
</div>
|
|
149
|
+
</>
|
|
150
|
+
} />
|
|
164
151
|
</ExampleGrid>
|
|
165
152
|
</div>
|
|
166
153
|
);
|
|
@@ -171,12 +158,9 @@ function SliderMacroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
171
158
|
// ──────────────────────────────────────────────────────────
|
|
172
159
|
function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
173
160
|
return (
|
|
174
|
-
<div className="space-y-10
|
|
161
|
+
<div className="space-y-10">
|
|
175
162
|
<ExampleGrid>
|
|
176
|
-
<
|
|
177
|
-
label="Cơ bản (Primitive)"
|
|
178
|
-
description="Slider đơn giản không có Field hay Label bọc ngoài."
|
|
179
|
-
codeString={`<CompositionalSlider
|
|
163
|
+
<ShowcaseExample title="Cơ bản (Primitive)" description="Slider đơn giản không có Field hay Label bọc ngoài." code={`<CompositionalSlider
|
|
180
164
|
defaultValue={[40]}
|
|
181
165
|
max={100}
|
|
182
166
|
step={1}
|
|
@@ -188,28 +172,26 @@ function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
188
172
|
</SliderTrack>
|
|
189
173
|
<SliderThumb />
|
|
190
174
|
</SliderControl>
|
|
191
|
-
</CompositionalSlider>`}
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
175
|
+
</CompositionalSlider>`} preview={
|
|
176
|
+
<>
|
|
177
|
+
<CompositionalSlider
|
|
178
|
+
size={globalSize}
|
|
179
|
+
defaultValue={[40]}
|
|
180
|
+
max={100}
|
|
181
|
+
step={1}
|
|
182
|
+
className="w-full"
|
|
183
|
+
>
|
|
184
|
+
<SliderControl>
|
|
185
|
+
<SliderTrack>
|
|
186
|
+
<SliderIndicator />
|
|
187
|
+
</SliderTrack>
|
|
188
|
+
<SliderThumb />
|
|
189
|
+
</SliderControl>
|
|
190
|
+
</CompositionalSlider>
|
|
191
|
+
</>
|
|
192
|
+
} />
|
|
208
193
|
|
|
209
|
-
<
|
|
210
|
-
label="Nhiều Thumb (Multi-thumb)"
|
|
211
|
-
description="Chỉ cần render nhiều SliderThumb, hệ thống sẽ tự chia."
|
|
212
|
-
codeString={`<CompositionalSlider
|
|
194
|
+
<ShowcaseExample title="Nhiều Thumb (Multi-thumb)" description="Chỉ cần render nhiều SliderThumb, hệ thống sẽ tự chia." code={`<CompositionalSlider
|
|
213
195
|
defaultValue={[20, 50, 80]}
|
|
214
196
|
max={100}
|
|
215
197
|
step={1}
|
|
@@ -223,32 +205,30 @@ function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
223
205
|
<SliderThumb />
|
|
224
206
|
<SliderThumb />
|
|
225
207
|
</SliderControl>
|
|
226
|
-
</CompositionalSlider>`}
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
208
|
+
</CompositionalSlider>`} preview={
|
|
209
|
+
<>
|
|
210
|
+
<CompositionalSlider
|
|
211
|
+
size={globalSize}
|
|
212
|
+
defaultValue={[20, 50, 80]}
|
|
213
|
+
max={100}
|
|
214
|
+
step={1}
|
|
215
|
+
className="w-full"
|
|
216
|
+
>
|
|
217
|
+
<SliderControl>
|
|
218
|
+
<SliderTrack>
|
|
219
|
+
<SliderIndicator />
|
|
220
|
+
</SliderTrack>
|
|
221
|
+
<SliderThumb />
|
|
222
|
+
<SliderThumb />
|
|
223
|
+
<SliderThumb />
|
|
224
|
+
</SliderControl>
|
|
225
|
+
</CompositionalSlider>
|
|
226
|
+
</>
|
|
227
|
+
} />
|
|
245
228
|
</ExampleGrid>
|
|
246
229
|
|
|
247
230
|
<ExampleGrid>
|
|
248
|
-
<
|
|
249
|
-
label="Ghép nối Field thủ công"
|
|
250
|
-
description="Lắp ráp với Field để có nhãn và mô tả."
|
|
251
|
-
codeString={`<Field className="w-full">
|
|
231
|
+
<ShowcaseExample title="Ghép nối Field thủ công" description="Lắp ráp với Field để có nhãn và mô tả." code={`<Field className="w-full">
|
|
252
232
|
<FieldLabel>Mật độ hiển thị</FieldLabel>
|
|
253
233
|
<FieldContent>
|
|
254
234
|
<CompositionalSlider
|
|
@@ -267,35 +247,33 @@ function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
267
247
|
<FieldDescription>
|
|
268
248
|
Điều chỉnh khoảng cách giữa các phần tử.
|
|
269
249
|
</FieldDescription>
|
|
270
|
-
</Field>`}
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
250
|
+
</Field>`} preview={
|
|
251
|
+
<>
|
|
252
|
+
<Field size={globalSize} className="w-full">
|
|
253
|
+
<FieldLabel>Mật độ hiển thị</FieldLabel>
|
|
254
|
+
<FieldContent>
|
|
255
|
+
<CompositionalSlider
|
|
256
|
+
size={globalSize}
|
|
257
|
+
defaultValue={[50]}
|
|
258
|
+
max={100}
|
|
259
|
+
step={1}
|
|
260
|
+
>
|
|
261
|
+
<SliderControl>
|
|
262
|
+
<SliderTrack>
|
|
263
|
+
<SliderIndicator />
|
|
264
|
+
</SliderTrack>
|
|
265
|
+
<SliderThumb />
|
|
266
|
+
</SliderControl>
|
|
267
|
+
</CompositionalSlider>
|
|
268
|
+
</FieldContent>
|
|
269
|
+
<FieldDescription>
|
|
270
|
+
Điều chỉnh khoảng cách giữa các phần tử.
|
|
271
|
+
</FieldDescription>
|
|
272
|
+
</Field>
|
|
273
|
+
</>
|
|
274
|
+
} />
|
|
294
275
|
|
|
295
|
-
<
|
|
296
|
-
label="Trạng thái Lỗi thủ công"
|
|
297
|
-
description="Tự gắn aria-invalid vào Slider và dùng FieldError."
|
|
298
|
-
codeString={`<Field className="w-full gap-2" data-invalid={true}>
|
|
276
|
+
<ShowcaseExample title="Trạng thái Lỗi thủ công" description="Tự gắn aria-invalid vào Slider và dùng FieldError." code={`<Field className="w-full gap-2" data-invalid={true}>
|
|
299
277
|
<FieldLabel>Ngân sách tối đa</FieldLabel>
|
|
300
278
|
<FieldContent>
|
|
301
279
|
<CompositionalSlider
|
|
@@ -313,37 +291,34 @@ function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
313
291
|
</CompositionalSlider>
|
|
314
292
|
</FieldContent>
|
|
315
293
|
<FieldError>Ngân sách của bạn chỉ còn $100.</FieldError>
|
|
316
|
-
</Field>`}
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
294
|
+
</Field>`} preview={
|
|
295
|
+
<>
|
|
296
|
+
<Field size={globalSize} className="w-full gap-2" data-invalid={true}>
|
|
297
|
+
<FieldLabel>Ngân sách tối đa</FieldLabel>
|
|
298
|
+
<FieldContent>
|
|
299
|
+
<CompositionalSlider
|
|
300
|
+
size={globalSize}
|
|
301
|
+
defaultValue={[120]}
|
|
302
|
+
max={100}
|
|
303
|
+
step={1}
|
|
304
|
+
aria-invalid={true}
|
|
305
|
+
>
|
|
306
|
+
<SliderControl>
|
|
307
|
+
<SliderTrack>
|
|
308
|
+
<SliderIndicator />
|
|
309
|
+
</SliderTrack>
|
|
310
|
+
<SliderThumb />
|
|
311
|
+
</SliderControl>
|
|
312
|
+
</CompositionalSlider>
|
|
313
|
+
</FieldContent>
|
|
314
|
+
<FieldError>Ngân sách của bạn chỉ còn $100.</FieldError>
|
|
315
|
+
</Field>
|
|
316
|
+
</>
|
|
317
|
+
} />
|
|
339
318
|
</ExampleGrid>
|
|
340
319
|
|
|
341
|
-
<
|
|
342
|
-
|
|
343
|
-
description="So sánh nhanh khi nào dùng Micro và Macro."
|
|
344
|
-
fullWidth
|
|
345
|
-
codeString={`<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
346
|
-
{/* Story 1: Macro wins */}
|
|
320
|
+
<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">
|
|
321
|
+
|
|
347
322
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
348
323
|
<div className="flex items-start gap-3">
|
|
349
324
|
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
@@ -378,7 +353,7 @@ function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
378
353
|
</p>
|
|
379
354
|
</div>
|
|
380
355
|
|
|
381
|
-
|
|
356
|
+
|
|
382
357
|
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
383
358
|
<div className="flex items-start gap-3">
|
|
384
359
|
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
@@ -412,78 +387,79 @@ function SliderMicroShowcase({ globalSize }: { globalSize: Size }) {
|
|
|
412
387
|
độc lập.
|
|
413
388
|
</p>
|
|
414
389
|
</div>
|
|
415
|
-
</div>`}
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
390
|
+
</div>`} preview={
|
|
391
|
+
<>
|
|
392
|
+
<div className="grid grid-cols-1 gap-6 md:grid-cols-2">
|
|
393
|
+
{/* Story 1: Macro wins */}
|
|
394
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
395
|
+
<div className="flex items-start gap-3">
|
|
396
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-green-500/10 p-1.5 text-green-600">
|
|
397
|
+
<svg
|
|
398
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
399
|
+
className="size-4"
|
|
400
|
+
viewBox="0 0 24 24"
|
|
401
|
+
fill="none"
|
|
402
|
+
stroke="currentColor"
|
|
403
|
+
strokeWidth="2"
|
|
404
|
+
strokeLinecap="round"
|
|
405
|
+
strokeLinejoin="round"
|
|
406
|
+
aria-hidden="true"
|
|
407
|
+
>
|
|
408
|
+
<path d="M12 22s8-4 8-10V5l-8-3-8 3v7c0 6 8 10 8 10z" />
|
|
409
|
+
</svg>
|
|
410
|
+
</span>
|
|
411
|
+
<div>
|
|
412
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
413
|
+
Story 1 · Dùng Macro
|
|
414
|
+
</p>
|
|
415
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
416
|
+
Bộ lọc sản phẩm
|
|
417
|
+
</h3>
|
|
418
|
+
</div>
|
|
419
|
+
</div>
|
|
420
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
421
|
+
Bạn cần làm bộ lọc "Khoảng giá" ở cột Sidebar cho trang Ecommerce.{" "}
|
|
422
|
+
<DocsCode>SliderPreset</DocsCode> sẽ giúp bạn tiết kiệm hàng tá
|
|
423
|
+
dòng code bọc Field loằng ngoằng.
|
|
424
|
+
</p>
|
|
425
|
+
</div>
|
|
451
426
|
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
427
|
+
{/* Story 2: Micro wins */}
|
|
428
|
+
<div className="rounded-xl border border-border bg-card p-5 flex flex-col gap-4">
|
|
429
|
+
<div className="flex items-start gap-3">
|
|
430
|
+
<span className="mt-0.5 shrink-0 rounded-full bg-blue-500/10 p-1.5 text-blue-600">
|
|
431
|
+
<svg
|
|
432
|
+
xmlns="http://www.w3.org/2000/svg"
|
|
433
|
+
className="size-4"
|
|
434
|
+
viewBox="0 0 24 24"
|
|
435
|
+
fill="none"
|
|
436
|
+
stroke="currentColor"
|
|
437
|
+
strokeWidth="2"
|
|
438
|
+
strokeLinecap="round"
|
|
439
|
+
strokeLinejoin="round"
|
|
440
|
+
aria-hidden="true"
|
|
441
|
+
>
|
|
442
|
+
<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" />
|
|
443
|
+
</svg>
|
|
444
|
+
</span>
|
|
445
|
+
<div>
|
|
446
|
+
<p className="text-xs font-semibold uppercase tracking-wider text-muted-foreground">
|
|
447
|
+
Story 2 · Dùng Micro
|
|
448
|
+
</p>
|
|
449
|
+
<h3 className="mt-0.5 text-sm font-semibold text-foreground">
|
|
450
|
+
Thanh thời lượng Video (Video Player)
|
|
451
|
+
</h3>
|
|
452
|
+
</div>
|
|
453
|
+
</div>
|
|
454
|
+
<p className="text-xs text-muted-foreground leading-relaxed">
|
|
455
|
+
Bạn đang làm một trình phát Video giống Youtube. Thanh Timeline
|
|
456
|
+
chạy dưới đáy không hề có Label hay Description. Ở đây bạn BẮT
|
|
457
|
+
BUỘC dùng Micro để dựng độc lập.
|
|
458
|
+
</p>
|
|
459
|
+
</div>
|
|
460
|
+
</div>
|
|
461
|
+
</>
|
|
462
|
+
} />
|
|
487
463
|
</div>
|
|
488
464
|
);
|
|
489
465
|
}
|
|
@@ -497,37 +473,9 @@ export default function SliderShowcase() {
|
|
|
497
473
|
<Showcase
|
|
498
474
|
title="Slider"
|
|
499
475
|
description="Thành phần điều khiển cho phép người dùng chọn một hoặc nhiều giá trị trong một phạm vi (range) nhất định."
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
<DocsH3>Khi nào nên dùng Macro</DocsH3>
|
|
504
|
-
<DocsP>
|
|
505
|
-
<DocsCode>SliderPreset</DocsCode> đóng gói sẵn Slider + Label +
|
|
506
|
-
Description + Error Message. Nó tự động xử lý ID linking cho khả
|
|
507
|
-
năng truy cập (Accessibility). Dùng Macro cho 95% trường hợp làm
|
|
508
|
-
form lấy giá trị số hoặc bộ lọc (filter).
|
|
509
|
-
</DocsP>
|
|
510
|
-
</ShowcaseDocs>
|
|
511
|
-
<ShowcaseDocs>
|
|
512
|
-
<DocsH3>Khi nào nên dùng Micro</DocsH3>
|
|
513
|
-
<DocsP>
|
|
514
|
-
Dùng <DocsCode>CompositionalSlider</DocsCode> và các thành phần
|
|
515
|
-
con (<DocsCode>SliderControl</DocsCode>,{" "}
|
|
516
|
-
<DocsCode>SliderTrack</DocsCode>, <DocsCode>SliderThumb</DocsCode>
|
|
517
|
-
) khi bạn cần tuỳ biến giao diện cực hạn (ví dụ: track đổi màu
|
|
518
|
-
theo giá trị, thumb có hình dáng đặc biệt) hoặc không cần label.
|
|
519
|
-
</DocsP>
|
|
520
|
-
</ShowcaseDocs>
|
|
521
|
-
</div>
|
|
522
|
-
}
|
|
523
|
-
tabs={[
|
|
524
|
-
{
|
|
525
|
-
label: "Micro (Primitive)",
|
|
526
|
-
content: <SliderMicroShowcase globalSize={globalSize} /> },
|
|
527
|
-
{
|
|
528
|
-
label: "Macro (Preset)",
|
|
529
|
-
content: <SliderMacroShowcase globalSize={globalSize} /> },
|
|
530
|
-
]}
|
|
476
|
+
|
|
477
|
+
micro={{ content: <SliderMicroShowcase globalSize={globalSize} /> }}
|
|
478
|
+
macro={{ content: <SliderMacroShowcase globalSize={globalSize} /> }}
|
|
531
479
|
/>
|
|
532
480
|
);
|
|
533
481
|
}
|