@gen-epix/ui-core-form 4.1.0 → 4.3.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.
Files changed (37) hide show
  1. package/dist/_chunks/Autocomplete.js +86 -84
  2. package/dist/_chunks/Autocomplete.js.map +1 -1
  3. package/dist/_chunks/DatePicker.js +26 -26
  4. package/dist/_chunks/FileUpload.js +7 -7
  5. package/dist/_chunks/FormUtil.js +4 -1
  6. package/dist/_chunks/FormUtil.js.map +1 -1
  7. package/dist/_chunks/RichTextEditor.js +7658 -4335
  8. package/dist/_chunks/RichTextEditor.js.map +1 -1
  9. package/dist/_chunks/TransferList.js +59 -59
  10. package/dist/_chunks/TransferList.js.map +1 -1
  11. package/dist/components/fields/Autocomplete/Autocomplete.d.ts +6 -3
  12. package/dist/components/fields/CheckboxGroup/index.js +14 -14
  13. package/dist/components/fields/DateRangePicker/index.js +39 -39
  14. package/dist/components/fields/DateRangePicker/index.js.map +1 -1
  15. package/dist/components/fields/NumberField/index.js +29 -29
  16. package/dist/components/fields/NumberField/index.js.map +1 -1
  17. package/dist/components/fields/NumberRangeInput/index.js +34 -34
  18. package/dist/components/fields/RadioGroup/index.js +7 -7
  19. package/dist/components/fields/Select/index.js +34 -22
  20. package/dist/components/fields/Select/index.js.map +1 -1
  21. package/dist/components/fields/Switch/Switch.d.ts +3 -2
  22. package/dist/components/fields/Switch/index.js +50 -40
  23. package/dist/components/fields/Switch/index.js.map +1 -1
  24. package/dist/components/fields/TextField/index.js +19 -19
  25. package/dist/components/fields/ToggleButtonGroup/index.js +7 -7
  26. package/dist/components/helpers/GenericForm/GenericForm.d.ts +1 -1
  27. package/dist/components/helpers/GenericForm/index.js +42 -32
  28. package/dist/components/helpers/GenericForm/index.js.map +1 -1
  29. package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js +5 -4
  30. package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js.map +1 -1
  31. package/dist/locale/en.json +0 -2
  32. package/dist/locale/nl.json +0 -2
  33. package/dist/models/form.d.ts +29 -18
  34. package/dist/models/form.js.map +1 -1
  35. package/package.json +81 -80
  36. package/dist/_chunks/index.esm.js +0 -398
  37. package/dist/_chunks/index.esm.js.map +0 -1
