@soyfri/shared-library 2.0.0-beta.9 → 2.0.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.
- package/Button-C17mExpd.cjs.map +1 -1
- package/Button-UkkP-bNw.js.map +1 -1
- package/README.md +182 -150
- package/components/ActionMenu/ActionMenu.cjs +52 -52
- package/components/ActionMenu/ActionMenu.cjs.map +1 -1
- package/components/ActionMenu/ActionMenu.d.ts +20 -36
- package/components/ActionMenu/ActionMenu.js +55 -55
- package/components/ActionMenu/ActionMenu.js.map +1 -1
- package/components/ActionMenu/index.d.ts +2 -2
- package/components/AppBar/AppBar.cjs +2 -219
- package/components/AppBar/AppBar.cjs.map +1 -1
- package/components/AppBar/AppBar.d.ts +6 -6
- package/components/AppBar/AppBar.js +5 -222
- package/components/AppBar/AppBar.js.map +1 -1
- package/components/AppBar/index.d.ts +0 -6
- package/components/Autocomplete/Autocomplete.cjs +93 -94
- package/components/Autocomplete/Autocomplete.cjs.map +1 -1
- package/components/Autocomplete/Autocomplete.d.ts +29 -26
- package/components/Autocomplete/Autocomplete.definitions.d.ts +2 -1
- package/components/Autocomplete/Autocomplete.helpers.d.ts +12 -8
- package/components/Autocomplete/Autocomplete.js +94 -95
- package/components/Autocomplete/Autocomplete.js.map +1 -1
- package/components/Autocomplete/_parts/AutocompleteChips.d.ts +7 -6
- package/components/Autocomplete/_parts/AutocompleteOption.d.ts +10 -13
- package/components/Autocomplete/index.d.ts +1 -1
- package/components/Avatar/Avatar.cjs +17 -18
- package/components/Avatar/Avatar.cjs.map +1 -1
- package/components/Avatar/Avatar.js +17 -18
- package/components/Avatar/Avatar.js.map +1 -1
- package/components/Avatar/index.d.ts +1 -0
- package/components/Button/Button.d.ts +5 -5
- package/components/Button/index.d.ts +1 -0
- package/components/Card/Card.cjs +3 -92
- package/components/Card/Card.cjs.map +1 -1
- package/components/Card/Card.d.ts +3 -50
- package/components/Card/Card.js +5 -94
- package/components/Card/Card.js.map +1 -1
- package/components/Card/Card.sx.d.ts +3 -6
- package/components/Card/index.d.ts +1 -1
- package/components/Checkbox/Checkbox.cjs +189 -0
- package/components/Checkbox/Checkbox.cjs.map +1 -0
- package/components/Checkbox/Checkbox.d.ts +55 -0
- package/components/Checkbox/Checkbox.js +189 -0
- package/components/Checkbox/Checkbox.js.map +1 -0
- package/components/Checkbox/Checkbox.sx.d.ts +13 -0
- package/components/Checkbox/index.d.ts +2 -0
- package/components/Checkbox.d.ts +6 -0
- package/components/Chip/Chip.cjs +2 -1
- package/components/Chip/Chip.cjs.map +1 -1
- package/components/Chip/Chip.js +2 -1
- package/components/Chip/Chip.js.map +1 -1
- package/components/Chip/index.d.ts +2 -1
- package/components/Chip.d.ts +4 -0
- package/components/DatePicker/DatePicker.cjs +40 -63
- package/components/DatePicker/DatePicker.cjs.map +1 -1
- package/components/DatePicker/DatePicker.d.ts +1 -13
- package/components/DatePicker/DatePicker.js +36 -59
- package/components/DatePicker/DatePicker.js.map +1 -1
- package/components/DatePicker/index.d.ts +1 -1
- package/components/DateTimePicker/DateTimePicker.cjs +58 -82
- package/components/DateTimePicker/DateTimePicker.cjs.map +1 -1
- package/components/DateTimePicker/DateTimePicker.d.ts +9 -17
- package/components/DateTimePicker/DateTimePicker.definitions.d.ts +2 -0
- package/components/DateTimePicker/DateTimePicker.helpers.d.ts +4 -2
- package/components/DateTimePicker/DateTimePicker.js +54 -78
- package/components/DateTimePicker/DateTimePicker.js.map +1 -1
- package/components/DateTimePicker/index.d.ts +1 -1
- package/components/Drawer/Drawer.cjs +12 -6
- package/components/Drawer/Drawer.cjs.map +1 -1
- package/components/Drawer/Drawer.d.ts +3 -1
- package/components/Drawer/Drawer.js +13 -7
- package/components/Drawer/Drawer.js.map +1 -1
- package/components/Drawer/DrawerItem.d.ts +6 -1
- package/components/Gallery/Gallery.cjs +154 -79
- package/components/Gallery/Gallery.cjs.map +1 -1
- package/components/Gallery/Gallery.d.ts +25 -9
- package/components/Gallery/Gallery.js +154 -79
- package/components/Gallery/Gallery.js.map +1 -1
- package/components/Gallery/GalleryLightbox.d.ts +6 -10
- package/components/Gallery/GalleryMain.d.ts +3 -7
- package/components/Gallery/GalleryThumbnails.d.ts +7 -11
- package/components/Gallery/index.d.ts +2 -1
- package/components/Gallery.d.ts +4 -0
- package/components/Icon/Icon.cjs +6 -8
- package/components/Icon/Icon.cjs.map +1 -1
- package/components/Icon/Icon.d.ts +11 -17
- package/components/Icon/Icon.js +6 -8
- package/components/Icon/Icon.js.map +1 -1
- package/components/Icon/index.d.ts +2 -1
- package/components/Icon.d.ts +4 -0
- package/components/Input/Input.cjs +26 -13
- package/components/Input/Input.cjs.map +1 -1
- package/components/Input/Input.d.ts +9 -2
- package/components/Input/Input.helpers.d.ts +3 -3
- package/components/Input/Input.js +23 -10
- package/components/Input/Input.js.map +1 -1
- package/components/Input/index.d.ts +1 -1
- package/components/InputGroup/InputGroup.cjs +23 -22
- package/components/InputGroup/InputGroup.cjs.map +1 -1
- package/components/InputGroup/InputGroup.d.ts +4 -4
- package/components/InputGroup/InputGroup.js +22 -21
- package/components/InputGroup/InputGroup.js.map +1 -1
- package/components/InputGroup/index.d.ts +2 -1
- package/components/InputGroup.d.ts +4 -0
- package/components/Modal/Modal.cjs +127 -98
- package/components/Modal/Modal.cjs.map +1 -1
- package/components/Modal/Modal.d.ts +20 -5
- package/components/Modal/Modal.js +130 -101
- package/components/Modal/Modal.js.map +1 -1
- package/components/Modal/ModalBody.d.ts +6 -1
- package/components/Modal/ModalFooter.d.ts +4 -4
- package/components/Modal/ModalHeader.d.ts +6 -1
- package/components/Modal/index.d.ts +4 -2
- package/components/Modal.d.ts +4 -0
- package/components/RadioGroup/RadioGroup.cjs +9 -7
- package/components/RadioGroup/RadioGroup.cjs.map +1 -1
- package/components/RadioGroup/RadioGroup.d.ts +9 -3
- package/components/RadioGroup/RadioGroup.js +9 -7
- package/components/RadioGroup/RadioGroup.js.map +1 -1
- package/components/RadioGroup/index.d.ts +1 -1
- package/components/Select/Select.cjs +129 -264
- package/components/Select/Select.cjs.map +1 -1
- package/components/Select/Select.d.ts +35 -20
- package/components/Select/Select.helpers.d.ts +6 -19
- package/components/Select/Select.js +134 -269
- package/components/Select/Select.js.map +1 -1
- package/components/Select/index.d.ts +1 -1
- package/components/Stat/Stat.cjs +2 -2
- package/components/Stat/Stat.cjs.map +1 -1
- package/components/Stat/Stat.js +2 -2
- package/components/Stat/Stat.js.map +1 -1
- package/components/Stat/index.d.ts +2 -1
- package/components/Stat.d.ts +4 -0
- package/components/StatusMessage/StatusMessage.cjs +84 -55
- package/components/StatusMessage/StatusMessage.cjs.map +1 -1
- package/components/StatusMessage/StatusMessage.d.ts +20 -36
- package/components/StatusMessage/StatusMessage.js +86 -57
- package/components/StatusMessage/StatusMessage.js.map +1 -1
- package/components/StatusMessage/StatusMessageContext.d.ts +16 -0
- package/components/StatusMessage/index.d.ts +4 -1
- package/components/StatusMessage.d.ts +4 -0
- package/components/Stepper/Stepper.cjs +289 -55
- package/components/Stepper/Stepper.cjs.map +1 -1
- package/components/Stepper/Stepper.d.ts +9 -20
- package/components/Stepper/Stepper.js +291 -57
- package/components/Stepper/Stepper.js.map +1 -1
- package/{hooks/Wizard/WizardContext.d.ts → components/Stepper/StepperContext.d.ts} +29 -23
- package/components/Stepper/_hooks/useHorizontalScroll.d.ts +19 -0
- package/components/Stepper/_parts/StepperScrollArrow.d.ts +19 -0
- package/components/Stepper/index.d.ts +6 -2
- package/components/Stepper.d.ts +4 -0
- package/components/Switch/Switch.cjs +5 -2
- package/components/Switch/Switch.cjs.map +1 -1
- package/components/Switch/Switch.d.ts +7 -2
- package/components/Switch/Switch.js +5 -2
- package/components/Switch/Switch.js.map +1 -1
- package/components/Tabs/Tabs.cjs +45 -29
- package/components/Tabs/Tabs.cjs.map +1 -1
- package/components/Tabs/Tabs.d.ts +21 -16
- package/components/Tabs/Tabs.js +46 -30
- package/components/Tabs/Tabs.js.map +1 -1
- package/components/Tabs/index.d.ts +4 -2
- package/components/Tabs.d.ts +4 -0
- package/components/Timeline/Timeline.cjs +3 -2
- package/components/Timeline/Timeline.cjs.map +1 -1
- package/components/Timeline/Timeline.d.ts +4 -8
- package/components/Timeline/Timeline.js +3 -2
- package/components/Timeline/Timeline.js.map +1 -1
- package/components/Timeline/index.d.ts +4 -2
- package/components/Timeline.d.ts +4 -0
- package/components/_shared/mergeSx.d.ts +7 -0
- package/{formField.sx-DfVbMe0V.js → formField.sx-8_QRnKxv.js} +2 -11
- package/formField.sx-8_QRnKxv.js.map +1 -0
- package/{formField.sx-CQ1mbk9M.cjs → formField.sx-BAX7KwMR.cjs} +10 -19
- package/formField.sx-BAX7KwMR.cjs.map +1 -0
- package/index.cjs +31 -2
- package/index.cjs.map +1 -1
- package/index.d.ts +1 -0
- package/index.js +16 -2
- package/index.js.map +1 -1
- package/mergeSx-BXoNZjB_.js +10 -0
- package/mergeSx-BXoNZjB_.js.map +1 -0
- package/mergeSx-Dbccoo_H.cjs +9 -0
- package/mergeSx-Dbccoo_H.cjs.map +1 -0
- package/mui.d.ts +3 -2
- package/package.json +6 -16
- package/theme/componentStyles.d.ts +1 -1
- package/tokens-BRrcP_p_.js +21 -0
- package/tokens-BRrcP_p_.js.map +1 -0
- package/tokens-jaWWNk39.cjs +20 -0
- package/tokens-jaWWNk39.cjs.map +1 -0
- package/utils/index.d.ts +2 -0
- package/{components/ScrollTopButton → utils}/scrollToTop.d.ts +6 -7
- package/components/AppBar/AppBarBrand.d.ts +0 -31
- package/components/AppBar/AppBarUserMenu.d.ts +0 -65
- package/components/Autocomplete/Autocomplete.types.d.ts +0 -1
- package/components/DatePicker/DatePicker.types.d.ts +0 -1
- package/components/DateTimePicker/DateTimePicker.types.d.ts +0 -1
- package/components/Input/Input.types.d.ts +0 -1
- package/components/PageLoader/PageLoader.cjs +0 -61
- package/components/PageLoader/PageLoader.cjs.map +0 -1
- package/components/PageLoader/PageLoader.d.ts +0 -38
- package/components/PageLoader/PageLoader.js +0 -61
- package/components/PageLoader/PageLoader.js.map +0 -1
- package/components/PageLoader/index.d.ts +0 -2
- package/components/PageLoader.d.ts +0 -6
- package/components/RadioGroup/RadioGroup.types.d.ts +0 -1
- package/components/ScrollTopButton/ScrollTopButton.cjs +0 -79
- package/components/ScrollTopButton/ScrollTopButton.cjs.map +0 -1
- package/components/ScrollTopButton/ScrollTopButton.d.ts +0 -48
- package/components/ScrollTopButton/ScrollTopButton.js +0 -79
- package/components/ScrollTopButton/ScrollTopButton.js.map +0 -1
- package/components/ScrollTopButton/index.d.ts +0 -4
- package/components/ScrollTopButton.d.ts +0 -6
- package/components/Select/Select.definitions.d.ts +0 -17
- package/components/Select/Select.types.d.ts +0 -1
- package/components/Select/_parts/SelectSearchHeader.d.ts +0 -15
- package/components/Select/_parts/SelectValue.d.ts +0 -22
- package/formField.sx-CQ1mbk9M.cjs.map +0 -1
- package/formField.sx-DfVbMe0V.js.map +0 -1
- package/hooks/Wizard/Wizard.cjs +0 -7
- package/hooks/Wizard/Wizard.cjs.map +0 -1
- package/hooks/Wizard/Wizard.js +0 -7
- package/hooks/Wizard/Wizard.js.map +0 -1
- package/hooks/Wizard/index.d.ts +0 -3
- package/hooks/Wizard/useWizard.d.ts +0 -9
- package/hooks/Wizard.d.ts +0 -2
- package/useWizard-CWdIxZzX.cjs +0 -94
- package/useWizard-CWdIxZzX.cjs.map +0 -1
- package/useWizard-CWq--C3o.js +0 -95
- package/useWizard-CWq--C3o.js.map +0 -1
- /package/{styles.css → index.css} +0 -0
|
@@ -36,16 +36,10 @@ const React = require("react");
|
|
|
36
36
|
const material = require("@mui/material");
|
|
37
37
|
const styles = require("@mui/material/styles");
|
|
38
38
|
const reactHookForm = require("react-hook-form");
|
|
39
|
-
const formField_sx = require("../../formField.sx-
|
|
39
|
+
const formField_sx = require("../../formField.sx-BAX7KwMR.cjs");
|
|
40
40
|
const resolvePreset = require("../../resolvePreset-CT3kU-K2.cjs");
|
|
41
|
-
const ClearIcon = require("@mui/icons-material/Clear");
|
|
42
41
|
const CheckIcon = require("@mui/icons-material/Check");
|
|
43
42
|
const buildSelectSx = (borderRadius, labelPosition) => formField_sx.buildFormFieldSx({ borderRadius, labelPosition });
|
|
44
|
-
const filterOptionsByLabel = (options, search) => {
|
|
45
|
-
if (!search) return options;
|
|
46
|
-
const needle = search.toLowerCase();
|
|
47
|
-
return options.filter((opt) => opt.label.toLowerCase().includes(needle));
|
|
48
|
-
};
|
|
49
43
|
const groupOptions = (options) => {
|
|
50
44
|
const groups = {};
|
|
51
45
|
options.forEach((opt) => {
|
|
@@ -55,108 +49,11 @@ const groupOptions = (options) => {
|
|
|
55
49
|
});
|
|
56
50
|
return groups;
|
|
57
51
|
};
|
|
58
|
-
const
|
|
59
|
-
|
|
60
|
-
if (
|
|
61
|
-
if (keys.length === 1 && groups["__default"] && groups["__default"].length === 0) {
|
|
62
|
-
return true;
|
|
63
|
-
}
|
|
64
|
-
return false;
|
|
65
|
-
};
|
|
66
|
-
const normalizeSelectValue = (value, multiple) => {
|
|
67
|
-
if (multiple) return value != null ? value : [];
|
|
68
|
-
return value != null ? value : "";
|
|
69
|
-
};
|
|
70
|
-
const isSelectValueEmpty = (normalizedValue, multiple) => {
|
|
71
|
-
if (multiple) return Array.isArray(normalizedValue) && normalizedValue.length === 0;
|
|
52
|
+
const normalizeSelectValue = (value) => value != null ? value : "";
|
|
53
|
+
const isSelectValueEmpty = (normalizedValue) => {
|
|
54
|
+
if (Array.isArray(normalizedValue)) return normalizedValue.length === 0;
|
|
72
55
|
return normalizedValue === "" || normalizedValue === null || normalizedValue === void 0;
|
|
73
56
|
};
|
|
74
|
-
const SelectSearchHeader = ({
|
|
75
|
-
value,
|
|
76
|
-
onChange,
|
|
77
|
-
placeholder = "Buscar...",
|
|
78
|
-
inputRef
|
|
79
|
-
}) => {
|
|
80
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
81
|
-
material.ListSubheader,
|
|
82
|
-
{
|
|
83
|
-
sx: {
|
|
84
|
-
px: 2,
|
|
85
|
-
pt: 1,
|
|
86
|
-
pb: 1,
|
|
87
|
-
backgroundColor: "background.paper",
|
|
88
|
-
zIndex: 1,
|
|
89
|
-
position: "sticky",
|
|
90
|
-
top: 0
|
|
91
|
-
},
|
|
92
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
93
|
-
material.TextField,
|
|
94
|
-
{
|
|
95
|
-
inputRef,
|
|
96
|
-
placeholder,
|
|
97
|
-
variant: "standard",
|
|
98
|
-
size: "small",
|
|
99
|
-
fullWidth: true,
|
|
100
|
-
value,
|
|
101
|
-
onChange: (e) => onChange(e.target.value),
|
|
102
|
-
slotProps: { htmlInput: { autoFocus: true } },
|
|
103
|
-
onClick: (e) => e.stopPropagation(),
|
|
104
|
-
onKeyDown: (e) => e.stopPropagation()
|
|
105
|
-
}
|
|
106
|
-
)
|
|
107
|
-
}
|
|
108
|
-
);
|
|
109
|
-
};
|
|
110
|
-
function SelectValue(props) {
|
|
111
|
-
var _a;
|
|
112
|
-
const {
|
|
113
|
-
selected,
|
|
114
|
-
options,
|
|
115
|
-
multiple,
|
|
116
|
-
placeholder,
|
|
117
|
-
maxChipsToShow,
|
|
118
|
-
chipVariant,
|
|
119
|
-
renderChipLabel,
|
|
120
|
-
onDeleteChip,
|
|
121
|
-
currentValues
|
|
122
|
-
} = props;
|
|
123
|
-
const isEmpty = !selected || Array.isArray(selected) && selected.length === 0;
|
|
124
|
-
if (isEmpty) {
|
|
125
|
-
return /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { sx: { color: "text.disabled" }, children: placeholder || "" });
|
|
126
|
-
}
|
|
127
|
-
if (!multiple) {
|
|
128
|
-
const item = options.find((opt) => opt.value === selected);
|
|
129
|
-
if (renderChipLabel && item) return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: renderChipLabel(item) });
|
|
130
|
-
return /* @__PURE__ */ jsxRuntime.jsx(jsxRuntime.Fragment, { children: (_a = item == null ? void 0 : item.label) != null ? _a : String(selected) });
|
|
131
|
-
}
|
|
132
|
-
const selectedValuesArray = selected;
|
|
133
|
-
const displayedChips = selectedValuesArray.slice(0, maxChipsToShow);
|
|
134
|
-
const hiddenChipsCount = selectedValuesArray.length - maxChipsToShow;
|
|
135
|
-
const handleDelete = (chipValue) => {
|
|
136
|
-
if (!onDeleteChip || !currentValues) return;
|
|
137
|
-
onDeleteChip(currentValues.filter((v) => v !== chipValue));
|
|
138
|
-
};
|
|
139
|
-
return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: [
|
|
140
|
-
displayedChips.map((val) => {
|
|
141
|
-
const item = options.find((o) => o.value === val);
|
|
142
|
-
if (!item) return null;
|
|
143
|
-
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
144
|
-
material.Chip,
|
|
145
|
-
{
|
|
146
|
-
variant: chipVariant,
|
|
147
|
-
color: "primary",
|
|
148
|
-
size: "small",
|
|
149
|
-
label: renderChipLabel ? renderChipLabel(item) : item.label,
|
|
150
|
-
avatar: item.img ? /* @__PURE__ */ jsxRuntime.jsx(material.Avatar, { src: item.img }) : void 0,
|
|
151
|
-
onDelete: () => handleDelete(val),
|
|
152
|
-
deleteIcon: /* @__PURE__ */ jsxRuntime.jsx(ClearIcon, { fontSize: "small" })
|
|
153
|
-
},
|
|
154
|
-
String(val)
|
|
155
|
-
);
|
|
156
|
-
}),
|
|
157
|
-
hiddenChipsCount > 0 && /* @__PURE__ */ jsxRuntime.jsx(material.Chip, { size: "small", variant: chipVariant, label: `+${hiddenChipsCount} más` })
|
|
158
|
-
] });
|
|
159
|
-
}
|
|
160
57
|
const renderSelectMenuItem = ({
|
|
161
58
|
option,
|
|
162
59
|
selected,
|
|
@@ -182,23 +79,12 @@ function Select(props) {
|
|
|
182
79
|
const _a = props, {
|
|
183
80
|
label,
|
|
184
81
|
options = [],
|
|
185
|
-
value,
|
|
186
|
-
onChange,
|
|
187
82
|
defaultValue,
|
|
188
83
|
size = "small",
|
|
189
|
-
multiple = false,
|
|
190
|
-
filterable = false,
|
|
191
84
|
placeholder,
|
|
192
85
|
children,
|
|
193
86
|
maxHeight = 300,
|
|
194
87
|
maxWidth,
|
|
195
|
-
maxChipsToShow = 3,
|
|
196
|
-
renderChipLabel,
|
|
197
|
-
chipVariant = "outlined",
|
|
198
|
-
loadOptions,
|
|
199
|
-
loadingMessage = "Cargando opciones...",
|
|
200
|
-
noOptionsMessage = "No hay opciones",
|
|
201
|
-
debounceTimeout = 300,
|
|
202
88
|
disabled = false,
|
|
203
89
|
error = false,
|
|
204
90
|
helperText,
|
|
@@ -206,27 +92,26 @@ function Select(props) {
|
|
|
206
92
|
labelPosition = "outside",
|
|
207
93
|
preset,
|
|
208
94
|
sx,
|
|
209
|
-
className
|
|
95
|
+
className,
|
|
96
|
+
multiple = false,
|
|
97
|
+
maxChipsToShow = 3,
|
|
98
|
+
renderChipLabel,
|
|
99
|
+
chipVariant = "outlined",
|
|
100
|
+
name: _nameIgnored,
|
|
101
|
+
control: _controlIgnored,
|
|
102
|
+
validation: _validationIgnored,
|
|
103
|
+
value: _valueIgnored,
|
|
104
|
+
onChange: _onChangeIgnored,
|
|
105
|
+
onValueChange: _onValueChangeIgnored
|
|
210
106
|
} = _a, rest = __objRest(_a, [
|
|
211
107
|
"label",
|
|
212
108
|
"options",
|
|
213
|
-
"value",
|
|
214
|
-
"onChange",
|
|
215
109
|
"defaultValue",
|
|
216
110
|
"size",
|
|
217
|
-
"multiple",
|
|
218
|
-
"filterable",
|
|
219
111
|
"placeholder",
|
|
220
112
|
"children",
|
|
221
113
|
"maxHeight",
|
|
222
114
|
"maxWidth",
|
|
223
|
-
"maxChipsToShow",
|
|
224
|
-
"renderChipLabel",
|
|
225
|
-
"chipVariant",
|
|
226
|
-
"loadOptions",
|
|
227
|
-
"loadingMessage",
|
|
228
|
-
"noOptionsMessage",
|
|
229
|
-
"debounceTimeout",
|
|
230
115
|
"disabled",
|
|
231
116
|
"error",
|
|
232
117
|
"helperText",
|
|
@@ -234,11 +119,23 @@ function Select(props) {
|
|
|
234
119
|
"labelPosition",
|
|
235
120
|
"preset",
|
|
236
121
|
"sx",
|
|
237
|
-
"className"
|
|
122
|
+
"className",
|
|
123
|
+
"multiple",
|
|
124
|
+
"maxChipsToShow",
|
|
125
|
+
"renderChipLabel",
|
|
126
|
+
"chipVariant",
|
|
127
|
+
// Separamos estos aunque no se usen directamente acá — evita que lleguen
|
|
128
|
+
// al DOM del MuiSelect via `{...rest}` y generen warnings de React.
|
|
129
|
+
"name",
|
|
130
|
+
"control",
|
|
131
|
+
"validation",
|
|
132
|
+
"value",
|
|
133
|
+
"onChange",
|
|
134
|
+
"onValueChange"
|
|
238
135
|
]);
|
|
239
136
|
const theme = styles.useTheme();
|
|
240
137
|
const presetSx = resolvePreset.resolvePreset("Select", preset, theme);
|
|
241
|
-
const isRHFMode = "control" in
|
|
138
|
+
const isRHFMode = "control" in props && props.control !== void 0;
|
|
242
139
|
const customRender = React.useMemo(() => {
|
|
243
140
|
var _a2;
|
|
244
141
|
if (React.Children.count(children) === 1) {
|
|
@@ -249,121 +146,92 @@ function Select(props) {
|
|
|
249
146
|
}
|
|
250
147
|
return null;
|
|
251
148
|
}, [children]);
|
|
252
|
-
const [search, setSearch] = React.useState("");
|
|
253
|
-
const [asyncOptions, setAsyncOptions] = React.useState([]);
|
|
254
|
-
const [loading, setLoading] = React.useState(false);
|
|
255
|
-
const debounceTimerRef = React.useRef(null);
|
|
256
|
-
const searchInputRef = React.useRef(null);
|
|
257
149
|
const [isOpen, setIsOpen] = React.useState(false);
|
|
258
150
|
const [isFocused, setIsFocused] = React.useState(false);
|
|
259
|
-
const
|
|
260
|
-
const
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
if (search) {
|
|
266
|
-
setLoading(true);
|
|
267
|
-
debounceTimerRef.current = window.setTimeout(() => {
|
|
268
|
-
loadOptions(search).then(setAsyncOptions).finally(() => {
|
|
269
|
-
var _a3;
|
|
270
|
-
setLoading(false);
|
|
271
|
-
(_a3 = searchInputRef.current) == null ? void 0 : _a3.focus();
|
|
272
|
-
});
|
|
273
|
-
}, debounceTimeout);
|
|
274
|
-
} else {
|
|
275
|
-
setAsyncOptions([]);
|
|
276
|
-
setLoading(false);
|
|
277
|
-
(_a2 = searchInputRef.current) == null ? void 0 : _a2.focus();
|
|
278
|
-
}
|
|
279
|
-
}, [search, isAsync, loadOptions, debounceTimeout]);
|
|
280
|
-
const filteredOptions = React.useMemo(() => {
|
|
281
|
-
if (isAsync) return currentOptions;
|
|
282
|
-
if (!filterable) return currentOptions;
|
|
283
|
-
return filterOptionsByLabel(currentOptions, search);
|
|
284
|
-
}, [search, filterable, currentOptions, isAsync]);
|
|
285
|
-
const groupedOptions = React.useMemo(() => groupOptions(filteredOptions), [filteredOptions]);
|
|
286
|
-
const menuItems = React.useMemo(() => {
|
|
151
|
+
const groupedOptions = React.useMemo(() => groupOptions(options), [options]);
|
|
152
|
+
const isSelected = (currentValue, val) => {
|
|
153
|
+
if (Array.isArray(currentValue)) return currentValue.includes(val);
|
|
154
|
+
return currentValue === val;
|
|
155
|
+
};
|
|
156
|
+
const buildMenuItems = (currentValue) => {
|
|
287
157
|
const items = [];
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
if (loading) {
|
|
303
|
-
items.push(
|
|
304
|
-
/* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { disabled: true, children: /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", alignItems: "center", gap: 1 }, children: [
|
|
305
|
-
/* @__PURE__ */ jsxRuntime.jsx(material.CircularProgress, { size: 20 }),
|
|
306
|
-
/* @__PURE__ */ jsxRuntime.jsx(material.Typography, { children: loadingMessage })
|
|
307
|
-
] }) }, "loading-message")
|
|
308
|
-
);
|
|
309
|
-
} else if (noOptions) {
|
|
310
|
-
items.push(
|
|
311
|
-
/* @__PURE__ */ jsxRuntime.jsx(material.MenuItem, { disabled: true, children: /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { children: noOptionsMessage }) }, "no-options-message")
|
|
312
|
-
);
|
|
313
|
-
} else {
|
|
314
|
-
Object.entries(groupedOptions).forEach(([group, opts]) => {
|
|
315
|
-
if (group !== "__default") {
|
|
316
|
-
items.push(
|
|
317
|
-
/* @__PURE__ */ jsxRuntime.jsx(material.ListSubheader, { disableSticky: true, children: group }, group)
|
|
318
|
-
);
|
|
319
|
-
}
|
|
320
|
-
opts.forEach((opt) => {
|
|
321
|
-
var _a2;
|
|
322
|
-
const isSelected = multiple ? (_a2 = value == null ? void 0 : value.includes(opt.value)) != null ? _a2 : false : value === opt.value;
|
|
323
|
-
items.push(
|
|
324
|
-
renderSelectMenuItem({
|
|
325
|
-
option: opt,
|
|
326
|
-
selected: isSelected,
|
|
327
|
-
customRender
|
|
328
|
-
})
|
|
329
|
-
);
|
|
330
|
-
});
|
|
158
|
+
Object.entries(groupedOptions).forEach(([group, opts]) => {
|
|
159
|
+
if (group !== "__default") {
|
|
160
|
+
items.push(
|
|
161
|
+
/* @__PURE__ */ jsxRuntime.jsx(material.ListSubheader, { disableSticky: true, children: group }, group)
|
|
162
|
+
);
|
|
163
|
+
}
|
|
164
|
+
opts.forEach((opt) => {
|
|
165
|
+
items.push(
|
|
166
|
+
renderSelectMenuItem({
|
|
167
|
+
option: opt,
|
|
168
|
+
selected: isSelected(currentValue, opt.value),
|
|
169
|
+
customRender
|
|
170
|
+
})
|
|
171
|
+
);
|
|
331
172
|
});
|
|
332
|
-
}
|
|
173
|
+
});
|
|
333
174
|
return items;
|
|
334
|
-
}, [
|
|
335
|
-
groupedOptions,
|
|
336
|
-
customRender,
|
|
337
|
-
filterable,
|
|
338
|
-
isAsync,
|
|
339
|
-
search,
|
|
340
|
-
loading,
|
|
341
|
-
loadingMessage,
|
|
342
|
-
noOptionsMessage,
|
|
343
|
-
multiple,
|
|
344
|
-
value
|
|
345
|
-
]);
|
|
346
|
-
const handleChangeInternal = (event, rhfOnChange) => {
|
|
347
|
-
const newValue = event.target.value;
|
|
348
|
-
if (isRHFMode) {
|
|
349
|
-
rhfOnChange == null ? void 0 : rhfOnChange(newValue);
|
|
350
|
-
} else {
|
|
351
|
-
onChange == null ? void 0 : onChange(newValue);
|
|
352
|
-
}
|
|
353
175
|
};
|
|
354
176
|
const mergedSx = [
|
|
355
177
|
buildSelectSx(borderRadius, labelPosition),
|
|
356
178
|
...presetSx ? [presetSx] : [],
|
|
357
|
-
...Array.isArray(sx) ? sx : [sx]
|
|
179
|
+
...Array.isArray(sx) ? sx : sx ? [sx] : []
|
|
358
180
|
];
|
|
359
|
-
const renderSelect = (selectValue,
|
|
360
|
-
const finalError = rhfError
|
|
181
|
+
const renderSelect = (selectValue, commitValue, onBlur, inputRef, rhfError, rhfHelperText) => {
|
|
182
|
+
const finalError = !!rhfError || !!error;
|
|
361
183
|
const finalHelperText = rhfHelperText != null ? rhfHelperText : helperText;
|
|
362
184
|
const inputElement = labelPosition === "floating" ? /* @__PURE__ */ jsxRuntime.jsx(material.OutlinedInput, { label }) : /* @__PURE__ */ jsxRuntime.jsx(material.OutlinedInput, {});
|
|
363
|
-
const normalizedValue = normalizeSelectValue(selectValue
|
|
364
|
-
const isEmpty = isSelectValueEmpty(normalizedValue
|
|
185
|
+
const normalizedValue = multiple ? selectValue != null ? selectValue : [] : normalizeSelectValue(selectValue);
|
|
186
|
+
const isEmpty = isSelectValueEmpty(normalizedValue);
|
|
365
187
|
const shouldShrink = !isEmpty || isFocused || isOpen;
|
|
366
188
|
const shouldDisplayPlaceholder = isEmpty && (isFocused || isOpen) && !!placeholder;
|
|
189
|
+
const renderValueFn = (selected) => {
|
|
190
|
+
var _a2;
|
|
191
|
+
if (multiple) {
|
|
192
|
+
const arr = selected != null ? selected : [];
|
|
193
|
+
if (arr.length === 0) {
|
|
194
|
+
return /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { sx: { color: "text.disabled" }, children: placeholder != null ? placeholder : "" });
|
|
195
|
+
}
|
|
196
|
+
const visible = arr.slice(0, maxChipsToShow);
|
|
197
|
+
const hidden = arr.length - visible.length;
|
|
198
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(material.Box, { sx: { display: "flex", flexWrap: "wrap", gap: 0.5 }, children: [
|
|
199
|
+
visible.map((val) => {
|
|
200
|
+
const item2 = options.find((o) => o.value === val);
|
|
201
|
+
if (!item2) return null;
|
|
202
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
203
|
+
material.Chip,
|
|
204
|
+
{
|
|
205
|
+
variant: chipVariant,
|
|
206
|
+
color: "primary",
|
|
207
|
+
size,
|
|
208
|
+
label: renderChipLabel ? renderChipLabel(item2) : item2.label,
|
|
209
|
+
avatar: item2.img ? /* @__PURE__ */ jsxRuntime.jsx(material.Avatar, { src: item2.img }) : void 0,
|
|
210
|
+
onMouseDown: (e) => e.stopPropagation(),
|
|
211
|
+
onDelete: () => {
|
|
212
|
+
commitValue(arr.filter((v) => v !== val));
|
|
213
|
+
}
|
|
214
|
+
},
|
|
215
|
+
String(val)
|
|
216
|
+
);
|
|
217
|
+
}),
|
|
218
|
+
hidden > 0 && /* @__PURE__ */ jsxRuntime.jsx(
|
|
219
|
+
material.Chip,
|
|
220
|
+
{
|
|
221
|
+
variant: chipVariant,
|
|
222
|
+
size,
|
|
223
|
+
label: `+${hidden} más`,
|
|
224
|
+
onMouseDown: (e) => e.stopPropagation()
|
|
225
|
+
}
|
|
226
|
+
)
|
|
227
|
+
] });
|
|
228
|
+
}
|
|
229
|
+
if (isSelectValueEmpty(selected)) {
|
|
230
|
+
return /* @__PURE__ */ jsxRuntime.jsx(material.Typography, { sx: { color: "text.disabled" }, children: placeholder != null ? placeholder : "" });
|
|
231
|
+
}
|
|
232
|
+
const item = options.find((opt) => opt.value === selected);
|
|
233
|
+
return (_a2 = item == null ? void 0 : item.label) != null ? _a2 : String(selected);
|
|
234
|
+
};
|
|
367
235
|
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
368
236
|
material.FormControl,
|
|
369
237
|
{
|
|
@@ -378,10 +246,9 @@ function Select(props) {
|
|
|
378
246
|
/* @__PURE__ */ jsxRuntime.jsx(
|
|
379
247
|
material.Select,
|
|
380
248
|
__spreadProps(__spreadValues({
|
|
381
|
-
value: normalizedValue,
|
|
382
|
-
defaultValue,
|
|
383
249
|
multiple,
|
|
384
|
-
|
|
250
|
+
value: normalizedValue,
|
|
251
|
+
onChange: (e) => commitValue(e.target.value),
|
|
385
252
|
onBlur: (e) => {
|
|
386
253
|
setIsFocused(false);
|
|
387
254
|
onBlur == null ? void 0 : onBlur(e);
|
|
@@ -389,20 +256,7 @@ function Select(props) {
|
|
|
389
256
|
onFocus: () => setIsFocused(true),
|
|
390
257
|
onOpen: () => setIsOpen(true),
|
|
391
258
|
onClose: () => setIsOpen(false),
|
|
392
|
-
renderValue:
|
|
393
|
-
SelectValue,
|
|
394
|
-
{
|
|
395
|
-
selected,
|
|
396
|
-
options: currentOptions,
|
|
397
|
-
multiple,
|
|
398
|
-
placeholder,
|
|
399
|
-
maxChipsToShow,
|
|
400
|
-
chipVariant,
|
|
401
|
-
renderChipLabel,
|
|
402
|
-
currentValues: value != null ? value : [],
|
|
403
|
-
onDeleteChip: (next) => onChange == null ? void 0 : onChange(next)
|
|
404
|
-
}
|
|
405
|
-
),
|
|
259
|
+
renderValue: renderValueFn,
|
|
406
260
|
displayEmpty: shouldDisplayPlaceholder,
|
|
407
261
|
input: inputElement,
|
|
408
262
|
disabled,
|
|
@@ -413,7 +267,7 @@ function Select(props) {
|
|
|
413
267
|
},
|
|
414
268
|
inputRef
|
|
415
269
|
}, rest), {
|
|
416
|
-
children:
|
|
270
|
+
children: buildMenuItems(normalizedValue)
|
|
417
271
|
})
|
|
418
272
|
),
|
|
419
273
|
finalHelperText && /* @__PURE__ */ jsxRuntime.jsx(material.FormHelperText, { children: finalHelperText })
|
|
@@ -422,25 +276,36 @@ function Select(props) {
|
|
|
422
276
|
);
|
|
423
277
|
};
|
|
424
278
|
if (isRHFMode) {
|
|
425
|
-
const
|
|
279
|
+
const { name, control, validation, onValueChange } = props;
|
|
426
280
|
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
427
281
|
reactHookForm.Controller,
|
|
428
282
|
{
|
|
429
|
-
name
|
|
430
|
-
control
|
|
431
|
-
rules:
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
283
|
+
name,
|
|
284
|
+
control,
|
|
285
|
+
rules: validation,
|
|
286
|
+
defaultValue,
|
|
287
|
+
render: ({ field, fieldState: { error: fieldError } }) => {
|
|
288
|
+
var _a2;
|
|
289
|
+
return renderSelect(
|
|
290
|
+
(_a2 = field.value) != null ? _a2 : multiple ? [] : null,
|
|
291
|
+
(next) => {
|
|
292
|
+
field.onChange(next);
|
|
293
|
+
onValueChange == null ? void 0 : onValueChange(next);
|
|
294
|
+
},
|
|
295
|
+
field.onBlur,
|
|
296
|
+
field.ref,
|
|
297
|
+
!!fieldError,
|
|
298
|
+
fieldError == null ? void 0 : fieldError.message
|
|
299
|
+
);
|
|
300
|
+
}
|
|
440
301
|
}
|
|
441
302
|
);
|
|
442
303
|
}
|
|
443
|
-
|
|
304
|
+
const standardProps = props;
|
|
305
|
+
return renderSelect(
|
|
306
|
+
standardProps.value,
|
|
307
|
+
(next) => standardProps.onChange(next)
|
|
308
|
+
);
|
|
444
309
|
}
|
|
445
310
|
exports.Option = Option;
|
|
446
311
|
exports.Select = Select;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Select.cjs","sources":["../../../src/components/Select/Select.sx.ts","../../../src/components/Select/Select.helpers.ts","../../../src/components/Select/_parts/SelectSearchHeader.tsx","../../../src/components/Select/_parts/SelectValue.tsx","../../../src/components/Select/_parts/SelectMenuItem.tsx","../../../src/components/Select/Select.tsx"],"sourcesContent":["import type { SelectProps as MuiSelectProps } from '@mui/material';\n\nimport { buildFormFieldSx } from '../_shared/formField.sx';\nimport type { LabelPosition } from './Select';\n\n/**\n * Builder de sx para el Select. Usa el builder compartido\n * `buildFormFieldSx`. El Select no necesita overrides específicos.\n */\nexport const buildSelectSx = (\n borderRadius: number | string,\n labelPosition: LabelPosition,\n): MuiSelectProps['sx'] =>\n buildFormFieldSx({ borderRadius, labelPosition }) as MuiSelectProps['sx'];\n","import type { SelectOption } from './Select';\n\n/**\n * Filtra opciones por `label` (case-insensitive). Si `search` es vacío,\n * devuelve el array completo. Solo se usa en modo no-async.\n */\nexport const filterOptionsByLabel = (\n options: SelectOption[],\n search: string,\n): SelectOption[] => {\n if (!search) return options;\n const needle = search.toLowerCase();\n return options.filter((opt) => opt.label.toLowerCase().includes(needle));\n};\n\n/**\n * Agrupa opciones por la propiedad `group`. Las opciones sin group caen\n * bajo la key especial `__default`. Devuelve un Record para iterar en orden\n * de inserción con Object.entries.\n */\nexport const groupOptions = (\n options: SelectOption[],\n): Record<string, SelectOption[]> => {\n const groups: Record<string, SelectOption[]> = {};\n options.forEach((opt) => {\n const group = opt.group || '__default';\n if (!groups[group]) groups[group] = [];\n groups[group].push(opt);\n });\n return groups;\n};\n\n/**\n * Determina si un conjunto de grupos está efectivamente vacío\n * (no hay grupos o solo existe `__default` sin items).\n */\nexport const isGroupedOptionsEmpty = (\n groups: Record<string, SelectOption[]>,\n): boolean => {\n const keys = Object.keys(groups);\n if (keys.length === 0) return true;\n if (keys.length === 1 && groups['__default'] && groups['__default'].length === 0) {\n return true;\n }\n return false;\n};\n\n/**\n * Normaliza el valor actual al shape que espera el MUI Select:\n * - multiple: siempre array (aunque esté vacío).\n * - single: string vacío si null/undefined.\n */\nexport const normalizeSelectValue = <T>(\n value: T | T[] | null | undefined,\n multiple: boolean,\n): T | T[] | '' => {\n if (multiple) return (value ?? []) as T[];\n return (value ?? '') as T | '';\n};\n\n/**\n * Evalúa si el valor actual está vacío (para decidir shrink del label\n * y visibilidad del placeholder).\n */\nexport const isSelectValueEmpty = (\n normalizedValue: unknown,\n multiple: boolean,\n): boolean => {\n if (multiple) return Array.isArray(normalizedValue) && normalizedValue.length === 0;\n return normalizedValue === '' || normalizedValue === null || normalizedValue === undefined;\n};\n","import React from 'react';\nimport { ListSubheader, TextField } from '@mui/material';\n\ninterface SelectSearchHeaderProps {\n value: string;\n onChange: (next: string) => void;\n placeholder?: string;\n inputRef?: React.Ref<HTMLInputElement>;\n}\n\n/**\n * Header sticky del menu del Select que contiene el input de búsqueda.\n * Se usa cuando `filterable` es true o cuando el Select opera en modo async.\n * Detiene la propagación de click/keydown para que el menu no se cierre ni\n * intercepte las teclas al tipear.\n */\nexport const SelectSearchHeader: React.FC<SelectSearchHeaderProps> = ({\n value,\n onChange,\n placeholder = 'Buscar...',\n inputRef,\n}) => {\n return (\n <ListSubheader\n sx={{\n px: 2,\n pt: 1,\n pb: 1,\n backgroundColor: 'background.paper',\n zIndex: 1,\n position: 'sticky',\n top: 0,\n }}\n >\n <TextField\n inputRef={inputRef}\n placeholder={placeholder}\n variant=\"standard\"\n size=\"small\"\n fullWidth\n value={value}\n onChange={(e) => onChange(e.target.value)}\n slotProps={{ htmlInput: { autoFocus: true } }}\n onClick={(e) => e.stopPropagation()}\n onKeyDown={(e) => e.stopPropagation()}\n />\n </ListSubheader>\n );\n};\n\nexport default SelectSearchHeader;\n","import React from 'react';\nimport { Avatar, Box, Chip, Typography } from '@mui/material';\nimport ClearIcon from '@mui/icons-material/Clear';\n\nimport type {\n SelectOption,\n RenderChipLabel,\n ChipVariant,\n} from '../Select';\n\ninterface SelectValueProps<TValue extends SelectOption['value']> {\n selected: TValue | TValue[] | null | undefined;\n options: SelectOption[];\n multiple: boolean;\n placeholder?: string;\n maxChipsToShow: number;\n chipVariant: ChipVariant;\n renderChipLabel?: RenderChipLabel;\n /** Solo relevante en modo multiple. Recibe el nuevo array de valores. */\n onDeleteChip?: (nextValues: TValue[]) => void;\n /** Array de valores actuales (para componer el nuevo array al borrar chips). */\n currentValues?: TValue[];\n}\n\n/**\n * Render del valor seleccionado del Select.\n * - single: texto (label) o lo que devuelva `renderChipLabel`.\n * - multiple: chips con delete. Trunca después de `maxChipsToShow` mostrando \"+N más\".\n * - empty: placeholder en color disabled.\n */\nexport function SelectValue<TValue extends SelectOption['value']>(\n props: SelectValueProps<TValue>,\n) {\n const {\n selected,\n options,\n multiple,\n placeholder,\n maxChipsToShow,\n chipVariant,\n renderChipLabel,\n onDeleteChip,\n currentValues,\n } = props;\n\n const isEmpty =\n !selected || (Array.isArray(selected) && selected.length === 0);\n\n if (isEmpty) {\n return (\n <Typography sx={{ color: 'text.disabled' }}>{placeholder || ''}</Typography>\n );\n }\n\n if (!multiple) {\n const item = options.find((opt) => opt.value === selected);\n if (renderChipLabel && item) return <>{renderChipLabel(item)}</>;\n return <>{item?.label ?? String(selected)}</>;\n }\n\n const selectedValuesArray = selected as TValue[];\n const displayedChips = selectedValuesArray.slice(0, maxChipsToShow);\n const hiddenChipsCount = selectedValuesArray.length - maxChipsToShow;\n\n const handleDelete = (chipValue: TValue) => {\n if (!onDeleteChip || !currentValues) return;\n onDeleteChip(currentValues.filter((v) => v !== chipValue));\n };\n\n return (\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>\n {displayedChips.map((val) => {\n const item = options.find((o) => o.value === val);\n if (!item) return null;\n\n return (\n <Chip\n variant={chipVariant}\n color=\"primary\"\n size=\"small\"\n key={String(val)}\n label={renderChipLabel ? renderChipLabel(item) : item.label}\n avatar={item.img ? <Avatar src={item.img} /> : undefined}\n onDelete={() => handleDelete(val)}\n deleteIcon={<ClearIcon fontSize=\"small\" />}\n />\n );\n })}\n {hiddenChipsCount > 0 && (\n <Chip size=\"small\" variant={chipVariant} label={`+${hiddenChipsCount} más`} />\n )}\n </Box>\n );\n}\n\nexport default SelectValue;\n","import React from 'react';\nimport { ListItemIcon, MenuItem } from '@mui/material';\nimport CheckIcon from '@mui/icons-material/Check';\n\nimport type { SelectOption, RenderOptionItem } from '../Select';\n\ninterface RenderSelectMenuItemArgs {\n option: SelectOption;\n selected: boolean;\n customRender?: RenderOptionItem | null;\n}\n\n/**\n * Render helper (no componente) que devuelve un <MenuItem> listo para\n * colocarse como hijo directo del <MuiSelect>. Se implementa como función\n * y no como componente porque MUI Select inspecciona `props.value` de sus\n * children para resolver la selección, y envolverlo en un componente extra\n * rompe esa detección.\n *\n * Incluye el icono de check a la izquierda cuando `selected` es true. Si el\n * consumer pasó un `<Option>{(opt) => ...}</Option>`, usa ese render para el\n * contenido principal; de lo contrario muestra `option.label`.\n */\nexport const renderSelectMenuItem = ({\n option,\n selected,\n customRender,\n}: RenderSelectMenuItemArgs): React.ReactElement => (\n <MenuItem\n key={String(option.value)}\n value={option.value}\n disabled={option.disabled}\n selected={selected}\n >\n <ListItemIcon sx={{ minWidth: 32 }}>\n {selected && <CheckIcon color=\"success\" fontSize=\"small\" />}\n </ListItemIcon>\n {customRender ? customRender(option) : option.label}\n </MenuItem>\n);\n","import React, {\n isValidElement,\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n Box,\n CircularProgress,\n FormControl,\n FormHelperText,\n InputLabel,\n ListSubheader,\n MenuItem,\n OutlinedInput,\n Select as MuiSelect,\n SelectChangeEvent,\n Typography,\n type SelectProps as MuiSelectProps,\n} from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { Controller, type Control, type RegisterOptions } from 'react-hook-form';\n\nimport { buildSelectSx } from './Select.sx';\nimport { resolvePreset } from '../_shared/resolvePreset';\nimport {\n filterOptionsByLabel,\n groupOptions,\n isGroupedOptionsEmpty,\n isSelectValueEmpty,\n normalizeSelectValue,\n} from './Select.helpers';\nimport { SelectSearchHeader } from './_parts/SelectSearchHeader';\nimport { SelectValue } from './_parts/SelectValue';\nimport { renderSelectMenuItem } from './_parts/SelectMenuItem';\n\n// ── Tipos de dominio ─────────────────────────────────────────────────────\nexport interface SelectOption {\n value: string | number;\n label: string;\n img?: string;\n disabled?: boolean;\n group?: string;\n [key: string]: any;\n}\n\nexport type LabelPosition = 'outside' | 'floating';\nexport type ChipVariant = 'outlined' | 'filled';\nexport type SelectSize = 'small' | 'medium';\n\n// ── Render slots ─────────────────────────────────────────────────────────\nexport type RenderOptionItem = (item: SelectOption) => ReactNode;\nexport type RenderChipLabel = (item: SelectOption) => ReactNode;\n\n// ── Sub-componente declarativo <Option> ──────────────────────────────────\nexport interface OptionProps {\n children: RenderOptionItem;\n}\n\n// ── Props base ───────────────────────────────────────────────────────────\nexport interface BaseSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> {\n label?: string;\n options?: SelectOption[];\n defaultValue?: TValue | TValue[];\n size?: SelectSize;\n multiple?: boolean;\n filterable?: boolean;\n placeholder?: string;\n children?: ReactElement<{ children: RenderOptionItem }>;\n maxHeight?: number | string;\n maxWidth?: number | string;\n maxChipsToShow?: number;\n renderChipLabel?: RenderChipLabel;\n chipVariant?: ChipVariant;\n loadOptions?: (inputValue: string) => Promise<SelectOption[]>;\n loadingMessage?: ReactNode;\n noOptionsMessage?: ReactNode;\n debounceTimeout?: number;\n disabled?: boolean;\n error?: boolean;\n helperText?: string;\n /** Border radius del input (px o string CSS). Default: 10 */\n borderRadius?: number | string;\n /**\n * Posición del label.\n * - \"outside\" (default): label arriba del input, sin animación.\n * - \"floating\": label clásico de MUI (flota dentro del notched outline).\n */\n labelPosition?: LabelPosition;\n /**\n * Nombre del preset de estilo registrado en `theme.styles.Select`.\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 sx?: MuiSelectProps['sx'];\n className?: string;\n}\n\n// ── Variantes discriminadas (RHF vs controlado) ──────────────────────────\nexport interface RHFSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> extends BaseSelectProps<TValue> {\n name: string;\n control: Control<any>;\n validation?: RegisterOptions;\n value?: TValue | TValue[];\n onChange?: (val: TValue | TValue[]) => void;\n}\n\nexport interface StandardSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> extends BaseSelectProps<TValue> {\n name?: string;\n control?: never;\n validation?: never;\n value: TValue | TValue[];\n onChange: (val: TValue | TValue[]) => void;\n}\n\n// ── API pública final ────────────────────────────────────────────────────\nexport type SelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> = RHFSelectProps<TValue> | StandardSelectProps<TValue>;\n\n// ── Sub-componente declarativo <Option> ──────────────────────────────────\nexport function Option(_props: OptionProps) {\n return null;\n}\nOption.displayName = 'Option';\n\n// ── Componente ───────────────────────────────────────────────────────────\nexport function Select<TValue extends SelectOption['value'] = SelectOption['value']>(\n props: SelectProps<TValue>,\n) {\n const {\n label,\n options = [],\n value,\n onChange,\n defaultValue,\n size = 'small',\n multiple = false,\n filterable = false,\n placeholder,\n children,\n maxHeight = 300,\n maxWidth,\n maxChipsToShow = 3,\n renderChipLabel,\n chipVariant = 'outlined',\n loadOptions,\n loadingMessage = 'Cargando opciones...',\n noOptionsMessage = 'No hay opciones',\n debounceTimeout = 300,\n disabled = false,\n error = false,\n helperText,\n borderRadius = 10,\n labelPosition = 'outside',\n preset,\n sx,\n className,\n ...rest\n } = props;\n\n const theme = useTheme();\n const presetSx = resolvePreset('Select', preset, theme);\n\n const isRHFMode = 'control' in rest && (rest as any).control !== undefined;\n\n // Custom render opcional vía <Option>{item => ...}</Option>\n const customRender: RenderOptionItem | null = useMemo(() => {\n if (React.Children.count(children) === 1) {\n const child = React.Children.only(children);\n if (isValidElement(child) && (child.type as any)?.displayName === 'Option') {\n return (child.props as OptionProps).children;\n }\n }\n return null;\n }, [children]);\n\n // Búsqueda / async\n const [search, setSearch] = useState('');\n const [asyncOptions, setAsyncOptions] = useState<SelectOption[]>([]);\n const [loading, setLoading] = useState(false);\n const debounceTimerRef = useRef<number | null>(null);\n const searchInputRef = useRef<HTMLInputElement>(null);\n\n // Focus/open tracking para el comportamiento del label \"outside\".\n const [isOpen, setIsOpen] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const isAsync = typeof loadOptions === 'function';\n const currentOptions = isAsync ? asyncOptions : options;\n\n useEffect(() => {\n if (!isAsync) return;\n\n if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);\n\n if (search) {\n setLoading(true);\n debounceTimerRef.current = window.setTimeout(() => {\n loadOptions!(search)\n .then(setAsyncOptions)\n .finally(() => {\n setLoading(false);\n searchInputRef.current?.focus();\n });\n }, debounceTimeout);\n } else {\n setAsyncOptions([]);\n setLoading(false);\n searchInputRef.current?.focus();\n }\n }, [search, isAsync, loadOptions, debounceTimeout]);\n\n const filteredOptions = useMemo(() => {\n if (isAsync) return currentOptions;\n if (!filterable) return currentOptions;\n return filterOptionsByLabel(currentOptions, search);\n }, [search, filterable, currentOptions, isAsync]);\n\n const groupedOptions = useMemo(() => groupOptions(filteredOptions), [filteredOptions]);\n\n // Items del menu (search header + loading/empty + grupos + opciones)\n const menuItems = useMemo(() => {\n const items: React.ReactNode[] = [];\n\n if (filterable || isAsync) {\n items.push(\n <SelectSearchHeader\n key=\"search-header\"\n value={search}\n onChange={setSearch}\n inputRef={searchInputRef}\n />,\n );\n }\n\n const noOptions = isGroupedOptionsEmpty(groupedOptions);\n\n if (loading) {\n items.push(\n <MenuItem key=\"loading-message\" disabled>\n <Box sx={{ display: 'flex', alignItems: 'center', gap: 1 }}>\n <CircularProgress size={20} />\n <Typography>{loadingMessage}</Typography>\n </Box>\n </MenuItem>,\n );\n } else if (noOptions) {\n items.push(\n <MenuItem key=\"no-options-message\" disabled>\n <Typography>{noOptionsMessage}</Typography>\n </MenuItem>,\n );\n } else {\n Object.entries(groupedOptions).forEach(([group, opts]) => {\n if (group !== '__default') {\n items.push(\n <ListSubheader key={group} disableSticky>\n {group}\n </ListSubheader>,\n );\n }\n opts.forEach((opt) => {\n const isSelected = multiple\n ? (value as TValue[] | undefined)?.includes(opt.value as TValue) ?? false\n : value === opt.value;\n\n items.push(\n renderSelectMenuItem({\n option: opt,\n selected: isSelected,\n customRender,\n }),\n );\n });\n });\n }\n return items;\n }, [\n groupedOptions,\n customRender,\n filterable,\n isAsync,\n search,\n loading,\n loadingMessage,\n noOptionsMessage,\n multiple,\n value,\n ]);\n\n // Handler de cambio\n const handleChangeInternal = (\n event: SelectChangeEvent<any>,\n rhfOnChange?: (...event: any[]) => void,\n ) => {\n const newValue = event.target.value;\n if (isRHFMode) {\n rhfOnChange?.(newValue);\n } else {\n (onChange as (val: TValue | TValue[]) => void)?.(newValue);\n }\n };\n\n // Sx mergeado (defaults + consumer)\n const mergedSx = [\n buildSelectSx(borderRadius, labelPosition),\n ...(presetSx ? [presetSx] : []),\n ...(Array.isArray(sx) ? sx : [sx]),\n ];\n\n // Render base\n const renderSelect = (\n selectValue: any,\n selectOnChange: any,\n onBlur?: any,\n inputRef?: any,\n rhfError?: boolean,\n rhfHelperText?: string,\n ) => {\n const finalError = rhfError ?? error;\n const finalHelperText = rhfHelperText ?? helperText;\n\n const inputElement =\n labelPosition === 'floating' ? (\n <OutlinedInput label={label} />\n ) : (\n <OutlinedInput />\n );\n\n const normalizedValue = normalizeSelectValue(selectValue, multiple);\n const isEmpty = isSelectValueEmpty(normalizedValue, multiple);\n\n // Shrink cuando hay valor, foco, o dropdown abierto.\n const shouldShrink = !isEmpty || isFocused || isOpen;\n // Placeholder solo cuando el label ya subió.\n const shouldDisplayPlaceholder = isEmpty && (isFocused || isOpen) && !!placeholder;\n\n return (\n <FormControl\n fullWidth\n size={size}\n error={finalError}\n disabled={disabled}\n className={className}\n sx={mergedSx}\n >\n {label && <InputLabel shrink={shouldShrink}>{label}</InputLabel>}\n <MuiSelect\n value={normalizedValue}\n defaultValue={defaultValue}\n multiple={multiple}\n onChange={selectOnChange}\n onBlur={(e) => {\n setIsFocused(false);\n onBlur?.(e);\n }}\n onFocus={() => setIsFocused(true)}\n onOpen={() => setIsOpen(true)}\n onClose={() => setIsOpen(false)}\n renderValue={(selected) => (\n <SelectValue<TValue>\n selected={selected as TValue | TValue[]}\n options={currentOptions}\n multiple={multiple}\n placeholder={placeholder}\n maxChipsToShow={maxChipsToShow}\n chipVariant={chipVariant}\n renderChipLabel={renderChipLabel}\n currentValues={(value as TValue[]) ?? []}\n onDeleteChip={(next) =>\n (onChange as (v: TValue | TValue[]) => void)?.(next)\n }\n />\n )}\n displayEmpty={shouldDisplayPlaceholder}\n input={inputElement}\n disabled={disabled}\n MenuProps={{\n PaperProps: {\n style: { maxHeight, maxWidth },\n },\n }}\n inputRef={inputRef}\n {...(rest as any)}\n >\n {menuItems}\n </MuiSelect>\n {finalHelperText && <FormHelperText>{finalHelperText}</FormHelperText>}\n </FormControl>\n );\n };\n\n // Branch: RHF vs controlado\n if (isRHFMode) {\n const rhfProps = rest as RHFSelectProps<TValue>;\n return (\n <Controller\n name={rhfProps.name}\n control={rhfProps.control}\n rules={rhfProps.validation}\n render={({ field, fieldState: { error: fieldError } }) =>\n renderSelect(\n field.value,\n (e: SelectChangeEvent<any>) => handleChangeInternal(e, field.onChange),\n field.onBlur,\n field.ref,\n !!fieldError,\n fieldError?.message,\n )\n }\n />\n );\n }\n\n return renderSelect(value, (e: SelectChangeEvent<any>) => handleChangeInternal(e));\n}\n\nexport default Select;\n"],"names":["buildFormFieldSx","jsx","ListSubheader","TextField","Typography","Fragment","jsxs","Box","Chip","Avatar","MenuItem","ListItemIcon","useTheme","resolvePreset","useMemo","isValidElement","_a","useState","useRef","useEffect","CircularProgress","OutlinedInput","FormControl","InputLabel","MuiSelect","FormHelperText","Controller"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Select.cjs","sources":["../../../src/components/Select/Select.sx.ts","../../../src/components/Select/Select.helpers.ts","../../../src/components/Select/_parts/SelectMenuItem.tsx","../../../src/components/Select/Select.tsx"],"sourcesContent":["import type { SelectProps as MuiSelectProps } from '@mui/material';\n\nimport { buildFormFieldSx } from '../_shared/formField.sx';\nimport type { LabelPosition } from './Select';\n\n/**\n * Builder de sx para el Select. Usa el builder compartido\n * `buildFormFieldSx`. El Select no necesita overrides específicos.\n */\nexport const buildSelectSx = (\n borderRadius: number | string,\n labelPosition: LabelPosition,\n): MuiSelectProps['sx'] =>\n buildFormFieldSx({ borderRadius, labelPosition }) as MuiSelectProps['sx'];\n","import type { SelectOption } from './Select';\n\n/**\n * Agrupa opciones por la propiedad `group`. Las opciones sin group caen\n * bajo la key especial `__default`. Devuelve un Record para iterar en orden\n * de inserción con Object.entries.\n */\nexport const groupOptions = (\n options: SelectOption[],\n): Record<string, SelectOption[]> => {\n const groups: Record<string, SelectOption[]> = {};\n options.forEach((opt) => {\n const group = opt.group || '__default';\n if (!groups[group]) groups[group] = [];\n groups[group].push(opt);\n });\n return groups;\n};\n\n/**\n * Normaliza el valor single al shape que espera MUI Select: string vacío si\n * el valor es `null`/`undefined`.\n */\nexport const normalizeSelectValue = <T>(value: T | null | undefined): T | '' =>\n (value ?? '') as T | '';\n\n/** `true` si el valor está vacío (para shrink del label + placeholder). En\n * multi se considera vacío cuando el array no tiene elementos. */\nexport const isSelectValueEmpty = (normalizedValue: unknown): boolean => {\n if (Array.isArray(normalizedValue)) return normalizedValue.length === 0;\n return (\n normalizedValue === '' ||\n normalizedValue === null ||\n normalizedValue === undefined\n );\n};\n","import React from 'react';\nimport { ListItemIcon, MenuItem } from '@mui/material';\nimport CheckIcon from '@mui/icons-material/Check';\n\nimport type { SelectOption, RenderOptionItem } from '../Select';\n\ninterface RenderSelectMenuItemArgs {\n option: SelectOption;\n selected: boolean;\n customRender?: RenderOptionItem | null;\n}\n\n/**\n * Render helper (no componente) que devuelve un <MenuItem> listo para\n * colocarse como hijo directo del <MuiSelect>. Se implementa como función\n * y no como componente porque MUI Select inspecciona `props.value` de sus\n * children para resolver la selección, y envolverlo en un componente extra\n * rompe esa detección.\n *\n * Incluye el icono de check a la izquierda cuando `selected` es true. Si el\n * consumer pasó un `<Option>{(opt) => ...}</Option>`, usa ese render para el\n * contenido principal; de lo contrario muestra `option.label`.\n */\nexport const renderSelectMenuItem = ({\n option,\n selected,\n customRender,\n}: RenderSelectMenuItemArgs): React.ReactElement => (\n <MenuItem\n key={String(option.value)}\n value={option.value}\n disabled={option.disabled}\n selected={selected}\n >\n <ListItemIcon sx={{ minWidth: 32 }}>\n {selected && <CheckIcon color=\"success\" fontSize=\"small\" />}\n </ListItemIcon>\n {customRender ? customRender(option) : option.label}\n </MenuItem>\n);\n","import {\n Children,\n isValidElement,\n useMemo,\n useState,\n type ReactElement,\n type ReactNode,\n} from 'react';\nimport {\n Avatar,\n Box,\n Chip,\n FormControl,\n FormHelperText,\n InputLabel,\n ListSubheader,\n OutlinedInput,\n Select as MuiSelect,\n Typography,\n type SelectChangeEvent,\n type SelectProps as MuiSelectProps,\n} from '@mui/material';\nimport { useTheme } from '@mui/material/styles';\nimport { Controller, type Control, type RegisterOptions } from 'react-hook-form';\n\nimport { buildSelectSx } from './Select.sx';\nimport { resolvePreset } from '../_shared/resolvePreset';\nimport {\n groupOptions,\n isSelectValueEmpty,\n normalizeSelectValue,\n} from './Select.helpers';\nimport { renderSelectMenuItem } from './_parts/SelectMenuItem';\n\n// ── Tipos de dominio ─────────────────────────────────────────────────────\nexport interface SelectOption {\n value: string | number;\n label: string;\n img?: string;\n disabled?: boolean;\n group?: string;\n [key: string]: any;\n}\n\nexport type LabelPosition = 'outside' | 'floating';\nexport type SelectSize = 'small' | 'medium';\n\n// ── Render slots ─────────────────────────────────────────────────────────\nexport type RenderOptionItem = (item: SelectOption) => ReactNode;\nexport type RenderChipLabel = (item: SelectOption) => ReactNode;\n\n// ── Sub-componente declarativo <Option> ──────────────────────────────────\nexport interface OptionProps {\n children: RenderOptionItem;\n}\n\n// ── Props base ───────────────────────────────────────────────────────────\nexport interface BaseSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> {\n label?: string;\n options?: SelectOption[];\n defaultValue?: TValue | TValue[];\n size?: SelectSize;\n placeholder?: string;\n children?: ReactElement<{ children: RenderOptionItem }>;\n maxHeight?: number | string;\n maxWidth?: number | string;\n disabled?: boolean;\n error?: boolean;\n helperText?: string;\n /** Border radius del input (px o string CSS). Default: 10 */\n borderRadius?: number | string;\n /**\n * Posición del label.\n * - \"outside\" (default): label arriba del input, sin animación.\n * - \"floating\": label clásico de MUI (flota dentro del notched outline).\n */\n labelPosition?: LabelPosition;\n /**\n * Nombre del preset de estilo registrado en `theme.styles.Select`.\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 sx?: MuiSelectProps['sx'];\n className?: string;\n // ── Props que solo aplican en modo `multiple` ──────────────────────────\n /** Cantidad máxima de chips visibles antes de colapsar al \"+N más\". Default: 3. */\n maxChipsToShow?: number;\n /** Custom render del label de cada chip. Si no se pasa, usa `option.label`. */\n renderChipLabel?: RenderChipLabel;\n /** Variant de los chips. Default: 'outlined'. */\n chipVariant?: 'outlined' | 'filled';\n}\n\n// ── Variantes discriminadas (single / multi / RHF) ──────────────────────\nexport interface SingleStandardSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> extends BaseSelectProps<TValue> {\n multiple?: false;\n name?: string;\n control?: never;\n validation?: never;\n value: TValue;\n onChange: (val: TValue) => void;\n}\n\nexport interface MultipleStandardSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> extends BaseSelectProps<TValue> {\n multiple: true;\n name?: string;\n control?: never;\n validation?: never;\n value: TValue[];\n onChange: (val: TValue[]) => void;\n}\n\nexport type StandardSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> =\n | SingleStandardSelectProps<TValue>\n | MultipleStandardSelectProps<TValue>;\n\nexport interface RHFSelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> extends BaseSelectProps<TValue> {\n /** En RHF se acepta como boolean dinámico — `field.value` se trata según\n * esto: array si `multiple`, valor único si no. */\n multiple?: boolean;\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 tiene generics propios (como `TValue` acá), TS se\n // confunde narroweando el discriminated union y `Control<any>` no logra\n // absorber `Control<MyForm>` en la comparación estructural profunda.\n // El `any` plano elimina ese ruido. RHF adentro sigue teniendo sus tipos\n // fuertes — solo degradamos la superficie del prop del Select.\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: TValue | TValue[]) => void;\n value?: never;\n onChange?: never;\n}\n\n// ── API pública final ────────────────────────────────────────────────────\nexport type SelectProps<\n TValue extends SelectOption['value'] = SelectOption['value'],\n> = RHFSelectProps<TValue> | StandardSelectProps<TValue>;\n\n// ── Sub-componente declarativo <Option> ──────────────────────────────────\nexport function Option(_props: OptionProps) {\n return null;\n}\nOption.displayName = 'Option';\n\n// ── Componente ───────────────────────────────────────────────────────────\nexport function Select<\n TValue extends SelectOption['value'] = SelectOption['value'],\n>(props: SelectProps<TValue>) {\n const {\n label,\n options = [],\n defaultValue,\n size = 'small',\n placeholder,\n children,\n maxHeight = 300,\n maxWidth,\n disabled = false,\n error = false,\n helperText,\n borderRadius = 10,\n labelPosition = 'outside',\n preset,\n sx,\n className,\n multiple = false,\n maxChipsToShow = 3,\n renderChipLabel,\n chipVariant = 'outlined',\n // Separamos estos aunque no se usen directamente acá — evita que lleguen\n // al DOM del MuiSelect via `{...rest}` y generen warnings de React.\n name: _nameIgnored,\n control: _controlIgnored,\n validation: _validationIgnored,\n value: _valueIgnored,\n onChange: _onChangeIgnored,\n onValueChange: _onValueChangeIgnored,\n ...rest\n } = props as MultipleStandardSelectProps<TValue> & {\n name?: string;\n control?: Control<any>;\n validation?: RegisterOptions;\n onValueChange?: (val: TValue | TValue[]) => void;\n };\n\n const theme = useTheme();\n const presetSx = resolvePreset('Select', preset, theme);\n\n const isRHFMode =\n 'control' in props &&\n (props as RHFSelectProps<TValue>).control !== undefined;\n\n // Custom render opcional vía <Option>{item => ...}</Option>\n const customRender: RenderOptionItem | null = useMemo(() => {\n if (Children.count(children) === 1) {\n const child = Children.only(children);\n if (isValidElement(child) && (child.type as any)?.displayName === 'Option') {\n return (child.props as OptionProps).children;\n }\n }\n return null;\n }, [children]);\n\n // Focus/open tracking para el comportamiento del label \"outside\".\n const [isOpen, setIsOpen] = useState(false);\n const [isFocused, setIsFocused] = useState(false);\n\n const groupedOptions = useMemo(() => groupOptions(options), [options]);\n\n // Igualdad por valor, soportando single y multi de forma uniforme.\n const isSelected = (\n currentValue: TValue | TValue[] | '',\n val: TValue,\n ): boolean => {\n if (Array.isArray(currentValue)) return currentValue.includes(val);\n return currentValue === val;\n };\n\n const buildMenuItems = (currentValue: TValue | TValue[] | '') => {\n const items: ReactNode[] = [];\n Object.entries(groupedOptions).forEach(([group, opts]) => {\n if (group !== '__default') {\n items.push(\n <ListSubheader key={group} disableSticky>\n {group}\n </ListSubheader>,\n );\n }\n opts.forEach((opt) => {\n items.push(\n renderSelectMenuItem({\n option: opt,\n selected: isSelected(currentValue, opt.value as TValue),\n customRender,\n }),\n );\n });\n });\n return items;\n };\n\n const mergedSx = [\n buildSelectSx(borderRadius, labelPosition),\n ...(presetSx ? [presetSx] : []),\n ...(Array.isArray(sx) ? sx : sx ? [sx] : []),\n ];\n\n // Render base (común a RHF y controlled). `commitValue` recibe el valor\n // ya resuelto (sin event) — lo usamos también para el delete de chips.\n const renderSelect = (\n selectValue: TValue | TValue[] | null | undefined,\n commitValue: (next: TValue | TValue[]) => void,\n onBlur?: (event: React.FocusEvent<HTMLInputElement | HTMLTextAreaElement>) => void,\n inputRef?: React.Ref<HTMLInputElement>,\n rhfError?: boolean,\n rhfHelperText?: string,\n ) => {\n const finalError = !!rhfError || !!error;\n const finalHelperText = rhfHelperText ?? helperText;\n\n const inputElement =\n labelPosition === 'floating' ? (\n <OutlinedInput label={label} />\n ) : (\n <OutlinedInput />\n );\n\n // Normalizamos según modo: array vacío para multi, '' para single.\n const normalizedValue: TValue | TValue[] | '' = multiple\n ? ((selectValue as TValue[] | null | undefined) ?? [])\n : normalizeSelectValue(selectValue as TValue | null | undefined);\n\n const isEmpty = isSelectValueEmpty(normalizedValue);\n\n // Shrink cuando hay valor, foco, o dropdown abierto.\n const shouldShrink = !isEmpty || isFocused || isOpen;\n // Placeholder solo cuando el label ya subió.\n const shouldDisplayPlaceholder =\n isEmpty && (isFocused || isOpen) && !!placeholder;\n\n const renderValueFn = (selected: any): ReactNode => {\n // ── Multi: render de chips con delete ────────────────────────────\n if (multiple) {\n const arr = (selected ?? []) as TValue[];\n if (arr.length === 0) {\n return (\n <Typography sx={{ color: 'text.disabled' }}>\n {placeholder ?? ''}\n </Typography>\n );\n }\n const visible = arr.slice(0, maxChipsToShow);\n const hidden = arr.length - visible.length;\n return (\n <Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>\n {visible.map((val) => {\n const item = options.find((o) => o.value === val);\n if (!item) return null;\n return (\n <Chip\n key={String(val)}\n variant={chipVariant}\n color=\"primary\"\n size={size}\n label={\n renderChipLabel ? renderChipLabel(item) : item.label\n }\n avatar={item.img ? <Avatar src={item.img} /> : undefined}\n // Evita que el click sobre el chip dispare el open del menú.\n onMouseDown={(e) => e.stopPropagation()}\n onDelete={() => {\n commitValue(arr.filter((v) => v !== val));\n }}\n />\n );\n })}\n {hidden > 0 && (\n <Chip\n variant={chipVariant}\n size={size}\n label={`+${hidden} más`}\n onMouseDown={(e) => e.stopPropagation()}\n />\n )}\n </Box>\n );\n }\n // ── Single: igual que el flujo previo ────────────────────────────\n if (isSelectValueEmpty(selected)) {\n return (\n <Typography sx={{ color: 'text.disabled' }}>\n {placeholder ?? ''}\n </Typography>\n );\n }\n const item = options.find((opt) => opt.value === selected);\n return item?.label ?? String(selected);\n };\n\n return (\n <FormControl\n fullWidth\n size={size}\n error={finalError}\n disabled={disabled}\n className={className}\n sx={mergedSx}\n >\n {label && <InputLabel shrink={shouldShrink}>{label}</InputLabel>}\n <MuiSelect\n multiple={multiple}\n value={normalizedValue as any}\n onChange={(e: SelectChangeEvent<TValue | TValue[]>) =>\n commitValue(e.target.value as TValue | TValue[])\n }\n onBlur={(e) => {\n setIsFocused(false);\n onBlur?.(e);\n }}\n onFocus={() => setIsFocused(true)}\n onOpen={() => setIsOpen(true)}\n onClose={() => setIsOpen(false)}\n renderValue={renderValueFn}\n displayEmpty={shouldDisplayPlaceholder}\n input={inputElement}\n disabled={disabled}\n MenuProps={{\n PaperProps: {\n style: { maxHeight, maxWidth },\n },\n }}\n inputRef={inputRef}\n {...(rest as any)}\n >\n {buildMenuItems(normalizedValue)}\n </MuiSelect>\n {finalHelperText && <FormHelperText>{finalHelperText}</FormHelperText>}\n </FormControl>\n );\n };\n\n // ── RHF mode ──────────────────────────────────────────────────────────\n if (isRHFMode) {\n const { name, control, validation, onValueChange } = props as RHFSelectProps<TValue>;\n return (\n <Controller\n name={name}\n control={control}\n rules={validation}\n defaultValue={defaultValue}\n render={({ field, fieldState: { error: fieldError } }) =>\n renderSelect(\n field.value ?? (multiple ? [] : null),\n (next) => {\n field.onChange(next);\n onValueChange?.(next);\n },\n field.onBlur,\n field.ref,\n !!fieldError,\n fieldError?.message,\n )\n }\n />\n );\n }\n\n // ── Controlled mode ───────────────────────────────────────────────────\n const standardProps = props as StandardSelectProps<TValue>;\n return renderSelect(\n standardProps.value as TValue | TValue[] | null | undefined,\n (next) =>\n (standardProps.onChange as (v: TValue | TValue[]) => void)(next),\n );\n}\n\nexport default Select;\n"],"names":["buildFormFieldSx","jsxs","MenuItem","jsx","ListItemIcon","useTheme","resolvePreset","useMemo","Children","isValidElement","_a","useState","ListSubheader","OutlinedInput","Typography","Box","item","Chip","Avatar","FormControl","InputLabel","MuiSelect","FormHelperText","Controller"],"mappings":"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"}
|