@soyfri/shared-library 1.5.0 → 2.0.0-beta.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/components/ActionMenu/ActionMenu.cjs +107 -0
- package/dist/components/ActionMenu/ActionMenu.cjs.map +1 -0
- package/dist/components/ActionMenu/ActionMenu.d.ts +60 -0
- package/dist/components/ActionMenu/ActionMenu.js +107 -0
- package/dist/components/ActionMenu/ActionMenu.js.map +1 -0
- package/dist/components/ActionMenu/index.d.ts +2 -0
- package/dist/components/ActionMenu.d.ts +6 -0
- package/dist/components/AppBar/AppBar.cjs +346 -0
- package/dist/components/AppBar/AppBar.cjs.map +1 -0
- package/dist/components/AppBar/AppBar.d.ts +55 -0
- package/dist/components/AppBar/AppBar.js +346 -0
- package/dist/components/AppBar/AppBar.js.map +1 -0
- package/dist/components/AppBar/AppBar.sx.d.ts +12 -0
- package/dist/components/AppBar/AppBarBrand.d.ts +31 -0
- package/dist/components/AppBar/AppBarContext.d.ts +18 -0
- package/dist/components/AppBar/AppBarMenuToggle.d.ts +39 -0
- package/dist/components/AppBar/AppBarUserMenu.d.ts +65 -0
- package/dist/components/AppBar/index.d.ts +12 -0
- package/dist/components/AppBar.d.ts +6 -0
- package/dist/components/Autocomplete/Autocomplete.cjs +259 -54
- package/dist/components/Autocomplete/Autocomplete.cjs.map +1 -1
- package/dist/components/Autocomplete/Autocomplete.d.ts +64 -9
- package/dist/components/Autocomplete/Autocomplete.definitions.d.ts +6 -0
- package/dist/components/Autocomplete/Autocomplete.helpers.d.ts +18 -0
- package/dist/components/Autocomplete/Autocomplete.js +261 -56
- package/dist/components/Autocomplete/Autocomplete.js.map +1 -1
- package/dist/components/Autocomplete/Autocomplete.sx.d.ts +7 -0
- package/dist/components/Autocomplete/Autocomplete.types.d.ts +1 -0
- package/dist/components/Autocomplete/_parts/AutocompleteChips.d.ts +19 -0
- package/dist/components/Autocomplete/_parts/AutocompleteLoader.d.ts +9 -0
- package/dist/components/Autocomplete/_parts/AutocompleteOption.d.ts +19 -0
- package/dist/components/Autocomplete/index.d.ts +2 -1
- package/dist/components/Autocomplete.d.ts +4 -0
- package/dist/components/Avatar/Avatar.cjs +116 -79
- package/dist/components/Avatar/Avatar.cjs.map +1 -1
- package/dist/components/Avatar/Avatar.d.ts +16 -2
- package/dist/components/Avatar/Avatar.definitions.d.ts +11 -0
- package/dist/components/Avatar/Avatar.js +117 -80
- package/dist/components/Avatar/Avatar.js.map +1 -1
- package/dist/components/Card/Card.cjs +168 -9
- package/dist/components/Card/Card.cjs.map +1 -1
- package/dist/components/Card/Card.d.ts +78 -8
- package/dist/components/Card/Card.js +170 -11
- package/dist/components/Card/Card.js.map +1 -1
- package/dist/components/Card/Card.sx.d.ts +17 -0
- package/dist/components/Card/index.d.ts +4 -1
- package/dist/components/Card.d.ts +4 -0
- package/dist/components/DatePicker/DatePicker.cjs +201 -3
- package/dist/components/DatePicker/DatePicker.cjs.map +1 -1
- package/dist/components/DatePicker/DatePicker.d.ts +47 -9
- package/dist/components/DatePicker/DatePicker.definitions.d.ts +1 -0
- package/dist/components/DatePicker/DatePicker.helpers.d.ts +7 -0
- package/dist/components/DatePicker/DatePicker.js +200 -2
- package/dist/components/DatePicker/DatePicker.js.map +1 -1
- package/dist/components/DatePicker/DatePicker.sx.d.ts +9 -0
- package/dist/components/DatePicker/DatePicker.types.d.ts +1 -0
- package/dist/components/DatePicker/index.d.ts +2 -1
- package/dist/components/DatePicker.d.ts +4 -0
- package/dist/components/DateTimePicker/DateTimePicker.cjs +152 -138
- package/dist/components/DateTimePicker/DateTimePicker.cjs.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.d.ts +46 -9
- package/dist/components/DateTimePicker/DateTimePicker.definitions.d.ts +1 -0
- package/dist/components/DateTimePicker/DateTimePicker.helpers.d.ts +11 -0
- package/dist/components/DateTimePicker/DateTimePicker.js +152 -138
- package/dist/components/DateTimePicker/DateTimePicker.js.map +1 -1
- package/dist/components/DateTimePicker/DateTimePicker.sx.d.ts +7 -0
- package/dist/components/DateTimePicker/DateTimePicker.types.d.ts +1 -0
- package/dist/components/DateTimePicker/index.d.ts +2 -1
- package/dist/components/DateTimePicker.d.ts +4 -0
- package/dist/components/Drawer/Drawer.cjs +271 -0
- package/dist/components/Drawer/Drawer.cjs.map +1 -0
- package/dist/components/Drawer/Drawer.d.ts +51 -0
- package/dist/components/Drawer/Drawer.js +271 -0
- package/dist/components/Drawer/Drawer.js.map +1 -0
- package/dist/components/Drawer/Drawer.sx.d.ts +23 -0
- package/dist/components/Drawer/DrawerContext.d.ts +18 -0
- package/dist/components/Drawer/DrawerItem.d.ts +35 -0
- package/dist/components/Drawer/index.d.ts +6 -0
- package/dist/components/Drawer.d.ts +6 -0
- package/dist/components/Icon/Icon.cjs +44 -3
- package/dist/components/Icon/Icon.cjs.map +1 -1
- package/dist/components/Icon/Icon.d.ts +34 -1
- package/dist/components/Icon/Icon.js +44 -3
- package/dist/components/Icon/Icon.js.map +1 -1
- package/dist/components/Input/Input.cjs +173 -3
- package/dist/components/Input/Input.cjs.map +1 -1
- package/dist/components/Input/Input.d.ts +20 -15
- package/dist/components/Input/Input.definitions.d.ts +5 -2
- package/dist/components/Input/Input.helpers.d.ts +14 -0
- package/dist/components/Input/Input.js +172 -2
- package/dist/components/Input/Input.js.map +1 -1
- package/dist/components/Input/Input.sx.d.ts +8 -0
- package/dist/components/Input/Input.types.d.ts +1 -0
- package/dist/components/Input/index.d.ts +2 -1
- package/dist/components/Input.d.ts +4 -0
- package/dist/components/InputGroup/InputGroup.cjs +104 -91
- package/dist/components/InputGroup/InputGroup.cjs.map +1 -1
- package/dist/components/InputGroup/InputGroup.d.ts +37 -1
- package/dist/components/InputGroup/InputGroup.definitions.d.ts +6 -0
- package/dist/components/InputGroup/InputGroup.js +106 -93
- package/dist/components/InputGroup/InputGroup.js.map +1 -1
- package/dist/components/Modal/Modal.cjs +226 -116
- package/dist/components/Modal/Modal.cjs.map +1 -1
- package/dist/components/Modal/Modal.d.ts +38 -2
- package/dist/components/Modal/Modal.js +227 -117
- package/dist/components/Modal/Modal.js.map +1 -1
- package/dist/components/Modal/ModalFooter.d.ts +9 -1
- package/dist/components/Modal/index.d.ts +5 -0
- package/dist/components/PageLoader/PageLoader.cjs +61 -0
- package/dist/components/PageLoader/PageLoader.cjs.map +1 -0
- package/dist/components/PageLoader/PageLoader.d.ts +38 -0
- package/dist/components/PageLoader/PageLoader.js +61 -0
- package/dist/components/PageLoader/PageLoader.js.map +1 -0
- package/dist/components/PageLoader/index.d.ts +2 -0
- package/dist/components/PageLoader.d.ts +6 -0
- package/dist/components/ScrollTopButton/ScrollTopButton.cjs +79 -0
- package/dist/components/ScrollTopButton/ScrollTopButton.cjs.map +1 -0
- package/dist/components/ScrollTopButton/ScrollTopButton.d.ts +48 -0
- package/dist/components/ScrollTopButton/ScrollTopButton.js +79 -0
- package/dist/components/ScrollTopButton/ScrollTopButton.js.map +1 -0
- package/dist/components/ScrollTopButton/index.d.ts +4 -0
- package/dist/components/ScrollTopButton/scrollToTop.d.ts +29 -0
- package/dist/components/ScrollTopButton.d.ts +6 -0
- package/dist/components/Select/Select.cjs +446 -4
- package/dist/components/Select/Select.cjs.map +1 -1
- package/dist/components/Select/Select.d.ts +33 -13
- package/dist/components/Select/Select.definitions.d.ts +3 -0
- package/dist/components/Select/Select.helpers.d.ts +28 -0
- package/dist/components/Select/Select.js +445 -3
- package/dist/components/Select/Select.js.map +1 -1
- package/dist/components/Select/Select.sx.d.ts +7 -0
- package/dist/components/Select/Select.types.d.ts +1 -0
- package/dist/components/Select/_parts/SelectMenuItem.d.ts +20 -0
- package/dist/components/Select/_parts/SelectSearchHeader.d.ts +15 -0
- package/dist/components/Select/_parts/SelectValue.d.ts +22 -0
- package/dist/components/Select/index.d.ts +2 -1
- package/dist/components/Select.d.ts +4 -0
- package/dist/components/Stat/Stat.cjs +1 -1
- package/dist/components/Stat/Stat.js +1 -1
- package/dist/components/Stepper/Stepper.cjs +4 -1
- package/dist/components/Stepper/Stepper.cjs.map +1 -1
- package/dist/components/Stepper/Stepper.d.ts +5 -0
- package/dist/components/Stepper/Stepper.js +4 -1
- package/dist/components/Stepper/Stepper.js.map +1 -1
- package/dist/components/_shared/formField.sx.d.ts +33 -0
- package/dist/components/_shared/resolvePreset.d.ts +18 -0
- package/dist/formField.sx-CQ1mbk9M.cjs +76 -0
- package/dist/formField.sx-CQ1mbk9M.cjs.map +1 -0
- package/dist/formField.sx-DfVbMe0V.js +77 -0
- package/dist/formField.sx-DfVbMe0V.js.map +1 -0
- package/dist/hooks/Wizard/Wizard.cjs +7 -0
- package/dist/hooks/Wizard/Wizard.cjs.map +1 -0
- package/dist/hooks/Wizard/Wizard.js +7 -0
- package/dist/hooks/Wizard/Wizard.js.map +1 -0
- package/dist/hooks/Wizard/WizardContext.d.ts +67 -0
- package/dist/hooks/Wizard/index.d.ts +3 -0
- package/dist/hooks/Wizard/useWizard.d.ts +9 -0
- package/dist/hooks/Wizard.d.ts +2 -0
- package/dist/index.cjs +99 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.ts +3 -0
- package/dist/index.js +31 -2
- package/dist/index.js.map +1 -1
- package/dist/mui.d.ts +5 -0
- package/dist/resolvePreset-B-IB0ehH.js +15 -0
- package/dist/resolvePreset-B-IB0ehH.js.map +1 -0
- package/dist/resolvePreset-CT3kU-K2.cjs +14 -0
- package/dist/resolvePreset-CT3kU-K2.cjs.map +1 -0
- package/dist/styles.css +3 -112
- package/dist/theme/componentStyles.d.ts +32 -0
- package/dist/theme/tokens.d.ts +28 -0
- package/dist/useWizard-CWdIxZzX.cjs +94 -0
- package/dist/useWizard-CWdIxZzX.cjs.map +1 -0
- package/dist/useWizard-CWq--C3o.js +95 -0
- package/dist/useWizard-CWq--C3o.js.map +1 -0
- package/package.json +1 -1
- package/src/components/ActionMenu/ActionMenu.stories.tsx +230 -0
- package/src/components/ActionMenu/ActionMenu.tsx +174 -0
- package/src/components/ActionMenu/index.ts +2 -0
- package/src/components/AppBar/AppBar.stories.tsx +272 -0
- package/src/components/AppBar/AppBar.sx.ts +32 -0
- package/src/components/AppBar/AppBar.tsx +123 -0
- package/src/components/AppBar/AppBarBrand.tsx +120 -0
- package/src/components/AppBar/AppBarContext.ts +25 -0
- package/src/components/AppBar/AppBarMenuToggle.tsx +90 -0
- package/src/components/AppBar/AppBarUserMenu.tsx +217 -0
- package/src/components/AppBar/index.ts +25 -0
- package/src/components/Autocomplete/Autocomplete.definitions.ts +223 -0
- package/src/components/Autocomplete/Autocomplete.helpers.ts +60 -0
- package/src/components/Autocomplete/Autocomplete.stories.tsx +363 -2
- package/src/components/Autocomplete/Autocomplete.sx.ts +30 -0
- package/src/components/Autocomplete/Autocomplete.tsx +312 -90
- package/src/components/Autocomplete/Autocomplete.types.ts +13 -0
- package/src/components/Autocomplete/_parts/AutocompleteChips.tsx +55 -0
- package/src/components/Autocomplete/_parts/AutocompleteLoader.tsx +17 -0
- package/src/components/Autocomplete/_parts/AutocompleteOption.tsx +31 -0
- package/src/components/Autocomplete/index.ts +12 -1
- package/src/components/Avatar/Avatar.definitions.ts +162 -0
- package/src/components/Avatar/Avatar.stories.tsx +205 -1
- package/src/components/Avatar/Avatar.tsx +166 -103
- package/src/components/Card/Card.stories.tsx +205 -16
- package/src/components/Card/Card.sx.ts +104 -0
- package/src/components/Card/Card.tsx +191 -35
- package/src/components/Card/index.ts +9 -1
- package/src/components/DatePicker/DatePicker.definitions.ts +24 -1
- package/src/components/DatePicker/DatePicker.helpers.ts +24 -0
- package/src/components/DatePicker/DatePicker.stories.tsx +29 -2
- package/src/components/DatePicker/DatePicker.sx.ts +33 -0
- package/src/components/DatePicker/DatePicker.tsx +163 -139
- package/src/components/DatePicker/DatePicker.types.ts +10 -0
- package/src/components/DatePicker/index.ts +9 -1
- package/src/components/DateTimePicker/DateTimePicker.definitions.ts +24 -0
- package/src/components/DateTimePicker/DateTimePicker.helpers.ts +38 -0
- package/src/components/DateTimePicker/DateTimePicker.stories.tsx +29 -1
- package/src/components/DateTimePicker/DateTimePicker.sx.ts +30 -0
- package/src/components/DateTimePicker/DateTimePicker.tsx +200 -166
- package/src/components/DateTimePicker/DateTimePicker.types.ts +10 -0
- package/src/components/DateTimePicker/index.ts +9 -1
- package/src/components/Drawer/Drawer.stories.tsx +270 -0
- package/src/components/Drawer/Drawer.sx.ts +106 -0
- package/src/components/Drawer/Drawer.tsx +214 -0
- package/src/components/Drawer/DrawerContext.ts +26 -0
- package/src/components/Drawer/DrawerItem.tsx +110 -0
- package/src/components/Drawer/index.ts +10 -0
- package/src/components/Flyout/Flyout.stories.tsx +26 -18
- package/src/components/Icon/Icon.stories.tsx +68 -1
- package/src/components/Icon/Icon.tsx +87 -6
- package/src/components/Input/Input.definitions.ts +74 -2
- package/src/components/Input/Input.helpers.ts +49 -0
- package/src/components/Input/Input.stories.tsx +116 -4
- package/src/components/Input/Input.sx.ts +42 -0
- package/src/components/Input/Input.tsx +117 -162
- package/src/components/Input/Input.types.ts +10 -0
- package/src/components/Input/index.ts +9 -1
- package/src/components/InputGroup/InputGroup.definitions.ts +158 -0
- package/src/components/InputGroup/InputGroup.stories.tsx +159 -28
- package/src/components/InputGroup/InputGroup.tsx +159 -116
- package/src/components/Modal/Modal.stories.tsx +434 -6
- package/src/components/Modal/Modal.tsx +303 -121
- package/src/components/Modal/ModalFooter.tsx +22 -12
- package/src/components/Modal/index.ts +6 -1
- package/src/components/PageLoader/PageLoader.stories.tsx +217 -0
- package/src/components/PageLoader/PageLoader.tsx +96 -0
- package/src/components/PageLoader/index.ts +2 -0
- package/src/components/ScrollTopButton/ScrollTopButton.stories.tsx +158 -0
- package/src/components/ScrollTopButton/ScrollTopButton.tsx +135 -0
- package/src/components/ScrollTopButton/index.ts +8 -0
- package/src/components/ScrollTopButton/scrollToTop.ts +37 -0
- package/src/components/Select/Select.definitions.ts +114 -0
- package/src/components/Select/Select.helpers.ts +71 -0
- package/src/components/Select/Select.stories.tsx +126 -8
- package/src/components/Select/Select.sx.ts +14 -0
- package/src/components/Select/Select.tsx +246 -285
- package/src/components/Select/Select.types.ts +15 -0
- package/src/components/Select/_parts/SelectMenuItem.tsx +40 -0
- package/src/components/Select/_parts/SelectSearchHeader.tsx +51 -0
- package/src/components/Select/_parts/SelectValue.tsx +96 -0
- package/src/components/Select/index.ts +14 -1
- package/src/components/Stepper/Stepper.tsx +17 -1
- package/src/components/Tooltip/Tooltip.stories.tsx +15 -3
- package/src/components/_shared/formField.sx.ts +118 -0
- package/src/components/_shared/resolvePreset.ts +35 -0
- package/src/hooks/Wizard/Wizard.stories.tsx +301 -0
- package/src/hooks/Wizard/WizardContext.tsx +166 -0
- package/src/hooks/Wizard/index.ts +6 -0
- package/src/hooks/Wizard/useWizard.ts +13 -0
- package/src/index.ts +17 -1
- package/src/mui.ts +44 -0
- package/src/theme/componentStyles.ts +47 -0
- package/src/theme/tokens.ts +43 -0
- package/dist/DatePicker-BSNboVhN.js +0 -201
- package/dist/DatePicker-BSNboVhN.js.map +0 -1
- package/dist/DatePicker-BoqxWAhj.cjs +0 -200
- package/dist/DatePicker-BoqxWAhj.cjs.map +0 -1
- package/dist/Input-DFHs7cJ_.js +0 -171
- package/dist/Input-DFHs7cJ_.js.map +0 -1
- package/dist/Input-c8MwNNPg.cjs +0 -170
- package/dist/Input-c8MwNNPg.cjs.map +0 -1
- package/dist/Select-BO2N56sm.cjs +0 -411
- package/dist/Select-BO2N56sm.cjs.map +0 -1
- package/dist/Select-BcLkyHSE.js +0 -412
- package/dist/Select-BcLkyHSE.js.map +0 -1
- package/dist/index.css +0 -3
|
@@ -1,25 +1,43 @@
|
|
|
1
|
-
import React, {
|
|
1
|
+
import React, {
|
|
2
|
+
isValidElement,
|
|
3
|
+
useEffect,
|
|
4
|
+
useMemo,
|
|
5
|
+
useRef,
|
|
6
|
+
useState,
|
|
7
|
+
type ReactElement,
|
|
8
|
+
type ReactNode,
|
|
9
|
+
} from 'react';
|
|
2
10
|
import {
|
|
11
|
+
Box,
|
|
12
|
+
CircularProgress,
|
|
3
13
|
FormControl,
|
|
14
|
+
FormHelperText,
|
|
4
15
|
InputLabel,
|
|
16
|
+
ListSubheader,
|
|
5
17
|
MenuItem,
|
|
6
|
-
Select as MuiSelect,
|
|
7
|
-
Chip,
|
|
8
|
-
Avatar,
|
|
9
|
-
Box,
|
|
10
|
-
Typography,
|
|
11
18
|
OutlinedInput,
|
|
12
|
-
|
|
13
|
-
ListSubheader,
|
|
14
|
-
CircularProgress,
|
|
15
|
-
ListItemIcon,
|
|
19
|
+
Select as MuiSelect,
|
|
16
20
|
SelectChangeEvent,
|
|
21
|
+
Typography,
|
|
22
|
+
type SelectProps as MuiSelectProps,
|
|
17
23
|
} from '@mui/material';
|
|
18
|
-
import {
|
|
19
|
-
import
|
|
20
|
-
import CheckIcon from '@mui/icons-material/Check';
|
|
21
|
-
import { Controller, Control, RegisterOptions } from 'react-hook-form';
|
|
24
|
+
import { useTheme } from '@mui/material/styles';
|
|
25
|
+
import { Controller, type Control, type RegisterOptions } from 'react-hook-form';
|
|
22
26
|
|
|
27
|
+
import { buildSelectSx } from './Select.sx';
|
|
28
|
+
import { resolvePreset } from '../_shared/resolvePreset';
|
|
29
|
+
import {
|
|
30
|
+
filterOptionsByLabel,
|
|
31
|
+
groupOptions,
|
|
32
|
+
isGroupedOptionsEmpty,
|
|
33
|
+
isSelectValueEmpty,
|
|
34
|
+
normalizeSelectValue,
|
|
35
|
+
} from './Select.helpers';
|
|
36
|
+
import { SelectSearchHeader } from './_parts/SelectSearchHeader';
|
|
37
|
+
import { SelectValue } from './_parts/SelectValue';
|
|
38
|
+
import { renderSelectMenuItem } from './_parts/SelectMenuItem';
|
|
39
|
+
|
|
40
|
+
// ── Tipos de dominio ─────────────────────────────────────────────────────
|
|
23
41
|
export interface SelectOption {
|
|
24
42
|
value: string | number;
|
|
25
43
|
label: string;
|
|
@@ -29,17 +47,27 @@ export interface SelectOption {
|
|
|
29
47
|
[key: string]: any;
|
|
30
48
|
}
|
|
31
49
|
|
|
32
|
-
type
|
|
33
|
-
type
|
|
50
|
+
export type LabelPosition = 'outside' | 'floating';
|
|
51
|
+
export type ChipVariant = 'outlined' | 'filled';
|
|
52
|
+
export type SelectSize = 'small' | 'medium';
|
|
53
|
+
|
|
54
|
+
// ── Render slots ─────────────────────────────────────────────────────────
|
|
55
|
+
export type RenderOptionItem = (item: SelectOption) => ReactNode;
|
|
56
|
+
export type RenderChipLabel = (item: SelectOption) => ReactNode;
|
|
34
57
|
|
|
35
|
-
//
|
|
58
|
+
// ── Sub-componente declarativo <Option> ──────────────────────────────────
|
|
59
|
+
export interface OptionProps {
|
|
60
|
+
children: RenderOptionItem;
|
|
61
|
+
}
|
|
36
62
|
|
|
37
|
-
// Props
|
|
38
|
-
interface BaseSelectProps<
|
|
63
|
+
// ── Props base ───────────────────────────────────────────────────────────
|
|
64
|
+
export interface BaseSelectProps<
|
|
65
|
+
TValue extends SelectOption['value'] = SelectOption['value'],
|
|
66
|
+
> {
|
|
39
67
|
label?: string;
|
|
40
68
|
options?: SelectOption[];
|
|
41
69
|
defaultValue?: TValue | TValue[];
|
|
42
|
-
size?:
|
|
70
|
+
size?: SelectSize;
|
|
43
71
|
multiple?: boolean;
|
|
44
72
|
filterable?: boolean;
|
|
45
73
|
placeholder?: string;
|
|
@@ -48,18 +76,36 @@ interface BaseSelectProps<TValue extends SelectOption['value'] = SelectOption['v
|
|
|
48
76
|
maxWidth?: number | string;
|
|
49
77
|
maxChipsToShow?: number;
|
|
50
78
|
renderChipLabel?: RenderChipLabel;
|
|
51
|
-
chipVariant?:
|
|
79
|
+
chipVariant?: ChipVariant;
|
|
52
80
|
loadOptions?: (inputValue: string) => Promise<SelectOption[]>;
|
|
53
|
-
loadingMessage?:
|
|
54
|
-
noOptionsMessage?:
|
|
81
|
+
loadingMessage?: ReactNode;
|
|
82
|
+
noOptionsMessage?: ReactNode;
|
|
55
83
|
debounceTimeout?: number;
|
|
56
84
|
disabled?: boolean;
|
|
57
85
|
error?: boolean;
|
|
58
86
|
helperText?: string;
|
|
87
|
+
/** Border radius del input (px o string CSS). Default: 10 */
|
|
88
|
+
borderRadius?: number | string;
|
|
89
|
+
/**
|
|
90
|
+
* Posición del label.
|
|
91
|
+
* - "outside" (default): label arriba del input, sin animación.
|
|
92
|
+
* - "floating": label clásico de MUI (flota dentro del notched outline).
|
|
93
|
+
*/
|
|
94
|
+
labelPosition?: LabelPosition;
|
|
95
|
+
/**
|
|
96
|
+
* Nombre del preset de estilo registrado en `theme.styles.Select`.
|
|
97
|
+
* - `"default"` (o ausente) = estilo built-in del paquete.
|
|
98
|
+
* - Cualquier otro string = mergea el preset encima del estilo built-in.
|
|
99
|
+
*/
|
|
100
|
+
preset?: string;
|
|
101
|
+
sx?: MuiSelectProps['sx'];
|
|
102
|
+
className?: string;
|
|
59
103
|
}
|
|
60
104
|
|
|
61
|
-
//
|
|
62
|
-
interface RHFSelectProps<
|
|
105
|
+
// ── Variantes discriminadas (RHF vs controlado) ──────────────────────────
|
|
106
|
+
export interface RHFSelectProps<
|
|
107
|
+
TValue extends SelectOption['value'] = SelectOption['value'],
|
|
108
|
+
> extends BaseSelectProps<TValue> {
|
|
63
109
|
name: string;
|
|
64
110
|
control: Control<any>;
|
|
65
111
|
validation?: RegisterOptions;
|
|
@@ -67,8 +113,9 @@ interface RHFSelectProps<TValue extends SelectOption['value'] = SelectOption['va
|
|
|
67
113
|
onChange?: (val: TValue | TValue[]) => void;
|
|
68
114
|
}
|
|
69
115
|
|
|
70
|
-
|
|
71
|
-
|
|
116
|
+
export interface StandardSelectProps<
|
|
117
|
+
TValue extends SelectOption['value'] = SelectOption['value'],
|
|
118
|
+
> extends BaseSelectProps<TValue> {
|
|
72
119
|
name?: string;
|
|
73
120
|
control?: never;
|
|
74
121
|
validation?: never;
|
|
@@ -76,98 +123,28 @@ interface StandardSelectProps<TValue extends SelectOption['value'] = SelectOptio
|
|
|
76
123
|
onChange: (val: TValue | TValue[]) => void;
|
|
77
124
|
}
|
|
78
125
|
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
}
|
|
126
|
+
// ── API pública final ────────────────────────────────────────────────────
|
|
127
|
+
export type SelectProps<
|
|
128
|
+
TValue extends SelectOption['value'] = SelectOption['value'],
|
|
129
|
+
> = RHFSelectProps<TValue> | StandardSelectProps<TValue>;
|
|
84
130
|
|
|
131
|
+
// ── Sub-componente declarativo <Option> ──────────────────────────────────
|
|
85
132
|
export function Option(_props: OptionProps) {
|
|
86
133
|
return null;
|
|
87
134
|
}
|
|
88
135
|
Option.displayName = 'Option';
|
|
89
136
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
borderRadius: '10px',
|
|
95
|
-
display: 'flex',
|
|
96
|
-
alignItems: 'center',
|
|
97
|
-
fontSize: '14px',
|
|
98
|
-
},
|
|
99
|
-
'& .MuiSelect-select': {
|
|
100
|
-
padding: '0 !important',
|
|
101
|
-
height: '28px !important',
|
|
102
|
-
display: 'flex',
|
|
103
|
-
alignItems: 'center',
|
|
104
|
-
marginLeft: '8px'
|
|
105
|
-
},
|
|
106
|
-
'& .MuiOutlinedInput-notchedOutline': {
|
|
107
|
-
marginBottom: '-4px !important',
|
|
108
|
-
borderRadius: '10px',
|
|
109
|
-
},
|
|
110
|
-
'& .MuiSelect-icon': {
|
|
111
|
-
top: '50%',
|
|
112
|
-
transform: 'translateY(-50%)',
|
|
113
|
-
},
|
|
114
|
-
'& .MuiOutlinedInput-notchedOutline > legend':{
|
|
115
|
-
display: 'none',
|
|
116
|
-
},
|
|
117
|
-
}));
|
|
118
|
-
|
|
119
|
-
const StyledLabel = styled(InputLabel)(({theme}) =>({
|
|
120
|
-
'&.MuiInputLabel-root': {
|
|
121
|
-
top: '50%',
|
|
122
|
-
transform: 'translate(14px, -50%)',
|
|
123
|
-
},
|
|
124
|
-
'&.MuiInputLabel-shrink': {
|
|
125
|
-
transform: 'translate(1px, -200%) scale(0.75)',
|
|
126
|
-
fontSize: '16px',
|
|
127
|
-
'> legend': {
|
|
128
|
-
display: 'none',
|
|
129
|
-
}
|
|
130
|
-
},
|
|
131
|
-
'&.MuiInputLabel-animated': {
|
|
132
|
-
'&.MuiInputLabel-shrink': {
|
|
133
|
-
display: 'block'
|
|
134
|
-
}
|
|
135
|
-
}
|
|
136
|
-
}));
|
|
137
|
-
|
|
138
|
-
const StyledOutlinedInput = styled(OutlinedInput)(({ theme }) => ({
|
|
139
|
-
'& .MuiInputBase-root': {
|
|
140
|
-
maxHeight: '34px',
|
|
141
|
-
padding: '8px 10px',
|
|
142
|
-
borderRadius: '10px',
|
|
143
|
-
display: 'flex',
|
|
144
|
-
alignItems: 'center',
|
|
145
|
-
fontSize: '14px',
|
|
146
|
-
' & > .MuiAvatar-img': {
|
|
147
|
-
width: '14px',
|
|
148
|
-
height: '14px',
|
|
149
|
-
}
|
|
150
|
-
},
|
|
151
|
-
'& .MuiInputBase-input': {
|
|
152
|
-
padding: '0 !important',
|
|
153
|
-
height: '18px',
|
|
154
|
-
display: 'flex',
|
|
155
|
-
alignItems: 'center',
|
|
156
|
-
},
|
|
157
|
-
'& .MuiOutlinedInput-notchedOutline': {
|
|
158
|
-
border: '0.7px solid',
|
|
159
|
-
borderColor: '#e0e0e0',
|
|
160
|
-
},
|
|
161
|
-
}));
|
|
162
|
-
|
|
163
|
-
export function Select<TValue extends SelectOption['value'] = SelectOption['value']>(props: SelectProps<TValue>) {
|
|
137
|
+
// ── Componente ───────────────────────────────────────────────────────────
|
|
138
|
+
export function Select<TValue extends SelectOption['value'] = SelectOption['value']>(
|
|
139
|
+
props: SelectProps<TValue>,
|
|
140
|
+
) {
|
|
164
141
|
const {
|
|
165
142
|
label,
|
|
166
143
|
options = [],
|
|
167
144
|
value,
|
|
168
145
|
onChange,
|
|
169
146
|
defaultValue,
|
|
170
|
-
size = '
|
|
147
|
+
size = 'small',
|
|
171
148
|
multiple = false,
|
|
172
149
|
filterable = false,
|
|
173
150
|
placeholder,
|
|
@@ -184,11 +161,20 @@ export function Select<TValue extends SelectOption['value'] = SelectOption['valu
|
|
|
184
161
|
disabled = false,
|
|
185
162
|
error = false,
|
|
186
163
|
helperText,
|
|
164
|
+
borderRadius = 10,
|
|
165
|
+
labelPosition = 'outside',
|
|
166
|
+
preset,
|
|
167
|
+
sx,
|
|
168
|
+
className,
|
|
187
169
|
...rest
|
|
188
170
|
} = props;
|
|
189
171
|
|
|
190
|
-
const
|
|
172
|
+
const theme = useTheme();
|
|
173
|
+
const presetSx = resolvePreset('Select', preset, theme);
|
|
174
|
+
|
|
175
|
+
const isRHFMode = 'control' in rest && (rest as any).control !== undefined;
|
|
191
176
|
|
|
177
|
+
// Custom render opcional vía <Option>{item => ...}</Option>
|
|
192
178
|
const customRender: RenderOptionItem | null = useMemo(() => {
|
|
193
179
|
if (React.Children.count(children) === 1) {
|
|
194
180
|
const child = React.Children.only(children);
|
|
@@ -199,153 +185,67 @@ export function Select<TValue extends SelectOption['value'] = SelectOption['valu
|
|
|
199
185
|
return null;
|
|
200
186
|
}, [children]);
|
|
201
187
|
|
|
188
|
+
// Búsqueda / async
|
|
202
189
|
const [search, setSearch] = useState('');
|
|
203
190
|
const [asyncOptions, setAsyncOptions] = useState<SelectOption[]>([]);
|
|
204
191
|
const [loading, setLoading] = useState(false);
|
|
205
192
|
const debounceTimerRef = useRef<number | null>(null);
|
|
206
|
-
|
|
207
193
|
const searchInputRef = useRef<HTMLInputElement>(null);
|
|
208
194
|
|
|
195
|
+
// Focus/open tracking para el comportamiento del label "outside".
|
|
196
|
+
const [isOpen, setIsOpen] = useState(false);
|
|
197
|
+
const [isFocused, setIsFocused] = useState(false);
|
|
198
|
+
|
|
209
199
|
const isAsync = typeof loadOptions === 'function';
|
|
210
200
|
const currentOptions = isAsync ? asyncOptions : options;
|
|
211
201
|
|
|
212
202
|
useEffect(() => {
|
|
213
|
-
if (isAsync)
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
}, debounceTimeout);
|
|
232
|
-
} else {
|
|
233
|
-
setAsyncOptions([]);
|
|
234
|
-
setLoading(false);
|
|
235
|
-
if (searchInputRef.current) {
|
|
236
|
-
searchInputRef.current.focus();
|
|
237
|
-
}
|
|
238
|
-
}
|
|
203
|
+
if (!isAsync) return;
|
|
204
|
+
|
|
205
|
+
if (debounceTimerRef.current) clearTimeout(debounceTimerRef.current);
|
|
206
|
+
|
|
207
|
+
if (search) {
|
|
208
|
+
setLoading(true);
|
|
209
|
+
debounceTimerRef.current = window.setTimeout(() => {
|
|
210
|
+
loadOptions!(search)
|
|
211
|
+
.then(setAsyncOptions)
|
|
212
|
+
.finally(() => {
|
|
213
|
+
setLoading(false);
|
|
214
|
+
searchInputRef.current?.focus();
|
|
215
|
+
});
|
|
216
|
+
}, debounceTimeout);
|
|
217
|
+
} else {
|
|
218
|
+
setAsyncOptions([]);
|
|
219
|
+
setLoading(false);
|
|
220
|
+
searchInputRef.current?.focus();
|
|
239
221
|
}
|
|
240
222
|
}, [search, isAsync, loadOptions, debounceTimeout]);
|
|
241
223
|
|
|
242
224
|
const filteredOptions = useMemo(() => {
|
|
243
|
-
if (isAsync)
|
|
244
|
-
|
|
245
|
-
|
|
246
|
-
if (!filterable || !search) return currentOptions;
|
|
247
|
-
return currentOptions.filter(opt =>
|
|
248
|
-
opt.label.toLowerCase().includes(search.toLowerCase())
|
|
249
|
-
);
|
|
225
|
+
if (isAsync) return currentOptions;
|
|
226
|
+
if (!filterable) return currentOptions;
|
|
227
|
+
return filterOptionsByLabel(currentOptions, search);
|
|
250
228
|
}, [search, filterable, currentOptions, isAsync]);
|
|
251
229
|
|
|
252
|
-
const groupedOptions = useMemo(() =>
|
|
253
|
-
const groups: Record<string, SelectOption[]> = {};
|
|
254
|
-
filteredOptions.forEach(opt => {
|
|
255
|
-
const group = opt.group || '__default';
|
|
256
|
-
if (!groups[group]) groups[group] = [];
|
|
257
|
-
groups[group].push(opt);
|
|
258
|
-
});
|
|
259
|
-
return groups;
|
|
260
|
-
}, [filteredOptions]);
|
|
261
|
-
|
|
262
|
-
const renderValue = (selected: any) => {
|
|
263
|
-
if (!selected || (Array.isArray(selected) && selected.length === 0)) {
|
|
264
|
-
return <Typography sx={{ color: 'text.disabled' }}>{placeholder || ''}</Typography>;
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
if (!multiple) {
|
|
268
|
-
const item = currentOptions.find((opt) => opt.value === selected);
|
|
269
|
-
return renderChipLabel && item ? renderChipLabel(item) : (item?.label ?? String(selected));
|
|
270
|
-
}
|
|
271
|
-
|
|
272
|
-
const selectedValuesArray = selected as TValue[];
|
|
273
|
-
const displayedChips = selectedValuesArray.slice(0, maxChipsToShow);
|
|
274
|
-
const hiddenChipsCount = selectedValuesArray.length - maxChipsToShow;
|
|
275
|
-
|
|
276
|
-
return (
|
|
277
|
-
<Box sx={{ display: 'flex', flexWrap: 'wrap', gap: 0.5 }}>
|
|
278
|
-
{displayedChips.map((val) => {
|
|
279
|
-
const item = currentOptions.find((o) => o.value === val);
|
|
280
|
-
if (!item) return null;
|
|
281
|
-
|
|
282
|
-
const handleDelete = (chipValue: TValue) => {
|
|
283
|
-
const newSelected = (value as TValue[]).filter(v => v !== chipValue);
|
|
284
|
-
(onChange as (val: TValue | TValue[]) => void)?.(newSelected);
|
|
285
|
-
};
|
|
286
|
-
|
|
287
|
-
return (
|
|
288
|
-
<Chip
|
|
289
|
-
variant={chipVariant}
|
|
290
|
-
color="primary"
|
|
291
|
-
key={val}
|
|
292
|
-
label={renderChipLabel ? renderChipLabel(item) : item.label}
|
|
293
|
-
avatar={item.img ?
|
|
294
|
-
<Avatar
|
|
295
|
-
sx={
|
|
296
|
-
{
|
|
297
|
-
'& > .MuiAvatar-root, .MuiChip-avatar': {
|
|
298
|
-
backgroundColor: 'red',
|
|
299
|
-
}
|
|
300
|
-
}
|
|
301
|
-
}
|
|
302
|
-
src={item.img}
|
|
303
|
-
/> : undefined}
|
|
304
|
-
onDelete={() => handleDelete(val)}
|
|
305
|
-
deleteIcon={<ClearIcon sx={{ fontSize: '12px !important' }} />}
|
|
306
|
-
sx={
|
|
307
|
-
{
|
|
308
|
-
height: '27px',
|
|
309
|
-
marginTop: '1px',
|
|
310
|
-
}
|
|
311
|
-
}
|
|
312
|
-
/>
|
|
313
|
-
);
|
|
314
|
-
})}
|
|
315
|
-
{hiddenChipsCount > 0 && (
|
|
316
|
-
<Chip
|
|
317
|
-
sx={{
|
|
318
|
-
height: '27px',
|
|
319
|
-
marginTop: '0px',
|
|
320
|
-
}}
|
|
321
|
-
label={`+${hiddenChipsCount} más`} variant={chipVariant} />
|
|
322
|
-
)}
|
|
323
|
-
</Box>
|
|
324
|
-
);
|
|
325
|
-
};
|
|
230
|
+
const groupedOptions = useMemo(() => groupOptions(filteredOptions), [filteredOptions]);
|
|
326
231
|
|
|
232
|
+
// Items del menu (search header + loading/empty + grupos + opciones)
|
|
327
233
|
const menuItems = useMemo(() => {
|
|
328
234
|
const items: React.ReactNode[] = [];
|
|
329
235
|
|
|
330
236
|
if (filterable || isAsync) {
|
|
331
237
|
items.push(
|
|
332
|
-
<
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
fullWidth
|
|
339
|
-
value={search}
|
|
340
|
-
onChange={(e) => setSearch(e.target.value)}
|
|
341
|
-
inputProps={{ autoFocus: true }}
|
|
342
|
-
onClick={(e) => e.stopPropagation()}
|
|
343
|
-
onKeyDown={(e) => e.stopPropagation()}
|
|
344
|
-
/>
|
|
345
|
-
</ListSubheader>
|
|
238
|
+
<SelectSearchHeader
|
|
239
|
+
key="search-header"
|
|
240
|
+
value={search}
|
|
241
|
+
onChange={setSearch}
|
|
242
|
+
inputRef={searchInputRef}
|
|
243
|
+
/>,
|
|
346
244
|
);
|
|
347
245
|
}
|
|
348
246
|
|
|
247
|
+
const noOptions = isGroupedOptionsEmpty(groupedOptions);
|
|
248
|
+
|
|
349
249
|
if (loading) {
|
|
350
250
|
items.push(
|
|
351
251
|
<MenuItem key="loading-message" disabled>
|
|
@@ -353,46 +253,57 @@ export function Select<TValue extends SelectOption['value'] = SelectOption['valu
|
|
|
353
253
|
<CircularProgress size={20} />
|
|
354
254
|
<Typography>{loadingMessage}</Typography>
|
|
355
255
|
</Box>
|
|
356
|
-
</MenuItem
|
|
256
|
+
</MenuItem>,
|
|
357
257
|
);
|
|
358
|
-
} else if (
|
|
258
|
+
} else if (noOptions) {
|
|
359
259
|
items.push(
|
|
360
260
|
<MenuItem key="no-options-message" disabled>
|
|
361
261
|
<Typography>{noOptionsMessage}</Typography>
|
|
362
|
-
</MenuItem
|
|
262
|
+
</MenuItem>,
|
|
363
263
|
);
|
|
364
264
|
} else {
|
|
365
265
|
Object.entries(groupedOptions).forEach(([group, opts]) => {
|
|
366
266
|
if (group !== '__default') {
|
|
367
267
|
items.push(
|
|
368
|
-
<ListSubheader key={group} disableSticky>
|
|
268
|
+
<ListSubheader key={group} disableSticky>
|
|
269
|
+
{group}
|
|
270
|
+
</ListSubheader>,
|
|
369
271
|
);
|
|
370
272
|
}
|
|
371
273
|
opts.forEach((opt) => {
|
|
372
274
|
const isSelected = multiple
|
|
373
|
-
? (value as TValue[] | undefined)?.includes(opt.value as TValue)
|
|
275
|
+
? (value as TValue[] | undefined)?.includes(opt.value as TValue) ?? false
|
|
374
276
|
: value === opt.value;
|
|
375
277
|
|
|
376
278
|
items.push(
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
</ListItemIcon>
|
|
383
|
-
{customRender ? customRender(opt) : opt.label}
|
|
384
|
-
</MenuItem>
|
|
279
|
+
renderSelectMenuItem({
|
|
280
|
+
option: opt,
|
|
281
|
+
selected: isSelected,
|
|
282
|
+
customRender,
|
|
283
|
+
}),
|
|
385
284
|
);
|
|
386
285
|
});
|
|
387
286
|
});
|
|
388
287
|
}
|
|
389
288
|
return items;
|
|
390
|
-
}, [
|
|
391
|
-
|
|
392
|
-
|
|
289
|
+
}, [
|
|
290
|
+
groupedOptions,
|
|
291
|
+
customRender,
|
|
292
|
+
filterable,
|
|
293
|
+
isAsync,
|
|
294
|
+
search,
|
|
295
|
+
loading,
|
|
296
|
+
loadingMessage,
|
|
297
|
+
noOptionsMessage,
|
|
298
|
+
multiple,
|
|
299
|
+
value,
|
|
300
|
+
]);
|
|
393
301
|
|
|
394
|
-
//
|
|
395
|
-
const handleChangeInternal = (
|
|
302
|
+
// Handler de cambio
|
|
303
|
+
const handleChangeInternal = (
|
|
304
|
+
event: SelectChangeEvent<any>,
|
|
305
|
+
rhfOnChange?: (...event: any[]) => void,
|
|
306
|
+
) => {
|
|
396
307
|
const newValue = event.target.value;
|
|
397
308
|
if (isRHFMode) {
|
|
398
309
|
rhfOnChange?.(newValue);
|
|
@@ -401,68 +312,118 @@ export function Select<TValue extends SelectOption['value'] = SelectOption['valu
|
|
|
401
312
|
}
|
|
402
313
|
};
|
|
403
314
|
|
|
404
|
-
//
|
|
405
|
-
const
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
315
|
+
// Sx mergeado (defaults + consumer)
|
|
316
|
+
const mergedSx = [
|
|
317
|
+
buildSelectSx(borderRadius, labelPosition),
|
|
318
|
+
...(presetSx ? [presetSx] : []),
|
|
319
|
+
...(Array.isArray(sx) ? sx : [sx]),
|
|
320
|
+
];
|
|
321
|
+
|
|
322
|
+
// Render base
|
|
323
|
+
const renderSelect = (
|
|
324
|
+
selectValue: any,
|
|
325
|
+
selectOnChange: any,
|
|
326
|
+
onBlur?: any,
|
|
327
|
+
inputRef?: any,
|
|
328
|
+
rhfError?: boolean,
|
|
329
|
+
rhfHelperText?: string,
|
|
330
|
+
) => {
|
|
331
|
+
const finalError = rhfError ?? error;
|
|
332
|
+
const finalHelperText = rhfHelperText ?? helperText;
|
|
333
|
+
|
|
334
|
+
const inputElement =
|
|
335
|
+
labelPosition === 'floating' ? (
|
|
336
|
+
<OutlinedInput label={label} />
|
|
337
|
+
) : (
|
|
338
|
+
<OutlinedInput />
|
|
339
|
+
);
|
|
340
|
+
|
|
341
|
+
const normalizedValue = normalizeSelectValue(selectValue, multiple);
|
|
342
|
+
const isEmpty = isSelectValueEmpty(normalizedValue, multiple);
|
|
343
|
+
|
|
344
|
+
// Shrink cuando hay valor, foco, o dropdown abierto.
|
|
345
|
+
const shouldShrink = !isEmpty || isFocused || isOpen;
|
|
346
|
+
// Placeholder solo cuando el label ya subió.
|
|
347
|
+
const shouldDisplayPlaceholder = isEmpty && (isFocused || isOpen) && !!placeholder;
|
|
348
|
+
|
|
349
|
+
return (
|
|
350
|
+
<FormControl
|
|
351
|
+
fullWidth
|
|
352
|
+
size={size}
|
|
353
|
+
error={finalError}
|
|
354
|
+
disabled={disabled}
|
|
355
|
+
className={className}
|
|
356
|
+
sx={mergedSx}
|
|
357
|
+
>
|
|
358
|
+
{label && <InputLabel shrink={shouldShrink}>{label}</InputLabel>}
|
|
359
|
+
<MuiSelect
|
|
360
|
+
value={normalizedValue}
|
|
420
361
|
defaultValue={defaultValue}
|
|
421
362
|
multiple={multiple}
|
|
422
363
|
onChange={selectOnChange}
|
|
423
|
-
onBlur={
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
364
|
+
onBlur={(e) => {
|
|
365
|
+
setIsFocused(false);
|
|
366
|
+
onBlur?.(e);
|
|
367
|
+
}}
|
|
368
|
+
onFocus={() => setIsFocused(true)}
|
|
369
|
+
onOpen={() => setIsOpen(true)}
|
|
370
|
+
onClose={() => setIsOpen(false)}
|
|
371
|
+
renderValue={(selected) => (
|
|
372
|
+
<SelectValue<TValue>
|
|
373
|
+
selected={selected as TValue | TValue[]}
|
|
374
|
+
options={currentOptions}
|
|
375
|
+
multiple={multiple}
|
|
376
|
+
placeholder={placeholder}
|
|
377
|
+
maxChipsToShow={maxChipsToShow}
|
|
378
|
+
chipVariant={chipVariant}
|
|
379
|
+
renderChipLabel={renderChipLabel}
|
|
380
|
+
currentValues={(value as TValue[]) ?? []}
|
|
381
|
+
onDeleteChip={(next) =>
|
|
382
|
+
(onChange as (v: TValue | TValue[]) => void)?.(next)
|
|
383
|
+
}
|
|
384
|
+
/>
|
|
385
|
+
)}
|
|
386
|
+
displayEmpty={shouldDisplayPlaceholder}
|
|
387
|
+
input={inputElement}
|
|
427
388
|
disabled={disabled}
|
|
428
389
|
MenuProps={{
|
|
429
390
|
PaperProps: {
|
|
430
|
-
style: {
|
|
431
|
-
maxHeight: maxHeight,
|
|
432
|
-
maxWidth: maxWidth,
|
|
433
|
-
},
|
|
391
|
+
style: { maxHeight, maxWidth },
|
|
434
392
|
},
|
|
435
393
|
}}
|
|
436
394
|
inputRef={inputRef}
|
|
437
|
-
{...rest}
|
|
395
|
+
{...(rest as any)}
|
|
438
396
|
>
|
|
439
397
|
{menuItems}
|
|
440
|
-
</
|
|
441
|
-
{
|
|
442
|
-
</
|
|
443
|
-
|
|
444
|
-
|
|
398
|
+
</MuiSelect>
|
|
399
|
+
{finalHelperText && <FormHelperText>{finalHelperText}</FormHelperText>}
|
|
400
|
+
</FormControl>
|
|
401
|
+
);
|
|
402
|
+
};
|
|
445
403
|
|
|
446
|
-
|
|
404
|
+
// Branch: RHF vs controlado
|
|
405
|
+
if (isRHFMode) {
|
|
447
406
|
const rhfProps = rest as RHFSelectProps<TValue>;
|
|
448
407
|
return (
|
|
449
408
|
<Controller
|
|
450
409
|
name={rhfProps.name}
|
|
451
410
|
control={rhfProps.control}
|
|
452
411
|
rules={rhfProps.validation}
|
|
453
|
-
render={({ field, fieldState: { error } }) =>
|
|
412
|
+
render={({ field, fieldState: { error: fieldError } }) =>
|
|
454
413
|
renderSelect(
|
|
455
414
|
field.value,
|
|
456
415
|
(e: SelectChangeEvent<any>) => handleChangeInternal(e, field.onChange),
|
|
457
416
|
field.onBlur,
|
|
458
|
-
field.ref
|
|
417
|
+
field.ref,
|
|
418
|
+
!!fieldError,
|
|
419
|
+
fieldError?.message,
|
|
459
420
|
)
|
|
460
|
-
|
|
421
|
+
}
|
|
461
422
|
/>
|
|
462
423
|
);
|
|
463
|
-
} else {
|
|
464
|
-
return renderSelect(value, (e: SelectChangeEvent<any>) => handleChangeInternal(e));
|
|
465
424
|
}
|
|
425
|
+
|
|
426
|
+
return renderSelect(value, (e: SelectChangeEvent<any>) => handleChangeInternal(e));
|
|
466
427
|
}
|
|
467
428
|
|
|
468
|
-
export default Select;
|
|
429
|
+
export default Select;
|