@soyfri/shared-library 1.5.0 → 2.0.0-beta.0

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 (283) hide show
  1. package/dist/components/ActionMenu/ActionMenu.cjs +107 -0
  2. package/dist/components/ActionMenu/ActionMenu.cjs.map +1 -0
  3. package/dist/components/ActionMenu/ActionMenu.d.ts +60 -0
  4. package/dist/components/ActionMenu/ActionMenu.js +107 -0
  5. package/dist/components/ActionMenu/ActionMenu.js.map +1 -0
  6. package/dist/components/ActionMenu/index.d.ts +2 -0
  7. package/dist/components/ActionMenu.d.ts +6 -0
  8. package/dist/components/AppBar/AppBar.cjs +346 -0
  9. package/dist/components/AppBar/AppBar.cjs.map +1 -0
  10. package/dist/components/AppBar/AppBar.d.ts +55 -0
  11. package/dist/components/AppBar/AppBar.js +346 -0
  12. package/dist/components/AppBar/AppBar.js.map +1 -0
  13. package/dist/components/AppBar/AppBar.sx.d.ts +12 -0
  14. package/dist/components/AppBar/AppBarBrand.d.ts +31 -0
  15. package/dist/components/AppBar/AppBarContext.d.ts +18 -0
  16. package/dist/components/AppBar/AppBarMenuToggle.d.ts +39 -0
  17. package/dist/components/AppBar/AppBarUserMenu.d.ts +65 -0
  18. package/dist/components/AppBar/index.d.ts +12 -0
  19. package/dist/components/AppBar.d.ts +6 -0
  20. package/dist/components/Autocomplete/Autocomplete.cjs +259 -54
  21. package/dist/components/Autocomplete/Autocomplete.cjs.map +1 -1
  22. package/dist/components/Autocomplete/Autocomplete.d.ts +64 -9
  23. package/dist/components/Autocomplete/Autocomplete.definitions.d.ts +6 -0
  24. package/dist/components/Autocomplete/Autocomplete.helpers.d.ts +18 -0
  25. package/dist/components/Autocomplete/Autocomplete.js +261 -56
  26. package/dist/components/Autocomplete/Autocomplete.js.map +1 -1
  27. package/dist/components/Autocomplete/Autocomplete.sx.d.ts +7 -0
  28. package/dist/components/Autocomplete/Autocomplete.types.d.ts +1 -0
  29. package/dist/components/Autocomplete/_parts/AutocompleteChips.d.ts +19 -0
  30. package/dist/components/Autocomplete/_parts/AutocompleteLoader.d.ts +9 -0
  31. package/dist/components/Autocomplete/_parts/AutocompleteOption.d.ts +19 -0
  32. package/dist/components/Autocomplete/index.d.ts +2 -1
  33. package/dist/components/Autocomplete.d.ts +4 -0
  34. package/dist/components/Avatar/Avatar.cjs +116 -79
  35. package/dist/components/Avatar/Avatar.cjs.map +1 -1
  36. package/dist/components/Avatar/Avatar.d.ts +16 -2
  37. package/dist/components/Avatar/Avatar.definitions.d.ts +11 -0
  38. package/dist/components/Avatar/Avatar.js +117 -80
  39. package/dist/components/Avatar/Avatar.js.map +1 -1
  40. package/dist/components/Card/Card.cjs +168 -9
  41. package/dist/components/Card/Card.cjs.map +1 -1
  42. package/dist/components/Card/Card.d.ts +78 -8
  43. package/dist/components/Card/Card.js +170 -11
  44. package/dist/components/Card/Card.js.map +1 -1
  45. package/dist/components/Card/Card.sx.d.ts +17 -0
  46. package/dist/components/Card/index.d.ts +4 -1
  47. package/dist/components/Card.d.ts +4 -0
  48. package/dist/components/DatePicker/DatePicker.cjs +201 -3
  49. package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
  50. package/dist/components/DatePicker/DatePicker.d.ts +47 -9
  51. package/dist/components/DatePicker/DatePicker.definitions.d.ts +1 -0
  52. package/dist/components/DatePicker/DatePicker.helpers.d.ts +7 -0
  53. package/dist/components/DatePicker/DatePicker.js +200 -2
  54. package/dist/components/DatePicker/DatePicker.js.map +1 -1
  55. package/dist/components/DatePicker/DatePicker.sx.d.ts +9 -0
  56. package/dist/components/DatePicker/DatePicker.types.d.ts +1 -0
  57. package/dist/components/DatePicker/index.d.ts +2 -1
  58. package/dist/components/DatePicker.d.ts +4 -0
  59. package/dist/components/DateTimePicker/DateTimePicker.cjs +152 -138
  60. package/dist/components/DateTimePicker/DateTimePicker.cjs.map +1 -1
  61. package/dist/components/DateTimePicker/DateTimePicker.d.ts +46 -9
  62. package/dist/components/DateTimePicker/DateTimePicker.definitions.d.ts +1 -0
  63. package/dist/components/DateTimePicker/DateTimePicker.helpers.d.ts +11 -0
  64. package/dist/components/DateTimePicker/DateTimePicker.js +152 -138
  65. package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
  66. package/dist/components/DateTimePicker/DateTimePicker.sx.d.ts +7 -0
  67. package/dist/components/DateTimePicker/DateTimePicker.types.d.ts +1 -0
  68. package/dist/components/DateTimePicker/index.d.ts +2 -1
  69. package/dist/components/DateTimePicker.d.ts +4 -0
  70. package/dist/components/Drawer/Drawer.cjs +271 -0
  71. package/dist/components/Drawer/Drawer.cjs.map +1 -0
  72. package/dist/components/Drawer/Drawer.d.ts +51 -0
  73. package/dist/components/Drawer/Drawer.js +271 -0
  74. package/dist/components/Drawer/Drawer.js.map +1 -0
  75. package/dist/components/Drawer/Drawer.sx.d.ts +23 -0
  76. package/dist/components/Drawer/DrawerContext.d.ts +18 -0
  77. package/dist/components/Drawer/DrawerItem.d.ts +35 -0
  78. package/dist/components/Drawer/index.d.ts +6 -0
  79. package/dist/components/Drawer.d.ts +6 -0
  80. package/dist/components/Icon/Icon.cjs +44 -3
  81. package/dist/components/Icon/Icon.cjs.map +1 -1
  82. package/dist/components/Icon/Icon.d.ts +34 -1
  83. package/dist/components/Icon/Icon.js +44 -3
  84. package/dist/components/Icon/Icon.js.map +1 -1
  85. package/dist/components/Input/Input.cjs +173 -3
  86. package/dist/components/Input/Input.cjs.map +1 -1
  87. package/dist/components/Input/Input.d.ts +20 -15
  88. package/dist/components/Input/Input.definitions.d.ts +5 -2
  89. package/dist/components/Input/Input.helpers.d.ts +14 -0
  90. package/dist/components/Input/Input.js +172 -2
  91. package/dist/components/Input/Input.js.map +1 -1
  92. package/dist/components/Input/Input.sx.d.ts +8 -0
  93. package/dist/components/Input/Input.types.d.ts +1 -0
  94. package/dist/components/Input/index.d.ts +2 -1
  95. package/dist/components/Input.d.ts +4 -0
  96. package/dist/components/InputGroup/InputGroup.cjs +104 -91
  97. package/dist/components/InputGroup/InputGroup.cjs.map +1 -1
  98. package/dist/components/InputGroup/InputGroup.d.ts +37 -1
  99. package/dist/components/InputGroup/InputGroup.definitions.d.ts +6 -0
  100. package/dist/components/InputGroup/InputGroup.js +106 -93
  101. package/dist/components/InputGroup/InputGroup.js.map +1 -1
  102. package/dist/components/Modal/Modal.cjs +226 -116
  103. package/dist/components/Modal/Modal.cjs.map +1 -1
  104. package/dist/components/Modal/Modal.d.ts +38 -2
  105. package/dist/components/Modal/Modal.js +227 -117
  106. package/dist/components/Modal/Modal.js.map +1 -1
  107. package/dist/components/Modal/ModalFooter.d.ts +9 -1
  108. package/dist/components/Modal/index.d.ts +5 -0
  109. package/dist/components/PageLoader/PageLoader.cjs +61 -0
  110. package/dist/components/PageLoader/PageLoader.cjs.map +1 -0
  111. package/dist/components/PageLoader/PageLoader.d.ts +38 -0
  112. package/dist/components/PageLoader/PageLoader.js +61 -0
  113. package/dist/components/PageLoader/PageLoader.js.map +1 -0
  114. package/dist/components/PageLoader/index.d.ts +2 -0
  115. package/dist/components/PageLoader.d.ts +6 -0
  116. package/dist/components/ScrollTopButton/ScrollTopButton.cjs +79 -0
  117. package/dist/components/ScrollTopButton/ScrollTopButton.cjs.map +1 -0
  118. package/dist/components/ScrollTopButton/ScrollTopButton.d.ts +48 -0
  119. package/dist/components/ScrollTopButton/ScrollTopButton.js +79 -0
  120. package/dist/components/ScrollTopButton/ScrollTopButton.js.map +1 -0
  121. package/dist/components/ScrollTopButton/index.d.ts +4 -0
  122. package/dist/components/ScrollTopButton/scrollToTop.d.ts +29 -0
  123. package/dist/components/ScrollTopButton.d.ts +6 -0
  124. package/dist/components/Select/Select.cjs +446 -4
  125. package/dist/components/Select/Select.cjs.map +1 -1
  126. package/dist/components/Select/Select.d.ts +33 -13
  127. package/dist/components/Select/Select.definitions.d.ts +3 -0
  128. package/dist/components/Select/Select.helpers.d.ts +28 -0
  129. package/dist/components/Select/Select.js +445 -3
  130. package/dist/components/Select/Select.js.map +1 -1
  131. package/dist/components/Select/Select.sx.d.ts +7 -0
  132. package/dist/components/Select/Select.types.d.ts +1 -0
  133. package/dist/components/Select/_parts/SelectMenuItem.d.ts +20 -0
  134. package/dist/components/Select/_parts/SelectSearchHeader.d.ts +15 -0
  135. package/dist/components/Select/_parts/SelectValue.d.ts +22 -0
  136. package/dist/components/Select/index.d.ts +2 -1
  137. package/dist/components/Select.d.ts +4 -0
  138. package/dist/components/Stat/Stat.cjs +1 -1
  139. package/dist/components/Stat/Stat.js +1 -1
  140. package/dist/components/Stepper/Stepper.cjs +4 -1
  141. package/dist/components/Stepper/Stepper.cjs.map +1 -1
  142. package/dist/components/Stepper/Stepper.d.ts +5 -0
  143. package/dist/components/Stepper/Stepper.js +4 -1
  144. package/dist/components/Stepper/Stepper.js.map +1 -1
  145. package/dist/components/_shared/formField.sx.d.ts +33 -0
  146. package/dist/components/_shared/resolvePreset.d.ts +18 -0
  147. package/dist/formField.sx-CQ1mbk9M.cjs +76 -0
  148. package/dist/formField.sx-CQ1mbk9M.cjs.map +1 -0
  149. package/dist/formField.sx-DfVbMe0V.js +77 -0
  150. package/dist/formField.sx-DfVbMe0V.js.map +1 -0
  151. package/dist/hooks/Wizard/Wizard.cjs +7 -0
  152. package/dist/hooks/Wizard/Wizard.cjs.map +1 -0
  153. package/dist/hooks/Wizard/Wizard.js +7 -0
  154. package/dist/hooks/Wizard/Wizard.js.map +1 -0
  155. package/dist/hooks/Wizard/WizardContext.d.ts +67 -0
  156. package/dist/hooks/Wizard/index.d.ts +3 -0
  157. package/dist/hooks/Wizard/useWizard.d.ts +9 -0
  158. package/dist/hooks/Wizard.d.ts +2 -0
  159. package/dist/index.cjs +99 -1
  160. package/dist/index.cjs.map +1 -1
  161. package/dist/index.d.ts +3 -0
  162. package/dist/index.js +31 -2
  163. package/dist/index.js.map +1 -1
  164. package/dist/mui.d.ts +5 -0
  165. package/dist/resolvePreset-B-IB0ehH.js +15 -0
  166. package/dist/resolvePreset-B-IB0ehH.js.map +1 -0
  167. package/dist/resolvePreset-CT3kU-K2.cjs +14 -0
  168. package/dist/resolvePreset-CT3kU-K2.cjs.map +1 -0
  169. package/dist/styles.css +3 -112
  170. package/dist/theme/componentStyles.d.ts +32 -0
  171. package/dist/theme/tokens.d.ts +28 -0
  172. package/dist/useWizard-CWdIxZzX.cjs +94 -0
  173. package/dist/useWizard-CWdIxZzX.cjs.map +1 -0
  174. package/dist/useWizard-CWq--C3o.js +95 -0
  175. package/dist/useWizard-CWq--C3o.js.map +1 -0
  176. package/package.json +1 -1
  177. package/src/components/ActionMenu/ActionMenu.stories.tsx +230 -0
  178. package/src/components/ActionMenu/ActionMenu.tsx +174 -0
  179. package/src/components/ActionMenu/index.ts +2 -0
  180. package/src/components/AppBar/AppBar.stories.tsx +272 -0
  181. package/src/components/AppBar/AppBar.sx.ts +32 -0
  182. package/src/components/AppBar/AppBar.tsx +123 -0
  183. package/src/components/AppBar/AppBarBrand.tsx +120 -0
  184. package/src/components/AppBar/AppBarContext.ts +25 -0
  185. package/src/components/AppBar/AppBarMenuToggle.tsx +90 -0
  186. package/src/components/AppBar/AppBarUserMenu.tsx +217 -0
  187. package/src/components/AppBar/index.ts +25 -0
  188. package/src/components/Autocomplete/Autocomplete.definitions.ts +223 -0
  189. package/src/components/Autocomplete/Autocomplete.helpers.ts +60 -0
  190. package/src/components/Autocomplete/Autocomplete.stories.tsx +363 -2
  191. package/src/components/Autocomplete/Autocomplete.sx.ts +30 -0
  192. package/src/components/Autocomplete/Autocomplete.tsx +312 -90
  193. package/src/components/Autocomplete/Autocomplete.types.ts +13 -0
  194. package/src/components/Autocomplete/_parts/AutocompleteChips.tsx +55 -0
  195. package/src/components/Autocomplete/_parts/AutocompleteLoader.tsx +17 -0
  196. package/src/components/Autocomplete/_parts/AutocompleteOption.tsx +31 -0
  197. package/src/components/Autocomplete/index.ts +12 -1
  198. package/src/components/Avatar/Avatar.definitions.ts +162 -0
  199. package/src/components/Avatar/Avatar.stories.tsx +205 -1
  200. package/src/components/Avatar/Avatar.tsx +166 -103
  201. package/src/components/Card/Card.stories.tsx +205 -16
  202. package/src/components/Card/Card.sx.ts +104 -0
  203. package/src/components/Card/Card.tsx +191 -35
  204. package/src/components/Card/index.ts +9 -1
  205. package/src/components/DatePicker/DatePicker.definitions.ts +24 -1
  206. package/src/components/DatePicker/DatePicker.helpers.ts +24 -0
  207. package/src/components/DatePicker/DatePicker.stories.tsx +29 -2
  208. package/src/components/DatePicker/DatePicker.sx.ts +33 -0
  209. package/src/components/DatePicker/DatePicker.tsx +163 -139
  210. package/src/components/DatePicker/DatePicker.types.ts +10 -0
  211. package/src/components/DatePicker/index.ts +9 -1
  212. package/src/components/DateTimePicker/DateTimePicker.definitions.ts +24 -0
  213. package/src/components/DateTimePicker/DateTimePicker.helpers.ts +38 -0
  214. package/src/components/DateTimePicker/DateTimePicker.stories.tsx +29 -1
  215. package/src/components/DateTimePicker/DateTimePicker.sx.ts +30 -0
  216. package/src/components/DateTimePicker/DateTimePicker.tsx +200 -166
  217. package/src/components/DateTimePicker/DateTimePicker.types.ts +10 -0
  218. package/src/components/DateTimePicker/index.ts +9 -1
  219. package/src/components/Drawer/Drawer.stories.tsx +270 -0
  220. package/src/components/Drawer/Drawer.sx.ts +106 -0
  221. package/src/components/Drawer/Drawer.tsx +214 -0
  222. package/src/components/Drawer/DrawerContext.ts +26 -0
  223. package/src/components/Drawer/DrawerItem.tsx +110 -0
  224. package/src/components/Drawer/index.ts +10 -0
  225. package/src/components/Flyout/Flyout.stories.tsx +26 -18
  226. package/src/components/Icon/Icon.stories.tsx +68 -1
  227. package/src/components/Icon/Icon.tsx +87 -6
  228. package/src/components/Input/Input.definitions.ts +74 -2
  229. package/src/components/Input/Input.helpers.ts +49 -0
  230. package/src/components/Input/Input.stories.tsx +116 -4
  231. package/src/components/Input/Input.sx.ts +42 -0
  232. package/src/components/Input/Input.tsx +117 -162
  233. package/src/components/Input/Input.types.ts +10 -0
  234. package/src/components/Input/index.ts +9 -1
  235. package/src/components/InputGroup/InputGroup.definitions.ts +158 -0
  236. package/src/components/InputGroup/InputGroup.stories.tsx +159 -28
  237. package/src/components/InputGroup/InputGroup.tsx +159 -116
  238. package/src/components/Modal/Modal.stories.tsx +434 -6
  239. package/src/components/Modal/Modal.tsx +303 -121
  240. package/src/components/Modal/ModalFooter.tsx +22 -12
  241. package/src/components/Modal/index.ts +6 -1
  242. package/src/components/PageLoader/PageLoader.stories.tsx +217 -0
  243. package/src/components/PageLoader/PageLoader.tsx +96 -0
  244. package/src/components/PageLoader/index.ts +2 -0
  245. package/src/components/ScrollTopButton/ScrollTopButton.stories.tsx +158 -0
  246. package/src/components/ScrollTopButton/ScrollTopButton.tsx +135 -0
  247. package/src/components/ScrollTopButton/index.ts +8 -0
  248. package/src/components/ScrollTopButton/scrollToTop.ts +37 -0
  249. package/src/components/Select/Select.definitions.ts +114 -0
  250. package/src/components/Select/Select.helpers.ts +71 -0
  251. package/src/components/Select/Select.stories.tsx +126 -8
  252. package/src/components/Select/Select.sx.ts +14 -0
  253. package/src/components/Select/Select.tsx +246 -285
  254. package/src/components/Select/Select.types.ts +15 -0
  255. package/src/components/Select/_parts/SelectMenuItem.tsx +40 -0
  256. package/src/components/Select/_parts/SelectSearchHeader.tsx +51 -0
  257. package/src/components/Select/_parts/SelectValue.tsx +96 -0
  258. package/src/components/Select/index.ts +14 -1
  259. package/src/components/Stepper/Stepper.tsx +17 -1
  260. package/src/components/Tooltip/Tooltip.stories.tsx +15 -3
  261. package/src/components/_shared/formField.sx.ts +118 -0
  262. package/src/components/_shared/resolvePreset.ts +35 -0
  263. package/src/hooks/Wizard/Wizard.stories.tsx +301 -0
  264. package/src/hooks/Wizard/WizardContext.tsx +166 -0
  265. package/src/hooks/Wizard/index.ts +6 -0
  266. package/src/hooks/Wizard/useWizard.ts +13 -0
  267. package/src/index.ts +17 -1
  268. package/src/mui.ts +44 -0
  269. package/src/theme/componentStyles.ts +47 -0
  270. package/src/theme/tokens.ts +43 -0
  271. package/dist/DatePicker-BSNboVhN.js +0 -201
  272. package/dist/DatePicker-BSNboVhN.js.map +0 -1
  273. package/dist/DatePicker-BoqxWAhj.cjs +0 -200
  274. package/dist/DatePicker-BoqxWAhj.cjs.map +0 -1
  275. package/dist/Input-DFHs7cJ_.js +0 -171
  276. package/dist/Input-DFHs7cJ_.js.map +0 -1
  277. package/dist/Input-c8MwNNPg.cjs +0 -170
  278. package/dist/Input-c8MwNNPg.cjs.map +0 -1
  279. package/dist/Select-BO2N56sm.cjs +0 -411
  280. package/dist/Select-BO2N56sm.cjs.map +0 -1
  281. package/dist/Select-BcLkyHSE.js +0 -412
  282. package/dist/Select-BcLkyHSE.js.map +0 -1
  283. package/dist/index.css +0 -3
