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
@@ -27,7 +27,7 @@ import {
27
27
  DocsP,
28
28
  DocsUl,
29
29
  ExampleGrid,
30
- ExampleSection,
30
+ ShowcaseExample,
31
31
  Showcase,
32
32
  ShowcaseDocs
33
33
  } from "../../dev/components/showcase";
@@ -39,13 +39,9 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
39
39
  const [count, setCount] = useState(0);
40
40
 
41
41
  return (
42
- <div className="space-y-10 mt-6">
43
- {/* ── Text / Icon Addons ─────────────────────────────── */}
42
+ <div className="space-y-10">
44
43
  <ExampleGrid>
45
- <ExampleSection
46
- label="Text Prefix & Suffix"
47
- description="InputGroupAddon với văn bản — click addon để focus input."
48
- codeString={`<InputGroup size="md">
44
+ <ShowcaseExample title="Text Prefix & Suffix" description="InputGroupAddon với văn bản — click addon để focus input." code={`<InputGroup size="md">
49
45
  <InputGroupAddon>
50
46
  <InputGroupText>https://</InputGroupText>
51
47
  </InputGroupAddon>
@@ -56,23 +52,21 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
56
52
  <InputGroupAddon align="end">
57
53
  <InputGroupText>.vn</InputGroupText>
58
54
  </InputGroupAddon>
59
- </InputGroup>`}
60
- >
61
- <InputGroup size={globalSize} className="w-full">
62
- <InputGroupAddon>
63
- <InputGroupText>https://</InputGroupText>
64
- </InputGroupAddon>
65
- <InputGroupInput id="ig-url" placeholder="example.com" />
66
- <InputGroupAddon align="end">
67
- <InputGroupText>.vn</InputGroupText>
68
- </InputGroupAddon>
69
- </InputGroup>
70
- </ExampleSection>
55
+ </InputGroup>`} preview={
56
+ <>
57
+ <InputGroup size={globalSize} className="w-full">
58
+ <InputGroupAddon>
59
+ <InputGroupText>https://</InputGroupText>
60
+ </InputGroupAddon>
61
+ <InputGroupInput id="ig-url" placeholder="example.com" />
62
+ <InputGroupAddon align="end">
63
+ <InputGroupText>.vn</InputGroupText>
64
+ </InputGroupAddon>
65
+ </InputGroup>
66
+ </>
67
+ } />
71
68
 
72
- <ExampleSection
73
- label="Icon Prefix & Text Suffix"
74
- description="InputGroupAddon với icon — thường dùng cho tiền tệ, số lượng."
75
- codeString={`<InputGroup size="md">
69
+ <ShowcaseExample title="Icon Prefix & Text Suffix" description="InputGroupAddon với icon — thường dùng cho tiền tệ, số lượng." code={`<InputGroup size="md">
76
70
  <InputGroupAddon>
77
71
  <InputGroupText>
78
72
  <DollarSignIcon aria-hidden="true" />
@@ -82,28 +76,25 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
82
76
  <InputGroupAddon align="end">
83
77
  <InputGroupText>USD</InputGroupText>
84
78
  </InputGroupAddon>
85
- </InputGroup>`}
86
- >
87
- <InputGroup size={globalSize} className="w-full">
88
- <InputGroupAddon>
89
- <InputGroupText>
90
- <DollarSignIcon aria-hidden="true" />
91
- </InputGroupText>
92
- </InputGroupAddon>
93
- <InputGroupInput id="ig-price" placeholder="0.00" />
94
- <InputGroupAddon align="end">
95
- <InputGroupText>USD</InputGroupText>
96
- </InputGroupAddon>
97
- </InputGroup>
98
- </ExampleSection>
79
+ </InputGroup>`} preview={
80
+ <>
81
+ <InputGroup size={globalSize} className="w-full">
82
+ <InputGroupAddon>
83
+ <InputGroupText>
84
+ <DollarSignIcon aria-hidden="true" />
85
+ </InputGroupText>
86
+ </InputGroupAddon>
87
+ <InputGroupInput id="ig-price" placeholder="0.00" />
88
+ <InputGroupAddon align="end">
89
+ <InputGroupText>USD</InputGroupText>
90
+ </InputGroupAddon>
91
+ </InputGroup>
92
+ </>
93
+ } />
99
94
  </ExampleGrid>
100
95
 
101
- {/* ── Icon Buttons (utility) ─────────────────────────── */}
102
96
  <ExampleGrid>
103
- <ExampleSection
104
- label="Password Toggle"
105
- description="InputGroupButton icon đặt trực tiếp trong InputGroup — tự có border-l border-l-border phân tách."
106
- codeString={`const [show, setShow] = useState(false);
97
+ <ShowcaseExample title="Password Toggle" description="InputGroupButton icon đặt trực tiếp trong InputGroup — tự có border-l border-l-border phân tách." code={`const [show, setShow] = useState(false);
107
98
  <InputGroup size="md">
108
99
  <InputGroupInput
109
100
  id="password-input"
@@ -121,32 +112,30 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
121
112
  <EyeIcon aria-hidden="true" />
122
113
  )}
