@m4l/components 9.1.78 β 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/components/Label/Label.styles.js +32 -18
- 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/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/index.d.ts +1 -0
- package/index.js +22 -20
- package/package.json +1 -1
|
@@ -8,8 +8,8 @@ const labelStyles = {
|
|
|
8
8
|
* @returns {object} - Los estilos aplicados al root del Label.
|
|
9
9
|
* @author Bruce Escobar - automatic
|
|
10
10
|
* @createdAt 2024-10-22 09:34:39 - automatic
|
|
11
|
-
* @updatedAt 2025-01-
|
|
12
|
-
* @updatedUser
|
|
11
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
12
|
+
* @updatedUser cesar - automatic
|
|
13
13
|
*/
|
|
14
14
|
root: ({ theme, ownerState }) => ({
|
|
15
15
|
display: "flex",
|
|
@@ -17,6 +17,16 @@ const labelStyles = {
|
|
|
17
17
|
alignItems: "center",
|
|
18
18
|
flexWrap: "wrap",
|
|
19
19
|
width: "fit-content",
|
|
20
|
+
...getHeightSizeStyles(
|
|
21
|
+
theme.generalSettings.isMobile,
|
|
22
|
+
ownerState.size || "small",
|
|
23
|
+
"base",
|
|
24
|
+
(height) => ({
|
|
25
|
+
minHeight: height,
|
|
26
|
+
height: "auto",
|
|
27
|
+
maxHeight: "none"
|
|
28
|
+
})
|
|
29
|
+
),
|
|
20
30
|
gap: theme.size.baseSpacings.sp1,
|
|
21
31
|
/** Estilos para el estado disabled del Label πΆβπ«οΈ */
|
|
22
32
|
...ownerState.disabled && {
|
|
@@ -24,10 +34,11 @@ const labelStyles = {
|
|
|
24
34
|
}
|
|
25
35
|
}),
|
|
26
36
|
/**
|
|
27
|
-
* Estilos para el slot Typography del Label
|
|
28
|
-
* @
|
|
29
|
-
* @
|
|
30
|
-
* @
|
|
37
|
+
* Estilos para el slot Typography del Label.
|
|
38
|
+
* @author cesar - automatic
|
|
39
|
+
* @createdAt 2025-01-20 18:52:54 - automatic
|
|
40
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
41
|
+
* @updatedUser cesar - automatic
|
|
31
42
|
*/
|
|
32
43
|
typographyStyled: ({ theme, ownerState }) => ({
|
|
33
44
|
"&.MuiTypography-root": {
|
|
@@ -50,10 +61,11 @@ const labelStyles = {
|
|
|
50
61
|
}
|
|
51
62
|
}),
|
|
52
63
|
/**
|
|
53
|
-
* Estilos para el slot Typography del mensaje obligatorio del Label
|
|
54
|
-
* @
|
|
55
|
-
* @
|
|
56
|
-
* @
|
|
64
|
+
* Estilos para el slot Typography del mensaje obligatorio del Label.
|
|
65
|
+
* @author cesar - automatic
|
|
66
|
+
* @createdAt 2025-01-20 18:52:54 - automatic
|
|
67
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
68
|
+
* @updatedUser cesar - automatic
|
|
57
69
|
*/
|
|
58
70
|
typographyMandatoryMessageStyled: ({ theme, ownerState }) => ({
|
|
59
71
|
"&.MuiTypography-root": {
|
|
@@ -76,10 +88,11 @@ const labelStyles = {
|
|
|
76
88
|
}
|
|
77
89
|
}),
|
|
78
90
|
/**
|
|
79
|
-
* Estilos para el slot Icon del Label
|
|
80
|
-
* @
|
|
81
|
-
* @
|
|
82
|
-
* @
|
|
91
|
+
* Estilos para el slot Icon del Label.
|
|
92
|
+
* @author cesar - automatic
|
|
93
|
+
* @createdAt 2025-01-20 18:52:54 - automatic
|
|
94
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
95
|
+
* @updatedUser cesar - automatic
|
|
83
96
|
*/
|
|
84
97
|
iconHelperMessageStyled: ({ theme, ownerState }) => ({
|
|
85
98
|
borderRadius: theme.vars.size.borderRadius.r1,
|
|
@@ -101,10 +114,11 @@ const labelStyles = {
|
|
|
101
114
|
)
|
|
102
115
|
}),
|
|
103
116
|
/**
|
|
104
|
-
* Estilos para el slot Skeleton del Label
|
|
105
|
-
* @
|
|
106
|
-
* @
|
|
107
|
-
* @
|
|
117
|
+
* Estilos para el slot Skeleton del Label.
|
|
118
|
+
* @author cesar - automatic
|
|
119
|
+
* @createdAt 2025-01-20 18:52:54 - automatic
|
|
120
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
121
|
+
* @updatedUser cesar - automatic
|
|
108
122
|
*/
|
|
109
123
|
skeletonStyled: ({ ownerState, theme }) => ({
|
|
110
124
|
width: "100%",
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
import { jsx, jsxs } from "react/jsx-runtime";
|
|
2
|
+
import clsx from "clsx";
|
|
3
|
+
import { forwardRef } from "react";
|
|
4
|
+
import { useEnvironment, useModuleSkeleton } from "@m4l/core";
|
|
5
|
+
import { g as getComponentClasses } from "../../utils/getComponentSlotRoot.js";
|
|
6
|
+
import { g as getPropDataTestId } from "../../test/getNameDataTestId.js";
|
|
7
|
+
import { u as useNumberInput } from "./hooks/useNumberInput/useNumberInput.js";
|
|
8
|
+
import { S as SkeletonStyled, R as RootStyled, I as InputStyled, C as ContainButtonsAdornmentStyled, a as ContainerButtonsStyled, b as IncrementButtonStyled, D as DecrementButtonStyled } from "./slots/NumberInputSlots.js";
|
|
9
|
+
import { N as NUMBER_INPUT_KEY_COMPONENT } from "./constants.js";
|
|
10
|
+
import { N as NumberInputSlots } from "./slots/NumberInputEnum.js";
|
|
11
|
+
const NumberInput = forwardRef(function NumberInput2(props, forwardedRef) {
|
|
12
|
+
const {
|
|
13
|
+
className,
|
|
14
|
+
defaultValue,
|
|
15
|
+
value,
|
|
16
|
+
disabled = false,
|
|
17
|
+
endAdornment,
|
|
18
|
+
error,
|
|
19
|
+
id,
|
|
20
|
+
max,
|
|
21
|
+
min,
|
|
22
|
+
onBlur,
|
|
23
|
+
onInputChange,
|
|
24
|
+
onFocus,
|
|
25
|
+
onChange,
|
|
26
|
+
required,
|
|
27
|
+
readOnly = false,
|
|
28
|
+
shiftMultiplier,
|
|
29
|
+
startAdornment,
|
|
30
|
+
step,
|
|
31
|
+
size = "medium",
|
|
32
|
+
variant = "outlined",
|
|
33
|
+
withDecimal = false,
|
|
34
|
+
dataTestId
|
|
35
|
+
} = props;
|
|
36
|
+
const {
|
|
37
|
+
getRootProps,
|
|
38
|
+
getInputProps,
|
|
39
|
+
getIncrementButtonProps,
|
|
40
|
+
getDecrementButtonProps,
|
|
41
|
+
focusError
|
|
42
|
+
} = useNumberInput({
|
|
43
|
+
min,
|
|
44
|
+
max,
|
|
45
|
+
step,
|
|
46
|
+
withDecimal,
|
|
47
|
+
shiftMultiplier,
|
|
48
|
+
defaultValue,
|
|
49
|
+
disabled,
|
|
50
|
+
error,
|
|
51
|
+
onFocus,
|
|
52
|
+
onInputChange,
|
|
53
|
+
onBlur,
|
|
54
|
+
onChange,
|
|
55
|
+
required,
|
|
56
|
+
readOnly,
|
|
57
|
+
value,
|
|
58
|
+
inputId: id,
|
|
59
|
+
componentName: NUMBER_INPUT_KEY_COMPONENT
|
|
60
|
+
});
|
|
61
|
+
const { host_static_assets, environment_assets } = useEnvironment();
|
|
62
|
+
const ownerState = {
|
|
63
|
+
disabled,
|
|
64
|
+
error,
|
|
65
|
+
size,
|
|
66
|
+
variant,
|
|
67
|
+
focusError,
|
|
68
|
+
noButtons: withDecimal
|
|
69
|
+
};
|
|
70
|
+
const isSkeleton = useModuleSkeleton();
|
|
71
|
+
const classes = getComponentClasses(NUMBER_INPUT_KEY_COMPONENT, NumberInputSlots);
|
|
72
|
+
if (isSkeleton) {
|
|
73
|
+
return /* @__PURE__ */ jsx(
|
|
74
|
+
SkeletonStyled,
|
|
75
|
+
{
|
|
76
|
+
ownerState,
|
|
77
|
+
className: clsx(classes.skeleton, className),
|
|
78
|
+
...getPropDataTestId(NUMBER_INPUT_KEY_COMPONENT, NumberInputSlots.skeleton, dataTestId)
|
|
79
|
+
}
|
|
80
|
+
);
|
|
81
|
+
}
|
|
82
|
+
const ICON_INCREMENT = `${host_static_assets}/${environment_assets}/frontend/components/ControlIncrement/assets/icons/chevron_up_sm.svg`;
|
|
83
|
+
const ICON_DECREMENT = `${host_static_assets}/${environment_assets}/frontend/components/ControlIncrement/assets/icons/chevron_down_sm.svg`;
|
|
84
|
+
return /* @__PURE__ */ jsxs(
|
|
85
|
+
RootStyled,
|
|
86
|
+
{
|
|
87
|
+
...getPropDataTestId(NUMBER_INPUT_KEY_COMPONENT, NumberInputSlots.root, dataTestId),
|
|
88
|
+
className: clsx(classes.root, className),
|
|
89
|
+
ref: forwardedRef,
|
|
90
|
+
ownerState,
|
|
91
|
+
...getRootProps(),
|
|
92
|
+
children: [
|
|
93
|
+
startAdornment,
|
|
94
|
+
/* @__PURE__ */ jsx(InputStyled, { className: clsx(classes.input, className), ownerState, ...getInputProps() }),
|
|
95
|
+
/* @__PURE__ */ jsxs(ContainButtonsAdornmentStyled, { ownerState, children: [
|
|
96
|
+
endAdornment,
|
|
97
|
+
!withDecimal && /* @__PURE__ */ jsxs(ContainerButtonsStyled, { className: clsx(classes.containerButtons, className), ownerState, children: [
|
|
98
|
+
/* @__PURE__ */ jsx(
|
|
99
|
+
IncrementButtonStyled,
|
|
100
|
+
{
|
|
101
|
+
icon: ICON_INCREMENT,
|
|
102
|
+
className: clsx(classes.increment, className),
|
|
103
|
+
ownerState,
|
|
104
|
+
...getIncrementButtonProps()
|
|
105
|
+
}
|
|
106
|
+
),
|
|
107
|
+
/* @__PURE__ */ jsx(
|
|
108
|
+
DecrementButtonStyled,
|
|
109
|
+
{
|
|
110
|
+
icon: ICON_DECREMENT,
|
|
111
|
+
className: clsx(classes.decrement, className),
|
|
112
|
+
ownerState,
|
|
113
|
+
...getDecrementButtonProps()
|
|
114
|
+
}
|
|
115
|
+
)
|
|
116
|
+
] })
|
|
117
|
+
] })
|
|
118
|
+
]
|
|
119
|
+
}
|
|
120
|
+
);
|
|
121
|
+
});
|
|
122
|
+
export {
|
|
123
|
+
NumberInput as N
|
|
124
|
+
};
|
|
@@ -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
|
+
};
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
import { styled } from "@mui/material/styles";
|
|
2
|
+
import { S as Skeleton } from "../../mui_extended/Skeleton/Skeleton.js";
|
|
3
|
+
import { n as numberInputStyles } from "../NumberInput.styles.js";
|
|
4
|
+
import { N as NUMBER_INPUT_KEY_COMPONENT } from "../constants.js";
|
|
5
|
+
import { N as NumberInputSlots } from "./NumberInputEnum.js";
|
|
6
|
+
import { I as IconButton } from "../../mui_extended/IconButton/IconButton.js";
|
|
7
|
+
const RootStyled = styled("div", {
|
|
8
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
9
|
+
slot: NumberInputSlots.root
|
|
10
|
+
})(numberInputStyles?.root);
|
|
11
|
+
const InputStyled = styled("input", {
|
|
12
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
13
|
+
slot: NumberInputSlots.input
|
|
14
|
+
})(numberInputStyles?.input);
|
|
15
|
+
const ContainerButtonsStyled = styled("div", {
|
|
16
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
17
|
+
slot: NumberInputSlots.containerButtons
|
|
18
|
+
})(numberInputStyles?.containerButtons);
|
|
19
|
+
const ContainButtonsAdornmentStyled = styled("div", {
|
|
20
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
21
|
+
slot: NumberInputSlots.containButtonsAdornment
|
|
22
|
+
})(numberInputStyles?.ContainButtonsAdornment);
|
|
23
|
+
const IncrementButtonStyled = styled(IconButton, {
|
|
24
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
25
|
+
slot: NumberInputSlots.increment
|
|
26
|
+
})(numberInputStyles?.increment);
|
|
27
|
+
const DecrementButtonStyled = styled(IconButton, {
|
|
28
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
29
|
+
slot: NumberInputSlots.decrement
|
|
30
|
+
})(numberInputStyles?.decrement);
|
|
31
|
+
const SkeletonStyled = styled(Skeleton, {
|
|
32
|
+
name: NUMBER_INPUT_KEY_COMPONENT,
|
|
33
|
+
slot: NumberInputSlots.skeleton
|
|
34
|
+
})(numberInputStyles?.skeleton);
|
|
35
|
+
export {
|
|
36
|
+
ContainButtonsAdornmentStyled as C,
|
|
37
|
+
DecrementButtonStyled as D,
|
|
38
|
+
InputStyled as I,
|
|
39
|
+
RootStyled as R,
|
|
40
|
+
SkeletonStyled as S,
|
|
41
|
+
ContainerButtonsStyled as a,
|
|
42
|
+
IncrementButtonStyled as b
|
|
43
|
+
};
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { clamp } from "@mui/utils";
|
|
2
|
+
function clampStepwise(val, min = Number.MIN_SAFE_INTEGER, max = Number.MAX_SAFE_INTEGER, stepProp = NaN, withDecimal = false) {
|
|
3
|
+
if (Number.isNaN(stepProp)) {
|
|
4
|
+
return clamp(val, min, max);
|
|
5
|
+
}
|
|
6
|
+
if (withDecimal) {
|
|
7
|
+
return clamp(val, min, max);
|
|
8
|
+
}
|
|
9
|
+
const step = stepProp || 1;
|
|
10
|
+
const remainder = val % step;
|
|
11
|
+
const positivity = Math.sign(remainder);
|
|
12
|
+
if (Math.abs(remainder) > step / 2) {
|
|
13
|
+
return clamp(val + positivity * (step - Math.abs(remainder)), min, max);
|
|
14
|
+
}
|
|
15
|
+
return clamp(val - positivity * Math.abs(remainder), min, max);
|
|
16
|
+
}
|
|
17
|
+
function isNumber(val) {
|
|
18
|
+
return typeof val === "number" && !Number.isNaN(val) && Number.isFinite(val);
|
|
19
|
+
}
|
|
20
|
+
export {
|
|
21
|
+
clampStepwise as c,
|
|
22
|
+
isNumber as i
|
|
23
|
+
};
|
|
@@ -3,7 +3,7 @@ import { PropertyValueProps } from './types';
|
|
|
3
3
|
* PropertyValue component is used to display a property and its value in a form or not.
|
|
4
4
|
* @author cesar - automatic
|
|
5
5
|
* @createdAt 2024-12-19 14:44:17 - automatic
|
|
6
|
-
* @updatedAt 2025-01-
|
|
6
|
+
* @updatedAt 2025-01-21 09:09:02 - automatic
|
|
7
7
|
* @updatedUser cesar - automatic
|
|
8
8
|
*/
|
|
9
9
|
export declare function PropertyValue(props: PropertyValueProps): import("react/jsx-runtime").JSX.Element;
|
|
@@ -6,8 +6,8 @@ import { g as getPropDataTestId, a as getNameDataTestId } from "../../test/getNa
|
|
|
6
6
|
import { P as PropertyValueRootStyled, a as PropertyStyled, V as ValueStyled } from "./slots/PropertyValueSlots.js";
|
|
7
7
|
import { a as getComponentSlotRoot } from "../../utils/getComponentSlotRoot.js";
|
|
8
8
|
import { u as useComponentSize } from "../../hooks/useComponentSize/useComponentSize.js";
|
|
9
|
+
import React from "react";
|
|
9
10
|
import { L as Label } from "../Label/Label.js";
|
|
10
|
-
import { T as TextField } from "../mui_extended/TextField/TextField.js";
|
|
11
11
|
import { T as Typography } from "../mui_extended/Typography/Typography.js";
|
|
12
12
|
import { I as Icon } from "../Icon/Icon.js";
|
|
13
13
|
function PropertyValue(props) {
|
|
@@ -47,23 +47,11 @@ function PropertyValue(props) {
|
|
|
47
47
|
return startAdornment;
|
|
48
48
|
};
|
|
49
49
|
const renderValue = () => {
|
|
50
|
-
if (
|
|
51
|
-
|
|
52
|
-
return /* @__PURE__ */ jsx(
|
|
53
|
-
TextField,
|
|
54
|
-
{
|
|
55
|
-
size: normalizedSize,
|
|
56
|
-
defaultValue: value,
|
|
57
|
-
disabled,
|
|
58
|
-
helperText: helperMessage,
|
|
59
|
-
fullWidth: true
|
|
60
|
-
}
|
|
61
|
-
);
|
|
62
|
-
}
|
|
63
|
-
return value;
|
|
50
|
+
if (typeof value === "string" || typeof value === "number") {
|
|
51
|
+
return /* @__PURE__ */ jsx(Typography, { size: normalizedSize, variant: "body", children: value });
|
|
64
52
|
}
|
|
65
|
-
if (
|
|
66
|
-
return
|
|
53
|
+
if (React.isValidElement(value)) {
|
|
54
|
+
return React.cloneElement(value, { size: normalizedSize });
|
|
67
55
|
}
|
|
68
56
|
return value;
|
|
69
57
|
};
|
|
@@ -4,8 +4,8 @@ const propertyValueStyles = {
|
|
|
4
4
|
* Property Value Root Styles
|
|
5
5
|
* @author cesar - automatic
|
|
6
6
|
* @createdAt 2024-12-19 14:44:17 - automatic
|
|
7
|
-
* @updatedAt 2025-01-
|
|
8
|
-
* @updatedUser
|
|
7
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
8
|
+
* @updatedUser cesar - automatic
|
|
9
9
|
*/
|
|
10
10
|
Root: ({ theme, ownerState }) => {
|
|
11
11
|
const createSemanticStyle = (minWidth, maxWidth) => ({
|
|
@@ -67,8 +67,8 @@ const propertyValueStyles = {
|
|
|
67
67
|
* Property Styles
|
|
68
68
|
* @author cesar - automatic
|
|
69
69
|
* @createdAt 2024-12-26 11:44:46 - automatic
|
|
70
|
-
* @updatedAt 2025-01-
|
|
71
|
-
* @updatedUser
|
|
70
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
71
|
+
* @updatedUser cesar - automatic
|
|
72
72
|
*/
|
|
73
73
|
property: ({ theme, ownerState }) => ({
|
|
74
74
|
display: "flex",
|
|
@@ -82,8 +82,8 @@ const propertyValueStyles = {
|
|
|
82
82
|
* Value Styles (Form and No Form Combined)
|
|
83
83
|
* @author cesar - automatic
|
|
84
84
|
* @createdAt 2024-12-26 11:44:46 - automatic
|
|
85
|
-
* @updatedAt 2025-01-
|
|
86
|
-
* @updatedUser
|
|
85
|
+
* @updatedAt 2025-01-20 18:52:54 - automatic
|
|
86
|
+
* @updatedUser cesar - automatic
|
|
87
87
|
*/
|
|
88
88
|
value: ({ theme, ownerState }) => ({
|
|
89
89
|
width: "100%",
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
import { jsx, jsxs, Fragment } from "react/jsx-runtime";
|
|
2
|
+
import { useFormContext, Controller } from "react-hook-form";
|
|
3
|
+
import useId from "@mui/material/utils/useId";
|
|
4
|
+
import { g as getPropDataTestId } from "../../../test/getNameDataTestId.js";
|
|
5
|
+
import { L as Label } from "../../Label/Label.js";
|
|
6
|
+
import { H as HelperError } from "../../HelperError/HelperError.js";
|
|
7
|
+
import { N as NumberInput } from "../../NumberInput/NumberInput.js";
|
|
8
|
+
import { R as RHFNumberInputSlots } from "./slots/RHFNumberInputEnum.js";
|
|
9
|
+
import { R as RHF_NUMBER_INPUT_KEY_COMPONENT } from "./constants.js";
|
|
10
|
+
import { R as RootStyled } from "./slots/RHFNumberInputSlots.js";
|
|
11
|
+
import { u as useComponentSize } from "../../../hooks/useComponentSize/useComponentSize.js";
|
|
12
|
+
const RHFNumberInput = (props) => {
|
|
13
|
+
const {
|
|
14
|
+
name,
|
|
15
|
+
max,
|
|
16
|
+
min,
|
|
17
|
+
step,
|
|
18
|
+
disabled,
|
|
19
|
+
size = "medium",
|
|
20
|
+
variant = "outlined",
|
|
21
|
+
label,
|
|
22
|
+
mandatory,
|
|
23
|
+
mandatoryMessage,
|
|
24
|
+
helperMessage,
|
|
25
|
+
startAdornment,
|
|
26
|
+
endAdornment,
|
|
27
|
+
...others
|
|
28
|
+
} = props;
|
|
29
|
+
const { control } = useFormContext();
|
|
30
|
+
const { currentSize } = useComponentSize(size);
|
|
31
|
+
const ownerState = {
|
|
32
|
+
iconSize: currentSize
|
|
33
|
+
};
|
|
34
|
+
const htmlForId = useId();
|
|
35
|
+
return /* @__PURE__ */ jsx(
|
|
36
|
+
RootStyled,
|
|
37
|
+
{
|
|
38
|
+
ownerState: { ...ownerState },
|
|
39
|
+
...getPropDataTestId(RHF_NUMBER_INPUT_KEY_COMPONENT, RHFNumberInputSlots.root),
|
|
40
|
+
children: /* @__PURE__ */ jsx(
|
|
41
|
+
Controller,
|
|
42
|
+
{
|
|
43
|
+
name,
|
|
44
|
+
control,
|
|
45
|
+
render: ({ field: { value, onChange }, fieldState: { error } }) => {
|
|
46
|
+
const onChangeLocal = (_event, newValue) => {
|
|
47
|
+
onChange(newValue);
|
|
48
|
+
};
|
|
49
|
+
return /* @__PURE__ */ jsxs(Fragment, { children: [
|
|
50
|
+
label && /* @__PURE__ */ jsx(
|
|
51
|
+
Label,
|
|
52
|
+
{
|
|
53
|
+
htmlFor: htmlForId,
|
|
54
|
+
label,
|
|
55
|
+
mandatory,
|
|
56
|
+
mandatoryMessage,
|
|
57
|
+
helperMessage,
|
|
58
|
+
size
|
|
59
|
+
}
|
|
60
|
+
),
|
|
61
|
+
/* @__PURE__ */ jsx(
|
|
62
|
+
NumberInput,
|
|
63
|
+
{
|
|
64
|
+
id: htmlForId,
|
|
65
|
+
size,
|
|
66
|
+
step,
|
|
67
|
+
max,
|
|
68
|
+
min,
|
|
69
|
+
value,
|
|
70
|
+
onChange: onChangeLocal,
|
|
71
|
+
variant,
|
|
72
|
+
disabled,
|
|
73
|
+
startAdornment,
|
|
74
|
+
endAdornment,
|
|
75
|
+
error: !!error,
|
|
76
|
+
...others
|
|
77
|
+
}
|
|
78
|
+
),
|
|
79
|
+
error?.message && /* @__PURE__ */ jsx(HelperError, { htmlFor: htmlForId, size, message: error.message })
|
|
80
|
+
] });
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
)
|
|
84
|
+
}
|
|
85
|
+
);
|
|
86
|
+
};
|
|
87
|
+
export {
|
|
88
|
+
RHFNumberInput as R
|
|
89
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
const rhfNumberInputStyles = {
|
|
2
|
+
/**
|
|
3
|
+
* Estilos para el slot `root`.
|
|
4
|
+
*
|
|
5
|
+
* Se utiliza para aplicar estilos personalizados al contenedor principal
|
|
6
|
+
* del componente `RHFInputNumberSpinner`.
|
|
7
|
+
*/
|
|
8
|
+
root: ({ theme }) => ({
|
|
9
|
+
display: "flex",
|
|
10
|
+
flexDirection: "column",
|
|
11
|
+
gap: theme.vars.size.baseSpacings.sp1
|
|
12
|
+
})
|
|
13
|
+
};
|
|
14
|
+
export {
|
|
15
|
+
rhfNumberInputStyles as r
|
|
16
|
+
};
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { styled } from "@mui/material";
|
|
2
|
+
import { R as RHF_NUMBER_INPUT_KEY_COMPONENT } from "../constants.js";
|
|
3
|
+
import { r as rhfNumberInputStyles } from "../RHFNumberInput.styles.js";
|
|
4
|
+
import { R as RHFNumberInputSlots } from "./RHFNumberInputEnum.js";
|
|
5
|
+
const RootStyled = styled("div", {
|
|
6
|
+
name: RHF_NUMBER_INPUT_KEY_COMPONENT,
|
|
7
|
+
slot: RHFNumberInputSlots.root
|
|
8
|
+
})(rhfNumberInputStyles?.root);
|
|
9
|
+
export {
|
|
10
|
+
RootStyled as R
|
|
11
|
+
};
|
|
@@ -13,4 +13,5 @@ export * from './RHFTextFieldPassword';
|
|
|
13
13
|
export { RHFPeriod } from './RHFPeriod/RHFPeriod';
|
|
14
14
|
export { getPeriodComponetsDictionary } from '../Period/dictionary';
|
|
15
15
|
export { RHFRadioGroup } from './RHFRadioGroup';
|
|
16
|
+
export { RHFNumberInput } from './RHFNumberInput/RHFNumberInput';
|
|
16
17
|
export * from './RHFUpload';
|
package/index.js
CHANGED
|
@@ -36,11 +36,12 @@ import { R as R6 } from "./components/hook-form/RHFHelperError/index.js";
|
|
|
36
36
|
import { R as R7 } from "./components/hook-form/RHFPeriod/RHFPeriod.js";
|
|
37
37
|
import { g as g6 } from "./components/Period/dictionary.js";
|
|
38
38
|
import { R as R8 } from "./components/hook-form/RHFRadioGroup/RHFRadioGroup.js";
|
|
39
|
-
import { R as R9 } from "./components/hook-form/
|
|
40
|
-
import { R as R10 } from "./components/hook-form/
|
|
41
|
-
import { R as R11 } from "./components/hook-form/
|
|
42
|
-
import { R as R12 } from "./components/hook-form/
|
|
43
|
-
import { R as R13 } from "./components/hook-form/
|
|
39
|
+
import { R as R9 } from "./components/hook-form/RHFNumberInput/RHFNumberInput.js";
|
|
40
|
+
import { R as R10 } from "./components/hook-form/RHFColorPicker/RFHColorPicker.js";
|
|
41
|
+
import { R as R11 } from "./components/hook-form/RHFCheckbox/RHFCheckbox.js";
|
|
42
|
+
import { R as R12 } from "./components/hook-form/RHFTextField/RHFTextField.js";
|
|
43
|
+
import { R as R13 } from "./components/hook-form/RHFTextFieldPassword/RHFTextFieldPassword.js";
|
|
44
|
+
import { R as R14 } from "./components/hook-form/RHFUpload/RHFUploadImage/RHFUploadImage.js";
|
|
44
45
|
import { B } from "./components/formatters/BooleanFormatter/BooleanFormatter.js";
|
|
45
46
|
import { D as D2, u as u4 } from "./components/formatters/DateFormatter/DateFormatter.js";
|
|
46
47
|
import { U, g as g7 } from "./components/formatters/UncertaintyFormatter/UncertaintyFormatter.js";
|
|
@@ -73,7 +74,7 @@ import { d, g as g13 } from "./components/CommonActions/dictionary.js";
|
|
|
73
74
|
import { D as D5 } from "./components/DragResizeWindow/DragResizeWindow.js";
|
|
74
75
|
import { d as d2 } from "./components/DragResizeWindow/classes/index.js";
|
|
75
76
|
import { G } from "./components/GridLayout/GridLayout.js";
|
|
76
|
-
import { R as
|
|
77
|
+
import { R as R15 } from "./components/GridLayout/subcomponents/Responsive/index.js";
|
|
77
78
|
import { c as c3, d as d3, e } from "./components/GridLayout/subcomponents/Responsive/responsiveUtils.js";
|
|
78
79
|
import { i, k } from "./components/GridLayout/utils.js";
|
|
79
80
|
import { w } from "./components/GridLayout/subcomponents/withSizeProvider/index.js";
|
|
@@ -127,8 +128,8 @@ import { H as H4 } from "./components/HelmetPage/index.js";
|
|
|
127
128
|
import { P as P11 } from "./components/PropertyValue/PropertyValue.js";
|
|
128
129
|
import { a as a9 } from "./components/MenuActions/dictionary.js";
|
|
129
130
|
import { a as a10, M as M11 } from "./components/MenuActions/MenuActions.js";
|
|
130
|
-
import { R as
|
|
131
|
-
import { R as
|
|
131
|
+
import { R as R16 } from "./components/extended/React-Resizable/Resizable/Resizable.js";
|
|
132
|
+
import { R as R17 } from "./components/extended/React-Resizable/ResizableBox/ResizableBox.js";
|
|
132
133
|
import { S as S3 } from "./components/ScrollBar/index.js";
|
|
133
134
|
import { S as S4 } from "./components/SplitLayout/SplitLayout.js";
|
|
134
135
|
import { T as T3 } from "./components/ToastContainer/ToastContainer.js";
|
|
@@ -182,12 +183,12 @@ import { T as T17 } from "./components/mui_extended/ToggleIconButton/constants.j
|
|
|
182
183
|
import { T as T18 } from "./components/mui_extended/ToggleIconButton/slots/ToggleIconButtonEnum.js";
|
|
183
184
|
import { T as T19 } from "./components/mui_extended/ToggleIconButton/slots/ToggleIconButtonSlots.js";
|
|
184
185
|
import { a as a13, D as D6, M as M13 } from "./components/areas/contexts/DynamicMFParmsContext/index.js";
|
|
185
|
-
import { F, R as
|
|
186
|
+
import { F, R as R18, u as u9 } from "./components/hook-form/RHFormContext/index.js";
|
|
186
187
|
import { g as g26 } from "./components/hook-form/RHFormContext/dictionary.js";
|
|
187
188
|
import { u as u10 } from "./contexts/AppearanceComponentContext/useAppearanceComponentStore.js";
|
|
188
189
|
import { A as A16 } from "./contexts/AppearanceComponentContext/AppearanceComponentContext.js";
|
|
189
190
|
import { a as a14, M as M14 } from "./contexts/ModalContext/index.js";
|
|
190
|
-
import { a as a15, R as
|
|
191
|
+
import { a as a15, R as R19 } from "./contexts/RealTimeContext/RealTimeContext.js";
|
|
191
192
|
import { u as u11 } from "./hooks/useFormAddEdit/index.js";
|
|
192
193
|
import { u as u12 } from "./hooks/useModal/index.js";
|
|
193
194
|
import { u as u13 } from "./hooks/useTab/index.js";
|
|
@@ -310,23 +311,24 @@ export {
|
|
|
310
311
|
P11 as PropertyValue,
|
|
311
312
|
R as RHFAutocomplete,
|
|
312
313
|
R2 as RHFAutocompleteAsync,
|
|
313
|
-
|
|
314
|
-
|
|
314
|
+
R11 as RHFCheckbox,
|
|
315
|
+
R10 as RHFColorPicker,
|
|
315
316
|
R3 as RHFDateTime,
|
|
316
317
|
R6 as RHFHelperError,
|
|
317
318
|
R4 as RHFMultiCheckbox,
|
|
319
|
+
R9 as RHFNumberInput,
|
|
318
320
|
R7 as RHFPeriod,
|
|
319
321
|
R8 as RHFRadioGroup,
|
|
320
322
|
R5 as RHFSelect,
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
323
|
+
R12 as RHFTextField,
|
|
324
|
+
R13 as RHFTextFieldPassword,
|
|
325
|
+
R14 as RHFUploadImage,
|
|
326
|
+
R18 as RHFormProvider,
|
|
325
327
|
a15 as RealTimeContext,
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
328
|
+
R19 as RealTimeProvider,
|
|
329
|
+
R16 as Resizable,
|
|
330
|
+
R17 as ResizableBox,
|
|
331
|
+
R15 as Responsive,
|
|
330
332
|
S3 as ScrollBar,
|
|
331
333
|
S as ScrollToTop,
|
|
332
334
|
S6 as SectionCommercial,
|