@soyfri/shared-library 3.0.0 → 3.2.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 (182) hide show
  1. package/ActionMenu-BXRVKopM.js +106 -0
  2. package/ActionMenu-BXRVKopM.js.map +1 -0
  3. package/ActionMenu-wNWkDZWh.cjs +105 -0
  4. package/ActionMenu-wNWkDZWh.cjs.map +1 -0
  5. package/AppBarMenuToggle-BpXBMeca.js +128 -0
  6. package/AppBarMenuToggle-BpXBMeca.js.map +1 -0
  7. package/AppBarMenuToggle-D_RJGtHO.cjs +127 -0
  8. package/AppBarMenuToggle-D_RJGtHO.cjs.map +1 -0
  9. package/{Autocomplete-CejWztBY.cjs → Autocomplete-Bd3bN4Cw.cjs} +16 -11
  10. package/Autocomplete-Bd3bN4Cw.cjs.map +1 -0
  11. package/{Autocomplete-C_lW1VER.js → Autocomplete-E5aSUGVK.js} +16 -11
  12. package/Autocomplete-E5aSUGVK.js.map +1 -0
  13. package/{Avatar-Dw5rzayR.cjs → Avatar-BjyfSNvP.cjs} +3 -7
  14. package/Avatar-BjyfSNvP.cjs.map +1 -0
  15. package/{Avatar-H8akSege.js → Avatar-C_C4bcb9.js} +3 -7
  16. package/Avatar-C_C4bcb9.js.map +1 -0
  17. package/{Checkbox-gB5YKkVo.js → Checkbox-BL4kvHFB.js} +3 -2
  18. package/Checkbox-BL4kvHFB.js.map +1 -0
  19. package/{Checkbox-BCqMFWt4.cjs → Checkbox-Bx4Asmg7.cjs} +3 -2
  20. package/Checkbox-Bx4Asmg7.cjs.map +1 -0
  21. package/{DatePicker-t7uDTZMl.cjs → DatePicker-CMcQddi1.cjs} +45 -42
  22. package/DatePicker-CMcQddi1.cjs.map +1 -0
  23. package/{DatePicker-_IGWc3I5.js → DatePicker-D__RSgs-.js} +45 -42
  24. package/DatePicker-D__RSgs-.js.map +1 -0
  25. package/{DateTimePicker-BxQyjTCY.cjs → DateTimePicker-BVJGq1A0.cjs} +7 -15
  26. package/DateTimePicker-BVJGq1A0.cjs.map +1 -0
  27. package/{DateTimePicker-CrmWav_j.js → DateTimePicker-LeaE716a.js} +7 -15
  28. package/DateTimePicker-LeaE716a.js.map +1 -0
  29. package/DrawerItem--OTb3X9v.cjs +270 -0
  30. package/DrawerItem--OTb3X9v.cjs.map +1 -0
  31. package/DrawerItem-DKlMQ-xs.js +271 -0
  32. package/DrawerItem-DKlMQ-xs.js.map +1 -0
  33. package/Flyout-DCcDBYKT.js +117 -0
  34. package/Flyout-DCcDBYKT.js.map +1 -0
  35. package/Flyout-fycujUVf.cjs +116 -0
  36. package/Flyout-fycujUVf.cjs.map +1 -0
  37. package/Gallery-ClBJxCMc.js +491 -0
  38. package/Gallery-ClBJxCMc.js.map +1 -0
  39. package/Gallery-Cn1Bj_ao.cjs +490 -0
  40. package/Gallery-Cn1Bj_ao.cjs.map +1 -0
  41. package/Icon-CUwK2c8z.js +108 -0
  42. package/Icon-CUwK2c8z.js.map +1 -0
  43. package/Icon-ChnAivGo.cjs +107 -0
  44. package/Icon-ChnAivGo.cjs.map +1 -0
  45. package/{Input-DP_fKl38.js → Input-BibHlnGN.js} +18 -11
  46. package/Input-BibHlnGN.js.map +1 -0
  47. package/{Input-CScC87J5.cjs → Input-Bpjw7qwq.cjs} +18 -11
  48. package/Input-Bpjw7qwq.cjs.map +1 -0
  49. package/InputGroup-BZ7cmAcg.cjs +140 -0
  50. package/InputGroup-BZ7cmAcg.cjs.map +1 -0
  51. package/InputGroup-D5pXKGjZ.js +141 -0
  52. package/InputGroup-D5pXKGjZ.js.map +1 -0
  53. package/MenuButton-C4s8rG05.cjs +79 -0
  54. package/MenuButton-C4s8rG05.cjs.map +1 -0
  55. package/MenuButton-CZRN4P6x.js +80 -0
  56. package/MenuButton-CZRN4P6x.js.map +1 -0
  57. package/README.md +0 -8
  58. package/{RadioGroup-Dd0rHXSX.cjs → RadioGroup-DVvmmDs3.cjs} +3 -2
  59. package/RadioGroup-DVvmmDs3.cjs.map +1 -0
  60. package/{RadioGroup-bO-ahP9T.js → RadioGroup-cKCpag8W.js} +3 -2
  61. package/RadioGroup-cKCpag8W.js.map +1 -0
  62. package/{Select-BY5Y0qZ1.js → Select-BaY3zJhq.js} +4 -3
  63. package/Select-BaY3zJhq.js.map +1 -0
  64. package/{Select-CURrHSyl.cjs → Select-WpHNCHHz.cjs} +4 -3
  65. package/Select-WpHNCHHz.cjs.map +1 -0
  66. package/{Switch-CQFOopYy.cjs → Switch-B4ex7yKR.cjs} +3 -2
  67. package/Switch-B4ex7yKR.cjs.map +1 -0
  68. package/{Switch-D72dpkH2.js → Switch-CY1Dd2ff.js} +3 -2
  69. package/Switch-CY1Dd2ff.js.map +1 -0
  70. package/{Table-C4OM6rrC.cjs → Table-DaNgX7PO.cjs} +8 -11
  71. package/{Table-C4OM6rrC.cjs.map → Table-DaNgX7PO.cjs.map} +1 -1
  72. package/{Table-C2LbW0B1.js → Table-aNFAOuQk.js} +8 -11
  73. package/{Table-C2LbW0B1.js.map → Table-aNFAOuQk.js.map} +1 -1
  74. package/TimelineItem-0jRPFT11.js +68 -0
  75. package/TimelineItem-0jRPFT11.js.map +1 -0
  76. package/TimelineItem-BbhUWJhU.cjs +84 -0
  77. package/TimelineItem-BbhUWJhU.cjs.map +1 -0
  78. package/Tooltip-BB77JBcg.js +42 -0
  79. package/Tooltip-BB77JBcg.js.map +1 -0
  80. package/Tooltip-DpAsWGpN.cjs +41 -0
  81. package/Tooltip-DpAsWGpN.cjs.map +1 -0
  82. package/components/ActionMenu/ActionMenu.cjs +4 -104
  83. package/components/ActionMenu/ActionMenu.cjs.map +1 -1
  84. package/components/ActionMenu/ActionMenu.js +4 -104
  85. package/components/ActionMenu/ActionMenu.js.map +1 -1
  86. package/components/AppBar/AppBar.cjs +6 -126
  87. package/components/AppBar/AppBar.cjs.map +1 -1
  88. package/components/AppBar/AppBar.js +6 -126
  89. package/components/AppBar/AppBar.js.map +1 -1
  90. package/components/Autocomplete/Autocomplete.cjs +1 -1
  91. package/components/Autocomplete/Autocomplete.js +1 -1
  92. package/components/Avatar/Avatar.cjs +1 -1
  93. package/components/Avatar/Avatar.js +1 -1
  94. package/components/Checkbox/Checkbox.cjs +1 -1
  95. package/components/Checkbox/Checkbox.js +1 -1
  96. package/components/DatePicker/DatePicker.cjs +1 -1
  97. package/components/DatePicker/DatePicker.js +1 -1
  98. package/components/DateTimePicker/DateTimePicker.cjs +1 -1
  99. package/components/DateTimePicker/DateTimePicker.js +1 -1
  100. package/components/Drawer/Drawer.cjs +5 -269
  101. package/components/Drawer/Drawer.cjs.map +1 -1
  102. package/components/Drawer/Drawer.js +5 -269
  103. package/components/Drawer/Drawer.js.map +1 -1
  104. package/components/Flyout/Flyout.cjs +2 -114
  105. package/components/Flyout/Flyout.cjs.map +1 -1
  106. package/components/Flyout/Flyout.js +2 -114
  107. package/components/Flyout/Flyout.js.map +1 -1
  108. package/components/Gallery/Gallery.cjs +3 -489
  109. package/components/Gallery/Gallery.cjs.map +1 -1
  110. package/components/Gallery/Gallery.js +3 -489
  111. package/components/Gallery/Gallery.js.map +1 -1
  112. package/components/Icon/Icon.cjs +3 -106
  113. package/components/Icon/Icon.cjs.map +1 -1
  114. package/components/Icon/Icon.js +3 -106
  115. package/components/Icon/Icon.js.map +1 -1
  116. package/components/Input/Input.cjs +1 -1
  117. package/components/Input/Input.d.ts +4 -0
  118. package/components/Input/Input.helpers.d.ts +2 -2
  119. package/components/Input/Input.js +1 -1
  120. package/components/InputGroup/InputGroup.cjs +3 -137
  121. package/components/InputGroup/InputGroup.cjs.map +1 -1
  122. package/components/InputGroup/InputGroup.js +3 -137
  123. package/components/InputGroup/InputGroup.js.map +1 -1
  124. package/components/MenuButton/MenuButton.cjs +2 -75
  125. package/components/MenuButton/MenuButton.cjs.map +1 -1
  126. package/components/MenuButton/MenuButton.d.ts +6 -0
  127. package/components/MenuButton/MenuButton.js +2 -75
  128. package/components/MenuButton/MenuButton.js.map +1 -1
  129. package/components/RadioGroup/RadioGroup.cjs +1 -1
  130. package/components/RadioGroup/RadioGroup.js +1 -1
  131. package/components/Select/Select.cjs +1 -1
  132. package/components/Select/Select.js +1 -1
  133. package/components/Switch/Switch.cjs +1 -1
  134. package/components/Switch/Switch.js +1 -1
  135. package/components/Table/Table.cjs +1 -1
  136. package/components/Table/Table.js +1 -1
  137. package/components/Timeline/Timeline.cjs +4 -83
  138. package/components/Timeline/Timeline.cjs.map +1 -1
  139. package/components/Timeline/Timeline.js +4 -66
  140. package/components/Timeline/Timeline.js.map +1 -1
  141. package/components/Tooltip/Tooltip.cjs +2 -39
  142. package/components/Tooltip/Tooltip.cjs.map +1 -1
  143. package/components/Tooltip/Tooltip.js +2 -39
  144. package/components/Tooltip/Tooltip.js.map +1 -1
  145. package/{formField.sx-BAX7KwMR.cjs → formField.sx-BZj7TaMa.cjs} +29 -4
  146. package/formField.sx-BZj7TaMa.cjs.map +1 -0
  147. package/{formField.sx-8_QRnKxv.js → formField.sx-DD1sxwWH.js} +29 -4
  148. package/formField.sx-DD1sxwWH.js.map +1 -0
  149. package/index.cjs +36 -10
  150. package/index.cjs.map +1 -1
  151. package/index.d.ts +11 -0
  152. package/index.js +36 -10
  153. package/index.js.map +1 -1
  154. package/package.json +1 -1
  155. package/styles.css +375 -0
  156. package/theme/tokens.d.ts +12 -2
  157. package/{tokens-jaWWNk39.cjs → tokens-BGPazVFO.cjs} +4 -2
  158. package/tokens-BGPazVFO.cjs.map +1 -0
  159. package/{tokens-BRrcP_p_.js → tokens-DE2fV3a9.js} +12 -10
  160. package/tokens-DE2fV3a9.js.map +1 -0
  161. package/Autocomplete-C_lW1VER.js.map +0 -1
  162. package/Autocomplete-CejWztBY.cjs.map +0 -1
  163. package/Avatar-Dw5rzayR.cjs.map +0 -1
  164. package/Avatar-H8akSege.js.map +0 -1
  165. package/Checkbox-BCqMFWt4.cjs.map +0 -1
  166. package/Checkbox-gB5YKkVo.js.map +0 -1
  167. package/DatePicker-_IGWc3I5.js.map +0 -1
  168. package/DatePicker-t7uDTZMl.cjs.map +0 -1
  169. package/DateTimePicker-BxQyjTCY.cjs.map +0 -1
  170. package/DateTimePicker-CrmWav_j.js.map +0 -1
  171. package/Input-CScC87J5.cjs.map +0 -1
  172. package/Input-DP_fKl38.js.map +0 -1
  173. package/RadioGroup-Dd0rHXSX.cjs.map +0 -1
  174. package/RadioGroup-bO-ahP9T.js.map +0 -1
  175. package/Select-BY5Y0qZ1.js.map +0 -1
  176. package/Select-CURrHSyl.cjs.map +0 -1
  177. package/Switch-CQFOopYy.cjs.map +0 -1
  178. package/Switch-D72dpkH2.js.map +0 -1
  179. package/formField.sx-8_QRnKxv.js.map +0 -1
  180. package/formField.sx-BAX7KwMR.cjs.map +0 -1
  181. package/tokens-BRrcP_p_.js.map +0 -1
  182. package/tokens-jaWWNk39.cjs.map +0 -1
