@soyfri/shared-library 2.0.0-beta.2 → 2.0.0-beta.4

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 (187) hide show
  1. package/.dockerignore +8 -0
  2. package/.github/workflows/publish.yml +107 -0
  3. package/.prettierrc +3 -0
  4. package/.storybook/main.ts +19 -0
  5. package/.storybook/preview.ts +14 -0
  6. package/.storybook/vitest.setup.ts +9 -0
  7. package/Dockerfile +37 -0
  8. package/build.js +102 -0
  9. package/chromatic.config.json +5 -0
  10. package/cleanDirectories.js +40 -0
  11. package/dist/README.md +243 -0
  12. package/dist/components/Icon/Icon.js +1 -1
  13. package/dist/components/Table/Table.js +1 -1
  14. package/dist/index.cjs +24 -0
  15. package/dist/index.cjs.map +1 -1
  16. package/dist/index.js +7 -1
  17. package/dist/mui.d.ts +1 -0
  18. package/dist/package.json +197 -0
  19. package/package.json +4 -32
  20. package/rollup.config.cjs +87 -0
  21. package/src/components/ActionMenu/ActionMenu.stories.tsx +230 -0
  22. package/src/components/ActionMenu/ActionMenu.tsx +174 -0
  23. package/src/components/ActionMenu/index.ts +2 -0
  24. package/src/components/AppBar/AppBar.stories.tsx +272 -0
  25. package/src/components/AppBar/AppBar.sx.ts +32 -0
  26. package/src/components/AppBar/AppBar.tsx +123 -0
  27. package/src/components/AppBar/AppBarBrand.tsx +120 -0
  28. package/src/components/AppBar/AppBarContext.ts +25 -0
  29. package/src/components/AppBar/AppBarMenuToggle.tsx +90 -0
  30. package/src/components/AppBar/AppBarUserMenu.tsx +217 -0
  31. package/src/components/AppBar/index.ts +25 -0
  32. package/src/components/Autocomplete/Autocomplete.definitions.ts +477 -0
  33. package/src/components/Autocomplete/Autocomplete.helpers.ts +60 -0
  34. package/src/components/Autocomplete/Autocomplete.stories.tsx +748 -0
  35. package/src/components/Autocomplete/Autocomplete.sx.ts +30 -0
  36. package/src/components/Autocomplete/Autocomplete.tsx +361 -0
  37. package/src/components/Autocomplete/Autocomplete.types.ts +13 -0
  38. package/src/components/Autocomplete/_parts/AutocompleteChips.tsx +55 -0
  39. package/src/components/Autocomplete/_parts/AutocompleteLoader.tsx +17 -0
  40. package/src/components/Autocomplete/_parts/AutocompleteOption.tsx +31 -0
  41. package/src/components/Autocomplete/index.ts +12 -0
  42. package/src/components/Avatar/Avatar.definitions.ts +162 -0
  43. package/src/components/Avatar/Avatar.stories.tsx +258 -0
  44. package/src/components/Avatar/Avatar.tsx +206 -0
  45. package/src/components/Avatar/index.ts +1 -0
  46. package/src/components/Button/Button.definition.ts +97 -0
  47. package/src/components/Button/Button.stories.tsx +285 -0
  48. package/src/components/Button/Button.tsx +67 -0
  49. package/src/components/Button/index.ts +1 -0
  50. package/src/components/Card/Card.definition.ts +5 -0
  51. package/src/components/Card/Card.stories.tsx +221 -0
  52. package/src/components/Card/Card.sx.ts +104 -0
  53. package/src/components/Card/Card.tsx +200 -0
  54. package/src/components/Card/index.ts +9 -0
  55. package/src/components/Chip/Chip.definitions.ts +167 -0
  56. package/src/components/Chip/Chip.stories.tsx +265 -0
  57. package/src/components/Chip/Chip.tsx +61 -0
  58. package/src/components/Chip/index.ts +1 -0
  59. package/src/components/Column/Column.tsx +29 -0
  60. package/src/components/Column/index.ts +1 -0
  61. package/src/components/DatePicker/DatePicker.definitions.ts +228 -0
  62. package/src/components/DatePicker/DatePicker.helpers.ts +24 -0
  63. package/src/components/DatePicker/DatePicker.stories.tsx +309 -0
  64. package/src/components/DatePicker/DatePicker.sx.ts +33 -0
  65. package/src/components/DatePicker/DatePicker.tsx +189 -0
  66. package/src/components/DatePicker/DatePicker.types.ts +10 -0
  67. package/src/components/DatePicker/index.ts +9 -0
  68. package/src/components/DateRangePicker/DateRangePicker.definitions.ts +191 -0
  69. package/src/components/DateRangePicker/DateRangePicker.stories.tsx +252 -0
  70. package/src/components/DateRangePicker/DateRangePicker.tsx +56 -0
  71. package/src/components/DateRangePicker/index.ts +1 -0
  72. package/src/components/DateTimePicker/DateTimePicker.definitions.ts +256 -0
  73. package/src/components/DateTimePicker/DateTimePicker.helpers.ts +38 -0
  74. package/src/components/DateTimePicker/DateTimePicker.stories.tsx +418 -0
  75. package/src/components/DateTimePicker/DateTimePicker.sx.ts +30 -0
  76. package/src/components/DateTimePicker/DateTimePicker.tsx +225 -0
  77. package/src/components/DateTimePicker/DateTimePicker.types.ts +10 -0
  78. package/src/components/DateTimePicker/index.ts +9 -0
  79. package/src/components/Drawer/Drawer.stories.tsx +270 -0
  80. package/src/components/Drawer/Drawer.sx.ts +106 -0
  81. package/src/components/Drawer/Drawer.tsx +214 -0
  82. package/src/components/Drawer/DrawerContext.ts +26 -0
  83. package/src/components/Drawer/DrawerItem.tsx +110 -0
  84. package/src/components/Drawer/index.ts +10 -0
  85. package/src/components/Flyout/Flyout.stories.tsx +282 -0
  86. package/src/components/Flyout/Flyout.tsx +122 -0
  87. package/src/components/Flyout/index.ts +1 -0
  88. package/src/components/Gallery/Gallery.definition.tsx +37 -0
  89. package/src/components/Gallery/Gallery.stories.tsx +82 -0
  90. package/src/components/Gallery/Gallery.tsx +118 -0
  91. package/src/components/Gallery/GalleryLightbox.tsx +170 -0
  92. package/src/components/Gallery/GalleryMain.tsx +84 -0
  93. package/src/components/Gallery/GalleryThumbnails.tsx +106 -0
  94. package/src/components/Gallery/index.ts +1 -0
  95. package/src/components/Icon/Icon.stories.tsx +121 -0
  96. package/src/components/Icon/Icon.tsx +175 -0
  97. package/src/components/Icon/index.ts +2 -0
  98. package/src/components/Input/Input.definitions.ts +324 -0
  99. package/src/components/Input/Input.helpers.ts +49 -0
  100. package/src/components/Input/Input.stories.tsx +499 -0
  101. package/src/components/Input/Input.sx.ts +42 -0
  102. package/src/components/Input/Input.tsx +141 -0
  103. package/src/components/Input/Input.types.ts +10 -0
  104. package/src/components/Input/index.ts +9 -0
  105. package/src/components/InputGroup/InputGroup.definitions.ts +158 -0
  106. package/src/components/InputGroup/InputGroup.stories.tsx +267 -0
  107. package/src/components/InputGroup/InputGroup.tsx +179 -0
  108. package/src/components/InputGroup/index.ts +1 -0
  109. package/src/components/MenuButton/MenuButton.stories.tsx +197 -0
  110. package/src/components/MenuButton/MenuButton.tsx +100 -0
  111. package/src/components/MenuButton/index.ts +1 -0
  112. package/src/components/Modal/Modal.stories.tsx +721 -0
  113. package/src/components/Modal/Modal.tsx +355 -0
  114. package/src/components/Modal/ModalBody.tsx +16 -0
  115. package/src/components/Modal/ModalFooter.tsx +71 -0
  116. package/src/components/Modal/ModalHeader.tsx +18 -0
  117. package/src/components/Modal/index.ts +6 -0
  118. package/src/components/PageLoader/PageLoader.stories.tsx +217 -0
  119. package/src/components/PageLoader/PageLoader.tsx +96 -0
  120. package/src/components/PageLoader/index.ts +2 -0
  121. package/src/components/ScrollTopButton/ScrollTopButton.stories.tsx +158 -0
  122. package/src/components/ScrollTopButton/ScrollTopButton.tsx +135 -0
  123. package/src/components/ScrollTopButton/index.ts +8 -0
  124. package/src/components/ScrollTopButton/scrollToTop.ts +37 -0
  125. package/src/components/Select/Select.definitions.ts +602 -0
  126. package/src/components/Select/Select.helpers.ts +71 -0
  127. package/src/components/Select/Select.stories.tsx +687 -0
  128. package/src/components/Select/Select.sx.ts +14 -0
  129. package/src/components/Select/Select.tsx +429 -0
  130. package/src/components/Select/Select.types.ts +15 -0
  131. package/src/components/Select/_parts/SelectMenuItem.tsx +40 -0
  132. package/src/components/Select/_parts/SelectSearchHeader.tsx +51 -0
  133. package/src/components/Select/_parts/SelectValue.tsx +96 -0
  134. package/src/components/Select/index.ts +14 -0
  135. package/src/components/Stat/Stat.stories.tsx +85 -0
  136. package/src/components/Stat/Stat.tsx +117 -0
  137. package/src/components/Stat/index.ts +2 -0
  138. package/src/components/StatusMessage/StatusMessage.stories.tsx +130 -0
  139. package/src/components/StatusMessage/StatusMessage.tsx +162 -0
  140. package/src/components/StatusMessage/index.ts +2 -0
  141. package/src/components/Stepper/Step.tsx +21 -0
  142. package/src/components/Stepper/Stepper.definition.ts +75 -0
  143. package/src/components/Stepper/Stepper.stories.tsx +122 -0
  144. package/src/components/Stepper/Stepper.tsx +75 -0
  145. package/src/components/Stepper/index.ts +2 -0
  146. package/src/components/Table/EmptyTable.png +0 -0
  147. package/src/components/Table/Table.definition.ts +580 -0
  148. package/src/components/Table/Table.stories.tsx +853 -0
  149. package/src/components/Table/Table.tsx +495 -0
  150. package/src/components/Table/data.ts +134 -0
  151. package/src/components/Table/exportsUtils.ts +195 -0
  152. package/src/components/Table/index.ts +3 -0
  153. package/src/components/Table/types.ts +34 -0
  154. package/src/components/Tabs/Tab.definition.ts +53 -0
  155. package/src/components/Tabs/Tab.tsx +19 -0
  156. package/src/components/Tabs/Tabs.stories.tsx +118 -0
  157. package/src/components/Tabs/Tabs.tsx +99 -0
  158. package/src/components/Tabs/_tabUtils.tsx +4 -0
  159. package/src/components/Tabs/index.ts +2 -0
  160. package/src/components/Timeline/Timeline.definition.ts +43 -0
  161. package/src/components/Timeline/Timeline.stories.tsx +108 -0
  162. package/src/components/Timeline/Timeline.tsx +49 -0
  163. package/src/components/Timeline/TimelineItem.tsx +31 -0
  164. package/src/components/Timeline/index.ts +2 -0
  165. package/src/components/Tooltip/Tooltip.stories.tsx +129 -0
  166. package/src/components/Tooltip/Tooltip.tsx +58 -0
  167. package/src/components/Tooltip/index.ts +1 -0
  168. package/src/components/_shared/formField.sx.ts +118 -0
  169. package/src/components/_shared/resolvePreset.ts +35 -0
  170. package/src/hooks/ClipBoard/ClipBoard.stories.tsx +168 -0
  171. package/src/hooks/ClipBoard/ClipBoard.tsx +131 -0
  172. package/src/hooks/ClipBoard/ClipboardUnifiedDemo.tsx +111 -0
  173. package/src/hooks/ClipBoard/index.ts +1 -0
  174. package/src/hooks/Wizard/Wizard.stories.tsx +301 -0
  175. package/src/hooks/Wizard/WizardContext.tsx +166 -0
  176. package/src/hooks/Wizard/index.ts +6 -0
  177. package/src/hooks/Wizard/useWizard.ts +13 -0
  178. package/src/index.ts +17 -0
  179. package/src/mui.ts +54 -0
  180. package/src/styles.css +3 -0
  181. package/src/theme/componentStyles.ts +47 -0
  182. package/src/theme/tokens.ts +43 -0
  183. package/tailwind.config.js +10 -0
  184. package/tsconfig.json +48 -0
  185. package/tsup.config.js +41 -0
  186. package/vite.config.js +132 -0
  187. package/vitest.config.ts +35 -0