@@ -441,6 +441,120 @@ export const SelectWithManyOptionsExample = () => {
441
441
  };
442
442
  `;
443
443
 
444
+ export const LabelPositionFloatingDefinition = `
445
+ import React, { useState } from 'react';
446
+ import { Select } from './Select';
447
+ import { Box, Typography } from '@mui/material';
448
+
449
+ const basicOptions = [
450
+ { value: '10', label: '10' },
451
+ { value: '25', label: '25' },
452
+ { value: '50', label: '50' },
453
+ { value: '100', label: '100' },
454
+ ];
455
+
456
+ export const LabelPositionFloatingExample = () => {
457
+ const [value, setValue] = useState('');
458
+ return (
459
+ <Box sx={{ width: 300 }}>
460
+ <Select
461
+ label="Label flotante (MUI nativo)"
462
+ options={basicOptions}
463
+ value={value}
464
+ onChange={(val) => setValue(val as string)}
465
+ labelPosition="floating"
466
+ />
467
+ <Typography sx={{ mt: 2 }}>Valor seleccionado: {value || 'Ninguno'}</Typography>
468
+ </Box>
469
+ );
470
+ };
471
+ `;
472
+
473
+ export const CustomBorderRadiusDefinition = `
474
+ import React, { useState } from 'react';
475
+ import { Select } from './Select';
476
+ import { Box } from '@mui/material';
477
+
478
+ const basicOptions = [
479
+ { value: '10', label: '10' },
480
+ { value: '25', label: '25' },
481
+ { value: '50', label: '50' },
482
+ { value: '100', label: '100' },
483
+ ];
484
+
485
+ export const CustomBorderRadiusExample = () => {
486
+ const [valueA, setValueA] = useState('25');
487
+ const [valueB, setValueB] = useState('25');
488
+ const [valueC, setValueC] = useState('25');
489
+ return (
490
+ <Box sx={{ width: 300, display: 'flex', flexDirection: 'column', gap: 2 }}>
491
+ <Select
492
+ label="Sin border radius"
493
+ options={basicOptions}
494
+ value={valueA}
495
+ onChange={(val) => setValueA(val as string)}
496
+ borderRadius={0}
497
+ />
498
+ <Select
499
+ label="Border radius estándar"
500
+ options={basicOptions}
501
+ value={valueB}
502
+ onChange={(val) => setValueB(val as string)}
503
+ borderRadius={10}
504
+ />
505
+ <Select
506
+ label="Pill-shaped"
507
+ options={basicOptions}
508
+ value={valueC}
509
+ onChange={(val) => setValueC(val as string)}
510
+ borderRadius={999}
511
+ />
512
+ </Box>
513
+ );
514
+ };
515
+ `;
516
+
517
+ export const CustomStylingDefinition = `
518
+ import React, { useState } from 'react';
519
+ import { Select } from './Select';
520
+ import { Box, Typography } from '@mui/material';
521
+
522
+ const userOptions = [
523
+ { value: 'admin', label: 'Administrador', img: 'https://placehold.co/40x40?text=A' },
524
+ { value: 'user', label: 'Usuario', img: 'https://placehold.co/40x40?text=U' },
525
+ { value: 'moderator', label: 'Moderador', img: 'https://placehold.co/40x40?text=M' },
526
+ ];
527
+
528
+ export const CustomStylingExample = () => {
529
+ const [value, setValue] = useState<string[]>(['admin']);
530
+ return (
531
+ <Box sx={{ width: 360 }}>
532
+ <Select
533
+ label="Select con estilos personalizados"
534
+ options={userOptions}
535
+ multiple
536
+ value={value}
537
+ onChange={(val) => setValue(val as string[])}
538
+ placeholder="Selecciona usuarios"
539
+ sx={{
540
+ '& .MuiInputBase-root': {
541
+ backgroundColor: 'action.hover',
542
+ },
543
+ '& .MuiOutlinedInput-notchedOutline': {
544
+ borderColor: 'primary.main',
545
+ borderWidth: '2px',
546
+ },
547
+ '&:hover .MuiOutlinedInput-notchedOutline': {
548
+ borderColor: 'primary.dark',
549
+ },
550
+ }}
551
+ />
552
+ <Typography sx={{ mt: 2 }}>Valor seleccionado: {JSON.stringify(value)}</Typography>
553
+ </Box>
554
+ );
555
+ };
556
+ `;
557
+
444
558
  export const AsyncSelectDefinition = `
