@axzydev/axzy_ui_system 1.2.1 → 1.2.3

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 (207) hide show
  1. package/dist/index.cjs +1 -1
  2. package/dist/index.cjs.map +1 -1
  3. package/dist/index.css +82 -1
  4. package/dist/index.css.map +1 -1
  5. package/dist/index.js +1 -1
  6. package/dist/index.js.map +1 -1
  7. package/package.json +2 -2
  8. package/src/App.tsx +354 -0
  9. package/src/assets/logo.png +0 -0
  10. package/src/assets/react.svg +1 -0
  11. package/src/components/alert/alert.props.ts +13 -0
  12. package/src/components/alert/alert.stories.tsx +41 -0
  13. package/src/components/alert/alert.tsx +53 -0
  14. package/src/components/avatar/avatar.props.ts +14 -0
  15. package/src/components/avatar/avatar.stories.tsx +46 -0
  16. package/src/components/avatar/avatar.tsx +53 -0
  17. package/src/components/badget/badget.props.ts +12 -0
  18. package/src/components/badget/badget.stories.tsx +76 -0
  19. package/src/components/badget/badget.tsx +61 -0
  20. package/src/components/breadcrumbs/breadcrumbs.props.ts +13 -0
  21. package/src/components/breadcrumbs/breadcrumbs.stories.tsx +21 -0
  22. package/src/components/breadcrumbs/breadcrumbs.tsx +34 -0
  23. package/src/components/button/button.props.ts +18 -0
  24. package/src/components/button/button.stories.tsx +174 -0
  25. package/src/components/button/button.tsx +117 -0
  26. package/src/components/calendar/calendar.props.ts +33 -0
  27. package/src/components/calendar/calendar.stories.tsx +91 -0
  28. package/src/components/calendar/calendar.tsx +608 -0
  29. package/src/components/calendar/index.ts +3 -0
  30. package/src/components/card/card.props.ts +13 -0
  31. package/src/components/card/card.stories.tsx +58 -0
  32. package/src/components/card/card.tsx +79 -0
  33. package/src/components/checkbox/checkbox.props.ts +11 -0
  34. package/src/components/checkbox/checkbox.stories.tsx +54 -0
  35. package/src/components/checkbox/checkbox.tsx +52 -0
  36. package/src/components/confirm-dialog/confirm-dialog.props.ts +14 -0
  37. package/src/components/confirm-dialog/confirm-dialog.stories.tsx +33 -0
  38. package/src/components/confirm-dialog/confirm-dialog.tsx +45 -0
  39. package/src/components/data-table/ITDataTable.stories.tsx +213 -0
  40. package/src/components/data-table/dataTable.props.ts +69 -0
  41. package/src/components/data-table/dataTable.tsx +313 -0
  42. package/src/components/date-picker/date-picker.props.ts +30 -0
  43. package/src/components/date-picker/date-picker.stories.tsx +90 -0
  44. package/src/components/date-picker/datePicker.tsx +307 -0
  45. package/src/components/dialog/dialog.props.ts +9 -0
  46. package/src/components/dialog/dialog.stories.tsx +80 -0
  47. package/src/components/dialog/dialog.tsx +88 -0
  48. package/src/components/divider/divider.props.ts +8 -0
  49. package/src/components/divider/divider.stories.tsx +34 -0
  50. package/src/components/divider/divider.tsx +21 -0
  51. package/src/components/drawer/drawer.props.ts +14 -0
  52. package/src/components/drawer/drawer.stories.tsx +41 -0
  53. package/src/components/drawer/drawer.tsx +53 -0
  54. package/src/components/dropfile/dropfile.stories.tsx +75 -0
  55. package/src/components/dropfile/dropfile.tsx +407 -0
  56. package/src/components/empty-state/empty-state.props.ts +9 -0
  57. package/src/components/empty-state/empty-state.stories.tsx +20 -0
  58. package/src/components/empty-state/empty-state.tsx +21 -0
  59. package/src/components/flex/flex.props.ts +22 -0
  60. package/src/components/flex/flex.stories.tsx +71 -0
  61. package/src/components/flex/flex.tsx +79 -0
  62. package/src/components/form-builder/fieldRenderer.tsx +218 -0
  63. package/src/components/form-builder/formBuilder.context.tsx +70 -0
  64. package/src/components/form-builder/formBuilder.props.ts +43 -0
  65. package/src/components/form-builder/formBuilder.stories.tsx +317 -0
  66. package/src/components/form-builder/formBuilder.tsx +186 -0
  67. package/src/components/form-builder/useFormBuilder.ts +80 -0
  68. package/src/components/form-header/form-header.props.ts +5 -0
  69. package/src/components/form-header/form-header.tsx +38 -0
  70. package/src/components/grid/grid.props.ts +17 -0
  71. package/src/components/grid/grid.stories.tsx +72 -0
  72. package/src/components/grid/grid.tsx +69 -0
  73. package/src/components/image/image.props.ts +7 -0
  74. package/src/components/image/image.tsx +38 -0
  75. package/src/components/input/input.props.ts +49 -0
  76. package/src/components/input/input.stories.tsx +115 -0
  77. package/src/components/input/input.tsx +615 -0
  78. package/src/components/layout/layout.props.ts +10 -0
  79. package/src/components/layout/layout.stories.tsx +114 -0
  80. package/src/components/layout/layout.tsx +80 -0
  81. package/src/components/loader/loader.props.ts +8 -0
  82. package/src/components/loader/loader.stories.tsx +105 -0
  83. package/src/components/loader/loader.tsx +108 -0
  84. package/src/components/navbar/navbar.props.ts +37 -0
  85. package/src/components/navbar/navbar.tsx +328 -0
  86. package/src/components/page/page.props.ts +19 -0
  87. package/src/components/page/page.stories.tsx +98 -0
  88. package/src/components/page/page.tsx +90 -0
  89. package/src/components/page-header/page-header.props.ts +11 -0
  90. package/src/components/page-header/page-header.stories.tsx +61 -0
  91. package/src/components/page-header/page-header.tsx +62 -0
  92. package/src/components/pagination/pagination.props.ts +53 -0
  93. package/src/components/pagination/pagination.stories.tsx +111 -0
  94. package/src/components/pagination/pagination.tsx +241 -0
  95. package/src/components/popover/popover.props.ts +12 -0
  96. package/src/components/popover/popover.stories.tsx +25 -0
  97. package/src/components/popover/popover.tsx +45 -0
  98. package/src/components/progress/progress.props.ts +12 -0
  99. package/src/components/progress/progress.stories.tsx +40 -0
  100. package/src/components/progress/progress.tsx +52 -0
  101. package/src/components/radio/radio.props.ts +16 -0
  102. package/src/components/radio/radio.stories.tsx +50 -0
  103. package/src/components/radio/radio.tsx +58 -0
  104. package/src/components/search-select/index.ts +2 -0
  105. package/src/components/search-select/search-select.props.ts +46 -0
  106. package/src/components/search-select/search-select.stories.tsx +129 -0
  107. package/src/components/search-select/search-select.tsx +229 -0
  108. package/src/components/searchTable/components/EditableCell.tsx +149 -0
  109. package/src/components/searchTable/components/PaginationControls.tsx +86 -0
  110. package/src/components/searchTable/components/PaginationInfo.tsx +20 -0
  111. package/src/components/searchTable/components/SearchAndSortBar.tsx +53 -0
  112. package/src/components/searchTable/components/SearchInput.tsx +33 -0
  113. package/src/components/searchTable/components/SortButton.tsx +50 -0
  114. package/src/components/searchTable/components/TableEmptyState.tsx +22 -0
  115. package/src/components/searchTable/components/TableHeader.tsx +35 -0
  116. package/src/components/searchTable/components/TableHeaderCell.tsx +43 -0
  117. package/src/components/searchTable/components/TableRow.tsx +144 -0
  118. package/src/components/searchTable/searchTable.props.ts +56 -0
  119. package/src/components/searchTable/searchTable.tsx +187 -0
  120. package/src/components/segmented-control/segmented-control.props.ts +18 -0
  121. package/src/components/segmented-control/segmented-control.stories.tsx +63 -0
  122. package/src/components/segmented-control/segmented-control.tsx +52 -0
  123. package/src/components/select/select.props.ts +25 -0
  124. package/src/components/select/select.stories.tsx +86 -0
  125. package/src/components/select/select.tsx +150 -0
  126. package/src/components/sidebar/sidebar.props.ts +28 -0
  127. package/src/components/sidebar/sidebar.stories.tsx +117 -0
  128. package/src/components/sidebar/sidebar.tsx +313 -0
  129. package/src/components/skeleton/skeleton.props.ts +12 -0
  130. package/src/components/skeleton/skeleton.stories.tsx +30 -0
  131. package/src/components/skeleton/skeleton.tsx +45 -0
  132. package/src/components/slide/slide.props.ts +45 -0
  133. package/src/components/slide/slide.stories.tsx +121 -0
  134. package/src/components/slide/slide.tsx +109 -0
  135. package/src/components/slider/slider.props.ts +10 -0
  136. package/src/components/slider/slider.stories.tsx +30 -0
  137. package/src/components/slider/slider.tsx +49 -0
  138. package/src/components/stack/stack.props.ts +19 -0
  139. package/src/components/stack/stack.stories.tsx +79 -0
  140. package/src/components/stack/stack.tsx +79 -0
  141. package/src/components/stat-card/stat-card.props.ts +13 -0
  142. package/src/components/stat-card/stat-card.stories.tsx +41 -0
  143. package/src/components/stat-card/stat-card.tsx +44 -0
  144. package/src/components/stepper/stepper.css +26 -0
  145. package/src/components/stepper/stepper.props.ts +29 -0
  146. package/src/components/stepper/stepper.stories.tsx +155 -0
  147. package/src/components/stepper/stepper.tsx +227 -0
  148. package/src/components/table/table.props.ts +43 -0
  149. package/src/components/table/table.stories.tsx +189 -0
  150. package/src/components/table/table.tsx +376 -0
  151. package/src/components/tabs/tabs.props.ts +18 -0
  152. package/src/components/tabs/tabs.stories.tsx +32 -0
  153. package/src/components/tabs/tabs.tsx +74 -0
  154. package/src/components/text/text.props.ts +9 -0
  155. package/src/components/text/text.tsx +20 -0
  156. package/src/components/textarea/textarea.props.ts +15 -0
  157. package/src/components/textarea/textarea.stories.tsx +27 -0
  158. package/src/components/textarea/textarea.tsx +55 -0
  159. package/src/components/theme-provider/themeProvider.props.ts +28 -0
  160. package/src/components/theme-provider/themeProvider.tsx +1854 -0
  161. package/src/components/time-picker/timePicker.props.ts +16 -0
  162. package/src/components/time-picker/timePicker.stories.tsx +131 -0
  163. package/src/components/time-picker/timePicker.tsx +317 -0
  164. package/src/components/toast/toast.css +32 -0
  165. package/src/components/toast/toast.props.ts +13 -0
  166. package/src/components/toast/toast.stories.tsx +138 -0
  167. package/src/components/toast/toast.tsx +87 -0
  168. package/src/components/tooltip/tooltip.props.ts +11 -0
  169. package/src/components/tooltip/tooltip.stories.tsx +20 -0
  170. package/src/components/tooltip/tooltip.tsx +55 -0
  171. package/src/components/topbar/topbar.props.ts +21 -0
  172. package/src/components/topbar/topbar.stories.tsx +80 -0
  173. package/src/components/topbar/topbar.tsx +205 -0
  174. package/src/components/triple-filter/tripleFilter.props.ts +15 -0
  175. package/src/components/triple-filter/tripleFilter.stories.tsx +32 -0
  176. package/src/components/triple-filter/tripleFilter.tsx +50 -0
  177. package/src/dev.css +2 -0
  178. package/src/hooks/useClickOutside.ts +21 -0
  179. package/src/hooks/useDebouncedSearch.ts +55 -0
  180. package/src/hooks/useEditableRow.ts +157 -0
  181. package/src/hooks/useTableState.ts +122 -0
  182. package/src/index.css +168 -0
  183. package/src/index.ts +165 -0
  184. package/src/main.tsx +9 -0
  185. package/src/showcases/DataShowcases.tsx +260 -0
  186. package/src/showcases/FeedbackShowcases.tsx +268 -0
  187. package/src/showcases/FormShowcases.tsx +1159 -0
  188. package/src/showcases/HomeShowcase.tsx +324 -0
  189. package/src/showcases/LayoutPrimitivesShowcases.tsx +569 -0
  190. package/src/showcases/NavigationShowcases.tsx +193 -0
  191. package/src/showcases/PageShowcases.tsx +207 -0
  192. package/src/showcases/ShowcaseLayout.tsx +139 -0
  193. package/src/showcases/StructureShowcases.tsx +152 -0
  194. package/src/types/badget.types.ts +37 -0
  195. package/src/types/button.types.ts +16 -0
  196. package/src/types/colors.types.ts +3 -0
  197. package/src/types/field.types.ts +103 -0
  198. package/src/types/formik.types.ts +15 -0
  199. package/src/types/input.types.ts +14 -0
  200. package/src/types/loader.types.ts +9 -0
  201. package/src/types/sizes.types.ts +1 -0
  202. package/src/types/table.types.ts +15 -0
  203. package/src/types/toast.types.ts +8 -0
  204. package/src/types/yup.types.ts +11 -0
  205. package/src/utils/color.utils.ts +99 -0
  206. package/src/utils/styles.ts +120 -0
  207. package/src/utils/table.utils.ts +10 -0
