@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
@@ -21,17 +21,17 @@ export interface ITPageProps {
21
21
  loading?: boolean;
22
22
  /** Error message to display. Shows an error state with retry button when provided. */
23
23
  error?: string | null;
24
- /** Custom title for the error state. Default: "Error". */
24
+ /** Custom title for the error state. Default: i18n `common.error` ("Error"). */
25
25
  errorTitle?: string;
26
- /** Label for the retry button in the error state. Default: "Reintentar". */
26
+ /** Label for the retry button in the error state. Default: i18n `common.retry` ("Reintentar"). */
27
27
  errorActionLabel?: string;
28
28
  /** Callback fired when the retry button is clicked in the error state. */
29
29
  onRetry?: () => void;
30
30
  /** Whether the page is in an empty state. Shows a placeholder when true. */
31
31
  empty?: boolean;
32
- /** Custom title for the empty state. Default: "Sin datos". */
32
+ /** Custom title for the empty state. Default: i18n `common.noData` ("Sin datos"). */
33
33
  emptyTitle?: string;
34
- /** Custom description for the empty state. */
34
+ /** Custom description for the empty state. Default: i18n `common.empty` ("No hay información para mostrar"). */
35
35
  emptyDescription?: string;
36
36
  /** Custom action element for the empty state. */
37
37
  emptyAction?: ReactNode;
@@ -5,6 +5,7 @@ import ITSkeleton from "@/components/atoms/skeleton/skeleton";
5
5
  import ITEmptyState from "@/components/molecules/empty-state/empty-state";
6
6
  import ITButton from "@/components/atoms/button/button";
7
7
  import ITStack from "@/components/atoms/stack/stack";
8
+ import { useITTranslation } from "@/i18n";
8
9
 
9
10
  const hasHeader = (props: ITPageProps) =>
10
11
  !!(props.title || props.description || props.breadcrumbs || props.actions || props.backAction || props.icon);
@@ -51,6 +52,7 @@ const renderHeader = (props: ITPageProps) => {
51
52
  * ```
52
53
  */
53
54
  export default function ITPage(props: ITPageProps) {
55
+ const { t } = useITTranslation();
54
56
  const {
55
57
  loading = false,
56
58
  error = null,
@@ -95,12 +97,12 @@ export default function ITPage(props: ITPageProps) {
95
97
  <div className={wrapperClass}>
96
98
  {renderHeader(props)}
97
99
  <ITEmptyState
98
- title={errorTitle || "Error"}
100
+ title={errorTitle || t("common.error")}
99
101
  description={error}
100
102
  action={
101
103
  onRetry ? (
102
104
  <ITButton
103
- label={errorActionLabel || "Reintentar"}
105
+ label={errorActionLabel || t("common.retry")}
104
106
  onClick={onRetry}
105
107
  size="sm"
106
108
  />
@@ -116,8 +118,8 @@ export default function ITPage(props: ITPageProps) {
116
118
  <div className={wrapperClass}>
117
119
  {renderHeader(props)}
118
120
  <ITEmptyState
119
- title={emptyTitle || "Sin datos"}
120
- description={emptyDescription || "No hay información para mostrar"}
121
+ title={emptyTitle || t("common.noData")}
122
+ description={emptyDescription || t("common.empty")}
121
123
  action={emptyAction}
122
124
  />
123
125
  </div>
@@ -9,6 +9,7 @@ import ITInput from "@/components/atoms/input/input";
9
9
  import ITSegmentedControl from "@/components/atoms/segmented-control/segmented-control";
10
10
  import ITDivider from "@/components/atoms/divider/divider";
11
11
  import ITText from "@/components/atoms/text/text";
12
+ import { useITTranslation } from "@/i18n";
12
13
 
13
14
  // ============================================================================
14
15
  // DEFAULT PALETTE & PRESETS CONFIG
@@ -66,6 +67,15 @@ const shadowLevel = (level: number | undefined): Record<string, string> | null =
66
67
 
67
68
  import { DEFAULT_PALETTE, PRESETS } from "./themePresets";
68
69
 
70
+ /** Mapea el nombre de un preset integrado a su key de i18n (`themeProvider.presets.*`). */
71
+ const PRESET_I18N_KEY: Record<string, string> = {
72
+ "Midnight Indigo 🌌": "themeProvider.presets.midnightIndigo",
73
+ "Coral Reef 🪸": "themeProvider.presets.coralReef",
74
+ "Oceanic Teal 🌊": "themeProvider.presets.oceanicTeal",
75
+ "Golden Hour ☀️": "themeProvider.presets.goldenHour",
76
+ "Deep Forest 🌲": "themeProvider.presets.deepForest",
77
+ };
78
+
69
79
  // ============================================================================
70
80
  // CONTEXT & PROVIDER
71
81
  // ============================================================================
@@ -145,6 +155,7 @@ export default function ITThemeProvider({
145
155
  shadow,
146
156
  appearance = "soft",
147
157
  }: ITThemeProviderProps) {
158
+ const { t } = useITTranslation();
148
159
  const [palette, setPaletteState] = useState<ITThemePalette>(() => {
149
160
  const basePalette = {
150
161
  ...DEFAULT_PALETTE,
@@ -1587,13 +1598,13 @@ export default function ITThemeProvider({
1587
1598
  handleDeletePreset(preset.name, e);
1588
1599
  }}
1589
1600
  className="absolute top-1.5 right-1.5 opacity-0 group-hover:opacity-100 p-0.5 rounded-md hover:bg-danger-500/10 hover:text-danger-500 text-slate-400 dark:text-slate-500 cursor-pointer transition-all z-10"
1590
- title="Eliminar"
1601
+ title={t("themeProvider.designer.deletePreset")}
1591
1602
  >
1592
1603
  <MdClose size={12} />
1593
1604
  </span>
1594
1605
  )}
1595
1606
  <ITText as="span" className="text-xs font-semibold truncate w-full mb-1.5 pr-4 text-slate-700 dark:text-slate-300">
1596
- {preset.name}
1607
+ {PRESET_I18N_KEY[preset.name] ? t(PRESET_I18N_KEY[preset.name]) : preset.name}
1597
1608
  </ITText>
1598
1609
  <div className="flex gap-1">
1599
1610
  {(["primary", "secondary", "ternary", "success"] as const).map((c) => (
@@ -1630,7 +1641,7 @@ export default function ITThemeProvider({
1630
1641
  onClick={() => setIsOpen((prev) => !prev)}
1631
1642
  className="it-theme-fab it-theme-bounce"
1632
1643
  style={{ backgroundColor: "var(--color-primary)" }}
1633
- aria-label="Configurar Paleta de Colores"
1644
+ aria-label={t("themeProvider.fab.ariaLabel")}
1634
1645
  >
1635
1646
  <MdPalette size={28} />
1636
1647
  </button>
@@ -1640,7 +1651,7 @@ export default function ITThemeProvider({
1640
1651
  <ITDialog
1641
1652
  isOpen={isOpen}
1642
1653
  onClose={() => setIsOpen(false)}
1643
- title="Diseñador de Temas"
1654
+ title={t("themeProvider.designer.title")}
1644
1655
  useFormHeader
1645
1656
  >
1646
1657
  <div className="flex gap-6 h-[580px]">
@@ -1648,7 +1659,7 @@ export default function ITThemeProvider({
1648
1659
  <div className="w-64 flex-shrink-0 flex flex-col gap-5 overflow-y-auto pr-1">
1649
1660
  <div>
1650
1661
  <ITText as="span" className="text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block">
1651
- Apariencia
1662
+ {t("themeProvider.designer.appearance")}
1652
1663
  </ITText>
1653
1664
  <ITSegmentedControl
1654
1665
  options={[
@@ -1665,7 +1676,7 @@ export default function ITThemeProvider({
1665
1676
  <div>
1666
1677
  <div className="flex items-center justify-between mb-2.5">
1667
1678
  <ITText as="span" className="text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500">
1668
- Presets
1679
+ {t("themeProvider.designer.presets")}
1669
1680
  </ITText>
1670
1681
  </div>
1671
1682
  <div className="grid grid-cols-2 gap-2">
@@ -1678,7 +1689,7 @@ export default function ITThemeProvider({
1678
1689
  {customPresets.length > 0 && (
1679
1690
  <div>
1680
1691
  <ITText as="span" className="text-[11px] font-bold uppercase tracking-wider text-slate-400 dark:text-slate-500 mb-2.5 block">
1681
- Mis Temas
1692
+ {t("themeProvider.designer.myThemes")}
1682
1693
  </ITText>
1683
1694
  <div className="flex flex-col gap-1.5">
1684
1695
  {customPresets.map((preset) => (
@@ -1693,7 +1704,7 @@ export default function ITThemeProvider({
1693
1704
  <div className="flex flex-col gap-2 p-3 rounded-xl border border-slate-200 dark:border-slate-700 bg-white dark:bg-slate-900/50">
1694
1705
  <ITInput
1695
1706
  name="presetName"
1696
- placeholder="Nombre del tema..."
1707
+ placeholder={t("themeProvider.designer.presetNamePlaceholder")}
1697
1708
  value={newPresetName}
1698
1709
  onChange={(e: any) => setNewPresetName(e.target.value)}
1699
1710
  containerClassName="mb-0"
@@ -1708,7 +1719,7 @@ export default function ITThemeProvider({
1708
1719
  />
1709
1720
  <div className="flex gap-2">
1710
1721
  <ITButton
1711
- label="Guardar"
1722
+ label={t("themeProvider.designer.save")}
1712
1723
  color="primary"
1713
1724
  onClick={handleSavePreset}
1714
1725
  disabled={!newPresetName.trim()}
@@ -1716,7 +1727,7 @@ export default function ITThemeProvider({
1716
1727
  className="flex-1"
1717
1728
  />
1718
1729
  <ITButton
1719
- label="X"
1730
+ label={t("themeProvider.designer.cancelSave")}
1720
1731
  variant="ghost"
1721
1732
  onClick={() => {
1722
1733
  setIsSavingPreset(false);
@@ -1732,7 +1743,7 @@ export default function ITThemeProvider({
1732
1743
  <ITButton
1733
1744
  variant="outlined"
1734
1745
  icon={<MdPalette size={14} />}
1735
- label="Guardar actual"
1746
+ label={t("themeProvider.designer.saveCurrent")}
1736
1747
  onClick={() => setIsSavingPreset(true)}
1737
1748
  size="sm"
1738
1749
  />
@@ -1742,7 +1753,7 @@ export default function ITThemeProvider({
1742
1753
  variant="outlined"
1743
1754
  color="danger"
1744
1755
  icon={<MdRefresh size={14} />}
1745
- label="Restaurar default"
1756
+ label={t("themeProvider.designer.reset")}
1746
1757
  onClick={resetTheme}
1747
1758
  size="sm"
1748
1759
  />
@@ -1757,7 +1768,7 @@ export default function ITThemeProvider({
1757
1768
  items={[
1758
1769
  {
1759
1770
  id: "brand",
1760
- label: "Marca",
1771
+ label: t("themeProvider.tabs.brand"),
1761
1772
  content: (
1762
1773
  <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3">
1763
1774
  {[
@@ -1777,7 +1788,7 @@ export default function ITThemeProvider({
1777
1788
  },
1778
1789
  {
1779
1790
  id: "layout",
1780
- label: "Nav & Sidebar",
1791
+ label: t("themeProvider.tabs.layout"),
1781
1792
  content: (
1782
1793
  <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3">
1783
1794
  {[
@@ -1793,7 +1804,7 @@ export default function ITThemeProvider({
1793
1804
  },
1794
1805
  {
1795
1806
  id: "tables",
1796
- label: "Tablas",
1807
+ label: t("themeProvider.tabs.tables"),
1797
1808
  content: (
1798
1809
  <div className="grid grid-cols-1 sm:grid-cols-2 gap-3 max-h-[480px] overflow-y-auto pr-2 mt-3">
1799
1810
  {[
@@ -1813,10 +1824,10 @@ export default function ITThemeProvider({
1813
1824
 
1814
1825
  <div className="flex items-center justify-end gap-3 mt-auto pt-4 border-t border-slate-100 dark:border-slate-800">
1815
1826
  <ITText as="p" className="text-[11px] text-slate-400 mr-auto">
1816
- Los cambios se guardan automáticamente
1827
+ {t("themeProvider.designer.autosave")}
1817
1828
  </ITText>
1818
1829
  <ITButton
1819
- label="Cerrar"
1830
+ label={t("themeProvider.designer.close")}
1820
1831
  color="primary"
1821
1832
  onClick={() => setIsOpen(false)}
1822
1833
  size="sm"
package/src/dev.css CHANGED
@@ -1,12 +1,70 @@
1
- @import "tailwindcss";
1
+ /* `index.css` ya importa Tailwind: importarlo otra vez aquí generaba una
2
+ segunda copia del tema por defecto (~154 KB) que, al emitirse después,
3
+ pisaba `--font-sans/--font-mono` y dejaba la hoja en las fuentes del sistema. */
2
4
  @import "./index.css";
3
5
 
6
+ /* ──────────────────────────────────────────────
7
+ DESIGN TOKENS — SANDBOX & PORTFOLIO (dev.css)
8
+ See DESIGN.md. Dev-only: never reach dist/index.css.
9
+ ────────────────────────────────────────────── */
10
+
11
+ /* La tipografía se declara DOS veces a propósito:
12
+ 1) en `@theme`, para que Tailwind genere las utilidades `font-sans/mono/display`;
13
+ 2) en un `:root` SIN CAPA, porque el tema por defecto de Tailwind vive en
14
+ `@layer theme` y, al emitirse después, pisaba estos valores (la hoja
15
+ acababa con las fuentes del sistema). El CSS sin capa gana a cualquier capa. */
16
+ @theme {
17
+ --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system,
18
+ "Segoe UI", sans-serif;
19
+ --font-display: "Bricolage Grotesque", "IBM Plex Sans", ui-sans-serif,
20
+ system-ui, sans-serif;
21
+ --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
22
+ }
23
+
24
+ :root {
25
+ --font-sans: "IBM Plex Sans", ui-sans-serif, system-ui, -apple-system,
26
+ "Segoe UI", sans-serif;
27
+ --font-display: "Bricolage Grotesque", "IBM Plex Sans", ui-sans-serif,
28
+ system-ui, sans-serif;
29
+ --font-mono: "JetBrains Mono", ui-monospace, SFMono-Regular, Menlo, monospace;
30
+ /* La prosa del sandbox sigue a `--font-sans` (preflight usa esta variable). */
31
+ --default-font-family: var(--font-sans);
32
+ }
33
+
4
34
  /* ──────────────────────────────────────────────
5
35
  SANDBOX-ONLY ANIMATIONS (dev.css)
6
36
  Never shipped: only src/main.tsx imports this file and `pnpm bundle`
7
37
  builds from src/index.ts, so these never reach dist/index.css.
8
38
  ────────────────────────────────────────────── */
9
39
 
40
+ /* Smooth in-page navigation for the portfolio anchors. */
41
+ html {
42
+ scroll-behavior: smooth;
43
+ }
44
+
45
+ @media (prefers-reduced-motion: reduce) {
46
+ html {
47
+ scroll-behavior: auto;
48
+ }
49
+ }
50
+
51
+ /* Staggered entrance: fade + translateY. `--it-delay` offsets each item. */
52
+ @keyframes it-reveal {
53
+ from {
54
+ opacity: 0;
55
+ transform: translateY(16px);
56
+ }
57
+ to {
58
+ opacity: 1;
59
+ transform: translateY(0);
60
+ }
61
+ }
62
+
63
+ .it-reveal {
64
+ animation: it-reveal 0.42s cubic-bezier(0.2, 0.8, 0.2, 1) both;
65
+ animation-delay: var(--it-delay, 0ms);
66
+ }
67
+
10
68
  @keyframes it-landing-rise {
11
69
  from {
12
70
  opacity: 0;
@@ -53,7 +111,8 @@
53
111
 
54
112
  @media (prefers-reduced-motion: reduce) {
55
113
  .it-landing-rise,
56
- .it-landing-float {
114
+ .it-landing-float,
115
+ .it-reveal {
57
116
  animation: none;
58
117
  }
59
118
  }
@@ -0,0 +1,10 @@
1
+ /**
2
+ * Constantes inyectadas por Vite en las superficies dev (`define` en
3
+ * `vite.config.ts` y `vite.app.config.ts`).
4
+ */
5
+
6
+ /**
7
+ * Versión de `package.json`, para no hardcodear el sello del sandbox (el badge
8
+ * decía `v1.3.0` cuando el paquete iba en 1.4.8).
9
+ */
10
+ declare const __APP_VERSION__: string;
@@ -0,0 +1,9 @@
1
+ import { createContext } from "react";
2
+ import { createI18n } from "./translator";
3
+ import type { ITI18nValue } from "./types";
4
+
5
+ /**
6
+ * Contexto de i18n. Su valor por defecto es un traductor en español (locale base),
7
+ * de modo que `useITTranslation()` funciona aunque no haya `ITI18nProvider`.
8
+ */
9
+ export const ITI18nContext = createContext<ITI18nValue>(createI18n());
@@ -0,0 +1,22 @@
1
+ export { default as ITI18nProvider } from "./provider";
2
+ export { useITTranslation } from "./useITTranslation";
3
+ export { ITI18nContext } from "./context";
4
+ export {
5
+ createI18n,
6
+ interpolate,
7
+ resolveMessages,
8
+ toDateLocale,
9
+ toIntlLocale,
10
+ baseCatalog,
11
+ DEFAULT_LOCALE,
12
+ } from "./translator";
13
+ export { default as esMessages } from "./locales/es";
14
+ export { default as enMessages } from "./locales/en";
15
+ export type {
16
+ ITLocale,
17
+ ITMessages,
18
+ ITMessagesByLocale,
19
+ ITI18nOptions,
20
+ ITI18nValue,
21
+ ITI18nProviderProps,
22
+ } from "./types";
@@ -0,0 +1,163 @@
1
+ import type { ITMessages } from "../types";
2
+
3
+ /**
4
+ * Catálogo base en inglés. Mantiene exactamente las mismas keys que `es.ts`
5
+ * (ver `docs/i18n/conventions.md`); si falta una key, se usa el texto en español.
6
+ */
7
+ const en: ITMessages = {
8
+ // ---------------------------------------------------------------- common
9
+ "common.loading": "Loading...",
10
+ "common.loadingOptions": "Loading options...",
11
+ "common.loadError": "Couldn't load",
12
+ "common.search": "Search...",
13
+ "common.clear": "Clear",
14
+ "common.clearSelection": "Clear selection",
15
+ "common.all": "All",
16
+ "common.true": "True",
17
+ "common.false": "False",
18
+ "common.back": "Back",
19
+ "common.next": "Next",
20
+ "common.finish": "Finish",
21
+ "common.accept": "OK",
22
+ "common.confirm": "Confirm",
23
+ "common.cancel": "Cancel",
24
+ "common.close": "Close",
25
+ "common.dismiss": "Dismiss",
26
+ "common.closeNotification": "Close notification",
27
+ "common.menu": "Menu",
28
+ "common.userAvatar": "Current user",
29
+ "common.retry": "Retry",
30
+ "common.error": "Error",
31
+ "common.noData": "No data",
32
+ "common.empty": "Nothing to show",
33
+ "common.noResults": "No results found",
34
+ "common.delete": "Delete",
35
+ "common.copy": "Copy",
36
+
37
+ // ------------------------------------------------------------- validation
38
+ "field.required": "This field is required",
39
+
40
+ // ------------------------------------------------------------------ atoms
41
+ "image.fallbackAlt": "Fallback",
42
+ "chip.remove": "Remove {label}",
43
+ "input.invalidFormat": "Invalid format",
44
+ "input.showPassword": "Show password",
45
+ "input.hidePassword": "Hide password",
46
+
47
+ // -------------------------------------------------------------- molecules
48
+ "card.imageAlt": "Card image",
49
+ "select.placeholder": "Select an option",
50
+ "select.noResults": "No results found",
51
+ "multiSelect.placeholder": "Select options",
52
+ "chipInput.placeholder": "Type and press Enter",
53
+ "chipInput.maxTags": "Maximum {count} tags",
54
+ "chipInput.duplicate": "Duplicate tag",
55
+ "dropdownMenu.open": "Open menu",
56
+ "lineBarChart.lineLabel": "Series A",
57
+ "lineBarChart.barLabel": "Series B",
58
+ "datePicker.invalid": "Invalid date",
59
+ "datePicker.placeholder": "dd/mm/yyyy",
60
+ "datePicker.rangePlaceholder": "dd/mm/yyyy - dd/mm/yyyy",
61
+ "calendar.today": "Today",
62
+ "timePicker.accept": "OK",
63
+ "timePicker.placeholder": "HH:MM",
64
+ "timePicker.invalid": "Invalid time",
65
+ "timePicker.hours": "Hours",
66
+ "timePicker.minutes": "Minutes",
67
+ "table.showAll": "Show all",
68
+ "table.filterTrue": "Filter true only",
69
+ "table.filterFalse": "Filter false only",
70
+ "table.sortBy": "Sort by {label}",
71
+ "table.filterToggle": "{action} for {label}",
72
+ "table.viewTable": "Table",
73
+ "table.viewCards": "Cards",
74
+ "table.noResults": "No results found",
75
+ "table.adjustFilters": "Try adjusting the filters",
76
+ "table.loading": "Loading data...",
77
+ "table.selectAll": "Select all",
78
+ "wysiwyg.bold": "Bold",
79
+ "wysiwyg.italic": "Italic",
80
+ "wysiwyg.underline": "Underline",
81
+ "wysiwyg.highlight": "Highlight",
82
+ "wysiwyg.bulletList": "Bulleted list",
83
+ "wysiwyg.numberedList": "Numbered list",
84
+ "wysiwyg.clearFormat": "Clear formatting",
85
+ "pagination.itemsPerPage": "Show",
86
+ "pagination.of": "of",
87
+ "breadcrumbs.aria": "Breadcrumb",
88
+ "pageHeader.back": "Back",
89
+ "pagination.showing": "Showing {from}-{to} of {total}",
90
+ "pagination.page": "Page {page}",
91
+ "pagination.aria": "Pagination",
92
+ "pagination.previous": "Previous page",
93
+ "pagination.next": "Next page",
94
+ "stepper.stepOf": "Step {current} of {total}",
95
+ "stepper.stepAria": "Step {n} {label}",
96
+
97
+ // -------------------------------------------------------------- organisms
98
+ "confirmDialog.title": "Confirm action",
99
+ "confirmDialog.message": "Are you sure you want to continue?",
100
+ "dropfile.upload": "Upload file",
101
+ "dropfile.status.pending": "Pending",
102
+ "dropfile.status.uploading": "Uploading...",
103
+ "dropfile.status.uploaded": "Uploaded",
104
+ "dropfile.status.error": "Error",
105
+ "dropfile.dropHere": "Drop here!",
106
+ "dropfile.clickOrDrag": "Click or drag",
107
+ "dropfile.imageLoaded": "Image loaded",
108
+ "dropfile.noPreview": "No preview",
109
+ "dropfile.previewAlt": "Preview",
110
+ "dropfile.fileTypeNotAllowed": "File type not allowed.",
111
+ "dropfile.fileLoaded": "File uploaded",
112
+ "sidebar.notifications": "Notifications",
113
+ "sidebar.navAria": "Library components",
114
+ "sidebar.noSubmenu": "No submenu",
115
+ // ---------------------------------------------------------------- sandbox
116
+ "searchTable.searchPlaceholder": "Search all fields...",
117
+ "searchTable.showing": "Showing {from}-{to} of {total} results",
118
+ "searchTable.emptySearch": "No results for your search",
119
+ "searchTable.empty": "No results found",
120
+ "searchTable.showLabel": "Show:",
121
+ "searchTable.pageOf": "Page {current} of {total}",
122
+ "searchTable.prev": "Previous page",
123
+ "searchTable.next": "Next page",
124
+ "searchTable.sort": "Sort",
125
+ "searchTable.sortAsc": "Asc ↑",
126
+ "searchTable.sortDesc": "Desc ↓",
127
+ "searchTable.clearSearch": "Clear search",
128
+ "searchTable.showingCount": "Showing {from} of {total} results",
129
+ "searchTable.sortTable": "Sort table",
130
+ "searchTable.sortAria": "Sort table {direction}",
131
+ "searchTable.sortAscending": "ascending",
132
+ "searchTable.sortDescending": "descending",
133
+ "formBuilder.arrayField": "Array field: {label}",
134
+ "formBuilder.loadingOptions": "Loading options...",
135
+
136
+ // -------------------------------------------------------- theme provider
137
+ "themeProvider.fab.ariaLabel": "Configure Color Palette",
138
+ "themeProvider.designer.title": "Theme Designer",
139
+ "themeProvider.designer.appearance": "Appearance",
140
+ "themeProvider.designer.presets": "Presets",
141
+ "themeProvider.designer.myThemes": "My Themes",
142
+ "themeProvider.designer.presetNamePlaceholder": "Theme name...",
143
+ "themeProvider.designer.save": "Save",
144
+ "themeProvider.designer.cancelSave": "X",
145
+ "themeProvider.designer.saveCurrent": "Save current",
146
+ "themeProvider.designer.reset": "Reset to default",
147
+ "themeProvider.designer.autosave": "Changes are saved automatically",
148
+ "themeProvider.designer.close": "Close",
149
+ "themeProvider.designer.deletePreset": "Delete",
150
+ "themeProvider.tabs.brand": "Brand",
151
+ "themeProvider.tabs.layout": "Nav & Sidebar",
152
+ "themeProvider.tabs.tables": "Tables",
153
+ "themeProvider.mode.light": "Light",
154
+ "themeProvider.mode.dark": "Dark",
155
+ "themeProvider.mode.system": "System",
156
+ "themeProvider.presets.midnightIndigo": "Midnight Indigo 🌌",
157
+ "themeProvider.presets.coralReef": "Coral Reef 🪸",
158
+ "themeProvider.presets.oceanicTeal": "Oceanic Teal 🌊",
159
+ "themeProvider.presets.goldenHour": "Golden Hour ☀️",
160
+ "themeProvider.presets.deepForest": "Deep Forest 🌲",
161
+ };
162
+
163
+ export default en;