445
559
  import React, { useState } from 'react';
446
560
  import { Select } from './Select';
@@ -0,0 +1,71 @@
1
+ import type { SelectOption } from './Select';
2
+
3
+ /**
4
+ * Filtra opciones por `label` (case-insensitive). Si `search` es vacío,
5
+ * devuelve el array completo. Solo se usa en modo no-async.
6
+ */
7
+ export const filterOptionsByLabel = (
8
+ options: SelectOption[],
9
+ search: string,
10
+ ): SelectOption[] => {
11
+ if (!search) return options;
12
+ const needle = search.toLowerCase();
13
+ return options.filter((opt) => opt.label.toLowerCase().includes(needle));
14
+ };
15
+
16
+ /**
17
+ * Agrupa opciones por la propiedad `group`. Las opciones sin group caen
18
+ * bajo la key especial `__default`. Devuelve un Record para iterar en orden
19
+ * de inserción con Object.entries.
20
+ */
21
+ export const groupOptions = (
22
+ options: SelectOption[],
23
+ ): Record<string, SelectOption[]> => {
24
+ const groups: Record<string, SelectOption[]> = {};
25
+ options.forEach((opt) => {
26
+ const group = opt.group || '__default';
27
+ if (!groups[group]) groups[group] = [];
28
+ groups[group].push(opt);
29
+ });
30
+ return groups;
31
+ };
32
+
33
+ /**
34
+ * Determina si un conjunto de grupos está efectivamente vacío
35
+ * (no hay grupos o solo existe `__default` sin items).
36
+ */
37
+ export const isGroupedOptionsEmpty = (
38
+ groups: Record<string, SelectOption[]>,
39
+ ): boolean => {
40
+ const keys = Object.keys(groups);
41
+ if (keys.length === 0) return true;
42
+ if (keys.length === 1 && groups['__default'] && groups['__default'].length === 0) {
43
+ return true;
44
+ }
45
+ return false;
46
+ };
47
+
48
+ /**
49
+ * Normaliza el valor actual al shape que espera el MUI Select:
50
+ * - multiple: siempre array (aunque esté vacío).
51
+ * - single: string vacío si null/undefined.
52
+ */
53
+ export const normalizeSelectValue = <T>(
54
+ value: T | T[] | null | undefined,
55
+ multiple: boolean,
56
+ ): T | T[] | '' => {
57
+ if (multiple) return (value ?? []) as T[];
58
+ return (value ?? '') as T | '';
59
+ };
60
+
61
+ /**
62
+ * Evalúa si el valor actual está vacío (para decidir shrink del label
63
+ * y visibilidad del placeholder).
64
+ */
65
+ export const isSelectValueEmpty = (
66
+ normalizedValue: unknown,
67
+ multiple: boolean,
68
+ ): boolean => {
69
+ if (multiple) return Array.isArray(normalizedValue) && normalizedValue.length === 0;
70
+ return normalizedValue === '' || normalizedValue === null || normalizedValue === undefined;
71
+ };
@@ -1,17 +1,10 @@
1
1
  import type { Meta, StoryObj } from '@storybook/react';