@@ -0,0 +1,193 @@
1
+ import React, { useState } from "react";
2
+ import { FaInfoCircle, FaSlidersH, FaRegBell, FaSync } from "react-icons/fa";
3
+ import {
4
+ ITTabs,
5
+ ITStepper,
6
+ ITPagination,
7
+ ITTripleFilter,
8
+ ITSelect,
9
+ ITSlideToggle
10
+ } from "../index";
11
+ import { ShowcaseLayout } from "./ShowcaseLayout";
12
+
13
+ // 1. ITTabs Showcase
14
+ export const TabsShowcase = () => {
15
+ const [variant, setVariant] = useState<any>("line");
16
+
17
+ const tabItems = [
18
+ {
19
+ id: "tab1",
20
+ label: "General",
21
+ icon: <FaInfoCircle />,
22
+ content: <div className="p-4 text-sm text-slate-600 dark:text-slate-300">Configuración global y perfil general de la cuenta.</div>
23
+ },
24
+ {
25
+ id: "tab2",
26
+ label: "Seguridad",
27
+ icon: <FaSlidersH />,
28
+ content: <div className="p-4 text-sm text-slate-600 dark:text-slate-300">Ajustes de credenciales, MFA y logs de accesos.</div>
29
+ },
30
+ {
31
+ id: "tab3",
32
+ label: "Notificaciones",
33
+ icon: <FaRegBell />,
34
+ content: <div className="p-4 text-sm text-slate-600 dark:text-slate-300">Preferencias de alertas vía email, SMS y notificaciones PUSH.</div>
35
+ }
36
+ ];
37
+
38
+ const code = `<ITTabs\n variant="${variant}"\n items={[\n { id: 'tab1', label: 'General', content: <General /> }\n ]}\n/>`;
39
+
40
+ return (
41
+ <ShowcaseLayout
42
+ title="ITTabs"
43
+ description="Separadores de contenido en pestañas integrables con íconos y transiciones."
44
+ code={code}
45
+ demo={
46
+ <div className="w-full bg-white dark:bg-slate-900 border rounded-2xl p-6 shadow-sm min-h-[160px]">
47
+ <ITTabs items={tabItems} defaultActiveId="tab1" variant={variant} />
48
+ </div>
49
+ }
50
+ controls={
51
+ <>
52
+ <ITSelect
53
+ name="var_ctrl"
54
+ label="Variante Estética"
55
+ value={variant}
56
+ onChange={(e: any) => setVariant(e.target.value)}
57
+ options={[
58
+ { label: "Línea (Line)", value: "line" },
59
+ { label: "Pastilla (Pill)", value: "pill" }
60
+ ]}
61
+ />
62
+ </>
63
+ }
64
+ />
65
+ );
66
+ };
67
+
68
+ // 2. ITStepper Showcase
69
+ export const StepperShowcase = () => {
70
+ const [step, setStep] = useState(0);
71
+ const [useIcons, setUseIcons] = useState(true);
72
+
73
+ const steps = [
74
+ { label: "Validar Identidad", content: <div className="p-6">Paso 1: Sube tu documento de identidad oficial.</div> },
75
+ { label: "Cargar KYC", content: <div className="p-6">Paso 2: Rellena tus datos fiscales y origen de fondos.</div> },
76
+ { label: "Completar Firma", content: <div className="p-6">Paso 3: Realiza la firma biométrica digital.</div> }
77
+ ];
78
+
79
+ const code = `<ITStepper\n steps={steps}\n currentStep={${step}}\n useIcons={${useIcons}}\n onStepChange={(idx) => setStep(idx)}\n/>`;
80
+
81
+ return (
82
+ <ShowcaseLayout
83
+ title="ITStepper"
84
+ description="Barra e indicador secuencial de pasos para completar procesos guiados complejos."
85
+ code={code}
86
+ demo={
87
+ <div className="w-full">
88
+ <ITStepper
89
+ steps={steps}
90
+ currentStep={step}
91
+ useIcons={useIcons}
92
+ onStepChange={setStep}
93
+ onFinish={() => alert("Proceso completado exitosamente!")}
94
+ />
95
+ </div>
96
+ }
97
+ controls={
98
+ <>
99
+ <div className="flex items-center justify-between pt-2">
100
+ <span className="text-sm font-semibold text-gray-700">Usar íconos</span>
101
+ <ITSlideToggle isOn={useIcons} onToggle={setUseIcons} size="sm" />
102
+ </div>
103
+ <div className="flex justify-between items-center pt-2">
104
+ <span className="text-sm font-semibold text-gray-700">Reiniciar Paso</span>
105
+ <button onClick={() => setStep(0)} className="p-2 bg-slate-100 rounded-lg hover:bg-slate-200 text-slate-800">
106
+ <FaSync size={12} />
107
+ </button>
108
+ </div>
109
+ </>
110
+ }
111
+ />
112
+ );
113
+ };
114
+
115
+ // 3. ITPagination Showcase
116
+ export const PaginationShowcase = () => {
117
+ const [page, setPage] = useState(1);
118
+ const [color, setColor] = useState<any>("primary");
119
+
120
+ const code = `<ITPagination\n currentPage={${page}}\n totalPages={10}\n onPageChange={(p) => setPage(p)}\n color="${color}"\n/>`;
121
+
122
+ return (
123
+ <ShowcaseLayout
124
+ title="ITPagination"
125
+ description="Controlador de navegación de páginas numeradas con botones de dirección rápida."
126
+ code={code}
127
+ demo={
128
+ <div className="flex flex-col items-center gap-3">
129
+ <ITPagination
130
+ currentPage={page}
131
+ totalPages={10}
132
+ onPageChange={setPage}
133
+ color={color}
134
+ />
135
+ <span className="text-xs font-mono text-slate-500">Página actual activa: {page} de 10</span>
136
+ </div>
137
+ }
138
+ controls={
139
+ <>
140
+ <ITSelect
141
+ name="col_ctrl"
142
+ label="Color del Botón Activo"
143
+ value={color}
144
+ onChange={(e: any) => setColor(e.target.value)}
145
+ options={[
146
+ { label: "Primary", value: "primary" },
147
+ { label: "Secondary", value: "secondary" },
148
+ { label: "Success", value: "success" },
149
+ { label: "Danger", value: "danger" },
150
+ { label: "Warning", value: "warning" },
151
+ { label: "Info", value: "info" },
152
+ { label: "Purple", value: "purple" }
153
+ ]}
154
+ />
155
+ </>
156
+ }
157
+ />
158
+ );
159
+ };
160
+
161
+ // 4. ITTripleFilter Showcase
162
+ export const TripleFilterShowcase = () => {
163
+ const [filter, setFilter] = useState("all");
164
+
165
+ const code = `<ITTripleFilter\n value="${filter}"\n onChange={(val) => setFilter(String(val))}\n options={[\n { label: 'Todos', value: 'all' },\n { label: 'Activos', value: 'active' },\n { label: 'Inactivos', value: 'inactive' }\n ]}\n/>`;
166
+
167
+ return (
168
+ <ShowcaseLayout
169
+ title="ITTripleFilter"
170
+ description="Selector segmentado rápido diseñado típicamente para filtros rápidos de 3 estados."
171
+ code={code}
172
+ demo={
173
+ <div className="flex flex-col items-center gap-4">
174
+ <ITTripleFilter
175
+ value={filter}
176
+ onChange={(val) => setFilter(String(val))}
177
+ options={[
178
+ { label: "Todos", value: "all" },
179
+ { label: "Activos", value: "active" },
180
+ { label: "Inactivos", value: "inactive" }
181
+ ]}
182
+ />
183
+ <p className="text-xs text-slate-500 font-mono">Filtro activo: "{filter}"</p>
184
+ </div>
185
+ }
186
+ controls={
187
+ <div className="p-2 bg-slate-50 dark:bg-slate-900 rounded-lg text-xs">
188
+ <p className="text-slate-500">Proporciona un layout de tipo segmentado con animación al cambiar entre las opciones disponibles.</p>
189
+ </div>
190
+ }
191
+ />
192
+ );
193
+ };
@@ -0,0 +1,207 @@
1
+ import { useState } from "react";
2
+ import ITPage from "../components/page/page";
3
+ import ITPageHeader from "../components/page-header/page-header";
4
+ import ITButton from "../components/button/button";
5
+ import ITCard from "../components/card/card";
6
+ import ITStack from "../components/stack/stack";
7
+ import ITGrid from "../components/grid/grid";
8
+ import ITStatCard from "../components/stat-card/stat-card";
9
+ import ITFlex from "../components/flex/flex";
10
+ import ITAvatar from "../components/avatar/avatar";
11
+ import ITSlideToggle from "../components/slide/slide";
12
+ import { ShowcaseLayout } from "./ShowcaseLayout";
13
+
14
+ export const PageHeaderShowcase = () => {
15
+ const [showBack, setShowBack] = useState(true);
16
+ const [showBreadcrumbs, setShowBreadcrumbs] = useState(true);
17
+ const [showDescription, setShowDescription] = useState(true);
18
+ const [showActions, setShowActions] = useState(true);
19
+
20
+ const code = `<ITPageHeader
21
+ title="Usuarios"
22
+ description="Gestiona los usuarios del sistema"
23
+ breadcrumbs={[
24
+ { label: "Inicio", href: "#" },
25
+ { label: "Usuarios" },
26
+ ]}
27
+ actions={<ITButton label="Nuevo" size="small" />}
28
+ />`;
29
+
30
+ return (
31
+ <ShowcaseLayout
32
+ title="ITPageHeader"
33
+ description="Encabezado estandarizado para pantallas. Incluye título, descripción, breadcrumbs, botón de volver y área de acciones."
34
+ code={code}
35
+ demo={
36
+ <div className="w-full border border-slate-200 dark:border-slate-700 rounded-xl p-6 bg-white dark:bg-slate-900/50">
37
+ <ITPageHeader
38
+ title="Usuarios"
39
+ description={showDescription ? "Gestiona los usuarios del sistema" : undefined}
40
+ breadcrumbs={showBreadcrumbs ? [
41
+ { label: "Inicio", href: "#" },
42
+ { label: "Usuarios" },
43
+ ] : undefined}
44
+ backAction={showBack ? () => {} : undefined}
45
+ actions={showActions ? <ITButton label="Nuevo Usuario" size="small" /> : undefined}
46
+ />
47
+ </div>
48
+ }
49
+ controls={
50
+ <ITStack spacing={4}>
51
+ <ITFlex justify="between" align="center">
52
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Volver</span>
53
+ <ITSlideToggle isOn={showBack} onToggle={setShowBack} size="sm" />
54
+ </ITFlex>
55
+ <ITFlex justify="between" align="center">
56
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Breadcrumbs</span>
57
+ <ITSlideToggle isOn={showBreadcrumbs} onToggle={setShowBreadcrumbs} size="sm" />
58
+ </ITFlex>
59
+ <ITFlex justify="between" align="center">
60
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Descripción</span>
61
+ <ITSlideToggle isOn={showDescription} onToggle={setShowDescription} size="sm" />
62
+ </ITFlex>
63
+ <ITFlex justify="between" align="center">
64
+ <span className="text-sm font-semibold text-slate-700 dark:text-slate-300">Acciones</span>
65
+ <ITSlideToggle isOn={showActions} onToggle={setShowActions} size="sm" />
66
+ </ITFlex>
67
+ </ITStack>
68
+ }
69
+ gallery={
70
+ <ITStack spacing={4}>
71
+ <div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
72
+ <ITPageHeader title="Solo título" />
73
+ </div>
74
+ <div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
75
+ <ITPageHeader
76
+ title="Dashboard"
77
+ description="Resumen de métricas del sistema"
78
+ />
79
+ </div>
80
+ <div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
81
+ <ITPageHeader
82
+ title="Órdenes"
83
+ description="Listado de órdenes activas"
84
+ breadcrumbs={[
85
+ { label: "Dashboard", href: "#" },
86
+ { label: "Órdenes" },
87
+ ]}
88
+ actions={
89
+ <>
90
+ <ITButton label="Exportar" variant="outlined" size="small" />
91
+ <ITButton label="Nueva" size="small" />
92
+ </>
93
+ }
94
+ />
95
+ </div>
96
+ <div className="border border-slate-200 dark:border-slate-700 rounded-xl p-4 bg-white dark:bg-slate-900/50">
97
+ <ITPageHeader
98
+ title="Editar Producto"
99
+ description="Modifica los datos del producto"
100
+ breadcrumbs={[
101
+ { label: "Productos", href: "#" },
102
+ { label: "Editar" },
103
+ ]}
104
+ backAction={() => {}}
105
+ actions={
106
+ <>
107
+ <ITButton label="Cancelar" variant="outlined" size="small" />
108
+ <ITButton label="Guardar" size="small" />
109
+ </>
110
+ }
111
+ />
112
+ </div>
113
+ </ITStack>
114
+ }
115
+ />
116
+ );
117
+ };
118
+
119
+ export const PageShowcase = () => {
120
+ const [state, setState] = useState<"normal" | "loading" | "error" | "empty">("normal");
121
+
122
+ const code = `<ITPage
123
+ title="Dashboard"
124
+ description="Resumen de actividad"
125
+ breadcrumbs={[{ label: "Dashboard" }]}
126
+ loading={isLoading}
127
+ error={error}
128
+ onRetry={refetch}
129
+ >
130
+ <ITGrid container spacing={3}>
131
+ <ITGrid item xs={12} sm={6} lg={3}>
132
+ <ITStatCard label="Usuarios" value="1,245" />
133
+ </ITGrid>
134
+ </ITGrid>
135
+ </ITPage>`;
136
+
137
+ return (
138
+ <ShowcaseLayout
139
+ title="ITPage"
140
+ description="Template completo de página con estados: carga, error, vacío y contenido normal."
141
+ code={code}
142
+ demo={
143
+ <div className="w-full">
144
+ <ITPage
145
+ title="Dashboard"
146
+ description="Resumen de actividad del sistema"
147
+ breadcrumbs={[
148
+ { label: "Dashboard" },
149
+ ]}
150
+ loading={state === "loading"}
151
+ error={state === "error" ? "Error al cargar los datos. Verifica tu conexión." : null}
152
+ onRetry={() => setState("normal")}
153
+ empty={state === "empty"}
154
+ emptyTitle="Sin datos disponibles"
155
+ emptyDescription="No hay actividad reciente para mostrar."
156
+ >
157
+ <ITGrid container spacing={3}>
158
+ <ITGrid item xs={12} sm={6} lg={3}>
159
+ <ITStatCard label="Usuarios Activos" value="1,245" trend="+12%" trendDirection="up" />
160
+ </ITGrid>
161
+ <ITGrid item xs={12} sm={6} lg={3}>
162
+ <ITStatCard label="Ventas Hoy" value="$4,320" trend="+5.4%" trendDirection="up" color="bg-blue-50 dark:bg-blue-950/20" />
163
+ </ITGrid>
164
+ <ITGrid item xs={12} sm={6} lg={3}>
165
+ <ITStatCard label="Órdenes" value="89" trend="-2.1%" trendDirection="down" color="bg-amber-50 dark:bg-amber-950/20" />
166
+ </ITGrid>
167
+ <ITGrid item xs={12} sm={6} lg={3}>
168
+ <ITStatCard label="Tickets" value="12" trend="-8%" trendDirection="down" color="bg-rose-50 dark:bg-rose-950/20" />
169
+ </ITGrid>
170
+ </ITGrid>
171
+
172
+ <ITCard title="Actividad Reciente">
173
+ <ITStack spacing={3}>
174
+ {[
175
+ { user: "Ana López", action: "creó un reporte" },
176
+ { user: "Carlos Ruiz", action: "aprobó orden #1234" },
177
+ { user: "María García", action: "actualizó perfil" },
178
+ ].map((item, i) => (
179
+ <ITFlex key={i} gap={3} align="center">
180
+ <ITAvatar initials={item.user.split(" ").map(w => w[0]).join("")} size="sm" color="bg-primary-500" />
181
+ <div className="flex-1 min-w-0">
182
+ <p className="text-xs font-semibold text-slate-700 dark:text-slate-200">{item.user}</p>
183
+ <p className="text-[10px] text-slate-400">{item.action}</p>
184
+ </div>
185
+ </ITFlex>
186
+ ))}
187
+ </ITStack>
188
+ </ITCard>
189
+ </ITPage>
190
+ </div>
191
+ }
192
+ controls={
193
+ <ITFlex gap={2} wrap="wrap">
194
+ {(["normal", "loading", "error", "empty"] as const).map((s) => (
195
+ <ITButton
196
+ key={s}
197
+ label={s.charAt(0).toUpperCase() + s.slice(1)}
198
+ variant={state === s ? "filled" : "outlined"}
199
+ size="small"
200
+ onClick={() => setState(s)}
201
+ />
202
+ ))}
203
+ </ITFlex>
204
+ }
205
+ />
206
+ );
207
+ };
@@ -0,0 +1,139 @@
1
+ import React, { useState } from "react";
2
+ import { FaCheck, FaCopy } from "react-icons/fa";
3
+ import ITCard from "../components/card/card";
4
+ import { useITTheme } from "../components/theme-provider/themeProvider";
5
+
6
+ export const CodeViewer: React.FC<{ code: string }> = ({ code }) => {
7
+ const [copied, setCopied] = useState(false);
8
+ const handleCopy = () => {
9
+ navigator.clipboard.writeText(code);
10
+ setCopied(true);
11
+ setTimeout(() => setCopied(false), 2000);
12
+ };
13
+ return (
14
+ <div className="relative mt-4 rounded-xl overflow-hidden bg-slate-950 text-slate-200 border border-slate-800 shadow-inner">
15
+ <div className="flex justify-between items-center px-4 py-2 bg-slate-900 border-b border-slate-800">
16
+ <span className="text-[10px] uppercase font-bold tracking-wider text-slate-400 font-mono">JSX Code</span>
17
+ <button
18
+ onClick={handleCopy}
19
+ className="text-slate-400 hover:text-white transition-colors flex items-center gap-1.5 text-xs py-1 px-2 rounded hover:bg-slate-800"
20
+ >
21
+ {copied ? <FaCheck size={11} className="text-emerald-500" /> : <FaCopy size={11} />}
22
+ <span>{copied ? "Copiado!" : "Copiar"}</span>
23
+ </button>
24
+ </div>
25
+ <pre className="p-4 text-xs font-mono overflow-x-auto leading-relaxed whitespace-pre-wrap">
26
+ <code>{code}</code>
27
+ </pre>
28
+ </div>
29
+ );
30
+ };
31
+
32
+ export interface ShowcaseLayoutProps {
33
+ title: string;
34
+ description: string;
35
+ demo: React.ReactNode;
36
+ controls: React.ReactNode;
37
+ code: string;
38
+ gallery?: React.ReactNode;
39
+ }
40
+
41
+ export const ShowcaseLayout: React.FC<ShowcaseLayoutProps> = ({
42
+ title,
43
+ description,
44
+ demo,
45
+ controls,
46
+ code,
47
+ gallery
48
+ }) => {
49
+ const { resolvedTheme } = useITTheme();
50
+ const [localTheme, setLocalTheme] = useState<"light" | "dark" | "default">("default");
51
+ const activeTheme = localTheme === "default" ? resolvedTheme : localTheme;
52
+
53
+ return (
54
+ <div className="space-y-8 animate-fadeIn">
55
+ {/* Title block */}
56
+ <div className="flex flex-col md:flex-row md:items-center justify-between gap-4">
57
+ <div>
58
+ <h1 className="text-3xl font-extrabold text-slate-800 dark:text-white tracking-tight flex items-center gap-3">
59
+ {title}
60
+ <span className={`text-[10px] px-2 py-0.5 rounded-full font-semibold border ${activeTheme === "dark"
61
+ ? "bg-slate-800 text-slate-200 border-slate-700"
62
+ : "bg-slate-100 text-slate-700 border-slate-200"
63
+ }`}>
64
+ {activeTheme === "dark" ? "Sandbox Oscuro 🌙" : "Sandbox Claro ☀️"}
65
+ </span>
66
+ </h1>
67
+ <p className="text-slate-500 dark:text-slate-400 mt-1.5 text-sm md:text-base">{description}</p>
68
+ </div>
69
+
70
+ {/* Local Sandbox Theme Switcher */}
71
+ <div className="flex items-center gap-1 bg-slate-100 dark:bg-slate-800 p-1 rounded-xl border border-slate-200 dark:border-slate-700">
72
+ <button
73
+ onClick={() => setLocalTheme("default")}
74
+ className={`px-3 py-1 text-xs font-medium rounded-lg transition-all ${localTheme === "default"
75
+ ? "bg-white dark:bg-slate-700 text-slate-800 dark:text-white shadow-sm border border-slate-200 dark:border-slate-600"
76
+ : "text-slate-500 hover:text-slate-800 dark:hover:text-slate-200 border border-transparent"
77
+ }`}
78
+ >
79
+ Auto
80
+ </button>
81
+ <button
82
+ onClick={() => setLocalTheme("light")}
83
+ className={`px-3 py-1 text-xs font-medium rounded-lg transition-all ${localTheme === "light"
84
+ ? "bg-white dark:bg-slate-700 text-slate-800 dark:text-white shadow-sm border border-slate-200 dark:border-slate-600"
85
+ : "text-slate-500 hover:text-slate-800 dark:hover:text-slate-200 border border-transparent"
86
+ }`}
87
+ >
88
+ Claro
89
+ </button>
90
+ <button
91
+ onClick={() => setLocalTheme("dark")}
92
+ className={`px-3 py-1 text-xs font-medium rounded-lg transition-all ${localTheme === "dark"
93
+ ? "bg-white dark:bg-slate-700 text-slate-800 dark:text-white shadow-sm border border-slate-200 dark:border-slate-600"
94
+ : "text-slate-500 hover:text-slate-800 dark:hover:text-slate-200 border border-transparent"
95
+ }`}
96
+ >
97
+ Oscuro
98
+ </button>
99
+ </div>
100
+ </div>
101
+
102
+ <div className="grid grid-cols-1 lg:grid-cols-3 gap-8">
103
+ {/* Interactive Sandbox & Code */}
104
+ <div className="lg:col-span-2 space-y-6">
105
+ <ITCard title="Sandbox Interactivo" className="shadow-lg border-slate-100 dark:border-slate-800">
106
+ <div
107
+ data-theme={activeTheme}
108
+ className={`p-6 min-h-[180px] rounded-2xl border border-dashed transition-all duration-300 flex items-center justify-center ${activeTheme === "dark"
109
+ ? "dark bg-slate-950 border-slate-800 text-slate-200"
110
+ : "light bg-white border-slate-200 text-slate-800"
111
+ }`}
112
+ >
113
+ <div className="w-full flex justify-center">{demo}</div>
114
+ </div>
115
+ </ITCard>
116
+
117
+ <CodeViewer code={code} />
118
+ </div>
119
+
120
+ {/* Controls */}
121
+ <div className="space-y-6">
122
+ <ITCard title="Propiedades / Controles" className="shadow-lg border-slate-100 dark:border-slate-800">
123
+ <div className="space-y-4">
124
+ {controls}
125
+ </div>
126
+ </ITCard>
127
+ </div>
128
+ </div>
129
+
130
+ {gallery && (
131
+ <ITCard title="Variaciones y Estados (Galería)" className="shadow-lg border-slate-100 dark:border-slate-800">
132
+ <div className="p-4">
133
+ {gallery}
134
+ </div>
135
+ </ITCard>
136
+ )}
137
+ </div>
138
+ );
139
+ };