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.
Files changed (134) hide show
  1. package/README.md +1 -1
  2. package/package.json +2 -1
  3. package/scripts/strip-comments.ts +79 -0
  4. package/src/blocks/auth-form.tsx +34 -30
  5. package/src/blocks/auth-recovery.tsx +9 -13
  6. package/src/blocks/auth-split.tsx +46 -36
  7. package/src/blocks/settings.tsx +84 -117
  8. package/src/components/macro/alert-preset.tsx +3 -1
  9. package/src/components/macro/carousel-preset.tsx +0 -1
  10. package/src/components/macro/checkbox-preset.test.tsx +2 -2
  11. package/src/components/macro/checkbox-preset.tsx +1 -2
  12. package/src/components/macro/command-preset.tsx +1 -1
  13. package/src/components/macro/date-picker.tsx +5 -18
  14. package/src/components/macro/dialog-preset.tsx +5 -3
  15. package/src/components/macro/input-preset.tsx +0 -1
  16. package/src/components/macro/select-preset.tsx +1 -1
  17. package/src/components/macro/switch-preset.test.tsx +1 -1
  18. package/src/components/micro/accordion.test.tsx +6 -12
  19. package/src/components/micro/alert-dialog.tsx +0 -2
  20. package/src/components/micro/alert.test.tsx +5 -8
  21. package/src/components/micro/alert.tsx +0 -2
  22. package/src/components/micro/badge.test.tsx +5 -7
  23. package/src/components/micro/badge.tsx +1 -3
  24. package/src/components/micro/button.test.tsx +19 -26
  25. package/src/components/micro/button.tsx +3 -11
  26. package/src/components/micro/calendar.tsx +12 -13
  27. package/src/components/micro/card.test.tsx +3 -5
  28. package/src/components/micro/carousel.tsx +0 -1
  29. package/src/components/micro/chart.tsx +3 -2
  30. package/src/components/micro/checkbox.test.tsx +9 -18
  31. package/src/components/micro/combobox.tsx +1 -3
  32. package/src/components/micro/command.tsx +23 -11
  33. package/src/components/micro/context-menu.tsx +0 -2
  34. package/src/components/micro/dialog.test.tsx +6 -14
  35. package/src/components/micro/dialog.tsx +0 -2
  36. package/src/components/micro/drawer.tsx +0 -3
  37. package/src/components/micro/dropdown-menu.test.tsx +8 -14
  38. package/src/components/micro/dropdown-menu.tsx +0 -2
  39. package/src/components/micro/field.tsx +3 -3
  40. package/src/components/micro/hover-card.tsx +0 -2
  41. package/src/components/micro/input-group.tsx +9 -42
  42. package/src/components/micro/input.test.tsx +15 -24
  43. package/src/components/micro/navigation-menu.tsx +0 -2
  44. package/src/components/micro/popover.test.tsx +5 -9
  45. package/src/components/micro/progress.tsx +5 -1
  46. package/src/components/micro/select.test.tsx +5 -18
  47. package/src/components/micro/select.tsx +3 -5
  48. package/src/components/micro/separator.tsx +1 -1
  49. package/src/components/micro/sheet.test.tsx +6 -14
  50. package/src/components/micro/sheet.tsx +0 -2
  51. package/src/components/micro/sidebar.tsx +5 -6
  52. package/src/components/micro/sonner.tsx +0 -1
  53. package/src/components/micro/switch.test.tsx +9 -18
  54. package/src/components/micro/switch.tsx +1 -1
  55. package/src/components/micro/tabs.test.tsx +5 -11
  56. package/src/components/micro/theme-provider.tsx +0 -12
  57. package/src/components/micro/toggle-group.tsx +1 -12
  58. package/src/components/micro/tooltip.test.tsx +7 -12
  59. package/src/dev/App.tsx +6 -6
  60. package/src/dev/components/BlockViewer.tsx +15 -4
  61. package/src/dev/components/Container.tsx +20 -0
  62. package/src/dev/components/GladvnLogo.tsx +3 -9
  63. package/src/dev/components/code-highlighter.tsx +5 -3
  64. package/src/dev/components/showcase.tsx +116 -168
  65. package/src/dev/sections/buttons.tsx +4 -9
  66. package/src/dev/sections/display.tsx +68 -72
  67. package/src/dev/sections/feedback.tsx +304 -314
  68. package/src/dev/sections/forms.tsx +10 -14
  69. package/src/dev/sections/interactive.tsx +32 -32
  70. package/src/dev/sections/overview.tsx +2 -10
  71. package/src/dev/showcase/accordion.tsx +512 -554
  72. package/src/dev/showcase/alert-dialog.tsx +525 -565
  73. package/src/dev/showcase/alert.tsx +352 -402
  74. package/src/dev/showcase/aspect-ratio.tsx +167 -193
  75. package/src/dev/showcase/avatar.tsx +231 -269
  76. package/src/dev/showcase/badge.tsx +92 -140
  77. package/src/dev/showcase/breadcrumb.tsx +113 -135
  78. package/src/dev/showcase/button.tsx +140 -173
  79. package/src/dev/showcase/calendar.tsx +187 -237
  80. package/src/dev/showcase/card.tsx +229 -261
  81. package/src/dev/showcase/carousel.tsx +288 -315
  82. package/src/dev/showcase/chart.tsx +44 -50
  83. package/src/dev/showcase/checkbox.tsx +286 -330
  84. package/src/dev/showcase/collapsible.tsx +143 -160
  85. package/src/dev/showcase/combobox.tsx +327 -369
  86. package/src/dev/showcase/command.tsx +106 -120
  87. package/src/dev/showcase/context-menu.tsx +93 -107
  88. package/src/dev/showcase/dialog.tsx +585 -630
  89. package/src/dev/showcase/drawer.tsx +176 -196
  90. package/src/dev/showcase/dropdown-menu.tsx +183 -201
  91. package/src/dev/showcase/empty.tsx +232 -274
  92. package/src/dev/showcase/hover-card.tsx +153 -180
  93. package/src/dev/showcase/input-group.tsx +221 -253
  94. package/src/dev/showcase/input-otp.tsx +204 -250
  95. package/src/dev/showcase/input.tsx +246 -325
  96. package/src/dev/showcase/item.tsx +134 -152
  97. package/src/dev/showcase/kbd.tsx +149 -172
  98. package/src/dev/showcase/label.tsx +50 -68
  99. package/src/dev/showcase/menubar.tsx +194 -213
  100. package/src/dev/showcase/navigation-menu.tsx +119 -133
  101. package/src/dev/showcase/overview-components/ArchitectureSection.tsx +126 -0
  102. package/src/dev/showcase/overview-components/CodeBlock.tsx +50 -0
  103. package/src/dev/showcase/overview-components/ColorPaletteSection.tsx +44 -0
  104. package/src/dev/showcase/overview-components/DashboardPreview.tsx +159 -0
  105. package/src/dev/showcase/overview-components/FeatureGridSection.tsx +535 -0
  106. package/src/dev/showcase/overview-components/FooterCTA.tsx +137 -0
  107. package/src/dev/showcase/overview-components/HeroSection.tsx +65 -0
  108. package/src/dev/showcase/overview-components/PrinciplesSection.tsx +128 -0
  109. package/src/dev/showcase/overview.tsx +21 -1163
  110. package/src/dev/showcase/pagination.tsx +144 -190
  111. package/src/dev/showcase/popover.tsx +181 -196
  112. package/src/dev/showcase/progress.tsx +141 -189
  113. package/src/dev/showcase/radio-group.tsx +272 -332
  114. package/src/dev/showcase/resizable.tsx +119 -141
  115. package/src/dev/showcase/scroll-area.tsx +21 -36
  116. package/src/dev/showcase/select.tsx +262 -322
  117. package/src/dev/showcase/separator.tsx +75 -73
  118. package/src/dev/showcase/sheet.tsx +333 -361
  119. package/src/dev/showcase/sidebar.tsx +53 -59
  120. package/src/dev/showcase/skeleton.tsx +93 -112
  121. package/src/dev/showcase/slider.tsx +244 -296
  122. package/src/dev/showcase/sonner.tsx +251 -258
  123. package/src/dev/showcase/spinner.tsx +46 -67
  124. package/src/dev/showcase/switch.tsx +298 -362
  125. package/src/dev/showcase/table.tsx +76 -80
  126. package/src/dev/showcase/tabs.tsx +302 -355
  127. package/src/dev/showcase/textarea.tsx +240 -293
  128. package/src/dev/showcase/toast.tsx +48 -54
  129. package/src/dev/showcase/toggle-group.tsx +104 -129
  130. package/src/dev/showcase/toggle.tsx +82 -102
  131. package/src/dev/showcase/tooltip.tsx +173 -192
  132. package/src/dev/showcase/why.tsx +6 -12
  133. package/src/hooks/use-mobile.test.ts +3 -2
  134. package/src/lib/utils.test.ts +5 -4