123
114
  </InputGroupButton>
124
- </InputGroup>`}
125
- >
126
- <InputGroup size={globalSize} className="w-full">
127
- <InputGroupInput
128
- id="ig-password"
129
- type={showPassword ? "text" : "password"}
130
- placeholder="••••••••"
131
- />
132
- <InputGroupButton
133
- icon
134
- aria-label={showPassword ? "Hide password" : "Show password"}
135
- onClick={() => setShowPassword((p) => !p)}
136
- >
137
- {showPassword ? (
138
- <EyeOffIcon aria-hidden="true" />
139
- ) : (
140
- <EyeIcon aria-hidden="true" />
141
- )}
142
- </InputGroupButton>
143
- </InputGroup>
144
- </ExampleSection>
115
+ </InputGroup>`} preview={
116
+ <>
117
+ <InputGroup size={globalSize} className="w-full">
118
+ <InputGroupInput
119
+ id="ig-password"
120
+ type={showPassword ? "text" : "password"}
121
+ placeholder="••••••••"
122
+ />
123
+ <InputGroupButton
124
+ icon
125
+ aria-label={showPassword ? "Hide password" : "Show password"}
126
+ onClick={() => setShowPassword((p) => !p)}
127
+ >
128
+ {showPassword ? (
129
+ <EyeOffIcon aria-hidden="true" />
130
+ ) : (
131
+ <EyeIcon aria-hidden="true" />
132
+ )}
133
+ </InputGroupButton>
134
+ </InputGroup>
135
+ </>
136
+ } />
145
137
 
146
- <ExampleSection
147
- label="Clear Button"
148
- description="InputGroupButton icon để xoá nhanh nội dung — hiện có điều kiện."
149
- codeString={`const [value, setValue] = useState("");
138
+ <ShowcaseExample title="Clear Button" description="InputGroupButton icon để xoá nhanh nội dung — hiện có điều kiện." code={`const [value, setValue] = useState("");
150
139
  <InputGroup size="md">
151
140
  <InputGroupAddon>
152
141
  <InputGroupText>
@@ -157,7 +146,7 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
157
146
  id="search-input"
158
147
  value={value}
159
148
  onChange={(e) => setValue(e.target.value)}
160
- placeholder="Search..."
149
+ placeholder="Tìm kiếm..."
161
150
  />
162
151
  {value && (
163
152
  <InputGroupButton
@@ -168,60 +157,55 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
168
157
  <XIcon aria-hidden="true" />
169
158
  </InputGroupButton>
170
159
  )}
171
- </InputGroup>`}
172
- >
173
- <InputGroup size={globalSize} className="w-full">
174
- <InputGroupAddon>
175
- <InputGroupText>
176
- <SearchIcon aria-hidden="true" />
177
- </InputGroupText>
178
- </InputGroupAddon>
179
- <InputGroupInput
180
- id="ig-search"
181
- value={clearValue}
182
- onChange={(e) => setClearValue(e.target.value)}
183
- placeholder="Search..."
184
- />
185
- {clearValue && (
186
- <InputGroupButton
187
- icon
188
- aria-label="Clear"
189
- onClick={() => setClearValue("")}
190
- >
191
- <XIcon aria-hidden="true" />
192
- </InputGroupButton>
193
- )}
194
- </InputGroup>
195
- </ExampleSection>
160
+ </InputGroup>`} preview={
161
+ <>
162
+ <InputGroup size={globalSize} className="w-full">
163
+ <InputGroupAddon>
164
+ <InputGroupText>
165
+ <SearchIcon aria-hidden="true" />
166
+ </InputGroupText>
167
+ </InputGroupAddon>
168
+ <InputGroupInput
169
+ id="ig-search"
170
+ value={clearValue}
171
+ onChange={(e) => setClearValue(e.target.value)}
172
+ placeholder="Tìm kiếm..."
173
+ />
174
+ {clearValue && (
175
+ <InputGroupButton
176
+ icon
177
+ aria-label="Clear"
178
+ onClick={() => setClearValue("")}
179
+ >
180
+ <XIcon aria-hidden="true" />
181
+ </InputGroupButton>
182
+ )}
183
+ </InputGroup>
184
+ </>
185
+ } />
196
186
  </ExampleGrid>