2
- import React, { ReactElement, useMemo, useState, Children, isValidElement } from 'react';
2
+ import React, { useState } from 'react';
3
3
  import {
4
- FormControl,
5
- InputLabel,
6
- MenuItem,
7
-
8
4
  Chip,
9
5
  Avatar,
10
6
  Box,
11
7
  Typography,
12
- OutlinedInput,
13
- TextField,
14
- ListSubheader,
15
8
  } from '@mui/material';
16
9
  import ClearIcon from '@mui/icons-material/Clear'; // Icono de cerrar
17
10
 
@@ -31,6 +24,9 @@ import {
31
24
  EmptyOptionsDefinition,
32
25
  SelectWithManyOptionsDefinition,
33
26
  AsyncSelectDefinition,
27
+ LabelPositionFloatingDefinition,
28
+ CustomBorderRadiusDefinition,
29
+ CustomStylingDefinition,
34
30
  } from "./Select.definitions";
35
31
  import Select, { SelectOption, Option } from './Select';
36
32
 
@@ -100,6 +96,19 @@ const meta: Meta<typeof Select> = {
100
96
  maxWidth: { control: 'text', description: 'Ancho máximo del menú desplegable.' },
101
97
  maxChipsToShow: { control: 'number', description: 'Número máximo de chips a mostrar en selección múltiple antes de agrupar.', if: { arg: 'multiple', eq: true } },
102
98
  renderChipLabel: { control: false, description: 'Función para personalizar el contenido del label de cada chip seleccionado (para múltiple) o del valor mostrado (para individual).', },
99
+ labelPosition: {
100
+ control: 'radio',
101
+ options: ['outside', 'floating'],
102
+ description: 'Posición del label. `outside` mantiene el label por encima del input con animación al enfocar. `floating` usa el comportamiento nativo de MUI (label flotando dentro del notched outline).',
103
+ },
104
+ borderRadius: {
105
+ control: 'number',
106
+ description: 'Radio del borde del select. Acepta un número (en px) o un string CSS.',
107
+ },
108
+ sx: {
109
+ control: false,
110
+ description: 'Prop `sx` que se pasa al MUI Select para overrides personalizados. Se mergea con los estilos por defecto.',
111
+ },
103
112
  }
