@soyfri/shared-library 1.5.0 → 2.0.0-beta.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 (284) hide show
  1. package/build.js +75 -38
  2. package/dist/components/ActionMenu/ActionMenu.cjs +107 -0
  3. package/dist/components/ActionMenu/ActionMenu.cjs.map +1 -0
  4. package/dist/components/ActionMenu/ActionMenu.d.ts +60 -0
  5. package/dist/components/ActionMenu/ActionMenu.js +107 -0
  6. package/dist/components/ActionMenu/ActionMenu.js.map +1 -0
  7. package/dist/components/ActionMenu/index.d.ts +2 -0
  8. package/dist/components/ActionMenu.d.ts +6 -0
  9. package/dist/components/AppBar/AppBar.cjs +346 -0
  10. package/dist/components/AppBar/AppBar.cjs.map +1 -0
  11. package/dist/components/AppBar/AppBar.d.ts +55 -0
  12. package/dist/components/AppBar/AppBar.js +346 -0
  13. package/dist/components/AppBar/AppBar.js.map +1 -0
  14. package/dist/components/AppBar/AppBar.sx.d.ts +12 -0
  15. package/dist/components/AppBar/AppBarBrand.d.ts +31 -0
  16. package/dist/components/AppBar/AppBarContext.d.ts +18 -0
  17. package/dist/components/AppBar/AppBarMenuToggle.d.ts +39 -0
  18. package/dist/components/AppBar/AppBarUserMenu.d.ts +65 -0
  19. package/dist/components/AppBar/index.d.ts +12 -0
  20. package/dist/components/AppBar.d.ts +6 -0
  21. package/dist/components/Autocomplete/Autocomplete.cjs +259 -54
  22. package/dist/components/Autocomplete/Autocomplete.cjs.map +1 -1
  23. package/dist/components/Autocomplete/Autocomplete.d.ts +64 -9
  24. package/dist/components/Autocomplete/Autocomplete.definitions.d.ts +6 -0
  25. package/dist/components/Autocomplete/Autocomplete.helpers.d.ts +18 -0
  26. package/dist/components/Autocomplete/Autocomplete.js +261 -56
  27. package/dist/components/Autocomplete/Autocomplete.js.map +1 -1
  28. package/dist/components/Autocomplete/Autocomplete.sx.d.ts +7 -0
  29. package/dist/components/Autocomplete/Autocomplete.types.d.ts +1 -0
  30. package/dist/components/Autocomplete/_parts/AutocompleteChips.d.ts +19 -0
  31. package/dist/components/Autocomplete/_parts/AutocompleteLoader.d.ts +9 -0
  32. package/dist/components/Autocomplete/_parts/AutocompleteOption.d.ts +19 -0
  33. package/dist/components/Autocomplete/index.d.ts +2 -1
  34. package/dist/components/Autocomplete.d.ts +4 -0
  35. package/dist/components/Avatar/Avatar.cjs +116 -79
  36. package/dist/components/Avatar/Avatar.cjs.map +1 -1
  37. package/dist/components/Avatar/Avatar.d.ts +16 -2
  38. package/dist/components/Avatar/Avatar.definitions.d.ts +11 -0
  39. package/dist/components/Avatar/Avatar.js +117 -80
  40. package/dist/components/Avatar/Avatar.js.map +1 -1
  41. package/dist/components/Card/Card.cjs +168 -9
  42. package/dist/components/Card/Card.cjs.map +1 -1
  43. package/dist/components/Card/Card.d.ts +78 -8
  44. package/dist/components/Card/Card.js +170 -11
  45. package/dist/components/Card/Card.js.map +1 -1
  46. package/dist/components/Card/Card.sx.d.ts +17 -0
  47. package/dist/components/Card/index.d.ts +4 -1
  48. package/dist/components/Card.d.ts +4 -0
  49. package/dist/components/DatePicker/DatePicker.cjs +201 -3
  50. package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
  51. package/dist/components/DatePicker/DatePicker.d.ts +47 -9
  52. package/dist/components/DatePicker/DatePicker.definitions.d.ts +1 -0
  53. package/dist/components/DatePicker/DatePicker.helpers.d.ts +7 -0
  54. package/dist/components/DatePicker/DatePicker.js +200 -2
  55. package/dist/components/DatePicker/DatePicker.js.map +1 -1
  56. package/dist/components/DatePicker/DatePicker.sx.d.ts +9 -0
  57. package/dist/components/DatePicker/DatePicker.types.d.ts +1 -0
  58. package/dist/components/DatePicker/index.d.ts +2 -1
  59. package/dist/components/DatePicker.d.ts +4 -0
  60. package/dist/components/DateTimePicker/DateTimePicker.cjs +152 -138
  61. package/dist/components/DateTimePicker/DateTimePicker.cjs.map +1 -1
  62. package/dist/components/DateTimePicker/DateTimePicker.d.ts +46 -9
  63. package/dist/components/DateTimePicker/DateTimePicker.definitions.d.ts +1 -0
  64. package/dist/components/DateTimePicker/DateTimePicker.helpers.d.ts +11 -0
  65. package/dist/components/DateTimePicker/DateTimePicker.js +152 -138
  66. package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
  67. package/dist/components/DateTimePicker/DateTimePicker.sx.d.ts +7 -0
  68. package/dist/components/DateTimePicker/DateTimePicker.types.d.ts +1 -0
  69. package/dist/components/DateTimePicker/index.d.ts +2 -1
  70. package/dist/components/DateTimePicker.d.ts +4 -0
  71. package/dist/components/Drawer/Drawer.cjs +271 -0
  72. package/dist/components/Drawer/Drawer.cjs.map +1 -0
  73. package/dist/components/Drawer/Drawer.d.ts +51 -0
  74. package/dist/components/Drawer/Drawer.js +271 -0
  75. package/dist/components/Drawer/Drawer.js.map +1 -0
  76. package/dist/components/Drawer/Drawer.sx.d.ts +23 -0
  77. package/dist/components/Drawer/DrawerContext.d.ts +18 -0
  78. package/dist/components/Drawer/DrawerItem.d.ts +35 -0
  79. package/dist/components/Drawer/index.d.ts +6 -0
  80. package/dist/components/Drawer.d.ts +6 -0
  81. package/dist/components/Icon/Icon.cjs +44 -3
  82. package/dist/components/Icon/Icon.cjs.map +1 -1
  83. package/dist/components/Icon/Icon.d.ts +34 -1
  84. package/dist/components/Icon/Icon.js +44 -3
  85. package/dist/components/Icon/Icon.js.map +1 -1
  86. package/dist/components/Input/Input.cjs +173 -3
  87. package/dist/components/Input/Input.cjs.map +1 -1
  88. package/dist/components/Input/Input.d.ts +20 -15
  89. package/dist/components/Input/Input.definitions.d.ts +5 -2
  90. package/dist/components/Input/Input.helpers.d.ts +14 -0
  91. package/dist/components/Input/Input.js +172 -2
  92. package/dist/components/Input/Input.js.map +1 -1
  93. package/dist/components/Input/Input.sx.d.ts +8 -0
  94. package/dist/components/Input/Input.types.d.ts +1 -0
  95. package/dist/components/Input/index.d.ts +2 -1
  96. package/dist/components/Input.d.ts +4 -0
  97. package/dist/components/InputGroup/InputGroup.cjs +104 -91
  98. package/dist/components/InputGroup/InputGroup.cjs.map +1 -1
  99. package/dist/components/InputGroup/InputGroup.d.ts +37 -1
  100. package/dist/components/InputGroup/InputGroup.definitions.d.ts +6 -0
  101. package/dist/components/InputGroup/InputGroup.js +106 -93
  102. package/dist/components/InputGroup/InputGroup.js.map +1 -1
  103. package/dist/components/Modal/Modal.cjs +226 -116
  104. package/dist/components/Modal/Modal.cjs.map +1 -1
  105. package/dist/components/Modal/Modal.d.ts +38 -2
  106. package/dist/components/Modal/Modal.js +227 -117
  107. package/dist/components/Modal/Modal.js.map +1 -1
  108. package/dist/components/Modal/ModalFooter.d.ts +9 -1
  109. package/dist/components/Modal/index.d.ts +5 -0
  110. package/dist/components/PageLoader/PageLoader.cjs +61 -0
  111. package/dist/components/PageLoader/PageLoader.cjs.map +1 -0
  112. package/dist/components/PageLoader/PageLoader.d.ts +38 -0
  113. package/dist/components/PageLoader/PageLoader.js +61 -0
  114. package/dist/components/PageLoader/PageLoader.js.map +1 -0
  115. package/dist/components/PageLoader/index.d.ts +2 -0
  116. package/dist/components/PageLoader.d.ts +6 -0
  117. package/dist/components/ScrollTopButton/ScrollTopButton.cjs +79 -0
  118. package/dist/components/ScrollTopButton/ScrollTopButton.cjs.map +1 -0
  119. package/dist/components/ScrollTopButton/ScrollTopButton.d.ts +48 -0
  120. package/dist/components/ScrollTopButton/ScrollTopButton.js +79 -0
  121. package/dist/components/ScrollTopButton/ScrollTopButton.js.map +1 -0
  122. package/dist/components/ScrollTopButton/index.d.ts +4 -0
  123. package/dist/components/ScrollTopButton/scrollToTop.d.ts +29 -0
  124. package/dist/components/ScrollTopButton.d.ts +6 -0
  125. package/dist/components/Select/Select.cjs +446 -4
  126. package/dist/components/Select/Select.cjs.map +1 -1
  127. package/dist/components/Select/Select.d.ts +33 -13
  128. package/dist/components/Select/Select.definitions.d.ts +3 -0
  129. package/dist/components/Select/Select.helpers.d.ts +28 -0
  130. package/dist/components/Select/Select.js +445 -3
  131. package/dist/components/Select/Select.js.map +1 -1
  132. package/dist/components/Select/Select.sx.d.ts +7 -0
  133. package/dist/components/Select/Select.types.d.ts +1 -0
  134. package/dist/components/Select/_parts/SelectMenuItem.d.ts +20 -0
  135. package/dist/components/Select/_parts/SelectSearchHeader.d.ts +15 -0
  136. package/dist/components/Select/_parts/SelectValue.d.ts +22 -0
  137. package/dist/components/Select/index.d.ts +2 -1
  138. package/dist/components/Select.d.ts +4 -0
  139. package/dist/components/Stat/Stat.cjs +1 -1
  140. package/dist/components/Stat/Stat.js +1 -1
  141. package/dist/components/Stepper/Stepper.cjs +4 -1
  142. package/dist/components/Stepper/Stepper.cjs.map +1 -1
  143. package/dist/components/Stepper/Stepper.d.ts +5 -0
  144. package/dist/components/Stepper/Stepper.js +4 -1
  145. package/dist/components/Stepper/Stepper.js.map +1 -1
  146. package/dist/components/_shared/formField.sx.d.ts +33 -0
  147. package/dist/components/_shared/resolvePreset.d.ts +18 -0
  148. package/dist/formField.sx-CQ1mbk9M.cjs +76 -0
  149. package/dist/formField.sx-CQ1mbk9M.cjs.map +1 -0
  150. package/dist/formField.sx-DfVbMe0V.js +77 -0
  151. package/dist/formField.sx-DfVbMe0V.js.map +1 -0
  152. package/dist/hooks/Wizard/Wizard.cjs +7 -0
  153. package/dist/hooks/Wizard/Wizard.cjs.map +1 -0
  154. package/dist/hooks/Wizard/Wizard.js +7 -0
  155. package/dist/hooks/Wizard/Wizard.js.map +1 -0
  156. package/dist/hooks/Wizard/WizardContext.d.ts +67 -0
  157. package/dist/hooks/Wizard/index.d.ts +3 -0
  158. package/dist/hooks/Wizard/useWizard.d.ts +9 -0
  159. package/dist/hooks/Wizard.d.ts +2 -0
  160. package/dist/index.cjs +99 -1
  161. package/dist/index.cjs.map +1 -1
  162. package/dist/index.d.ts +3 -0
  163. package/dist/index.js +31 -2
  164. package/dist/index.js.map +1 -1
  165. package/dist/mui.d.ts +5 -0
  166. package/dist/resolvePreset-B-IB0ehH.js +15 -0
  167. package/dist/resolvePreset-B-IB0ehH.js.map +1 -0
  168. package/dist/resolvePreset-CT3kU-K2.cjs +14 -0
  169. package/dist/resolvePreset-CT3kU-K2.cjs.map +1 -0
  170. package/dist/styles.css +3 -112
  171. package/dist/theme/componentStyles.d.ts +32 -0
  172. package/dist/theme/tokens.d.ts +28 -0
  173. package/dist/useWizard-CWdIxZzX.cjs +94 -0
  174. package/dist/useWizard-CWdIxZzX.cjs.map +1 -0
  175. package/dist/useWizard-CWq--C3o.js +95 -0
  176. package/dist/useWizard-CWq--C3o.js.map +1 -0
  177. package/package.json +1 -1
  178. package/src/components/ActionMenu/ActionMenu.stories.tsx +230 -0
  179. package/src/components/ActionMenu/ActionMenu.tsx +174 -0
  180. package/src/components/ActionMenu/index.ts +2 -0
  181. package/src/components/AppBar/AppBar.stories.tsx +272 -0
  182. package/src/components/AppBar/AppBar.sx.ts +32 -0
  183. package/src/components/AppBar/AppBar.tsx +123 -0
  184. package/src/components/AppBar/AppBarBrand.tsx +120 -0
  185. package/src/components/AppBar/AppBarContext.ts +25 -0
  186. package/src/components/AppBar/AppBarMenuToggle.tsx +90 -0
  187. package/src/components/AppBar/AppBarUserMenu.tsx +217 -0
  188. package/src/components/AppBar/index.ts +25 -0
  189. package/src/components/Autocomplete/Autocomplete.definitions.ts +223 -0
  190. package/src/components/Autocomplete/Autocomplete.helpers.ts +60 -0
  191. package/src/components/Autocomplete/Autocomplete.stories.tsx +363 -2
  192. package/src/components/Autocomplete/Autocomplete.sx.ts +30 -0
  193. package/src/components/Autocomplete/Autocomplete.tsx +312 -90
  194. package/src/components/Autocomplete/Autocomplete.types.ts +13 -0
  195. package/src/components/Autocomplete/_parts/AutocompleteChips.tsx +55 -0
  196. package/src/components/Autocomplete/_parts/AutocompleteLoader.tsx +17 -0
  197. package/src/components/Autocomplete/_parts/AutocompleteOption.tsx +31 -0
  198. package/src/components/Autocomplete/index.ts +12 -1
  199. package/src/components/Avatar/Avatar.definitions.ts +162 -0
  200. package/src/components/Avatar/Avatar.stories.tsx +205 -1
  201. package/src/components/Avatar/Avatar.tsx +166 -103
  202. package/src/components/Card/Card.stories.tsx +205 -16
  203. package/src/components/Card/Card.sx.ts +104 -0
  204. package/src/components/Card/Card.tsx +191 -35
  205. package/src/components/Card/index.ts +9 -1
  206. package/src/components/DatePicker/DatePicker.definitions.ts +24 -1
  207. package/src/components/DatePicker/DatePicker.helpers.ts +24 -0
  208. package/src/components/DatePicker/DatePicker.stories.tsx +29 -2
  209. package/src/components/DatePicker/DatePicker.sx.ts +33 -0
  210. package/src/components/DatePicker/DatePicker.tsx +163 -139
  211. package/src/components/DatePicker/DatePicker.types.ts +10 -0
  212. package/src/components/DatePicker/index.ts +9 -1
  213. package/src/components/DateTimePicker/DateTimePicker.definitions.ts +24 -0
  214. package/src/components/DateTimePicker/DateTimePicker.helpers.ts +38 -0
  215. package/src/components/DateTimePicker/DateTimePicker.stories.tsx +29 -1
  216. package/src/components/DateTimePicker/DateTimePicker.sx.ts +30 -0
  217. package/src/components/DateTimePicker/DateTimePicker.tsx +200 -166
  218. package/src/components/DateTimePicker/DateTimePicker.types.ts +10 -0
  219. package/src/components/DateTimePicker/index.ts +9 -1
  220. package/src/components/Drawer/Drawer.stories.tsx +270 -0
  221. package/src/components/Drawer/Drawer.sx.ts +106 -0
  222. package/src/components/Drawer/Drawer.tsx +214 -0
  223. package/src/components/Drawer/DrawerContext.ts +26 -0
  224. package/src/components/Drawer/DrawerItem.tsx +110 -0
  225. package/src/components/Drawer/index.ts +10 -0
  226. package/src/components/Flyout/Flyout.stories.tsx +26 -18
  227. package/src/components/Icon/Icon.stories.tsx +68 -1
  228. package/src/components/Icon/Icon.tsx +87 -6
  229. package/src/components/Input/Input.definitions.ts +74 -2
  230. package/src/components/Input/Input.helpers.ts +49 -0
  231. package/src/components/Input/Input.stories.tsx +116 -4
  232. package/src/components/Input/Input.sx.ts +42 -0
  233. package/src/components/Input/Input.tsx +117 -162
  234. package/src/components/Input/Input.types.ts +10 -0
  235. package/src/components/Input/index.ts +9 -1
  236. package/src/components/InputGroup/InputGroup.definitions.ts +158 -0
  237. package/src/components/InputGroup/InputGroup.stories.tsx +159 -28
  238. package/src/components/InputGroup/InputGroup.tsx +159 -116
  239. package/src/components/Modal/Modal.stories.tsx +434 -6
  240. package/src/components/Modal/Modal.tsx +303 -121
  241. package/src/components/Modal/ModalFooter.tsx +22 -12
  242. package/src/components/Modal/index.ts +6 -1
  243. package/src/components/PageLoader/PageLoader.stories.tsx +217 -0
  244. package/src/components/PageLoader/PageLoader.tsx +96 -0
  245. package/src/components/PageLoader/index.ts +2 -0
  246. package/src/components/ScrollTopButton/ScrollTopButton.stories.tsx +158 -0
  247. package/src/components/ScrollTopButton/ScrollTopButton.tsx +135 -0
  248. package/src/components/ScrollTopButton/index.ts +8 -0
  249. package/src/components/ScrollTopButton/scrollToTop.ts +37 -0
  250. package/src/components/Select/Select.definitions.ts +114 -0
  251. package/src/components/Select/Select.helpers.ts +71 -0
  252. package/src/components/Select/Select.stories.tsx +126 -8
  253. package/src/components/Select/Select.sx.ts +14 -0
  254. package/src/components/Select/Select.tsx +246 -285
  255. package/src/components/Select/Select.types.ts +15 -0
  256. package/src/components/Select/_parts/SelectMenuItem.tsx +40 -0
  257. package/src/components/Select/_parts/SelectSearchHeader.tsx +51 -0
  258. package/src/components/Select/_parts/SelectValue.tsx +96 -0
  259. package/src/components/Select/index.ts +14 -1
  260. package/src/components/Stepper/Stepper.tsx +17 -1
  261. package/src/components/Tooltip/Tooltip.stories.tsx +15 -3
  262. package/src/components/_shared/formField.sx.ts +118 -0
  263. package/src/components/_shared/resolvePreset.ts +35 -0
  264. package/src/hooks/Wizard/Wizard.stories.tsx +301 -0
  265. package/src/hooks/Wizard/WizardContext.tsx +166 -0
  266. package/src/hooks/Wizard/index.ts +6 -0
  267. package/src/hooks/Wizard/useWizard.ts +13 -0
  268. package/src/index.ts +17 -1
  269. package/src/mui.ts +44 -0
  270. package/src/theme/componentStyles.ts +47 -0
  271. package/src/theme/tokens.ts +43 -0
  272. package/dist/DatePicker-BSNboVhN.js +0 -201
  273. package/dist/DatePicker-BSNboVhN.js.map +0 -1
  274. package/dist/DatePicker-BoqxWAhj.cjs +0 -200
  275. package/dist/DatePicker-BoqxWAhj.cjs.map +0 -1
  276. package/dist/Input-DFHs7cJ_.js +0 -171
  277. package/dist/Input-DFHs7cJ_.js.map +0 -1
  278. package/dist/Input-c8MwNNPg.cjs +0 -170
  279. package/dist/Input-c8MwNNPg.cjs.map +0 -1
  280. package/dist/Select-BO2N56sm.cjs +0 -411
  281. package/dist/Select-BO2N56sm.cjs.map +0 -1
  282. package/dist/Select-BcLkyHSE.js +0 -412
  283. package/dist/Select-BcLkyHSE.js.map +0 -1
  284. package/dist/index.css +0 -3
