@gen-epix/ui-core-form 4.0.2 → 4.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/_chunks/Autocomplete.js +86 -84
- package/dist/_chunks/Autocomplete.js.map +1 -1
- package/dist/_chunks/DatePicker.js +26 -26
- package/dist/_chunks/FileUpload.js +73 -0
- package/dist/_chunks/FileUpload.js.map +1 -0
- package/dist/_chunks/FormUtil.js +4 -1
- package/dist/_chunks/FormUtil.js.map +1 -1
- package/dist/_chunks/RichTextEditor.js +7658 -4335
- package/dist/_chunks/RichTextEditor.js.map +1 -1
- package/dist/_chunks/TransferList.js +59 -59
- package/dist/_chunks/TransferList.js.map +1 -1
- package/dist/components/fields/Autocomplete/Autocomplete.d.ts +6 -3
- package/dist/components/fields/CheckboxGroup/index.js +14 -14
- package/dist/components/fields/DateRangePicker/index.js +39 -39
- package/dist/components/fields/DateRangePicker/index.js.map +1 -1
- package/dist/components/fields/{UploadButton/UploadButton.d.ts → FileUpload/FileUpload.d.ts} +2 -2
- package/dist/components/fields/FileUpload/index.d.ts +1 -0
- package/dist/components/fields/FileUpload/index.js +2 -0
- package/dist/components/fields/NumberField/index.js +29 -29
- package/dist/components/fields/NumberField/index.js.map +1 -1
- package/dist/components/fields/NumberRangeInput/index.js +34 -34
- package/dist/components/fields/RadioGroup/index.js +7 -7
- package/dist/components/fields/Select/index.js +32 -19
- package/dist/components/fields/Select/index.js.map +1 -1
- package/dist/components/fields/Switch/Switch.d.ts +3 -2
- package/dist/components/fields/Switch/index.js +50 -40
- package/dist/components/fields/Switch/index.js.map +1 -1
- package/dist/components/fields/TextField/index.js +19 -19
- package/dist/components/fields/ToggleButtonGroup/index.js +7 -7
- package/dist/components/helpers/GenericForm/GenericForm.d.ts +1 -1
- package/dist/components/helpers/GenericForm/index.js +42 -32
- package/dist/components/helpers/GenericForm/index.js.map +1 -1
- package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js +5 -4
- package/dist/hooks/useIsFormFieldRequiredFromSchema/index.js.map +1 -1
- package/dist/models/form.d.ts +31 -19
- package/dist/models/form.js.map +1 -1
- package/package.json +84 -81
- package/dist/_chunks/UploadButton.js +0 -91
- package/dist/_chunks/UploadButton.js.map +0 -1
- package/dist/_chunks/index.esm.js +0 -398
- package/dist/_chunks/index.esm.js.map +0 -1
- package/dist/components/fields/UploadButton/index.d.ts +0 -1
- package/dist/components/fields/UploadButton/index.js +0 -2
|
@@ -1,29 +1,29 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime.js";
|
|
2
2
|
import { t } from "./FormUtil.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import {
|
|
7
|
-
import {
|
|
8
|
-
import { useTranslation as
|
|
9
|
-
import { Autocomplete as
|
|
10
|
-
import { Fragment as
|
|
11
|
-
import { TestIdUtil as
|
|
12
|
-
import
|
|
13
|
-
import
|
|
14
|
-
import
|
|
3
|
+
import { FormFieldHelperText as n } from "../components/helpers/FormFieldHelperText/index.js";
|
|
4
|
+
import { FormFieldLoadingIndicator as r } from "../components/helpers/FormFieldLoadingIndicator/index.js";
|
|
5
|
+
import { t as i } from "./classnames.js";
|
|
6
|
+
import { createContext as a, createElement as o, use as s, useCallback as c, useEffect as l, useMemo as u, useRef as d, useState as ee } from "react";
|
|
7
|
+
import { Controller as te, useFormContext as ne } from "react-hook-form";
|
|
8
|
+
import { useTranslation as re } from "react-i18next";
|
|
9
|
+
import { Autocomplete as ie, Box as f, Checkbox as p, Chip as ae, Divider as m, FormControl as oe, Paper as h, Stack as se, TextField as ce } from "@mui/material";
|
|
10
|
+
import { Fragment as g, jsx as _, jsxs as v } from "react/jsx-runtime";
|
|
11
|
+
import { TestIdUtil as le } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
12
|
+
import ue from "@mui/icons-material/CheckBoxOutlineBlank";
|
|
13
|
+
import y from "@mui/icons-material/CheckBox";
|
|
14
|
+
import b from "@mui/icons-material/IndeterminateCheckBox";
|
|
15
15
|
//#region src/components/fields/Autocomplete/AutocompleteSelectAllContext.tsx
|
|
16
|
-
var
|
|
17
|
-
let n =
|
|
16
|
+
var x = /* @__PURE__ */ e(i(), 1), S = a(null), de = ({ children: e, ...t }) => {
|
|
17
|
+
let n = s(S), r = c(() => {
|
|
18
18
|
if (!n) return;
|
|
19
19
|
let { currentValues: e, enabledOptionValues: t, handleSelectAll: r } = n, i = e.filter((e) => t.includes(e)).length;
|
|
20
20
|
r(t.length > 0 && i === t.length, e);
|
|
21
|
-
}, [n]), i =
|
|
21
|
+
}, [n]), i = c((e) => {
|
|
22
22
|
e.preventDefault();
|
|
23
|
-
}, []), a = n?.currentValues ?? [], o = n?.enabledOptionValues ?? [],
|
|
24
|
-
return /* @__PURE__ */
|
|
23
|
+
}, []), a = n?.currentValues ?? [], o = n?.enabledOptionValues ?? [], l = a.filter((e) => o.includes(e)).length, u = o.length > 0 && l === o.length, d = l > 0 && !u;
|
|
24
|
+
return /* @__PURE__ */ v(h, {
|
|
25
25
|
...t,
|
|
26
|
-
children: [!!n && /* @__PURE__ */
|
|
26
|
+
children: [!!n && /* @__PURE__ */ v(g, { children: [/* @__PURE__ */ v(f, {
|
|
27
27
|
onClick: r,
|
|
28
28
|
onMouseDown: i,
|
|
29
29
|
sx: {
|
|
@@ -32,22 +32,22 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
32
32
|
cursor: "pointer",
|
|
33
33
|
display: "flex"
|
|
34
34
|
},
|
|
35
|
-
children: [/* @__PURE__ */
|
|
36
|
-
checked:
|
|
37
|
-
checkedIcon: /* @__PURE__ */ y
|
|
38
|
-
icon: /* @__PURE__ */
|
|
35
|
+
children: [/* @__PURE__ */ _(p, {
|
|
36
|
+
checked: u,
|
|
37
|
+
checkedIcon: /* @__PURE__ */ _(y, {}),
|
|
38
|
+
icon: /* @__PURE__ */ _(ue, {}),
|
|
39
39
|
indeterminate: d,
|
|
40
|
-
indeterminateIcon: /* @__PURE__ */
|
|
40
|
+
indeterminateIcon: /* @__PURE__ */ _(b, {}),
|
|
41
41
|
style: { marginRight: 8 }
|
|
42
42
|
}), n.selectAllLabel]
|
|
43
|
-
}), /* @__PURE__ */
|
|
43
|
+
}), /* @__PURE__ */ _(m, {})] }), e]
|
|
44
44
|
});
|
|
45
|
-
},
|
|
46
|
-
let { t: O } =
|
|
47
|
-
|
|
48
|
-
N.current =
|
|
49
|
-
}, [
|
|
50
|
-
let P = !!A, F = !!D && !P, I =
|
|
45
|
+
}, C = ({ disabled: e = !1, groupValues: i = !1, hideSelectAll: a = !1, infoMessage: s, label: f, loading: m = !1, multiple: h, name: g, onChange: b, options: C, required: w = !1, shouldSortOptions: T, textFieldVariant: E = "outlined", warningMessage: D }) => {
|
|
46
|
+
let { t: O } = re(), { control: fe, formState: { errors: pe }, setValue: k, watch: me } = ne(), A = t.getFieldErrorMessage(pe, g), j = d(null), [M, he] = ee(""), N = d(b);
|
|
47
|
+
l(() => {
|
|
48
|
+
N.current = b;
|
|
49
|
+
}, [b]);
|
|
50
|
+
let P = !!A, F = !!D && !P, I = u(() => T ? structuredClone(C).sort((e, t) => e.label.localeCompare(t.label)) : C, [C, T]), { mappedOptions: L, optionValues: R } = u(() => {
|
|
51
51
|
let e = [], t = /* @__PURE__ */ new Map();
|
|
52
52
|
return I.forEach((n) => {
|
|
53
53
|
e.push(n.value), t.set(n.value, n);
|
|
@@ -55,11 +55,11 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
55
55
|
mappedOptions: t,
|
|
56
56
|
optionValues: e
|
|
57
57
|
};
|
|
58
|
-
}, [I]), z =
|
|
58
|
+
}, [I]), z = c((e) => m ? O`Loading...` : L.get(e)?.label, [
|
|
59
59
|
m,
|
|
60
60
|
L,
|
|
61
61
|
O
|
|
62
|
-
]), B =
|
|
62
|
+
]), B = c((e, t) => e === t, []), V = c((e) => L.get(e)?.disabled, [L]), H = c((e) => L.get(e)?.groupByValue, [L]), U = c((e) => String(L.get(e)?.value), [L]), W = c((e, t, n) => /* @__PURE__ */ v("li", {
|
|
63
63
|
"aria-disabled": e["aria-disabled"],
|
|
64
64
|
"aria-selected": e["aria-selected"],
|
|
65
65
|
className: e.className,
|
|
@@ -74,43 +74,43 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
74
74
|
padding: 0
|
|
75
75
|
},
|
|
76
76
|
tabIndex: e.tabIndex,
|
|
77
|
-
children: [/* @__PURE__ */
|
|
77
|
+
children: [/* @__PURE__ */ _(p, {
|
|
78
78
|
checked: n.selected,
|
|
79
|
-
checkedIcon: /* @__PURE__ */ y
|
|
80
|
-
icon: /* @__PURE__ */
|
|
79
|
+
checkedIcon: /* @__PURE__ */ _(y, {}),
|
|
80
|
+
icon: /* @__PURE__ */ _(ue, {}),
|
|
81
81
|
style: { marginRight: 8 }
|
|
82
82
|
}), z(t)]
|
|
83
|
-
}, U(t)), [U, z]), G =
|
|
84
|
-
|
|
85
|
-
}, []), K =
|
|
86
|
-
let
|
|
83
|
+
}, U(t)), [U, z]), G = c((e, t) => {
|
|
84
|
+
he(t);
|
|
85
|
+
}, []), K = c((t) => {
|
|
86
|
+
let r = /* @__PURE__ */ _(n, {
|
|
87
87
|
errorMessage: A,
|
|
88
88
|
infoMessage: s,
|
|
89
89
|
warningMessage: D
|
|
90
90
|
});
|
|
91
|
-
return /* @__PURE__ */
|
|
91
|
+
return /* @__PURE__ */ _(ce, {
|
|
92
92
|
disabled: e || m,
|
|
93
93
|
error: P,
|
|
94
94
|
fullWidth: t.fullWidth,
|
|
95
|
-
helperText:
|
|
95
|
+
helperText: r,
|
|
96
96
|
id: t.id,
|
|
97
97
|
inputRef: j,
|
|
98
|
-
label:
|
|
98
|
+
label: f,
|
|
99
99
|
size: t.size,
|
|
100
100
|
slotProps: {
|
|
101
|
-
formHelperText: { className: (0,
|
|
101
|
+
formHelperText: { className: (0, x.default)({ "Mui-warning": F }) },
|
|
102
102
|
htmlInput: { ...t.slotProps.htmlInput },
|
|
103
103
|
input: {
|
|
104
104
|
...t.slotProps.input,
|
|
105
|
-
className: (0,
|
|
105
|
+
className: (0, x.default)(t.slotProps.input.className, { "Mui-warning": F })
|
|
106
106
|
},
|
|
107
107
|
inputLabel: {
|
|
108
108
|
...t.slotProps.inputLabel,
|
|
109
|
-
className: (0,
|
|
110
|
-
required:
|
|
109
|
+
className: (0, x.default)({ "Mui-warning": F }),
|
|
110
|
+
required: w && !e
|
|
111
111
|
}
|
|
112
112
|
},
|
|
113
|
-
variant:
|
|
113
|
+
variant: E
|
|
114
114
|
});
|
|
115
115
|
}, [
|
|
116
116
|
e,
|
|
@@ -118,16 +118,17 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
118
118
|
P,
|
|
119
119
|
F,
|
|
120
120
|
s,
|
|
121
|
-
|
|
121
|
+
f,
|
|
122
122
|
m,
|
|
123
|
-
|
|
123
|
+
w,
|
|
124
|
+
E,
|
|
124
125
|
D
|
|
125
|
-
]), q =
|
|
126
|
+
]), q = c((e, t) => /* @__PURE__ */ _(se, {
|
|
126
127
|
direction: "row",
|
|
127
128
|
sx: { flexWrap: "wrap" },
|
|
128
129
|
children: (Array.isArray(e) ? e : [e]).map((e, n) => {
|
|
129
130
|
let r = t({ index: n }), i = L.get(e);
|
|
130
|
-
return /* @__PURE__ */
|
|
131
|
+
return /* @__PURE__ */ o(ae, {
|
|
131
132
|
...r,
|
|
132
133
|
key: String(e),
|
|
133
134
|
label: z(e),
|
|
@@ -135,11 +136,11 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
135
136
|
size: "small"
|
|
136
137
|
});
|
|
137
138
|
})
|
|
138
|
-
}), [z, L]), J =
|
|
139
|
-
|
|
140
|
-
}, [
|
|
139
|
+
}), [z, L]), J = c((e) => (t, n) => {
|
|
140
|
+
b && b(n), e(n);
|
|
141
|
+
}, [b]), Y = c((e, t) => t.inputValue ? I.filter((e) => e.label.toLowerCase().includes(t.inputValue.toLowerCase())).map((e) => e.value) : I.map((e) => e.value), [I]), X = u(() => R.filter((e) => !L.get(e)?.disabled), [R, L]), Z = me(g), Q = u(() => h && Array.isArray(Z) ? Z : [], [h, Z]), $ = c((e, t) => {
|
|
141
142
|
let n = e ? t.filter((e) => L.get(e)?.disabled) : [.../* @__PURE__ */ new Set([...t, ...X])];
|
|
142
|
-
N.current?.(n), k(
|
|
143
|
+
N.current?.(n), k(g, n, {
|
|
143
144
|
shouldDirty: !0,
|
|
144
145
|
shouldTouch: !0,
|
|
145
146
|
shouldValidate: !0
|
|
@@ -147,9 +148,9 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
147
148
|
}, [
|
|
148
149
|
X,
|
|
149
150
|
L,
|
|
150
|
-
|
|
151
|
+
g,
|
|
151
152
|
k
|
|
152
|
-
]),
|
|
153
|
+
]), ge = u(() => ({
|
|
153
154
|
currentValues: Q,
|
|
154
155
|
enabledOptionValues: X,
|
|
155
156
|
handleSelectAll: $,
|
|
@@ -159,42 +160,43 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
159
160
|
X,
|
|
160
161
|
$,
|
|
161
162
|
O
|
|
162
|
-
]),
|
|
163
|
+
]), _e = c(({ field: { onBlur: t, onChange: n, ref: r, value: o } }) => (r({ focus: () => {
|
|
163
164
|
j?.current?.focus();
|
|
164
|
-
} }), /* @__PURE__ */
|
|
165
|
+
} }), /* @__PURE__ */ _(ie, {
|
|
165
166
|
autoComplete: !0,
|
|
166
167
|
autoHighlight: !0,
|
|
167
|
-
disableClearable:
|
|
168
|
-
disableCloseOnSelect:
|
|
168
|
+
disableClearable: w,
|
|
169
|
+
disableCloseOnSelect: h,
|
|
169
170
|
disabled: e || m,
|
|
170
171
|
filterOptions: Y,
|
|
171
172
|
getOptionDisabled: V,
|
|
172
173
|
getOptionKey: U,
|
|
173
174
|
getOptionLabel: z,
|
|
174
|
-
groupBy:
|
|
175
|
-
inputValue:
|
|
175
|
+
groupBy: i ? H : void 0,
|
|
176
|
+
inputValue: h ? M : void 0,
|
|
176
177
|
isOptionEqualToValue: B,
|
|
177
|
-
multiple:
|
|
178
|
+
multiple: h,
|
|
178
179
|
noOptionsText: O`No results`,
|
|
179
180
|
onBlur: t,
|
|
180
181
|
onChange: J(n),
|
|
181
|
-
onInputChange:
|
|
182
|
+
onInputChange: h ? G : void 0,
|
|
182
183
|
options: R,
|
|
183
184
|
renderInput: K,
|
|
184
|
-
renderOption:
|
|
185
|
-
renderValue:
|
|
186
|
-
slots:
|
|
187
|
-
value:
|
|
185
|
+
renderOption: h ? W : void 0,
|
|
186
|
+
renderValue: h ? q : void 0,
|
|
187
|
+
slots: h && !a ? { paper: de } : void 0,
|
|
188
|
+
value: o
|
|
188
189
|
})), [
|
|
189
|
-
|
|
190
|
-
|
|
190
|
+
w,
|
|
191
|
+
h,
|
|
192
|
+
a,
|
|
191
193
|
e,
|
|
192
194
|
m,
|
|
193
195
|
Y,
|
|
194
196
|
V,
|
|
195
197
|
U,
|
|
196
198
|
z,
|
|
197
|
-
|
|
199
|
+
i,
|
|
198
200
|
H,
|
|
199
201
|
M,
|
|
200
202
|
B,
|
|
@@ -206,24 +208,24 @@ var w = /* @__PURE__ */ e(o(), 1), ce = s(null), le = ({ children: e, ...t }) =>
|
|
|
206
208
|
W,
|
|
207
209
|
q
|
|
208
210
|
]);
|
|
209
|
-
return /* @__PURE__ */
|
|
210
|
-
value:
|
|
211
|
-
children: /* @__PURE__ */
|
|
212
|
-
...
|
|
213
|
-
label:
|
|
214
|
-
name:
|
|
211
|
+
return /* @__PURE__ */ _(S, {
|
|
212
|
+
value: h ? ge : null,
|
|
213
|
+
children: /* @__PURE__ */ v(oe, {
|
|
214
|
+
...le.createAttributes("Autocomplete", {
|
|
215
|
+
label: f,
|
|
216
|
+
name: g
|
|
215
217
|
}),
|
|
216
218
|
fullWidth: !0,
|
|
217
|
-
children: [/* @__PURE__ */
|
|
218
|
-
control:
|
|
219
|
+
children: [/* @__PURE__ */ _(te, {
|
|
220
|
+
control: fe,
|
|
219
221
|
defaultValue: null,
|
|
220
|
-
name:
|
|
221
|
-
render:
|
|
222
|
-
}), !!m && /* @__PURE__ */
|
|
222
|
+
name: g,
|
|
223
|
+
render: _e
|
|
224
|
+
}), !!m && /* @__PURE__ */ _(r, {})]
|
|
223
225
|
})
|
|
224
226
|
});
|
|
225
227
|
};
|
|
226
228
|
//#endregion
|
|
227
|
-
export {
|
|
229
|
+
export { C as t };
|
|
228
230
|
|
|
229
231
|
//# sourceMappingURL=Autocomplete.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Autocomplete.js","names":[],"sources":["../../src/components/fields/Autocomplete/AutocompleteSelectAllContext.tsx","../../src/components/fields/Autocomplete/AutocompleteSelectAllPaper.tsx","../../src/components/fields/Autocomplete/Autocomplete.tsx"],"sourcesContent":["import { createContext } from 'react';\n\nimport type { AutocompleteSelectAllContextData } from '../../../models/form';\n\nexport const AutocompleteSelectAllContext = createContext<AutocompleteSelectAllContextData | null>(null);\n","import type { MouseEvent } from 'react';\nimport {\n use,\n useCallback,\n} from 'react';\nimport {\n Box,\n Checkbox,\n Divider,\n Paper,\n} from '@mui/material';\nimport type { PaperProps } from '@mui/material';\nimport CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';\nimport CheckBoxIcon from '@mui/icons-material/CheckBox';\nimport IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';\n\nimport { AutocompleteSelectAllContext } from './AutocompleteSelectAllContext';\n\nexport const AutocompleteSelectAllPaper = ({ children, ...props }: PaperProps) => {\n const ctx = use(AutocompleteSelectAllContext);\n\n const onClickSelectAll = useCallback(() => {\n if (!ctx) {\n return;\n }\n const { currentValues, enabledOptionValues, handleSelectAll } = ctx;\n const selCount = currentValues.filter(v => enabledOptionValues.includes(v)).length;\n const curIsAll = enabledOptionValues.length > 0 && selCount === enabledOptionValues.length;\n handleSelectAll(curIsAll, currentValues);\n }, [ctx]);\n\n const onMouseDownSelectAll = useCallback((e: MouseEvent<HTMLElement>) => {\n e.preventDefault();\n }, []);\n\n const currentValues = ctx?.currentValues ?? [];\n const enabledOptionValues = ctx?.enabledOptionValues ?? [];\n const selectedEnabledCount = currentValues.filter(v => enabledOptionValues.includes(v)).length;\n const isAll = enabledOptionValues.length > 0 && selectedEnabledCount === enabledOptionValues.length;\n const isSome = selectedEnabledCount > 0 && !isAll;\n\n return (\n <Paper {...props}>\n {!!ctx && (\n <>\n <Box\n onClick={onClickSelectAll}\n onMouseDown={onMouseDownSelectAll}\n sx={{ '&:hover': { bgcolor: 'action.hover' }, alignItems: 'center', cursor: 'pointer', display: 'flex' }}\n >\n <Checkbox\n checked={isAll}\n checkedIcon={<CheckBoxIcon />}\n icon={<CheckBoxOutlineBlankIcon />}\n indeterminate={isSome}\n indeterminateIcon={<IndeterminateCheckBoxIcon />}\n style={{ marginRight: 8 }}\n />\n {ctx.selectAllLabel}\n </Box>\n <Divider />\n </>\n )}\n {children}\n </Paper>\n );\n};\n","import type {\n HTMLAttributes,\n ReactElement,\n ReactNode,\n SyntheticEvent,\n} from 'react';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n Checkbox,\n Chip,\n FormControl,\n Autocomplete as MuiAutocomplete,\n Stack,\n TextField,\n} from '@mui/material';\nimport CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';\nimport CheckBoxIcon from '@mui/icons-material/CheckBox';\nimport type {\n AutocompleteRenderInputParams,\n AutocompleteRenderOptionState,\n AutocompleteRenderValueGetItemProps,\n AutocompleteValue,\n FilterOptionsState,\n} from '@mui/material';\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 {\n AutoCompleteOption,\n AutocompleteSelectAllContextData,\n} from '../../../models/form';\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nimport { AutocompleteSelectAllPaper } from './AutocompleteSelectAllPaper';\nimport { AutocompleteSelectAllContext } from './AutocompleteSelectAllContext';\n\n\nexport type AutocompleteProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>, TMultiple extends boolean> = {\n readonly disabled?: boolean;\n readonly groupValues?: 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: AutocompleteValue<TFieldValues[TName], TMultiple, false, false>) => void;\n readonly options: AutoCompleteOption[];\n readonly required?: boolean;\n readonly shouldSortOptions?: boolean;\n readonly warningMessage?: string;\n};\ntype MultipleRenderValueItemProps = ReturnType<AutocompleteRenderValueGetItemProps<true>>;\n\ntype Value = number | string;\n\nexport const Autocomplete = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>, TMultiple extends boolean = false>({\n disabled = false,\n groupValues = false,\n infoMessage,\n label,\n loading = false,\n multiple,\n name,\n onChange: onChangeProp,\n options,\n required = false,\n shouldSortOptions,\n warningMessage,\n}: AutocompleteProps<TFieldValues, TName, TMultiple>): ReactElement => {\n const { t } = useTranslation();\n const { control, formState: { errors }, setValue, watch } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const inputRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState('');\n\n const onChangePropRef = useRef(onChangeProp);\n useEffect(() => {\n onChangePropRef.current = onChangeProp;\n }, [onChangeProp]);\n\n const hasError = !!errorMessage;\n const hasWarning = !!warningMessage && !hasError;\n\n const sortedOptions = useMemo(() => {\n if (!shouldSortOptions) {\n return options;\n }\n return structuredClone(options).sort((a, b) => a.label.localeCompare(b.label));\n }, [options, shouldSortOptions]);\n\n const { mappedOptions, optionValues }: { mappedOptions: Map<Value, AutoCompleteOption>; optionValues: Array<Value> } = useMemo(() => {\n const values: Array<Value> = [];\n const mapped = new Map<Value, AutoCompleteOption>();\n sortedOptions.forEach(option => {\n values.push(option.value);\n mapped.set(option.value, option);\n });\n return {\n mappedOptions: mapped,\n optionValues: values,\n };\n }, [sortedOptions]);\n\n const getOptionLabel = useCallback((value: AutoCompleteOption['value']) => loading ? t`Loading...` : mappedOptions.get(value)?.label, [loading, mappedOptions, t]);\n const getIsOptionEqualToValue = useCallback((optionValue: AutoCompleteOption['value'], value: AutoCompleteOption['value']) => optionValue === value, []);\n const getIsOptionDisabled = useCallback((value: AutoCompleteOption['value']): boolean => mappedOptions.get(value)?.disabled, [mappedOptions]);\n const groupBy = useCallback((value: AutoCompleteOption['value']): string => mappedOptions.get(value)?.groupByValue, [mappedOptions]);\n const getOptionKey = useCallback((value: AutoCompleteOption['value']): string => String(mappedOptions.get(value)?.value), [mappedOptions]);\n\n const renderOption = useCallback((props: HTMLAttributes<HTMLLIElement>, option: TFieldValues[TName], state: AutocompleteRenderOptionState): ReactNode => {\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions\n <li\n aria-disabled={props['aria-disabled']}\n aria-selected={props['aria-selected']}\n className={props.className}\n data-option-index={(props as { 'data-option-index': string })['data-option-index']}\n id={props.id}\n key={getOptionKey(option)}\n onClick={props.onClick}\n onMouseMove={props.onMouseMove}\n onTouchStart={props.onTouchStart}\n role={props.role}\n style={{\n margin: 0,\n padding: 0,\n }}\n tabIndex={props.tabIndex}\n >\n <Checkbox\n checked={state.selected}\n checkedIcon={<CheckBoxIcon />}\n icon={<CheckBoxOutlineBlankIcon />}\n style={{ marginRight: 8 }}\n />\n {getOptionLabel(option)}\n </li>\n );\n }, [getOptionKey, getOptionLabel]);\n\n const onMuiAutocompleteInputChange = useCallback((_event: SyntheticEvent, value: string) => {\n setInputValue(value);\n }, []);\n\n const renderInput = useCallback((params: AutocompleteRenderInputParams) => {\n const helperText = (\n <FormFieldHelperText\n errorMessage={errorMessage}\n infoMessage={infoMessage}\n warningMessage={warningMessage}\n />\n );\n\n return (\n <TextField\n disabled={disabled || loading}\n error={hasError}\n fullWidth={params.fullWidth}\n helperText={helperText}\n id={params.id}\n inputRef={inputRef}\n label={label}\n size={params.size}\n slotProps={{\n formHelperText: { className: classnames({ 'Mui-warning': hasWarning }) },\n htmlInput: {\n ...params.slotProps.htmlInput,\n },\n input: {\n ...params.slotProps.input,\n className: classnames(params.slotProps.input.className, {\n 'Mui-warning': hasWarning,\n }),\n },\n inputLabel: {\n ...params.slotProps.inputLabel,\n className: classnames({ 'Mui-warning': hasWarning }),\n required: required && !disabled,\n },\n }}\n variant={'outlined'}\n />\n );\n }, [disabled, errorMessage, hasError, hasWarning, infoMessage, label, loading, required, warningMessage]);\n\n const renderValue = useCallback((values: AutocompleteValue<TFieldValues[TName], TMultiple, false, false>, getItemProps: AutocompleteRenderValueGetItemProps<TMultiple>) => {\n const selectedValues = (Array.isArray(values) ? values : [values]) as Value[];\n\n return (\n <Stack\n direction={'row'}\n sx={{\n flexWrap: 'wrap',\n }}\n >\n {selectedValues.map((value: Value, index: number) => {\n const props = getItemProps({ index }) as MultipleRenderValueItemProps;\n const option = mappedOptions.get(value);\n\n return (\n <Chip\n {...props}\n // eslint-disable-next-line @eslint-react/jsx-no-key-after-spread\n key={String(value)}\n label={getOptionLabel(value)}\n onDelete={option?.disabled ? undefined : props.onDelete}\n size={'small'}\n />\n );\n })}\n </Stack>\n );\n }, [getOptionLabel, mappedOptions]);\n\n const onMuiAutocompleteChange = useCallback((onChange: ControllerRenderProps<TFieldValues, TName>['onChange']) =>\n (_event: SyntheticEvent, value: AutocompleteValue<TFieldValues[TName], TMultiple, false, false>) => {\n if (onChangeProp) {\n onChangeProp(value);\n }\n onChange(value);\n }\n , [onChangeProp]);\n\n const filterOptions = useCallback((_filterableOptions: TFieldValues[TName][], filterState: FilterOptionsState<TFieldValues[TName]>): TFieldValues[TName][] => {\n if (filterState.inputValue) {\n return sortedOptions.filter(option => option.label.toLowerCase().includes(filterState.inputValue.toLowerCase())).map((option) => option.value) as TFieldValues[TName][];\n }\n return sortedOptions.map((option) => option.value) as TFieldValues[TName][];\n }, [sortedOptions]);\n\n const enabledOptionValues = useMemo(() =>\n optionValues.filter(v => !mappedOptions.get(v)?.disabled)\n , [optionValues, mappedOptions]);\n\n const watchedValue = watch(name);\n const currentValues = useMemo(() =>\n multiple && Array.isArray(watchedValue) ? watchedValue as Value[] : []\n , [multiple, watchedValue]);\n\n const handleSelectAll = useCallback((isCurrentlyAll: boolean, curValues: Value[]) => {\n const newValue = isCurrentlyAll\n ? curValues.filter(v => mappedOptions.get(v)?.disabled)\n : [...new Set([...curValues, ...enabledOptionValues])];\n onChangePropRef.current?.(newValue as unknown as AutocompleteValue<TFieldValues[TName], TMultiple, false, false>);\n setValue(name, newValue as TFieldValues[TName], { shouldDirty: true, shouldTouch: true, shouldValidate: true });\n }, [enabledOptionValues, mappedOptions, name, setValue]);\n\n const selectAllContextValue = useMemo<AutocompleteSelectAllContextData>(() => ({\n currentValues,\n enabledOptionValues,\n handleSelectAll,\n selectAllLabel: t`Select all`,\n }), [currentValues, enabledOptionValues, handleSelectAll, t]);\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 <MuiAutocomplete<TFieldValues[TName], TMultiple>\n autoComplete\n autoHighlight\n disableClearable={required as undefined}\n disableCloseOnSelect={multiple}\n disabled={disabled || loading}\n filterOptions={filterOptions}\n getOptionDisabled={getIsOptionDisabled}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n groupBy={groupValues ? groupBy : undefined}\n inputValue={multiple ? inputValue : undefined}\n isOptionEqualToValue={getIsOptionEqualToValue}\n multiple={multiple}\n noOptionsText={t`No results`}\n onBlur={onBlur}\n onChange={onMuiAutocompleteChange(onChange)}\n onInputChange={multiple ? onMuiAutocompleteInputChange : undefined}\n options={optionValues as TFieldValues[TName]}\n renderInput={renderInput}\n renderOption={multiple ? renderOption : undefined}\n renderValue={multiple ? renderValue : undefined}\n slots={multiple ? { paper: AutocompleteSelectAllPaper } : undefined}\n value={value}\n />\n );\n }, [required, multiple, disabled, loading, filterOptions, getIsOptionDisabled, getOptionKey, getOptionLabel, groupValues, groupBy, inputValue, getIsOptionEqualToValue, t, onMuiAutocompleteChange, onMuiAutocompleteInputChange, optionValues, renderInput, renderOption, renderValue]);\n\n return (\n <AutocompleteSelectAllContext value={multiple ? selectAllContextValue : null}>\n <FormControl\n {...TestIdUtil.createAttributes('Autocomplete', { 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 </AutocompleteSelectAllContext>\n );\n};\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"Autocomplete.js","names":[],"sources":["../../src/components/fields/Autocomplete/AutocompleteSelectAllContext.tsx","../../src/components/fields/Autocomplete/AutocompleteSelectAllPaper.tsx","../../src/components/fields/Autocomplete/Autocomplete.tsx"],"sourcesContent":["import { createContext } from 'react';\n\nimport type { AutocompleteSelectAllContextData } from '../../../models/form';\n\nexport const AutocompleteSelectAllContext = createContext<AutocompleteSelectAllContextData | null>(null);\n","import type { MouseEvent } from 'react';\nimport {\n use,\n useCallback,\n} from 'react';\nimport {\n Box,\n Checkbox,\n Divider,\n Paper,\n} from '@mui/material';\nimport type { PaperProps } from '@mui/material';\nimport CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';\nimport CheckBoxIcon from '@mui/icons-material/CheckBox';\nimport IndeterminateCheckBoxIcon from '@mui/icons-material/IndeterminateCheckBox';\n\nimport { AutocompleteSelectAllContext } from './AutocompleteSelectAllContext';\n\nexport const AutocompleteSelectAllPaper = ({ children, ...props }: PaperProps) => {\n const ctx = use(AutocompleteSelectAllContext);\n\n const onClickSelectAll = useCallback(() => {\n if (!ctx) {\n return;\n }\n const { currentValues, enabledOptionValues, handleSelectAll } = ctx;\n const selCount = currentValues.filter(v => enabledOptionValues.includes(v)).length;\n const curIsAll = enabledOptionValues.length > 0 && selCount === enabledOptionValues.length;\n handleSelectAll(curIsAll, currentValues);\n }, [ctx]);\n\n const onMouseDownSelectAll = useCallback((e: MouseEvent<HTMLElement>) => {\n e.preventDefault();\n }, []);\n\n const currentValues = ctx?.currentValues ?? [];\n const enabledOptionValues = ctx?.enabledOptionValues ?? [];\n const selectedEnabledCount = currentValues.filter(v => enabledOptionValues.includes(v)).length;\n const isAll = enabledOptionValues.length > 0 && selectedEnabledCount === enabledOptionValues.length;\n const isSome = selectedEnabledCount > 0 && !isAll;\n\n return (\n <Paper {...props}>\n {!!ctx && (\n <>\n <Box\n onClick={onClickSelectAll}\n onMouseDown={onMouseDownSelectAll}\n sx={{ '&:hover': { bgcolor: 'action.hover' }, alignItems: 'center', cursor: 'pointer', display: 'flex' }}\n >\n <Checkbox\n checked={isAll}\n checkedIcon={<CheckBoxIcon />}\n icon={<CheckBoxOutlineBlankIcon />}\n indeterminate={isSome}\n indeterminateIcon={<IndeterminateCheckBoxIcon />}\n style={{ marginRight: 8 }}\n />\n {ctx.selectAllLabel}\n </Box>\n <Divider />\n </>\n )}\n {children}\n </Paper>\n );\n};\n","import type {\n HTMLAttributes,\n ReactElement,\n ReactNode,\n SyntheticEvent,\n} from 'react';\nimport {\n useCallback,\n useEffect,\n useMemo,\n useRef,\n useState,\n} from 'react';\nimport {\n Checkbox,\n Chip,\n FormControl,\n Autocomplete as MuiAutocomplete,\n Stack,\n TextField,\n} from '@mui/material';\nimport CheckBoxOutlineBlankIcon from '@mui/icons-material/CheckBoxOutlineBlank';\nimport CheckBoxIcon from '@mui/icons-material/CheckBox';\nimport type {\n AutocompleteRenderInputParams,\n AutocompleteRenderOptionState,\n AutocompleteRenderValueGetItemProps,\n AutocompleteValue,\n FilterOptionsState,\n TextFieldVariants,\n} from '@mui/material';\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 {\n AutoCompleteOption,\n AutocompleteSelectAllContextData,\n} from '../../../models/form';\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\nimport { FormFieldLoadingIndicator } from '../../helpers/FormFieldLoadingIndicator';\n\nimport { AutocompleteSelectAllPaper } from './AutocompleteSelectAllPaper';\nimport { AutocompleteSelectAllContext } from './AutocompleteSelectAllContext';\n\n\n// A multi-select field's own value is already the array, so it must not be re-wrapped by `AutocompleteValue`'s `Multiple` handling.\nexport type AutocompleteChangeValue<TFieldValues extends FieldValues, TName extends Path<TFieldValues>, TMultiple extends boolean> = TMultiple extends true ? TFieldValues[TName] : AutocompleteValue<TFieldValues[TName], false, false, false>;\n\nexport type AutocompleteProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues>, TMultiple extends boolean> = {\n readonly disabled?: boolean;\n readonly groupValues?: boolean;\n readonly hideSelectAll?: 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: AutocompleteChangeValue<TFieldValues, TName, TMultiple>) => void;\n readonly options: AutoCompleteOption[];\n readonly required?: boolean;\n readonly shouldSortOptions?: boolean;\n readonly textFieldVariant?: TextFieldVariants;\n readonly warningMessage?: string;\n};\ntype MultipleRenderValueItemProps = ReturnType<AutocompleteRenderValueGetItemProps<true>>;\n\ntype Value = number | string;\n\nexport const Autocomplete = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>, TMultiple extends boolean = false>({\n disabled = false,\n groupValues = false,\n hideSelectAll = false,\n infoMessage,\n label,\n loading = false,\n multiple,\n name,\n onChange: onChangeProp,\n options,\n required = false,\n shouldSortOptions,\n textFieldVariant = 'outlined',\n warningMessage,\n}: AutocompleteProps<TFieldValues, TName, TMultiple>): ReactElement => {\n const { t } = useTranslation();\n const { control, formState: { errors }, setValue, watch } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n const inputRef = useRef<HTMLInputElement>(null);\n const [inputValue, setInputValue] = useState('');\n\n const onChangePropRef = useRef(onChangeProp);\n useEffect(() => {\n onChangePropRef.current = onChangeProp;\n }, [onChangeProp]);\n\n const hasError = !!errorMessage;\n const hasWarning = !!warningMessage && !hasError;\n\n const sortedOptions = useMemo(() => {\n if (!shouldSortOptions) {\n return options;\n }\n return structuredClone(options).sort((a, b) => a.label.localeCompare(b.label));\n }, [options, shouldSortOptions]);\n\n const { mappedOptions, optionValues }: { mappedOptions: Map<Value, AutoCompleteOption>; optionValues: Array<Value> } = useMemo(() => {\n const values: Array<Value> = [];\n const mapped = new Map<Value, AutoCompleteOption>();\n sortedOptions.forEach(option => {\n values.push(option.value);\n mapped.set(option.value, option);\n });\n return {\n mappedOptions: mapped,\n optionValues: values,\n };\n }, [sortedOptions]);\n\n const getOptionLabel = useCallback((value: AutoCompleteOption['value']) => loading ? t`Loading...` : mappedOptions.get(value)?.label, [loading, mappedOptions, t]);\n const getIsOptionEqualToValue = useCallback((optionValue: AutoCompleteOption['value'], value: AutoCompleteOption['value']) => optionValue === value, []);\n const getIsOptionDisabled = useCallback((value: AutoCompleteOption['value']): boolean => mappedOptions.get(value)?.disabled, [mappedOptions]);\n const groupBy = useCallback((value: AutoCompleteOption['value']): string => mappedOptions.get(value)?.groupByValue, [mappedOptions]);\n const getOptionKey = useCallback((value: AutoCompleteOption['value']): string => String(mappedOptions.get(value)?.value), [mappedOptions]);\n\n const renderOption = useCallback((props: HTMLAttributes<HTMLLIElement>, option: TFieldValues[TName], state: AutocompleteRenderOptionState): ReactNode => {\n return (\n // eslint-disable-next-line jsx-a11y/click-events-have-key-events, jsx-a11y/no-noninteractive-element-interactions\n <li\n aria-disabled={props['aria-disabled']}\n aria-selected={props['aria-selected']}\n className={props.className}\n data-option-index={(props as { 'data-option-index': string })['data-option-index']}\n id={props.id}\n key={getOptionKey(option)}\n onClick={props.onClick}\n onMouseMove={props.onMouseMove}\n onTouchStart={props.onTouchStart}\n role={props.role}\n style={{\n margin: 0,\n padding: 0,\n }}\n tabIndex={props.tabIndex}\n >\n <Checkbox\n checked={state.selected}\n checkedIcon={<CheckBoxIcon />}\n icon={<CheckBoxOutlineBlankIcon />}\n style={{ marginRight: 8 }}\n />\n {getOptionLabel(option)}\n </li>\n );\n }, [getOptionKey, getOptionLabel]);\n\n const onMuiAutocompleteInputChange = useCallback((_event: SyntheticEvent, value: string) => {\n setInputValue(value);\n }, []);\n\n const renderInput = useCallback((params: AutocompleteRenderInputParams) => {\n const helperText = (\n <FormFieldHelperText\n errorMessage={errorMessage}\n infoMessage={infoMessage}\n warningMessage={warningMessage}\n />\n );\n\n return (\n <TextField\n disabled={disabled || loading}\n error={hasError}\n fullWidth={params.fullWidth}\n helperText={helperText}\n id={params.id}\n inputRef={inputRef}\n label={label}\n size={params.size}\n slotProps={{\n formHelperText: { className: classnames({ 'Mui-warning': hasWarning }) },\n htmlInput: {\n ...params.slotProps.htmlInput,\n },\n input: {\n ...params.slotProps.input,\n className: classnames(params.slotProps.input.className, {\n 'Mui-warning': hasWarning,\n }),\n },\n inputLabel: {\n ...params.slotProps.inputLabel,\n className: classnames({ 'Mui-warning': hasWarning }),\n required: required && !disabled,\n },\n }}\n variant={textFieldVariant}\n />\n );\n }, [disabled, errorMessage, hasError, hasWarning, infoMessage, label, loading, required, textFieldVariant, warningMessage]);\n\n const renderValue = useCallback((values: AutocompleteValue<TFieldValues[TName], TMultiple, false, false>, getItemProps: AutocompleteRenderValueGetItemProps<TMultiple>) => {\n const selectedValues = (Array.isArray(values) ? values : [values]) as Value[];\n\n return (\n <Stack\n direction={'row'}\n sx={{\n flexWrap: 'wrap',\n }}\n >\n {selectedValues.map((value: Value, index: number) => {\n const props = getItemProps({ index }) as MultipleRenderValueItemProps;\n const option = mappedOptions.get(value);\n\n return (\n <Chip\n {...props}\n // eslint-disable-next-line @eslint-react/jsx-no-key-after-spread\n key={String(value)}\n label={getOptionLabel(value)}\n onDelete={option?.disabled ? undefined : props.onDelete}\n size={'small'}\n />\n );\n })}\n </Stack>\n );\n }, [getOptionLabel, mappedOptions]);\n\n const onMuiAutocompleteChange = useCallback((onChange: ControllerRenderProps<TFieldValues, TName>['onChange']) =>\n (_event: SyntheticEvent, value: AutocompleteValue<TFieldValues[TName], TMultiple, false, false>) => {\n if (onChangeProp) {\n onChangeProp(value as unknown as AutocompleteChangeValue<TFieldValues, TName, TMultiple>);\n }\n onChange(value);\n }\n , [onChangeProp]);\n\n const filterOptions = useCallback((_filterableOptions: TFieldValues[TName][], filterState: FilterOptionsState<TFieldValues[TName]>): TFieldValues[TName][] => {\n if (filterState.inputValue) {\n return sortedOptions.filter(option => option.label.toLowerCase().includes(filterState.inputValue.toLowerCase())).map((option) => option.value) as TFieldValues[TName][];\n }\n return sortedOptions.map((option) => option.value) as TFieldValues[TName][];\n }, [sortedOptions]);\n\n const enabledOptionValues = useMemo(() =>\n optionValues.filter(v => !mappedOptions.get(v)?.disabled)\n , [optionValues, mappedOptions]);\n\n const watchedValue = watch(name);\n const currentValues = useMemo(() =>\n multiple && Array.isArray(watchedValue) ? watchedValue as Value[] : []\n , [multiple, watchedValue]);\n\n const handleSelectAll = useCallback((isCurrentlyAll: boolean, curValues: Value[]) => {\n const newValue = isCurrentlyAll\n ? curValues.filter(v => mappedOptions.get(v)?.disabled)\n : [...new Set([...curValues, ...enabledOptionValues])];\n onChangePropRef.current?.(newValue as unknown as AutocompleteChangeValue<TFieldValues, TName, TMultiple>);\n setValue(name, newValue as TFieldValues[TName], { shouldDirty: true, shouldTouch: true, shouldValidate: true });\n }, [enabledOptionValues, mappedOptions, name, setValue]);\n\n const selectAllContextValue = useMemo<AutocompleteSelectAllContextData>(() => ({\n currentValues,\n enabledOptionValues,\n handleSelectAll,\n selectAllLabel: t`Select all`,\n }), [currentValues, enabledOptionValues, handleSelectAll, t]);\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 <MuiAutocomplete<TFieldValues[TName], TMultiple>\n autoComplete\n autoHighlight\n disableClearable={required as undefined}\n disableCloseOnSelect={multiple}\n disabled={disabled || loading}\n filterOptions={filterOptions}\n getOptionDisabled={getIsOptionDisabled}\n getOptionKey={getOptionKey}\n getOptionLabel={getOptionLabel}\n groupBy={groupValues ? groupBy : undefined}\n inputValue={multiple ? inputValue : undefined}\n isOptionEqualToValue={getIsOptionEqualToValue}\n multiple={multiple}\n noOptionsText={t`No results`}\n onBlur={onBlur}\n onChange={onMuiAutocompleteChange(onChange)}\n onInputChange={multiple ? onMuiAutocompleteInputChange : undefined}\n options={optionValues as TFieldValues[TName]}\n renderInput={renderInput}\n renderOption={multiple ? renderOption : undefined}\n renderValue={multiple ? renderValue : undefined}\n slots={(multiple && !hideSelectAll) ? { paper: AutocompleteSelectAllPaper } : undefined}\n value={value}\n />\n );\n }, [required, multiple, hideSelectAll, disabled, loading, filterOptions, getIsOptionDisabled, getOptionKey, getOptionLabel, groupValues, groupBy, inputValue, getIsOptionEqualToValue, t, onMuiAutocompleteChange, onMuiAutocompleteInputChange, optionValues, renderInput, renderOption, renderValue]);\n\n return (\n <AutocompleteSelectAllContext value={multiple ? selectAllContextValue : null}>\n <FormControl\n {...TestIdUtil.createAttributes('Autocomplete', { 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 </AutocompleteSelectAllContext>\n );\n};\n"],"mappings":"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"}
|
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
import { n as e } from "./rolldown-runtime.js";
|
|
2
2
|
import { t, u as n } from "./FormUtil.js";
|
|
3
|
-
import {
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
import { t as
|
|
7
|
-
import {
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
3
|
+
import { FormFieldHelperText as r } from "../components/helpers/FormFieldHelperText/index.js";
|
|
4
|
+
import { FormFieldLoadingIndicator as i } from "../components/helpers/FormFieldLoadingIndicator/index.js";
|
|
5
|
+
import { t as a } from "./classnames.js";
|
|
6
|
+
import { t as o } from "./sv.js";
|
|
7
|
+
import { DATE_FORMAT as s } from "@gen-epix/ui-core/constants/date";
|
|
8
|
+
import { useCallback as c, useMemo as l, useRef as u } from "react";
|
|
9
|
+
import { Controller as d, useFormContext as f } from "react-hook-form";
|
|
10
10
|
import { useTranslation as p } from "react-i18next";
|
|
11
11
|
import { FormControl as m, FormHelperText as h, IconButton as g, InputAdornment as _ } from "@mui/material";
|
|
12
12
|
import v from "@mui/icons-material/Clear";
|
|
@@ -15,7 +15,7 @@ import { TestIdUtil as x } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
|
15
15
|
import { DatePicker as S, DateTimePicker as C, LocalizationProvider as w } from "@mui/x-date-pickers";
|
|
16
16
|
import { AdapterDateFns as T } from "@mui/x-date-pickers/AdapterDateFns";
|
|
17
17
|
//#region src/components/fields/DatePicker/DatePickerInputAdornment.tsx
|
|
18
|
-
var E = /* @__PURE__ */ e(
|
|
18
|
+
var E = /* @__PURE__ */ e(a(), 1), D = ({ children: e, disabled: t, loading: n, onResetButtonClickRef: r, ...i }) => {
|
|
19
19
|
let { t: a } = p();
|
|
20
20
|
return /* @__PURE__ */ b(_, {
|
|
21
21
|
...i,
|
|
@@ -29,21 +29,21 @@ var E = /* @__PURE__ */ e(s(), 1), D = ({ children: e, disabled: t, loading: n,
|
|
|
29
29
|
children: /* @__PURE__ */ y(v, {})
|
|
30
30
|
}), e]
|
|
31
31
|
});
|
|
32
|
-
}, O = ({ dateFormat: e =
|
|
33
|
-
let { control: j, formState: { errors: M } } =
|
|
32
|
+
}, O = ({ dateFormat: e = s.DATE, disabled: a = !1, infoMessage: p, label: g, loading: _ = !1, name: v, onChange: O, required: k = !1, warningMessage: A }) => {
|
|
33
|
+
let { control: j, formState: { errors: M } } = f(), N = t.getFieldErrorMessage(M, v), P = !!N, F = !!A && !P, I = u(null), L = u(() => void 0), R = c((e) => (t) => {
|
|
34
34
|
O && O(t), e(t);
|
|
35
|
-
}, [O]), z =
|
|
35
|
+
}, [O]), z = l(() => ({
|
|
36
36
|
...n,
|
|
37
|
-
formatLong:
|
|
38
|
-
}), []), B =
|
|
37
|
+
formatLong: o.formatLong
|
|
38
|
+
}), []), B = l(() => {
|
|
39
39
|
switch (e) {
|
|
40
|
-
case
|
|
41
|
-
case
|
|
42
|
-
case
|
|
43
|
-
case
|
|
40
|
+
case s.DATE:
|
|
41
|
+
case s.DATE_TIME: return;
|
|
42
|
+
case s.YEAR: return ["year"];
|
|
43
|
+
case s.YEAR_MONTH: return ["year", "month"];
|
|
44
44
|
default: throw Error(`Unsupported date format: ${e}`);
|
|
45
45
|
}
|
|
46
|
-
}, [e]), V = e ===
|
|
46
|
+
}, [e]), V = e === s.DATE_TIME ? C : S, H = c(({ field: { onBlur: t, onChange: n, ref: o, value: c } }) => (o({ focus: () => {
|
|
47
47
|
I?.current?.focus();
|
|
48
48
|
} }), L.current = () => {
|
|
49
49
|
n(null);
|
|
@@ -62,12 +62,12 @@ var E = /* @__PURE__ */ e(s(), 1), D = ({ children: e, disabled: t, loading: n,
|
|
|
62
62
|
adapterLocale: z,
|
|
63
63
|
dateAdapter: T,
|
|
64
64
|
children: /* @__PURE__ */ y(V, {
|
|
65
|
-
disabled:
|
|
65
|
+
disabled: a || _,
|
|
66
66
|
inputRef: I,
|
|
67
67
|
label: g,
|
|
68
68
|
loading: _,
|
|
69
69
|
onChange: R(n),
|
|
70
|
-
openTo: e ===
|
|
70
|
+
openTo: e === s.DATE_TIME ? void 0 : "year",
|
|
71
71
|
slotProps: { textField: {
|
|
72
72
|
className: (0, E.default)({ "Mui-warning": F }),
|
|
73
73
|
error: P,
|
|
@@ -77,18 +77,18 @@ var E = /* @__PURE__ */ e(s(), 1), D = ({ children: e, disabled: t, loading: n,
|
|
|
77
77
|
} },
|
|
78
78
|
slots: { inputAdornment: (e) => /* @__PURE__ */ y(D, {
|
|
79
79
|
...e,
|
|
80
|
-
disabled:
|
|
80
|
+
disabled: a,
|
|
81
81
|
loading: _,
|
|
82
82
|
onResetButtonClickRef: L
|
|
83
83
|
}) },
|
|
84
|
-
value:
|
|
84
|
+
value: c,
|
|
85
85
|
views: B
|
|
86
86
|
})
|
|
87
87
|
}),
|
|
88
|
-
!!_ && /* @__PURE__ */ y(
|
|
88
|
+
!!_ && /* @__PURE__ */ y(i, {}),
|
|
89
89
|
/* @__PURE__ */ y(h, {
|
|
90
90
|
sx: { ml: 0 },
|
|
91
|
-
children: /* @__PURE__ */ y(
|
|
91
|
+
children: /* @__PURE__ */ y(r, {
|
|
92
92
|
errorMessage: N,
|
|
93
93
|
infoMessage: p,
|
|
94
94
|
noIndent: !0,
|
|
@@ -100,7 +100,7 @@ var E = /* @__PURE__ */ e(s(), 1), D = ({ children: e, disabled: t, loading: n,
|
|
|
100
100
|
V,
|
|
101
101
|
z,
|
|
102
102
|
e,
|
|
103
|
-
|
|
103
|
+
a,
|
|
104
104
|
N,
|
|
105
105
|
P,
|
|
106
106
|
F,
|
|
@@ -113,7 +113,7 @@ var E = /* @__PURE__ */ e(s(), 1), D = ({ children: e, disabled: t, loading: n,
|
|
|
113
113
|
B,
|
|
114
114
|
A
|
|
115
115
|
]);
|
|
116
|
-
return /* @__PURE__ */ y(
|
|
116
|
+
return /* @__PURE__ */ y(d, {
|
|
117
117
|
control: j,
|
|
118
118
|
defaultValue: "",
|
|
119
119
|
name: v,
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { t as e } from "./FormUtil.js";
|
|
2
|
+
import { FormFieldHelperText as t } from "../components/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
|
+
import { FormControl as s, FormHelperText as c, FormLabel as l } from "@mui/material";
|
|
6
|
+
import { jsx as u, jsxs as d } from "react/jsx-runtime";
|
|
7
|
+
import { TestIdUtil as f } from "@gen-epix/ui-core/utils/TestIdUtil";
|
|
8
|
+
import { FileDropZone as p } from "@gen-epix/ui-core-components/components/FileDropZone";
|
|
9
|
+
//#region src/components/fields/FileUpload/FileUpload.tsx
|
|
10
|
+
var m = ({ accept: m, disabled: h, infoMessage: g, label: _, multiple: v = !1, name: y, onChange: b, required: x, warningMessage: S }) => {
|
|
11
|
+
let C = r(), w = r(), { control: T, formState: { errors: E } } = o(), D = e.getFieldErrorMessage(E, y), O = i(null), k = !!D, A = n((e) => (t) => {
|
|
12
|
+
b && b(t), e(t);
|
|
13
|
+
}, [b]), j = n(({ field: { onBlur: e, onChange: t, ref: n, value: r } }) => (n({ focus: () => {
|
|
14
|
+
O?.current?.focus();
|
|
15
|
+
} }), /* @__PURE__ */ u(p, {
|
|
16
|
+
accept: m,
|
|
17
|
+
ariaDescribedBy: w,
|
|
18
|
+
disabled: h,
|
|
19
|
+
error: k,
|
|
20
|
+
files: r ?? null,
|
|
21
|
+
label: _,
|
|
22
|
+
labelledById: C,
|
|
23
|
+
multiple: v,
|
|
24
|
+
onBlur: e,
|
|
25
|
+
onFilesSelected: A(t),
|
|
26
|
+
ref: O
|
|
27
|
+
})), [
|
|
28
|
+
m,
|
|
29
|
+
w,
|
|
30
|
+
h,
|
|
31
|
+
k,
|
|
32
|
+
_,
|
|
33
|
+
C,
|
|
34
|
+
v,
|
|
35
|
+
A
|
|
36
|
+
]);
|
|
37
|
+
return /* @__PURE__ */ d(s, {
|
|
38
|
+
error: k,
|
|
39
|
+
...f.createAttributes("UploadButton", {
|
|
40
|
+
label: _,
|
|
41
|
+
name: y
|
|
42
|
+
}),
|
|
43
|
+
fullWidth: !0,
|
|
44
|
+
children: [
|
|
45
|
+
/* @__PURE__ */ u(l, {
|
|
46
|
+
component: "legend",
|
|
47
|
+
id: C,
|
|
48
|
+
required: x,
|
|
49
|
+
children: _
|
|
50
|
+
}),
|
|
51
|
+
/* @__PURE__ */ u(a, {
|
|
52
|
+
control: T,
|
|
53
|
+
defaultValue: null,
|
|
54
|
+
name: y,
|
|
55
|
+
render: j
|
|
56
|
+
}),
|
|
57
|
+
/* @__PURE__ */ u(c, {
|
|
58
|
+
id: w,
|
|
59
|
+
sx: { ml: 0 },
|
|
60
|
+
children: /* @__PURE__ */ u(t, {
|
|
61
|
+
errorMessage: D,
|
|
62
|
+
infoMessage: g,
|
|
63
|
+
noIndent: !0,
|
|
64
|
+
warningMessage: S
|
|
65
|
+
})
|
|
66
|
+
})
|
|
67
|
+
]
|
|
68
|
+
});
|
|
69
|
+
};
|
|
70
|
+
//#endregion
|
|
71
|
+
export { m as t };
|
|
72
|
+
|
|
73
|
+
//# sourceMappingURL=FileUpload.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"FileUpload.js","names":[],"sources":["../../src/components/fields/FileUpload/FileUpload.tsx"],"sourcesContent":["import type { ReactElement } from 'react';\nimport {\n useCallback,\n useId,\n useRef,\n} from 'react';\nimport {\n FormControl,\n FormHelperText,\n FormLabel,\n} from '@mui/material';\nimport {\n Controller,\n useFormContext,\n} from 'react-hook-form';\nimport type {\n FieldValues,\n Path,\n UseControllerReturn,\n} from 'react-hook-form';\nimport { TestIdUtil } from '@gen-epix/ui-core/utils/TestIdUtil';\nimport { FileDropZone } from '@gen-epix/ui-core-components/components/FileDropZone';\n\nimport { FormUtil } from '../../../utils/FormUtil';\nimport { FormFieldHelperText } from '../../helpers/FormFieldHelperText';\n\nexport type FileUploadProps<TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>> = {\n readonly accept: string;\n readonly disabled?: boolean;\n readonly infoMessage?: string;\n readonly label: string;\n readonly loading?: boolean; // NOT implemented\n readonly multiple?: boolean;\n readonly name: TName;\n readonly onChange?: (value: FileList) => void;\n readonly required?: boolean;\n readonly warningMessage?: string;\n};\n\nexport const FileUpload = <TFieldValues extends FieldValues, TName extends Path<TFieldValues> = Path<TFieldValues>>({\n accept,\n disabled,\n infoMessage,\n label,\n multiple = false,\n name,\n onChange: onChangeProp,\n required,\n warningMessage,\n}: FileUploadProps<TFieldValues, TName>): ReactElement => {\n const labelId = useId();\n const helperTextId = useId();\n const { control, formState: { errors } } = useFormContext<TFieldValues>();\n const errorMessage = FormUtil.getFieldErrorMessage(errors, name);\n\n const dropZoneRef = useRef<HTMLDivElement>(null);\n const hasError = !!errorMessage;\n\n const onFilesSelected = useCallback((onChange: UseControllerReturn<TFieldValues, TName>['field']['onChange']) =>\n (files: FileList) => {\n if (onChangeProp) {\n onChangeProp(files);\n }\n onChange(files);\n }\n , [onChangeProp]);\n\n const renderController = useCallback(({ field: { onBlur, onChange, ref, value } }: UseControllerReturn<TFieldValues, TName>) => {\n ref({\n focus: () => {\n dropZoneRef?.current?.focus();\n },\n });\n return (\n <FileDropZone\n accept={accept}\n ariaDescribedBy={helperTextId}\n disabled={disabled}\n error={hasError}\n files={value ?? null}\n label={label}\n labelledById={labelId}\n multiple={multiple}\n onBlur={onBlur}\n onFilesSelected={onFilesSelected(onChange)}\n ref={dropZoneRef}\n />\n );\n }, [accept, helperTextId, disabled, hasError, label, labelId, multiple, onFilesSelected]);\n\n return (\n <FormControl\n error={hasError}\n {...TestIdUtil.createAttributes('UploadButton', { label, name })}\n fullWidth\n >\n <FormLabel\n component={'legend'}\n id={labelId}\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\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 </FormControl>\n );\n};\n"],"mappings":";;;;;;;;;AAuCA,IAAa,KAAuG,EAClH,WACA,aACA,gBACA,UACA,cAAW,IACX,SACA,UAAU,GACV,aACA,wBACwD;CACxD,IAAM,IAAU,EAAM,GAChB,IAAe,EAAM,GACrB,EAAE,YAAS,WAAW,EAAE,gBAAa,EAA6B,GAClE,IAAe,EAAS,qBAAqB,GAAQ,CAAI,GAEzD,IAAc,EAAuB,IAAI,GACzC,IAAW,CAAC,CAAC,GAEb,IAAkB,GAAa,OAClC,MAAoB;EAInB,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,GAAa,SAAS,MAAM;CAC9B,EACF,CAAC,GAEC,kBAAC,GAAD;EACU;EACR,iBAAiB;EACP;EACV,OAAO;EACP,OAAO,KAAS;EACT;EACP,cAAc;EACJ;EACF;EACR,iBAAiB,EAAgB,CAAQ;EACzC,KAAK;CACN,CAAA,IAEF;EAAC;EAAQ;EAAc;EAAU;EAAU;EAAO;EAAS;EAAU;CAAe,CAAC;CAExF,OACE,kBAAC,GAAD;EACE,OAAO;EACP,GAAI,EAAW,iBAAiB,gBAAgB;GAAE;GAAO;EAAK,CAAC;EAC/D,WAAA;EAHF,UAAA;GAKE,kBAAC,GAAD;IACE,WAAW;IACX,IAAI;IACM;IAET,UAAA;GACQ,CAAA;GACX,kBAAC,GAAD;IACW;IACT,cAAc;IACR;IACN,QAAQ;GACT,CAAA;GACD,kBAAC,GAAD;IACE,IAAI;IACJ,IAAI,EAAE,IAAI,EAAE;IAEZ,UAAA,kBAAC,GAAD;KACgB;KACD;KACb,UAAA;KACgB;IACjB,CAAA;GACa,CAAA;EACL;;AAEjB"}
|
package/dist/_chunks/FormUtil.js
CHANGED
|
@@ -1247,7 +1247,8 @@ var Pe = class {
|
|
|
1247
1247
|
let t = n[e.name];
|
|
1248
1248
|
switch (e.definition) {
|
|
1249
1249
|
case s.BOOLEAN:
|
|
1250
|
-
case s.BOOLEAN_SWITCH:
|
|
1250
|
+
case s.BOOLEAN_SWITCH:
|
|
1251
|
+
case s.SWITCH: return typeof t == "boolean";
|
|
1251
1252
|
case s.DATE:
|
|
1252
1253
|
case s.HIDDEN:
|
|
1253
1254
|
case s.RICH_TEXT:
|
|
@@ -1275,7 +1276,9 @@ var Pe = class {
|
|
|
1275
1276
|
e.multiple ? n[e.name] = t?.[e.name] ?? [] : n[e.name] = t?.[e.name] ?? null;
|
|
1276
1277
|
break;
|
|
1277
1278
|
case s.BOOLEAN:
|
|
1279
|
+
case s.BOOLEAN_SWITCH:
|
|
1278
1280
|
case s.RICH_TEXT:
|
|
1281
|
+
case s.SWITCH:
|
|
1279
1282
|
case s.TEXTFIELD:
|
|
1280
1283
|
n[e.name] = t?.[e.name] ?? "";
|
|
1281
1284
|
break;
|