@@ -13,7 +13,7 @@ import {
13
13
  } from "../../components/micro/navigation-menu";
14
14
  import {
15
15
  DocsP,
16
- ExampleSection,
16
+ ShowcaseExample,
17
17
  Showcase,
18
18
  ShowcaseDocs
19
19
  } from "../../dev/components/showcase";
@@ -47,16 +47,10 @@ const ListItem = React.forwardRef<
47
47
  });
48
48
  ListItem.displayName = "ListItem";
49
49
 
50
- // ──────────────────────────────────────────────────────────
51
- // SECTION 2: Micro Content (không export)
52
- // ──────────────────────────────────────────────────────────
53
50
  function NavigationMenuMicroShowcase() {
54
51
  return (
55
- <div className="space-y-10 mt-6">
56
- <ExampleSection
57
- label="Default"
58
- description="Điều hướng đa cấp với bảng thả xuống."
59
- codeString={`<NavigationMenu>
52
+ <div className="space-y-10">
53
+ <ShowcaseExample title="Mặc định" description="Điều hướng đa cấp với bảng thả xuống." code={`<NavigationMenu>
60
54
  <NavigationMenuList>
61
55
  <NavigationMenuItem>
62
56
  <NavigationMenuTrigger>
@@ -82,20 +76,20 @@ function NavigationMenuMicroShowcase() {
82
76
  </p>
83
77
  </NavigationMenuLink>
84
78
  </li>
85
- <ListItem href="/docs" title="Introduction">
79
+ <ListItem href="/docs" title="Giới thiệu">
86
80
  Re-usable components built using Radix UI and
87
81
  Tailwind CSS.
88
82
  </ListItem>
89
83
  <ListItem
90
84
  href="/docs/installation"
91
- title="Installation"
85
+ title="Cài đặt"
92
86
  >
93
87
  How to install dependencies and structure your
94
88
  app.
95
89
  </ListItem>
96
90
  <ListItem
97
91
  href="/docs/primitives/typography"
98
- title="Typography"
92
+ title="Kiểu chữ"
99
93
  >
100
94
  Styles for headings, paragraphs, lists...etc
101
95
  </ListItem>
@@ -109,28 +103,28 @@ function NavigationMenuMicroShowcase() {
109
103
  <NavigationMenuContent>
110
104
  <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
111
105
  <ListItem
112
- title="Alert Dialog"
106
+ title="Hộp thoại Cảnh báo"
113
107
  href="/docs/primitives/alert-dialog"
114
108
  >
115
109
  A modal dialog that interrupts the user with
116
110
  important content and expects a response.
117
111
  </ListItem>
118
112
  <ListItem
119
- title="Hover Card"
113
+ title="Thẻ Hover"
120
114
  href="/docs/primitives/hover-card"
121
115
  >
122
116
  For sighted users to preview content available
123
117
  behind a link.
124
118
  </ListItem>
125
119
  <ListItem
126
- title="Progress"
120
+ title="Tiến trình"
127
121
  href="/docs/primitives/progress"
128
122
  >
129
123
  Displays an indicator showing the completion
130
124
  progress of a task.
131
125
  </ListItem>
132
126
  <ListItem
133
- title="Scroll-area"
127
+ title="Khu vực Cuộn"
134
128
  href="/docs/primitives/scroll-area"
135
129
  >
136
130
  Visually or semantically separates content.
@@ -150,99 +144,97 @@ function NavigationMenuMicroShowcase() {
150
144
 
151
145
  <NavigationMenuPositioner />
152
146
 
153
- </NavigationMenu>`}
154
- >
155
- <NavigationMenu>
156
- <NavigationMenuList>
157
- <NavigationMenuItem>
158
- <NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
147
+ </NavigationMenu>`} preview={
148
+ <>
149
+ <NavigationMenu>
150
+ <NavigationMenuList>
151
+ <NavigationMenuItem>
152
+ <NavigationMenuTrigger>Getting started</NavigationMenuTrigger>
159
153
 
160
- <NavigationMenuContent>
161
- <ul className="grid gap-3 p-4 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
162
- <li className="row-span-3">
163
- <NavigationMenuLink
164
- render={
165
- <a
166
- className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
167
- href="/"
168
- />
169
- }
170
- >
171
- <div className="mb-2 mt-4 text-lg font-medium">
172
- gladvn/ui
173
- </div>
174
- <p className="text-sm leading-tight text-muted-foreground">
175
- Beautifully designed components built with Radix UI and
176
- Tailwind CSS.
177
- </p>
178
- </NavigationMenuLink>
179
- </li>
180
- <ListItem href="/docs" title="Introduction">
181
- Re-usable components built using Radix UI and Tailwind CSS.
182
- </ListItem>
183
- <ListItem href="/docs/installation" title="Installation">
184
- How to install dependencies and structure your app.
185
- </ListItem>
186
- <ListItem
187
- href="/docs/primitives/typography"
188
- title="Typography"
189
- >
190
- Styles for headings, paragraphs, lists...etc
191
- </ListItem>
192
- </ul>
193
- </NavigationMenuContent>
194
- </NavigationMenuItem>
195
- <NavigationMenuItem>
196
- <NavigationMenuTrigger>Components</NavigationMenuTrigger>
154
+ <NavigationMenuContent>
155
+ <ul className="grid gap-3 p-4 md:w-[400px] lg:w-[500px] lg:grid-cols-[.75fr_1fr]">
156
+ <li className="row-span-3">
157
+ <NavigationMenuLink
158
+ render={
159
+ <a
160
+ className="flex h-full w-full select-none flex-col justify-end rounded-md bg-gradient-to-b from-muted/50 to-muted p-6 no-underline outline-none focus:shadow-md"
161
+ href="/"
162
+ />
163
+ }
164
+ >
165
+ <div className="mb-2 mt-4 text-lg font-medium">
166
+ gladvn/ui
167
+ </div>
168
+ <p className="text-sm leading-tight text-muted-foreground">
169
+ Beautifully designed components built with Radix UI and
170
+ Tailwind CSS.
171
+ </p>
172
+ </NavigationMenuLink>
173
+ </li>
174
+ <ListItem href="/docs" title="Giới thiệu">
175
+ Re-usable components built using Radix UI and Tailwind CSS.
176
+ </ListItem>
177
+ <ListItem href="/docs/installation" title="Cài đặt">
178
+ How to install dependencies and structure your app.
179
+ </ListItem>
180
+ <ListItem
181
+ href="/docs/primitives/typography"
182
+ title="Kiểu chữ"
183
+ >
184
+ Styles for headings, paragraphs, lists...etc
185
+ </ListItem>
186
+ </ul>
187
+ </NavigationMenuContent>
188
+ </NavigationMenuItem>
189
+ <NavigationMenuItem>
190
+ <NavigationMenuTrigger>Thành phần</NavigationMenuTrigger>
197
191
 
198
- <NavigationMenuContent>
199
- <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
200
- <ListItem
201
- title="Alert Dialog"
202
- href="/docs/primitives/alert-dialog"
203
- >
204
- A modal dialog that interrupts the user with important
205
- content and expects a response.
206
- </ListItem>
207
- <ListItem
208
- title="Hover Card"
209
- href="/docs/primitives/hover-card"
210
- >
211
- For sighted users to preview content available behind a
212
- link.
213
- </ListItem>
214
- <ListItem title="Progress" href="/docs/primitives/progress">
215
- Displays an indicator showing the completion progress of a
216
- task.
217
- </ListItem>
218
- <ListItem
219
- title="Scroll-area"
220
- href="/docs/primitives/scroll-area"
221
- >
222
- Visually or semantically separates content.
223
- </ListItem>
224
- </ul>
225
- </NavigationMenuContent>
226
- </NavigationMenuItem>
227
- <NavigationMenuItem>
228
- <NavigationMenuLink
229
- href="/docs"
230
- className={navigationMenuTriggerStyle()}
231
- >
232
- Documentation
233
- </NavigationMenuLink>
234
- </NavigationMenuItem>
235
- </NavigationMenuList>
236
-
237
- <NavigationMenuPositioner />
238
-
239
- </NavigationMenu>
240
- </ExampleSection>
192
+ <NavigationMenuContent>
193
+ <ul className="grid w-[400px] gap-3 p-4 md:w-[500px] md:grid-cols-2 lg:w-[600px] ">
194
+ <ListItem
195
+ title="Hộp thoại Cảnh báo"
196
+ href="/docs/primitives/alert-dialog"
197
+ >
198
+ A modal dialog that interrupts the user with important
199
+ content and expects a response.
200
+ </ListItem>
201
+ <ListItem
202
+ title="Thẻ Hover"
203
+ href="/docs/primitives/hover-card"
204
+ >
205
+ For sighted users to preview content available behind a
206
+ link.
207
+ </ListItem>
208
+ <ListItem title="Tiến trình" href="/docs/primitives/progress">
209
+ Displays an indicator showing the completion progress of a
210
+ task.
211
+ </ListItem>
212
+ <ListItem
213
+ title="Khu vực Cuộn"
214
+ href="/docs/primitives/scroll-area"
215
+ >
216
+ Visually or semantically separates content.
217
+ </ListItem>
218
+ </ul>
219
+ </NavigationMenuContent>
220
+ </NavigationMenuItem>
221
+ <NavigationMenuItem>
222
+ <NavigationMenuLink
223
+ href="/docs"
224
+ className={navigationMenuTriggerStyle()}
225
+ >
226
+ Documentation
227
+ </NavigationMenuLink>
228
+ </NavigationMenuItem>
229
+ </NavigationMenuList>
230
+
231
+ <NavigationMenuPositioner />
232
+
233
+ </NavigationMenu>
234
+ </>
235
+ } />
241
236
 
242
- <ExampleSection
243
- label="Disabled State"
244
- description="Menu trigger ở trạng thái vô hiệu hóa."
245
- codeString={`<NavigationMenu>
237
+ <ShowcaseExample title="Disabled State" description="Menu trigger ở trạng thái vô hiệu hóa." code={`<NavigationMenu>
246
238
  <NavigationMenuList>
247
239
  <NavigationMenuItem>
248
240
  <NavigationMenuTrigger disabled>
@@ -258,38 +250,36 @@ function NavigationMenuMicroShowcase() {
258
250
 
259
251
  <NavigationMenuPositioner />
260
252
 
261
- </NavigationMenu>`}
262
- >
263
- <NavigationMenu>
264
- <NavigationMenuList>
265
- <NavigationMenuItem>
266
- <NavigationMenuTrigger disabled>
267
- Disabled Trigger
268
- </NavigationMenuTrigger>
253
+ </NavigationMenu>`} preview={
254
+ <>
255
+ <NavigationMenu>
256
+ <NavigationMenuList>
257
+ <NavigationMenuItem>
258
+ <NavigationMenuTrigger disabled>
259
+ Disabled Trigger
260
+ </NavigationMenuTrigger>
269
261
 
270
- <NavigationMenuContent>
271
- <div className="p-4 w-[200px]">Content will not be visible</div>
272
- </NavigationMenuContent>
273
- </NavigationMenuItem>
274
- </NavigationMenuList>
275
-
276
- <NavigationMenuPositioner />
277
-
278
- </NavigationMenu>
279
- </ExampleSection>
262
+ <NavigationMenuContent>
263
+ <div className="p-4 w-[200px]">Content will not be visible</div>
264
+ </NavigationMenuContent>
265
+ </NavigationMenuItem>
266
+ </NavigationMenuList>
267
+
268
+ <NavigationMenuPositioner />
269
+
270
+ </NavigationMenu>
271
+ </>
272
+ } />
280
273
  </div>
281
274
  );
282
275
  }
283
276
 
284
- // ──────────────────────────────────────────────────────────
285
- // SECTION 3: Entry point (export default)
286
- // ──────────────────────────────────────────────────────────
287
277
  export default function NavigationMenuShowcase() {
288
278
  return (
289
279
  <Showcase
290
280
  title="Navigation Menu"
291
281
  description="Thanh điều hướng đa cấp với panel thả xuống — dùng cho header navigation."
292
- generalConcept={
282
+ guideline={
293
283
  <ShowcaseDocs>
294
284
  <DocsP>
295
285
  Navigation Menu là một hệ thống điều hướng chính (thường nằm ở
@@ -298,11 +288,7 @@ export default function NavigationMenuShowcase() {
298
288
  </DocsP>
299
289
  </ShowcaseDocs>
300
290
  }
301
- tabs={[
302
- {
303
- label: "Micro (Primitive)",
304
- content: <NavigationMenuMicroShowcase /> },
305
- ]}
291
+ micro={{ content: <NavigationMenuMicroShowcase /> }}
306
292
  />
307
293
  );
308
294
  }
@@ -0,0 +1,126 @@
1
+ import React from "react";
2
+ import { cn } from "../../../lib/utils";
3
+
4
+ const ARCHITECTURE_CARDS = [
5
+ {
6
+ tag: "Nên bắt đầu ở đây",
7
+ path: "src/components/macro/",
8
+ title: "Macro — Khu vực an toàn",
9
+ desc: (
10
+ <>
11
+ Muốn tuỳ chỉnh? Bắt đầu từ đây nhé. Mỗi Macro là một khối độc lập — thêm footer cho DatePicker, giấu nút đóng của Dialog, v.v.{" "}
12
+ <strong className="text-foreground">Cứ thoải mái vọc vạch</strong>
13
+ , sửa cái nào thì chỉ ảnh hưởng cái đó thôi, chả lo "cháy nhà" hàng xóm.
14
+ </>
15
+ ),
16
+ colorScheme: "primary"
17
+ },
18
+ {
19
+ tag: "Cẩn thận",
20
+ path: "src/components/micro/",
21
+ title: "Micro — Lãnh địa cốt lõi",
22
+ desc: (
23
+ <>
24
+ Mọi thứ đều xây từ đây. Sửa cái padding của Button hay animation của Tooltip thì{" "}
25
+ <strong className="text-foreground">nguyên dàn app sẽ ăn theo</strong>
26
+ . Cân nhắc kỹ chút trước khi gõ phím nhé, "sai một ly đi một dặm" đấy!
27
+ </>
28
+ ),
29
+ colorScheme: "warning"
30
+ },
31
+ {
32
+ tag: "Ảnh hưởng toàn cục",
33
+ path: "src/index.css",
34
+ title: "CSS Token — Nút bấm hạt nhân",
35
+ desc: (
36
+ <>
37
+ Nơi nắm trùm về màu sắc, font, độ bo góc. Đổi một biến ở đây là{" "}
38
+ <strong className="text-foreground">giao diện lột xác toàn tập</strong>
39
+ . Rất đã khi cần thay áo mới (rebrand), nhưng tuyệt đối đừng dùng để vá lỗi vặt.
40
+ </>
41
+ ),
42
+ colorScheme: "destructive"
43
+ },
44
+ {
45
+ tag: "Lắp ghép linh hoạt",
46
+ path: "src/blocks/",
47
+ title: "Blocks — Sân chơi tự do",
48
+ desc: (
49
+ <>
50
+ Chẳng có quy tắc nào ép bạn phải dùng 100% Micro hay Macro. Layout quen thuộc thì <strong className="text-foreground">lấy Macro ra xài cho lẹ</strong>. Gặp thiết kế dị biệt thì <strong className="text-foreground">mở Micro ra tự xếp hình</strong>. Linh hoạt lên, code sao cho bản thân thấy sướng là được!
51
+ </>
52
+ ),
53
+ colorScheme: "info"
54
+ }
55
+ ] as const;
56
+
57
+ export function ArchitectureSection({ className }: { className?: string }) {
58
+ return (
59
+ <div
60
+ className={cn(
61
+ "relative z-10 border-t border-primary/20 pt-8",
62
+ className
63
+ )}
64
+ >
65
+ <p className="text-sm font-bold uppercase tracking-wider text-primary mb-5">
66
+ Tuỳ chỉnh theo từng tầng kiến trúc
67
+ </p>
68
+ <div className="grid sm:grid-cols-2 lg:grid-cols-4 gap-4">
69
+ {ARCHITECTURE_CARDS.map((card, idx) => {
70
+ const isPrimary = card.colorScheme === "primary";
71
+ const isWarning = card.colorScheme === "warning";
72
+ const isDestructive = card.colorScheme === "destructive";
73
+ const isInfo = card.colorScheme === "info";
74
+
75
+ return (
76
+ <div
77
+ key={idx}
78
+ className={cn(
79
+ "p-5 pt-10 rounded-2xl space-y-3 relative",
80
+ {
81
+ "border-2 border-primary/40 bg-primary/5": isPrimary,
82
+ "border border-warning/40 bg-warning/5": isWarning,
83
+ "border border-destructive/30 bg-destructive/5": isDestructive,
84
+ "border border-info/40 bg-info/5": isInfo
85
+ }
86
+ )}
87
+ >
88
+ <div
89
+ className={cn(
90
+ "absolute top-3 right-3 text-[10px] font-bold uppercase tracking-wider px-2 py-0.5 rounded-full",
91
+ {
92
+ "text-primary bg-primary/10": isPrimary,
93
+ "text-warning bg-warning/10": isWarning,
94
+ "text-destructive bg-destructive/10": isDestructive,
95
+ "text-info bg-info/10": isInfo
96
+ }
97
+ )}
98
+ >
99
+ {card.tag}
100
+ </div>
101
+ <div
102
+ className={cn(
103
+ "font-mono text-xs",
104
+ {
105
+ "text-primary/70": isPrimary,
106
+ "text-warning/70": isWarning,
107
+ "text-destructive/60": isDestructive,
108
+ "text-info/70": isInfo
109
+ }
110
+ )}
111
+ >
112
+ {card.path}
113
+ </div>
114
+ <h4 className="font-bold text-foreground text-base">
115
+ {card.title}
116
+ </h4>
117
+ <p className="text-sm text-muted-foreground leading-relaxed">
118
+ {card.desc}
119
+ </p>
120
+ </div>
121
+ );
122
+ })}
123
+ </div>
124
+ </div>
125
+ );
126
+ }
@@ -0,0 +1,50 @@
1
+ import { cn } from "../../../lib/utils";
2
+ import React from "react";
3
+
4
+ export function CodeBlock({
5
+ type,
6
+ title,
7
+ className,
8
+ children
9
+ }: {
10
+ type: "success" | "destructive";
11
+ title: string;
12
+ className?: string;
13
+ children: React.ReactNode;
14
+ }) {
15
+ const isSuccess = type === "success";
16
+ return (
17
+ <div
18
+ className={cn(
19
+ "rounded-xl overflow-hidden border shadow-sm",
20
+ isSuccess
21
+ ? "border-success/30 bg-success/5"
22
+ : "border-destructive/30 bg-destructive/5 opacity-80",
23
+ className
24
+ )}
25
+ >
26
+ <div
27
+ className={cn(
28
+ "px-4 py-2 font-semibold flex items-center gap-2",
29
+ {
30
+ "text-success": isSuccess,
31
+ "text-destructive": !isSuccess,
32
+ }
33
+ )}
34
+ >
35
+ {isSuccess ? "✅" : "❌"} {title}
36
+ </div>
37
+ <div
38
+ className={cn(
39
+ "text-muted-foreground pl-3 border-l-2 leading-relaxed",
40
+ {
41
+ "border-success/50": isSuccess,
42
+ "border-destructive/50": !isSuccess,
43
+ }
44
+ )}
45
+ >
46
+ {children}
47
+ </div>
48
+ </div>
49
+ );
50
+ }
@@ -0,0 +1,44 @@
1
+ import React from "react";
2
+ import { PaletteIcon } from "lucide-react";
3
+ import { ColorSwatch } from "../../../dev/components/showcase";
4
+ import { COLORS } from "../../../dev/data";
5
+ import { cn } from "../../../lib/utils";
6
+ import { Container } from "../../components/Container";
7
+
8
+ export function ColorPaletteSection({ className }: { className?: string }) {
9
+ return (
10
+ <Container as="section" className={className}>
11
+ <div className="rounded-[2.5rem] border border-border bg-card/30 p-10 md:p-16 shadow-xl relative overflow-hidden group">
12
+ <div className="absolute -top-10 -right-10 p-8 opacity-5 pointer-events-none group-hover:rotate-12 group-hover:scale-125 transition-all duration-1000">
13
+ <PaletteIcon className="size-64 md:size-[400px]" />
14
+ </div>
15
+
16
+ <div className="relative z-10 max-w-3xl mb-14 space-y-5">
17
+ <h3 className="text-3xl md:text-5xl font-extrabold tracking-tight">
18
+ Không gian màu OKLCH
19
+ </h3>
20
+ <p className="text-muted-foreground text-xl leading-relaxed">
21
+ Mọi token màu sắc được tính trên không gian OKLCH — chuyển sắc
22
+ mượt, tương phản đạt WCAG AA/AAA trên mọi theme mà không cần định
23
+ nghĩa thủ công từng dải màu.
24
+ </p>
25
+ </div>
26
+
27
+ <div className="relative z-10 flex flex-wrap gap-6 md:gap-8 justify-center">
28
+ {COLORS.map((c, i) => (
29
+ <div
30
+ key={c}
31
+ className="animate-fade-up"
32
+ style={{
33
+ animationDelay: `${i * 50}ms`,
34
+ animationFillMode: "both"
35
+ }}
36
+ >
37
+ <ColorSwatch color={c} />
38
+ </div>
39
+ ))}
40
+ </div>
41
+ </div>
42
+ </Container>
43
+ );
44
+ }