@@ -0,0 +1,110 @@
1
+ import React, { type ReactNode, type MouseEvent } from 'react';
2
+ import { Box, Tooltip, Typography } from '@mui/material';
3
+ import type { SxProps, Theme } from '@mui/material/styles';
4
+
5
+ import { useDrawerContext } from './DrawerContext';
6
+ import { buildDrawerItemSx } from './Drawer.sx';
7
+
8
+ export interface DrawerItemProps {
9
+ /** Icono del item. Se muestra siempre (expanded y collapsed). */
10
+ icon?: ReactNode;
11
+ /** Texto del item. Se oculta cuando el drawer está colapsado (muestra tooltip). */
12
+ label: ReactNode;
13
+ /** Handler de click. */
14
+ onClick?: (event: MouseEvent<HTMLDivElement>) => void;
15
+ /** Marca el item como activo (destaca color y fondo). */
16
+ active?: boolean;
17
+ /** Marca el item como "destructivo" (p.ej. cerrar sesión): color error. */
18
+ danger?: boolean;
19
+ /** Deshabilita click + bajo opacidad. */
20
+ disabled?: boolean;
21
+ /** Contenido adicional a la derecha del label (badge, count, chevron). */
22
+ endAdornment?: ReactNode;
23
+ /** sx override del consumer, se mergea al final. */
24
+ sx?: SxProps<Theme>;
25
+ className?: string;
26
+ }
27
+
28
+ /**
29
+ * Item de un Drawer de shared-library. Lee el estado `collapsed` del
30
+ * DrawerContext para adaptar layout y mostrar tooltip en modo mini.
31
+ *
32
+ * Uso típico:
33
+ * ```tsx
34
+ * <Drawer collapsed={collapsed} onToggleCollapse={toggle}>
35
+ * <DrawerItem icon={<HomeIcon />} label="Inicio" active />
36
+ * <DrawerItem icon={<UserIcon />} label="Perfil" />
37
+ * </Drawer>
38
+ * ```
39
+ */
40
+ export function DrawerItem({
41
+ icon,
42
+ label,
43
+ onClick,
44
+ active = false,
45
+ danger = false,
46
+ disabled = false,
47
+ endAdornment,
48
+ sx,
49
+ className,
50
+ }: DrawerItemProps) {
51
+ const { collapsed } = useDrawerContext();
52
+
53
+ const baseSx = buildDrawerItemSx({ collapsed, active, danger });
54
+
55
+ const mergedSx: SxProps<Theme> = [
56
+ baseSx,
57
+ disabled && { pointerEvents: 'none', opacity: 0.5 },
58
+ ...(Array.isArray(sx) ? sx : sx ? [sx] : []),
59
+ ].filter(Boolean) as SxProps<Theme>;
60
+
61
+ const content = (
62
+ <Box
63
+ role="button"
64
+ tabIndex={disabled ? -1 : 0}
65
+ aria-disabled={disabled}
66
+ onClick={disabled ? undefined : onClick}
67
+ onKeyDown={(event) => {
68
+ if (disabled) return;
69
+ if (event.key === 'Enter' || event.key === ' ') {
70
+ event.preventDefault();
71
+ onClick?.(event as unknown as MouseEvent<HTMLDivElement>);
72
+ }
73
+ }}
74
+ className={className}
75
+ sx={mergedSx}
76
+ >
77
+ {icon !== undefined && (
78
+ <Box className="drawer-item__icon" component="span">
79
+ {icon}
80
+ </Box>
81
+ )}
82
+ <Typography
83
+ component="span"
84
+ variant="body2"
85
+ className="drawer-item__label"
86
+ sx={{ fontWeight: active ? 600 : 400 }}
87
+ >
88
+ {label}
89
+ </Typography>
90
+ {!collapsed && endAdornment && (
91
+ <Box component="span" sx={{ flexShrink: 0, ml: 'auto' }}>
92
+ {endAdornment}
93
+ </Box>
94
+ )}
95
+ </Box>
96
+ );
97
+
98
+ // Cuando está colapsado, envolvemos en tooltip para revelar el label al hover.
99
+ if (collapsed && typeof label === 'string') {
100
+ return (
101
+ <Tooltip title={label} placement="right" arrow>
102
+ {content}
103
+ </Tooltip>
104
+ );
105
+ }
106
+
107
+ return content;
108
+ }
109
+
110
+ export default DrawerItem;
@@ -0,0 +1,10 @@
1
+ export { Drawer, default } from './Drawer';
2
+ export { DrawerItem } from './DrawerItem';
3
+ export { useDrawerContext } from './DrawerContext';
4
+ export type {
5
+ DrawerProps,
6
+ DrawerVariant,
7
+ DrawerAnchor,
8
+ } from './Drawer';
9
+ export type { DrawerItemProps } from './DrawerItem';
10
+ export type { DrawerContextValue } from './DrawerContext';
@@ -1,7 +1,8 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
2
  import React, { useState } from 'react';
