@axzydev/axzy_ui_system 1.4.8 → 1.5.1

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 (223) hide show
  1. package/README.md +2 -11
  2. package/dist/index.cjs +1826 -1351
  3. package/dist/index.cjs.map +1 -1
  4. package/dist/index.css +1 -1
  5. package/dist/index.css.map +1 -1
  6. package/dist/index.d.cts +115 -14
  7. package/dist/index.d.ts +115 -14
  8. package/dist/index.js +1481 -1010
  9. package/dist/index.js.map +1 -1
  10. package/dist/layered.css +1 -1
  11. package/package.json +3 -16
  12. package/src/App.tsx +90 -73
  13. package/src/components/atoms/badget/badget.tsx +23 -5
  14. package/src/components/atoms/chip/chip.tsx +3 -1
  15. package/src/components/atoms/image/image.tsx +3 -1
  16. package/src/components/atoms/input/input.tsx +8 -5
  17. package/src/components/atoms/loader/loader.tsx +3 -1
  18. package/src/components/atoms/slide/slide.props.ts +12 -0
  19. package/src/components/atoms/slide/slide.tsx +3 -0
  20. package/src/components/molecules/alert/alert.tsx +3 -1
  21. package/src/components/molecules/breadcrumbs/breadcrumbs.tsx +3 -1
  22. package/src/components/molecules/calendar/calendar.tsx +9 -6
  23. package/src/components/molecules/card/card.tsx +5 -2
  24. package/src/components/molecules/chip-input/chip-input.tsx +9 -7
  25. package/src/components/molecules/date-picker/datePicker.tsx +9 -9
  26. package/src/components/molecules/dropdown-menu/dropdown-menu.props.ts +1 -1
  27. package/src/components/molecules/dropdown-menu/dropdown-menu.tsx +6 -3
  28. package/src/components/molecules/field/field.tsx +3 -1
  29. package/src/components/molecules/form-header/form-header.tsx +3 -1
  30. package/src/components/molecules/line-bar-chart/line-bar-chart.props.ts +2 -2
  31. package/src/components/molecules/line-bar-chart/line-bar-chart.tsx +20 -15
  32. package/src/components/molecules/masked-input/masked-input.tsx +3 -1
  33. package/src/components/molecules/multi-select/multi-select.tsx +12 -9
  34. package/src/components/molecules/pagination/pagination.tsx +11 -5
  35. package/src/components/molecules/search-select/search-select.tsx +11 -9
  36. package/src/components/molecules/select/select.tsx +6 -4
  37. package/src/components/molecules/stepper/stepper.tsx +6 -4
  38. package/src/components/molecules/table/table.tsx +30 -28
  39. package/src/components/molecules/time-picker/timePicker.tsx +8 -6
  40. package/src/components/molecules/wysiwyg/wysiwyg.tsx +23 -12
  41. package/src/components/organisms/confirm-dialog/confirm-dialog.props.ts +4 -4
  42. package/src/components/organisms/confirm-dialog/confirm-dialog.tsx +16 -8
  43. package/src/components/organisms/data-table/dataTable.tsx +31 -25
  44. package/src/components/organisms/dialog/dialog.tsx +3 -0
  45. package/src/components/organisms/drawer/drawer.tsx +3 -0
  46. package/src/components/organisms/dropfile/dropfile.tsx +19 -17
  47. package/src/components/organisms/form-builder/fieldRenderer.tsx +4 -2
  48. package/src/components/organisms/navbar/navbar.tsx +4 -2
  49. package/src/components/organisms/page-header/page-header.tsx +3 -1
  50. package/src/components/organisms/searchTable/components/PaginationControls.tsx +8 -6
  51. package/src/components/organisms/searchTable/components/PaginationInfo.tsx +3 -1
  52. package/src/components/organisms/searchTable/components/SearchAndSortBar.tsx +7 -5
  53. package/src/components/organisms/searchTable/components/SearchInput.tsx +4 -2
  54. package/src/components/organisms/searchTable/components/SortButton.tsx +13 -11
  55. package/src/components/organisms/searchTable/components/TableEmptyState.tsx +4 -2
  56. package/src/components/organisms/searchTable/components/TableRow.tsx +6 -4
  57. package/src/components/organisms/searchTable/searchTable.tsx +4 -2
  58. package/src/components/organisms/sidebar/sidebar.props.ts +1 -1
  59. package/src/components/organisms/sidebar/sidebar.tsx +9 -4
  60. package/src/components/organisms/toast/toast.tsx +3 -1
  61. package/src/components/organisms/topbar/topbar.tsx +4 -2
  62. package/src/components/templates/page/page.props.ts +4 -4
  63. package/src/components/templates/page/page.tsx +6 -4
  64. package/src/components/theme-provider/themeProvider.tsx +28 -17
  65. package/src/dev.css +61 -2
  66. package/src/global.d.ts +10 -0
  67. package/src/i18n/context.ts +9 -0
  68. package/src/i18n/index.ts +22 -0
  69. package/src/i18n/locales/en.ts +163 -0
  70. package/src/i18n/locales/es.ts +165 -0
  71. package/src/i18n/provider.tsx +44 -0
  72. package/src/i18n/translator.ts +82 -0
  73. package/src/i18n/types.ts +54 -0
  74. package/src/i18n/useITTranslation.ts +20 -0
  75. package/src/index.css +0 -1
  76. package/src/index.ts +7 -1
  77. package/src/sandbox/LandingShowcase.tsx +224 -580
  78. package/src/sandbox/NotFoundShowcase.tsx +51 -36
  79. package/src/sandbox/TopbarSearch.tsx +6 -4
  80. package/src/sandbox/controls.tsx +180 -0
  81. package/src/sandbox/i18n.ts +1939 -0
  82. package/src/sandbox/icons.tsx +25 -0
  83. package/src/sandbox/locale.tsx +72 -0
  84. package/src/sandbox/ui.tsx +474 -0
  85. package/src/sandbox/useHashRoute.ts +46 -10
  86. package/src/showcases/DataShowcases.tsx +103 -87
  87. package/src/showcases/FeedbackShowcases.tsx +37 -30
  88. package/src/showcases/FormShowcases.tsx +303 -215
  89. package/src/showcases/GettingStartedShowcase.tsx +151 -145
  90. package/src/showcases/HelpShowcase.tsx +126 -128
  91. package/src/showcases/HomeShowcase.tsx +678 -482
  92. package/src/showcases/LayoutPrimitivesShowcases.tsx +129 -114
  93. package/src/showcases/NavigationShowcases.tsx +45 -37
  94. package/src/showcases/PageShowcases.tsx +171 -152
  95. package/src/showcases/ProductoDetalle.tsx +272 -129
  96. package/src/showcases/ShowcaseLayout.tsx +256 -219
  97. package/src/showcases/SizesShowcase.tsx +123 -64
  98. package/src/showcases/StructureShowcases.tsx +203 -138
  99. package/src/showcases/portfolioUi.tsx +153 -0
  100. package/src/showcases/techIcons.ts +3 -0
  101. package/src/utils/table.utils.ts +10 -2
  102. package/src/components/atoms/avatar/avatar.doc.mdx +0 -48
  103. package/src/components/atoms/avatar/avatar.stories.tsx +0 -64
  104. package/src/components/atoms/badget/badget.doc.mdx +0 -46
  105. package/src/components/atoms/badget/badget.stories.tsx +0 -75
  106. package/src/components/atoms/button/button.doc.mdx +0 -59
  107. package/src/components/atoms/button/button.stories.tsx +0 -173
  108. package/src/components/atoms/checkbox/checkbox.doc.mdx +0 -54
  109. package/src/components/atoms/checkbox/checkbox.stories.tsx +0 -53
  110. package/src/components/atoms/chip/chip.doc.mdx +0 -47
  111. package/src/components/atoms/chip/chip.stories.tsx +0 -64
  112. package/src/components/atoms/divider/divider.doc.mdx +0 -42
  113. package/src/components/atoms/divider/divider.stories.tsx +0 -33
  114. package/src/components/atoms/flex/flex.doc.mdx +0 -59
  115. package/src/components/atoms/flex/flex.stories.tsx +0 -70
  116. package/src/components/atoms/grid/grid.doc.mdx +0 -54
  117. package/src/components/atoms/grid/grid.stories.tsx +0 -71
  118. package/src/components/atoms/image/image.doc.mdx +0 -44
  119. package/src/components/atoms/image/image.stories.tsx +0 -48
  120. package/src/components/atoms/input/input.doc.mdx +0 -70
  121. package/src/components/atoms/input/input.stories.tsx +0 -113
  122. package/src/components/atoms/input-number/input-number.doc.mdx +0 -74
  123. package/src/components/atoms/input-number/input-number.stories.tsx +0 -111
  124. package/src/components/atoms/loader/loader.doc.mdx +0 -43
  125. package/src/components/atoms/loader/loader.stories.tsx +0 -104
  126. package/src/components/atoms/popover/popover.doc.mdx +0 -53
  127. package/src/components/atoms/popover/popover.stories.tsx +0 -24
  128. package/src/components/atoms/progress/progress.doc.mdx +0 -48
  129. package/src/components/atoms/progress/progress.stories.tsx +0 -39
  130. package/src/components/atoms/radio/radio.doc.mdx +0 -62
  131. package/src/components/atoms/radio/radio.stories.tsx +0 -48
  132. package/src/components/atoms/segmented-control/segmented-control.doc.mdx +0 -60
  133. package/src/components/atoms/segmented-control/segmented-control.stories.tsx +0 -62
  134. package/src/components/atoms/skeleton/skeleton.doc.mdx +0 -43
  135. package/src/components/atoms/skeleton/skeleton.stories.tsx +0 -29
  136. package/src/components/atoms/slide/slide.doc.mdx +0 -46
  137. package/src/components/atoms/slide/slide.stories.tsx +0 -120
  138. package/src/components/atoms/slider/slider.doc.mdx +0 -49
  139. package/src/components/atoms/slider/slider.stories.tsx +0 -29
  140. package/src/components/atoms/stack/stack.doc.mdx +0 -126
  141. package/src/components/atoms/stack/stack.stories.tsx +0 -283
  142. package/src/components/atoms/text/text.doc.mdx +0 -41
  143. package/src/components/atoms/text/text.stories.tsx +0 -66
  144. package/src/components/atoms/textarea/textarea.doc.mdx +0 -64
  145. package/src/components/atoms/textarea/textarea.stories.tsx +0 -26
  146. package/src/components/atoms/tooltip/tooltip.doc.mdx +0 -47
  147. package/src/components/atoms/tooltip/tooltip.stories.tsx +0 -19
  148. package/src/components/isolation/isolation.stories.tsx +0 -202
  149. package/src/components/molecules/accordion/accordion.doc.mdx +0 -47
  150. package/src/components/molecules/accordion/accordion.stories.tsx +0 -68
  151. package/src/components/molecules/alert/alert.doc.mdx +0 -48
  152. package/src/components/molecules/alert/alert.stories.tsx +0 -40
  153. package/src/components/molecules/breadcrumbs/breadcrumbs.doc.mdx +0 -57
  154. package/src/components/molecules/breadcrumbs/breadcrumbs.stories.tsx +0 -20
  155. package/src/components/molecules/calendar/calendar.doc.mdx +0 -76
  156. package/src/components/molecules/calendar/calendar.stories.tsx +0 -90
  157. package/src/components/molecules/card/card.doc.mdx +0 -54
  158. package/src/components/molecules/card/card.stories.tsx +0 -57
  159. package/src/components/molecules/chip-input/chip-input.doc.mdx +0 -44
  160. package/src/components/molecules/chip-input/chip-input.stories.tsx +0 -52
  161. package/src/components/molecules/date-picker/date-picker.doc.mdx +0 -65
  162. package/src/components/molecules/date-picker/date-picker.stories.tsx +0 -88
  163. package/src/components/molecules/dropdown-menu/dropdown-menu.doc.mdx +0 -46
  164. package/src/components/molecules/dropdown-menu/dropdown-menu.stories.tsx +0 -41
  165. package/src/components/molecules/empty-state/empty-state.doc.mdx +0 -50
  166. package/src/components/molecules/empty-state/empty-state.stories.tsx +0 -19
  167. package/src/components/molecules/field/field.doc.mdx +0 -43
  168. package/src/components/molecules/field/field.stories.tsx +0 -42
  169. package/src/components/molecules/form-header/form-header.doc.mdx +0 -38
  170. package/src/components/molecules/form-header/form-header.stories.tsx +0 -52
  171. package/src/components/molecules/masked-input/masked-input.doc.mdx +0 -78
  172. package/src/components/molecules/masked-input/masked-input.stories.tsx +0 -126
  173. package/src/components/molecules/multi-select/multi-select.doc.mdx +0 -55
  174. package/src/components/molecules/multi-select/multi-select.stories.tsx +0 -59
  175. package/src/components/molecules/pagination/pagination.doc.mdx +0 -62
  176. package/src/components/molecules/pagination/pagination.stories.tsx +0 -110
  177. package/src/components/molecules/search-select/search-select.doc.mdx +0 -77
  178. package/src/components/molecules/search-select/search-select.stories.tsx +0 -146
  179. package/src/components/molecules/select/select.doc.mdx +0 -75
  180. package/src/components/molecules/select/select.stories.tsx +0 -85
  181. package/src/components/molecules/stat-card/stat-card.doc.mdx +0 -48
  182. package/src/components/molecules/stat-card/stat-card.stories.tsx +0 -40
  183. package/src/components/molecules/stepper/stepper.doc.mdx +0 -54
  184. package/src/components/molecules/stepper/stepper.stories.tsx +0 -154
  185. package/src/components/molecules/table/table.doc.mdx +0 -140
  186. package/src/components/molecules/table/table.stories.tsx +0 -402
  187. package/src/components/molecules/tabs/tabs.doc.mdx +0 -52
  188. package/src/components/molecules/tabs/tabs.stories.tsx +0 -31
  189. package/src/components/molecules/time-picker/timePicker.doc.mdx +0 -68
  190. package/src/components/molecules/time-picker/timePicker.stories.tsx +0 -130
  191. package/src/components/molecules/wysiwyg/wysiwyg.stories.tsx +0 -95
  192. package/src/components/organisms/confirm-dialog/confirm-dialog.doc.mdx +0 -60
  193. package/src/components/organisms/confirm-dialog/confirm-dialog.stories.tsx +0 -32
  194. package/src/components/organisms/data-table/ITDataTable.doc.mdx +0 -132
  195. package/src/components/organisms/data-table/ITDataTable.stories.tsx +0 -353
  196. package/src/components/organisms/dialog/dialog.doc.mdx +0 -54
  197. package/src/components/organisms/dialog/dialog.stories.tsx +0 -126
  198. package/src/components/organisms/drawer/drawer.doc.mdx +0 -59
  199. package/src/components/organisms/drawer/drawer.stories.tsx +0 -40
  200. package/src/components/organisms/dropfile/dropfile.doc.mdx +0 -74
  201. package/src/components/organisms/dropfile/dropfile.stories.tsx +0 -93
  202. package/src/components/organisms/form-builder/formBuilder.doc.mdx +0 -251
  203. package/src/components/organisms/form-builder/formBuilder.stories.tsx +0 -914
  204. package/src/components/organisms/navbar/navbar.doc.mdx +0 -77
  205. package/src/components/organisms/navbar/navbar.stories.tsx +0 -83
  206. package/src/components/organisms/page-header/page-header.doc.mdx +0 -54
  207. package/src/components/organisms/page-header/page-header.stories.tsx +0 -74
  208. package/src/components/organisms/searchTable/searchTable.doc.mdx +0 -79
  209. package/src/components/organisms/searchTable/searchTable.stories.tsx +0 -73
  210. package/src/components/organisms/sidebar/sidebar.doc.mdx +0 -176
  211. package/src/components/organisms/sidebar/sidebar.stories.tsx +0 -234
  212. package/src/components/organisms/toast/toast.doc.mdx +0 -50
  213. package/src/components/organisms/toast/toast.stories.tsx +0 -137
  214. package/src/components/organisms/topbar/topbar.doc.mdx +0 -72
  215. package/src/components/organisms/topbar/topbar.stories.tsx +0 -79
  216. package/src/components/organisms/triple-filter/tripleFilter.doc.mdx +0 -62
  217. package/src/components/organisms/triple-filter/tripleFilter.stories.tsx +0 -31
  218. package/src/components/templates/layout/layout.doc.mdx +0 -53
  219. package/src/components/templates/layout/layout.stories.tsx +0 -113
  220. package/src/components/templates/page/page.doc.mdx +0 -86
  221. package/src/components/templates/page/page.stories.tsx +0 -97
  222. package/src/components/theme-provider/themeProvider.doc.mdx +0 -85
  223. package/src/components/theme-provider/themeProvider.stories.tsx +0 -58