197
187
 
198
- {/* ── Text Buttons ───────────────────────────────────── */}
199
188
  <ExampleGrid>
200
- <ExampleSection
201
- label="Text Button (non-icon)"
202
- description="InputGroupButton không có prop icon — dùng horizontal padding và font-size từ group."
203
- codeString={`<InputGroup size="md">
189
+ <ShowcaseExample title="Text Button (non-icon)" description="InputGroupButton không có prop icon — dùng horizontal padding và font-size từ group." code={`<InputGroup size="md">
204
190
  <InputGroupInput
205
191
  id="find-input"
206
- placeholder="Search..."
192
+ placeholder="Tìm kiếm..."
207
193
  />
208
194
  <InputGroupButton variant="solid">
209
195
  <SearchIcon aria-hidden="true" /> Find
210
196
  </InputGroupButton>
211
- </InputGroup>`}
212
- >
213
- <InputGroup size={globalSize} className="w-full">
214
- <InputGroupInput id="ig-find" placeholder="Search..." />
215
- <InputGroupButton variant="solid">
216
- <SearchIcon aria-hidden="true" /> Find
217
- </InputGroupButton>
218
- </InputGroup>
219
- </ExampleSection>
197
+ </InputGroup>`} preview={
198
+ <>
199
+ <InputGroup size={globalSize} className="w-full">
200
+ <InputGroupInput id="ig-find" placeholder="Tìm kiếm..." />
201
+ <InputGroupButton variant="solid">
202
+ <SearchIcon aria-hidden="true" /> Find
203
+ </InputGroupButton>
204
+ </InputGroup>
205
+ </>
206
+ } />
220
207
 
221
- <ExampleSection
222
- label="Both Ends — Counter"
223
- description="Button ở cả 2 đầu — border-r border-r-border (start) và border-l border-l-border (end) tự động theo vị trí DOM."
224
- codeString={`const [count, setCount] = useState(0);
208
+ <ShowcaseExample title="Both Ends — Counter" description="Button ở cả 2 đầu — border-r border-r-border (start) và border-l border-l-border (end) tự động theo vị trí DOM." code={`const [count, setCount] = useState(0);
225
209
  <InputGroup size="md">
226
210
  <InputGroupButton
227
211
  icon
@@ -244,45 +228,42 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
244
228
  >
245
229
  <PlusIcon aria-hidden="true" />
246
230
  </InputGroupButton>
247
- </InputGroup>`}
248
- >
249
- <InputGroup size={globalSize} className="w-full">
250
- <InputGroupButton
251
- icon
252
- aria-label="Decrement"
253
- onClick={() => setCount((c) => c - 1)}
254
- >
255
- <MinusIcon aria-hidden="true" />
256
- </InputGroupButton>
257
- <InputGroupInput
258
- id="ig-counter"
259
- type="number"
260
- value={count}
261
- onChange={(e) => setCount(Number(e.target.value))}
262
- className="text-center"
263
- />
264
- <InputGroupButton
265
- icon
266
- aria-label="Increment"
267
- onClick={() => setCount((c) => c + 1)}
268
- >
269
- <PlusIcon aria-hidden="true" />
270
- </InputGroupButton>
271
- </InputGroup>
272
- </ExampleSection>
231
+ </InputGroup>`} preview={
232
+ <>
233
+ <InputGroup size={globalSize} className="w-full">
234
+ <InputGroupButton
235
+ icon
236
+ aria-label="Decrement"
237
+ onClick={() => setCount((c) => c - 1)}
238
+ >
239
+ <MinusIcon aria-hidden="true" />
240
+ </InputGroupButton>
241
+ <InputGroupInput
242
+ id="ig-counter"
243
+ type="number"
244
+ value={count}
245
+ onChange={(e) => setCount(Number(e.target.value))}
246
+ className="text-center"
247
+ />
248
+ <InputGroupButton
249
+ icon
250
+ aria-label="Increment"
251
+ onClick={() => setCount((c) => c + 1)}
252
+ >
253
+ <PlusIcon aria-hidden="true" />
254
+ </InputGroupButton>
255
+ </InputGroup>
256
+ </>
257
+ } />
273
258
  </ExampleGrid>