3
- import { Box, Button, List, ListItem, ListItemText, TextField, Typography } from '@mui/material';
3
+ import { Box, Button, List, ListItem, ListItemText, Typography } from '@mui/material';
4
4
  import Flyout from './Flyout'; // Adjust the import path if your Flyout.tsx is in a different directory
5
+ import { Input } from '../Input/Input';
5
6
 
6
7
  // Define the Meta for the Flyout component
7
8
  const meta: Meta<typeof Flyout> = {
@@ -55,6 +56,19 @@ export default meta;
55
56
  type Story = StoryObj<typeof Flyout>;
56
57
 
57
58
  // --- Helper component for demonstration content ---
59
+ const DefaultValueInput: React.FC = () => {
60
+ const [value, setValue] = useState<string | number>('Some text');
61
+ return (
62
+ <Box sx={{ my: 2 }}>
63
+ <Input
64
+ label="Input Field"
65
+ value={value}
66
+ onChange={(next) => setValue(next)}
67
+ />
68
+ </Box>
69
+ );
70
+ };
71
+
58
72
  const DemoContent: React.FC = () => (
59
73
  <Box>
60
74
  <Typography variant="body1" paragraph>
@@ -76,13 +90,7 @@ const DemoContent: React.FC = () => (
76
90
  </ListItem>
77
91
  ))}