@@ -0,0 +1,580 @@
1
+ export const BasicTableCode = `
2
+ <Table data={data} visiblePageNumbers={5} pageSizeSelectorValue={1} pageSize={1}>
3
+ <Column name="Nombre" field="nombre">
4
+ {({ nombre }) => <Typography variant="body2">{nombre}</Typography>}
5
+ </Column>
6
+ <Column name="Email" field="email">
7
+ {({ email }) => <Typography variant="body2" color="text.secondary">{email}</Typography>}
8
+ </Column>
9
+ <Column name="Edad" field="edad">
10
+ {({ edad }) => <Typography variant="body2">{edad} años</Typography>}
11
+ </Column>
12
+ </Table>
13
+ `
14
+
15
+ export const ComplexComponentsCode =`
16
+ <Table data={data}>
17
+ <Column name="Usuario" field={['avatar', 'nombre']}>
18
+ {({ avatar, nombre }) => (
19
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
20
+ <Avatar src={avatar} alt={nombre} sx={{ width: 40, height: 40 }} />
21
+ <Typography variant="body2" fontWeight="medium">{nombre}</Typography>
22
+ </Box>
23
+ )}
24
+ </Column>
25
+ <Column name="Estado" field="activo">
26
+ {({ activo }) => (
27
+ <Chip
28
+ label={activo ? 'Activo' : 'Inactivo'}
29
+ color={activo ? 'success' : 'default'}
30
+ size="small"
31
+ />
32
+ )}
33
+ </Column>
34
+ <Column name="Rol" field="rol">
35
+ {({ rol }) => (
36
+ <Chip
37
+ label={rol!.charAt(0).toUpperCase() + rol!.slice(1)}
38
+ color={rol === 'admin' ? 'primary' : rol === 'moderador' ? 'secondary' : 'default'}
39
+ variant="outlined"
40
+ size="small"
41
+ />
42
+ )}
43
+ </Column>
44
+ <Column name="Puntuación" field="puntuacion">
45
+ {({ puntuacion }) => (
46
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
47
+ <Rating value={puntuacion} max={5} precision={0.1} size="small" readOnly />
48
+ <Typography variant="caption" color="text.secondary">
49
+ {puntuacion}
50
+ </Typography>
51
+ </Box>
52
+ )}
53
+ </Column>
54
+ </Table>
55
+ `
56
+
57
+ export const WithExternalPaginationControlCode = `
58
+ const [currentPage, setCurrentPage] = useState(1);
59
+ const [pageSize, setPageSize] = useState(2);
60
+ const totalItems = usuarios.length;
61
+ const totalPages = Math.ceil(totalItems / pageSize);
62
+
63
+ const startIndex = (currentPage - 1) * pageSize;
64
+ const currentData = usuarios.slice(startIndex, startIndex + pageSize);
65
+
66
+ const previousPageNum = currentPage > 1 ? currentPage - 1 : 1;
67
+ const nextPageNum = currentPage < totalPages ? currentPage + 1 : totalPages;
68
+
69
+ return (
70
+ <Table
71
+ data={currentData} // Pasa solo los datos de la página actual
72
+ currentPage={currentPage}
73
+ pageSize={pageSize}
74
+ totalPages={totalPages}
75
+ previousPage={previousPageNum}
76
+ nextPage={nextPageNum}
77
+ onPageChange={setCurrentPage}
78
+ onPageSizeChange={setPageSize}
79
+ >
80
+ <Column name="Nombre" field="nombre">
81
+ {({ nombre }) => <Typography variant="body2" fontWeight="medium">{nombre}</Typography>}
82
+ </Column>
83
+ <Column name="Email" field="email">
84
+ {({ email }) => <Typography variant="body2" color="text.secondary">{email}</Typography>}
85
+ </Column>
86
+ <Column name="Estado" field="activo">
87
+ {({ activo }) => (
88
+ <Chip
89
+ label={activo ? 'Activo' : 'Inactivo'}
90
+ color={activo ? 'success' : 'default'}
91
+ size="small"
92
+ />
93
+ )}
94
+ </Column>
95
+ <Column name="Fecha de Registro" field="fechaRegistro">
96
+ {({ fechaRegistro }) => (
97
+ <Typography variant="body2">
98
+ {new Date(fechaRegistro!).toLocaleDateString('es-ES')}
99
+ </Typography>
100
+ )}
101
+ </Column>
102
+ </Table>
103
+ );
104
+ `
105
+
106
+ export const ProductTableCode = `
107
+ <Table data={data} pageSizeSelectorValue={pageSizeSelectorValue}>
108
+ <Column name="Producto" field={['imagen', 'nombre']}>
109
+ {({ imagen, nombre }) => (
110
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
111
+ <Box
112
+ component="img"
113
+ src={imagen}
114
+ alt={nombre}
115
+ sx={{ width: 50, height: 50, borderRadius: 1, objectFit: 'cover' }}
116
+ />
117
+ <Typography variant="body2" fontWeight="medium">{nombre}</Typography>
118
+ </Box>
119
+ )}
120
+ </Column>
121
+ <Column name="Precio" field={['precio', 'enOferta']}>
122
+ {({ precio, enOferta }) => (
123
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
124
+ <Typography
125
+ variant="body2"
126
+ color={enOferta ? 'error.main' : 'text.primary'}
127
+ fontWeight={enOferta ? 'bold' : 'normal'}
128
+ >
129
+ \${precio!.toLocaleString()}
130
+ </Typography>
131
+ {enOferta && (
132
+ <Chip label="OFERTA" color="error" size="small" />
133
+ )}
134
+ </Box>
135
+ )}
136
+ </Column>
137
+ <Column name="Stock" field="stock">
138
+ {({ stock }) => (
139
+ <Chip
140
+ label={stock! > 0 ? \`\${stock} unidades\` : 'Sin stock'}
141
+ color={stock! > 5 ? 'success' : stock! > 0 ? 'warning' : 'error'}
142
+ size="small"
143
+ />
144
+ )}
145
+ </Column>
146
+ <Column name="Categoría" field="categoria">
147
+ {({ categoria }) => (
148
+ <Typography variant="body2">{categoria}</Typography>
149
+ )}
150
+ </Column>
151
+ <Column name="Rating" field="rating">
152
+ {({ rating }) => (
153
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
154
+ <Rating value={rating} max={5} precision={0.1} size="small" readOnly />
155
+ <Typography variant="caption">({rating})</Typography>
156
+ </Box>
157
+ )}
158
+ </Column>
159
+ </Table>
160
+ `
161
+
162
+ export const EmployeeTableCode = `
163
+ <Table data={data} pageSizeSelectorValue={pageSizeSelectorValue}>
164
+ <Column name="Empleado" field={['avatar', 'nombre', 'apellido']}>
165
+ {({ avatar, nombre, apellido }) => (
166
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
167
+ <Avatar src={avatar} sx={{ width: 40, height: 40 }}>
168
+ {avatar ? '' : \`\${nombre!.charAt(0)}\${apellido!.charAt(0)}\`}
169
+ </Avatar>
170
+ <Typography variant="body2" fontWeight="medium">
171
+ {nombre} {apellido}
172
+ </Typography>
173
+ </Box>
174
+ )}
175
+ </Column>
176
+ <Column name="Departamento" field="departamento">
177
+ {({ departamento }) => (
178
+ <Chip
179
+ label={departamento}
180
+ color="info"
181
+ variant="filled"
182
+ size="small"
183
+ />
184
+ )}
185
+ </Column>
186
+ <Column name="Salario" field="salario">
187
+ {({ salario }) => (
188
+ <Typography variant="body2" fontWeight="bold" color="success.dark">
189
+ \${salario!.toLocaleString('es-ES')}
190
+ </Typography>
191
+ )}
192
+ </Column>
193
+ <Column name="Estado" field={['activo', 'fechaIngreso']}>
194
+ {({ activo, fechaIngreso }) => (
195
+ <Box>
196
+ <Chip
197
+ label={activo ? 'Contratado' : 'Inactivo'}
198
+ color={activo ? 'success' : 'error'}
199
+ size="small"
200
+ />
201
+ <Typography variant="caption" display="block" color="text.secondary" sx={{ mt: 0.5 }}>
202
+ Desde: {new Date(fechaIngreso!).toLocaleDateString('es-ES')}
203
+ </Typography>
204
+ </Box>
205
+ )}
206
+ </Column>
207
+ </Table>
208
+ `
209
+
210
+ export const EmptyTableCode = `
211
+ <Table data={data}>
212
+ <Column name="Nombre" field="nombre">
213
+ {({ nombre }) => <Typography variant="body2">{nombre}</Typography>}
214
+ </Column>
215
+ <Column name="Email" field="email">
216
+ {({ email }) => <Typography variant="body2">{email}</Typography>}
217
+ </Column>
218
+ <Column name="Estado" field="activo">
219
+ {({ activo }) => <Chip label={activo ? 'Activo' : 'Inactivo'} size="small" />}
220
+ </Column>
221
+ </Table>
222
+ `
223
+
224
+ export const SingleRowCode = `
225
+ <Table data={data}>
226
+ <Column name="Usuario" field={['avatar', 'nombre', 'email']}>
227
+ {({ avatar, nombre, email }) => (
228
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
229
+ <Avatar src={avatar} alt={nombre} />
230
+ <Box>
231
+ <Typography variant="body2" fontWeight="medium">{nombre}</Typography>
232
+ <Typography variant="caption" color="text.secondary">{email}</Typography>
233
+ </Box>
234
+ </Box>
235
+ )}
236
+ </Column>
237
+ <Column<Usuario> name="Información" field={[]}>
238
+ {(user) => (
239
+ <>
240
+ <Typography variant="body2">{user.edad} años</Typography>
241
+ <Box sx={{ display: 'flex', gap: 1, mt: 0.5 }}>
242
+ <Chip label={user.rol} size="small" color="primary" variant="outlined" />
243
+ <Chip
244
+ label={user.activo ? 'Activo' : 'Inactivo'}
245
+ size="small"
246
+ color={user.activo ? 'success' : 'default'}
247
+ />
248
+ </Box>
249
+ </>
250
+ )}
251
+ </Column>
252
+ </Table>
253
+ `
254
+ export const ProductTableWithZeroStockHighlightedCode =`
255
+ <Table data={data}>
256
+ <Column name="Producto" field={['imagen', 'nombre']}>
257
+ {({ imagen, nombre }) => (
258
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
259
+ <Box
260
+ component="img"
261
+ src={imagen}
262
+ alt={nombre}
263
+ sx={{ width: 50, height: 50, borderRadius: 1, objectFit: 'cover' }}
264
+ />
265
+ <Typography variant="body2" fontWeight="medium">{nombre}</Typography>
266
+ </Box>
267
+ )}
268
+ </Column>
269
+ <Column name="Precio" field={['precio', 'enOferta']}>
270
+ {({ precio, enOferta }) => (
271
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
272
+ <Typography
273
+ variant="body2"
274
+ color={enOferta ? 'error.main' : 'text.primary'}
275
+ fontWeight={enOferta ? 'bold' : 'normal'}
276
+ >
277
+ \${precio!.toLocaleString()}
278
+ </Typography>
279
+ {enOferta && (
280
+ <Chip label="OFERTA" color="error" size="small" />
281
+ )}
282
+ </Box>
283
+ )}
284
+ </Column>
285
+ <Column name="Stock" field="stock">
286
+ {({ stock }) => (
287
+ <Chip
288
+ label={stock! > 0 ? \`\${stock} unidades\` : 'Sin stock'}
289
+ color={stock!> 5 ? 'success' : stock! > 0 ? 'warning' : 'error'}
290
+ size="small"
291
+ sx={{ backgroundColor: stock === 0 ? 'rgba(255, 0, 0, 0.1)' : undefined }}
292
+ />
293
+ )}
294
+ </Column>
295
+ <Column name="Rating" field="rating">
296
+ {({ rating }) => (
297
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
298
+ <Rating value={rating} max={5} precision={0.1} size="small" readOnly />
299
+ <Typography variant="caption">({rating})</Typography>
300
+ </Box>
301
+ )}
302
+ </Column>
303
+ </Table>
304
+ `
305
+
306
+ export const UserTableSortedByAgeCode = `
307
+ const sortedUsers = [...usuarios].sort((a, b) => a.edad - b.edad);
308
+ return (
309
+ <Table {...args} data={sortedUsers.slice(0, 4)}>
310
+ <Column name="Nombre" field="nombre">
311
+ {({ nombre }) => <Typography variant="body2">{nombre}</Typography>}
312
+ </Column>
313
+ <Column name="Edad" field="edad">
314
+ {({ edad }) => <Typography variant="body2" fontWeight="medium">{edad} años</Typography>}
315
+ </Column>
316
+ <Column name="Rol" field="rol">
317
+ {({ rol }) => (
318
+ <Chip
319
+ label={rol!.charAt(0).toUpperCase() + rol!.slice(1)}
320
+ color={rol === 'admin' ? 'primary' : rol === 'moderador' ? 'secondary' : 'default'}
321
+ variant="outlined"
322
+ size="small"
323
+ />
324
+ )}
325
+ </Column>
326
+ <Column name="Puntuación" field="puntuacion">
327
+ {({ puntuacion }) => (
328
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>
329
+ <Rating value={puntuacion} max={5} precision={0.1} size="small" readOnly />
330
+ <Typography variant="caption" color="text.secondary">
331
+ {puntuacion!.toFixed(1)}
332
+ </Typography>
333
+ </Box>
334
+ )}
335
+ </Column>
336
+ </Table>
337
+ );
338
+ `
339
+ export const EmployeeDetailedStatusCode = `
340
+ <Table data={data}>
341
+ <Column name="Empleado" field={['nombre', 'apellido', 'avatar']}>
342
+ {({ nombre, apellido, avatar }) => (
343
+ <Box sx={{ display: 'flex', alignItems: 'center', gap: 2 }}>
344
+ <Avatar src={avatar} sx={{ width: 40, height: 40 }}>
345
+ {avatar ? '' : \`\${nombre!.charAt(0)}\${apellido!.charAt(0)}\`}
346
+ </Avatar>
347
+ <Typography variant="body2" fontWeight="medium">
348
+ {nombre} {apellido}
349
+ </Typography>
350
+ </Box>
351
+ )}
352
+ </Column>
353
+ <Column name="Departamento" field="departamento">
354
+ {({ departamento }) => (
355
+ <Chip
356
+ label={departamento}
357
+ color="info"
358
+ variant="filled"
359
+ size="small"
360
+ />
361
+ )}
362
+ </Column>
363
+ <Column name="Salario" field="salario">
364
+ {({ salario }) => (
365
+ <Typography variant="body2" fontWeight="bold" color="success.dark">
366
+ \${salario!.toLocaleString('es-ES')}
367
+ </Typography>
368
+ )}
369
+ </Column>
370
+ <Column name="Estado de Contratación" field={['activo', 'fechaIngreso']}>
371
+ {({ activo, fechaIngreso }) => (
372
+ <Box>
373
+ <Chip
374
+ label={activo ? 'Contratado' : 'Inactivo'}
375
+ color={activo ? 'success' : 'error'}
376
+ size="small"
377
+ />
378
+ <Typography variant="caption" display="block" color="text.secondary" sx={{ mt: 0.5 }}>
379
+ Desde: {new Date(fechaIngreso!).toLocaleDateString('es-ES')}
380
+ </Typography>
381
+ </Box>
382
+ )}
383
+ </Column>
384
+ </Table>
385
+ `
386
+
387
+ export const ActionsColumnCode = `
388
+ <Table data={data}>
389
+ <Column name="Nombre" field="nombre">
390
+ {({ nombre }) => <Typography variant="body2">{nombre}</Typography>}
391
+ </Column>
392
+ <Column name="Email" field="email">
393
+ {({ email }) => <Typography variant="body2" color="text.secondary">{email}</Typography>}
394
+ </Column>
395
+ <Column name="Acciones" field="id">
396
+ {({ id }) => (
397
+ <Button
398
+ variant="contained"
399
+ color="primary"
400
+ size="small"
401
+ onClick={() => alert('ID del usuario: '+id )} // Log al hacer clic
402
+ >
403
+ Ver Detalles ({id})
404
+ </Button>
405
+ )}
406
+ </Column>
407
+ </Table>
408
+ `
409
+
410
+ export const TableWithExportCode = `
411
+ <Table<Usuario>
412
+ data={usuarios}
413
+ enableExport={enableExport}
414
+ exportFileName={exportFileName}
415
+ exportButtonText={exportButtonText}
416
+ exportColumns={exportColumns}
417
+ >
418
+ <Column<Usuario> name="ID" field="id">
419
+ {(row) => <Typography>{row.id}</Typography>}
420
+ </Column>
421
+ <Column<Usuario> name="Nombre" field="nombre">
422
+ {(row) => <Typography>{row.nombre}</Typography>}
423
+ </Column>
424
+ <Column<Usuario> name="Email" field="email">
425
+ {({ email }) => <Link href={\`mailto:\${email}\`}>{email}</Link>}
426
+ </Column>
427
+ <Column<Usuario> name="Edad" field="edad">
428
+ {(row) => <Typography>{row.edad}</Typography>}
429
+ </Column>
430
+ <Column<Usuario> name="Rol" field="rol">
431
+ {({ rol }) => <Chip label={rol} size="small" />}
432
+ </Column>
433
+ <Column<Usuario> name="Acciones" field="id">
434
+ {({ id }) => (
435
+ <Button variant="outlined" size="small" onClick={() => alert(\`Ver detalles de usuario \${id}\`)}>
436
+ Ver
437
+ </Button>
438
+ )}
439
+ </Column>
440
+ </Table>
441
+ `
442
+
443
+ export const WithRowSelectionCode = `
444
+
445
+ const [selectedItems, setSelectedItems] = useState<UserData[]>([]);
446
+
447
+ const handleSelectionChange = (items: UserData[]) => {
448
+ setSelectedItems(items);
449
+ args.onSelectionChange?.(items);
450
+ };
451
+
452
+ const handleBulkDelete = () => {
453
+ if (selectedItems.length > 0) {
454
+ alert(\`Eliminando \${selectedItems.length} usuarios: \${selectedItems.map(item => item.nombre).join(', ')}\`);
455
+ setSelectedItems([]);
456
+ } else {
457
+ alert('No hay elementos seleccionados para eliminar.');
458
+ }
459
+ };
460
+
461
+ const handleBulkUpdateCity = () => {
462
+ if (selectedItems.length > 0) {
463
+ const newCity = prompt('Ingresa la nueva ciudad para los seleccionados:');
464
+ if (newCity) {
465
+ alert(\`Actualizando ciudad de \${selectedItems.length} usuarios a \${newCity}\`);
466
+ setSelectedItems([]);
467
+ }
468
+ } else {
469
+ alert('No hay elementos seleccionados para actualizar.');
470
+ }
471
+ };
472
+
473
+ return (
474
+ <Box>
475
+ <Typography variant="h6" gutterBottom>
476
+ Tabla con Selección de Filas
477
+ </Typography>
478
+ {selectedItems.length > 0 && (
479
+ <Box sx={{ mb: 2, display: 'flex', gap: 1 }}>
480
+ <Button variant="contained" color="error" onClick={handleBulkDelete}>
481
+ Eliminar ({selectedItems.length})
482
+ </Button>
483
+ <Button variant="contained" color="primary" onClick={handleBulkUpdateCity}>
484
+ Actualizar Ciudad ({selectedItems.length})
485
+ </Button>
486
+ <Typography variant="body2" sx={{ alignSelf: 'center', ml: 2 }}>
487
+ Elementos seleccionados: {selectedItems.length}
488
+ </Typography>
489
+ </Box>
490
+ )}
491
+ <Table<UserData>
492
+ {...args}
493
+ data={sampleData} // Usamos sampleData para esta historia
494
+ enableRowSelection={true}
495
+ rowIdentifier="id" // Es crucial que coincida con una clave única en tus datos
496
+ onSelectionChange={handleSelectionChange}
497
+ pageSizeSelectorValue={5}
498
+ >
499
+ <Column<UserData>
500
+ name="ID"
501
+ field="id"
502
+ children={(row) => <Typography>{row.id}</Typography>}
503
+ />
504
+ <Column<UserData>
505
+ name="Nombre"
506
+ field="name"
507
+ children={(row) => <Typography>{row.name}</Typography>}
508
+ />
509
+ <Column<UserData>
510
+ name="Email"
511
+ field="email"
512
+ children={(row) => <Typography>{row.email}</Typography>}
513
+ />
514
+ <Column<UserData>
515
+ name="Ciudad"
516
+ field="city"
517
+ children={(row) => <Typography>{row.city}</Typography>}
518
+ />
519
+ </Table>
520
+ </Box>
521
+ );
522
+
523
+ `
524
+
525
+ export const WithExportAndSelectionCode = `
526
+ const [selectedItems, setSelectedItems] = useState<UserData[]>([]);
527
+
528
+ const handleSelectionChange = (items: UserData[]) => {
529
+ setSelectedItems(items);
530
+ args.onSelectionChange?.(items);
531
+ };
532
+
533
+ return (
534
+ <Box>
535
+ <Typography variant="h6" gutterBottom>
536
+ Tabla con Exportación y Selección de Filas
537
+ </Typography>
538
+ {selectedItems.length > 0 && (
539
+ <Box sx={{ mb: 2 }}>
540
+ <Typography variant="body2">
541
+ Elementos seleccionados: {selectedItems.length}
542
+ </Typography>
543
+ </Box>
544
+ )}
545
+ <Table<UserData>
546
+ {...args}
547
+ data={sampleData} // Usamos sampleData para esta historia
548
+ enableRowSelection={true}
549
+ rowIdentifier="id"
550
+ onSelectionChange={handleSelectionChange}
551
+ pageSizeSelectorValue={5}
552
+ enableCSVExport={true}
553
+ csvExportFileName="users_data_with_selection"
554
+ enableExcelExport={true}
555
+ excelExportFileName="users_data_with_selection"
556
+ >
557
+ <Column<UserData>
558
+ name="ID"
559
+ field="id"
560
+ children={(row) => <Typography>{row.id}</Typography>}
561
+ />
562
+ <Column<UserData>
563
+ name="Nombre"
564
+ field="name"
565
+ children={(row) => <Typography>{row.name}</Typography>}
566
+ />
567
+ <Column<UserData>
568
+ name="Email"
569
+ field="email"
570
+ children={(row) => <Typography>{row.email}</Typography>}
571
+ />
572
+ <Column<UserData>
573
+ name="Ciudad"
574
+ field="city"
575
+ children={(row) => <Typography>{row.city}</Typography>}
576
+ />
577
+ </Table>
578
+ </Box>
579
+ );
580
+ `