@@ -0,0 +1,107 @@
1
+ "use strict";
2
+ const jsxRuntime = require("react/jsx-runtime");
3
+ const React = require("react");
4
+ const material = require("@mui/material");
5
+ const sizeMap = {
6
+ xs: 18,
7
+ sm: 24,
8
+ md: 36,
9
+ lg: 48,
10
+ xl: 64
11
+ };
12
+ const StyledIcon = material.styled("span")(({ color, fontSize, spin, outlined }) => ({
13
+ display: "inline-flex",
14
+ alignItems: "center",
15
+ justifyContent: "center",
16
+ color,
17
+ fontSize,
18
+ width: fontSize,
19
+ height: fontSize,
20
+ animation: spin ? "spin 1s linear infinite" : void 0,
21
+ border: outlined ? "1px solid currentColor" : void 0,
22
+ borderRadius: "50%",
23
+ padding: outlined ? 4 : 0,
24
+ "@keyframes spin": {
25
+ "0%": { transform: "rotate(0deg)" },
26
+ "100%": { transform: "rotate(360deg)" }
27
+ },
28
+ "& svg": {
29
+ width: "100%",
30
+ height: "100%",
31
+ fill: "currentColor",
32
+ display: "block"
33
+ },
34
+ "& img": {
35
+ width: "100%",
36
+ height: "100%",
37
+ display: "block"
38
+ }
39
+ }));
40
+ const Icon = ({
41
+ children,
42
+ path,
43
+ url,
44
+ alt = "icon",
45
+ viewBox = "0 0 24 24",
46
+ color = "var(--primary-color)",
47
+ outlined = false,
48
+ spin = false,
49
+ badge,
50
+ badgeColor = "primary",
51
+ badgePosition = { vertical: "bottom", horizontal: "right" },
52
+ size = "sm",
53
+ black,
54
+ white,
55
+ className,
56
+ sx
57
+ }) => {
58
+ const finalColor = white ? "white" : black ? "black" : color;
59
+ const iconSize = sizeMap[size];
60
+ const content = React.useMemo(() => {
61
+ if (children) return children;
62
+ if (path) {
63
+ const trimmed = path.trim();
64
+ if (trimmed.startsWith("<svg")) {
65
+ return /* @__PURE__ */ jsxRuntime.jsx("span", { dangerouslySetInnerHTML: { __html: trimmed } });
66
+ }
67
+ return /* @__PURE__ */ jsxRuntime.jsx(
68
+ "svg",
69
+ {
70
+ xmlns: "http://www.w3.org/2000/svg",
71
+ viewBox,
72
+ fill: "currentColor",
73
+ "aria-hidden": "true",
74
+ children: /* @__PURE__ */ jsxRuntime.jsx("path", { d: trimmed })
75
+ }
76
+ );
77
+ }
78
+ if (url) {
79
+ return /* @__PURE__ */ jsxRuntime.jsx("img", { src: url, alt });
80
+ }
81
+ return null;
82
+ }, [children, path, url, alt, viewBox]);
83
+ return /* @__PURE__ */ jsxRuntime.jsx(
84
+ material.Badge,
85
+ {
86
+ badgeContent: badge,
87
+ color: badgeColor,
88
+ anchorOrigin: badgePosition,
89
+ invisible: badge === void 0,
90
+ sx: { ".MuiBadge-badge": { transform: "scale(1)" } },
91
+ children: /* @__PURE__ */ jsxRuntime.jsx(
92
+ StyledIcon,
93
+ {
94
+ color: finalColor,
95
+ fontSize: iconSize,
96
+ spin,
97
+ outlined,
98
+ className: `hsi-icon ${className || ""}`,
99
+ sx,
100
+ children: content
101
+ }
102
+ )
103
+ }
104
+ );
105
+ };
106
+ exports.Icon = Icon;
107
+ //# sourceMappingURL=Icon-ChnAivGo.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Icon-ChnAivGo.cjs","sources":["../src/components/Icon/Icon.tsx"],"sourcesContent":["import React, { type ReactNode, useMemo } from 'react';\nimport { Badge, styled } from '@mui/material';\nimport type { SxProps, Theme } from '@mui/material/styles';\n\nexport type IconSize = 'xs' | 'sm' | 'md' | 'lg' | 'xl';\n\nexport interface IconProps {\n /**\n * Contenido del icono. Modo legacy: acepta un elemento MUI o SVG ya armado.\n * Si se usa junto con `path` o `url`, `children` tiene prioridad.\n */\n children?: ReactNode;\n /**\n * Ruta SVG inline. Acepta dos formatos:\n * - Solo el valor del atributo `d` de un `<path>` (ej. `\"M12 2L2 22...\"`).\n * - Un SVG completo (ej. `\"<svg>...</svg>\"`).\n *\n * ⚠️ Seguridad: cuando el string empieza con `<svg`, se inyecta vía\n * `dangerouslySetInnerHTML`. **NUNCA pasar contenido proveniente de input\n * de usuario o de backends no confiables** — riesgo XSS.\n */\n path?: string;\n /**\n * URL a un archivo `.svg` (asset local o remoto). Se renderiza vía `<img>`.\n * El color del icono NO aplica en este modo (limitación de `<img>`).\n */\n url?: string;\n /** Alt text cuando se usa `url`. Default: `\"icon\"`. */\n alt?: string;\n /**\n * ViewBox cuando se usa `path`. Default: `\"0 0 24 24\"`. Ignorado si `path`\n * ya viene como `<svg>` completo.\n */\n viewBox?: string;\n color?: string;\n outlined?: boolean;\n spin?: boolean;\n badge?: string | number;\n badgeColor?: 'primary' | 'secondary' | 'error';\n badgePosition?: {\n vertical: 'top' | 'bottom';\n horizontal: 'right' | 'left';\n };\n size?: IconSize;\n black?: boolean;\n white?: boolean;\n className?: string;\n sx?: SxProps<Theme>;\n}\n\nconst sizeMap: Record<IconSize, number> = {\n xs: 18,\n sm: 24,\n md: 36,\n lg: 48,\n xl: 64,\n};\n\nconst StyledIcon = styled('span')<{\n color?: string;\n fontSize?: number;\n spin?: boolean;\n outlined?: boolean;\n}>(({ color, fontSize, spin, outlined }) => ({\n display: 'inline-flex',\n alignItems: 'center',\n justifyContent: 'center',\n color: color,\n fontSize: fontSize,\n width: fontSize,\n height: fontSize,\n animation: spin ? 'spin 1s linear infinite' : undefined,\n border: outlined ? '1px solid currentColor' : undefined,\n borderRadius: '50%',\n padding: outlined ? 4 : 0,\n '@keyframes spin': {\n '0%': { transform: 'rotate(0deg)' },\n '100%': { transform: 'rotate(360deg)' },\n },\n '& svg': {\n width: '100%',\n height: '100%',\n fill: 'currentColor',\n display: 'block',\n },\n '& img': {\n width: '100%',\n height: '100%',\n display: 'block',\n },\n}));\n\nexport const Icon: React.FC<IconProps> = ({\n children,\n path,\n url,\n alt = 'icon',\n viewBox = '0 0 24 24',\n color = 'var(--primary-color)',\n outlined = false,\n spin = false,\n badge,\n badgeColor = 'primary',\n badgePosition = { vertical: 'bottom', horizontal: 'right' },\n size = 'sm',\n black,\n white,\n className,\n sx,\n}) => {\n const finalColor = white ? 'white' : black ? 'black' : color;\n const iconSize = sizeMap[size];\n\n const content = useMemo(() => {\n if (children) return children;\n\n if (path) {\n const trimmed = path.trim();\n if (trimmed.startsWith('<svg')) {\n return <span dangerouslySetInnerHTML={{ __html: trimmed }} />;\n }\n return (\n <svg\n xmlns=\"http://www.w3.org/2000/svg\"\n viewBox={viewBox}\n fill=\"currentColor\"\n aria-hidden=\"true\"\n >\n <path d={trimmed} />\n </svg>\n );\n }\n\n if (url) {\n return <img src={url} alt={alt} />;\n }\n\n return null;\n }, [children, path, url, alt, viewBox]);\n\n return (\n <Badge\n badgeContent={badge}\n color={badgeColor}\n anchorOrigin={badgePosition}\n invisible={badge === undefined}\n sx={{ '.MuiBadge-badge': { transform: 'scale(1)' } }}\n >\n <StyledIcon\n color={finalColor}\n fontSize={iconSize}\n spin={spin}\n outlined={outlined}\n className={`hsi-icon ${className || ''}`}\n sx={sx}\n >\n {content}\n </StyledIcon>\n </Badge>\n );\n};\n\nexport default Icon;\n"],"names":["styled","useMemo","jsx","Badge"],"mappings":";;;;AAkDA,MAAM,UAAoC;AAAA,EACxC,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AAAA,EACJ,IAAI;AACN;AAEA,MAAM,aAAaA,SAAAA,OAAO,MAAM,EAK7B,CAAC,EAAE,OAAO,UAAU,MAAM,gBAAgB;AAAA,EAC3C,SAAS;AAAA,EACT,YAAY;AAAA,EACZ,gBAAgB;AAAA,EAChB;AAAA,EACA;AAAA,EACA,OAAO;AAAA,EACP,QAAQ;AAAA,EACR,WAAW,OAAO,4BAA4B;AAAA,EAC9C,QAAQ,WAAW,2BAA2B;AAAA,EAC9C,cAAc;AAAA,EACd,SAAS,WAAW,IAAI;AAAA,EACxB,mBAAmB;AAAA,IACjB,MAAM,EAAE,WAAW,eAAA;AAAA,IACnB,QAAQ,EAAE,WAAW,iBAAA;AAAA,EAAiB;AAAA,EAExC,SAAS;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,MAAM;AAAA,IACN,SAAS;AAAA,EAAA;AAAA,EAEX,SAAS;AAAA,IACP,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,SAAS;AAAA,EAAA;AAEb,EAAE;AAEK,MAAM,OAA4B,CAAC;AAAA,EACxC;AAAA,EACA;AAAA,EACA;AAAA,EACA,MAAM;AAAA,EACN,UAAU;AAAA,EACV,QAAQ;AAAA,EACR,WAAW;AAAA,EACX,OAAO;AAAA,EACP;AAAA,EACA,aAAa;AAAA,EACb,gBAAgB,EAAE,UAAU,UAAU,YAAY,QAAA;AAAA,EAClD,OAAO;AAAA,EACP;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,MAAM;AACJ,QAAM,aAAa,QAAQ,UAAU,QAAQ,UAAU;AACvD,QAAM,WAAW,QAAQ,IAAI;AAE7B,QAAM,UAAUC,MAAAA,QAAQ,MAAM;AAC5B,QAAI,SAAU,QAAO;AAErB,QAAI,MAAM;AACR,YAAM,UAAU,KAAK,KAAA;AACrB,UAAI,QAAQ,WAAW,MAAM,GAAG;AAC9B,8CAAQ,QAAA,EAAK,yBAAyB,EAAE,QAAQ,WAAW;AAAA,MAC7D;AACA,aACEC,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAM;AAAA,UACN;AAAA,UACA,MAAK;AAAA,UACL,eAAY;AAAA,UAEZ,UAAAA,2BAAAA,IAAC,QAAA,EAAK,GAAG,QAAA,CAAS;AAAA,QAAA;AAAA,MAAA;AAAA,IAGxB;AAEA,QAAI,KAAK;AACP,aAAOA,2BAAAA,IAAC,OAAA,EAAI,KAAK,KAAK,IAAA,CAAU;AAAA,IAClC;AAEA,WAAO;AAAA,EACT,GAAG,CAAC,UAAU,MAAM,KAAK,KAAK,OAAO,CAAC;AAEtC,SACEA,2BAAAA;AAAAA,IAACC,SAAAA;AAAAA,IAAA;AAAA,MACC,cAAc;AAAA,MACd,OAAO;AAAA,MACP,cAAc;AAAA,MACd,WAAW,UAAU;AAAA,MACrB,IAAI,EAAE,mBAAmB,EAAE,WAAW,aAAW;AAAA,MAEjD,UAAAD,2BAAAA;AAAAA,QAAC;AAAA,QAAA;AAAA,UACC,OAAO;AAAA,UACP,UAAU;AAAA,UACV;AAAA,UACA;AAAA,UACA,WAAW,YAAY,aAAa,EAAE;AAAA,UACtC;AAAA,UAEC,UAAA;AAAA,QAAA;AAAA,MAAA;AAAA,IACH;AAAA,EAAA;AAGN;;"}
@@ -33,8 +33,8 @@ import { jsx } from "react/jsx-runtime";
33
33
  import { TextField } from "@mui/material";