@@ -35,6 +35,8 @@ import {
35
35
  } from "../index";
36
36
  import type { ITSidebarProps } from "../index";
37
37
  import { ShowcaseLayout, CodeViewer } from "./ShowcaseLayout";
38
+ import { EjemploContenedor } from "@/sandbox/ui";
39
+ import { useITTranslation } from "@/i18n";
38
40
 
39
41
  // ─────────────────────────────────────────
40
42
  // 1. ITCard Showcase
@@ -252,19 +254,20 @@ const GallerySection = ({ title, subtitle, children }: { title: string; subtitle
252
254
  );
253
255
 
254
256
  const PatternCard = ({ title, desc, code, children }: { title: string; desc?: string; code?: string; children: React.ReactNode }) => {
257
+ const { t } = useITTranslation();
255
258
  const [showCode, setShowCode] = useState(false);
256
259
  return (
257
260
  <div className="bg-white dark:bg-slate-900/60 rounded-2xl border border-slate-200 dark:border-slate-700 shadow-sm hover:shadow-md transition-shadow overflow-hidden">
258
261
  <div className="flex items-start justify-between gap-2 p-4 pb-3">
259
262
  <div className="min-w-0">
260
- <p className="text-sm font-semibold text-slate-800 dark:text-slate-100">{title}</p>
263
+ <p className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{title}</p>
261
264
  {desc && <p className="text-[11px] text-slate-500 dark:text-slate-400 mt-0.5">{desc}</p>}
262
265
  </div>
263
266
  {code && (
264
267
  <ITButton variant="outlined" color="gray" size="sm" onClick={() => setShowCode(!showCode)}>
265
268
  <ITFlex align="center" gap={1}>
266
269
  <FaCode size={9} />
267
- {showCode ? "Hide code" : "Code"}
270
+ {showCode ? t("showcase.common.hideCode") : t("showcase.common.code")}
268
271
  </ITFlex>
269
272
  </ITButton>
270
273
  )}
@@ -280,6 +283,7 @@ const PatternCard = ({ title, desc, code, children }: { title: string; desc?: st
280
283
  };
281
284
 
282
285
  export const CardShowcase = () => {
286
+ const { t } = useITTranslation();
283
287
  const [title, setTitle] = useState("Monthly revenue");
284
288
  const [showActions, setShowActions] = useState(true);
285
289
  const [showImage, setShowImage] = useState(false);
@@ -301,7 +305,7 @@ export const CardShowcase = () => {
301
305
  return (
302
306
  <ShowcaseLayout
303
307
  title="ITCard"
304
- description="Contenedor multipropósito con cabecera opcional, imagen, contenido y pie de acciones. Se vuelve interactivo con `onClick` (efecto hover)."
308
+ description={t("showcase.structure.cardDesc")}
305
309
  code={buildCode()}
306
310
  demo={
307
311
  <div className="w-full max-w-xl flex flex-col">
@@ -327,7 +331,7 @@ export const CardShowcase = () => {
327
331
 
328
332
  {/* Fixed footer with active-property badges */}
329
333
  <div className="sticky bottom-0 mt-4 -mx-6 -mb-6 px-6 py-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-t border-slate-200 dark:border-slate-700 flex items-center flex-wrap gap-1.5 text-[10px] font-mono">
330
- <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
334
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">{t("showcase.common.activeLabel")}</span>
331
335
  {title && <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">title</span>}
332
336
  {showImage && <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">image</span>}
333
337
  {showActions && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">actions</span>}
@@ -339,37 +343,43 @@ export const CardShowcase = () => {
339
343
  <ITStack spacing={4}>
340
344
  <ITInput
341
345
  name="title_ctrl"
342
- label="Title"
346
+ label={t("showcase.structure.cardTitleLabel")}
343
347
  value={title}
344
348
  onChange={(e: any) => setTitle(e.target.value)}
345
349
  onBlur={() => { }}
346
- placeholder="Leave empty to hide"
350
+ placeholder={t("showcase.structure.cardTitlePlaceholder")}
347
351
  />
348
352
  <div className="flex items-center justify-between pt-1">
349
- <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Show image</span>
350
- <ITSlideToggle isOn={showImage} onToggle={setShowImage} size="sm" />
353
+ <span className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.showImage")}</span>
354
+ <ITSlideToggle isOn={showImage} onToggle={setShowImage} size="sm"
355
+ ariaLabel={t("showcase.structure.showImage")}
356
+ />
351
357
  </div>
352
358
  <div className="flex items-center justify-between">
353
- <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Show actions</span>
354
- <ITSlideToggle isOn={showActions} onToggle={setShowActions} size="sm" />
359
+ <span className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.showActions")}</span>
360
+ <ITSlideToggle isOn={showActions} onToggle={setShowActions} size="sm"
361
+ ariaLabel={t("showcase.structure.showActions")}
362
+ />
355
363
  </div>
356
364
  <div className="flex items-center justify-between">
357
- <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Interactive (onClick)</span>
358
- <ITSlideToggle isOn={clickable} onToggle={setClickable} size="sm" />
365
+ <span className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.interactiveOnClick")}</span>
366
+ <ITSlideToggle isOn={clickable} onToggle={setClickable} size="sm"
367
+ ariaLabel={t("showcase.structure.interactiveOnClick")}
368
+ />
359
369
  </div>
360
370
  </ITStack>
361
371
  }
362
372
  gallery={
363
373
  <ITStack spacing={8}>
364
374
  <GallerySection
365
- title="Real UI cases"
366
- subtitle="Production-ready card layouts built with ITCard"
375
+ title={t("showcase.structure.galleryRealCases")}
376
+ subtitle={t("showcase.structure.galleryCardsSubtitle")}
367
377
  >
368
378
  <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
369
379
 
370
380
  {/* 1. Course progress — ITProgress + ITBadget + ITDivider + ITText */}
371
381
  <PatternCard
372
- title="Course progress"
382
+ title={t("showcase.structure.patternCourseProgress")}
373
383
  desc="ITProgress + ITBadget + ITDivider + ITText"
374
384
  code={CARD_PATTERN_CODES.course}
375
385
  >
@@ -403,7 +413,7 @@ export const CardShowcase = () => {
403
413
 
404
414
  {/* 2. Featured pricing plan — ITBadget outside + ITFlex + ITStack + ITDivider */}
405
415
  <PatternCard
406
- title="Featured pricing plan"
416
+ title={t("showcase.structure.patternPricing")}
407
417
  desc="ITBadget + ITDivider + ITStack with ITFlex items"
408
418
  code={CARD_PATTERN_CODES.pricing}
409
419
  >
@@ -443,7 +453,7 @@ export const CardShowcase = () => {
443
453
 
444
454
  {/* 3. Activity feed item — ITText + ITBadget for commit hash + ITDivider separators */}
445
455
  <PatternCard
446
- title="Activity feed item"
456
+ title={t("showcase.structure.patternActivity")}
447
457
  desc="ITText + ITBadget (commit hash) + ITDivider separators"
448
458
  code={CARD_PATTERN_CODES.activity}
449
459
  >
@@ -485,7 +495,7 @@ export const CardShowcase = () => {
485
495
 
486
496
  {/* 4. Team member profile — ITFlex + ITBadget for skills + ITText throughout */}
487
497
  <PatternCard
488
- title="Team member profile"
498
+ title={t("showcase.structure.patternTeamMember")}
489
499
  desc="ITFlex + ITBadget skills + ITText throughout"
490
500
  code={CARD_PATTERN_CODES.teamMember}
491
501
  >
@@ -530,6 +540,7 @@ export const CardShowcase = () => {
530
540
 
531
541
  // 2. ITText Showcase
532
542
  export const TextShowcase = () => {
543
+ const { t } = useITTranslation();
533
544
  const [element, setElement] = useState("p");
534
545
  const [size, setSize] = useState("text-base");
535
546
  const [bold, setBold] = useState(false);
@@ -583,7 +594,7 @@ export const TextShowcase = () => {
583
594
  return (
584
595
  <ShowcaseLayout
585
596
  title="ITText"
586
- description="Wrapper tipográfico semántico. Renderiza cualquier elemento HTML, con soporte para truncado por caracteres, clamp de líneas y corte programático."
597
+ description={t("showcase.structure.textDesc")}
587
598
  code={buildCode()}
588
599
  demo={
589
600
  <div className="w-full flex flex-col">
@@ -592,7 +603,7 @@ export const TextShowcase = () => {
592
603
  {/* BIG element indicator — makes the `as` change unmissable */}
593
604
  <ITStack spacing={2} alignItems="center" className="mb-5 text-center">
594
605
  <ITText muted as="span" className="text-[10px] uppercase tracking-wider font-bold">
595
- Rendering as
606
+ {t("showcase.structure.renderingAs")}
596
607
  </ITText>
597
608
  <code
598
609
  key={element}
@@ -617,7 +628,7 @@ export const TextShowcase = () => {
617
628
 
618
629
  {/* Fixed footer with active-property badges */}
619
630
  <div className="sticky bottom-0 mt-4 -mx-6 -mb-6 px-6 py-3 bg-white/95 dark:bg-slate-900/95 backdrop-blur-sm border-t border-slate-200 dark:border-slate-700 flex items-center flex-wrap gap-1.5 text-[10px] font-mono">
620
- <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">Active:</span>
631
+ <span className="text-[9px] uppercase tracking-wider font-bold text-slate-400 dark:text-slate-500 mr-1">{t("showcase.common.activeLabel")}</span>
621
632
  {element !== "p" && <span className="px-2 py-0.5 rounded-md bg-slate-900 text-white dark:bg-white dark:text-slate-900 font-semibold">as=&quot;{element}&quot;</span>}
622
633
  <span className="px-2 py-0.5 rounded-md bg-primary-100 dark:bg-primary-900/30 text-primary-700 dark:text-primary-300">{size}</span>
623
634
  {bold && <span className="px-2 py-0.5 rounded-md bg-emerald-100 dark:bg-emerald-900/30 text-emerald-700 dark:text-emerald-300">font-bold</span>}
@@ -632,7 +643,7 @@ export const TextShowcase = () => {
632
643
  <ITStack spacing={4}>
633
644
  <ITSelect
634
645
  name="elem_ctrl"
635
- label="Elemento HTML (as)"
646
+ label={t("showcase.structure.elementAs")}
636
647
  value={element}
637
648
  onChange={(e) => setElement(e.target.value)}
638
649
  options={[
@@ -647,7 +658,7 @@ export const TextShowcase = () => {
647
658
  />
648
659
  <ITSelect
649
660
  name="sz_ctrl"
650
- label="Tamaño"
661
+ label={t("showcase.common.size")}
651
662
  value={size}
652
663
  onChange={(e) => setSize(e.target.value)}
653
664
  options={[
@@ -661,7 +672,7 @@ export const TextShowcase = () => {
661
672
  />
662
673
  <ITSelect
663
674
  name="clamp_ctrl"
664
- label="Número de líneas (lineClamp)"
675
+ label={t("showcase.structure.lineClampLabel")}
665
676
  value={String(lineClamp)}
666
677
  onChange={(e) => setLineClamp(Number(e.target.value))}
667
678
  options={[
@@ -674,39 +685,39 @@ export const TextShowcase = () => {
674
685
  />
675
686
  <ITInput
676
687
  name="max_ctrl"
677
- label="Texto máximo (caracteres)"
688
+ label={t("showcase.structure.maxTextLabel")}
678
689
  type="number"
679
690
  value={maxLength}
680
691
  onChange={(e) => setMaxLength(e.target.value)}
681
- placeholder="0 = sin límite"
692
+ placeholder={t("showcase.structure.noLimit")}
682
693
  />
683
694
  <ITFlex justify="between" align="center">
684
695
  <ITText muted as="span" className="text-[10px]">
685
- Trunca con "…" al superar (0 = desactivado).
696
+ {t("showcase.structure.truncateHint")}
686
697
  </ITText>
687
698
  <ITButton variant="text" color="primary" size="sm" onClick={() => setMaxLength("0")}>
688
- Reset
699
+ {t("showcase.common.reset")}
689
700
  </ITButton>
690
701
  </ITFlex>
691
702
  <ITInput
692
703
  name="break_ctrl"
693
- label="Salto de línea después de (caracteres)"
704
+ label={t("showcase.structure.breakLabel")}
694
705
  type="number"
695
706
  value={breakLength}
696
707
  onChange={(e) => setBreakLength(e.target.value)}
697
- placeholder="0 = sin salto"
708
+ placeholder={t("showcase.structure.noBreak")}
698
709
  />
699
710
  <ITFlex justify="between" align="center">
700
711
  <ITText muted as="span" className="text-[10px]">
701
- Inserta un &lt;br /&gt; al superar el límite.
712
+ {t("showcase.structure.brHint")}
702
713
  </ITText>
703
714
  <ITButton variant="text" color="primary" size="sm" onClick={() => setBreakLength("0")}>
704
- Reset
715
+ {t("showcase.common.reset")}
705
716
  </ITButton>
706
717
  </ITFlex>
707
718
  <div>
708
719
  <ITText as="label" htmlFor="break_ctrl" className="text-xs font-semibold text-slate-600 dark:text-slate-400 block mb-1">
709
- breakLengthWrap (corte cada N caracteres)
720
+ {t("showcase.structure.breakWrapLabel")}
710
721
  </ITText>
711
722
  <input
712
723
  id="break_ctrl"
@@ -716,42 +727,46 @@ export const TextShowcase = () => {
716
727
  value={breakLength}
717
728
  onChange={(e) => setBreakLength(e.target.value)}
718
729
  className="w-full bg-slate-50 dark:bg-slate-900 border border-slate-200 dark:border-slate-800 rounded-lg p-2 text-xs text-slate-800 dark:text-slate-100 outline-none focus:ring-2 focus:ring-primary-500"
719
- placeholder="0 = sin corte"
730
+ placeholder={t("showcase.structure.noCut")}
720
731
  />
721
732
  <ITFlex justify="between" align="center" className="mt-1.5">
722
733
  <ITText muted as="span" className="text-[10px]">
723
- Inserta oportunidades de corte cada N chars (0 = desactivado).
734
+ {t("showcase.structure.cutHint")}
724
735
  </ITText>
725
736
  <button
726
737
  type="button"
727
738
  onClick={() => setBreakLength("0")}
728
739
  className="text-[10px] font-semibold text-primary-600 hover:text-primary-700 dark:text-primary-400"
729
740
  >
730
- Reset
741
+ {t("showcase.common.reset")}
731
742
  </button>
732
743
  </ITFlex>
733
744
  </div>
734
745
  <div className="flex items-center justify-between pt-1">
735
- <ITText as="span" className="text-sm font-semibold text-slate-700 dark:text-slate-300">Negrita (font-bold)</ITText>
736
- <ITSlideToggle isOn={bold} onToggle={setBold} size="sm" />
746
+ <ITText as="span" className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.boldLabel")}</ITText>
747
+ <ITSlideToggle isOn={bold} onToggle={setBold} size="sm"
748
+ ariaLabel={t("showcase.structure.boldLabel")}
749
+ />
737
750
  </div>
738
751
  <div className="flex items-center justify-between">
739
- <ITText as="span" className="text-sm font-semibold text-slate-700 dark:text-slate-300">Muted color</ITText>
740
- <ITSlideToggle isOn={muted} onToggle={setMuted} size="sm" />
752
+ <ITText as="span" className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.mutedLabel")}</ITText>
753
+ <ITSlideToggle isOn={muted} onToggle={setMuted} size="sm"
754
+ ariaLabel={t("showcase.structure.mutedLabel")}
755
+ />
741
756
  </div>
742
757
  </ITStack>
743
758
  }
744
759
  gallery={
745
760
  <ITStack spacing={8}>
746
761
  <GallerySection
747
- title="Real UI cases"
748
- subtitle="Production-ready typography patterns built with ITText"
762
+ title={t("showcase.structure.galleryRealCases")}
763
+ subtitle={t("showcase.structure.galleryTextSubtitle")}
749
764
  >
750
765
  <div className="grid grid-cols-1 lg:grid-cols-2 gap-5">
751
766
 
752
767
  {/* 1. Article header — eyebrow + title + meta */}
753
768
  <PatternCard
754
- title="Article header"
769
+ title={t("showcase.structure.patternArticleHeader")}
755
770
  desc="eyebrow tag + h1 title + author/date/read-time meta"
756
771
  code={TEXT_PATTERN_CODES.articleHeader}
757
772
  >
@@ -779,7 +794,7 @@ export const TextShowcase = () => {
779
794
 
780
795
  {/* 2. Section heading — h2 + description + action link */}
781
796
  <PatternCard
782
- title="Section heading"
797
+ title={t("showcase.structure.patternSectionHeading")}
783
798
  desc="h2 title + description + action link on the right"
784
799
  code={TEXT_PATTERN_CODES.sectionHeading}
785
800
  >
@@ -798,7 +813,7 @@ export const TextShowcase = () => {
798
813
 
799
814
  {/* 3. Empty state — big title + description + muted helper */}
800
815
  <PatternCard
801
- title="Empty state"
816
+ title={t("showcase.structure.patternEmptyState")}
802
817
  desc="big title + description + muted helper text"
803
818
  code={TEXT_PATTERN_CODES.emptyState}
804
819
  >
@@ -826,7 +841,7 @@ export const TextShowcase = () => {
826
841
 
827
842
  {/* 4. Inline content — paragraph with bold name + inline code + muted meta */}
828
843
  <PatternCard
829
- title="Inline content"
844
+ title={t("showcase.structure.patternInlineContent")}
830
845
  desc="paragraph with bold name + inline code + muted timestamp"
831
846
  code={TEXT_PATTERN_CODES.inlineContent}
832
847
  >
@@ -854,13 +869,13 @@ export const TextShowcase = () => {
854
869
 
855
870
  {/* 5. Form labels — label + helper text */}
856
871
  <PatternCard
857
- title="Form labels"
872
+ title={t("showcase.structure.patternFormLabels")}
858
873
  desc="label + required asterisk + muted helper text"
859
874
  code={TEXT_PATTERN_CODES.formLabels}
860
875
  >
861
876
  <ITStack spacing={4} className="max-w-sm">
862
877
  <div>
863
- <ITText as="label" className="text-sm font-semibold text-slate-700 dark:text-slate-200 block mb-1">
878
+ <ITText as="label" className="block mb-1 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">
864
879
  Workspace name <ITText as="span" className="text-danger-500">*</ITText>
865
880
  </ITText>
866
881
  <ITInput
@@ -875,7 +890,7 @@ export const TextShowcase = () => {
875
890
  </ITText>
876
891
  </div>
877
892
  <div>
878
- <ITText as="label" className="text-sm font-semibold text-slate-700 dark:text-slate-200 block mb-1">
893
+ <ITText as="label" className="block mb-1 font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">
879
894
  Description
880
895
  </ITText>
881
896
  <ITInput
@@ -903,6 +918,7 @@ export const TextShowcase = () => {
903
918
 
904
919
  // 3. ITLayout & ITNavbar Showcase
905
920
  export const LayoutShowcase = () => {
921
+ const { t } = useITTranslation();
906
922
  const [collapsed, setCollapsed] = useState(true);
907
923
  const [activeId, setActiveId] = useState("dashboard");
908
924
  const [navActiveId, setNavActiveId] = useState<string | null>("1");
@@ -913,55 +929,55 @@ export const LayoutShowcase = () => {
913
929
  centerContent: (
914
930
  <input
915
931
  type="search"
916
- placeholder="Buscar componente…"
932
+ placeholder={t("sandbox.search.placeholder")}
917
933
  className="w-full rounded-lg border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900 px-3 py-1.5 text-xs text-slate-700 dark:text-slate-200 outline-none focus:ring-2 focus:ring-primary-500/40"
918
934
  />
919
935
  ),
920
936
  navItems: [
921
- { id: "home", label: "Inicio", icon: <FaHome />, action: () => setActiveId("home") },
922
- { id: "docs", label: "Documentos", icon: <FaFileAlt />, action: () => setActiveId("docs") },
923
- { id: "alerts", label: "Alertas", icon: <FaBell />, action: () => setActiveId("alerts") },
937
+ { id: "home", label: t("showcase.common.home"), icon: <FaHome />, action: () => setActiveId("home") },
938
+ { id: "docs", label: t("showcase.structure.navDocuments"), icon: <FaFileAlt />, action: () => setActiveId("docs") },
939
+ { id: "alerts", label: t("showcase.structure.navAlerts"), icon: <FaBell />, action: () => setActiveId("alerts") },
924
940
  ],
925
941
  onNavItemClick: (id: string) => setActiveId(id),
926
942
  userMenu: {
927
943
  userName: "Auditor AXZY",
928
944
  userEmail: "auditor@axzy.dev",
929
945
  menuItems: [
930
- { label: "Ajustes", onClick: () => {} },
931
- { label: "Cerrar sesión", onClick: () => {} },
946
+ { label: t("showcase.structure.navSettings"), onClick: () => {} },
947
+ { label: t("showcase.structure.navLogout"), onClick: () => {} },
932
948
  ],
933
949
  },
934
950
  };
935
951
 
936
952
  const sidebar: ITSidebarProps = {
937
953
  navigationItems: [
938
- { id: "dashboard", label: "Dashboard", icon: <FaChartLine />, isActive: activeId === "dashboard", action: () => setActiveId("dashboard") },
939
- { id: "users", label: "Usuarios", icon: <FaUsers />, isActive: activeId === "users", action: () => setActiveId("users"), badge: 4 },
954
+ { id: "dashboard", label: t("showcase.structure.navDashboard"), icon: <FaChartLine />, isActive: activeId === "dashboard", action: () => setActiveId("dashboard") },
955
+ { id: "users", label: t("showcase.structure.navUsers"), icon: <FaUsers />, isActive: activeId === "users", action: () => setActiveId("users"), badge: 4 },
940
956
  {
941
957
  id: "sales",
942
- label: "Ventas",
958
+ label: t("showcase.structure.navSales"),
943
959
  icon: <FaShoppingCart />,
944
960
  isActive: activeId === "sales" || activeId === "orders" || activeId === "quotes",
945
961
  subitems: [
946
962
  {
947
963
  id: "sales-gestion",
948
- label: "Gestión",
964
+ label: t("showcase.structure.navManagement"),
949
965
  items: [
950
- { id: "orders", label: "Órdenes", action: () => setActiveId("orders") },
951
- { id: "invoices", label: "Facturas", action: () => setActiveId("invoices") },
966
+ { id: "orders", label: t("showcase.structure.navOrders"), action: () => setActiveId("orders") },
967
+ { id: "invoices", label: t("showcase.structure.navInvoices"), action: () => setActiveId("invoices") },
952
968
  ],
953
969
  },
954
970
  {
955
971
  id: "sales-catalogo",
956
- label: "Catálogo",
972
+ label: t("showcase.structure.navCatalog"),
957
973
  items: [
958
- { id: "quotes", label: "Cotizaciones", action: () => setActiveId("quotes") },
974
+ { id: "quotes", label: t("showcase.structure.navQuotes"), action: () => setActiveId("quotes") },
959
975
  ],
960
976
  },
961
977
  ],
962
978
  },
963
- { id: "products", label: "Productos", icon: <FaBoxOpen />, isActive: activeId === "products", action: () => setActiveId("products"), badge: 12 },
964
- { id: "settings", label: "Configuración", icon: <FaCog />, isActive: activeId === "settings", action: () => setActiveId("settings"), badge: 3, badgeProps: { color: "warning", variant: "outlined" } },
979
+ { id: "products", label: t("showcase.structure.navProducts"), icon: <FaBoxOpen />, isActive: activeId === "products", action: () => setActiveId("products"), badge: 12 },
980
+ { id: "settings", label: t("showcase.structure.navConfiguration"), icon: <FaCog />, isActive: activeId === "settings", action: () => setActiveId("settings"), badge: 3, badgeProps: { color: "warning", variant: "outlined" } },
965
981
  ],
966
982
  isCollapsed: collapsed,
967
983
  header: (
@@ -976,7 +992,7 @@ export const LayoutShowcase = () => {
976
992
  notification: {
977
993
  count: 5,
978
994
  icon: <FaBell />,
979
- label: "Notificaciones",
995
+ label: t("sandbox.notifications"),
980
996
  onClick: () => setActiveId("notifications"),
981
997
  badgeProps: { color: "danger" },
982
998
  },
@@ -1027,57 +1043,45 @@ export const LayoutShowcase = () => {
1027
1043
  </ITLayout>`;
1028
1044
 
1029
1045
  const navbarItems = [
1030
- { id: "1", label: "Inicio", icon: <FaHome />, isActive: navActiveId === "1", action: () => setNavActiveId("1") },
1031
- { id: "2", label: "Documentos", icon: <FaFileAlt />, isActive: navActiveId === "2", action: () => setNavActiveId("2") },
1032
- { id: "3", label: "Alertas", icon: <FaBell />, isActive: navActiveId === "3", action: () => setNavActiveId("3") },
1046
+ { id: "1", label: t("showcase.common.home"), icon: <FaHome />, isActive: navActiveId === "1", action: () => setNavActiveId("1") },
1047
+ { id: "2", label: t("showcase.structure.navDocuments"), icon: <FaFileAlt />, isActive: navActiveId === "2", action: () => setNavActiveId("2") },
1048
+ { id: "3", label: t("showcase.structure.navAlerts"), icon: <FaBell />, isActive: navActiveId === "3", action: () => setNavActiveId("3") },
1033
1049
  ];
1034
1050
 
1035
- const navbarCode = `<ITNavbar
1036
- logoText="AXZY"
1037
- navigationItems={[
1038
- { id: "1", label: "Inicio", icon: <FaHome />, isActive: true },
1039
- { id: "2", label: "Documentos", icon: <FaFileAlt /> },
1040
- { id: "3", label: "Alertas", icon: <FaBell /> }
1041
- ]}
1042
- userMenu={{
1043
- userName: "Auditor AXZY",
1044
- userEmail: "auditor@axzy.dev",
1045
- menuItems: [{ label: "Ajustes", onClick: () => {} }]
1046
- }}
1047
- />`;
1048
1051
 
1049
1052
  return (
1050
1053
  <ShowcaseLayout
1054
+ demoMinAncho={780}
1051
1055
  title="ITLayout & ITNavbar"
1052
1056
  description="Chasis estructural del portal con barra superior y lateral colapsable. Totalmente responsivo con drawer móvil."
1053
1057
  code={code}
1054
1058
  demo={
1055
1059
  <div className="w-full h-[640px] rounded-xl overflow-hidden border border-slate-200 dark:border-slate-700 shadow-md">
1056
- <ITLayout topBar={topBar} sidebar={sidebar}>
1060
+ <ITLayout className="!h-full" topBar={topBar} sidebar={sidebar}>
1057
1061
  <ITStack spacing={5}>
1058
1062
  <ITPageHeader
1059
- title="Dashboard"
1060
- description="Resumen general del sistema"
1063
+ title={t("showcase.structure.navDashboard")}
1064
+ description={t("showcase.structure.dashboardDesc")}
1061
1065
  icon={<FaChartLine size={20} />}
1062
1066
  iconColor="#6366f1"
1063
1067
  />
1064
1068
  <ITGrid container spacing={3}>
1065
1069
  <ITGrid item xs={12} sm={6} lg={3}>
1066
- <ITStatCard label="Usuarios" value="1,245" trend="+12%" trendDirection="up" />
1070
+ <ITStatCard label={t("showcase.structure.navUsers")} value="1,245" trend="+12%" trendDirection="up" />
1067
1071
  </ITGrid>
1068
1072
  <ITGrid item xs={12} sm={6} lg={3}>
1069
- <ITStatCard label="Ventas Hoy" value="$4,320" trend="+5.4%" trendDirection="up" color="bg-blue-50 dark:bg-blue-950/20" />
1073
+ <ITStatCard label={t("showcase.structure.statSalesToday")} value="$4,320" trend="+5.4%" trendDirection="up" color="bg-blue-50 dark:bg-blue-950/20" />
1070
1074
  </ITGrid>
1071
1075
  <ITGrid item xs={12} sm={6} lg={3}>
1072
- <ITStatCard label="Órdenes" value="89" trend="-2.1%" trendDirection="down" color="bg-amber-50 dark:bg-amber-950/20" />
1076
+ <ITStatCard label={t("showcase.structure.navOrders")} value="89" trend="-2.1%" trendDirection="down" color="bg-amber-50 dark:bg-amber-950/20" />
1073
1077
  </ITGrid>
1074
1078
  <ITGrid item xs={12} sm={6} lg={3}>
1075
- <ITStatCard label="Tickets" value="12" trend="-8%" trendDirection="down" color="bg-rose-50 dark:bg-rose-950/20" />
1079
+ <ITStatCard label={t("showcase.structure.statTickets")} value="12" trend="-8%" trendDirection="down" color="bg-rose-50 dark:bg-rose-950/20" />
1076
1080
  </ITGrid>
1077
1081
  </ITGrid>
1078
- <ITCard title="Actividad reciente">
1082
+ <ITCard title={t("showcase.structure.recentActivity")}>
1079
1083
  <ITText className="text-sm text-slate-600 dark:text-slate-300">
1080
- El layout se adapta al colapsar/expandir el sidebar y muestra un drawer en móvil.
1084
+ {t("showcase.structure.layoutBody")}
1081
1085
  </ITText>
1082
1086
  </ITCard>
1083
1087
  </ITStack>
@@ -1087,19 +1091,35 @@ export const LayoutShowcase = () => {
1087
1091
  controls={
1088
1092
  <ITStack spacing={4}>
1089
1093
  <div className="flex items-center justify-between">
1090
- <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Sidebar colapsado</span>
1091
- <ITSlideToggle isOn={collapsed} onToggle={setCollapsed} size="sm" />
1094
+ <span className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.sidebarCollapsed")}</span>
1095
+ <ITSlideToggle isOn={collapsed} onToggle={setCollapsed} size="sm"
1096
+ ariaLabel={t("showcase.structure.sidebarCollapsed")}
1097
+ />
1092
1098
  </div>
1093
1099
  <div className="text-xs text-slate-500">
1094
- En móvil (&lt;lg) el sidebar se abre como drawer con un fondo oscuro. Usa el botón ☰ del topbar. En desktop el riel colapsado se expande al pasar el cursor; no hay botón de colapso en el sidebar.
1100
+ {t("showcase.structure.layoutHint")}
1095
1101
  </div>
1096
1102
  </ITStack>
1097
1103
  }
1098
1104
  gallery={
1099
- <ITStack spacing={6}>
1100
- <div>
1101
- <h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">ITNavbar (standalone)</h4>
1102
- <div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden h-[420px]">
1105
+ <ITStack spacing={8}>
1106
+ <EjemploContenedor
1107
+ numero="02"
1108
+ titulo={t("showcase.structure.galleryNavbarStandalone")}
1109
+ codigo={`<ITNavbar
1110
+ logoText="AXZY"
1111
+ navigationItems={[
1112
+ { id: "1", label: "Inicio", icon: <FaHome />, isActive: true },
1113
+ { id: "2", label: "Documentos", icon: <FaFileAlt /> },
1114
+ { id: "3", label: "Alertas", icon: <FaBell /> },
1115
+ ]}
1116
+ userMenu={{ userName: "Auditor AXZY", userEmail: "auditor@axzy.dev" }}
1117
+ >
1118
+ <Dashboard />
1119
+ </ITNavbar>`}
1120
+ sangrado
1121
+ >
1122
+ <div className="h-[380px] overflow-hidden [&>div]:!h-full">
1103
1123
  <ITNavbar
1104
1124
  logoText="AXZY"
1105
1125
  navigationItems={navbarItems}
@@ -1107,77 +1127,119 @@ export const LayoutShowcase = () => {
1107
1127
  userName: "Auditor AXZY",
1108
1128
  userEmail: "auditor@axzy.dev",
1109
1129
  menuItems: [
1110
- { label: "Ajustes", onClick: () => {} },
1111
- { label: "Cerrar sesión", onClick: () => {} },
1130
+ { label: t("showcase.structure.navSettings"), onClick: () => {} },
1131
+ { label: t("showcase.structure.navLogout"), onClick: () => {} },
1112
1132
  ],
1113
1133
  }}
1114
1134
  >
1115
- <div className="p-8 text-center text-slate-500 text-sm">
1116
- {navActiveId ? `Item activo: "${navbarItems.find(i => i.isActive)?.label}"` : "Selecciona un item en la navegación"}
1135
+ <div className="p-6">
1136
+ <p className="font-mono text-[11px] uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">
1137
+ {navActiveId
1138
+ ? t("showcase.structure.activeItem", {
1139
+ label: navbarItems.find((item) => item.isActive)?.label ?? "",
1140
+ })
1141
+ : t("showcase.structure.selectNavItem")}
1142
+ </p>
1117
1143
  </div>
1118
1144
  </ITNavbar>
1119
1145
  </div>
1120
- <div className="mt-3">
1121
- <CodeViewer code={navbarCode} />
1122
- </div>
1123
- </div>
1146
+ </EjemploContenedor>
1124
1147
 
1125
- <div>
1126
- <h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">ITNavbar con submenús</h4>
1127
- <div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden h-[420px]">
1148
+ <EjemploContenedor
1149
+ numero="03"
1150
+ titulo={t("showcase.structure.galleryNavbarSubmenus")}
1151
+ codigo={`<ITNavbar
1152
+ logoText="Admin"
1153
+ navigationItems={[
1154
+ { id: "u", label: "Usuarios", icon: <FaUsers /> },
1155
+ {
1156
+ id: "s",
1157
+ label: "Ventas",
1158
+ icon: <FaShoppingCart />,
1159
+ subitems: [
1160
+ { id: "o", label: "Órdenes", action: () => {} },
1161
+ { id: "i", label: "Facturas", action: () => {} },
1162
+ ],
1163
+ },
1164
+ ]}
1165
+ />`}
1166
+ sangrado
1167
+ >
1168
+ <div className="h-[380px] overflow-hidden [&>div]:!h-full">
1128
1169
  <ITNavbar
1129
1170
  logoText="Admin"
1130
1171
  navigationItems={[
1131
- { id: "u", label: "Usuarios", icon: <FaUsers /> },
1172
+ { id: "u", label: t("showcase.structure.navUsers"), icon: <FaUsers /> },
1132
1173
  {
1133
1174
  id: "s",
1134
- label: "Ventas",
1175
+ label: t("showcase.structure.navSales"),
1135
1176
  icon: <FaShoppingCart />,
1136
1177
  subitems: [
1137
- { id: "o", label: "Órdenes", action: () => {} },
1138
- { id: "i", label: "Facturas", action: () => {} },
1178
+ { id: "o", label: t("showcase.structure.navOrders"), action: () => {} },
1179
+ { id: "i", label: t("showcase.structure.navInvoices"), action: () => {} },
1139
1180
  ],
1140
1181
  },
1141
- { id: "c", label: "Configuración", icon: <FaCog /> },
1182
+ { id: "c", label: t("showcase.structure.navConfiguration"), icon: <FaCog /> },
1142
1183
  ]}
1143
1184
  userMenu={{
1144
1185
  userName: "Admin",
1145
1186
  userEmail: "admin@axzy.dev",
1146
- menuItems: [{ label: "Salir", onClick: () => {} }],
1187
+ menuItems: [{ label: t("showcase.structure.navExit"), onClick: () => {} }],
1147
1188
  }}
1148
1189
  >
1149
- <div className="p-8 text-center text-slate-500 text-sm">
1150
- Haz clic en "Ventas" para expandir/colapsar el submenú
1190
+ <div className="p-6">
1191
+ <p className="font-mono text-[11px] uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">
1192
+ {t("showcase.structure.submenuHint")}
1193
+ </p>
1151
1194
  </div>
1152
1195
  </ITNavbar>
1153
1196
  </div>
1154
- </div>
1197
+ </EjemploContenedor>
1155
1198
 
1156
- <div>
1157
- <h4 className="text-sm font-bold text-slate-700 dark:text-slate-200 mb-3">ITSidebar — badges + notificación</h4>
1158
- <div className="border border-slate-200 dark:border-slate-700 rounded-xl overflow-hidden h-[420px] flex">
1199
+ <EjemploContenedor
1200
+ numero="04"
1201
+ titulo={t("showcase.structure.gallerySidebarBadges")}
1202
+ codigo={`<ITSidebar
1203
+ subitemConnector="dot"
1204
+ navigationItems={[
1205
+ { id: "home", label: "Inicio", icon: <FaHome />, isActive: true },
1206
+ { id: "inbox", label: "Bandeja", icon: <FaUsers />, badge: 12 },
1207
+ { id: "alerts", label: "Alertas", icon: <FaBell />, badge: 3 },
1208
+ ]}
1209
+ notification={{ count: 5, icon: <FaBell /> }}
1210
+ />`}
1211
+ sangrado
1212
+ >
1213
+ <div className="flex h-[320px] overflow-hidden [&>div]:!h-full">
1159
1214
  <ITSidebar
1160
1215
  visibleOnMobile
1161
1216
  className="h-full"
1162
1217
  subitemConnector="dot"
1163
1218
  navigationItems={[
1164
- { id: "home", label: "Inicio", icon: <FaHome />, isActive: true, action: () => {} },
1165
- { id: "inbox", label: "Bandeja", icon: <FaUsers />, badge: 12, action: () => {} },
1166
- { id: "alerts", label: "Alertas", icon: <FaBell />, badge: 3, badgeProps: { color: "warning", variant: "outlined" }, action: () => {} },
1167
- { id: "settings", label: "Configuración", icon: <FaCog />, action: () => {} },
1219
+ { id: "home", label: t("showcase.common.home"), icon: <FaHome />, isActive: true, action: () => {} },
1220
+ { id: "inbox", label: t("showcase.structure.navInbox"), icon: <FaUsers />, badge: 12, action: () => {} },
1221
+ { id: "alerts", label: t("showcase.structure.navAlerts"), icon: <FaBell />, badge: 3, badgeProps: { color: "warning", variant: "outlined" }, action: () => {} },
1222
+ { id: "settings", label: t("showcase.structure.navConfiguration"), icon: <FaCog />, action: () => {} },
1168
1223
  ]}
1169
1224
  notification={{
1170
1225
  count: 5,
1171
1226
  icon: <FaBell />,
1172
- label: "Notificaciones",
1227
+ label: t("sandbox.notifications"),
1173
1228
  onClick: () => {},
1174
1229
  }}
1175
1230
  />
1176
- <div className="flex-1 p-6 text-sm text-slate-500">
1177
- Cada ítem puede llevar un contador con <code className="font-mono text-xs">badge</code> + <code className="font-mono text-xs">badgeProps</code>, y el sidebar admite una fila <code className="font-mono text-xs">notification</code> con icono + ITBadget.
1231
+ <div className="flex-1 p-6">
1232
+ <p className="font-mono text-[11px] leading-relaxed text-slate-500 dark:text-slate-400">
1233
+ {t("showcase.structure.sidebarItemsHint1")}{" "}
1234
+ <code className="rounded-[4px] border border-slate-200 px-1 dark:border-slate-800">badge</code> +{" "}
1235
+ <code className="rounded-[4px] border border-slate-200 px-1 dark:border-slate-800">badgeProps</code>
1236
+ {t("showcase.structure.sidebarItemsHint2")}{" "}
1237
+ <code className="rounded-[4px] border border-slate-200 px-1 dark:border-slate-800">notification</code>{" "}
1238
+ {t("showcase.structure.sidebarItemsHint3")}
1239
+ </p>
1178
1240
  </div>
1179
1241
  </div>
1180
- </div>
1242
+ </EjemploContenedor>
1181
1243
  </ITStack>
1182
1244
  }
1183
1245
  doc={{
@@ -1215,13 +1277,14 @@ export const LayoutShowcase = () => {
1215
1277
  // ITAccordion Showcase
1216
1278
  // ─────────────────────────────────────────
1217
1279
  export const AccordionShowcase = () => {
1280
+ const { t } = useITTranslation();
1218
1281
  const [allowMultiple, setAllowMultiple] = useState(false);
1219
1282
 
1220
1283
  const items = [
1221
- { id: "what", title: "¿Qué es AXZY UI System?", content: "Una librería de componentes React + TypeScript con Tailwind CSS v4." },
1222
- { id: "install", title: "¿Cómo lo instalo?", content: "pnpm add @axzydev/axzy_ui_system" },
1223
- { id: "theme", title: "¿Puedo personalizar el tema?", content: "Sí, usa ITThemeProvider para definir la paleta y los tokens." },
1224
- { id: "disabled", title: "Sección deshabilitada", content: "No se puede abrir.", disabled: true },
1284
+ { id: "what", title: t("showcase.structure.accWhat"), content: t("showcase.structure.accWhatBody") },
1285
+ { id: "install", title: t("showcase.structure.accInstall"), content: "pnpm add @axzydev/axzy_ui_system" },
1286
+ { id: "theme", title: t("showcase.structure.accTheme"), content: t("showcase.structure.accThemeBody") },
1287
+ { id: "disabled", title: t("showcase.structure.accDisabled"), content: t("showcase.structure.accDisabledBody"), disabled: true },
1225
1288
  ];
1226
1289
 
1227
1290
  const code = `<ITAccordion\n allowMultiple={${allowMultiple}}\n defaultOpenIds={['what']}\n items={[\n { id: 'what', title: '¿Qué es AXZY?', content: '...' },\n { id: 'install', title: '¿Cómo lo instalo?', content: '...' },\n ]}\n/>`;
@@ -1229,7 +1292,7 @@ export const AccordionShowcase = () => {
1229
1292
  return (
1230
1293
  <ShowcaseLayout
1231
1294
  title="ITAccordion"
1232
- description="Secciones plegables para FAQs, paneles de configuración y contenido largo. Controlado o no controlado, single o multiple, con animación CSS grid-rows."
1295
+ description={t("showcase.structure.accordionDesc")}
1233
1296
  code={code}
1234
1297
  demo={
1235
1298
  <div className="w-full max-w-xl">
@@ -1238,18 +1301,20 @@ export const AccordionShowcase = () => {
1238
1301
  }
1239
1302
  controls={
1240
1303
  <div className="flex items-center justify-between">
1241
- <span className="text-sm font-semibold text-gray-700">Permitir múltiples abiertas</span>
1242
- <ITSlideToggle isOn={allowMultiple} onToggle={setAllowMultiple} size="sm" />
1304
+ <span className="font-mono text-[11px] font-medium uppercase tracking-[0.14em] text-slate-500 dark:text-slate-400">{t("showcase.structure.allowMultiple")}</span>
1305
+ <ITSlideToggle isOn={allowMultiple} onToggle={setAllowMultiple} size="sm"
1306
+ ariaLabel={t("showcase.structure.allowMultiple")}
1307
+ />
1243
1308
  </div>
1244
1309
  }
1245
1310
  gallery={
1246
1311
  <div className="grid grid-cols-1 md:grid-cols-2 gap-8">
1247
1312
  <div>
1248
- <p className="mb-3 text-[10px] font-bold uppercase tracking-wider text-slate-400">Bordered</p>
1313
+ <p className="mb-3 text-[10px] font-bold uppercase tracking-wider text-slate-400">{t("showcase.structure.accordionBordered")}</p>
1249
1314
  <ITAccordion items={items.slice(0, 3)} variant="bordered" defaultOpenIds={["install"]} />
1250
1315
  </div>
1251
1316
  <div>
1252
- <p className="mb-3 text-[10px] font-bold uppercase tracking-wider text-slate-400">Separated (default)</p>
1317
+ <p className="mb-3 text-[10px] font-bold uppercase tracking-wider text-slate-400">{t("showcase.structure.accordionSeparated")}</p>
1253
1318
  <ITAccordion items={items.slice(0, 3)} defaultOpenIds={["theme"]} />
1254
1319
  </div>
1255
1320
  </div>