@gen-epix/ui-core-form 4.0.2 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/Autocomplete.js +86 -84
- package/dist/_chunks/Autocomplete.js.map +1 -1
- package/dist/_chunks/DatePicker.js +26 -26
- package/dist/_chunks/FileUpload.js +73 -0
- package/dist/_chunks/FileUpload.js.map +1 -0
- package/dist/_chunks/FormUtil.js +4 -1
- package/dist/_chunks/FormUtil.js.map +1 -1
- package/dist/_chunks/RichTextEditor.js +7658 -4335
- package/dist/_chunks/RichTextEditor.js.map +1 -1
- package/dist/_chunks/TransferList.js +59 -59
- package/dist/_chunks/TransferList.js.map +1 -1
- package/dist/components/fields/Autocomplete/Autocomplete.d.ts +6 -3
- package/dist/components/fields/CheckboxGroup/index.js +14 -14
- package/dist/components/fields/DateRangePicker/index.js +39 -39
- package/dist/components/fields/DateRangePicker/index.js.map +1 -1
- package/dist/components/fields/{UploadButton/UploadButton.d.ts → FileUpload/FileUpload.d.ts} +2 -2
- package/dist/components/fields/FileUpload/index.d.ts +1 -0
- package/dist/components/fields/FileUpload/index.js +2 -0
- package/dist/components/fields/NumberField/index.js +29 -29
- package/dist/components/fields/NumberField/index.js.map +1 -1
- package/dist/components/fields/NumberRangeInput/index.js +34 -34
- package/dist/components/fields/RadioGroup/index.js +7 -7
- package/dist/components/fields/Select/index.js +32 -19
- package/dist/components/fields/Select/index.js.map +1 -1
- package/dist/components/fields/Switch/Switch.d.ts +3 -2
- package/dist/components/fields/Switch/index.js +50 -40
- package/dist/components/fields/Switch/index.js.map +1 -1
- package/dist/components/fields/TextField/index.js +19 -19
- package/dist/components/fields/ToggleButtonGroup/index.js +7 -7
- package/dist/components/helpers/GenericForm/GenericForm.d.ts +1 -1
- package/dist/components/helpers/GenericForm/index.js +42 -32
- package/dist/components/helpers/GenericForm/index.js.map +1 -1
- package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js +5 -4
- package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js.map +1 -1
- package/dist/models/form.d.ts +31 -19
- package/dist/models/form.js.map +1 -1
- package/package.json +84 -81
- package/dist/_chunks/UploadButton.js +0 -91
- package/dist/_chunks/UploadButton.js.map +0 -1
- package/dist/_chunks/index.esm.js +0 -398
- package/dist/_chunks/index.esm.js.map +0 -1
- package/dist/components/fields/UploadButton/index.d.ts +0 -1
- package/dist/components/fields/UploadButton/index.js +0 -2
package/dist/components/fields/{UploadButton/UploadButton.d.ts → FileUpload/FileUpload.d.ts}
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { ReactElement } from 'react';
|
|
2
2
|
import { FieldValues, Path } from 'react-hook-form';
|
|
3
|
-
export type
|
|
3
|
+
export type FileUploadProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {
|
|
4
4
|
readonly accept: string;
|
|
5
5
|
readonly disabled?: boolean;
|
|
6
6
|
readonly infoMessage?: string;
|
|
@@ -12,4 +12,4 @@ export type UploadButtonProps<TFieldValues extends FieldValues, TName extends Pa
|
|
|
12
12
|
readonly required?: boolean;
|
|
13
13
|
readonly warningMessage?: string;
|
|
14
14
|
};
|
|
15
|
-
export declare const
|
|
15
|
+
export declare const FileUpload: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({ accept, disabled, infoMessage, label, multiple, name, onChange: onChangeProp, required, warningMessage, }: FileUploadProps<TFieldValues, TName>) => ReactElement;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export * from './FileUpload';
|
|
@@ -1,25 +1,25 @@
|
|
|
1
1
|
import { n as e } from "../../../_chunks/rolldown-runtime.js";
|
|
2
2
|
import { t } from "../../../_chunks/FormUtil.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { useTranslation as
|
|
9
|
-
import { Box as
|
|
10
|
-
import
|
|
3
|
+
import { FormFieldHelperText as n } from "../../helpers/FormFieldHelperText/index.js";
|
|
4
|
+
import { FormFieldLoadingIndicator as r } from "../../helpers/FormFieldLoadingIndicator/index.js";
|
|
5
|
+
import { t as i } from "../../../_chunks/classnames.js";
|
|
6
|
+
import { useCallback as a, useEffect as ee, useMemo as o, useRef as s, useState as c } from "react";
|
|
7
|
+
import { useFormContext as l } from "react-hook-form";
|
|
8
|
+
import { useTranslation as u } from "react-i18next";
|
|
9
|
+
import { Box as d, FormControl as te, FormHelperText as ne, IconButton as f, InputAdornment as p, Slider as m, TextField as re } from "@mui/material";
|
|
10
|
+
import ie from "@mui/icons-material/Clear";
|
|
11
11
|
import { jsx as h, jsxs as g } from "react/jsx-runtime";
|
|
12
12
|
import { TestIdUtil as _ } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
13
13
|
import { NumberUtil as v } from "@gen-epix/ui-core/utils/NumberUtil";
|
|
14
14
|
//#region src/components/fields/NumberField/NumberField.tsx
|
|
15
|
-
var y = /* @__PURE__ */ e(
|
|
16
|
-
let { t: j } =
|
|
15
|
+
var y = /* @__PURE__ */ e(i(), 1), ae = 250, b = ({ autocomplete: e, disabled: i = !1, label: b, loading: x = !1, max: S, min: C, name: w, onChange: T, placeholder: E, required: D = !1, showSlider: O = !1, step: k, warningMessage: A }) => {
|
|
16
|
+
let { t: j } = u(), { formState: { errors: M }, register: N, subscribe: P } = l(), F = t.getFieldErrorMessage(M, w), I = !!F, L = !!A && !I, R = s(null), [z, B] = c(null), [V, H] = c(null), U = s(null), [W, G] = c(!1), K = a((e) => {
|
|
17
17
|
if (R.current) {
|
|
18
18
|
let t = (e ?? "").toString().replace(".", ",");
|
|
19
19
|
R.current.value = t, G(!!t);
|
|
20
20
|
}
|
|
21
21
|
}, []);
|
|
22
|
-
|
|
22
|
+
ee(() => {
|
|
23
23
|
let e = P({
|
|
24
24
|
callback: ({ name: e, values: t }) => {
|
|
25
25
|
e === w && (B(t[w]), H(t[w]), K(t[w]));
|
|
@@ -35,12 +35,12 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
35
35
|
P,
|
|
36
36
|
K
|
|
37
37
|
]);
|
|
38
|
-
let q =
|
|
38
|
+
let q = o(() => N(w), [w, N]), J = o(() => !(!O || !isFinite(C) || !isFinite(S) || !isFinite(k) || C >= S || (S - C) / k > ae), [
|
|
39
39
|
O,
|
|
40
40
|
C,
|
|
41
41
|
S,
|
|
42
42
|
k
|
|
43
|
-
]), Y =
|
|
43
|
+
]), Y = a(async (e) => {
|
|
44
44
|
let t;
|
|
45
45
|
t = isNaN(e) ? null : e, K(t), t !== V && (await q.onChange({ target: {
|
|
46
46
|
name: w,
|
|
@@ -52,9 +52,9 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
52
52
|
T,
|
|
53
53
|
q,
|
|
54
54
|
K
|
|
55
|
-
]), X =
|
|
55
|
+
]), X = a(async () => {
|
|
56
56
|
await Y(null);
|
|
57
|
-
}, [Y]), Z =
|
|
57
|
+
}, [Y]), Z = a(async () => {
|
|
58
58
|
let e = v.parse(R.current.value);
|
|
59
59
|
await Y(e), await q.onBlur({
|
|
60
60
|
target: {
|
|
@@ -67,7 +67,7 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
67
67
|
Y,
|
|
68
68
|
w,
|
|
69
69
|
q
|
|
70
|
-
]), oe =
|
|
70
|
+
]), oe = a(async () => {
|
|
71
71
|
let e = v.parse(R.current.value);
|
|
72
72
|
await Y(e), await q.onBlur({
|
|
73
73
|
target: {
|
|
@@ -80,14 +80,14 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
80
80
|
Y,
|
|
81
81
|
w,
|
|
82
82
|
q
|
|
83
|
-
]), se =
|
|
83
|
+
]), se = a((e, t) => {
|
|
84
84
|
let n = Array.isArray(t) ? t[0] : t;
|
|
85
85
|
K(n), B(n);
|
|
86
86
|
}, [K]), Q = v.parse(z);
|
|
87
87
|
isNaN(Q) ? Q = null : Q < C ? Q = C : Q > S && (Q = S);
|
|
88
|
-
let $ =
|
|
88
|
+
let $ = o(() => /* @__PURE__ */ h(re, {
|
|
89
89
|
defaultValue: z ?? "",
|
|
90
|
-
disabled:
|
|
90
|
+
disabled: i || x,
|
|
91
91
|
error: I,
|
|
92
92
|
inputRef: R,
|
|
93
93
|
label: b,
|
|
@@ -97,29 +97,29 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
97
97
|
formHelperText: { className: (0, y.default)({ "Mui-warning": L }) },
|
|
98
98
|
input: {
|
|
99
99
|
className: (0, y.default)({ "Mui-warning": L }),
|
|
100
|
-
endAdornment:
|
|
100
|
+
endAdornment: i ? void 0 : /* @__PURE__ */ h(p, {
|
|
101
101
|
position: "end",
|
|
102
|
-
children: /* @__PURE__ */ h(
|
|
102
|
+
children: /* @__PURE__ */ h(f, {
|
|
103
103
|
..._.createAttributes("TextField-reset"),
|
|
104
104
|
"aria-label": j`Clear text field`,
|
|
105
105
|
onClick: X,
|
|
106
106
|
sx: { "& svg": { fontSize: "16px" } },
|
|
107
107
|
tabIndex: -1,
|
|
108
|
-
children: /* @__PURE__ */ h(
|
|
108
|
+
children: /* @__PURE__ */ h(ie, {})
|
|
109
109
|
})
|
|
110
110
|
}),
|
|
111
111
|
inputProps: { autoComplete: e ?? w }
|
|
112
112
|
},
|
|
113
113
|
inputLabel: {
|
|
114
114
|
className: (0, y.default)({ "Mui-warning": L }),
|
|
115
|
-
required: D && !
|
|
115
|
+
required: D && !i,
|
|
116
116
|
shrink: W
|
|
117
117
|
}
|
|
118
118
|
},
|
|
119
119
|
variant: "outlined"
|
|
120
120
|
}), [
|
|
121
121
|
e,
|
|
122
|
-
|
|
122
|
+
i,
|
|
123
123
|
I,
|
|
124
124
|
W,
|
|
125
125
|
L,
|
|
@@ -133,7 +133,7 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
133
133
|
D,
|
|
134
134
|
j
|
|
135
135
|
]);
|
|
136
|
-
return /* @__PURE__ */ g(
|
|
136
|
+
return /* @__PURE__ */ g(te, {
|
|
137
137
|
..._.createAttributes("NumberField", {
|
|
138
138
|
label: b,
|
|
139
139
|
name: w
|
|
@@ -146,14 +146,14 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
146
146
|
},
|
|
147
147
|
children: [
|
|
148
148
|
!J && $,
|
|
149
|
-
J && /* @__PURE__ */ g(
|
|
149
|
+
J && /* @__PURE__ */ g(d, {
|
|
150
150
|
sx: {
|
|
151
151
|
alignItems: "center",
|
|
152
152
|
display: "grid",
|
|
153
153
|
gap: 2,
|
|
154
154
|
gridTemplateColumns: (e) => `${e.spacing(24)} auto`
|
|
155
155
|
},
|
|
156
|
-
children: [$, /* @__PURE__ */ h(
|
|
156
|
+
children: [$, /* @__PURE__ */ h(m, {
|
|
157
157
|
color: "primary",
|
|
158
158
|
marks: !0,
|
|
159
159
|
max: S,
|
|
@@ -166,8 +166,8 @@ var y = /* @__PURE__ */ e(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a
|
|
|
166
166
|
valueLabelDisplay: "auto"
|
|
167
167
|
})]
|
|
168
168
|
}),
|
|
169
|
-
!!x && /* @__PURE__ */ h(
|
|
170
|
-
/* @__PURE__ */ h(
|
|
169
|
+
!!x && /* @__PURE__ */ h(r, {}),
|
|
170
|
+
/* @__PURE__ */ h(ne, { children: /* @__PURE__ */ h(n, {
|
|
171
171
|
errorMessage: F,
|
|
172
172
|
warningMessage: A
|
|
173
173
|
}) })
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/fields/NumberField/NumberField.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n Box,\n FormControl,\n FormHelperText,\n IconButton,\n InputAdornment,\n TextField as MuiTextField,\n Slider,\n} from '@mui/material';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport type {\n FieldValues,\n Path,\n} from 'react-hook-form';\nimport { useFormContext } from 'react-hook-form';\nimport classnames from 'classnames';\nimport { useTranslation } from 'react-i18next';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\nimport { NumberUtil } from '@gen-epix/ui-core/utils/NumberUtil';\n\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nexport type NumberFieldProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {\n readonly autocomplete?: string;\n readonly disabled?: boolean;\n readonly infoMessage?: string;\n readonly label: string;\n readonly loading?: boolean;\n readonly max?: number;\n readonly min?: number;\n readonly name: TName;\n readonly onChange?: (value: number) => void;\n readonly placeholder?: string;\n readonly required?: boolean;\n readonly showSlider?: boolean;\n readonly step?: number;\n readonly warningMessage?: string;\n};\n\nconst MAX_NUMBER_OF_SLIDER_STEPS = 250;\n\nexport const NumberField = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({\n autocomplete,\n disabled = false,\n label,\n loading = false,\n max,\n min,\n name,\n onChange: onChangeProp,\n placeholder,\n required = false,\n showSlider = false,\n step,\n warningMessage,\n}: NumberFieldProps<TFieldValues, TName>): ReactElement => {\n const { t } = useTranslation();\n const { formState: { errors }, register, subscribe } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const hasError = !!errorMessage;\n const hasWarning = !!warningMessage && !hasError;\n const inputRef = useRef<HTMLInputElement>(null);\n const [internalValue, setInternalValue] = useState<number>(null);\n const [externalValue, setExternalValue] = useState<number>(null);\n const formControlRef = useRef<HTMLDivElement>(null);\n const [hasInputValue, setHasInputValue] = useState(false);\n\n const updateInputValue = useCallback((value: number) => {\n if (inputRef.current) {\n const inputValue = (value ?? '').toString().replace('.', ',');\n inputRef.current.value = inputValue;\n setHasInputValue(!!inputValue);\n }\n }, []);\n\n useEffect(() => {\n const unsubscribe = subscribe({\n callback: ({ name: changedName, values }) => {\n if (changedName !== name) {\n return;\n }\n setInternalValue(values[name]);\n setExternalValue(values[name]);\n updateInputValue(values[name]);\n },\n formState: {\n values: true,\n },\n name,\n });\n return () => {\n unsubscribe();\n };\n }, [name, subscribe, updateInputValue]);\n\n const registration = useMemo(() => register(name), [name, register]);\n\n const shouldShowSlider = useMemo(() => {\n if (!showSlider) {\n return false;\n }\n if (!isFinite(min) || !isFinite(max) || !isFinite(step) || min >= max) {\n return false;\n }\n if ((max - min) / step > MAX_NUMBER_OF_SLIDER_STEPS) {\n return false;\n }\n return true;\n }, [showSlider, min, max, step]);\n\n const emitValue = useCallback(async (parsedValue: number) => {\n let newValue: number;\n\n if (isNaN(parsedValue)) {\n newValue = null;\n } else {\n newValue = parsedValue;\n }\n\n updateInputValue(newValue);\n\n if (newValue !== externalValue) {\n await registration.onChange({\n target: {\n name,\n value: newValue,\n },\n });\n if (onChangeProp) {\n onChangeProp(newValue);\n }\n }\n }, [externalValue, name, onChangeProp, registration, updateInputValue]);\n\n const onResetButtonClick = useCallback(async () => {\n await emitValue(null);\n }, [emitValue]);\n\n\n const onMuiTextFieldBlur = useCallback(async () => {\n const parsedValue = NumberUtil.parse(inputRef.current.value);\n\n await emitValue(parsedValue);\n await registration.onBlur({\n target: {\n name,\n value: parsedValue,\n },\n type: 'blur',\n });\n }, [emitValue, name, registration]);\n\n const onMuiSliderBlur = useCallback(async () => {\n const parsedValue = NumberUtil.parse(inputRef.current.value);\n\n await emitValue(parsedValue);\n await registration.onBlur({\n target: {\n name,\n value: parsedValue,\n },\n type: 'blur',\n });\n }, [emitValue, name, registration]);\n\n const onMuiRangeSliderChange = useCallback((_event: unknown, sliderValue: number | number[]) => {\n const value = Array.isArray(sliderValue) ? sliderValue[0] : sliderValue;\n updateInputValue(value);\n setInternalValue(value);\n }, [updateInputValue]);\n\n let sliderValue = NumberUtil.parse(internalValue);\n if (isNaN(sliderValue)) {\n sliderValue = null;\n } else if (sliderValue < min) {\n sliderValue = min;\n } else if (sliderValue > max) {\n sliderValue = max;\n }\n\n const textField = useMemo(() => (\n <MuiTextField\n defaultValue={internalValue ?? ''}\n disabled={disabled || loading}\n error={hasError}\n inputRef={inputRef}\n label={label}\n onBlur={onMuiTextFieldBlur}\n placeholder={placeholder}\n slotProps={{\n formHelperText: {\n className: classnames({ 'Mui-warning': hasWarning }),\n },\n input: {\n className: classnames({ 'Mui-warning': hasWarning }),\n endAdornment: disabled ? undefined : (\n <InputAdornment position={'end'}>\n <IconButton\n {...TestIdUtil.createAttributes('TextField-reset')}\n aria-label={t`Clear text field`}\n onClick={onResetButtonClick}\n sx={{\n '& svg': {\n fontSize: '16px',\n },\n }}\n tabIndex={-1}\n >\n <ClearIcon />\n </IconButton>\n </InputAdornment>\n ),\n inputProps: {\n autoComplete: autocomplete ?? name,\n },\n },\n inputLabel: {\n className: classnames({ 'Mui-warning': hasWarning }),\n required: required && !disabled,\n shrink: hasInputValue,\n },\n }}\n variant={'outlined'}\n />\n ), [autocomplete, disabled, hasError, hasInputValue, hasWarning, internalValue, label, loading, name, onMuiTextFieldBlur, onResetButtonClick, placeholder, required, t]);\n\n return (\n <FormControl\n {...TestIdUtil.createAttributes('NumberField', { label, name })}\n fullWidth\n ref={formControlRef}\n sx={{\n '&:hover button, &:focus-within button': {\n display: 'initial',\n },\n button: {\n display: 'none',\n },\n }}\n >\n {!shouldShowSlider && textField}\n {shouldShowSlider && (\n <Box\n sx={{\n alignItems: 'center',\n display: 'grid',\n gap: 2,\n gridTemplateColumns: theme => `${theme.spacing(24)} auto`,\n }}\n >\n {textField}\n <Slider\n color={'primary'}\n marks\n max={max}\n min={min}\n onBlur={onMuiSliderBlur}\n onChange={onMuiRangeSliderChange}\n slotProps={{\n input: {\n 'aria-label': t`Value`,\n },\n }}\n step={step}\n value={sliderValue}\n valueLabelDisplay={'auto'}\n />\n </Box>\n )}\n { !!loading && <FormFieldLoadingIndicator />}\n <FormHelperText>\n <FormFieldHelperText\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n />\n </FormHelperText>\n </FormControl>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/fields/NumberField/NumberField.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n Box,\n FormControl,\n FormHelperText,\n IconButton,\n InputAdornment,\n TextField as MuiTextField,\n Slider,\n} from '@mui/material';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport type {\n FieldValues,\n Path,\n} from 'react-hook-form';\nimport { useFormContext } from 'react-hook-form';\nimport classnames from 'classnames';\nimport { useTranslation } from 'react-i18next';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\nimport { NumberUtil } from '@gen-epix/ui-core/utils/NumberUtil';\n\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nexport type NumberFieldProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {\n readonly autocomplete?: string;\n readonly disabled?: boolean;\n readonly infoMessage?: string;\n readonly label: string;\n readonly loading?: boolean;\n readonly max?: number;\n readonly min?: number;\n readonly name: TName;\n readonly onChange?: (value: number) => void;\n readonly placeholder?: string;\n readonly required?: boolean;\n readonly showSlider?: boolean;\n readonly step?: number;\n readonly warningMessage?: string;\n};\n\nconst MAX_NUMBER_OF_SLIDER_STEPS = 250;\n\nexport const NumberField = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({\n autocomplete,\n disabled = false,\n label,\n loading = false,\n max,\n min,\n name,\n onChange: onChangeProp,\n placeholder,\n required = false,\n showSlider = false,\n step,\n warningMessage,\n}: NumberFieldProps<TFieldValues, TName>): ReactElement => {\n const { t } = useTranslation();\n const { formState: { errors }, register, subscribe } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const hasError = !!errorMessage;\n const hasWarning = !!warningMessage && !hasError;\n const inputRef = useRef<HTMLInputElement>(null);\n const [internalValue, setInternalValue] = useState<number>(null);\n const [externalValue, setExternalValue] = useState<number>(null);\n const formControlRef = useRef<HTMLDivElement>(null);\n const [hasInputValue, setHasInputValue] = useState(false);\n\n const updateInputValue = useCallback((value: number) => {\n if (inputRef.current) {\n const inputValue = (value ?? '').toString().replace('.', ',');\n inputRef.current.value = inputValue;\n setHasInputValue(!!inputValue);\n }\n }, []);\n\n useEffect(() => {\n const unsubscribe = subscribe({\n callback: ({ name: changedName, values }) => {\n if (changedName !== name) {\n return;\n }\n setInternalValue(values[name]);\n setExternalValue(values[name]);\n updateInputValue(values[name]);\n },\n formState: {\n values: true,\n },\n name,\n });\n return () => {\n unsubscribe();\n };\n }, [name, subscribe, updateInputValue]);\n\n const registration = useMemo(() => register(name), [name, register]);\n\n const shouldShowSlider = useMemo(() => {\n if (!showSlider) {\n return false;\n }\n if (!isFinite(min) || !isFinite(max) || !isFinite(step) || min >= max) {\n return false;\n }\n if ((max - min) / step > MAX_NUMBER_OF_SLIDER_STEPS) {\n return false;\n }\n return true;\n }, [showSlider, min, max, step]);\n\n const emitValue = useCallback(async (parsedValue: number) => {\n let newValue: number;\n\n if (isNaN(parsedValue)) {\n newValue = null;\n } else {\n newValue = parsedValue;\n }\n\n updateInputValue(newValue);\n\n if (newValue !== externalValue) {\n await registration.onChange({\n target: {\n name,\n value: newValue,\n },\n });\n if (onChangeProp) {\n onChangeProp(newValue);\n }\n }\n }, [externalValue, name, onChangeProp, registration, updateInputValue]);\n\n const onResetButtonClick = useCallback(async () => {\n await emitValue(null);\n }, [emitValue]);\n\n\n const onMuiTextFieldBlur = useCallback(async () => {\n const parsedValue = NumberUtil.parse(inputRef.current.value);\n\n await emitValue(parsedValue);\n await registration.onBlur({\n target: {\n name,\n value: parsedValue,\n },\n type: 'blur',\n });\n }, [emitValue, name, registration]);\n\n const onMuiSliderBlur = useCallback(async () => {\n const parsedValue = NumberUtil.parse(inputRef.current.value);\n\n await emitValue(parsedValue);\n await registration.onBlur({\n target: {\n name,\n value: parsedValue,\n },\n type: 'blur',\n });\n }, [emitValue, name, registration]);\n\n const onMuiRangeSliderChange = useCallback((_event: unknown, sliderValue: number | number[]) => {\n const value = Array.isArray(sliderValue) ? sliderValue[0] : sliderValue;\n updateInputValue(value);\n setInternalValue(value);\n }, [updateInputValue]);\n\n let sliderValue = NumberUtil.parse(internalValue);\n if (isNaN(sliderValue)) {\n sliderValue = null;\n } else if (sliderValue < min) {\n sliderValue = min;\n } else if (sliderValue > max) {\n sliderValue = max;\n }\n\n const textField = useMemo(() => (\n <MuiTextField\n defaultValue={internalValue ?? ''}\n disabled={disabled || loading}\n error={hasError}\n inputRef={inputRef}\n label={label}\n onBlur={onMuiTextFieldBlur}\n placeholder={placeholder}\n slotProps={{\n formHelperText: {\n className: classnames({ 'Mui-warning': hasWarning }),\n },\n input: {\n className: classnames({ 'Mui-warning': hasWarning }),\n endAdornment: disabled ? undefined : (\n <InputAdornment position={'end'}>\n <IconButton\n {...TestIdUtil.createAttributes('TextField-reset')}\n aria-label={t`Clear text field`}\n onClick={onResetButtonClick}\n sx={{\n '& svg': {\n fontSize: '16px',\n },\n }}\n tabIndex={-1}\n >\n <ClearIcon />\n </IconButton>\n </InputAdornment>\n ),\n inputProps: {\n autoComplete: autocomplete ?? name,\n },\n },\n inputLabel: {\n className: classnames({ 'Mui-warning': hasWarning }),\n required: required && !disabled,\n shrink: hasInputValue,\n },\n }}\n variant={'outlined'}\n />\n ), [autocomplete, disabled, hasError, hasInputValue, hasWarning, internalValue, label, loading, name, onMuiTextFieldBlur, onResetButtonClick, placeholder, required, t]);\n\n return (\n <FormControl\n {...TestIdUtil.createAttributes('NumberField', { label, name })}\n fullWidth\n ref={formControlRef}\n sx={{\n '&:hover button, &:focus-within button': {\n display: 'initial',\n },\n button: {\n display: 'none',\n },\n }}\n >\n {!shouldShowSlider && textField}\n {shouldShowSlider && (\n <Box\n sx={{\n alignItems: 'center',\n display: 'grid',\n gap: 2,\n gridTemplateColumns: theme => `${theme.spacing(24)} auto`,\n }}\n >\n {textField}\n <Slider\n color={'primary'}\n marks\n max={max}\n min={min}\n onBlur={onMuiSliderBlur}\n onChange={onMuiRangeSliderChange}\n slotProps={{\n input: {\n 'aria-label': t`Value`,\n },\n }}\n step={step}\n value={sliderValue}\n valueLabelDisplay={'auto'}\n />\n </Box>\n )}\n { !!loading && <FormFieldLoadingIndicator />}\n <FormHelperText>\n <FormFieldHelperText\n errorMessage={errorMessage}\n warningMessage={warningMessage}\n />\n </FormHelperText>\n </FormControl>\n );\n};\n"],"mappings":";;;;;;;;;;;;;;mCAiDM,KAA6B,KAEtB,KAAwG,EACnH,iBACA,cAAW,IACX,UACA,aAAU,IACV,QACA,QACA,SACA,UAAU,GACV,gBACA,cAAW,IACX,gBAAa,IACb,SACA,wBACyD;CACzD,IAAM,EAAE,SAAM,EAAe,GACvB,EAAE,WAAW,EAAE,aAAU,aAAU,iBAAc,EAA6B,GAC9E,IAAe,EAAS,qBAAqB,GAAQ,CAAI,GACzD,IAAW,CAAC,CAAC,GACb,IAAa,CAAC,CAAC,KAAkB,CAAC,GAClC,IAAW,EAAyB,IAAI,GACxC,CAAC,GAAe,KAAoB,EAAiB,IAAI,GACzD,CAAC,GAAe,KAAoB,EAAiB,IAAI,GACzD,IAAiB,EAAuB,IAAI,GAC5C,CAAC,GAAe,KAAoB,EAAS,EAAK,GAElD,IAAmB,GAAa,MAAkB;EACtD,IAAI,EAAS,SAAS;GACpB,IAAM,KAAc,KAAS,GAAA,CAAI,SAAS,CAAC,CAAC,QAAQ,KAAK,GAAG;GAE5D,AADA,EAAS,QAAQ,QAAQ,GACzB,EAAiB,CAAC,CAAC,CAAU;EAC/B;CACF,GAAG,CAAC,CAAC;CAEL,SAAgB;EACd,IAAM,IAAc,EAAU;GAC5B,WAAW,EAAE,MAAM,GAAa,gBAAa;IACvC,MAAgB,MAGpB,EAAiB,EAAO,EAAK,GAC7B,EAAiB,EAAO,EAAK,GAC7B,EAAiB,EAAO,EAAK;GAC/B;GACA,WAAW,EACT,QAAQ,GACV;GACA;EACF,CAAC;EACD,aAAa;GACX,EAAY;EACd;CACF,GAAG;EAAC;EAAM;EAAW;CAAgB,CAAC;CAEtC,IAAM,IAAe,QAAc,EAAS,CAAI,GAAG,CAAC,GAAM,CAAQ,CAAC,GAE7D,IAAmB,QAOvB,EANI,CAAC,KAGD,CAAC,SAAS,CAAG,KAAK,CAAC,SAAS,CAAG,KAAK,CAAC,SAAS,CAAI,KAAK,KAAO,MAG7D,IAAM,KAAO,IAAO,KAIxB;EAAC;EAAY;EAAK;EAAK;CAAI,CAAC,GAEzB,IAAY,EAAY,OAAO,MAAwB;EAC3D,IAAI;EAUJ,AARA,AAGE,IAHE,MAAM,CAAW,IACR,OAEA,GAGb,EAAiB,CAAQ,GAErB,MAAa,MACf,MAAM,EAAa,SAAS,EAC1B,QAAQ;GACN;GACA,OAAO;EACT,EACF,CAAC,GACG,KACF,EAAa,CAAQ;CAG3B,GAAG;EAAC;EAAe;EAAM;EAAc;EAAc;CAAgB,CAAC,GAEhE,IAAqB,EAAY,YAAY;EACjD,MAAM,EAAU,IAAI;CACtB,GAAG,CAAC,CAAS,CAAC,GAGR,IAAqB,EAAY,YAAY;EACjD,IAAM,IAAc,EAAW,MAAM,EAAS,QAAQ,KAAK;EAG3D,AADA,MAAM,EAAU,CAAW,GAC3B,MAAM,EAAa,OAAO;GACxB,QAAQ;IACN;IACA,OAAO;GACT;GACA,MAAM;EACR,CAAC;CACH,GAAG;EAAC;EAAW;EAAM;CAAY,CAAC,GAE5B,KAAkB,EAAY,YAAY;EAC9C,IAAM,IAAc,EAAW,MAAM,EAAS,QAAQ,KAAK;EAG3D,AADA,MAAM,EAAU,CAAW,GAC3B,MAAM,EAAa,OAAO;GACxB,QAAQ;IACN;IACA,OAAO;GACT;GACA,MAAM;EACR,CAAC;CACH,GAAG;EAAC;EAAW;EAAM;CAAY,CAAC,GAE5B,KAAyB,GAAa,GAAiB,MAAmC;EAC9F,IAAM,IAAQ,MAAM,QAAQ,CAAW,IAAI,EAAY,KAAK;EAE5D,AADA,EAAiB,CAAK,GACtB,EAAiB,CAAK;CACxB,GAAG,CAAC,CAAgB,CAAC,GAEjB,IAAc,EAAW,MAAM,CAAa;CAChD,AAAI,MAAM,CAAW,IACnB,IAAc,OACL,IAAc,IACvB,IAAc,IACL,IAAc,MACvB,IAAc;CAGhB,IAAM,IAAY,QAChB,kBAAC,IAAD;EACE,cAAc,KAAiB;EAC/B,UAAU,KAAY;EACtB,OAAO;EACG;EACH;EACP,QAAQ;EACK;EACb,WAAW;GACT,gBAAgB,EACd,YAAA,GAAW,EAAA,QAAA,CAAW,EAAE,eAAe,EAAW,CAAC,EACrD;GACA,OAAO;IACL,YAAA,GAAW,EAAA,QAAA,CAAW,EAAE,eAAe,EAAW,CAAC;IACnD,cAAc,IAAW,KAAA,IACvB,kBAAC,GAAD;KAAgB,UAAU;KACxB,UAAA,kBAAC,GAAD;MACE,GAAI,EAAW,iBAAiB,iBAAiB;MACjD,cAAY,CAAC;MACb,SAAS;MACT,IAAI,EACF,SAAS,EACP,UAAU,OACZ,EACF;MACA,UAAU;MAEV,UAAA,kBAAC,IAAD,CAAY,CAAA;KACF,CAAA;IACE,CAAA;IAElB,YAAY,EACV,cAAc,KAAgB,EAChC;GACF;GACA,YAAY;IACV,YAAA,GAAW,EAAA,QAAA,CAAW,EAAE,eAAe,EAAW,CAAC;IACnD,UAAU,KAAY,CAAC;IACvB,QAAQ;GACV;EACF;EACA,SAAS;CACV,CAAA,GACA;EAAC;EAAc;EAAU;EAAU;EAAe;EAAY;EAAe;EAAO;EAAS;EAAM;EAAoB;EAAoB;EAAa;EAAU;CAAC,CAAC;CAEvK,OACE,kBAAC,IAAD;EACE,GAAI,EAAW,iBAAiB,eAAe;GAAE;GAAO;EAAK,CAAC;EAC9D,WAAA;EACA,KAAK;EACL,IAAI;GACF,yCAAyC,EACvC,SAAS,UACX;GACA,QAAQ,EACN,SAAS,OACX;EACF;EAXF,UAAA;GAaG,CAAC,KAAoB;GACrB,KACC,kBAAC,GAAD;IACE,IAAI;KACF,YAAY;KACZ,SAAS;KACT,KAAK;KACL,sBAAqB,MAAS,GAAG,EAAM,QAAQ,EAAE,EAAE;IACrD;IANF,UAAA,CAQG,GACD,kBAAC,GAAD;KACE,OAAO;KACP,OAAA;KACK;KACA;KACL,QAAQ;KACR,UAAU;KACV,WAAW,EACT,OAAO,EACL,cAAc,CAAC,QACjB,EACF;KACM;KACN,OAAO;KACP,mBAAmB;IACpB,CAAA,CACE;;GAEL,CAAC,CAAC,KAAW,kBAAC,GAAD,CAA4B,CAAA;GAC3C,kBAAC,IAAD,EAAA,UACE,kBAAC,GAAD;IACgB;IACE;GACjB,CAAA,EACa,CAAA;EACL;;AAEjB"}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { n as e, t } from "../../../_chunks/rolldown-runtime.js";
|
|
2
2
|
import { t as n } from "../../../_chunks/FormUtil.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
3
|
+
import { FormFieldHelperText as r } from "../../helpers/FormFieldHelperText/index.js";
|
|
4
|
+
import { FormFieldLoadingIndicator as i } from "../../helpers/FormFieldLoadingIndicator/index.js";
|
|
5
|
+
import { h as a, p as o, t as s } from "../../../_chunks/isObjectLike.js";
|
|
6
|
+
import { t as c } from "../../../_chunks/isEqual.js";
|
|
7
|
+
import { useCallback as l, useId as u, useRef as d } from "react";
|
|
8
|
+
import { Controller as f, useFormContext as p, useWatch as m } from "react-hook-form";
|
|
9
9
|
import { useTranslation as h } from "react-i18next";
|
|
10
10
|
import { Box as g, FormControl as _, FormHelperText as v, FormLabel as y, IconButton as b, Input as x, Slider as S, useTheme as C } from "@mui/material";
|
|
11
11
|
import w from "@mui/icons-material/Clear";
|
|
@@ -13,43 +13,43 @@ import { jsx as T, jsxs as E } from "react/jsx-runtime";
|
|
|
13
13
|
import { TestIdUtil as D } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
14
14
|
//#region ../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/isNumber.js
|
|
15
15
|
var O = /* @__PURE__ */ t(((e, t) => {
|
|
16
|
-
var n =
|
|
16
|
+
var n = o(), r = s(), i = "[object Number]";
|
|
17
17
|
function a(e) {
|
|
18
18
|
return typeof e == "number" || r(e) && n(e) == i;
|
|
19
19
|
}
|
|
20
20
|
t.exports = a;
|
|
21
21
|
})), k = /* @__PURE__ */ t(((e, t) => {
|
|
22
|
-
var n =
|
|
22
|
+
var n = a().isFinite;
|
|
23
23
|
function r(e) {
|
|
24
24
|
return typeof e == "number" && n(e);
|
|
25
25
|
}
|
|
26
26
|
t.exports = r;
|
|
27
|
-
})), A = /* @__PURE__ */ e(
|
|
28
|
-
let F = (0, M.default)(
|
|
27
|
+
})), A = /* @__PURE__ */ e(c(), 1), j = /* @__PURE__ */ e(O(), 1), M = /* @__PURE__ */ e(k(), 1), N = ({ disabled: e = !1, infoMessage: t, label: a, loading: o = !1, max: s, min: c, name: O, onChange: k, required: N = !1, warningMessage: P }) => {
|
|
28
|
+
let F = (0, M.default)(c) && (0, M.default)(s), I = C(), { t: L } = h(), { control: R, formState: { errors: z } } = p(), B = n.getFieldErrorMessage(z, O), V = !!B, H = d(null), U = u(), W = m({
|
|
29
29
|
control: R,
|
|
30
30
|
name: O
|
|
31
|
-
}), G =
|
|
31
|
+
}), G = l((e, t) => {
|
|
32
32
|
(0, A.default)(W, e) || (k && k(e), t(e));
|
|
33
|
-
}, [k, W]), K =
|
|
33
|
+
}, [k, W]), K = l((e) => (t, n) => {
|
|
34
34
|
G(n, e);
|
|
35
|
-
}, [G]), q =
|
|
36
|
-
|
|
35
|
+
}, [G]), q = l(({ field: { onBlur: n, onChange: l, ref: u, value: d } }) => {
|
|
36
|
+
u({ focus: () => {
|
|
37
37
|
H?.current?.focus();
|
|
38
38
|
} });
|
|
39
|
-
let f =
|
|
40
|
-
e.target.value === "" ? G([null, p],
|
|
39
|
+
let f = d?.[0], p = d?.[1], m = (e) => {
|
|
40
|
+
e.target.value === "" ? G([null, p], l) : (0, M.default)(+e.target.value) && G([+e.target.value, p], l);
|
|
41
41
|
}, h = (e) => {
|
|
42
|
-
e.target.value === "" ? G([f, null],
|
|
42
|
+
e.target.value === "" ? G([f, null], l) : (0, M.default)(+e.target.value) && G([f, +e.target.value], l);
|
|
43
43
|
}, C = () => {
|
|
44
|
-
f === null || !(0, M.default)(f) ? G([null, p],
|
|
44
|
+
f === null || !(0, M.default)(f) ? G([null, p], l) : f < c ? G([c, p], l) : f > s ? G([s, s], l) : (0, j.default)(p) && f > p && G([p, f], l), n();
|
|
45
45
|
}, k = () => {
|
|
46
|
-
p === null || !(0, M.default)(p) ? G([f, null],
|
|
46
|
+
p === null || !(0, M.default)(p) ? G([f, null], l) : p > s ? G([f, s], l) : p < c ? G([c, c], l) : (0, j.default)(f) && p < f && G([p, f], l), n();
|
|
47
47
|
}, A = () => {
|
|
48
|
-
G([null, null],
|
|
48
|
+
G([null, null], l);
|
|
49
49
|
};
|
|
50
50
|
return /* @__PURE__ */ E(g, {
|
|
51
51
|
...D.createAttributes("RangeSlider", {
|
|
52
|
-
label:
|
|
52
|
+
label: a,
|
|
53
53
|
name: O
|
|
54
54
|
}),
|
|
55
55
|
sx: {
|
|
@@ -57,7 +57,7 @@ var O = /* @__PURE__ */ t(((e, t) => {
|
|
|
57
57
|
"legend button": { display: "none" }
|
|
58
58
|
},
|
|
59
59
|
children: [
|
|
60
|
-
!
|
|
60
|
+
!o && /* @__PURE__ */ E(g, {
|
|
61
61
|
sx: {
|
|
62
62
|
display: "grid",
|
|
63
63
|
gridTemplateColumns: "max-content auto max-content",
|
|
@@ -90,14 +90,14 @@ var O = /* @__PURE__ */ t(((e, t) => {
|
|
|
90
90
|
sx: { position: "initial" },
|
|
91
91
|
children: [/* @__PURE__ */ E(y, {
|
|
92
92
|
component: "legend",
|
|
93
|
-
disabled: e ||
|
|
93
|
+
disabled: e || o,
|
|
94
94
|
id: U,
|
|
95
95
|
required: N,
|
|
96
96
|
sx: {
|
|
97
97
|
left: 0,
|
|
98
98
|
position: "absolute"
|
|
99
99
|
},
|
|
100
|
-
children: [
|
|
100
|
+
children: [a, !e && /* @__PURE__ */ T(b, {
|
|
101
101
|
...D.createAttributes("RangeSlider-reset"),
|
|
102
102
|
"aria-label": L`Clear number range`,
|
|
103
103
|
onClick: A,
|
|
@@ -116,12 +116,12 @@ var O = /* @__PURE__ */ t(((e, t) => {
|
|
|
116
116
|
},
|
|
117
117
|
children: F && /* @__PURE__ */ T(S, {
|
|
118
118
|
color: "primary",
|
|
119
|
-
max:
|
|
120
|
-
min:
|
|
119
|
+
max: s,
|
|
120
|
+
min: c,
|
|
121
121
|
onBlur: n,
|
|
122
|
-
onChange: K(
|
|
122
|
+
onChange: K(l),
|
|
123
123
|
slotProps: { input: { "aria-label": L`Value` } },
|
|
124
|
-
value:
|
|
124
|
+
value: d,
|
|
125
125
|
valueLabelDisplay: "off"
|
|
126
126
|
})
|
|
127
127
|
})]
|
|
@@ -148,10 +148,10 @@ var O = /* @__PURE__ */ t(((e, t) => {
|
|
|
148
148
|
})
|
|
149
149
|
]
|
|
150
150
|
}),
|
|
151
|
-
!!
|
|
151
|
+
!!o && /* @__PURE__ */ T(i, { inline: !0 }),
|
|
152
152
|
/* @__PURE__ */ T(v, {
|
|
153
153
|
sx: { ml: 0 },
|
|
154
|
-
children: /* @__PURE__ */ T(
|
|
154
|
+
children: /* @__PURE__ */ T(r, {
|
|
155
155
|
errorMessage: B,
|
|
156
156
|
infoMessage: t,
|
|
157
157
|
noIndent: !0,
|
|
@@ -167,10 +167,10 @@ var O = /* @__PURE__ */ t(((e, t) => {
|
|
|
167
167
|
V,
|
|
168
168
|
U,
|
|
169
169
|
t,
|
|
170
|
+
a,
|
|
171
|
+
o,
|
|
172
|
+
s,
|
|
170
173
|
c,
|
|
171
|
-
l,
|
|
172
|
-
u,
|
|
173
|
-
d,
|
|
174
174
|
O,
|
|
175
175
|
K,
|
|
176
176
|
N,
|
|
@@ -179,7 +179,7 @@ var O = /* @__PURE__ */ t(((e, t) => {
|
|
|
179
179
|
P,
|
|
180
180
|
I
|
|
181
181
|
]);
|
|
182
|
-
return /* @__PURE__ */ T(
|
|
182
|
+
return /* @__PURE__ */ T(f, {
|
|
183
183
|
control: R,
|
|
184
184
|
defaultValue: null,
|
|
185
185
|
name: O,
|
|
@@ -1,15 +1,15 @@
|
|
|
1
1
|
import { t as e } from "../../../_chunks/FormUtil.js";
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
2
|
+
import { FormFieldHelperText as t } from "../../helpers/FormFieldHelperText/index.js";
|
|
3
|
+
import { useCallback as n, useId as r, useRef as i } from "react";
|
|
4
|
+
import { Controller as a, useFormContext as o } from "react-hook-form";
|
|
5
5
|
import { FormControl as s, FormControlLabel as c, FormHelperText as l, FormLabel as u, Radio as d, RadioGroup as f } from "@mui/material";
|
|
6
6
|
import { jsx as p, jsxs as m } from "react/jsx-runtime";
|
|
7
7
|
import { TestIdUtil as h } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
8
8
|
//#region src/components/fields/RadioGroup/RadioGroup.tsx
|
|
9
9
|
var g = ({ disabled: g, infoMessage: _, label: v, name: y, onChange: b, options: x, required: S, row: C, warningMessage: w }) => {
|
|
10
|
-
let T =
|
|
10
|
+
let T = r(), { control: E, formState: { errors: D } } = o(), O = e.getFieldErrorMessage(D, y), k = i(null), A = !!O, j = n((e) => (t, n) => {
|
|
11
11
|
b && b(n), e(n);
|
|
12
|
-
}, [b]), M =
|
|
12
|
+
}, [b]), M = n(({ field: { onBlur: e, onChange: t, ref: n, value: r } }) => (n({ focus: () => {
|
|
13
13
|
k?.current?.focus();
|
|
14
14
|
} }), /* @__PURE__ */ p(f, {
|
|
15
15
|
"aria-labelledby": T,
|
|
@@ -48,7 +48,7 @@ var g = ({ disabled: g, infoMessage: _, label: v, name: y, onChange: b, options:
|
|
|
48
48
|
required: S,
|
|
49
49
|
children: v
|
|
50
50
|
}),
|
|
51
|
-
/* @__PURE__ */ p(
|
|
51
|
+
/* @__PURE__ */ p(a, {
|
|
52
52
|
control: E,
|
|
53
53
|
defaultValue: null,
|
|
54
54
|
name: y,
|
|
@@ -56,7 +56,7 @@ var g = ({ disabled: g, infoMessage: _, label: v, name: y, onChange: b, options:
|
|
|
56
56
|
}),
|
|
57
57
|
/* @__PURE__ */ p(l, {
|
|
58
58
|
sx: { ml: 0 },
|
|
59
|
-
children: /* @__PURE__ */ p(
|
|
59
|
+
children: /* @__PURE__ */ p(t, {
|
|
60
60
|
errorMessage: O,
|
|
61
61
|
infoMessage: _,
|
|
62
62
|
noIndent: !0,
|
|
@@ -1,30 +1,30 @@
|
|
|
1
1
|
import { n as e } from "../../../_chunks/rolldown-runtime.js";
|
|
2
2
|
import { t } from "../../../_chunks/FormUtil.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
3
|
+
import { FormFieldHelperText as n } from "../../helpers/FormFieldHelperText/index.js";
|
|
4
|
+
import { FormFieldLoadingIndicator as r } from "../../helpers/FormFieldLoadingIndicator/index.js";
|
|
5
|
+
import { t as i } from "../../../_chunks/classnames.js";
|
|
6
|
+
import { useCallback as a, useId as o, useMemo as s, useRef as c } from "react";
|
|
7
|
+
import { Controller as l, useFormContext as u } from "react-hook-form";
|
|
8
8
|
import { useTranslation as d } from "react-i18next";
|
|
9
9
|
import { Checkbox as f, FormControl as p, FormHelperText as m, IconButton as h, InputAdornment as g, InputLabel as _, ListItemText as v, MenuItem as y, OutlinedInput as b, Select as x } from "@mui/material";
|
|
10
10
|
import S from "@mui/icons-material/Clear";
|
|
11
11
|
import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
|
|
12
12
|
import { TestIdUtil as E } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
13
13
|
//#region src/components/fields/Select/Select.tsx
|
|
14
|
-
var D = /* @__PURE__ */ e(
|
|
15
|
-
let { t: I } = d(), { control: L, formState: { errors: R } } =
|
|
14
|
+
var D = /* @__PURE__ */ e(i(), 1), O = ({ disabled: e = !1, infoMessage: i, label: O, loading: k = !1, multiple: A, name: j, onChange: M, options: N, required: P = !1, warningMessage: F }) => {
|
|
15
|
+
let { t: I } = d(), { control: L, formState: { errors: R } } = u(), z = t.getFieldErrorMessage(R, j), B = c(null), V = o(), H = o(), U = o(), W = !!z, G = !!F && !W, K = s(() => {
|
|
16
16
|
let e = /* @__PURE__ */ new Map();
|
|
17
17
|
return N.forEach((t) => {
|
|
18
18
|
e.set(t.value, t);
|
|
19
19
|
}), e;
|
|
20
|
-
}, [N]), q =
|
|
20
|
+
}, [N]), q = a((e) => K.get(e)?.disabled, [K]), J = a((e) => (Array.isArray(e) ? e : [e]).map((e) => K.get(e)?.label).join(", "), [K]), Y = a((e) => (t) => {
|
|
21
21
|
M && M(t.target.value), e(t.target.value);
|
|
22
|
-
}, [M]), X =
|
|
23
|
-
|
|
22
|
+
}, [M]), X = a(({ field: { onBlur: t, onChange: r, ref: a, value: o } }) => {
|
|
23
|
+
a({ focus: () => {
|
|
24
24
|
B?.current?.focus();
|
|
25
25
|
} });
|
|
26
26
|
let s = () => {
|
|
27
|
-
Y(
|
|
27
|
+
Y(r)({ target: { value: A ? [] : "" } });
|
|
28
28
|
};
|
|
29
29
|
return /* @__PURE__ */ T(C, { children: [
|
|
30
30
|
/* @__PURE__ */ w(_, {
|
|
@@ -67,23 +67,36 @@ var D = /* @__PURE__ */ e(o(), 1), O = ({ disabled: e = !1, infoMessage: o, labe
|
|
|
67
67
|
},
|
|
68
68
|
multiple: A,
|
|
69
69
|
onBlur: t,
|
|
70
|
-
onChange: Y(
|
|
70
|
+
onChange: Y(r),
|
|
71
71
|
renderValue: J,
|
|
72
72
|
required: P,
|
|
73
|
-
value:
|
|
73
|
+
value: o ?? (A ? [] : ""),
|
|
74
74
|
children: N.map((e) => /* @__PURE__ */ T(y, {
|
|
75
75
|
disabled: q(e.value),
|
|
76
76
|
value: e.value,
|
|
77
|
-
children: [A && /* @__PURE__ */ w(f, { checked:
|
|
77
|
+
children: [A && /* @__PURE__ */ w(f, { checked: o.includes(e.value) }), /* @__PURE__ */ w(v, {
|
|
78
|
+
primary: e.label,
|
|
79
|
+
secondary: e.secondaryLabel,
|
|
80
|
+
slotProps: { secondary: { sx: {
|
|
81
|
+
fontSize: "0.875rem",
|
|
82
|
+
fontStyle: "italic"
|
|
83
|
+
} } },
|
|
84
|
+
sx: {
|
|
85
|
+
alignItems: "baseline",
|
|
86
|
+
display: "flex",
|
|
87
|
+
gap: 2,
|
|
88
|
+
justifyContent: "space-between"
|
|
89
|
+
}
|
|
90
|
+
})]
|
|
78
91
|
}, e.value.toString()))
|
|
79
92
|
}),
|
|
80
93
|
/* @__PURE__ */ w(m, {
|
|
81
94
|
className: (0, D.default)({ "Mui-warning": G }),
|
|
82
95
|
id: U,
|
|
83
96
|
sx: { ml: 0 },
|
|
84
|
-
children: /* @__PURE__ */ w(
|
|
97
|
+
children: /* @__PURE__ */ w(n, {
|
|
85
98
|
errorMessage: z,
|
|
86
|
-
infoMessage:
|
|
99
|
+
infoMessage: i,
|
|
87
100
|
noIndent: !0,
|
|
88
101
|
warningMessage: F
|
|
89
102
|
})
|
|
@@ -91,7 +104,7 @@ var D = /* @__PURE__ */ e(o(), 1), O = ({ disabled: e = !1, infoMessage: o, labe
|
|
|
91
104
|
] });
|
|
92
105
|
}, [
|
|
93
106
|
e,
|
|
94
|
-
|
|
107
|
+
i,
|
|
95
108
|
z,
|
|
96
109
|
q,
|
|
97
110
|
I,
|
|
@@ -115,12 +128,12 @@ var D = /* @__PURE__ */ e(o(), 1), O = ({ disabled: e = !1, infoMessage: o, labe
|
|
|
115
128
|
name: j
|
|
116
129
|
}),
|
|
117
130
|
fullWidth: !0,
|
|
118
|
-
children: [/* @__PURE__ */ w(
|
|
131
|
+
children: [/* @__PURE__ */ w(l, {
|
|
119
132
|
control: L,
|
|
120
133
|
defaultValue: null,
|
|
121
134
|
name: j,
|
|
122
135
|
render: X
|
|
123
|
-
}), !!k && /* @__PURE__ */ w(
|
|
136
|
+
}), !!k && /* @__PURE__ */ w(r, {})]
|
|
124
137
|
});
|
|
125
138
|
};
|
|
126
139
|
//#endregion
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/fields/Select/Select.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport {\n useCallback,\n useId,\n useMemo,\n useRef,\n} from 'react';\nimport {\n Checkbox,\n FormControl,\n FormHelperText,\n IconButton,\n InputAdornment,\n InputLabel,\n ListItemText,\n MenuItem,\n Select as MuiSelect,\n OutlinedInput,\n} from '@mui/material';\nimport type { SelectChangeEvent } from '@mui/material';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport type {\n ControllerRenderProps,\n FieldValues,\n Path,\n UseControllerReturn,\n} from 'react-hook-form';\nimport {\n Controller,\n useFormContext,\n} from 'react-hook-form';\nimport classnames from 'classnames';\nimport { useTranslation } from 'react-i18next';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\n\nimport type { SelectOption } from '../../../models/form';\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nexport type SelectProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>, TMultiple extends boolean> = {\n readonly disabled?: boolean;\n readonly infoMessage?: string;\n readonly label: string;\n readonly loading?: boolean;\n readonly multiple?: TMultiple;\n readonly name: TName;\n readonly onChange?: (value: string) => void;\n readonly options: SelectOption[];\n readonly required?: boolean;\n readonly warningMessage?: string;\n};\n\ntype Value = boolean | number | string;\n\nexport const Select = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>, TMultiple extends boolean = false>({\n disabled = false,\n infoMessage,\n label,\n loading = false,\n multiple,\n name,\n onChange: onChangeProp,\n options,\n required = false,\n warningMessage,\n}: SelectProps<TFieldValues, TName, TMultiple>): ReactElement => {\n const { t } = useTranslation();\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const inputRef = useRef<HTMLInputElement>(null);\n const id = useId();\n const labelId = useId();\n const helperTextId = useId();\n\n const hasError = !!errorMessage;\n const hasWarning = !!warningMessage && !hasError;\n\n const mappedOptions = useMemo<Map<Value, SelectOption>>(() => {\n const mapped = new Map<Value, SelectOption>();\n options.forEach(option => {\n mapped.set(option.value, option);\n });\n return mapped;\n }, [options]);\n\n const getIsOptionDisabled = useCallback((value: SelectOption['value']): boolean => mappedOptions.get(value)?.disabled, [mappedOptions]);\n\n const renderValue = useCallback((value: string | string []) => {\n const values = Array.isArray(value) ? value : [value];\n return values.map(v => mappedOptions.get(v)?.label).join(', ');\n }, [mappedOptions]);\n\n const onMuiSelectChange = useCallback((onChange: ControllerRenderProps<TFieldValues, TName>['onChange']) =>\n (event: SelectChangeEvent<string>) => {\n if (onChangeProp) {\n onChangeProp(event.target.value);\n }\n onChange(event.target.value);\n }\n , [onChangeProp]);\n\n const renderController = useCallback(({ field: { onBlur, onChange, ref, value } }: UseControllerReturn<TFieldValues, TName>) => {\n ref({\n focus: () => {\n inputRef?.current?.focus();\n },\n });\n const onResetButtonClick = () => {\n onMuiSelectChange(onChange)({ target: { value: multiple ? [] : '' } } as SelectChangeEvent<string>);\n };\n\n return (\n <>\n <InputLabel\n className={classnames({ 'Mui-warning': hasWarning })}\n error={hasError}\n htmlFor={id}\n id={labelId}\n required={required && !disabled}\n >\n {label}\n </InputLabel>\n <MuiSelect<TFieldValues[TName]>\n disabled={disabled || loading}\n error={hasError}\n input={(\n <OutlinedInput\n endAdornment={disabled ? undefined : (\n <InputAdornment\n position={'start'}\n sx={{\n position: 'absolute',\n right: theme => theme.spacing(2),\n }}\n >\n <IconButton\n {...TestIdUtil.createAttributes('TextField-reset')}\n aria-label={t`Clear selection`}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onClick={onResetButtonClick}\n sx={{\n '& svg': {\n fontSize: '16px',\n },\n }}\n tabIndex={-1}\n >\n <ClearIcon />\n </IconButton>\n </InputAdornment>\n )}\n label={label}\n />\n )}\n inputProps={{\n 'aria-describedby': helperTextId,\n 'aria-label': label,\n 'aria-labelledby': labelId,\n className: classnames({\n 'Mui-warning': hasWarning,\n }),\n id,\n ref: inputRef,\n required: required && !disabled,\n }}\n multiple={multiple}\n onBlur={onBlur}\n onChange={onMuiSelectChange(onChange)}\n renderValue={renderValue}\n required={required}\n value={value ?? (multiple ? [] : '') as TFieldValues[TName]}\n >\n { options.map((option) => {\n return (\n <MenuItem\n disabled={getIsOptionDisabled(option.value)}\n key={option.value.toString()}\n value={option.value as string}\n >\n\n {multiple && (\n <Checkbox\n checked={(value as string[]).includes(option.value as string)}\n />\n )}\n <ListItemText primary={option.label} />\n </MenuItem>\n );\n })}\n </MuiSelect>\n <FormHelperText\n className={classnames({ 'Mui-warning': hasWarning })}\n id={helperTextId}\n sx={{ ml: 0 }}\n >\n <FormFieldHelperText\n errorMessage={errorMessage}\n infoMessage={infoMessage}\n noIndent\n warningMessage={warningMessage}\n />\n </FormHelperText>\n </>\n );\n }, [disabled, infoMessage, errorMessage, getIsOptionDisabled, t, hasError, hasWarning, helperTextId, id, label, labelId, loading, multiple, onMuiSelectChange, options, renderValue, required, warningMessage]);\n\n return (\n <FormControl\n {...TestIdUtil.createAttributes('Select', { label, name })}\n fullWidth\n >\n <Controller\n control={control}\n defaultValue={null}\n name={name}\n render={renderController}\n />\n { !!loading && <FormFieldLoadingIndicator />}\n </FormControl>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/fields/Select/Select.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport {\n useCallback,\n useId,\n useMemo,\n useRef,\n} from 'react';\nimport {\n Checkbox,\n FormControl,\n FormHelperText,\n IconButton,\n InputAdornment,\n InputLabel,\n ListItemText,\n MenuItem,\n Select as MuiSelect,\n OutlinedInput,\n} from '@mui/material';\nimport type { SelectChangeEvent } from '@mui/material';\nimport ClearIcon from '@mui/icons-material/Clear';\nimport type {\n ControllerRenderProps,\n FieldValues,\n Path,\n UseControllerReturn,\n} from 'react-hook-form';\nimport {\n Controller,\n useFormContext,\n} from 'react-hook-form';\nimport classnames from 'classnames';\nimport { useTranslation } from 'react-i18next';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\n\nimport type { SelectOption } from '../../../models/form';\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nexport type SelectProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>, TMultiple extends boolean> = {\n readonly disabled?: boolean;\n readonly infoMessage?: string;\n readonly label: string;\n readonly loading?: boolean;\n readonly multiple?: TMultiple;\n readonly name: TName;\n readonly onChange?: (value: string) => void;\n readonly options: SelectOption[];\n readonly required?: boolean;\n readonly warningMessage?: string;\n};\n\ntype Value = boolean | number | string;\n\nexport const Select = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>, TMultiple extends boolean = false>({\n disabled = false,\n infoMessage,\n label,\n loading = false,\n multiple,\n name,\n onChange: onChangeProp,\n options,\n required = false,\n warningMessage,\n}: SelectProps<TFieldValues, TName, TMultiple>): ReactElement => {\n const { t } = useTranslation();\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const inputRef = useRef<HTMLInputElement>(null);\n const id = useId();\n const labelId = useId();\n const helperTextId = useId();\n\n const hasError = !!errorMessage;\n const hasWarning = !!warningMessage && !hasError;\n\n const mappedOptions = useMemo<Map<Value, SelectOption>>(() => {\n const mapped = new Map<Value, SelectOption>();\n options.forEach(option => {\n mapped.set(option.value, option);\n });\n return mapped;\n }, [options]);\n\n const getIsOptionDisabled = useCallback((value: SelectOption['value']): boolean => mappedOptions.get(value)?.disabled, [mappedOptions]);\n\n const renderValue = useCallback((value: string | string []) => {\n const values = Array.isArray(value) ? value : [value];\n return values.map(v => mappedOptions.get(v)?.label).join(', ');\n }, [mappedOptions]);\n\n const onMuiSelectChange = useCallback((onChange: ControllerRenderProps<TFieldValues, TName>['onChange']) =>\n (event: SelectChangeEvent<string>) => {\n if (onChangeProp) {\n onChangeProp(event.target.value);\n }\n onChange(event.target.value);\n }\n , [onChangeProp]);\n\n const renderController = useCallback(({ field: { onBlur, onChange, ref, value } }: UseControllerReturn<TFieldValues, TName>) => {\n ref({\n focus: () => {\n inputRef?.current?.focus();\n },\n });\n const onResetButtonClick = () => {\n onMuiSelectChange(onChange)({ target: { value: multiple ? [] : '' } } as SelectChangeEvent<string>);\n };\n\n return (\n <>\n <InputLabel\n className={classnames({ 'Mui-warning': hasWarning })}\n error={hasError}\n htmlFor={id}\n id={labelId}\n required={required && !disabled}\n >\n {label}\n </InputLabel>\n <MuiSelect<TFieldValues[TName]>\n disabled={disabled || loading}\n error={hasError}\n input={(\n <OutlinedInput\n endAdornment={disabled ? undefined : (\n <InputAdornment\n position={'start'}\n sx={{\n position: 'absolute',\n right: theme => theme.spacing(2),\n }}\n >\n <IconButton\n {...TestIdUtil.createAttributes('TextField-reset')}\n aria-label={t`Clear selection`}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onClick={onResetButtonClick}\n sx={{\n '& svg': {\n fontSize: '16px',\n },\n }}\n tabIndex={-1}\n >\n <ClearIcon />\n </IconButton>\n </InputAdornment>\n )}\n label={label}\n />\n )}\n inputProps={{\n 'aria-describedby': helperTextId,\n 'aria-label': label,\n 'aria-labelledby': labelId,\n className: classnames({\n 'Mui-warning': hasWarning,\n }),\n id,\n ref: inputRef,\n required: required && !disabled,\n }}\n multiple={multiple}\n onBlur={onBlur}\n onChange={onMuiSelectChange(onChange)}\n renderValue={renderValue}\n required={required}\n value={value ?? (multiple ? [] : '') as TFieldValues[TName]}\n >\n { options.map((option) => {\n return (\n <MenuItem\n disabled={getIsOptionDisabled(option.value)}\n key={option.value.toString()}\n value={option.value as string}\n >\n\n {multiple && (\n <Checkbox\n checked={(value as string[]).includes(option.value as string)}\n />\n )}\n <ListItemText\n primary={option.label}\n secondary={option.secondaryLabel}\n slotProps={{\n secondary: { sx: { fontSize: '0.875rem', fontStyle: 'italic' } },\n }}\n sx={{\n alignItems: 'baseline',\n display: 'flex',\n gap: 2,\n justifyContent: 'space-between',\n }}\n />\n </MenuItem>\n );\n })}\n </MuiSelect>\n <FormHelperText\n className={classnames({ 'Mui-warning': hasWarning })}\n id={helperTextId}\n sx={{ ml: 0 }}\n >\n <FormFieldHelperText\n errorMessage={errorMessage}\n infoMessage={infoMessage}\n noIndent\n warningMessage={warningMessage}\n />\n </FormHelperText>\n </>\n );\n }, [disabled, infoMessage, errorMessage, getIsOptionDisabled, t, hasError, hasWarning, helperTextId, id, label, labelId, loading, multiple, onMuiSelectChange, options, renderValue, required, warningMessage]);\n\n return (\n <FormControl\n {...TestIdUtil.createAttributes('Select', { label, name })}\n fullWidth\n >\n <Controller\n control={control}\n defaultValue={null}\n name={name}\n render={renderController}\n />\n { !!loading && <FormFieldLoadingIndicator />}\n </FormControl>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,7 +1,8 @@
|
|
|
1
|
-
import { ReactElement } from 'react';
|
|
1
|
+
import { ReactElement, ReactNode } from 'react';
|
|
2
2
|
import { FieldValues, Path } from 'react-hook-form';
|
|
3
3
|
export type SwitchProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>> = {
|
|
4
4
|
readonly disabled?: boolean;
|
|
5
|
+
readonly icon?: ReactNode;
|
|
5
6
|
readonly infoMessage?: string;
|
|
6
7
|
readonly label: string;
|
|
7
8
|
readonly loading?: boolean;
|
|
@@ -10,4 +11,4 @@ export type SwitchProps<TFieldValues extends FieldValues, TName extends Path<TFi
|
|
|
10
11
|
readonly required?: boolean;
|
|
11
12
|
readonly warningMessage?: string;
|
|
12
13
|
};
|
|
13
|
-
export declare const Switch: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({ disabled, infoMessage, label, loading, name, onChange: onChangeProp, warningMessage, }: SwitchProps<TFieldValues, TName>) => ReactElement;
|
|
14
|
+
export declare const Switch: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({ disabled, icon, infoMessage, label, loading, name, onChange: onChangeProp, warningMessage, }: SwitchProps<TFieldValues, TName>) => ReactElement;
|