104
113
  };
105
114
 
@@ -513,6 +522,115 @@ export const SelectWithManyOptions: Story = {
513
522
  }
514
523
  };
515
524
 
525
+ // =============================================================================
526
+ // Historias de personalización (labelPosition / borderRadius / sx)
527
+ // =============================================================================
528
+ export const LabelPositionFloating: Story = {
529
+ render: () => {
530
+ const [value, setValue] = useState('');
531
+ return (
532
+ <Box sx={{ width: 300 }}>
533
+ <Select
534
+ label="Label flotante (MUI nativo)"
535
+ options={basicOptions}
536
+ value={value}
537
+ onChange={(val) => setValue(val as string)}
538
+ labelPosition="floating"
539
+ />
540
+ <Typography sx={{ mt: 2 }}>Valor seleccionado: {value || 'Ninguno'}</Typography>
541
+ </Box>
542
+ );
543
+ },
544
+ parameters: {
545
+ docs: {
546
+ description: {
547
+ story: "Select con `labelPosition='floating'`, que usa el comportamiento nativo de MUI (label flotando dentro del notched outline al enfocar). Útil cuando se necesita el look estándar de Material UI."
548
+ },
549
+ source: { code: LabelPositionFloatingDefinition.trim() }
550
+ }
551
+ }
552
+ };
553
+
554
+ export const CustomBorderRadius: Story = {
555
+ render: () => {
556
+ const [valueA, setValueA] = useState('25');
557
+ const [valueB, setValueB] = useState('25');
558
+ const [valueC, setValueC] = useState('25');
559
+ return (
560
+ <Box sx={{ width: 300, display: 'flex', flexDirection: 'column', gap: 2 }}>
561
+ <Select
562
+ label="Sin border radius"
563
+ options={basicOptions}
564
+ value={valueA}
565
+ onChange={(val) => setValueA(val as string)}
566
+ borderRadius={0}
567
+ />
568
+ <Select
569
+ label="Border radius estándar"
570
+ options={basicOptions}
571
+ value={valueB}
572
+ onChange={(val) => setValueB(val as string)}
573
+ borderRadius={10}
574
+ />
575
+ <Select
576
+ label="Pill-shaped"
577
+ options={basicOptions}
578
+ value={valueC}
579
+ onChange={(val) => setValueC(val as string)}
580
+ borderRadius={999}
581
+ />
582
+ </Box>
583
+ );
584
+ },
585
+ parameters: {
586
+ docs: {
587
+ description: {
588
+ story: "Control del radio del borde mediante la prop `borderRadius`. Acepta un número (en px) o un string CSS como `'0.5rem'`."
589
+ },
590
+ source: { code: CustomBorderRadiusDefinition.trim() }
591
+ }
592
+ }
593
+ };
594
+
595
+ export const CustomStyling: Story = {
596
+ render: () => {
597
+ const [value, setValue] = useState<string[]>(['admin']);
598
+ return (
599
+ <Box sx={{ width: 360 }}>
600
+ <Select
601
+ label="Select con estilos personalizados"
602
+ options={userOptions}
603
+ multiple
604
+ value={value}
605
+ onChange={(val) => setValue(val as string[])}
606
+ placeholder="Selecciona usuarios"
607
+ sx={{
608
+ '& .MuiInputBase-root': {
609
+ backgroundColor: 'action.hover',
610
+ },
611
+ '& .MuiOutlinedInput-notchedOutline': {
612
+ borderColor: 'primary.main',
613
+ borderWidth: '2px',
614
+ },
615
+ '&:hover .MuiOutlinedInput-notchedOutline': {
616
+ borderColor: 'primary.dark',
617
+ },
618
+ }}
619
+ />
620
+ <Typography sx={{ mt: 2 }}>Valor seleccionado: {JSON.stringify(value)}</Typography>
621
+ </Box>
622
+ );
623
+ },
624
+ parameters: {
625
+ docs: {
626
+ description: {
627
+ story: "Demuestra cómo el consumidor puede pasar un `sx` personalizado. El sx del consumidor se mergea sobre los defaults del componente, permitiendo overrides granulares (fondo, borde, hover, etc.) sin romper el comportamiento del label."
628
+ },
629
+ source: { code: CustomStylingDefinition.trim() }
630
+ }
631
+ }
632
+ };
633
+
516
634
  export const AsyncSelect: Story = {
517
635
  render: () => {
518
636
  const [value, setValue] = useState('');
@@ -0,0 +1,14 @@
1
+ import type { SelectProps as MuiSelectProps } from '@mui/material';
2
+
3
+ import { buildFormFieldSx } from '../_shared/formField.sx';
4
+ import type { LabelPosition } from './Select';
5
+
6
+ /**
7
+ * Builder de sx para el Select. Usa el builder compartido
8
+ * `buildFormFieldSx`. El Select no necesita overrides específicos.
9
+ */
10
+ export const buildSelectSx = (
11
+ borderRadius: number | string,
12
+ labelPosition: LabelPosition,
13
+ ): MuiSelectProps['sx'] =>
14
+ buildFormFieldSx({ borderRadius, labelPosition }) as MuiSelectProps['sx'];