274
259
 
275
- {/* ── Button Variants ─────────────────────────────────── */}
276
- <ExampleSection
277
- label="Button Variants"
278
- description="InputGroupButton hỗ trợ 4 variants: ghost (default), solid, soft, outline. Demo với icon và text mode."
279
- codeString={`{/* icon mode — 4 variants */}
260
+ <ShowcaseExample title="Button Variants" description="InputGroupButton hỗ trợ 4 variants: ghost (default), solid, soft, outline. Demo với icon và text mode." code={`{/* icon mode 4 variants */}
280
261
  <InputGroup size="md">
281
262
  <InputGroupInput placeholder="ghost" />
282
263
  <InputGroupButton
283
264
  icon
284
265
  variant="ghost"
285
- aria-label="Search"
266
+ aria-label="Tìm kiếm"
286
267
  >
287
268
  <SearchIcon aria-hidden="true" />
288
269
  </InputGroupButton>
@@ -293,7 +274,7 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
293
274
  <InputGroupButton
294
275
  icon
295
276
  variant="solid"
296
- aria-label="Search"
277
+ aria-label="Tìm kiếm"
297
278
  >
298
279
  <SearchIcon aria-hidden="true" />
299
280
  </InputGroupButton>
@@ -304,7 +285,7 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
304
285
  <InputGroupButton
305
286
  icon
306
287
  variant="soft"
307
- aria-label="Search"
288
+ aria-label="Tìm kiếm"
308
289
  >
309
290
  <SearchIcon aria-hidden="true" />
310
291
  </InputGroupButton>
@@ -315,7 +296,7 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
315
296
  <InputGroupButton
316
297
  icon
317
298
  variant="outline"
318
- aria-label="Search"
299
+ aria-label="Tìm kiếm"
319
300
  >
320
301
  <SearchIcon aria-hidden="true" />
321
302
  </InputGroupButton>
@@ -342,61 +323,56 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
342
323
  <InputGroupButton variant="outline">
343
324
  Go
344
325
  </InputGroupButton>
345
- </InputGroup>`}
346
- fullWidth
347
- >
348
- <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
349
- <InputGroup size={globalSize}>
350
- <InputGroupInput placeholder="ghost" />
351
- <InputGroupButton icon variant="ghost" aria-label="Search">
352
- <SearchIcon aria-hidden="true" />
353
- </InputGroupButton>
354
- </InputGroup>
355
- <InputGroup size={globalSize}>
356
- <InputGroupInput placeholder="solid" />
357
- <InputGroupButton icon variant="solid" aria-label="Search">
358
- <SearchIcon aria-hidden="true" />
359
- </InputGroupButton>
360
- </InputGroup>
361
- <InputGroup size={globalSize}>
362
- <InputGroupInput placeholder="soft" />
363
- <InputGroupButton icon variant="soft" aria-label="Search">
364
- <SearchIcon aria-hidden="true" />
365
- </InputGroupButton>
366
- </InputGroup>
367
- <InputGroup size={globalSize}>
368
- <InputGroupInput placeholder="outline" />
369
- <InputGroupButton icon variant="outline" aria-label="Search">
370
- <SearchIcon aria-hidden="true" />
371
- </InputGroupButton>
372
- </InputGroup>
373
- </div>
374
- <div className="mt-3 grid grid-cols-2 gap-3 sm:grid-cols-4">
375
- <InputGroup size={globalSize}>
376
- <InputGroupInput placeholder="ghost text" />
377
- <InputGroupButton variant="ghost">Go</InputGroupButton>
378
- </InputGroup>
379
- <InputGroup size={globalSize}>
380
- <InputGroupInput placeholder="solid text" />
381
- <InputGroupButton variant="solid">Go</InputGroupButton>
382
- </InputGroup>
383
- <InputGroup size={globalSize}>
384
- <InputGroupInput placeholder="soft text" />
385
- <InputGroupButton variant="soft">Go</InputGroupButton>
386
- </InputGroup>
387
- <InputGroup size={globalSize}>
388
- <InputGroupInput placeholder="outline text" />
389
- <InputGroupButton variant="outline">Go</InputGroupButton>
390
- </InputGroup>
391
- </div>
392
- </ExampleSection>
326
+ </InputGroup>`} preview={
327
+ <>
328
+ <div className="grid grid-cols-2 gap-3 sm:grid-cols-4">
329
+ <InputGroup size={globalSize}>
330
+ <InputGroupInput placeholder="ghost" />
331
+ <InputGroupButton icon variant="ghost" aria-label="Tìm kiếm">
332
+ <SearchIcon aria-hidden="true" />
333
+ </InputGroupButton>
334
+ </InputGroup>
335
+ <InputGroup size={globalSize}>
336
+ <InputGroupInput placeholder="solid" />
337
+ <InputGroupButton icon variant="solid" aria-label="Tìm kiếm">
338
+ <SearchIcon aria-hidden="true" />
339
+ </InputGroupButton>
340
+ </InputGroup>
341
+ <InputGroup size={globalSize}>
342
+ <InputGroupInput placeholder="soft" />
343
+ <InputGroupButton icon variant="soft" aria-label="Tìm kiếm">
344
+ <SearchIcon aria-hidden="true" />
345
+ </InputGroupButton>
346
+ </InputGroup>
347
+ <InputGroup size={globalSize}>
348
+ <InputGroupInput placeholder="outline" />
349
+ <InputGroupButton icon variant="outline" aria-label="Tìm kiếm">
350
+ <SearchIcon aria-hidden="true" />
351
+ </InputGroupButton>
352
+ </InputGroup>
353
+ </div><div className="mt-3 grid grid-cols-2 gap-3 sm:grid-cols-4">
354
+ <InputGroup size={globalSize}>
355
+ <InputGroupInput placeholder="ghost text" />
356
+ <InputGroupButton variant="ghost">Go</InputGroupButton>
357
+ </InputGroup>
358
+ <InputGroup size={globalSize}>
359
+ <InputGroupInput placeholder="solid text" />
360
+ <InputGroupButton variant="solid">Go</InputGroupButton>
361
+ </InputGroup>
362
+ <InputGroup size={globalSize}>
363
+ <InputGroupInput placeholder="soft text" />
364
+ <InputGroupButton variant="soft">Go</InputGroupButton>
365
+ </InputGroup>
366
+ <InputGroup size={globalSize}>
367
+ <InputGroupInput placeholder="outline text" />
368
+ <InputGroupButton variant="outline">Go</InputGroupButton>
369
+ </InputGroup>
370
+ </div>
371
+ </>
372
+ } />
393
373
 
