@gen-epix/ui-core-form 4.0.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 (117) hide show
  1. package/LICENSE +287 -0
  2. package/dist/@types/ui-form.d.ts +2 -0
  3. package/dist/@types/vite-env.d.ts +2 -0
  4. package/dist/@types/yup.d.ts +30 -0
  5. package/dist/_chunks/Autocomplete.js +229 -0
  6. package/dist/_chunks/Autocomplete.js.map +1 -0
  7. package/dist/_chunks/DatePicker.js +126 -0
  8. package/dist/_chunks/DatePicker.js.map +1 -0
  9. package/dist/_chunks/FormUtil.js +1350 -0
  10. package/dist/_chunks/FormUtil.js.map +1 -0
  11. package/dist/_chunks/RichTextEditor.js +22721 -0
  12. package/dist/_chunks/RichTextEditor.js.map +1 -0
  13. package/dist/_chunks/TransferList.js +453 -0
  14. package/dist/_chunks/TransferList.js.map +1 -0
  15. package/dist/_chunks/UploadButton.js +91 -0
  16. package/dist/_chunks/UploadButton.js.map +1 -0
  17. package/dist/_chunks/classnames.js +33 -0
  18. package/dist/_chunks/classnames.js.map +1 -0
  19. package/dist/_chunks/index.esm.js +348 -0
  20. package/dist/_chunks/index.esm.js.map +1 -0
  21. package/dist/_chunks/isEqual.js +348 -0
  22. package/dist/_chunks/isEqual.js.map +1 -0
  23. package/dist/_chunks/isObjectLike.js +304 -0
  24. package/dist/_chunks/isObjectLike.js.map +1 -0
  25. package/dist/_chunks/isValid.js +28 -0
  26. package/dist/_chunks/isValid.js.map +1 -0
  27. package/dist/_chunks/rolldown-runtime.js +13 -0
  28. package/dist/_chunks/sv.js +434 -0
  29. package/dist/_chunks/sv.js.map +1 -0
  30. package/dist/components/fields/Autocomplete/Autocomplete.d.ts +19 -0
  31. package/dist/components/fields/Autocomplete/AutocompleteSelectAllContext.d.ts +2 -0
  32. package/dist/components/fields/Autocomplete/AutocompleteSelectAllPaper.d.ts +2 -0
  33. package/dist/components/fields/Autocomplete/index.d.ts +1 -0
  34. package/dist/components/fields/Autocomplete/index.js +2 -0
  35. package/dist/components/fields/CheckboxGroup/CheckboxGroup.d.ts +18 -0
  36. package/dist/components/fields/CheckboxGroup/index.d.ts +1 -0
  37. package/dist/components/fields/CheckboxGroup/index.js +114 -0
  38. package/dist/components/fields/CheckboxGroup/index.js.map +1 -0
  39. package/dist/components/fields/DatePicker/DatePicker.d.ts +15 -0
  40. package/dist/components/fields/DatePicker/DatePickerInputAdornment.d.ts +8 -0
  41. package/dist/components/fields/DatePicker/index.d.ts +1 -0
  42. package/dist/components/fields/DatePicker/index.js +2 -0
  43. package/dist/components/fields/DateRangePicker/DateRangePicker.d.ts +17 -0
  44. package/dist/components/fields/DateRangePicker/index.d.ts +1 -0
  45. package/dist/components/fields/DateRangePicker/index.js +1648 -0
  46. package/dist/components/fields/DateRangePicker/index.js.map +1 -0
  47. package/dist/components/fields/NumberField/NumberField.d.ts +19 -0
  48. package/dist/components/fields/NumberField/index.d.ts +1 -0
  49. package/dist/components/fields/NumberField/index.js +180 -0
  50. package/dist/components/fields/NumberField/index.js.map +1 -0
  51. package/dist/components/fields/NumberRangeInput/NumberRangeInput.d.ts +15 -0
  52. package/dist/components/fields/NumberRangeInput/index.d.ts +1 -0
  53. package/dist/components/fields/NumberRangeInput/index.js +192 -0
  54. package/dist/components/fields/NumberRangeInput/index.js.map +1 -0
  55. package/dist/components/fields/RadioGroup/RadioGroup.d.ts +16 -0
  56. package/dist/components/fields/RadioGroup/index.d.ts +1 -0
  57. package/dist/components/fields/RadioGroup/index.js +72 -0
  58. package/dist/components/fields/RadioGroup/index.js.map +1 -0
  59. package/dist/components/fields/RichTextEditor/RichTextEditor.d.ts +13 -0
  60. package/dist/components/fields/RichTextEditor/RichTextEditorContent.d.ts +4 -0
  61. package/dist/components/fields/RichTextEditor/index.d.ts +2 -0
  62. package/dist/components/fields/RichTextEditor/index.js +2 -0
  63. package/dist/components/fields/RichTextEditor/useRichTextEditorExtensions.d.ts +10 -0
  64. package/dist/components/fields/Select/Select.d.ts +16 -0
  65. package/dist/components/fields/Select/index.d.ts +1 -0
  66. package/dist/components/fields/Select/index.js +129 -0
  67. package/dist/components/fields/Select/index.js.map +1 -0
  68. package/dist/components/fields/Switch/Switch.d.ts +13 -0
  69. package/dist/components/fields/Switch/index.d.ts +1 -0
  70. package/dist/components/fields/Switch/index.js +68 -0
  71. package/dist/components/fields/Switch/index.js.map +1 -0
  72. package/dist/components/fields/TextField/TextField.d.ts +18 -0
  73. package/dist/components/fields/TextField/index.d.ts +1 -0
  74. package/dist/components/fields/TextField/index.js +108 -0
  75. package/dist/components/fields/TextField/index.js.map +1 -0
  76. package/dist/components/fields/ToggleButtonGroup/ToggleButtonGroup.d.ts +14 -0
  77. package/dist/components/fields/ToggleButtonGroup/index.d.ts +1 -0
  78. package/dist/components/fields/ToggleButtonGroup/index.js +57 -0
  79. package/dist/components/fields/ToggleButtonGroup/index.js.map +1 -0
  80. package/dist/components/fields/TransferList/TransferList.d.ts +16 -0
  81. package/dist/components/fields/TransferList/index.d.ts +1 -0
  82. package/dist/components/fields/TransferList/index.js +2 -0
  83. package/dist/components/fields/UploadButton/UploadButton.d.ts +15 -0
  84. package/dist/components/fields/UploadButton/index.d.ts +1 -0
  85. package/dist/components/fields/UploadButton/index.js +2 -0
  86. package/dist/components/helpers/FormFieldHelperText/FormFieldHelperText.d.ts +8 -0
  87. package/dist/components/helpers/FormFieldHelperText/index.d.ts +1 -0
  88. package/dist/components/helpers/FormFieldHelperText/index.js +50 -0
  89. package/dist/components/helpers/FormFieldHelperText/index.js.map +1 -0
  90. package/dist/components/helpers/FormFieldLoadingIndicator/FormFieldLoadingIndicator.d.ts +4 -0
  91. package/dist/components/helpers/FormFieldLoadingIndicator/index.d.ts +1 -0
  92. package/dist/components/helpers/FormFieldLoadingIndicator/index.js +16 -0
  93. package/dist/components/helpers/FormFieldLoadingIndicator/index.js.map +1 -0
  94. package/dist/components/helpers/GenericForm/GenericForm.d.ts +18 -0
  95. package/dist/components/helpers/GenericForm/index.d.ts +1 -0
  96. package/dist/components/helpers/GenericForm/index.js +156 -0
  97. package/dist/components/helpers/GenericForm/index.js.map +1 -0
  98. package/dist/hooks/useIsFormFieldRequiredFromSchema/index.d.ts +1 -0
  99. package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js +18 -0
  100. package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js.map +1 -0
  101. package/dist/hooks/useIsFormFieldRequiredFromSchema/useIsFormFieldRequiredFromSchema.d.ts +4 -0
  102. package/dist/locale/en.json +97 -0
  103. package/dist/locale/nl.json +97 -0
  104. package/dist/models/form.d.ts +112 -0
  105. package/dist/models/form.js +8 -0
  106. package/dist/models/form.js.map +1 -0
  107. package/dist/setup/setup.d.ts +1 -0
  108. package/dist/setup/setup.js +166 -0
  109. package/dist/setup/setup.js.map +1 -0
  110. package/dist/utils/FormUtil/FormUtil.d.ts +19 -0
  111. package/dist/utils/FormUtil/index.d.ts +1 -0
  112. package/dist/utils/FormUtil/index.js +2 -0
  113. package/dist/utils/SchemaUtil/SchemaUtil.d.ts +9 -0
  114. package/dist/utils/SchemaUtil/index.d.ts +1 -0
  115. package/dist/utils/SchemaUtil/index.js +30 -0
  116. package/dist/utils/SchemaUtil/index.js.map +1 -0
  117. package/package.json +207 -0
