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
|
@@ -6,12 +6,11 @@ import {
|
|
|
6
6
|
DocsCode,
|
|
7
7
|
DocsP,
|
|
8
8
|
ExampleGrid,
|
|
9
|
-
|
|
9
|
+
ShowcaseExample,
|
|
10
10
|
Showcase,
|
|
11
11
|
ShowcaseDocs
|
|
12
12
|
} from "../../dev/components/showcase";
|
|
13
13
|
|
|
14
|
-
// Simulated async operation for Promise demo
|
|
15
14
|
const mockSave = () =>
|
|
16
15
|
new Promise<{ name: string }>((resolve) =>
|
|
17
16
|
setTimeout(() => resolve({ name: "Sonner" }), 1500),
|
|
@@ -22,120 +21,114 @@ const mockFail = () =>
|
|
|
22
21
|
setTimeout(() => reject(new Error("Server error")), 1500),
|
|
23
22
|
);
|
|
24
23
|
|
|
25
|
-
// ──────────────────────────────────────────────────────────
|
|
26
|
-
// SECTION 2: Micro Content (không export)
|
|
27
|
-
// ──────────────────────────────────────────────────────────
|
|
28
24
|
function SonnerMicroShowcase() {
|
|
29
25
|
return (
|
|
30
|
-
<div className="space-y-10
|
|
31
|
-
|
|
26
|
+
<div className="space-y-10">
|
|
27
|
+
|
|
32
28
|
<Toaster position="bottom-right" />
|
|
33
|
-
|
|
34
|
-
<
|
|
35
|
-
label="Loại Toast"
|
|
36
|
-
description="Năm loại toast cơ bản: default, success, error, warning, info."
|
|
37
|
-
codeString={`import { toast } from "sonner";
|
|
29
|
+
|
|
30
|
+
<ShowcaseExample title="Loại Toast" description="Năm loại toast cơ bản: default, success, error, warning, info." code={`import { toast } from "sonner";
|
|
38
31
|
|
|
39
32
|
// Default
|
|
40
|
-
toast("
|
|
41
|
-
description: "
|
|
42
|
-
action: { label: "
|
|
33
|
+
toast("Sự kiện đã được tạo", {
|
|
34
|
+
description: "Chủ nhật, ngày 03 tháng 12 năm 2023 lúc 9:00 sáng",
|
|
35
|
+
action: { label: "Hoàn tác", onClick: () => console.log("Hoàn tác") } });
|
|
43
36
|
|
|
44
37
|
// Typed variants
|
|
45
38
|
toast.success("Successfully saved!");
|
|
46
39
|
toast.error("An error occurred.");
|
|
47
40
|
toast.warning("Connection is unstable.");
|
|
48
|
-
toast.info("Update is available.");`}
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
41
|
+
toast.info("Update is available.");`} preview={
|
|
42
|
+
<>
|
|
43
|
+
<div className="flex flex-wrap gap-2">
|
|
44
|
+
<Button
|
|
45
|
+
variant="outline"
|
|
46
|
+
onClick={() =>
|
|
47
|
+
toast("Sự kiện đã được tạo", {
|
|
48
|
+
description: "Chủ nhật, ngày 03 tháng 12 năm 2023 lúc 9:00 sáng",
|
|
49
|
+
action: { label: "Hoàn tác", onClick: () => console.log("Hoàn tác") }
|
|
50
|
+
})
|
|
51
|
+
}
|
|
52
|
+
>
|
|
53
|
+
Default
|
|
54
|
+
</Button>
|
|
55
|
+
<Button
|
|
56
|
+
variant="outline"
|
|
57
|
+
color="success"
|
|
58
|
+
onClick={() => toast.success("Successfully saved!")}
|
|
59
|
+
>
|
|
60
|
+
Success
|
|
61
|
+
</Button>
|
|
62
|
+
<Button
|
|
63
|
+
variant="outline"
|
|
64
|
+
color="destructive"
|
|
65
|
+
onClick={() => toast.error("An error occurred.")}
|
|
66
|
+
>
|
|
67
|
+
Error
|
|
68
|
+
</Button>
|
|
69
|
+
<Button
|
|
70
|
+
variant="outline"
|
|
71
|
+
color="warning"
|
|
72
|
+
onClick={() => toast.warning("Connection is unstable.")}
|
|
73
|
+
>
|
|
74
|
+
Warning
|
|
75
|
+
</Button>
|
|
76
|
+
<Button
|
|
77
|
+
variant="outline"
|
|
78
|
+
color="info"
|
|
79
|
+
onClick={() => toast.info("Update is available.")}
|
|
80
|
+
>
|
|
81
|
+
Info
|
|
82
|
+
</Button>
|
|
83
|
+
</div>
|
|
84
|
+
</>
|
|
85
|
+
} />
|
|
91
86
|
|
|
92
|
-
|
|
93
|
-
<ExampleSection
|
|
94
|
-
label="Mô tả & Action Button"
|
|
95
|
-
description="Toast kèm description phụ và action button — pattern phổ biến cho undo/redo, navigation."
|
|
96
|
-
codeString={`toast("File deleted", {
|
|
87
|
+
<ShowcaseExample title="Mô tả & Action Button" description="Toast kèm description phụ và action button — pattern phổ biến cho undo/redo, navigation." code={`toast("File deleted", {
|
|
97
88
|
description: "draft-v2.docx has been moved to trash.",
|
|
98
89
|
action: {
|
|
99
|
-
label: "
|
|
90
|
+
label: "Hoàn tác",
|
|
100
91
|
onClick: () => console.log("Undo delete") },
|
|
101
92
|
cancel: {
|
|
102
93
|
label: "Dismiss",
|
|
103
|
-
onClick: () => {} } });`}
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
94
|
+
onClick: () => {} } });`} preview={
|
|
95
|
+
<>
|
|
96
|
+
<div className="flex flex-wrap gap-2">
|
|
97
|
+
<Button
|
|
98
|
+
variant="outline"
|
|
99
|
+
onClick={() =>
|
|
100
|
+
toast("File deleted", {
|
|
101
|
+
description: "draft-v2.docx has been moved to trash.",
|
|
102
|
+
action: {
|
|
103
|
+
label: "Hoàn tác",
|
|
104
|
+
onClick: () => console.log("Undo delete")
|
|
105
|
+
},
|
|
106
|
+
cancel: {
|
|
107
|
+
label: "Dismiss",
|
|
108
|
+
onClick: () => { }
|
|
109
|
+
}
|
|
110
|
+
})
|
|
111
|
+
}
|
|
112
|
+
>
|
|
113
|
+
File Deleted (with Action)
|
|
114
|
+
</Button>
|
|
115
|
+
<Button
|
|
116
|
+
variant="outline"
|
|
117
|
+
onClick={() =>
|
|
118
|
+
toast.success("Profile updated", {
|
|
119
|
+
description: "Your changes have been saved successfully."
|
|
120
|
+
})
|
|
121
|
+
}
|
|
122
|
+
>
|
|
123
|
+
Success with Description
|
|
124
|
+
</Button>
|
|
125
|
+
</div>
|
|
126
|
+
</>
|
|
127
|
+
} />
|
|
132
128
|
|
|
133
|
-
{
|
|
129
|
+
{ }
|
|
134
130
|
<ExampleGrid>
|
|
135
|
-
<
|
|
136
|
-
label="Promise — Thành công"
|
|
137
|
-
description="toast.promise() tự quản lý trạng thái loading → success/error theo kết quả của Promise."
|
|
138
|
-
codeString={`const saveData = () =>
|
|
131
|
+
<ShowcaseExample title="Promise — Thành công" description="toast.promise() tự quản lý trạng thái loading → success/error theo kết quả của Promise." code={`const saveData = () =>
|
|
139
132
|
new Promise<{ name: string }>((resolve) =>
|
|
140
133
|
setTimeout(() => resolve({ name: "Sonner" }), 1500),
|
|
141
134
|
);
|
|
@@ -143,25 +136,24 @@ toast.info("Update is available.");`}
|
|
|
143
136
|
toast.promise(saveData(), {
|
|
144
137
|
loading: "Đang lưu...",
|
|
145
138
|
success: (data) => \`Đã lưu \${data.name} thành công!\`,
|
|
146
|
-
error: "Lưu thất bại!" });`}
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
139
|
+
error: "Lưu thất bại!" });`} preview={
|
|
140
|
+
<>
|
|
141
|
+
<Button
|
|
142
|
+
variant="outline"
|
|
143
|
+
onClick={() =>
|
|
144
|
+
toast.promise(mockSave(), {
|
|
145
|
+
loading: "Đang lưu...",
|
|
146
|
+
success: (data) => `Đã lưu ${data.name} thành công!`,
|
|
147
|
+
error: "Lưu thất bại!"
|
|
148
|
+
})
|
|
149
|
+
}
|
|
150
|
+
>
|
|
151
|
+
Promise (Success)
|
|
152
|
+
</Button>
|
|
153
|
+
</>
|
|
154
|
+
} />
|
|
160
155
|
|
|
161
|
-
<
|
|
162
|
-
label="Promise — Thất bại"
|
|
163
|
-
description="Promise bị reject sẽ tự chuyển sang trạng thái error toast."
|
|
164
|
-
codeString={`const failRequest = () =>
|
|
156
|
+
<ShowcaseExample title="Promise — Thất bại" description="Promise bị reject sẽ tự chuyển sang trạng thái error toast." code={`const failRequest = () =>
|
|
165
157
|
new Promise<void>((_, reject) =>
|
|
166
158
|
setTimeout(() => reject(new Error("Server error")), 1500),
|
|
167
159
|
);
|
|
@@ -169,157 +161,158 @@ toast.promise(saveData(), {
|
|
|
169
161
|
toast.promise(failRequest(), {
|
|
170
162
|
loading: "Đang gửi yêu cầu...",
|
|
171
163
|
success: "Yêu cầu thành công!",
|
|
172
|
-
error: "Yêu cầu thất bại!" });`}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
164
|
+
error: "Yêu cầu thất bại!" });`} preview={
|
|
165
|
+
<>
|
|
166
|
+
<Button
|
|
167
|
+
variant="outline"
|
|
168
|
+
color="destructive"
|
|
169
|
+
onClick={() =>
|
|
170
|
+
toast.promise(mockFail(), {
|
|
171
|
+
loading: "Đang gửi yêu cầu...",
|
|
172
|
+
success: "Yêu cầu thành công!",
|
|
173
|
+
error: "Yêu cầu thất bại!"
|
|
174
|
+
})
|
|
175
|
+
}
|
|
176
|
+
>
|
|
177
|
+
Promise (Error)
|
|
178
|
+
</Button>
|
|
179
|
+
</>
|
|
180
|
+
} />
|
|
187
181
|
</ExampleGrid>
|
|
188
182
|
|
|
189
183
|
{/* ── Loading & Dismiss ── */}
|
|
190
|
-
<
|
|
191
|
-
label="Loading & Dismiss"
|
|
192
|
-
description="toast.loading() tạo toast thủ công, sau đó dùng toast.success/error(id) để cập nhật, hoặc toast.dismiss(id) để huỷ."
|
|
193
|
-
codeString={`// Tạo loading toast và giữ id
|
|
184
|
+
<ShowcaseExample title="Loading & Dismiss" description="toast.loading() tạo toast thủ công, sau đó dùng toast.success/error(id) để cập nhật, hoặc toast.dismiss(id) để huỷ." code={`
|
|
194
185
|
const toastId = toast.loading("Đang xử lý...");
|
|
195
186
|
|
|
196
|
-
// Sau khi async xong — cập nhật cùng toast
|
|
197
187
|
setTimeout(() => {
|
|
198
188
|
toast.success("Hoàn tất!", { id: toastId });
|
|
199
189
|
}, 2000);
|
|
200
190
|
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
191
|
+
toast.dismiss(toastId);`} preview={
|
|
192
|
+
<>
|
|
193
|
+
<div className="flex flex-wrap gap-2">
|
|
194
|
+
<Button
|
|
195
|
+
variant="outline"
|
|
196
|
+
onClick={() => {
|
|
197
|
+
const id = toast.loading("Đang xử lý...");
|
|
198
|
+
setTimeout(() => toast.success("Hoàn tất!", { id }), 2000);
|
|
199
|
+
}}
|
|
200
|
+
>
|
|
201
|
+
Loading → Success (2s)
|
|
202
|
+
</Button>
|
|
203
|
+
<Button
|
|
204
|
+
variant="outline"
|
|
205
|
+
onClick={() => {
|
|
206
|
+
const id = toast.loading("Đang tải dữ liệu...");
|
|
207
|
+
setTimeout(() => toast.error("Mất kết nối!", { id }), 2000);
|
|
208
|
+
}}
|
|
209
|
+
>
|
|
210
|
+
Loading → Error (2s)
|
|
211
|
+
</Button>
|
|
212
|
+
<Button
|
|
213
|
+
variant="outline"
|
|
214
|
+
color="destructive"
|
|
215
|
+
onClick={() => toast.dismiss()}
|
|
216
|
+
>
|
|
217
|
+
Dismiss All
|
|
218
|
+
</Button>
|
|
219
|
+
</div>
|
|
220
|
+
</>
|
|
221
|
+
} />
|
|
232
222
|
|
|
233
223
|
{/* ── Position ── */}
|
|
234
|
-
<
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
224
|
+
<ShowcaseExample title="Position" description="Toaster nhận prop position để xác định vị trí hiển thị — cấu hình một lần ở root layout. Nhấn vào từng vùng để xem toast xuất hiện ở đâu." code={`
|
|
225
|
+
<Toaster position="bottom-right" />
|
|
226
|
+
trí hỗ trợ:
|
|
227
|
+
"bottom-left" | "bottom-center" | "bottom-right"`} preview={
|
|
228
|
+
<>
|
|
229
|
+
{/* Visual 3×2 position grid */}<div className="w-full max-w-sm">
|
|
230
|
+
<p className="mb-3 text-xs text-muted-foreground">
|
|
231
|
+
Nhấn từng ô để xem toast xuất hiện đúng vị trí tương ứng.
|
|
232
|
+
</p>
|
|
233
|
+
<div className="grid grid-cols-3 gap-1.5">
|
|
234
|
+
<Button
|
|
235
|
+
variant="outline"
|
|
236
|
+
size="sm"
|
|
237
|
+
className="text-xs"
|
|
238
|
+
onClick={() =>
|
|
239
|
+
toast("Toast: top-left", {
|
|
240
|
+
description: 'position="top-left"',
|
|
241
|
+
position: "top-left"
|
|
242
|
+
})
|
|
243
|
+
}
|
|
244
|
+
>
|
|
245
|
+
top-left
|
|
246
|
+
</Button>
|
|
247
|
+
<Button
|
|
248
|
+
variant="outline"
|
|
249
|
+
size="sm"
|
|
250
|
+
className="text-xs"
|
|
251
|
+
onClick={() =>
|
|
252
|
+
toast("Toast: top-center", {
|
|
253
|
+
description: 'position="top-center"',
|
|
254
|
+
position: "top-center"
|
|
255
|
+
})
|
|
256
|
+
}
|
|
257
|
+
>
|
|
258
|
+
top-center
|
|
259
|
+
</Button>
|
|
260
|
+
<Button
|
|
261
|
+
variant="outline"
|
|
262
|
+
size="sm"
|
|
263
|
+
className="text-xs"
|
|
264
|
+
onClick={() =>
|
|
265
|
+
toast("Toast: top-right", {
|
|
266
|
+
description: 'position="top-right"',
|
|
267
|
+
position: "top-right"
|
|
268
|
+
})
|
|
269
|
+
}
|
|
270
|
+
>
|
|
271
|
+
top-right
|
|
272
|
+
</Button>
|
|
273
|
+
<Button
|
|
274
|
+
variant="outline"
|
|
275
|
+
size="sm"
|
|
276
|
+
className="text-xs"
|
|
277
|
+
onClick={() =>
|
|
278
|
+
toast("Toast: bottom-left", {
|
|
279
|
+
description: 'position="bottom-left"',
|
|
280
|
+
position: "bottom-left"
|
|
281
|
+
})
|
|
282
|
+
}
|
|
283
|
+
>
|
|
284
|
+
bottom-left
|
|
285
|
+
</Button>
|
|
286
|
+
<Button
|
|
287
|
+
variant="outline"
|
|
288
|
+
size="sm"
|
|
289
|
+
className="text-xs"
|
|
290
|
+
onClick={() =>
|
|
291
|
+
toast("Toast: bottom-center", {
|
|
292
|
+
description: 'position="bottom-center"',
|
|
293
|
+
position: "bottom-center"
|
|
294
|
+
})
|
|
295
|
+
}
|
|
296
|
+
>
|
|
297
|
+
bottom-center
|
|
298
|
+
</Button>
|
|
299
|
+
<Button
|
|
300
|
+
variant="outline"
|
|
301
|
+
size="sm"
|
|
302
|
+
className="text-xs"
|
|
303
|
+
onClick={() =>
|
|
304
|
+
toast("Toast: bottom-right", {
|
|
305
|
+
description: 'position="bottom-right"',
|
|
306
|
+
position: "bottom-right"
|
|
307
|
+
})
|
|
308
|
+
}
|
|
309
|
+
>
|
|
310
|
+
bottom-right
|
|
311
|
+
</Button>
|
|
312
|
+
</div>
|
|
313
|
+
</div>
|
|
314
|
+
</>
|
|
315
|
+
} />
|
|
323
316
|
</div>
|
|
324
317
|
);
|
|
325
318
|
}
|
|
@@ -332,7 +325,7 @@ export default function SonnerShowcase() {
|
|
|
332
325
|
<Showcase
|
|
333
326
|
title="Sonner"
|
|
334
327
|
description="Hệ thống thông báo toast nhẹ, đẹp, và linh hoạt — tích hợp với design system qua CSS Variables."
|
|
335
|
-
|
|
328
|
+
guideline={
|
|
336
329
|
<ShowcaseDocs>
|
|
337
330
|
<DocsP>
|
|
338
331
|
<DocsCode>Toaster</DocsCode> là wrapper của thư viện{" "}
|
|
@@ -349,7 +342,7 @@ export default function SonnerShowcase() {
|
|
|
349
342
|
</DocsP>
|
|
350
343
|
</ShowcaseDocs>
|
|
351
344
|
}
|
|
352
|
-
|
|
345
|
+
micro={{ content: <SonnerMicroShowcase /> }}
|
|
353
346
|
/>
|
|
354
347
|
);
|
|
355
348
|
}
|