394
- {/* ── States ─────────────────────────────────────────── */}
395
374
  <ExampleGrid>
396
- <ExampleSection
397
- label="Disabled"
398
- description="Trạng thái disabled delegate lên wrapper qua has-disabled: — toàn bộ group mờ đi."
399
- codeString={`<InputGroup size="md">
375
+ <ShowcaseExample title="Disabled" description="Trạng thái disabled delegate lên wrapper qua has-disabled: — toàn bộ group mờ đi." code={`<InputGroup size="md">
400
376
  <InputGroupAddon>
401
377
  <InputGroupText>
402
378
  <GlobeIcon aria-hidden="true" />
@@ -407,22 +383,20 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
407
383
  placeholder="Disabled"
408
384
  disabled
409
385
  />
410
- </InputGroup>`}
411
- >
412
- <InputGroup size={globalSize} className="w-full">
413
- <InputGroupAddon>
414
- <InputGroupText>
415
- <GlobeIcon aria-hidden="true" />
416
- </InputGroupText>
417
- </InputGroupAddon>
418
- <InputGroupInput id="ig-disabled" placeholder="Disabled" disabled />
419
- </InputGroup>
420
- </ExampleSection>
386
+ </InputGroup>`} preview={
387
+ <>
388
+ <InputGroup size={globalSize} className="w-full">
389
+ <InputGroupAddon>
390
+ <InputGroupText>
391
+ <GlobeIcon aria-hidden="true" />
392
+ </InputGroupText>
393
+ </InputGroupAddon>
394
+ <InputGroupInput id="ig-disabled" placeholder="Disabled" disabled />
395
+ </InputGroup>
396
+ </>
397
+ } />
421
398
 