@@ -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 { i as n } from "../../../_chunks/index.esm.js";
4
- import { FormFieldHelperText as r } from "../../helpers/FormFieldHelperText/index.js";
5
- import { FormFieldLoadingIndicator as i } from "../../helpers/FormFieldLoadingIndicator/index.js";
6
- import { t as a } from "../../../_chunks/classnames.js";
7
- import { useCallback as o, useEffect as s, useMemo as c, useRef as l, useState as u } from "react";
8
- import { useTranslation as ee } from "react-i18next";
9
- import { Box as te, FormControl as ne, FormHelperText as re, IconButton as d, InputAdornment as f, Slider as p, TextField as ie } from "@mui/material";
10
- import m from "@mui/icons-material/Clear";
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(a(), 1), ae = 250, b = ({ autocomplete: e, disabled: a = !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 } = ee(), { formState: { errors: M }, register: N, subscribe: P } = n(), F = t.getFieldErrorMessage(M, w), I = !!F, L = !!A && !I, R = l(null), [z, B] = u(null), [V, H] = u(null), U = l(null), [W, G] = u(!1), K = o((e) => {
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
- s(() => {
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 = c(() => N(w), [w, N]), J = c(() => !(!O || !isFinite(C) || !isFinite(S) || !isFinite(k) || C >= S || (S - C) / k > ae), [
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 = o(async (e) => {
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 = o(async () => {
55
+ ]), X = a(async () => {
56
56
  await Y(null);
57
- }, [Y]), Z = o(async () => {
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 = o(async () => {
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 = o((e, t) => {
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 $ = c(() => /* @__PURE__ */ h(ie, {
88
+ let $ = o(() => /* @__PURE__ */ h(re, {
89
89
  defaultValue: z ?? "",
90
- disabled: a || x,
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: a ? void 0 : /* @__PURE__ */ h(f, {
100
+ endAdornment: i ? void 0 : /* @__PURE__ */ h(p, {
101
101
  position: "end",
102
- children: /* @__PURE__ */ h(d, {
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(m, {})
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 && !a,
115
+ required: D && !i,
116
116
  shrink: W
117
117
  }
118
118
  },
119
119
  variant: "outlined"
120
120
  }), [
121
121
  e,
122
- a,
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(ne, {
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(te, {
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(p, {
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(i, {}),
170
- /* @__PURE__ */ h(re, { children: /* @__PURE__ */ h(r, {
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":"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"}
@@ -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 { a as r, i, t as a } from "../../../_chunks/index.esm.js";
4
- import { FormFieldHelperText as o } from "../../helpers/FormFieldHelperText/index.js";
5
- import { FormFieldLoadingIndicator as s } from "../../helpers/FormFieldLoadingIndicator/index.js";
6
- import { h as c, p as l, t as u } from "../../../_chunks/isObjectLike.js";
7
- import { t as d } from "../../../_chunks/isEqual.js";
8
- import { useCallback as f, useId as p, useRef as m } from "react";
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 = l(), r = u(), i = "[object Number]";
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 = c().isFinite;
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(d(), 1), j = /* @__PURE__ */ e(O(), 1), M = /* @__PURE__ */ e(k(), 1), N = ({ disabled: e = !1, infoMessage: t, label: c, loading: l = !1, max: u, min: d, name: O, onChange: k, required: N = !1, warningMessage: P }) => {
28
- let F = (0, M.default)(d) && (0, M.default)(u), I = C(), { t: L } = h(), { control: R, formState: { errors: z } } = i(), B = n.getFieldErrorMessage(z, O), V = !!B, H = m(null), U = p(), W = r({
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 = f((e, t) => {
31
+ }), G = l((e, t) => {
32
32
  (0, A.default)(W, e) || (k && k(e), t(e));
33
- }, [k, W]), K = f((e) => (t, n) => {
33
+ }, [k, W]), K = l((e) => (t, n) => {
34
34
  G(n, e);
35
- }, [G]), q = f(({ field: { onBlur: n, onChange: r, ref: i, value: a } }) => {
36
- i({ focus: () => {
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 = a?.[0], p = a?.[1], m = (e) => {
40
- e.target.value === "" ? G([null, p], r) : (0, M.default)(+e.target.value) && G([+e.target.value, p], r);
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], r) : (0, M.default)(+e.target.value) && G([f, +e.target.value], r);
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], r) : f < d ? G([d, p], r) : f > u ? G([u, u], r) : (0, j.default)(p) && f > p && G([p, f], r), n();
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], r) : p > u ? G([f, u], r) : p < d ? G([d, d], r) : (0, j.default)(f) && p < f && G([p, f], r), n();
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], r);
48
+ G([null, null], l);
49
49
  };
50
50
  return /* @__PURE__ */ E(g, {
51
51
  ...D.createAttributes("RangeSlider", {
52
- label: c,
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
- !l && /* @__PURE__ */ E(g, {
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 || l,
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: [c, !e && /* @__PURE__ */ T(b, {
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: u,
120
- min: d,
119
+ max: s,
120
+ min: c,
121
121
  onBlur: n,
122
- onChange: K(r),
122
+ onChange: K(l),
123
123
  slotProps: { input: { "aria-label": L`Value` } },
124
- value: a,
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
- !!l && /* @__PURE__ */ T(s, { inline: !0 }),
151
+ !!o && /* @__PURE__ */ T(i, { inline: !0 }),
152
152
  /* @__PURE__ */ T(v, {
153
153
  sx: { ml: 0 },
154
- children: /* @__PURE__ */ T(o, {
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(a, {
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 { i as t, t as n } from "../../../_chunks/index.esm.js";
3
- import { FormFieldHelperText as r } from "../../helpers/FormFieldHelperText/index.js";
4
- import { useCallback as i, useId as a, useRef as o } from "react";
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 = a(), { control: E, formState: { errors: D } } = t(), O = e.getFieldErrorMessage(D, y), k = o(null), A = !!O, j = i((e) => (t, n) => {
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 = i(({ field: { onBlur: e, onChange: t, ref: n, value: r } }) => (n({ focus: () => {
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(n, {
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(r, {
59
+ children: /* @__PURE__ */ p(t, {
60
60
  errorMessage: O,
61
61
  infoMessage: _,
62
62
  noIndent: !0,
@@ -1,34 +1,35 @@
1
1
  import { n as e } from "../../../_chunks/rolldown-runtime.js";
2
2
  import { t } from "../../../_chunks/FormUtil.js";
3
- import { i as n, t as r } from "../../../_chunks/index.esm.js";
4
- import { FormFieldHelperText as i } from "../../helpers/FormFieldHelperText/index.js";
5
- import { FormFieldLoadingIndicator as a } from "../../helpers/FormFieldLoadingIndicator/index.js";
6
- import { t as o } from "../../../_chunks/classnames.js";
7
- import { useCallback as s, useId as c, useMemo as l, useRef as u } from "react";
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(o(), 1), O = ({ disabled: e = !1, infoMessage: o, 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 } } = n(), z = t.getFieldErrorMessage(R, j), B = u(null), V = c(), H = c(), U = c(), W = !!z, G = !!F && !W, K = l(() => {
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 = s((e) => K.get(e)?.disabled, [K]), J = s((e) => (Array.isArray(e) ? e : [e]).map((e) => K.get(e)?.label).join(", "), [K]), Y = s((e) => (t) => {
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 = s(({ field: { onBlur: t, onChange: n, ref: r, value: a } }) => {
23
- r({ focus: () => {
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(n)({ target: { value: A ? [] : "" } });
27
+ Y(r)({ target: { value: A ? [] : "" } });
28
28
  };
29
29
  return /* @__PURE__ */ T(C, { children: [
30
30
  /* @__PURE__ */ w(_, {
31
31
  className: (0, D.default)({ "Mui-warning": G }),
32
+ disabled: e,
32
33
  error: W,
33
34
  htmlFor: V,
34
35
  id: H,
@@ -62,28 +63,39 @@ var D = /* @__PURE__ */ e(o(), 1), O = ({ disabled: e = !1, infoMessage: o, labe
62
63
  "aria-labelledby": H,
63
64
  className: (0, D.default)({ "Mui-warning": G }),
64
65
  id: V,
65
- ref: B,
66
- required: P && !e
66
+ ref: B
67
67
  },
68
68
  multiple: A,
69
69
  onBlur: t,
70
- onChange: Y(n),
70
+ onChange: Y(r),
71
71
  renderValue: J,
72
- required: P,
73
- value: a ?? (A ? [] : ""),
72
+ value: o ?? (A ? [] : ""),
74
73
  children: N.map((e) => /* @__PURE__ */ T(y, {
75
74
  disabled: q(e.value),
76
75
  value: e.value,
77
- children: [A && /* @__PURE__ */ w(f, { checked: a.includes(e.value) }), /* @__PURE__ */ w(v, { primary: e.label })]
76
+ children: [A && /* @__PURE__ */ w(f, { checked: o.includes(e.value) }), /* @__PURE__ */ w(v, {
77
+ primary: e.label,
78
+ secondary: e.secondaryLabel,
79
+ slotProps: { secondary: { sx: {
80
+ fontSize: "0.875rem",
81
+ fontStyle: "italic"
82
+ } } },
83
+ sx: {
84
+ alignItems: "baseline",
85
+ display: "flex",
86
+ gap: 2,
87
+ justifyContent: "space-between"
88
+ }
89
+ })]
78
90
  }, e.value.toString()))
79
91
  }),
80
92
  /* @__PURE__ */ w(m, {
81
93
  className: (0, D.default)({ "Mui-warning": G }),
82
94
  id: U,
83
95
  sx: { ml: 0 },
84
- children: /* @__PURE__ */ w(i, {
96
+ children: /* @__PURE__ */ w(n, {
85
97
  errorMessage: z,
86
- infoMessage: o,
98
+ infoMessage: i,
87
99
  noIndent: !0,
88
100
  warningMessage: F
89
101
  })
@@ -91,7 +103,7 @@ var D = /* @__PURE__ */ e(o(), 1), O = ({ disabled: e = !1, infoMessage: o, labe
91
103
  ] });
92
104
  }, [
93
105
  e,
94
- o,
106
+ i,
95
107
  z,
96
108
  q,
97
109
  I,
@@ -115,12 +127,12 @@ var D = /* @__PURE__ */ e(o(), 1), O = ({ disabled: e = !1, infoMessage: o, labe
115
127
  name: j
116
128
  }),
117
129
  fullWidth: !0,
118
- children: [/* @__PURE__ */ w(r, {
130
+ children: [/* @__PURE__ */ w(l, {
119
131
  control: L,
120
132
  defaultValue: null,
121
133
  name: j,
122
134
  render: X
123
- }), !!k && /* @__PURE__ */ w(a, {})]
135
+ }), !!k && /* @__PURE__ */ w(r, {})]
124
136
  });
125
137
  };
126
138
  //#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 disabled={disabled}\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 }}\n multiple={multiple}\n onBlur={onBlur}\n onChange={onMuiSelectChange(onChange)}\n renderValue={renderValue}\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;