@m4l/components 9.1.77 → 9.1.79
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/@types/types.d.ts +11 -2
- package/components/HelperError/HelperError.d.ts +1 -1
- package/components/HelperError/HelperError.js +16 -21
- package/components/HelperError/HelperError.styles.js +25 -15
- package/components/HelperError/constant.d.ts +0 -1
- package/components/HelperError/constant.js +0 -2
- package/components/HelperError/slots/HelperErrorSlots.js +2 -1
- package/components/HelperError/types.d.ts +6 -10
- package/components/Label/Label.js +1 -1
- package/components/Label/Label.styles.js +70 -13
- package/components/Label/types.d.ts +1 -0
- package/components/NumberInput/NumberInput.js +124 -0
- package/components/NumberInput/NumberInput.styles.js +199 -0
- package/components/NumberInput/constants.js +4 -0
- package/components/NumberInput/hooks/useNumberInput/NumberInputActions.js +12 -0
- package/components/NumberInput/hooks/useNumberInput/NumberInputReducer.js +106 -0
- package/components/NumberInput/hooks/useNumberInput/useNumberInput.js +364 -0
- package/components/NumberInput/slots/NumberInputEnum.js +13 -0
- package/components/NumberInput/slots/NumberInputSlots.js +43 -0
- package/components/NumberInput/utils.js +23 -0
- package/components/PropertyValue/PropertyValue.d.ts +1 -1
- package/components/PropertyValue/PropertyValue.js +5 -17
- package/components/PropertyValue/PropertyValue.styles.js +6 -6
- package/components/hook-form/RHFCheckbox/RHFCheckBox.styles.d.ts +2 -0
- package/components/hook-form/RHFCheckbox/RHFCheckBox.styles.js +31 -0
- package/components/hook-form/RHFCheckbox/RHFCheckbox.d.ts +2 -2
- package/components/hook-form/RHFCheckbox/RHFCheckbox.js +57 -67
- package/components/hook-form/RHFCheckbox/constants.d.ts +2 -0
- package/components/hook-form/RHFCheckbox/constants.js +7 -0
- package/components/hook-form/RHFCheckbox/slots/RHFCheckBoxEnum.d.ts +6 -0
- package/components/hook-form/RHFCheckbox/slots/RHFCheckBoxEnum.js +10 -0
- package/components/hook-form/RHFCheckbox/slots/RHFCheckBoxSlots.d.ts +4 -0
- package/components/hook-form/RHFCheckbox/slots/RHFCheckBoxSlots.js +28 -0
- package/components/hook-form/RHFCheckbox/slots/index.d.ts +2 -0
- package/components/hook-form/RHFCheckbox/types.d.ts +33 -5
- package/components/hook-form/RHFNumberInput/RHFNumberInput.js +89 -0
- package/components/hook-form/RHFNumberInput/RHFNumberInput.styles.js +16 -0
- package/components/hook-form/RHFNumberInput/constants.js +4 -0
- package/components/hook-form/RHFNumberInput/slots/RHFNumberInputEnum.js +7 -0
- package/components/hook-form/RHFNumberInput/slots/RHFNumberInputSlots.js +11 -0
- package/components/hook-form/RHFSelect/slots/RHFSlots.d.ts +1 -1
- package/components/hook-form/RHFTextField/slots/RHFTextFieldSlots.d.ts +1 -1
- package/components/hook-form/index.d.ts +1 -0
- package/components/maps/components/Map/subcomponents/Controls/subcomponents/TopLeftTools/subcomponents/PopoverToolButton/subcomponentes/MapSourcesTool/index.js +1 -1
- package/components/mui_extended/CheckBox/CheckBox.d.ts +2 -2
- package/components/mui_extended/CheckBox/CheckBox.js +4 -3
- package/components/mui_extended/CheckBox/CheckBox.styles.js +64 -15
- package/components/mui_extended/CheckBox/types.d.ts +31 -6
- package/index.js +22 -20
- package/package.json +1 -1
- package/components/HelperError/HelperError.stories.d.ts +0 -13
- package/components/hook-form/RHFCheckbox/classes/index.d.ts +0 -12
- package/components/hook-form/RHFCheckbox/classes/index.js +0 -44
- package/components/hook-form/RHFCheckbox/classes/types.d.ts +0 -12
- package/components/hook-form/RHFCheckbox/styles.d.ts +0 -6
- package/components/hook-form/RHFCheckbox/styles.js +0 -24
- package/components/hook-form/RHFCheckbox/test/constants.d.ts +0 -4
- package/components/hook-form/RHFCheckbox/test/constants.js +0 -4
- package/components/hook-form/RHFCheckbox/test/utils.d.ts +0 -2
- package/components/hook-form/RHFCheckbox/test/utils.js +0 -7
|
@@ -0,0 +1,199 @@
|
|
|
1
|
+
import { g as getHeightSizeStyles } from "../../utils/getHeightSizeStyles.js";
|
|
2
|
+
const numberInputStyles = {
|
|
3
|
+
/**
|
|
4
|
+
* Estilos aplicados al contenedor principal (root).
|
|
5
|
+
*/
|
|
6
|
+
root: ({ theme, ownerState }) => ({
|
|
7
|
+
//Estilos generales
|
|
8
|
+
display: "flex",
|
|
9
|
+
alignItems: "center",
|
|
10
|
+
position: "relative",
|
|
11
|
+
height: "auto",
|
|
12
|
+
width: "100%",
|
|
13
|
+
gap: theme.vars.size.baseSpacings.sp1,
|
|
14
|
+
paddingLeft: theme.vars.size.baseSpacings.sp1,
|
|
15
|
+
paddingRight: ownerState.noButtons && theme.vars.size.baseSpacings.sp1,
|
|
16
|
+
boxSizing: "border-box",
|
|
17
|
+
//Variantes (Outlined y Text)
|
|
18
|
+
...ownerState.variant === "outlined" && {
|
|
19
|
+
border: theme.vars.size.borderStroke.container,
|
|
20
|
+
borderColor: ownerState.error ? theme.vars.palette.error.main : theme.vars.palette.border.default,
|
|
21
|
+
borderRadius: theme.vars.size.borderRadius.r1
|
|
22
|
+
},
|
|
23
|
+
...ownerState.variant === "text" && {
|
|
24
|
+
borderBottom: theme.vars.size.borderStroke.container,
|
|
25
|
+
borderColor: ownerState.error ? theme.vars.palette.error.main : theme.vars.palette.border.default,
|
|
26
|
+
borderRadius: theme.vars.size.borderRadius.r1
|
|
27
|
+
},
|
|
28
|
+
// Estados (Pseudo-classes)
|
|
29
|
+
...ownerState.disabled === false && {
|
|
30
|
+
"&:hover": {
|
|
31
|
+
background: ownerState.error ? theme.vars.palette.error.hoverOpacity : theme.vars.palette.primary.hoverOpacity,
|
|
32
|
+
borderColor: ownerState.error ? theme.vars.palette.error.hover : theme.vars.palette.primary.hover,
|
|
33
|
+
"& button": {
|
|
34
|
+
background: ownerState.error ? theme.vars.palette.error.hoverOpacity : theme.vars.palette.primary.hoverOpacity,
|
|
35
|
+
"&:hover": {
|
|
36
|
+
// background: theme.vars.palette?.default.hover,
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"&:focus-within": {
|
|
41
|
+
borderColor: ownerState.error ? theme.vars.palette.error.main : theme.vars.palette.primary.main
|
|
42
|
+
},
|
|
43
|
+
"&:active": {
|
|
44
|
+
background: "transparent",
|
|
45
|
+
borderColor: ownerState.error ? theme.vars.palette.error.active : theme.vars.palette.primary.active
|
|
46
|
+
}
|
|
47
|
+
},
|
|
48
|
+
...getHeightSizeStyles(
|
|
49
|
+
theme.generalSettings.isMobile,
|
|
50
|
+
ownerState.size || "medium",
|
|
51
|
+
"action"
|
|
52
|
+
)
|
|
53
|
+
}),
|
|
54
|
+
/**
|
|
55
|
+
* Estilos aplicados al campo de entrada (input).
|
|
56
|
+
*/
|
|
57
|
+
input: ({ theme, ownerState }) => ({
|
|
58
|
+
//Estilos generales
|
|
59
|
+
background: "transparent",
|
|
60
|
+
border: 0,
|
|
61
|
+
outline: 0,
|
|
62
|
+
color: ownerState.disabled ? theme.vars.palette.text.disabled : theme.vars.palette.text.primary,
|
|
63
|
+
height: "max-content ",
|
|
64
|
+
width: "100%",
|
|
65
|
+
...ownerState.focusError && {
|
|
66
|
+
color: theme.vars.palette.error.main
|
|
67
|
+
}
|
|
68
|
+
}),
|
|
69
|
+
/**
|
|
70
|
+
* Estilos para envoltorio de boton y endAdornment
|
|
71
|
+
*/
|
|
72
|
+
ContainButtonsAdornment: ({ theme }) => ({
|
|
73
|
+
display: "flex",
|
|
74
|
+
flexDirection: "row",
|
|
75
|
+
justifyContent: "center",
|
|
76
|
+
alignContent: "center",
|
|
77
|
+
height: "100%",
|
|
78
|
+
gap: theme.vars.size.baseSpacings.sp2,
|
|
79
|
+
"span": {
|
|
80
|
+
alignSelf: "center"
|
|
81
|
+
}
|
|
82
|
+
}),
|
|
83
|
+
/**
|
|
84
|
+
* Estilos aplicados al div que contiene los botones de incremento/decremento.
|
|
85
|
+
*/
|
|
86
|
+
containerButtons: () => ({
|
|
87
|
+
display: "flex",
|
|
88
|
+
flexDirection: "column",
|
|
89
|
+
height: "100%"
|
|
90
|
+
}),
|
|
91
|
+
/**
|
|
92
|
+
* Estilos de increment
|
|
93
|
+
*/
|
|
94
|
+
increment: ({ theme, ownerState }) => ({
|
|
95
|
+
//Estilos generales
|
|
96
|
+
height: "50%",
|
|
97
|
+
background: theme.vars.palette.default.main,
|
|
98
|
+
borderBottomLeftRadius: 0,
|
|
99
|
+
borderBottomRightRadius: 0,
|
|
100
|
+
borderTopLeftRadius: 0,
|
|
101
|
+
borderTopRightRadius: `calc(${theme.vars.size.borderRadius.r1} - 1px)`,
|
|
102
|
+
outlineOffset: 0,
|
|
103
|
+
//Sizes
|
|
104
|
+
...ownerState.sizes === "medium" && {
|
|
105
|
+
...theme.generalSettings.isMobile ? {
|
|
106
|
+
width: theme.vars.size.mobile.medium.action
|
|
107
|
+
} : {
|
|
108
|
+
width: theme.vars.size.desktop.medium.action
|
|
109
|
+
}
|
|
110
|
+
},
|
|
111
|
+
...ownerState.sizes === "small" && {
|
|
112
|
+
...theme.generalSettings.isMobile ? {
|
|
113
|
+
width: theme.vars.size.mobile.small.action
|
|
114
|
+
} : {
|
|
115
|
+
width: theme.vars.size.desktop.small.action
|
|
116
|
+
}
|
|
117
|
+
},
|
|
118
|
+
//Estados (Pseudo-classes)
|
|
119
|
+
"&:focus-visible": {
|
|
120
|
+
zIndex: 1,
|
|
121
|
+
outline: `1px solid ${theme.vars.palette?.primary.main}`
|
|
122
|
+
},
|
|
123
|
+
"&:active": {
|
|
124
|
+
background: `${theme.vars.palette?.default.active} !important`
|
|
125
|
+
},
|
|
126
|
+
"& div": {
|
|
127
|
+
height: "100%",
|
|
128
|
+
width: "100%",
|
|
129
|
+
"& div": {
|
|
130
|
+
height: "100%",
|
|
131
|
+
width: "50%",
|
|
132
|
+
minHeight: "min-content",
|
|
133
|
+
maskPosition: "center center"
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
}),
|
|
137
|
+
/**
|
|
138
|
+
* Estilos Decrement
|
|
139
|
+
*/
|
|
140
|
+
decrement: ({ theme, ownerState }) => ({
|
|
141
|
+
//Estilos generales
|
|
142
|
+
height: "50%",
|
|
143
|
+
background: theme.vars.palette.default.main,
|
|
144
|
+
borderTopLeftRadius: 0,
|
|
145
|
+
borderTopRightRadius: 0,
|
|
146
|
+
borderBottomLeftRadius: 0,
|
|
147
|
+
borderBottomRightRadius: `calc(${theme.vars.size.borderRadius.r1} - 1px)`,
|
|
148
|
+
outlineOffset: 0,
|
|
149
|
+
//Sizes
|
|
150
|
+
...ownerState.sizes === "medium" && {
|
|
151
|
+
...theme.generalSettings.isMobile ? {
|
|
152
|
+
width: theme.vars.size.mobile.medium.action
|
|
153
|
+
} : {
|
|
154
|
+
width: theme.vars.size.desktop.medium.action
|
|
155
|
+
}
|
|
156
|
+
},
|
|
157
|
+
...ownerState.sizes === "small" && {
|
|
158
|
+
...theme.generalSettings.isMobile ? {
|
|
159
|
+
width: theme.vars.size.mobile.small.action
|
|
160
|
+
} : {
|
|
161
|
+
width: theme.vars.size.desktop.small.action
|
|
162
|
+
}
|
|
163
|
+
},
|
|
164
|
+
// Estados (Pseudo-classes)
|
|
165
|
+
"&:focus-visible": {
|
|
166
|
+
zIndex: 1,
|
|
167
|
+
outline: `1px solid ${theme.vars.palette?.primary.main}`
|
|
168
|
+
},
|
|
169
|
+
"&:active": {
|
|
170
|
+
background: `${theme.vars.palette?.default.active} !important`
|
|
171
|
+
},
|
|
172
|
+
"& div": {
|
|
173
|
+
height: "100%",
|
|
174
|
+
width: "100%",
|
|
175
|
+
"& div": {
|
|
176
|
+
height: "100%",
|
|
177
|
+
width: "50%",
|
|
178
|
+
minHeight: "min-content",
|
|
179
|
+
maskPosition: "center center"
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
}),
|
|
183
|
+
/**
|
|
184
|
+
* Estilos aplicados al skeleton.
|
|
185
|
+
*/
|
|
186
|
+
skeleton: ({ theme, ownerState }) => ({
|
|
187
|
+
"&.M4lclassCssSpecificity": {
|
|
188
|
+
width: "100%",
|
|
189
|
+
...getHeightSizeStyles(
|
|
190
|
+
theme.generalSettings.isMobile,
|
|
191
|
+
ownerState.size || "medium",
|
|
192
|
+
"action"
|
|
193
|
+
)
|
|
194
|
+
}
|
|
195
|
+
})
|
|
196
|
+
};
|
|
197
|
+
export {
|
|
198
|
+
numberInputStyles as n
|
|
199
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
const NumberInputActionTypes = {
|
|
2
|
+
clamp: "numberInput:clamp",
|
|
3
|
+
inputChange: "numberInput:inputChange",
|
|
4
|
+
increment: "numberInput:increment",
|
|
5
|
+
decrement: "numberInput:decrement",
|
|
6
|
+
decrementToMin: "numberInput:decrementToMin",
|
|
7
|
+
incrementToMax: "numberInput:incrementToMax",
|
|
8
|
+
resetInputValue: "numberInput:resetInputValue"
|
|
9
|
+
};
|
|
10
|
+
export {
|
|
11
|
+
NumberInputActionTypes as N
|
|
12
|
+
};
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { c as clampStepwise, i as isNumber } from "../../utils.js";
|
|
2
|
+
import { N as NumberInputActionTypes } from "./NumberInputActions.js";
|
|
3
|
+
function getClampedValues(rawValue, context) {
|
|
4
|
+
const { min, max, step, withDecimal } = context;
|
|
5
|
+
const clampedValue = rawValue === null ? null : clampStepwise(rawValue, min, max, step, withDecimal);
|
|
6
|
+
const newInputValue = clampedValue === null ? "" : String(clampedValue);
|
|
7
|
+
return {
|
|
8
|
+
value: clampedValue,
|
|
9
|
+
inputValue: newInputValue
|
|
10
|
+
};
|
|
11
|
+
}
|
|
12
|
+
function roundToDecimals(value, decimals = 6) {
|
|
13
|
+
const factor = Math.pow(10, decimals);
|
|
14
|
+
return Math.round(value * factor) / factor;
|
|
15
|
+
}
|
|
16
|
+
function stepValue(state, context, direction, multiplier) {
|
|
17
|
+
const { value } = state;
|
|
18
|
+
const { step = 1, min, max } = context;
|
|
19
|
+
if (isNumber(value)) {
|
|
20
|
+
return {
|
|
21
|
+
up: roundToDecimals(value + (step ?? 1) * multiplier),
|
|
22
|
+
down: roundToDecimals(value - (step ?? 1) * multiplier)
|
|
23
|
+
}[direction];
|
|
24
|
+
}
|
|
25
|
+
return {
|
|
26
|
+
up: min ?? 1,
|
|
27
|
+
down: max ?? -1
|
|
28
|
+
}[direction];
|
|
29
|
+
}
|
|
30
|
+
function handleClamp(state, context, inputValue) {
|
|
31
|
+
const { getInputValueAsString } = context;
|
|
32
|
+
const numberValueAsString = getInputValueAsString(inputValue);
|
|
33
|
+
const intermediateValue = numberValueAsString === "" || numberValueAsString === "-" ? null : Number(numberValueAsString);
|
|
34
|
+
const clampedValues = getClampedValues(intermediateValue, context);
|
|
35
|
+
return {
|
|
36
|
+
...state,
|
|
37
|
+
...clampedValues,
|
|
38
|
+
noControlledValue: clampedValues.value
|
|
39
|
+
};
|
|
40
|
+
}
|
|
41
|
+
function handleInputChange(state, context, inputValue) {
|
|
42
|
+
const { getInputValueAsString, min, max, step, withDecimal } = context;
|
|
43
|
+
const numberValueAsString = getInputValueAsString(inputValue);
|
|
44
|
+
if (numberValueAsString.match(withDecimal ? /^-?(?:\d+(\.\d*)?|\.\d+)$/ : /^-?\d+?$/) || numberValueAsString === "" || numberValueAsString === "." || numberValueAsString === "-") {
|
|
45
|
+
const intermediateValue = numberValueAsString === "" || numberValueAsString === "-" || numberValueAsString === "." ? null : Number(numberValueAsString);
|
|
46
|
+
const clampedValue = intermediateValue === null ? null : clampStepwise(intermediateValue, min, max, step, withDecimal);
|
|
47
|
+
const value = intermediateValue !== null && clampedValue === Number(numberValueAsString) ? clampedValue : state.value;
|
|
48
|
+
const ret = {
|
|
49
|
+
...state,
|
|
50
|
+
value,
|
|
51
|
+
inputValue: numberValueAsString,
|
|
52
|
+
noControlledValue: value
|
|
53
|
+
};
|
|
54
|
+
return ret;
|
|
55
|
+
}
|
|
56
|
+
return state;
|
|
57
|
+
}
|
|
58
|
+
function handleStep(state, context, applyMultiplier, direction) {
|
|
59
|
+
const multiplier = applyMultiplier ? context.shiftMultiplier : 1;
|
|
60
|
+
const newValue = stepValue(state, context, direction, multiplier);
|
|
61
|
+
const clampedValues = getClampedValues(newValue, context);
|
|
62
|
+
return {
|
|
63
|
+
...state,
|
|
64
|
+
...clampedValues,
|
|
65
|
+
noControlledValue: clampedValues.value
|
|
66
|
+
};
|
|
67
|
+
}
|
|
68
|
+
function handleToMinOrMax(state, context, to) {
|
|
69
|
+
const newValue = context[to];
|
|
70
|
+
if (!isNumber(newValue)) {
|
|
71
|
+
return state;
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
...state,
|
|
75
|
+
value: newValue,
|
|
76
|
+
inputValue: String(newValue),
|
|
77
|
+
noControlledValue: newValue
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
function numberInputReducer(state, action) {
|
|
81
|
+
const { type, context } = action;
|
|
82
|
+
switch (type) {
|
|
83
|
+
case NumberInputActionTypes.clamp:
|
|
84
|
+
return handleClamp(state, context, action.inputValue);
|
|
85
|
+
case NumberInputActionTypes.inputChange:
|
|
86
|
+
return handleInputChange(state, context, action.inputValue);
|
|
87
|
+
case NumberInputActionTypes.increment:
|
|
88
|
+
return handleStep(state, context, action.applyMultiplier, "up");
|
|
89
|
+
case NumberInputActionTypes.decrement:
|
|
90
|
+
return handleStep(state, context, action.applyMultiplier, "down");
|
|
91
|
+
case NumberInputActionTypes.incrementToMax:
|
|
92
|
+
return handleToMinOrMax(state, context, "max");
|
|
93
|
+
case NumberInputActionTypes.decrementToMin:
|
|
94
|
+
return handleToMinOrMax(state, context, "min");
|
|
95
|
+
case NumberInputActionTypes.resetInputValue:
|
|
96
|
+
return {
|
|
97
|
+
...state,
|
|
98
|
+
inputValue: String(state.value)
|
|
99
|
+
};
|
|
100
|
+
default:
|
|
101
|
+
return state;
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
export {
|
|
105
|
+
numberInputReducer as n
|
|
106
|
+
};
|
|
@@ -0,0 +1,364 @@
|
|
|
1
|
+
import { useRef, useCallback, useState, useMemo, useEffect } from "react";
|
|
2
|
+
import { useFormControlContext, extractEventHandlers } from "@mui/base";
|
|
3
|
+
import { useForkRef } from "@mui/material";
|
|
4
|
+
import useId from "@mui/material/utils/useId";
|
|
5
|
+
import { useControllableReducer } from "@mui/base/utils/useControllableReducer";
|
|
6
|
+
import { i as isNumber } from "../../utils.js";
|
|
7
|
+
import { N as NUMBER_INPUT_KEY_COMPONENT } from "../../constants.js";
|
|
8
|
+
import { N as NumberInputActionTypes } from "./NumberInputActions.js";
|
|
9
|
+
import { n as numberInputReducer } from "./NumberInputReducer.js";
|
|
10
|
+
const STEP_KEYS = ["ArrowUp", "ArrowDown", "PageUp", "PageDown", "Enter"];
|
|
11
|
+
const SUPPORTED_KEYS = [...STEP_KEYS, "Home", "End"];
|
|
12
|
+
function getInputValueAsString(v) {
|
|
13
|
+
return v ? String(v.trim()) : String(v);
|
|
14
|
+
}
|
|
15
|
+
const useNumberInput = (parameters) => {
|
|
16
|
+
const {
|
|
17
|
+
min,
|
|
18
|
+
max,
|
|
19
|
+
step,
|
|
20
|
+
withDecimal,
|
|
21
|
+
shiftMultiplier = 10,
|
|
22
|
+
value: valueProp,
|
|
23
|
+
inputRef: inputRefProp,
|
|
24
|
+
inputId: inputIdProp,
|
|
25
|
+
onChange,
|
|
26
|
+
disabled: disabledProp = false,
|
|
27
|
+
onBlur,
|
|
28
|
+
onFocus,
|
|
29
|
+
onInputChange,
|
|
30
|
+
defaultValue: defaultValueProp,
|
|
31
|
+
componentName = NUMBER_INPUT_KEY_COMPONENT,
|
|
32
|
+
error: errorProp = false,
|
|
33
|
+
required: requiredProp = false,
|
|
34
|
+
readOnly: readOnlyProp = false
|
|
35
|
+
} = parameters;
|
|
36
|
+
const formControlContext = useFormControlContext();
|
|
37
|
+
const { current: isControlled } = useRef(valueProp !== null);
|
|
38
|
+
const handleInputRefWarning = useCallback((instance) => {
|
|
39
|
+
if (process.env.NODE_ENV !== "production") {
|
|
40
|
+
if (instance && instance.nodeName !== "INPUT" && !instance.focus) {
|
|
41
|
+
console.error(
|
|
42
|
+
[
|
|
43
|
+
"MUI: You have provided a `slots.input` to the input component",
|
|
44
|
+
"that does not correctly handle the `ref` prop.",
|
|
45
|
+
"Make sure the `ref` prop is called with a HTMLInputElement."
|
|
46
|
+
].join("\n")
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}, []);
|
|
51
|
+
const inputRef = useRef(null);
|
|
52
|
+
const handleInputRef = useForkRef(inputRef, inputRefProp, handleInputRefWarning);
|
|
53
|
+
const inputId = useId(inputIdProp);
|
|
54
|
+
const [focused, setFocused] = useState(false);
|
|
55
|
+
const handleStateChange = useCallback(
|
|
56
|
+
(event, field, fieldValue, reason) => {
|
|
57
|
+
if (field === "value" && typeof fieldValue !== "string") {
|
|
58
|
+
switch (reason) {
|
|
59
|
+
case "numberInput:inputChange":
|
|
60
|
+
onChange?.(event, fieldValue);
|
|
61
|
+
break;
|
|
62
|
+
case "numberInput:clamp":
|
|
63
|
+
onChange?.(event, fieldValue);
|
|
64
|
+
break;
|
|
65
|
+
case "numberInput:increment":
|
|
66
|
+
case "numberInput:decrement":
|
|
67
|
+
case "numberInput:incrementToMax":
|
|
68
|
+
case "numberInput:decrementToMin":
|
|
69
|
+
onChange?.(event, fieldValue);
|
|
70
|
+
break;
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
},
|
|
74
|
+
[onChange]
|
|
75
|
+
);
|
|
76
|
+
const numberInputActionContext = useMemo(() => {
|
|
77
|
+
return {
|
|
78
|
+
min,
|
|
79
|
+
max,
|
|
80
|
+
step,
|
|
81
|
+
withDecimal,
|
|
82
|
+
shiftMultiplier,
|
|
83
|
+
getInputValueAsString
|
|
84
|
+
};
|
|
85
|
+
}, [min, max, step, withDecimal, shiftMultiplier]);
|
|
86
|
+
const initialValue = valueProp ?? defaultValueProp ?? null;
|
|
87
|
+
const initialState = {
|
|
88
|
+
value: initialValue,
|
|
89
|
+
inputValue: initialValue ? String(initialValue) : "",
|
|
90
|
+
noControlledValue: initialValue
|
|
91
|
+
};
|
|
92
|
+
const controlledState = useMemo(
|
|
93
|
+
() => ({
|
|
94
|
+
value: valueProp
|
|
95
|
+
}),
|
|
96
|
+
[valueProp]
|
|
97
|
+
);
|
|
98
|
+
const [state, dispatch] = useControllableReducer({
|
|
99
|
+
reducer: numberInputReducer,
|
|
100
|
+
controlledProps: controlledState,
|
|
101
|
+
initialState,
|
|
102
|
+
onStateChange: handleStateChange,
|
|
103
|
+
actionContext: useMemo(() => numberInputActionContext, [numberInputActionContext]),
|
|
104
|
+
componentName
|
|
105
|
+
});
|
|
106
|
+
const { value, inputValue, noControlledValue } = state;
|
|
107
|
+
const focusError = focused && inputValue !== "" ? noControlledValue !== Number(inputValue) : false;
|
|
108
|
+
useEffect(() => {
|
|
109
|
+
if (!formControlContext && disabledProp && focused) {
|
|
110
|
+
setFocused(false);
|
|
111
|
+
onBlur?.();
|
|
112
|
+
}
|
|
113
|
+
}, [formControlContext, disabledProp, focused, onBlur]);
|
|
114
|
+
useEffect(() => {
|
|
115
|
+
if (isControlled && isNumber(value)) {
|
|
116
|
+
dispatch({
|
|
117
|
+
type: NumberInputActionTypes.resetInputValue
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}, [value, dispatch, isControlled]);
|
|
121
|
+
const createHandleFocus = (otherHandlers) => (event) => {
|
|
122
|
+
otherHandlers.onFocus?.(event);
|
|
123
|
+
if (event.defaultMuiPrevented || event.defaultPrevented) {
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (formControlContext && formControlContext.onFocus) {
|
|
127
|
+
formControlContext?.onFocus?.();
|
|
128
|
+
}
|
|
129
|
+
setFocused(true);
|
|
130
|
+
};
|
|
131
|
+
const createHandleInputChange = (otherHandlers) => (event) => {
|
|
132
|
+
if (!isControlled && event.target === null) {
|
|
133
|
+
throw (
|
|
134
|
+
/* minify-error */
|
|
135
|
+
new Error(
|
|
136
|
+
"MUI: Expected valid input target. Did you use a custom `slots.input` and forget to forward refs? See https://mui.com/r/input-component-ref-interface for more info."
|
|
137
|
+
)
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
formControlContext?.onChange?.(event);
|
|
141
|
+
otherHandlers.onInputChange?.(event);
|
|
142
|
+
if (event.defaultMuiPrevented || event.defaultPrevented) {
|
|
143
|
+
return;
|
|
144
|
+
}
|
|
145
|
+
dispatch({
|
|
146
|
+
type: NumberInputActionTypes.inputChange,
|
|
147
|
+
event,
|
|
148
|
+
inputValue: event.currentTarget.value
|
|
149
|
+
});
|
|
150
|
+
};
|
|
151
|
+
const createHandleBlur = (otherHandlers) => (event) => {
|
|
152
|
+
formControlContext?.onBlur();
|
|
153
|
+
otherHandlers.onBlur?.(event);
|
|
154
|
+
if (event.defaultMuiPrevented || event.defaultPrevented) {
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
dispatch({
|
|
158
|
+
type: NumberInputActionTypes.clamp,
|
|
159
|
+
event,
|
|
160
|
+
inputValue: event.currentTarget.value
|
|
161
|
+
});
|
|
162
|
+
setFocused(false);
|
|
163
|
+
};
|
|
164
|
+
const createHandleClick = (otherHandlers) => (event) => {
|
|
165
|
+
otherHandlers.onClick?.(event);
|
|
166
|
+
if (event.defaultMuiPrevented || event.defaultPrevented) {
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (inputRef.current && event.currentTarget === event.target) {
|
|
170
|
+
inputRef.current.focus();
|
|
171
|
+
}
|
|
172
|
+
};
|
|
173
|
+
const handleStep = (direction) => (event) => {
|
|
174
|
+
const applyMultiplier = Boolean(event.shiftKey);
|
|
175
|
+
const actionType = {
|
|
176
|
+
up: NumberInputActionTypes.increment,
|
|
177
|
+
down: NumberInputActionTypes.decrement
|
|
178
|
+
}[direction];
|
|
179
|
+
dispatch({
|
|
180
|
+
type: actionType,
|
|
181
|
+
event,
|
|
182
|
+
applyMultiplier
|
|
183
|
+
});
|
|
184
|
+
};
|
|
185
|
+
const createHandleKeyDown = (otherHandlers) => (event) => {
|
|
186
|
+
otherHandlers.onKeyDown?.(event);
|
|
187
|
+
if (event.defaultMuiPrevented || event.defaultPrevented) {
|
|
188
|
+
return;
|
|
189
|
+
}
|
|
190
|
+
if (SUPPORTED_KEYS.includes(event.key)) {
|
|
191
|
+
event.preventDefault();
|
|
192
|
+
}
|
|
193
|
+
switch (event.key) {
|
|
194
|
+
case "ArrowUp":
|
|
195
|
+
dispatch({
|
|
196
|
+
type: NumberInputActionTypes.increment,
|
|
197
|
+
event,
|
|
198
|
+
applyMultiplier: !!event.shiftKey
|
|
199
|
+
});
|
|
200
|
+
break;
|
|
201
|
+
case "ArrowDown":
|
|
202
|
+
dispatch({
|
|
203
|
+
type: NumberInputActionTypes.decrement,
|
|
204
|
+
event,
|
|
205
|
+
applyMultiplier: !!event.shiftKey
|
|
206
|
+
});
|
|
207
|
+
break;
|
|
208
|
+
case "PageUp":
|
|
209
|
+
dispatch({
|
|
210
|
+
type: NumberInputActionTypes.increment,
|
|
211
|
+
event,
|
|
212
|
+
applyMultiplier: true
|
|
213
|
+
});
|
|
214
|
+
break;
|
|
215
|
+
case "PageDown":
|
|
216
|
+
dispatch({
|
|
217
|
+
type: NumberInputActionTypes.decrement,
|
|
218
|
+
event,
|
|
219
|
+
applyMultiplier: true
|
|
220
|
+
});
|
|
221
|
+
break;
|
|
222
|
+
case "Home":
|
|
223
|
+
dispatch({
|
|
224
|
+
type: NumberInputActionTypes.decrementToMin,
|
|
225
|
+
event
|
|
226
|
+
});
|
|
227
|
+
break;
|
|
228
|
+
case "Enter":
|
|
229
|
+
dispatch({
|
|
230
|
+
type: NumberInputActionTypes.clamp,
|
|
231
|
+
event,
|
|
232
|
+
inputValue: event.currentTarget.value
|
|
233
|
+
});
|
|
234
|
+
break;
|
|
235
|
+
case "End":
|
|
236
|
+
dispatch({
|
|
237
|
+
type: NumberInputActionTypes.incrementToMax,
|
|
238
|
+
event
|
|
239
|
+
});
|
|
240
|
+
break;
|
|
241
|
+
}
|
|
242
|
+
};
|
|
243
|
+
const getRootProps = (externalProps = {}) => {
|
|
244
|
+
const propsEventHandlers = extractEventHandlers(parameters, [
|
|
245
|
+
// these are handled by the input slot
|
|
246
|
+
"onBlur",
|
|
247
|
+
"onInputChange",
|
|
248
|
+
"onFocus",
|
|
249
|
+
"onChange"
|
|
250
|
+
]);
|
|
251
|
+
const externalEventHandlers = {
|
|
252
|
+
...propsEventHandlers,
|
|
253
|
+
...extractEventHandlers(externalProps)
|
|
254
|
+
};
|
|
255
|
+
return {
|
|
256
|
+
...externalProps,
|
|
257
|
+
...externalEventHandlers,
|
|
258
|
+
onClick: createHandleClick(externalEventHandlers)
|
|
259
|
+
};
|
|
260
|
+
};
|
|
261
|
+
const getInputProps = (externalProps = {}) => {
|
|
262
|
+
const propsEventHandlers = {
|
|
263
|
+
onBlur,
|
|
264
|
+
onFocus,
|
|
265
|
+
// onChange from normal props is the custom onChange so we ignore it here
|
|
266
|
+
onChange: onInputChange
|
|
267
|
+
};
|
|
268
|
+
const externalEventHandlers = {
|
|
269
|
+
...propsEventHandlers,
|
|
270
|
+
...extractEventHandlers(externalProps, [
|
|
271
|
+
// onClick is handled by the root slot
|
|
272
|
+
"onClick"
|
|
273
|
+
// do not ignore 'onInputChange', we want slotProps.input.onInputChange to enter the DOM and throw
|
|
274
|
+
])
|
|
275
|
+
};
|
|
276
|
+
const mergedEventHandlers = {
|
|
277
|
+
...externalEventHandlers,
|
|
278
|
+
onFocus: createHandleFocus(externalEventHandlers),
|
|
279
|
+
// slotProps.onChange is renamed to onInputChange and passed to createHandleInputChange
|
|
280
|
+
onChange: createHandleInputChange({
|
|
281
|
+
...externalEventHandlers,
|
|
282
|
+
onInputChange: externalEventHandlers.onChange
|
|
283
|
+
}),
|
|
284
|
+
onBlur: createHandleBlur(externalEventHandlers),
|
|
285
|
+
onKeyDown: createHandleKeyDown(externalEventHandlers)
|
|
286
|
+
};
|
|
287
|
+
const displayValue = (focused ? inputValue : value) ?? "";
|
|
288
|
+
delete externalProps.onInputChange;
|
|
289
|
+
return {
|
|
290
|
+
type: "text",
|
|
291
|
+
id: inputId,
|
|
292
|
+
"aria-invalid": errorProp || void 0,
|
|
293
|
+
defaultValue: void 0,
|
|
294
|
+
value: displayValue,
|
|
295
|
+
"aria-valuenow": displayValue,
|
|
296
|
+
"aria-valuetext": String(displayValue),
|
|
297
|
+
"aria-valuemin": min,
|
|
298
|
+
"aria-valuemax": max,
|
|
299
|
+
autoComplete: "off",
|
|
300
|
+
autoCorrect: "off",
|
|
301
|
+
spellCheck: "false",
|
|
302
|
+
required: !!requiredProp,
|
|
303
|
+
readOnly: readOnlyProp,
|
|
304
|
+
"aria-disabled": disabledProp,
|
|
305
|
+
disabled: disabledProp,
|
|
306
|
+
...externalProps,
|
|
307
|
+
ref: handleInputRef,
|
|
308
|
+
...mergedEventHandlers
|
|
309
|
+
};
|
|
310
|
+
};
|
|
311
|
+
const handleStepperButtonMouseDown = (event) => {
|
|
312
|
+
event.preventDefault();
|
|
313
|
+
if (inputRef.current) {
|
|
314
|
+
inputRef.current.focus();
|
|
315
|
+
}
|
|
316
|
+
};
|
|
317
|
+
const stepperButtonCommonProps = {
|
|
318
|
+
"aria-controls": inputId,
|
|
319
|
+
tabIndex: -1
|
|
320
|
+
};
|
|
321
|
+
const isIncrementDisabled = disabledProp || (isNumber(value) ? value >= (max ?? Number.MAX_SAFE_INTEGER) : false);
|
|
322
|
+
const getIncrementButtonProps = (externalProps = {}) => {
|
|
323
|
+
return {
|
|
324
|
+
...externalProps,
|
|
325
|
+
...stepperButtonCommonProps,
|
|
326
|
+
disabled: isIncrementDisabled,
|
|
327
|
+
tabIndex: 0,
|
|
328
|
+
"aria-disabled": isIncrementDisabled,
|
|
329
|
+
onMouseDown: handleStepperButtonMouseDown,
|
|
330
|
+
onClick: handleStep("up")
|
|
331
|
+
};
|
|
332
|
+
};
|
|
333
|
+
const isDecrementDisabled = disabledProp || (isNumber(value) ? value <= (min ?? Number.MIN_SAFE_INTEGER) : false);
|
|
334
|
+
const getDecrementButtonProps = (externalProps = {}) => {
|
|
335
|
+
return {
|
|
336
|
+
...externalProps,
|
|
337
|
+
...stepperButtonCommonProps,
|
|
338
|
+
disabled: isDecrementDisabled,
|
|
339
|
+
tabIndex: 0,
|
|
340
|
+
"aria-disabled": isDecrementDisabled,
|
|
341
|
+
onMouseDown: handleStepperButtonMouseDown,
|
|
342
|
+
onClick: handleStep("down")
|
|
343
|
+
};
|
|
344
|
+
};
|
|
345
|
+
return {
|
|
346
|
+
disabled: disabledProp,
|
|
347
|
+
error: errorProp,
|
|
348
|
+
focused,
|
|
349
|
+
formControlContext,
|
|
350
|
+
getInputProps,
|
|
351
|
+
getIncrementButtonProps,
|
|
352
|
+
getDecrementButtonProps,
|
|
353
|
+
getRootProps,
|
|
354
|
+
required: requiredProp,
|
|
355
|
+
value,
|
|
356
|
+
inputValue,
|
|
357
|
+
isIncrementDisabled,
|
|
358
|
+
isDecrementDisabled,
|
|
359
|
+
focusError
|
|
360
|
+
};
|
|
361
|
+
};
|
|
362
|
+
export {
|
|
363
|
+
useNumberInput as u
|
|
364
|
+
};
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
var NumberInputSlots = /* @__PURE__ */ ((NumberInputSlots2) => {
|
|
2
|
+
NumberInputSlots2["root"] = "root";
|
|
3
|
+
NumberInputSlots2["input"] = "input";
|
|
4
|
+
NumberInputSlots2["containButtonsAdornment"] = "ContainButtonsAdornment";
|
|
5
|
+
NumberInputSlots2["containerButtons"] = "containerButtons";
|
|
6
|
+
NumberInputSlots2["increment"] = "increment";
|
|
7
|
+
NumberInputSlots2["decrement"] = "decrement";
|
|
8
|
+
NumberInputSlots2["skeleton"] = "skeleton";
|
|
9
|
+
return NumberInputSlots2;
|
|
10
|
+
})(NumberInputSlots || {});
|
|
11
|
+
export {
|
|
12
|
+
NumberInputSlots as N
|
|
13
|
+
};
|