422
- <ExampleSection
423
- label="Invalid / Error"
424
- description="aria-invalid='true' trên input delegate border border-border đỏ lên toàn bộ wrapper qua has-[...aria-invalid]."
425
- codeString={`<InputGroup size="md">
399
+ <ShowcaseExample title="Invalid / Error" description="aria-invalid='true' trên input delegate border border-border đỏ lên toàn bộ wrapper qua has-[...aria-invalid]." code={`<InputGroup size="md">
426
400
  <InputGroupAddon>
427
401
  <InputGroupText>$</InputGroupText>
428
402
  </InputGroupAddon>
@@ -432,27 +406,24 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
432
406
  defaultValue="abc"
433
407
  placeholder="0.00"
434
408
  />
435
- </InputGroup>`}
436
- >
437
- <InputGroup size={globalSize} className="w-full">
438
- <InputGroupAddon>
439
- <InputGroupText>$</InputGroupText>
440
- </InputGroupAddon>
441
- <InputGroupInput
442
- id="ig-error"
443
- aria-invalid="true"
444
- defaultValue="abc"
445
- placeholder="0.00"
446
- />
447
- </InputGroup>
448
- </ExampleSection>
409
+ </InputGroup>`} preview={
410
+ <>
411
+ <InputGroup size={globalSize} className="w-full">
412
+ <InputGroupAddon>
413
+ <InputGroupText>$</InputGroupText>
414
+ </InputGroupAddon>
415
+ <InputGroupInput
416
+ id="ig-error"
417
+ aria-invalid="true"
418
+ defaultValue="abc"
419
+ placeholder="0.00"
420
+ />
421
+ </InputGroup>
422
+ </>
423
+ } />
449
424
  </ExampleGrid>
450
425
 
451
- {/* ── Textarea ───────────────────────────────────────── */}
452
- <ExampleSection
453
- label="With Textarea"
454
- description="InputGroupTextarea — InputGroup wrapper tự co giãn chiều cao với className='h-auto'."
455
- codeString={`<InputGroup size="md" className="h-auto">
426
+ <ShowcaseExample title="With Textarea" description="InputGroupTextarea — InputGroup wrapper tự co giãn chiều cao với className='h-auto'." code={`<InputGroup size="md" className="h-auto">
456
427
  <InputGroupAddon className="self-start">
457
428
  <InputGroupText>@</InputGroupText>
458
429
  </InputGroupAddon>
@@ -461,19 +432,20 @@ function InputGroupMicroShowcase({ globalSize }: { globalSize: Size }) {
461
432
  placeholder="Write a comment..."
462
433
  rows={4}
463
434
  />
464
- </InputGroup>`}
465
- >
466
- <InputGroup size={globalSize} className="h-auto w-full">
467
- <InputGroupAddon className="self-start">
468
- <InputGroupText>@</InputGroupText>
469
- </InputGroupAddon>
470
- <InputGroupTextarea
471
- id="ig-comment"
472
- placeholder="Write a comment..."
473
- rows={4}
474
- />
475
- </InputGroup>
476
- </ExampleSection>
435
+ </InputGroup>`} preview={
436
+ <>
437
+ <InputGroup size={globalSize} className="h-auto w-full">
438
+ <InputGroupAddon className="self-start">
439
+ <InputGroupText>@</InputGroupText>
440
+ </InputGroupAddon>
441
+ <InputGroupTextarea
442
+ id="ig-comment"
443
+ placeholder="Write a comment..."
444
+ rows={4}
445
+ />
446
+ </InputGroup>
447
+ </>
448
+ } />
477
449
  </div>
478
450
  );
479
451
  }
@@ -484,7 +456,7 @@ export default function InputGroupShowcase() {
484
456
  <Showcase
485
457
  title="Input Group"
486
458
  description="Kết hợp input với text, icon và action button bên trong một wrapper tuyến tính theo size."
487
- generalConcept={
459
+ guideline={
488
460
  <ShowcaseDocs>
489
461
  <DocsH3>Kiến trúc Self-Contained</DocsH3>
490
462
  <DocsP>
@@ -533,11 +505,7 @@ export default function InputGroupShowcase() {
533
505
  </DocsP>
534
506
  </ShowcaseDocs>
535
507
  }
536
- tabs={[
537
- {
538
- label: "Micro (Primitive)",
539
- content: <InputGroupMicroShowcase globalSize={globalSize} /> },
540
- ]}
508
+ micro={{ content: <InputGroupMicroShowcase globalSize={globalSize} /> }}
541
509
  />
542
510
  );
543
511
  }