@@ -0,0 +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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"}
@@ -0,0 +1,15 @@
1
+ import { ReactElement } from 'react';
2
+ import { FieldValues, Path } from 'react-hook-form';
3
+ export type NumberRangeInputProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {
4
+ readonly disabled?: boolean;
5
+ readonly infoMessage?: string;
6
+ readonly label: string;
7
+ readonly loading?: boolean;
8
+ readonly max: number;
9
+ readonly min: number;
10
+ readonly name: TName;
11
+ readonly onChange?: (value: number | number[]) => void;
12
+ readonly required?: boolean;
13
+ readonly warningMessage?: string;
14
+ };
15
+ export declare const NumberRangeInput: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({ disabled, infoMessage, label, loading, max, min, name, onChange: onChangeProp, required, warningMessage, }: NumberRangeInputProps<TFieldValues, TName>) => ReactElement;
@@ -0,0 +1 @@
1
+ export * from './NumberRangeInput';
@@ -0,0 +1,192 @@
1
+ import { n as e, t } from "../../../_chunks/rolldown-runtime.js";
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";
9
+ import { useTranslation as h } from "react-i18next";
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
+ import w from "@mui/icons-material/Clear";
12
+ import { jsx as T, jsxs as E } from "react/jsx-runtime";
13
+ import { TestIdUtil as D } from "@gen-epix/ui-core/utils/TestIdUtil";
14
+ //#region ../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/isNumber.js
15
+ var O = /* @__PURE__ */ t(((e, t) => {
16
+ var n = l(), r = u(), i = "[object Number]";
17
+ function a(e) {
18
+ return typeof e == "number" || r(e) && n(e) == i;
19
+ }
20
+ t.exports = a;
21
+ })), k = /* @__PURE__ */ t(((e, t) => {
22
+ var n = c().isFinite;
23
+ function r(e) {
24
+ return typeof e == "number" && n(e);
25
+ }
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({
29
+ control: R,
30
+ name: O
31
+ }), G = f((e, t) => {
32
+ (0, A.default)(W, e) || (k && k(e), t(e));
33
+ }, [k, W]), K = f((e) => (t, n) => {
34
+ G(n, e);
35
+ }, [G]);
36
+ return /* @__PURE__ */ T(a, {
37
+ control: R,
38
+ defaultValue: null,
39
+ name: O,
40
+ render: f(({ field: { onBlur: n, onChange: r, ref: i, value: a } }) => {
41
+ i({ focus: () => {
42
+ H?.current?.focus();
43
+ } });
44
+ let f = a?.[0], p = a?.[1], m = (e) => {
45
+ e.target.value === "" ? G([null, p], r) : (0, M.default)(+e.target.value) && G([+e.target.value, p], r);
46
+ }, h = (e) => {
47
+ e.target.value === "" ? G([f, null], r) : (0, M.default)(+e.target.value) && G([f, +e.target.value], r);
48
+ }, C = () => {
49
+ 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();
50
+ }, k = () => {
51
+ 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();
52
+ }, A = () => {
53
+ G([null, null], r);
54
+ };
55
+ return /* @__PURE__ */ E(g, {
56
+ ...D.createAttributes("RangeSlider", {
57
+ label: c,
58
+ name: O
59
+ }),
60
+ sx: {
61
+ "&:hover legend button, &:focus-within legend button": { display: "initial" },
62
+ "legend button": { display: "none" }
63
+ },
64
+ children: [
65
+ !l && /* @__PURE__ */ E(g, {
66
+ sx: {
67
+ display: "grid",
68
+ gridTemplateColumns: "max-content auto max-content",
69
+ position: "relative"
70
+ },
71
+ children: [
72
+ /* @__PURE__ */ T(g, {
73
+ sx: {
74
+ marginTop: 4,
75
+ width: I.spacing(F ? 6 : 16)
76
+ },
77
+ children: /* @__PURE__ */ T(x, {
78
+ fullWidth: !0,
79
+ inputProps: {
80
+ ...D.createAttributes("RangeSlider-from-input"),
81
+ "aria-labelledby": U,
82
+ name: `${O}-from}`,
83
+ variant: "outlined"
84
+ },
85
+ onBlur: C,
86
+ onChange: m,
87
+ placeholder: L`From`,
88
+ size: "small",
89
+ value: f ?? ""
90
+ })
91
+ }),
92
+ /* @__PURE__ */ E(_, {
93
+ error: V,
94
+ fullWidth: !0,
95
+ sx: { position: "initial" },
96
+ children: [/* @__PURE__ */ E(y, {
97
+ component: "legend",
98
+ disabled: e || l,
99
+ id: U,
100
+ required: N,
101
+ sx: {
102
+ left: 0,
103
+ position: "absolute"
104
+ },
105
+ children: [c, !e && /* @__PURE__ */ T(b, {
106
+ ...D.createAttributes("RangeSlider-reset"),
107
+ "aria-label": L`Clear number range`,
108
+ onClick: A,
109
+ sx: {
110
+ "& svg": { fontSize: "16px" },
111
+ position: "absolute",
112
+ top: "-10px"
113
+ },
114
+ tabIndex: -1,
115
+ children: /* @__PURE__ */ T(w, {})
116
+ })]
117
+ }), /* @__PURE__ */ T(g, {
118
+ sx: {
119
+ marginTop: 4,
120
+ marginX: 3
121
+ },
122
+ children: F && /* @__PURE__ */ T(S, {
123
+ color: "primary",
124
+ max: u,
125
+ min: d,
126
+ onBlur: n,
127
+ onChange: K(r),
128
+ slotProps: { input: { "aria-label": L`Value` } },
129
+ value: a,
130
+ valueLabelDisplay: "off"
131
+ })
132
+ })]
133
+ }),
134
+ /* @__PURE__ */ T(g, {
135
+ sx: {
136
+ marginTop: 4,
137
+ width: I.spacing(F ? 6 : 16)
138
+ },
139
+ children: /* @__PURE__ */ T(x, {
140
+ fullWidth: !0,
141
+ inputProps: {
142
+ ...D.createAttributes("RangeSlider-to-input"),
143
+ "aria-labelledby": U,
144
+ name: `${O}-to}`,
145
+ variant: "outlined"
146
+ },
147
+ onBlur: k,
148
+ onChange: h,
149
+ placeholder: L`To`,
150
+ size: "small",
151
+ value: p ?? ""
152
+ })
153
+ })
154
+ ]
155
+ }),
156
+ !!l && /* @__PURE__ */ T(s, { inline: !0 }),
157
+ /* @__PURE__ */ T(v, {
158
+ sx: { ml: 0 },
159
+ children: /* @__PURE__ */ T(o, {
160
+ errorMessage: B,
161
+ infoMessage: t,
162
+ noIndent: !0,
163
+ warningMessage: P
164
+ })
165
+ })
166
+ ]
167
+ });
168
+ }, [
169
+ e,
170
+ B,
171
+ G,
172
+ V,
173
+ U,
174
+ t,
175
+ c,
176
+ l,
177
+ u,
178
+ d,
179
+ O,
180
+ K,
181
+ N,
182
+ F,
183
+ L,
184
+ P,
185
+ I
186
+ ])
187
+ });
188
+ };
189
+ //#endregion
190
+ export { N as NumberRangeInput };
191
+
192
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/isNumber.js","../../../../../../node_modules/.pnpm/lodash@4.18.1/node_modules/lodash/isFinite.js","../../../../src/components/fields/NumberRangeInput/NumberRangeInput.tsx"],"sourcesContent":["var baseGetTag = require('./_baseGetTag'),\n isObjectLike = require('./isObjectLike');\n\n/** `Object#toString` result references. */\nvar numberTag = '[object Number]';\n\n/**\n * Checks if `value` is classified as a `Number` primitive or object.\n *\n * **Note:** To exclude `Infinity`, `-Infinity`, and `NaN`, which are\n * classified as numbers, use the `_.isFinite` method.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a number, else `false`.\n * @example\n *\n * _.isNumber(3);\n * // => true\n *\n * _.isNumber(Number.MIN_VALUE);\n * // => true\n *\n * _.isNumber(Infinity);\n * // => true\n *\n * _.isNumber('3');\n * // => false\n */\nfunction isNumber(value) {\n return typeof value == 'number' ||\n (isObjectLike(value) && baseGetTag(value) == numberTag);\n}\n\nmodule.exports = isNumber;\n","var root = require('./_root');\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeIsFinite = root.isFinite;\n\n/**\n * Checks if `value` is a finite primitive number.\n *\n * **Note:** This method is based on\n * [`Number.isFinite`](https://mdn.io/Number/isFinite).\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a finite number, else `false`.\n * @example\n *\n * _.isFinite(3);\n * // => true\n *\n * _.isFinite(Number.MIN_VALUE);\n * // => true\n *\n * _.isFinite(Infinity);\n * // => false\n *\n * _.isFinite('3');\n * // => false\n */\nfunction isFinite(value) {\n return typeof value == 'number' && nativeIsFinite(value);\n}\n\nmodule.exports = isFinite;\n","import type {\n ChangeEvent,\n ReactElement,\n} from 'react';\nimport {\n useCallback,\n useId,\n useRef,\n} from 'react';\nimport {\n Box,\n FormControl,\n FormHelperText,\n FormLabel,\n IconButton,\n Input,\n Slider,\n useTheme,\n} 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 useWatch,\n} from 'react-hook-form';\nimport { useTranslation } from 'react-i18next';\nimport isEqual from 'lodash/isEqual';\nimport isNumber from 'lodash/isNumber';\nimport isFinite from 'lodash/isFinite';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\n\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nexport type NumberRangeInputProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {\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 | number[]) => void;\n readonly required?: boolean;\n readonly warningMessage?: string;\n};\n\nexport const NumberRangeInput = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({\n disabled = false,\n infoMessage,\n label,\n loading = false,\n max,\n min,\n name,\n onChange: onChangeProp,\n required = false,\n warningMessage,\n}: NumberRangeInputProps<TFieldValues, TName>): ReactElement => {\n const shouldShowSlider = isFinite(min) && isFinite(max);\n const theme = useTheme();\n\n const { t } = useTranslation();\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const hasError = !!errorMessage;\n const inputRef = useRef<HTMLInputElement>(null);\n const id = useId();\n\n const outerValue = useWatch({ control, name }) as number[];\n\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const handleChange = useCallback((newValue: number[], onChange: (...event: any[]) => void) => {\n if (isEqual(outerValue, newValue)) {\n return;\n }\n if (onChangeProp) {\n onChangeProp(newValue);\n }\n onChange(newValue);\n }, [onChangeProp, outerValue]);\n\n const onMuiRangeSliderChange = useCallback((onChange: ControllerRenderProps<TFieldValues, TName>['onChange']) =>\n (_event: Event, newValue: number | number[]) => {\n handleChange(newValue as number[], onChange);\n }\n , [handleChange]);\n\n const renderController = useCallback(({ field: { onBlur, onChange, ref, value } }: UseControllerReturn<TFieldValues, TName>) => {\n ref({\n focus: () => {\n inputRef?.current?.focus();\n },\n });\n\n const leftValue = (value as [number, number])?.[0];\n const rightValue = (value as [number, number])?.[1];\n\n const onLeftValueChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (event.target.value === '') {\n handleChange([null, rightValue], onChange);\n } else if (isFinite(+event.target.value)) {\n handleChange([+event.target.value, rightValue], onChange);\n }\n };\n const onRightValueChange = (event: ChangeEvent<HTMLInputElement>) => {\n if (event.target.value === '') {\n handleChange([leftValue, null], onChange);\n } else if (isFinite(+event.target.value)) {\n handleChange([leftValue, +event.target.value], onChange);\n }\n };\n\n const onLeftValueBlur = () => {\n if (leftValue === null || !isFinite(leftValue)) {\n handleChange([null, rightValue], onChange);\n } else if (leftValue < min) {\n handleChange([min, rightValue], onChange);\n } else if (leftValue > max) {\n handleChange([max, max], onChange);\n } else if (isNumber(rightValue) && leftValue > rightValue) {\n handleChange([rightValue, leftValue], onChange);\n }\n\n onBlur();\n };\n const onRightValueBlur = () => {\n if (rightValue === null || !isFinite(rightValue)) {\n handleChange([leftValue, null], onChange);\n } else if (rightValue > max) {\n handleChange([leftValue, max], onChange);\n } else if (rightValue < min) {\n handleChange([min, min], onChange);\n } else if (isNumber(leftValue) && rightValue < leftValue) {\n handleChange([rightValue, leftValue], onChange);\n }\n\n onBlur();\n };\n\n const onResetButtonClick = () => {\n handleChange([null, null], onChange);\n };\n\n return (\n <Box\n {...TestIdUtil.createAttributes('RangeSlider', { label, name })}\n sx={{\n '&:hover legend button, &:focus-within legend button': {\n display: 'initial',\n },\n 'legend button': {\n display: 'none',\n },\n }}\n >\n { !loading && (\n <Box\n sx={{\n display: 'grid',\n gridTemplateColumns: 'max-content auto max-content',\n position: 'relative',\n }}\n >\n <Box\n sx={{\n marginTop: 4,\n width: theme.spacing(shouldShowSlider ? 6 : 16),\n }}\n >\n <Input\n fullWidth\n inputProps={{\n ...TestIdUtil.createAttributes('RangeSlider-from-input'),\n 'aria-labelledby': id,\n name: `${name}-from}`,\n variant: 'outlined',\n }}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onBlur={onLeftValueBlur}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onChange={onLeftValueChange}\n placeholder={t`From`}\n size={'small'}\n value={leftValue ?? ''}\n />\n </Box>\n <FormControl\n error={hasError}\n fullWidth\n sx={{\n position: 'initial',\n }}\n >\n <FormLabel\n component={'legend'}\n disabled={disabled || loading}\n id={id}\n required={required}\n sx={{\n left: 0,\n position: 'absolute',\n }}\n >\n {label}\n {!disabled && (\n <IconButton\n {...TestIdUtil.createAttributes('RangeSlider-reset')}\n aria-label={t`Clear number range`}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onClick={onResetButtonClick}\n sx={{\n '& svg': {\n fontSize: '16px',\n },\n position: 'absolute',\n top: '-10px',\n }}\n tabIndex={-1}\n >\n <ClearIcon />\n </IconButton>\n )}\n </FormLabel>\n <Box\n sx={{\n marginTop: 4,\n marginX: 3,\n }}\n >\n {shouldShowSlider && (\n <Slider\n color={'primary'}\n max={max}\n min={min}\n onBlur={onBlur}\n onChange={onMuiRangeSliderChange(onChange)}\n slotProps={{\n input: {\n 'aria-label': t`Value`,\n },\n }}\n value={value as [number, number]}\n valueLabelDisplay={'off'}\n />\n )}\n </Box>\n </FormControl>\n <Box\n sx={{\n marginTop: 4,\n width: theme.spacing(shouldShowSlider ? 6 : 16),\n }}\n >\n <Input\n fullWidth\n inputProps={{\n ...TestIdUtil.createAttributes('RangeSlider-to-input'),\n 'aria-labelledby': id,\n name: `${name}-to}`,\n variant: 'outlined',\n }}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onBlur={onRightValueBlur}\n // eslint-disable-next-line @eslint-react/kit/jsx-no-bind\n onChange={onRightValueChange}\n placeholder={t`To`}\n size={'small'}\n value={rightValue ?? ''}\n />\n </Box>\n </Box>\n )}\n { !!loading && <FormFieldLoadingIndicator inline />}\n <FormHelperText sx={{ ml: 0 }}>\n <FormFieldHelperText\n errorMessage={errorMessage}\n infoMessage={infoMessage}\n noIndent\n warningMessage={warningMessage}\n />\n </FormHelperText>\n </Box>\n );\n }, [disabled, errorMessage, handleChange, hasError, id, infoMessage, label, loading, max, min, name, onMuiRangeSliderChange, required, shouldShowSlider, t, warningMessage, theme]);\n\n return (\n <Controller\n control={control}\n defaultValue={null}\n name={name}\n render={renderController}\n />\n );\n};\n"],"x_google_ignoreList":[0,1],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from 'react';
2
+ import { FieldValues, Path } from 'react-hook-form';
3
+ import { RadioButtonOption } from '../../../models/form';
4
+ export type RadioGroupProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {
5
+ readonly disabled?: boolean;
6
+ readonly infoMessage?: string;
7
+ readonly label: string;
8
+ readonly loading?: boolean;
9
+ readonly name: TName;
10
+ readonly onChange?: (value: string) => void;
11
+ readonly options: RadioButtonOption[];
12
+ readonly required?: boolean;
13
+ readonly row?: boolean;
14
+ readonly warningMessage?: string;
15
+ };
16
+ export declare const RadioGroup: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({ disabled, infoMessage, label, name, onChange: onChangeProp, options, required, row, warningMessage, }: RadioGroupProps<TFieldValues, TName>) => ReactElement;
@@ -0,0 +1 @@
1
+ export * from './RadioGroup';
@@ -0,0 +1,72 @@
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";
5
+ import { FormControl as s, FormControlLabel as c, FormHelperText as l, FormLabel as u, Radio as d, RadioGroup as f } from "@mui/material";
6
+ import { jsx as p, jsxs as m } from "react/jsx-runtime";
7
+ import { TestIdUtil as h } from "@gen-epix/ui-core/utils/TestIdUtil";
8
+ //#region src/components/fields/RadioGroup/RadioGroup.tsx
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) => {
11
+ b && b(n), e(n);
12
+ }, [b]), M = i(({ field: { onBlur: e, onChange: t, ref: n, value: r } }) => (n({ focus: () => {
13
+ k?.current?.focus();
14
+ } }), /* @__PURE__ */ p(f, {
15
+ "aria-labelledby": T,
16
+ onBlur: e,
17
+ onChange: j(t),
18
+ row: C,
19
+ value: r,
20
+ children: x.map((e, t) => /* @__PURE__ */ p(c, {
21
+ ...h.createAttributes("RadioGroup-option", {
22
+ code: e.value.toString(),
23
+ description: e.label
24
+ }),
25
+ control: /* @__PURE__ */ p(d, { slotProps: { input: { ref: t === 0 ? k : void 0 } } }),
26
+ disabled: g,
27
+ label: e.label,
28
+ value: e.value
29
+ }, e.value.toString()))
30
+ })), [
31
+ T,
32
+ j,
33
+ C,
34
+ x,
35
+ g
36
+ ]);
37
+ return /* @__PURE__ */ m(s, {
38
+ error: A,
39
+ ...h.createAttributes("RadioGroup", {
40
+ label: v,
41
+ name: y
42
+ }),
43
+ fullWidth: !0,
44
+ children: [
45
+ /* @__PURE__ */ p(u, {
46
+ component: "legend",
47
+ id: T,
48
+ required: S,
49
+ children: v
50
+ }),
51
+ /* @__PURE__ */ p(n, {
52
+ control: E,
53
+ defaultValue: null,
54
+ name: y,
55
+ render: M
56
+ }),
57
+ /* @__PURE__ */ p(l, {
58
+ sx: { ml: 0 },
59
+ children: /* @__PURE__ */ p(r, {
60
+ errorMessage: O,
61
+ infoMessage: _,
62
+ noIndent: !0,
63
+ warningMessage: w
64
+ })
65
+ })
66
+ ]
67
+ });
68
+ };
69
+ //#endregion
70
+ export { g as RadioGroup };
71
+
72
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","names":[],"sources":["../../../../src/components/fields/RadioGroup/RadioGroup.tsx"],"sourcesContent":["import type {\n ChangeEvent,\n ReactElement,\n} from 'react';\nimport {\n useCallback,\n useId,\n useRef,\n} from 'react';\nimport {\n FormControl,\n FormControlLabel,\n FormHelperText,\n FormLabel,\n RadioGroup as MuiRadioGroup,\n Radio,\n} from '@mui/material';\nimport {\n Controller,\n useFormContext,\n} from 'react-hook-form';\nimport type {\n ControllerRenderProps,\n FieldValues,\n Path,\n UseControllerReturn,\n} from 'react-hook-form';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\n\nimport type { RadioButtonOption } from '../../../models/form';\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\n\nexport type RadioGroupProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {\n readonly disabled?: boolean;\n readonly infoMessage?: string;\n readonly label: string;\n readonly loading?: boolean; // NOT USED YET\n readonly name: TName;\n readonly onChange?: (value: string) => void;\n readonly options: RadioButtonOption[];\n readonly required?: boolean;\n readonly row?: boolean;\n readonly warningMessage?: string;\n};\n\nexport const RadioGroup = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({\n disabled,\n infoMessage,\n label,\n name,\n onChange: onChangeProp,\n options,\n required,\n row,\n warningMessage,\n}: RadioGroupProps<TFieldValues, TName>): ReactElement => {\n const id = useId();\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n\n const inputRef = useRef<HTMLInputElement>(null);\n const hasError = !!errorMessage;\n\n const onMuiRadioGroupChange = useCallback((onChange: ControllerRenderProps<TFieldValues, TName>['onChange']) =>\n (_event: ChangeEvent<unknown>, value: string) => {\n if (onChangeProp) {\n onChangeProp(value);\n }\n onChange(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 return (\n <MuiRadioGroup\n aria-labelledby={id}\n onBlur={onBlur}\n onChange={onMuiRadioGroupChange(onChange)}\n row={row}\n value={value}\n >\n { options.map((option, index) => {\n return (\n <FormControlLabel\n key={option.value.toString()}\n {...TestIdUtil.createAttributes('RadioGroup-option', { code: option.value.toString(), description: option.label })}\n control={(\n <Radio\n slotProps={{\n input: {\n ref: index === 0 ? inputRef : undefined,\n },\n }}\n />\n )}\n disabled={disabled}\n label={option.label}\n value={option.value}\n />\n );\n })}\n </MuiRadioGroup>\n );\n }, [id, onMuiRadioGroupChange, row, options, disabled]);\n\n return (\n <FormControl\n error={hasError}\n {...TestIdUtil.createAttributes('RadioGroup', { label, name })}\n fullWidth\n >\n <FormLabel\n component={'legend'}\n id={id}\n required={required}\n >\n {label}\n </FormLabel>\n <Controller\n control={control}\n defaultValue={null}\n name={name}\n render={renderController}\n />\n <FormHelperText sx={{ ml: 0 }}>\n <FormFieldHelperText\n errorMessage={errorMessage}\n infoMessage={infoMessage}\n noIndent\n warningMessage={warningMessage}\n />\n </FormHelperText>\n </FormControl>\n );\n};\n"],"mappings":";;;;;;;;AA8CA,IAAa,KAAuG,EAClH,aACA,gBACA,UACA,SACA,UAAU,GACV,YACA,aACA,QACA,wBACwD;CACxD,IAAM,IAAK,EAAM,GACX,EAAE,YAAS,WAAW,EAAE,gBAAa,EAA6B,GAClE,IAAe,EAAS,qBAAqB,GAAQ,CAAI,GAEzD,IAAW,EAAyB,IAAI,GACxC,IAAW,CAAC,CAAC,GAEb,IAAwB,GAAa,OACxC,GAA8B,MAAkB;EAI/C,AAHI,KACF,EAAa,CAAK,GAEpB,EAAS,CAAK;CAChB,GACA,CAAC,CAAY,CAAC,GAEV,IAAmB,GAAa,EAAE,OAAO,EAAE,WAAQ,aAAU,QAAK,kBACtE,EAAI,EACF,aAAa;EACX,GAAU,SAAS,MAAM;CAC3B,EACF,CAAC,GAEC,kBAAC,GAAD;EACE,mBAAiB;EACT;EACR,UAAU,EAAsB,CAAQ;EACnC;EACE;YAEL,EAAQ,KAAK,GAAQ,MAEnB,kBAAC,GAAD;GAEE,GAAI,EAAW,iBAAiB,qBAAqB;IAAE,MAAM,EAAO,MAAM,SAAS;IAAG,aAAa,EAAO;GAAM,CAAC;GACjH,SACE,kBAAC,GAAD,EACE,WAAW,EACT,OAAO,EACL,KAAK,MAAU,IAAI,IAAW,KAAA,EAChC,EACF,EACD,CAAA;GAEO;GACV,OAAO,EAAO;GACd,OAAO,EAAO;EACf,GAdM,EAAO,MAAM,SAAS,CAc5B,CAEJ;CACY,CAAA,IAEhB;EAAC;EAAI;EAAuB;EAAK;EAAS;CAAQ,CAAC;CAEtD,OACE,kBAAC,GAAD;EACE,OAAO;EACP,GAAI,EAAW,iBAAiB,cAAc;GAAE;GAAO;EAAK,CAAC;EAC7D,WAAA;YAHF;GAKE,kBAAC,GAAD;IACE,WAAW;IACP;IACM;cAET;GACQ,CAAA;GACX,kBAAC,GAAD;IACW;IACT,cAAc;IACR;IACN,QAAQ;GACT,CAAA;GACD,kBAAC,GAAD;IAAgB,IAAI,EAAE,IAAI,EAAE;cAC1B,kBAAC,GAAD;KACgB;KACD;KACb,UAAA;KACgB;IACjB,CAAA;GACa,CAAA;EACL;;AAEjB"}
@@ -0,0 +1,13 @@
1
+ import { ReactElement } from 'react';
2
+ import { FieldValues, Path } from 'react-hook-form';
3
+ export type RichTextEditorProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {
4
+ readonly disabled?: boolean;
5
+ readonly infoMessage?: string;
6
+ readonly label: string;
7
+ readonly loading?: boolean;
8
+ readonly name: TName;
9
+ readonly onChange?: (value: string) => void;
10
+ readonly required?: boolean;
11
+ readonly warningMessage?: string;
12
+ };
13
+ export declare const RichTextEditor: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({ disabled, infoMessage, label, loading, name, onChange: onChangeProp, required, warningMessage, }: RichTextEditorProps<TFieldValues, TName>) => ReactElement;
@@ -0,0 +1,4 @@
1
+ export type RichTextEditorContentProps = {
2
+ readonly source: string;
3
+ };
4
+ export declare const RichTextEditorContent: ({ source }: RichTextEditorContentProps) => import("react").JSX.Element;
@@ -0,0 +1,2 @@
1
+ export * from './RichTextEditor';
2
+ export * from './RichTextEditorContent';
@@ -0,0 +1,2 @@
1
+ import { n as e, t } from "../../../_chunks/RichTextEditor.js";
2
+ export { e as RichTextEditor, t as RichTextEditorContent };
@@ -0,0 +1,10 @@
1
+ import { EditorOptions } from '@tiptap/core';
2
+ export type UseRichTextEditorExtensionsOptions = {
3
+ /** Placeholder hint to show in the text input area before a user types a message. */
4
+ placeholder?: string;
5
+ };
6
+ /**
7
+ * A hook for providing a default set of useful extensions for the MUI-Tiptap
8
+ * editor.
9
+ */
10
+ export declare const useRichTextEditorExtensions: ({ placeholder, }?: UseRichTextEditorExtensionsOptions) => EditorOptions["extensions"];
@@ -0,0 +1,16 @@
1
+ import { ReactElement } from 'react';
2
+ import { FieldValues, Path } from 'react-hook-form';
3
+ import { SelectOption } from '../../../models/form';
4
+ export type SelectProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>, TMultiple extends boolean> = {
5
+ readonly disabled?: boolean;
6
+ readonly infoMessage?: string;
7
+ readonly label: string;
8
+ readonly loading?: boolean;
9
+ readonly multiple?: TMultiple;
10
+ readonly name: TName;
11
+ readonly onChange?: (value: string) => void;
12
+ readonly options: SelectOption[];
13
+ readonly required?: boolean;
14
+ readonly warningMessage?: string;
15
+ };
16
+ export declare const Select: <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>, TMultiple extends boolean = false>({ disabled, infoMessage, label, loading, multiple, name, onChange: onChangeProp, options, required, warningMessage, }: SelectProps<TFieldValues, TName, TMultiple>) => ReactElement;
@@ -0,0 +1 @@
1
+ export * from './Select';
@@ -0,0 +1,129 @@
1
+ import { n as e } from "../../../_chunks/rolldown-runtime.js";
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";
8
+ import { useTranslation as d } from "react-i18next";
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
+ import S from "@mui/icons-material/Clear";
11
+ import { Fragment as C, jsx as w, jsxs as T } from "react/jsx-runtime";
12
+ import { TestIdUtil as E } from "@gen-epix/ui-core/utils/TestIdUtil";
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(() => {
16
+ let e = /* @__PURE__ */ new Map();
17
+ return N.forEach((t) => {
18
+ e.set(t.value, t);
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) => {
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: () => {
24
+ B?.current?.focus();
25
+ } });
26
+ let s = () => {
27
+ Y(n)({ target: { value: A ? [] : "" } });
28
+ };
29
+ return /* @__PURE__ */ T(C, { children: [
30
+ /* @__PURE__ */ w(_, {
31
+ className: (0, D.default)({ "Mui-warning": G }),
32
+ error: W,
33
+ htmlFor: V,
34
+ id: H,
35
+ required: P && !e,
36
+ children: O
37
+ }),
38
+ /* @__PURE__ */ w(x, {
39
+ disabled: e || k,
40
+ error: W,
41
+ input: /* @__PURE__ */ w(b, {
42
+ endAdornment: e ? void 0 : /* @__PURE__ */ w(g, {
43
+ position: "start",
44
+ sx: {
45
+ position: "absolute",
46
+ right: (e) => e.spacing(2)
47
+ },
48
+ children: /* @__PURE__ */ w(h, {
49
+ ...E.createAttributes("TextField-reset"),
50
+ "aria-label": I`Clear selection`,
51
+ onClick: s,
52
+ sx: { "& svg": { fontSize: "16px" } },
53
+ tabIndex: -1,
54
+ children: /* @__PURE__ */ w(S, {})
55
+ })
56
+ }),
57
+ label: O
58
+ }),
59
+ inputProps: {
60
+ "aria-describedby": U,
61
+ "aria-label": O,
62
+ "aria-labelledby": H,
63
+ className: (0, D.default)({ "Mui-warning": G }),
64
+ id: V,
65
+ ref: B,
66
+ required: P && !e
67
+ },
68
+ multiple: A,
69
+ onBlur: t,
70
+ onChange: Y(n),
71
+ renderValue: J,
72
+ required: P,
73
+ value: a ?? (A ? [] : ""),
74
+ children: N.map((e) => /* @__PURE__ */ T(y, {
75
+ disabled: q(e.value),
76
+ value: e.value,
77
+ children: [A && /* @__PURE__ */ w(f, { checked: a.includes(e.value) }), /* @__PURE__ */ w(v, { primary: e.label })]
78
+ }, e.value.toString()))
79
+ }),
80
+ /* @__PURE__ */ w(m, {
81
+ className: (0, D.default)({ "Mui-warning": G }),
82
+ id: U,
83
+ sx: { ml: 0 },
84
+ children: /* @__PURE__ */ w(i, {
85
+ errorMessage: z,
86
+ infoMessage: o,
87
+ noIndent: !0,
88
+ warningMessage: F
89
+ })
90
+ })
91
+ ] });
92
+ }, [
93
+ e,
94
+ o,
95
+ z,
96
+ q,
97
+ I,
98
+ W,
99
+ G,
100
+ U,
101
+ V,
102
+ O,
103
+ H,
104
+ k,
105
+ A,
106
+ Y,
107
+ N,
108
+ J,
109
+ P,
110
+ F
111
+ ]);
112
+ return /* @__PURE__ */ T(p, {
113
+ ...E.createAttributes("Select", {
114
+ label: O,
115
+ name: j
116
+ }),
117
+ fullWidth: !0,
118
+ children: [/* @__PURE__ */ w(r, {
119
+ control: L,
120
+ defaultValue: null,
121
+ name: j,
122
+ render: X
123
+ }), !!k && /* @__PURE__ */ w(a, {})]
124
+ });
125
+ };
126
+ //#endregion
127
+ export { O as Select };
128
+
129
+ //# sourceMappingURL=index.js.map
@@ -0,0 +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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"}
@@ -0,0 +1,13 @@
1
+ import { ReactElement } from 'react';
2
+ import { FieldValues, Path } from 'react-hook-form';
3
+ export type SwitchProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>> = {
4
+ readonly disabled?: boolean;
5
+ readonly infoMessage?: string;
6
+ readonly label: string;
7
+ readonly loading?: boolean;
8
+ readonly name: TName;
9
+ readonly onChange?: (value: boolean) => void;
10
+ readonly required?: boolean;
11
+ readonly warningMessage?: string;
12
+ };
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;
@@ -0,0 +1 @@
1
+ export * from './Switch';