34
34
  import { useTheme } from "@mui/material/styles";
35
35
  import { Controller } from "react-hook-form";
36
- import { b as buildFormFieldSx } from "./formField.sx-8_QRnKxv.js";
37
- import { F as FIELD_INPUT_PADDING_Y } from "./tokens-BRrcP_p_.js";
36
+ import { b as buildFormFieldSx } from "./formField.sx-DD1sxwWH.js";
37
+ import { a as FIELD_INPUT_PADDING_Y, F as FIELD_BORDER_RADIUS } from "./tokens-DE2fV3a9.js";
38
38
  import { r as resolvePreset } from "./resolvePreset-K6_BfWHD.js";
39
39
  const parseValue = (raw, type) => {
40
40
  if (type !== "number") return raw;
@@ -42,9 +42,12 @@ const parseValue = (raw, type) => {
42
42
  const n = parseFloat(raw);
43
43
  return isNaN(n) ? raw : n;
44
44
  };
45
- const buildSlotProps = (type, min, max, maxLength, customSlotProps, customInputProps, readOnly) => {
45
+ const buildSlotProps = (type, min, max, maxLength, customSlotProps, customInputProps, readOnly, startAdornment, endAdornment) => {
46
46
  const numberAttrs = type === "number" ? __spreadValues({ min: min != null ? min : Number.NEGATIVE_INFINITY }, max !== void 0 && { max }) : {};
47
- return __spreadProps(__spreadValues({}, customSlotProps), {
47
+ const customInputSlot = customSlotProps == null ? void 0 : customSlotProps.input;
48
+ const inputSlot = __spreadValues(__spreadValues(__spreadValues({}, startAdornment !== void 0 && { startAdornment }), endAdornment !== void 0 && { endAdornment }), customInputSlot);
49
+ const hasInputSlot = Object.keys(inputSlot).length > 0;
50
+ return __spreadProps(__spreadValues(__spreadValues({}, customSlotProps), hasInputSlot && { input: inputSlot }), {
48
51
  htmlInput: __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, customInputProps), customSlotProps == null ? void 0 : customSlotProps.htmlInput), numberAttrs), maxLength !== void 0 && { maxLength }), readOnly && { readOnly: true }),
49
52
  // Dejamos que MUI maneje el shrink nativamente (animación inside → up).
50
53
  // El consumidor puede forzar shrink con slotProps.inputLabel.shrink=true si lo necesita.
@@ -57,10 +60,8 @@ const buildInputSx = (borderRadius, labelPosition) => {
57
60
  borderRadius,
58
61
  labelPosition,
59
62
  extraOutsideSx: {
60
- "& .MuiInputBase-input": {
61
- paddingTop: FIELD_INPUT_PADDING_Y,
62
- paddingBottom: FIELD_INPUT_PADDING_Y
63
- },
63
+ // El padding vertical del input base lo fija `buildFormFieldSx`
64
+ // (misma altura para los cinco campos). Acá solo van las variantes.
64
65
  // Filled: quitar el padding-top reservado para el label flotante dentro.
65
66
  "& .MuiFilledInput-root": {
66
67
  paddingTop: 0,
@@ -81,7 +82,7 @@ const Input = (props) => {
81
82
  type = "text",
82
83
  variant = "outlined",
83
84
  size = "small",
84
- borderRadius = 10,
85
+ borderRadius = FIELD_BORDER_RADIUS,
85
86
  labelPosition = "outside",
86
87
  preset,
87
88
  min,
@@ -90,6 +91,8 @@ const Input = (props) => {
90
91
  readOnly,
91
92
  inputProps,
92
93
  slotProps,
94
+ startAdornment,
95
+ endAdornment,
93
96
  sx,
94
97
  onBlur
95
98
  } = _a, rest = __objRest(_a, [
@@ -105,6 +108,8 @@ const Input = (props) => {
105
108
  "readOnly",
106
109
  "inputProps",
107
110
  "slotProps",
111
+ "startAdornment",
112
+ "endAdornment",
108
113
  "sx",
109
114
  "onBlur"
110
115
  ]);
@@ -117,7 +122,9 @@ const Input = (props) => {
117
122
  maxLength,
118
123
  slotProps,
119
124
  inputProps,
120
- readOnly
125
+ readOnly,
126
+ startAdornment,
127
+ endAdornment
121
128
  );
122
129
  const mergedSx = [
123
130
  ...presetSx ? [presetSx] : [buildInputSx(borderRadius, labelPosition)],
@@ -183,4 +190,4 @@ const Input = (props) => {
183
190
  export {
184
191
  Input as I
185
192
  };
186
- //# sourceMappingURL=Input-DP_fKl38.js.map
193
+ //# sourceMappingURL=Input-BibHlnGN.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input-BibHlnGN.js","sources":["../src/components/Input/Input.helpers.ts","../src/components/Input/Input.sx.ts","../src/components/Input/Input.tsx"],"sourcesContent":["import type { InputHTMLAttributes, ReactNode } from 'react';\nimport type { TextFieldProps } from '@mui/material';\nimport type { InputType } from './Input';\n\n/**\n * Convierte el valor raw del evento al tipo apropiado.\n * Para type=\"number\" intenta parsear a número; si falla, devuelve el raw\n * (permite estados intermedios como \"\" o \"-\" mientras el usuario tipea).\n */\nexport const parseValue = (raw: string, type: InputType): string | number => {\n if (type !== 'number') return raw;\n if (raw === '' || raw === '-') return raw;\n const n = parseFloat(raw);\n return isNaN(n) ? raw : n;\n};\n\n/**\n * Construye los slotProps del TextField consolidando htmlInput + inputLabel.\n * Maneja los atributos min/max cuando type=\"number\", maxLength y readOnly.\n */\nexport const buildSlotProps = (\n type: InputType,\n min: number | undefined,\n max: number | undefined,\n maxLength: number | undefined,\n customSlotProps: TextFieldProps['slotProps'],\n customInputProps: InputHTMLAttributes<HTMLInputElement> | undefined,\n readOnly?: boolean,\n startAdornment?: ReactNode,\n endAdornment?: ReactNode,\n): TextFieldProps['slotProps'] => {\n const numberAttrs =\n type === 'number'\n ? { min: min ?? Number.NEGATIVE_INFINITY, ...(max !== undefined && { max }) }\n : {};\n\n // Atajos `startAdornment`/`endAdornment` → slot `input` (OutlinedInput).\n // Lo que el consumidor pase en `slotProps.input` gana (no lo pisamos).\n const customInputSlot = (customSlotProps as any)?.input;\n const inputSlot = {\n ...(startAdornment !== undefined && { startAdornment }),\n ...(endAdornment !== undefined && { endAdornment }),\n ...customInputSlot,\n };\n const hasInputSlot = Object.keys(inputSlot).length > 0;\n\n return {\n ...customSlotProps,\n ...(hasInputSlot && { input: inputSlot }),\n htmlInput: {\n ...customInputProps,\n ...(customSlotProps as any)?.htmlInput,\n ...numberAttrs,\n ...(maxLength !== undefined && { maxLength }),\n ...(readOnly && { readOnly: true }),\n },\n // Dejamos que MUI maneje el shrink nativamente (animación inside → up).\n // El consumidor puede forzar shrink con slotProps.inputLabel.shrink=true si lo necesita.\n inputLabel: {\n ...(customSlotProps as any)?.inputLabel,\n },\n };\n};\n","import type { TextFieldProps } from '@mui/material';\n\nimport { buildFormFieldSx } from '../_shared/formField.sx';\nimport { FIELD_INPUT_PADDING_Y } from '../../theme/tokens';\nimport type { LabelPosition } from './Input';\n\n/**\n * Builder de sx para el Input. Usa el builder compartido\n * `buildFormFieldSx` y añade overrides específicos de TextField\n * (padding del input base, filled, standard).\n */\nexport const buildInputSx = (\n borderRadius: number | string,\n labelPosition: LabelPosition,\n): TextFieldProps['sx'] => {\n const radius = typeof borderRadius === 'number' ? `${borderRadius}px` : borderRadius;\n\n return buildFormFieldSx({\n borderRadius,\n labelPosition,\n extraOutsideSx: {\n // El padding vertical del input base lo fija `buildFormFieldSx`\n // (misma altura para los cinco campos). Acá solo van las variantes.\n\n // Filled: quitar el padding-top reservado para el label flotante dentro.\n '& .MuiFilledInput-root': {\n paddingTop: 0,\n borderRadius: `${radius} ${radius} 0 0`,\n },\n '& .MuiFilledInput-input': {\n paddingTop: FIELD_INPUT_PADDING_Y,\n },\n\n // Standard: quitar el margin-top reservado para el label flotante.\n '& .MuiInput-root': {\n marginTop: 0,\n },\n },\n });\n};\n","import { TextField, type TextFieldProps } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { Controller, type Control, type RegisterOptions } from 'react-hook-form';\n\nimport { parseValue, buildSlotProps } from './Input.helpers';\nimport { buildInputSx } from './Input.sx';\nimport { resolvePreset } from '../_shared/resolvePreset';\nimport { FIELD_BORDER_RADIUS } from '../../theme/tokens';\n\n// ── Tipos de dominio ─────────────────────────────────────────────────────\nexport type InputType =\n | 'text' | 'number' | 'email' | 'password' | 'tel'\n | 'url' | 'search' | 'date' | 'datetime-local'\n | 'month' | 'week' | 'time' | 'color';\n\nexport type LabelPosition = 'outside' | 'floating';\n\n// ── Props base (todo lo común entre RHF y controlado) ────────────────────\nexport interface BaseInputProps\n extends Omit<TextFieldProps, 'value' | 'onChange' | 'type'> {\n type?: InputType;\n min?: number;\n max?: number;\n maxLength?: number;\n /** Border radius del input. Default: 10 */\n borderRadius?: number | string;\n /** \"outside\" = label arriba del campo (default). \"floating\" = label clásico MUI dentro del borde */\n labelPosition?: LabelPosition;\n readOnly?: boolean;\n /** Contenido al inicio del input (ej. icono de búsqueda). Atajo de `slotProps.input.startAdornment`. */\n startAdornment?: React.ReactNode;\n /** Contenido al final del input (ej. botón clear). Atajo de `slotProps.input.endAdornment`. */\n endAdornment?: React.ReactNode;\n /**\n * Nombre del preset de estilo registrado en `theme.styles.Input`.\n * - `\"default\"` (o ausente) = estilo built-in del paquete.\n * - Cualquier otro string = mergea el preset encima del estilo built-in.\n */\n preset?: string;\n}\n\n// ── Variantes discriminadas (RHF vs controlado) ──────────────────────────\nexport interface RHFInputProps extends BaseInputProps {\n name: string;\n // `any` plano (no `Control<any>`): RHF tipa `Control<T>` con generics en\n // posiciones tanto contravariantes como covariantes (ej. `_subjects.state`).\n // Cuando el componente o su uso involucra generics adicionales, TS se\n // confunde narroweando el discriminated union y `Control<any>` no logra\n // absorber `Control<MyForm>` en la comparación estructural profunda. El\n // `any` plano elimina ese ruido. RHF adentro sigue teniendo sus tipos\n // fuertes — solo degradamos la superficie del prop del componente.\n control: any;\n validation?: RegisterOptions;\n /**\n * Side-effect que corre después de que RHF actualiza el form state.\n * Útil para cascadas entre campos (ej. reset de municipio al cambiar\n * departamento). NO reemplaza al handler de RHF.\n */\n onValueChange?: (value: string | number) => void;\n value?: never;\n onChange?: never;\n}\n\nexport interface ControlledInputProps extends BaseInputProps {\n name?: string;\n control?: never;\n validation?: never;\n value: string | number;\n onChange: (value: string | number) => void;\n}\n\n// ── API pública final ────────────────────────────────────────────────────\nexport type InputProps = RHFInputProps | ControlledInputProps;\n\nexport const Input: React.FC<InputProps> = (props) => {\n const {\n type = 'text',\n variant = 'outlined',\n size = 'small',\n borderRadius = FIELD_BORDER_RADIUS,\n labelPosition = 'outside',\n preset,\n min,\n max,\n maxLength,\n readOnly,\n inputProps,\n slotProps,\n startAdornment,\n endAdornment,\n sx,\n onBlur,\n ...rest\n } = props as ControlledInputProps & {\n control?: Control<any>;\n validation?: RegisterOptions;\n };\n\n const theme = useTheme();\n const presetSx = resolvePreset('Input', preset, theme);\n\n const finalSlotProps = buildSlotProps(\n type,\n min,\n max,\n maxLength,\n slotProps,\n inputProps,\n readOnly,\n startAdornment,\n endAdornment,\n );\n const mergedSx = [\n ...(presetSx ? [presetSx] : [buildInputSx(borderRadius, labelPosition)]),\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ];\n\n if ('control' in props && props.control) {\n const { name, control, validation, onValueChange } = props as RHFInputProps;\n return (\n <Controller\n name={name}\n control={control}\n rules={validation}\n render={({ field, fieldState: { error } }) => (\n <TextField\n fullWidth\n {...rest}\n name={field.name}\n value={field.value ?? ''}\n onChange={(e) => {\n const parsed = parseValue(e.target.value, type);\n field.onChange(parsed);\n onValueChange?.(parsed);\n }}\n onBlur={(e) => {\n field.onBlur();\n onBlur?.(e);\n }}\n inputRef={field.ref}\n type={type}\n variant={variant}\n size={size}\n slotProps={finalSlotProps}\n sx={mergedSx}\n error={!!error || rest.error}\n helperText={error?.message ?? rest.helperText}\n />\n )}\n />\n );\n }\n\n const { value, onChange } = props as ControlledInputProps;\n return (\n <TextField\n fullWidth\n {...rest}\n value={value ?? ''}\n onChange={(e) => onChange(parseValue(e.target.value, type))}\n onBlur={onBlur}\n type={type}\n variant={variant}\n size={size}\n slotProps={finalSlotProps}\n sx={mergedSx}\n />\n );\n};\n\nexport default Input;\n"],"names":["_a"],"mappings":"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"}
@@ -34,8 +34,8 @@ const jsxRuntime = require("react/jsx-runtime");
34
34
  const material = require("@mui/material");
35
35
  const styles = require("@mui/material/styles");
36
36
  const reactHookForm = require("react-hook-form");
37
- const formField_sx = require("./formField.sx-BAX7KwMR.cjs");
38
- const tokens = require("./tokens-jaWWNk39.cjs");
37
+ const formField_sx = require("./formField.sx-BZj7TaMa.cjs");
38
+ const tokens = require("./tokens-BGPazVFO.cjs");
39
39
  const resolvePreset = require("./resolvePreset-CxTI6_Ln.cjs");
40
40
  const parseValue = (raw, type) => {
41
41
  if (type !== "number") return raw;
@@ -43,9 +43,12 @@ const parseValue = (raw, type) => {
43
43
  const n = parseFloat(raw);
44
44
  return isNaN(n) ? raw : n;
45
45
  };
46
- const buildSlotProps = (type, min, max, maxLength, customSlotProps, customInputProps, readOnly) => {
46
+ const buildSlotProps = (type, min, max, maxLength, customSlotProps, customInputProps, readOnly, startAdornment, endAdornment) => {
47
47
  const numberAttrs = type === "number" ? __spreadValues({ min: min != null ? min : Number.NEGATIVE_INFINITY }, max !== void 0 && { max }) : {};
48
- return __spreadProps(__spreadValues({}, customSlotProps), {
48
+ const customInputSlot = customSlotProps == null ? void 0 : customSlotProps.input;
49
+ const inputSlot = __spreadValues(__spreadValues(__spreadValues({}, startAdornment !== void 0 && { startAdornment }), endAdornment !== void 0 && { endAdornment }), customInputSlot);
50
+ const hasInputSlot = Object.keys(inputSlot).length > 0;
51
+ return __spreadProps(__spreadValues(__spreadValues({}, customSlotProps), hasInputSlot && { input: inputSlot }), {
49
52
  htmlInput: __spreadValues(__spreadValues(__spreadValues(__spreadValues(__spreadValues({}, customInputProps), customSlotProps == null ? void 0 : customSlotProps.htmlInput), numberAttrs), maxLength !== void 0 && { maxLength }), readOnly && { readOnly: true }),
50
53
  // Dejamos que MUI maneje el shrink nativamente (animación inside → up).
51
54
  // El consumidor puede forzar shrink con slotProps.inputLabel.shrink=true si lo necesita.
@@ -58,10 +61,8 @@ const buildInputSx = (borderRadius, labelPosition) => {
58
61
  borderRadius,
59
62
  labelPosition,
60
63
  extraOutsideSx: {
61
- "& .MuiInputBase-input": {
62
- paddingTop: tokens.FIELD_INPUT_PADDING_Y,
63
- paddingBottom: tokens.FIELD_INPUT_PADDING_Y
64
- },
64
+ // El padding vertical del input base lo fija `buildFormFieldSx`
65
+ // (misma altura para los cinco campos). Acá solo van las variantes.
65
66
  // Filled: quitar el padding-top reservado para el label flotante dentro.
66
67
  "& .MuiFilledInput-root": {
67
68
  paddingTop: 0,
@@ -82,7 +83,7 @@ const Input = (props) => {
82
83
  type = "text",
83
84
  variant = "outlined",
84
85
  size = "small",
85
- borderRadius = 10,
86
+ borderRadius = tokens.FIELD_BORDER_RADIUS,
86
87
  labelPosition = "outside",
87
88
  preset,
88
89
  min,
@@ -91,6 +92,8 @@ const Input = (props) => {
91
92
  readOnly,
92
93
  inputProps,
93
94
  slotProps,
95
+ startAdornment,
96
+ endAdornment,
94
97
  sx,
95
98
  onBlur
96
99
  } = _a, rest = __objRest(_a, [
@@ -106,6 +109,8 @@ const Input = (props) => {
106
109
  "readOnly",
107
110
  "inputProps",
108
111
  "slotProps",
112
+ "startAdornment",
113
+ "endAdornment",
109
114
  "sx",
110
115
  "onBlur"
111
116
  ]);
@@ -118,7 +123,9 @@ const Input = (props) => {
118
123
  maxLength,
119
124
  slotProps,
120
125
  inputProps,
121
- readOnly
126
+ readOnly,
127
+ startAdornment,
128
+ endAdornment
122
129
  );
123
130
  const mergedSx = [
124
131
  ...presetSx ? [presetSx] : [buildInputSx(borderRadius, labelPosition)],
@@ -182,4 +189,4 @@ const Input = (props) => {
182
189
  );
183
190
  };
184
191
  exports.Input = Input;
185
- //# sourceMappingURL=Input-CScC87J5.cjs.map
192
+ //# sourceMappingURL=Input-Bpjw7qwq.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Input-Bpjw7qwq.cjs","sources":["../src/components/Input/Input.helpers.ts","../src/components/Input/Input.sx.ts","../src/components/Input/Input.tsx"],"sourcesContent":["import type { InputHTMLAttributes, ReactNode } from 'react';\nimport type { TextFieldProps } from '@mui/material';\nimport type { InputType } from './Input';\n\n/**\n * Convierte el valor raw del evento al tipo apropiado.\n * Para type=\"number\" intenta parsear a número; si falla, devuelve el raw\n * (permite estados intermedios como \"\" o \"-\" mientras el usuario tipea).\n */\nexport const parseValue = (raw: string, type: InputType): string | number => {\n if (type !== 'number') return raw;\n if (raw === '' || raw === '-') return raw;\n const n = parseFloat(raw);\n return isNaN(n) ? raw : n;\n};\n\n/**\n * Construye los slotProps del TextField consolidando htmlInput + inputLabel.\n * Maneja los atributos min/max cuando type=\"number\", maxLength y readOnly.\n */\nexport const buildSlotProps = (\n type: InputType,\n min: number | undefined,\n max: number | undefined,\n maxLength: number | undefined,\n customSlotProps: TextFieldProps['slotProps'],\n customInputProps: InputHTMLAttributes<HTMLInputElement> | undefined,\n readOnly?: boolean,\n startAdornment?: ReactNode,\n endAdornment?: ReactNode,\n): TextFieldProps['slotProps'] => {\n const numberAttrs =\n type === 'number'\n ? { min: min ?? Number.NEGATIVE_INFINITY, ...(max !== undefined && { max }) }\n : {};\n\n // Atajos `startAdornment`/`endAdornment` → slot `input` (OutlinedInput).\n // Lo que el consumidor pase en `slotProps.input` gana (no lo pisamos).\n const customInputSlot = (customSlotProps as any)?.input;\n const inputSlot = {\n ...(startAdornment !== undefined && { startAdornment }),\n ...(endAdornment !== undefined && { endAdornment }),\n ...customInputSlot,\n };\n const hasInputSlot = Object.keys(inputSlot).length > 0;\n\n return {\n ...customSlotProps,\n ...(hasInputSlot && { input: inputSlot }),\n htmlInput: {\n ...customInputProps,\n ...(customSlotProps as any)?.htmlInput,\n ...numberAttrs,\n ...(maxLength !== undefined && { maxLength }),\n ...(readOnly && { readOnly: true }),\n },\n // Dejamos que MUI maneje el shrink nativamente (animación inside → up).\n // El consumidor puede forzar shrink con slotProps.inputLabel.shrink=true si lo necesita.\n inputLabel: {\n ...(customSlotProps as any)?.inputLabel,\n },\n };\n};\n","import type { TextFieldProps } from '@mui/material';\n\nimport { buildFormFieldSx } from '../_shared/formField.sx';\nimport { FIELD_INPUT_PADDING_Y } from '../../theme/tokens';\nimport type { LabelPosition } from './Input';\n\n/**\n * Builder de sx para el Input. Usa el builder compartido\n * `buildFormFieldSx` y añade overrides específicos de TextField\n * (padding del input base, filled, standard).\n */\nexport const buildInputSx = (\n borderRadius: number | string,\n labelPosition: LabelPosition,\n): TextFieldProps['sx'] => {\n const radius = typeof borderRadius === 'number' ? `${borderRadius}px` : borderRadius;\n\n return buildFormFieldSx({\n borderRadius,\n labelPosition,\n extraOutsideSx: {\n // El padding vertical del input base lo fija `buildFormFieldSx`\n // (misma altura para los cinco campos). Acá solo van las variantes.\n\n // Filled: quitar el padding-top reservado para el label flotante dentro.\n '& .MuiFilledInput-root': {\n paddingTop: 0,\n borderRadius: `${radius} ${radius} 0 0`,\n },\n '& .MuiFilledInput-input': {\n paddingTop: FIELD_INPUT_PADDING_Y,\n },\n\n // Standard: quitar el margin-top reservado para el label flotante.\n '& .MuiInput-root': {\n marginTop: 0,\n },\n },\n });\n};\n","import { TextField, type TextFieldProps } from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { Controller, type Control, type RegisterOptions } from 'react-hook-form';\n\nimport { parseValue, buildSlotProps } from './Input.helpers';\nimport { buildInputSx } from './Input.sx';\nimport { resolvePreset } from '../_shared/resolvePreset';\nimport { FIELD_BORDER_RADIUS } from '../../theme/tokens';\n\n// ── Tipos de dominio ─────────────────────────────────────────────────────\nexport type InputType =\n | 'text' | 'number' | 'email' | 'password' | 'tel'\n | 'url' | 'search' | 'date' | 'datetime-local'\n | 'month' | 'week' | 'time' | 'color';\n\nexport type LabelPosition = 'outside' | 'floating';\n\n// ── Props base (todo lo común entre RHF y controlado) ────────────────────\nexport interface BaseInputProps\n extends Omit<TextFieldProps, 'value' | 'onChange' | 'type'> {\n type?: InputType;\n min?: number;\n max?: number;\n maxLength?: number;\n /** Border radius del input. Default: 10 */\n borderRadius?: number | string;\n /** \"outside\" = label arriba del campo (default). \"floating\" = label clásico MUI dentro del borde */\n labelPosition?: LabelPosition;\n readOnly?: boolean;\n /** Contenido al inicio del input (ej. icono de búsqueda). Atajo de `slotProps.input.startAdornment`. */\n startAdornment?: React.ReactNode;\n /** Contenido al final del input (ej. botón clear). Atajo de `slotProps.input.endAdornment`. */\n endAdornment?: React.ReactNode;\n /**\n * Nombre del preset de estilo registrado en `theme.styles.Input`.\n * - `\"default\"` (o ausente) = estilo built-in del paquete.\n * - Cualquier otro string = mergea el preset encima del estilo built-in.\n */\n preset?: string;\n}\n\n// ── Variantes discriminadas (RHF vs controlado) ──────────────────────────\nexport interface RHFInputProps extends BaseInputProps {\n name: string;\n // `any` plano (no `Control<any>`): RHF tipa `Control<T>` con generics en\n // posiciones tanto contravariantes como covariantes (ej. `_subjects.state`).\n // Cuando el componente o su uso involucra generics adicionales, TS se\n // confunde narroweando el discriminated union y `Control<any>` no logra\n // absorber `Control<MyForm>` en la comparación estructural profunda. El\n // `any` plano elimina ese ruido. RHF adentro sigue teniendo sus tipos\n // fuertes — solo degradamos la superficie del prop del componente.\n control: any;\n validation?: RegisterOptions;\n /**\n * Side-effect que corre después de que RHF actualiza el form state.\n * Útil para cascadas entre campos (ej. reset de municipio al cambiar\n * departamento). NO reemplaza al handler de RHF.\n */\n onValueChange?: (value: string | number) => void;\n value?: never;\n onChange?: never;\n}\n\nexport interface ControlledInputProps extends BaseInputProps {\n name?: string;\n control?: never;\n validation?: never;\n value: string | number;\n onChange: (value: string | number) => void;\n}\n\n// ── API pública final ────────────────────────────────────────────────────\nexport type InputProps = RHFInputProps | ControlledInputProps;\n\nexport const Input: React.FC<InputProps> = (props) => {\n const {\n type = 'text',\n variant = 'outlined',\n size = 'small',\n borderRadius = FIELD_BORDER_RADIUS,\n labelPosition = 'outside',\n preset,\n min,\n max,\n maxLength,\n readOnly,\n inputProps,\n slotProps,\n startAdornment,\n endAdornment,\n sx,\n onBlur,\n ...rest\n } = props as ControlledInputProps & {\n control?: Control<any>;\n validation?: RegisterOptions;\n };\n\n const theme = useTheme();\n const presetSx = resolvePreset('Input', preset, theme);\n\n const finalSlotProps = buildSlotProps(\n type,\n min,\n max,\n maxLength,\n slotProps,\n inputProps,\n readOnly,\n startAdornment,\n endAdornment,\n );\n const mergedSx = [\n ...(presetSx ? [presetSx] : [buildInputSx(borderRadius, labelPosition)]),\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ];\n\n if ('control' in props && props.control) {\n const { name, control, validation, onValueChange } = props as RHFInputProps;\n return (\n <Controller\n name={name}\n control={control}\n rules={validation}\n render={({ field, fieldState: { error } }) => (\n <TextField\n fullWidth\n {...rest}\n name={field.name}\n value={field.value ?? ''}\n onChange={(e) => {\n const parsed = parseValue(e.target.value, type);\n field.onChange(parsed);\n onValueChange?.(parsed);\n }}\n onBlur={(e) => {\n field.onBlur();\n onBlur?.(e);\n }}\n inputRef={field.ref}\n type={type}\n variant={variant}\n size={size}\n slotProps={finalSlotProps}\n sx={mergedSx}\n error={!!error || rest.error}\n helperText={error?.message ?? rest.helperText}\n />\n )}\n />\n );\n }\n\n const { value, onChange } = props as ControlledInputProps;\n return (\n <TextField\n fullWidth\n {...rest}\n value={value ?? ''}\n onChange={(e) => onChange(parseValue(e.target.value, type))}\n onBlur={onBlur}\n type={type}\n variant={variant}\n size={size}\n slotProps={finalSlotProps}\n sx={mergedSx}\n />\n );\n};\n\nexport default Input;\n"],"names":["buildFormFieldSx","FIELD_INPUT_PADDING_Y","FIELD_BORDER_RADIUS","useTheme","resolvePreset","jsx","Controller","TextField","_a"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AASO,MAAM,aAAa,CAAC,KAAa,SAAqC;AAC3E,MAAI,SAAS,SAAU,QAAO;AAC9B,MAAI,QAAQ,MAAM,QAAQ,IAAK,QAAO;AACtC,QAAM,IAAI,WAAW,GAAG;AACxB,SAAO,MAAM,CAAC,IAAI,MAAM;AAC1B;AAMO,MAAM,iBAAiB,CAC5B,MACA,KACA,KACA,WACA,iBACA,kBACA,UACA,gBACA,iBACgC;AAChC,QAAM,cACJ,SAAS,WACL,iBAAE,KAAK,oBAAO,OAAO,qBAAuB,QAAQ,UAAa,EAAE,IAAA,KACnE,CAAA;AAIN,QAAM,kBAAmB,mDAAyB;AAClD,QAAM,YAAY,iDACZ,mBAAmB,UAAa,EAAE,eAAA,IAClC,iBAAiB,UAAa,EAAE,aAAA,IACjC;AAEL,QAAM,eAAe,OAAO,KAAK,SAAS,EAAE,SAAS;AAErD,SAAO,gDACF,kBACC,gBAAgB,EAAE,OAAO,UAAA,IAFxB;AAAA,IAGL,WAAW,+EACN,mBACC,mDAAyB,YAC1B,cACC,cAAc,UAAa,EAAE,UAAA,IAC7B,YAAY,EAAE,UAAU,KAAA;AAAA;AAAA;AAAA,IAI9B,YAAY,mBACN,mDAAyB;AAAA,EAC/B;AAEJ;ACnDO,MAAM,eAAe,CAC1B,cACA,kBACyB;AACzB,QAAM,SAAS,OAAO,iBAAiB,WAAW,GAAG,YAAY,OAAO;AAExE,SAAOA,8BAAiB;AAAA,IACtB;AAAA,IACA;AAAA,IACA,gBAAgB;AAAA;AAAA;AAAA;AAAA,MAKd,0BAA0B;AAAA,QACxB,YAAY;AAAA,QACZ,cAAc,GAAG,MAAM,IAAI,MAAM;AAAA,MAAA;AAAA,MAEnC,2BAA2B;AAAA,QACzB,YAAYC,OAAAA;AAAAA,MAAA;AAAA;AAAA,MAId,oBAAoB;AAAA,QAClB,WAAW;AAAA,MAAA;AAAA,IACb;AAAA,EACF,CACD;AACH;ACmCO,MAAM,QAA8B,CAAC,UAAU;AACpD,QAkBI,YAjBF;AAAA,WAAO;AAAA,IACP,UAAU;AAAA,IACV,OAAO;AAAA,IACP,eAAeC,OAAAA;AAAAA,IACf,gBAAgB;AAAA,IAChB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,MAEE,IADC,iBACD,IADC;AAAA,IAhBH;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA;AAOF,QAAM,QAAQC,OAAAA,SAAA;AACd,QAAM,WAAWC,cAAAA,cAAc,SAAS,QAAQ,KAAK;AAErD,QAAM,iBAAiB;AAAA,IACrB;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EAAA;AAEF,QAAM,WAAW;AAAA,IACf,GAAI,WAAW,CAAC,QAAQ,IAAI,CAAC,aAAa,cAAc,aAAa,CAAC;AAAA,IACtE,GAAI,MAAM,QAAQ,EAAE,IAAI,KAAK,KAAK,CAAC,EAAE,IAAI,CAAA;AAAA,EAAC;AAG5C,MAAI,aAAa,SAAS,MAAM,SAAS;AACvC,UAAM,EAAE,MAAM,SAAS,YAAY,kBAAkB;AACrD,WACEC,2BAAAA;AAAAA,MAACC,cAAAA;AAAAA,MAAA;AAAA,QACC;AAAA,QACA;AAAA,QACA,OAAO;AAAA,QACP,QAAQ,CAAC,EAAE,OAAO,YAAY,EAAE,MAAA;;AAC9BD,4CAAAA;AAAAA,YAACE,SAAAA;AAAAA,YAAA;AAAA,cACC,WAAS;AAAA,eACL,OAFL;AAAA,cAGC,MAAM,MAAM;AAAA,cACZ,QAAOC,MAAA,MAAM,UAAN,OAAAA,MAAe;AAAA,cACtB,UAAU,CAAC,MAAM;AACf,sBAAM,SAAS,WAAW,EAAE,OAAO,OAAO,IAAI;AAC9C,sBAAM,SAAS,MAAM;AACrB,+DAAgB;AAAA,cAClB;AAAA,cACA,QAAQ,CAAC,MAAM;AACb,sBAAM,OAAA;AACN,iDAAS;AAAA,cACX;AAAA,cACA,UAAU,MAAM;AAAA,cAChB;AAAA,cACA;AAAA,cACA;AAAA,cACA,WAAW;AAAA,cACX,IAAI;AAAA,cACJ,OAAO,CAAC,CAAC,SAAS,KAAK;AAAA,cACvB,aAAY,oCAAO,YAAP,YAAkB,KAAK;AAAA,YAAA;AAAA,UAAA;AAAA;AAAA,MACrC;AAAA,IAAA;AAAA,EAIR;AAEA,QAAM,EAAE,OAAO,SAAA,IAAa;AAC5B,SACEH,2BAAAA;AAAAA,IAACE,SAAAA;AAAAA,IAAA;AAAA,MACC,WAAS;AAAA,OACL,OAFL;AAAA,MAGC,OAAO,wBAAS;AAAA,MAChB,UAAU,CAAC,MAAM,SAAS,WAAW,EAAE,OAAO,OAAO,IAAI,CAAC;AAAA,MAC1D;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,WAAW;AAAA,MACX,IAAI;AAAA,IAAA;AAAA,EAAA;AAGV;;"}
@@ -0,0 +1,140 @@
1
+ "use strict";
2
+ var __defProp = Object.defineProperty;
3
+ var __defProps = Object.defineProperties;
4
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
5
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
8
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
9
+ var __spreadValues = (a, b) => {
10
+ for (var prop in b || (b = {}))
11
+ if (__hasOwnProp.call(b, prop))
12
+ __defNormalProp(a, prop, b[prop]);
13
+ if (__getOwnPropSymbols)
14
+ for (var prop of __getOwnPropSymbols(b)) {
15
+ if (__propIsEnum.call(b, prop))
16
+ __defNormalProp(a, prop, b[prop]);
17
+ }
18
+ return a;
19
+ };
20
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
21
+ const jsxRuntime = require("react/jsx-runtime");
22
+ const React = require("react");
23
+ const material = require("@mui/material");
24
+ const mergeSx = require("./mergeSx-Dbccoo_H.cjs");
25
+ const tokens = require("./tokens-BGPazVFO.cjs");
26
+ const InputGroup = ({
27
+ children,
28
+ sx,
29
+ slotSx,
30
+ borderRadius = tokens.FIELD_BORDER_RADIUS,
31
+ disabled,
32
+ orientation = "horizontal",
33
+ className
34
+ }) => {
35
+ const radius = typeof borderRadius === "number" ? `${borderRadius}px` : borderRadius;
36
+ const slots = React.Children.toArray(children).filter(React.isValidElement);
37
+ const isHorizontal = orientation === "horizontal";
38
+ const baseSx = {
39
+ // Respeta el label "outside" de Input/Select: los hijos pierden su marginTop
40
+ // (ver más abajo) y el grupo reserva el mismo espacio arriba para que los
41
+ // labels floten por encima del borde del grupo.
42
+ marginTop: tokens.LABEL_MARGIN_TOP,
43
+ display: "flex",
44
+ flexDirection: isHorizontal ? "row" : "column",
45
+ alignItems: "stretch",
46
+ width: "100%",
47
+ border: (theme) => `1px solid ${theme.palette.divider}`,
48
+ borderRadius: radius,
49
+ backgroundColor: "background.paper",
50
+ transition: "border-color 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms, box-shadow 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms",
51
+ "&:focus-within": {
52
+ borderColor: "primary.main",
53
+ boxShadow: (theme) => `0 0 0 1px ${theme.palette.primary.main}`
54
+ },
55
+ opacity: disabled ? 0.6 : 1,
56
+ pointerEvents: disabled ? "none" : "auto",
57
+ // Cancelar el marginTop que Input/Select reservan en labelPosition="outside".
58
+ // El grupo ya lo reservó en su nivel externo.
59
+ "& .MuiFormControl-root, & .MuiPickersTextField-root, & > [data-input-group-slot] > .MuiTextField-root, & > [data-input-group-slot] > .MuiFormControl-root": {
60
+ marginTop: 0
61
+ },
62
+ // Quitar el borde del notched outline interno: el borde visible es el del
63
+ // grupo, los separadores son los borderRight/borderBottom de cada slot.
64
+ // Incluye la API nueva de MUI X Pickers (v8) para que DatePicker/DateTimePicker
65
+ // no pinten su propio outline dentro del grupo.
66
+ "& .MuiOutlinedInput-notchedOutline, & .MuiPickersOutlinedInput-notchedOutline": {
67
+ border: "none"
68
+ },
69
+ // Forzar que todos los campos pinten sus esquinas cuadradas (las esquinas
70
+ // redondeadas se aplican solo al primer/último slot más abajo).
71
+ "& .MuiInputBase-root, & .MuiPickersInputBase-root, & .MuiChip-root": {
72
+ borderRadius: 0
73
+ },
74
+ // Botones integrados: sin radius propio, altura completa, sin sombra.
75
+ "& .MuiButton-root": {
76
+ borderRadius: 0,
77
+ height: "100%",
78
+ boxShadow: "none",
79
+ border: "none"
80
+ },
81
+ // Slots: cada hijo vive en un slot neutro que lo centra verticalmente.
82
+ "& > [data-input-group-slot]": __spreadProps(__spreadValues({
83
+ flex: 1,
84
+ display: "flex",
85
+ alignItems: "center",
86
+ minWidth: 0
87
+ }, isHorizontal ? { borderRight: (theme) => `1px solid ${theme.palette.divider}` } : { borderBottom: (theme) => `1px solid ${theme.palette.divider}` }), {
88
+ "&:last-of-type": {
89
+ borderRight: "none",
90
+ borderBottom: "none"
91
+ }
92
+ }),
93
+ // Esquinas redondeadas: primer slot (izquierda o arriba).
94
+ "& > [data-input-group-slot]:first-of-type .MuiInputBase-root, & > [data-input-group-slot]:first-of-type .MuiPickersInputBase-root, & > [data-input-group-slot]:first-of-type .MuiButton-root, & > [data-input-group-slot]:first-of-type .MuiChip-root": isHorizontal ? {
95
+ borderTopLeftRadius: radius,
96
+ borderBottomLeftRadius: radius
97
+ } : {
98
+ borderTopLeftRadius: radius,
99
+ borderTopRightRadius: radius
100
+ },
101
+ // Esquinas redondeadas: último slot (derecha o abajo).
102
+ "& > [data-input-group-slot]:last-of-type .MuiInputBase-root, & > [data-input-group-slot]:last-of-type .MuiPickersInputBase-root, & > [data-input-group-slot]:last-of-type .MuiButton-root, & > [data-input-group-slot]:last-of-type .MuiChip-root": isHorizontal ? {
103
+ borderTopRightRadius: radius,
104
+ borderBottomRightRadius: radius
105
+ } : {
106
+ borderBottomLeftRadius: radius,
107
+ borderBottomRightRadius: radius
108
+ }
109
+ };
110
+ const baseSlotSx = {
111
+ flex: 1,
112
+ display: "flex",
113
+ alignItems: "center",
114
+ minWidth: 0
115
+ };
116
+ return /* @__PURE__ */ jsxRuntime.jsx(
117
+ material.Box,
118
+ {
119
+ "data-testid": "input-group",
120
+ className,
121
+ "aria-disabled": disabled ? "true" : void 0,
122
+ sx: mergeSx.mergeSx(baseSx, sx),
123
+ children: slots.map((child, i) => {
124
+ var _a;
125
+ const slotKey = (_a = child.key) != null ? _a : i;
126
+ return /* @__PURE__ */ jsxRuntime.jsx(
127
+ material.Box,
128
+ {
129
+ "data-input-group-slot": true,
130
+ sx: mergeSx.mergeSx(baseSlotSx, slotSx),
131
+ children: child
132
+ },
133
+ slotKey
134
+ );
135
+ })
136
+ }
137
+ );
138
+ };
139
+ exports.InputGroup = InputGroup;
140
+ //# sourceMappingURL=InputGroup-BZ7cmAcg.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"InputGroup-BZ7cmAcg.cjs","sources":["../src/components/InputGroup/InputGroup.tsx"],"sourcesContent":["import React, { Children, isValidElement } from 'react';\nimport { Box, type SxProps, type Theme } from '@mui/material';\n\nimport { mergeSx } from '../_shared/mergeSx';\nimport { FIELD_BORDER_RADIUS, LABEL_MARGIN_TOP } from '../../theme/tokens';\n\nexport interface InputGroupProps {\n children: React.ReactNode;\n /**\n * sx aplicado al contenedor raíz del grupo. Se mergea sobre los defaults.\n */\n sx?: SxProps<Theme>;\n /**\n * sx aplicado a cada slot individual. Útil para controlar flex/gap entre\n * los hijos del grupo.\n */\n slotSx?: SxProps<Theme>;\n /**\n * Radio del borde del grupo. Default: 10.\n */\n borderRadius?: number | string;\n /**\n * Desactiva visualmente el grupo (no cascada lógica — los hijos deben\n * manejar su propio `disabled`).\n */\n disabled?: boolean;\n /**\n * Orientación del grupo. Default: 'horizontal'.\n */\n orientation?: 'horizontal' | 'vertical';\n className?: string;\n}\n\n/**\n * Agrupa visualmente varios componentes de entrada (Input / Select / DatePicker /\n * Button, etc.) compartiendo un solo borde y con separadores internos.\n *\n * El grupo respeta el espacio que Input/Select reservan para su label `outside`\n * (`LABEL_MARGIN_TOP`) moviendo ese reservado al contenedor externo y\n * cancelándolo en los hijos. Los labels siguen flotando por encima del borde\n * del grupo con la misma animación que fuera del grupo.\n *\n * No inspecciona el tipo de cada hijo; aplica los overrides a través de\n * descendant selectors por CSS para funcionar con cualquier wrapper / memoizado.\n */\nexport const InputGroup: React.FC<InputGroupProps> = ({\n children,\n sx,\n slotSx,\n borderRadius = FIELD_BORDER_RADIUS,\n disabled,\n orientation = 'horizontal',\n className,\n}) => {\n const radius = typeof borderRadius === 'number' ? `${borderRadius}px` : borderRadius;\n const slots = Children.toArray(children).filter(isValidElement);\n const isHorizontal = orientation === 'horizontal';\n\n const baseSx: SxProps<Theme> = {\n // Respeta el label \"outside\" de Input/Select: los hijos pierden su marginTop\n // (ver más abajo) y el grupo reserva el mismo espacio arriba para que los\n // labels floten por encima del borde del grupo.\n marginTop: LABEL_MARGIN_TOP,\n\n display: 'flex',\n flexDirection: isHorizontal ? 'row' : 'column',\n alignItems: 'stretch',\n width: '100%',\n border: (theme) => `1px solid ${theme.palette.divider}`,\n borderRadius: radius,\n backgroundColor: 'background.paper',\n transition:\n 'border-color 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms, box-shadow 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms',\n '&:focus-within': {\n borderColor: 'primary.main',\n boxShadow: (theme) => `0 0 0 1px ${theme.palette.primary.main}`,\n },\n opacity: disabled ? 0.6 : 1,\n pointerEvents: disabled ? 'none' : 'auto',\n\n // Cancelar el marginTop que Input/Select reservan en labelPosition=\"outside\".\n // El grupo ya lo reservó en su nivel externo.\n '& .MuiFormControl-root, & .MuiPickersTextField-root, & > [data-input-group-slot] > .MuiTextField-root, & > [data-input-group-slot] > .MuiFormControl-root':\n {\n marginTop: 0,\n },\n\n // Quitar el borde del notched outline interno: el borde visible es el del\n // grupo, los separadores son los borderRight/borderBottom de cada slot.\n // Incluye la API nueva de MUI X Pickers (v8) para que DatePicker/DateTimePicker\n // no pinten su propio outline dentro del grupo.\n '& .MuiOutlinedInput-notchedOutline, & .MuiPickersOutlinedInput-notchedOutline': {\n border: 'none',\n },\n\n // Forzar que todos los campos pinten sus esquinas cuadradas (las esquinas\n // redondeadas se aplican solo al primer/último slot más abajo).\n '& .MuiInputBase-root, & .MuiPickersInputBase-root, & .MuiChip-root': {\n borderRadius: 0,\n },\n\n // Botones integrados: sin radius propio, altura completa, sin sombra.\n '& .MuiButton-root': {\n borderRadius: 0,\n height: '100%',\n boxShadow: 'none',\n border: 'none',\n },\n\n // Slots: cada hijo vive en un slot neutro que lo centra verticalmente.\n '& > [data-input-group-slot]': {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n minWidth: 0,\n // Separador entre slots (horizontal: borderRight / vertical: borderBottom),\n // usando el color de divider del theme.\n ...(isHorizontal\n ? { borderRight: (theme: Theme) => `1px solid ${theme.palette.divider}` }\n : { borderBottom: (theme: Theme) => `1px solid ${theme.palette.divider}` }),\n '&:last-of-type': {\n borderRight: 'none',\n borderBottom: 'none',\n },\n },\n\n // Esquinas redondeadas: primer slot (izquierda o arriba).\n '& > [data-input-group-slot]:first-of-type .MuiInputBase-root, & > [data-input-group-slot]:first-of-type .MuiPickersInputBase-root, & > [data-input-group-slot]:first-of-type .MuiButton-root, & > [data-input-group-slot]:first-of-type .MuiChip-root':\n isHorizontal\n ? {\n borderTopLeftRadius: radius,\n borderBottomLeftRadius: radius,\n }\n : {\n borderTopLeftRadius: radius,\n borderTopRightRadius: radius,\n },\n\n // Esquinas redondeadas: último slot (derecha o abajo).\n '& > [data-input-group-slot]:last-of-type .MuiInputBase-root, & > [data-input-group-slot]:last-of-type .MuiPickersInputBase-root, & > [data-input-group-slot]:last-of-type .MuiButton-root, & > [data-input-group-slot]:last-of-type .MuiChip-root':\n isHorizontal\n ? {\n borderTopRightRadius: radius,\n borderBottomRightRadius: radius,\n }\n : {\n borderBottomLeftRadius: radius,\n borderBottomRightRadius: radius,\n },\n };\n\n const baseSlotSx: SxProps<Theme> = {\n flex: 1,\n display: 'flex',\n alignItems: 'center',\n minWidth: 0,\n };\n\n return (\n <Box\n data-testid=\"input-group\"\n className={className}\n aria-disabled={disabled ? 'true' : undefined}\n sx={mergeSx(baseSx, sx)}\n >\n {slots.map((child, i) => {\n const slotKey = (child as React.ReactElement).key ?? i;\n return (\n <Box\n key={slotKey}\n data-input-group-slot\n sx={mergeSx(baseSlotSx, slotSx)}\n >\n {child}\n </Box>\n );\n })}\n </Box>\n );\n};\n\nexport default InputGroup;\n"],"names":["FIELD_BORDER_RADIUS","Children","isValidElement","LABEL_MARGIN_TOP","jsx","Box","mergeSx"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;AA6CO,MAAM,aAAwC,CAAC;AAAA,EACpD;AAAA,EACA;AAAA,EACA;AAAA,EACA,eAAeA,OAAAA;AAAAA,EACf;AAAA,EACA,cAAc;AAAA,EACd;AACF,MAAM;AACJ,QAAM,SAAS,OAAO,iBAAiB,WAAW,GAAG,YAAY,OAAO;AACxE,QAAM,QAAQC,MAAAA,SAAS,QAAQ,QAAQ,EAAE,OAAOC,oBAAc;AAC9D,QAAM,eAAe,gBAAgB;AAErC,QAAM,SAAyB;AAAA;AAAA;AAAA;AAAA,IAI7B,WAAWC,OAAAA;AAAAA,IAEX,SAAS;AAAA,IACT,eAAe,eAAe,QAAQ;AAAA,IACtC,YAAY;AAAA,IACZ,OAAO;AAAA,IACP,QAAQ,CAAC,UAAU,aAAa,MAAM,QAAQ,OAAO;AAAA,IACrD,cAAc;AAAA,IACd,iBAAiB;AAAA,IACjB,YACE;AAAA,IACF,kBAAkB;AAAA,MAChB,aAAa;AAAA,MACb,WAAW,CAAC,UAAU,aAAa,MAAM,QAAQ,QAAQ,IAAI;AAAA,IAAA;AAAA,IAE/D,SAAS,WAAW,MAAM;AAAA,IAC1B,eAAe,WAAW,SAAS;AAAA;AAAA;AAAA,IAInC,6JACE;AAAA,MACE,WAAW;AAAA,IAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAOf,iFAAiF;AAAA,MAC/E,QAAQ;AAAA,IAAA;AAAA;AAAA;AAAA,IAKV,sEAAsE;AAAA,MACpE,cAAc;AAAA,IAAA;AAAA;AAAA,IAIhB,qBAAqB;AAAA,MACnB,cAAc;AAAA,MACd,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,QAAQ;AAAA,IAAA;AAAA;AAAA,IAIV,+BAA+B;AAAA,MAC7B,MAAM;AAAA,MACN,SAAS;AAAA,MACT,YAAY;AAAA,MACZ,UAAU;AAAA,OAGN,eACA,EAAE,aAAa,CAAC,UAAiB,aAAa,MAAM,QAAQ,OAAO,OACnE,EAAE,cAAc,CAAC,UAAiB,aAAa,MAAM,QAAQ,OAAO,GAAA,IAT3C;AAAA,MAU7B,kBAAkB;AAAA,QAChB,aAAa;AAAA,QACb,cAAc;AAAA,MAAA;AAAA,IAChB;AAAA;AAAA,IAIF,yPACE,eACI;AAAA,MACE,qBAAqB;AAAA,MACrB,wBAAwB;AAAA,IAAA,IAE1B;AAAA,MACE,qBAAqB;AAAA,MACrB,sBAAsB;AAAA,IAAA;AAAA;AAAA,IAI9B,qPACE,eACI;AAAA,MACE,sBAAsB;AAAA,MACtB,yBAAyB;AAAA,IAAA,IAE3B;AAAA,MACE,wBAAwB;AAAA,MACxB,yBAAyB;AAAA,IAAA;AAAA,EAC3B;AAGR,QAAM,aAA6B;AAAA,IACjC,MAAM;AAAA,IACN,SAAS;AAAA,IACT,YAAY;AAAA,IACZ,UAAU;AAAA,EAAA;AAGZ,SACEC,2BAAAA;AAAAA,IAACC,SAAAA;AAAAA,IAAA;AAAA,MACC,eAAY;AAAA,MACZ;AAAA,MACA,iBAAe,WAAW,SAAS;AAAA,MACnC,IAAIC,QAAAA,QAAQ,QAAQ,EAAE;AAAA,MAErB,UAAA,MAAM,IAAI,CAAC,OAAO,MAAM;;AACvB,cAAM,WAAW,WAA6B,QAA7B,YAAoC;AACrD,eACEF,2BAAAA;AAAAA,UAACC,SAAAA;AAAAA,UAAA;AAAA,YAEC,yBAAqB;AAAA,YACrB,IAAIC,QAAAA,QAAQ,YAAY,MAAM;AAAA,YAE7B,UAAA;AAAA,UAAA;AAAA,UAJI;AAAA,QAAA;AAAA,MAOX,CAAC;AAAA,IAAA;AAAA,EAAA;AAGP;;"}
@@ -0,0 +1,141 @@
1
+ var __defProp = Object.defineProperty;
2
+ var __defProps = Object.defineProperties;
3
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
4
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
5
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
6
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
7
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
8
+ var __spreadValues = (a, b) => {
9
+ for (var prop in b || (b = {}))
10
+ if (__hasOwnProp.call(b, prop))
11
+ __defNormalProp(a, prop, b[prop]);
12
+ if (__getOwnPropSymbols)
13
+ for (var prop of __getOwnPropSymbols(b)) {
14
+ if (__propIsEnum.call(b, prop))
15
+ __defNormalProp(a, prop, b[prop]);
16
+ }
17
+ return a;
18
+ };
19
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
20
+ import { jsx } from "react/jsx-runtime";
21
+ import { Children, isValidElement } from "react";
22
+ import { Box } from "@mui/material";
23
+ import { m as mergeSx } from "./mergeSx-BXoNZjB_.js";
24
+ import { F as FIELD_BORDER_RADIUS, L as LABEL_MARGIN_TOP } from "./tokens-DE2fV3a9.js";
25
+ const InputGroup = ({
26
+ children,
27
+ sx,
28
+ slotSx,
29
+ borderRadius = FIELD_BORDER_RADIUS,
30
+ disabled,
31
+ orientation = "horizontal",
32
+ className
33
+ }) => {
34
+ const radius = typeof borderRadius === "number" ? `${borderRadius}px` : borderRadius;
35
+ const slots = Children.toArray(children).filter(isValidElement);
36
+ const isHorizontal = orientation === "horizontal";
37
+ const baseSx = {
38
+ // Respeta el label "outside" de Input/Select: los hijos pierden su marginTop
39
+ // (ver más abajo) y el grupo reserva el mismo espacio arriba para que los
40
+ // labels floten por encima del borde del grupo.
41
+ marginTop: LABEL_MARGIN_TOP,
42
+ display: "flex",
43
+ flexDirection: isHorizontal ? "row" : "column",
44
+ alignItems: "stretch",
45
+ width: "100%",
46
+ border: (theme) => `1px solid ${theme.palette.divider}`,
47
+ borderRadius: radius,
48
+ backgroundColor: "background.paper",
49
+ transition: "border-color 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms, box-shadow 200ms cubic-bezier(0.0, 0, 0.2, 1) 0ms",
50
+ "&:focus-within": {
51
+ borderColor: "primary.main",
52
+ boxShadow: (theme) => `0 0 0 1px ${theme.palette.primary.main}`
53
+ },
54
+ opacity: disabled ? 0.6 : 1,
55
+ pointerEvents: disabled ? "none" : "auto",
56
+ // Cancelar el marginTop que Input/Select reservan en labelPosition="outside".
57
+ // El grupo ya lo reservó en su nivel externo.
58
+ "& .MuiFormControl-root, & .MuiPickersTextField-root, & > [data-input-group-slot] > .MuiTextField-root, & > [data-input-group-slot] > .MuiFormControl-root": {
59
+ marginTop: 0
60
+ },
61
+ // Quitar el borde del notched outline interno: el borde visible es el del
62
+ // grupo, los separadores son los borderRight/borderBottom de cada slot.
63
+ // Incluye la API nueva de MUI X Pickers (v8) para que DatePicker/DateTimePicker
64
+ // no pinten su propio outline dentro del grupo.
65
+ "& .MuiOutlinedInput-notchedOutline, & .MuiPickersOutlinedInput-notchedOutline": {
66
+ border: "none"
67
+ },
68
+ // Forzar que todos los campos pinten sus esquinas cuadradas (las esquinas
69
+ // redondeadas se aplican solo al primer/último slot más abajo).
70
+ "& .MuiInputBase-root, & .MuiPickersInputBase-root, & .MuiChip-root": {
71
+ borderRadius: 0
72
+ },
73
+ // Botones integrados: sin radius propio, altura completa, sin sombra.
74
+ "& .MuiButton-root": {
75
+ borderRadius: 0,
76
+ height: "100%",
77
+ boxShadow: "none",
78
+ border: "none"
79
+ },
80
+ // Slots: cada hijo vive en un slot neutro que lo centra verticalmente.
81
+ "& > [data-input-group-slot]": __spreadProps(__spreadValues({
82
+ flex: 1,
83
+ display: "flex",
84
+ alignItems: "center",
85
+ minWidth: 0
86
+ }, isHorizontal ? { borderRight: (theme) => `1px solid ${theme.palette.divider}` } : { borderBottom: (theme) => `1px solid ${theme.palette.divider}` }), {
87
+ "&:last-of-type": {
88
+ borderRight: "none",
89
+ borderBottom: "none"
90
+ }
91
+ }),
92
+ // Esquinas redondeadas: primer slot (izquierda o arriba).
93
+ "& > [data-input-group-slot]:first-of-type .MuiInputBase-root, & > [data-input-group-slot]:first-of-type .MuiPickersInputBase-root, & > [data-input-group-slot]:first-of-type .MuiButton-root, & > [data-input-group-slot]:first-of-type .MuiChip-root": isHorizontal ? {
94
+ borderTopLeftRadius: radius,
95
+ borderBottomLeftRadius: radius
96
+ } : {
97
+ borderTopLeftRadius: radius,
98
+ borderTopRightRadius: radius
99
+ },
100
+ // Esquinas redondeadas: último slot (derecha o abajo).
101
+ "& > [data-input-group-slot]:last-of-type .MuiInputBase-root, & > [data-input-group-slot]:last-of-type .MuiPickersInputBase-root, & > [data-input-group-slot]:last-of-type .MuiButton-root, & > [data-input-group-slot]:last-of-type .MuiChip-root": isHorizontal ? {
102
+ borderTopRightRadius: radius,
103
+ borderBottomRightRadius: radius
104
+ } : {
105
+ borderBottomLeftRadius: radius,
106
+ borderBottomRightRadius: radius
107
+ }
108
+ };
109
+ const baseSlotSx = {
110
+ flex: 1,
111
+ display: "flex",
112
+ alignItems: "center",
113
+ minWidth: 0
114
+ };
115
+ return /* @__PURE__ */ jsx(
116
+ Box,
117
+ {
118
+ "data-testid": "input-group",
119
+ className,
120
+ "aria-disabled": disabled ? "true" : void 0,
121
+ sx: mergeSx(baseSx, sx),
122
+ children: slots.map((child, i) => {
123
+ var _a;
124
+ const slotKey = (_a = child.key) != null ? _a : i;
125
+ return /* @__PURE__ */ jsx(
126
+ Box,
127
+ {
128
+ "data-input-group-slot": true,
129
+ sx: mergeSx(baseSlotSx, slotSx),
130
+ children: child
131
+ },
132
+ slotKey
133
+ );
134
+ })
135
+ }
136
+ );
137
+ };
138
+ export {
139
+ InputGroup as I
140
+ };
141
+ //# sourceMappingURL=InputGroup-D5pXKGjZ.js.map