78
92
  </List>
79
- <TextField
80
- label="Input Field"
81
- variant="outlined"
82
- fullWidth
83
- margin="normal"
84
- defaultValue="Some text"
85
- />
93
+ <DefaultValueInput />
86
94
  <Button variant="contained" color="primary" sx={{ mt: 2 }}>
87
95
  Action Button
88
96
  </Button>
@@ -247,16 +255,16 @@ export const CustomContent: Story = {
247
255
  <Flyout {...args} open={isOpen} onClose={() => setIsOpen(false)}>
248
256
  <Box sx={{ p: 2 }}>
249
257
  <Typography variant="h6" gutterBottom>Custom Form</Typography>
250
- <TextField
251
- label="Your Message"
252
- multiline
253
- rows={4}
254
- fullWidth
255
- variant="outlined"
256
- value={customText}
257
- onChange={(e) => setCustomText(e.target.value)}
258
- sx={{ mb: 2 }}
259
- />
258
+ <Box sx={{ mb: 2 }}>
259
+ <Input
260
+ label="Your Message"
261
+ multiline
262
+ rows={4}
263
+ fullWidth
264
+ value={customText}
265
+ onChange={(next) => setCustomText(String(next))}
266
+ />
267
+ </Box>
260
268
  <Button variant="contained" color="secondary">
261
269
  Submit Custom Content
262
270
  </Button>
@@ -8,6 +8,12 @@ const meta: Meta<typeof Icon> = {
8
8
  component: Icon,
9
9
  parameters: {
10
10
  layout: 'centered',
11
+ docs: {
12
+ description: {
13
+ component:
14
+ 'Componente Icon con soporte para 3 fuentes: `children` (elemento MUI), `path` (string SVG inline, para los iconos custom de Metronic) y `url` (ruta a un archivo `.svg`).',
15
+ },
16
+ },
11
17
  },
12
18
  tags: ['autodocs'],
13
19
  };
@@ -15,9 +21,11 @@ const meta: Meta<typeof Icon> = {
15
21
  export default meta;
16
22
  type Story = StoryObj<typeof Icon>;
17
23
 
24
+ // ── Modo legacy: children ──────────────────────────────────────────────
25
+
18
26
  export const Default: Story = {
19
27
  args: {
20
- children: <NotificationsIcon />
28
+ children: <NotificationsIcon />,
21
29
  },
22
30
  };
23
31
 
@@ -52,3 +60,62 @@ export const LargeWhiteIcon: Story = {
52
60
  badgeColor: 'primary',
53
61
  },
54
62
  };
63
+
64
+ // ── Nuevas fuentes: path + url ────────────────────────────────────────
65
+
66
+ export const FromPathD: Story = {
67
+ args: {
68
+ path: 'M12 2L2 22h20L12 2zm0 3.83L19.17 20H4.83L12 5.83zM11 16h2v2h-2v-2zm0-6h2v5h-2v-5z',
69
+ color: '#f59e0b',
70
+ size: 'lg',
71
+ },
72
+ parameters: {
73
+ docs: {
74
+ description: {
75
+ story:
76
+ 'Renderiza un SVG a partir del atributo `d` de un `<path>`. Es la forma en que Metronic suele entregar iconos custom.',
77
+ },
78
+ },
79
+ },
80
+ };
81
+
82
+ export const FromFullSvg: Story = {
83
+ args: {
84
+ path: '<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24" fill="currentColor"><circle cx="12" cy="12" r="10"/><path d="M12 6v6l4 2" stroke="white" stroke-width="2" fill="none"/></svg>',
85
+ color: '#2563eb',
86
+ size: 'lg',
87
+ },
88
+ parameters: {
89
+ docs: {
90
+ description: {
91
+ story:
92
+ 'Si `path` contiene un `<svg>` completo (con `viewBox`, múltiples paths, etc), se inyecta tal cual.',
93
+ },
94
+ },
95
+ },
96
+ };
97
+
98
+ export const FromUrl: Story = {
99
+ args: {
100
+ url: 'https://upload.wikimedia.org/wikipedia/commons/4/4f/SVG_Logo.svg',
101
+ alt: 'SVG logo',
102
+ size: 'xl',
103
+ },
104
+ parameters: {
105
+ docs: {
106
+ description: {
107
+ story:
108
+ 'Renderiza un `<img>` apuntando a un archivo `.svg`. Útil para assets locales (p.ej. `/public/icons/foo.svg`).',
109
+ },
110
+ },
111
+ },
112
+ };
113
+
114
+ export const PathWithBadge: Story = {
115
+ args: {
116
+ path: 'M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6v2z',
117
+ badge: '9+',
118
+ badgeColor: 'error',
119
+ size: 'md',
120
+ },
121
+ };
@@ -1,10 +1,43 @@
1
- import React, { ReactNode, useMemo } from 'react';
2
- import { Badge, SvgIconProps, styled } from '@mui/material';
1
+ import React, { type ReactNode, useMemo } from 'react';
2
+ import { Badge, styled } from '@mui/material';
3
3
 
4
4
  export type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';
5
5
 
6
6
  export interface IconProps {
7
- children: ReactNode;
7
+ /**
8
+ * Contenido icono. Modo legacy: acepta un elemento MUI o SVG ya armado.
9
+ * Si se usa junto con `path` o `url`, `children` tiene prioridad.
10
+ */
11
+ children?: ReactNode;
12
+ /**
13
+ * Ruta SVG inline (el contenido del atributo `d` de un `<path>`). Útil para
14
+ * los iconos custom de Metronic que vienen como strings de path.
15
+ *
16
+ * ```tsx
17
+ * <Icon path="M12 2L2 22h20L12 2z" />
18
+ * ```
19
+ *
20
+ * Si el string contiene el tag `<svg>` completo (no solo el `d`), también
21
+ * se soporta y se inyecta tal cual via `dangerouslySetInnerHTML`.
22
+ */
23
+ path?: string;
24
+ /**
25
+ * URL a un archivo `.svg` (asset local o remoto). Se renderiza vía `<img>`.
26
+ *
27
+ * ```tsx
28
+ * <Icon url="/assets/icons/custom-warning.svg" />
29
+ * ```
30
+ */
31
+ url?: string;
32
+ /**
33
+ * Alt text cuando se usa `url`. Default: `"icon"`.
34
+ */
35
+ alt?: string;
36
+ /**
37
+ * ViewBox cuando se usa `path`. Default: `"0 0 24 24"`. Ignorado si `path`
38
+ * ya viene como `<svg>` completo.
39
+ */
40
+ viewBox?: string;
8
41
  color?: string;
9
42
  outlined?: boolean;
10
43
  spin?: boolean;
@@ -36,8 +69,12 @@ const StyledIcon = styled('span')<{
36
69
  outlined?: boolean;
37
70
  }>(({ color, fontSize, spin, outlined }) => ({
38
71
  display: 'inline-flex',
72
+ alignItems: 'center',
73
+ justifyContent: 'center',
39
74
  color: color,
40
75
  fontSize: fontSize,
76
+ width: fontSize,
77
+ height: fontSize,
41
78
  animation: spin ? 'spin 1s linear infinite' : undefined,
42
79
  border: outlined ? '1px solid currentColor' : undefined,
43
80
  borderRadius: '50%',
@@ -46,17 +83,31 @@ const StyledIcon = styled('span')<{
46
83
  '0%': { transform: 'rotate(0deg)' },
47
84
  '100%': { transform: 'rotate(360deg)' },
48
85
  },
86
+ '& svg': {
87
+ width: '100%',
88
+ height: '100%',
89
+ fill: 'currentColor',
90
+ display: 'block',
91
+ },
92
+ '& img': {
93
+ width: '100%',
94
+ height: '100%',
95
+ display: 'block',
96
+ },
49
97
  }));
50
98
 
51
99
  export const Icon: React.FC<IconProps> = ({
52
100
  children,
101
+ path,
102
+ url,
103
+ alt = 'icon',
104
+ viewBox = '0 0 24 24',
53
105
  color = 'var(--primary-color)',
54
106
  outlined = false,
55
107
  spin = false,
56
108
  badge,
57
109
  badgeColor = 'primary',
58
110
  badgePosition = { vertical: 'bottom', horizontal: 'right' },
59
- badgeSize = 'medium',
60
111
  size = 'sm',
61
112
  black,
62
113
  white,
@@ -70,6 +121,36 @@ export const Icon: React.FC<IconProps> = ({
70
121
 
71
122
  const iconSize = sizeMap[size];
72
123
 
124
+ // Resolver el contenido según la prop activa.
125
+ const content = useMemo(() => {
126
+ if (children) return children;
127
+
128
+ if (path) {
129
+ const trimmed = path.trim();
130
+ // Si es un SVG completo (empieza con <svg), lo inyectamos tal cual.
131
+ if (trimmed.startsWith('<svg')) {
132
+ return <span dangerouslySetInnerHTML={{ __html: trimmed }} />;
133
+ }
134
+ // Si no, asumimos que es el atributo `d` de un <path>.
135
+ return (
136
+ <svg
137
+ xmlns="http://www.w3.org/2000/svg"
138
+ viewBox={viewBox}
139
+ fill="currentColor"
140
+ aria-hidden="true"
141
+ >
142
+ <path d={trimmed} />
143
+ </svg>
144
+ );
145
+ }
146
+
147
+ if (url) {
148
+ return <img src={url} alt={alt} />;
149
+ }
150
+
151
+ return null;
152
+ }, [children, path, url, alt, viewBox]);
153
+
73
154
  return (
74
155
  <Badge
75
156
  badgeContent={badge}
@@ -85,10 +166,10 @@ export const Icon: React.FC<IconProps> = ({
85
166
  outlined={outlined}
86
167
  className={`hsi-icon ${className || ''}`}
87
168
  >
88
- {children}
169
+ {content}
89
170
  </StyledIcon>
90
171
  </Badge>
91
172
  );
92
173
  };
93
174
 
94
- export default Icon;
175
+ export default Icon;
@@ -42,7 +42,7 @@ export const NumberInputExample = () => {
42
42
  `;
43
43
 
44
44
  export const EmailInputDefinition = `
45
- import React, { useState } => from 'react';
45
+ import React, { useState } from 'react';
46
46
  import { Input } from './Input'; // Ajusta la ruta si es necesario
47
47
  import { Box, Typography } from '@mui/material';
48
48
 
@@ -149,7 +149,7 @@ export const DisabledInputExample = () => {
149
149
  `;
150
150
 
151
151
  export const ReadOnlyInputDefinition = `
152
- import React, { useState } => from 'react';
152
+ import React, { useState } from 'react';
153
153
  import { Input } from './Input'; // Ajusta la ruta si es necesario
154
154
  import { Box, Typography } from '@mui/material';
155
155
 
@@ -250,3 +250,75 @@ export const FullWidthInputExample = () => {
250
250
  );
251
251
  };
252
252
  `;
253
+
254
+ export const LabelPositionFloatingDefinition = `
255
+ import React, { useState } from 'react';
256
+ import { Input } from './Input'; // Ajusta la ruta si es necesario
257
+ import { Box } from '@mui/material';
258
+
259
+ export const LabelPositionExample = () => {
260
+ const [outside, setOutside] = useState('Outside (default)');
261
+ const [floating, setFloating] = useState('Floating');
262
+ return (
263
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, width: 300 }}>
264
+ <Input
265
+ label="Label outside"
266
+ value={outside}
267
+ onChange={setOutside}
268
+ labelPosition="outside"
269
+ />
270
+ <Input
271
+ label="Label floating (MUI clásico)"
272
+ value={floating}
273
+ onChange={setFloating}
274
+ labelPosition="floating"
275
+ />
276
+ </Box>
277
+ );
278
+ };
279
+ `;
280
+
281
+ export const CustomBorderRadiusDefinition = `
282
+ import React, { useState } from 'react';
283
+ import { Input } from './Input'; // Ajusta la ruta si es necesario
284
+ import { Box } from '@mui/material';
285
+
286
+ export const CustomBorderRadiusExample = () => {
287
+ const [v, setV] = useState('Texto');
288
+ return (
289
+ <Box sx={{ display: 'flex', flexDirection: 'column', gap: 3, width: 300 }}>
290
+ <Input label="Sin radius" value={v} onChange={setV} borderRadius={0} />
291
+ <Input label="Radius 4px" value={v} onChange={setV} borderRadius={4} />
292
+ <Input label="Default (10px)" value={v} onChange={setV} />
293
+ <Input label="Pill (24px)" value={v} onChange={setV} borderRadius={24} />
294
+ </Box>
295
+ );
296
+ };
297
+ `;
298
+
299
+ export const CustomStylingDefinition = `
300
+ import React, { useState } from 'react';
301
+ import { Input } from './Input'; // Ajusta la ruta si es necesario
302
+ import { Box } from '@mui/material';
303
+
304
+ export const CustomStylingExample = () => {
305
+ const [v, setV] = useState('Custom completo');
306
+ return (
307
+ <Box sx={{ width: 300 }}>
308
+ <Input
309
+ label="Combinado: bg + borderColor + label color"
310
+ value={v}
311
+ onChange={setV}
312
+ sx={{
313
+ '& .MuiInputLabel-root': { color: 'primary.main' },
314
+ '& .MuiOutlinedInput-root': { bgcolor: '#fff7e6' },
315
+ '& .MuiOutlinedInput-notchedOutline': {
316
+ borderColor: 'warning.main',
317
+ borderWidth: 2,
318
+ },
319
+ }}
320
+ />
321
+ </Box>
322
+ );
323
+ };
324
+ `;
@@ -0,0 +1,49 @@
1
+ import type { InputHTMLAttributes } from 'react';
2
+ import type { TextFieldProps } from '@mui/material';
3
+ import type { InputType, LabelPosition } from './Input';
4
+
5
+ /**
6
+ * Convierte el valor raw del evento al tipo apropiado.
7
+ * Para type="number" intenta parsear a número; si falla, devuelve el raw
8
+ * (permite estados intermedios como "" o "-" mientras el usuario tipea).
9
+ */
10
+ export const parseValue = (raw: string, type: InputType): string | number => {
11
+ if (type !== 'number') return raw;
12
+ if (raw === '' || raw === '-') return raw;
13
+ const n = parseFloat(raw);
14
+ return isNaN(n) ? raw : n;
15
+ };
16
+
17
+ /**
18
+ * Construye los slotProps del TextField consolidando htmlInput + inputLabel.
19
+ * Maneja los atributos min/max cuando type="number" y readOnly.
20
+ */
21
+ export const buildSlotProps = (
22
+ type: InputType,
23
+ min: number | undefined,
24
+ max: number | undefined,
25
+ customSlotProps: TextFieldProps['slotProps'],
26
+ customInputProps: InputHTMLAttributes<HTMLInputElement> | undefined,
27
+ _labelPosition: LabelPosition,
28
+ readOnly?: boolean,
29
+ ): TextFieldProps['slotProps'] => {
30
+ const numberAttrs =
31
+ type === 'number'
32
+ ? { min: min ?? Number.NEGATIVE_INFINITY, ...(max !== undefined && { max }) }
33
+ : {};
34
+
35
+ return {
36
+ ...customSlotProps,
37
+ htmlInput: {
38
+ ...customInputProps,
39
+ ...(customSlotProps as any)?.htmlInput,
40
+ ...numberAttrs,
41
+ ...(readOnly && { readOnly: true }),
42
+ },
43
+ // Dejamos que MUI maneje el shrink nativamente (animación inside → up).
44
+ // El consumidor puede forzar shrink con slotProps.inputLabel.shrink=true si lo necesita.
45
+ inputLabel: {
46
+ ...(customSlotProps as any)?.inputLabel,
47
+ },
48
+ };
49
+ };