@etsoo/materialui 1.6.18 → 1.6.20

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.
@@ -32,6 +32,7 @@ function ComboBoxMultiple(props) {
32
32
  const { search = false, autoAddBlankItem = search, idField = "id", idValue, idValues, inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputReset, inputVariant, defaultValue, label, labelField = "label", loadData, onLoadData, name, inputAutoComplete = "off", options, dataReadonly = true, readOnly, onChange, openOnFocus = true, value, disableCloseOnSelect = true, renderOption = ({ key, ...restProps }, option, { selected }) => ((0, jsx_runtime_1.jsxs)("li", { ...restProps, children: [(0, jsx_runtime_1.jsx)(Checkbox_1.default, { icon: icon, checkedIcon: checkedIcon, style: { marginRight: 8 }, checked: selected }), `${option[labelField]}`] }, key)), getOptionLabel = (option) => `${option[labelField]}`, getOptionKey = (option) => `${option[idField]}`, sx = { minWidth: "150px" }, noOptionsText = labels?.noOptions, loadingText = labels?.loading, disabled, ...rest } = props;
33
33
  // Value input ref
34
34
  const inputRef = react_1.default.createRef();
35
+ const localRef = react_1.default.useRef(undefined);
35
36
  // Options state
36
37
  const [localOptions, setOptions] = react_1.default.useState(options ?? []);
37
38
  const isMounted = react_1.default.useRef(true);
@@ -44,6 +45,11 @@ function ComboBoxMultiple(props) {
44
45
  // State
45
46
  // null for controlled
46
47
  const [stateValue, setStateValue] = react_1.default.useState(null);
48
+ const selectedCount = stateValue?.length ?? 0;
49
+ react_1.default.useEffect(() => {
50
+ if (localRef.current && inputRequired)
51
+ localRef.current.required = selectedCount === 0;
52
+ }, [inputRequired, selectedCount]);
47
53
  react_1.default.useEffect(() => {
48
54
  const localValue = idValue != null
49
55
  ? localOptions.filter((o) => o[idField] === idValue)
@@ -119,5 +125,5 @@ function ComboBoxMultiple(props) {
119
125
  // Custom
120
126
  if (onChange != null)
121
127
  onChange(event, value, reason, details);
122
- }, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? ((0, jsx_runtime_1.jsx)(SearchField_1.SearchField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })) : ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })), options: localOptions, renderOption: renderOption, noOptionsText: noOptionsText, loadingText: loadingText, ...rest })] }));
128
+ }, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? ((0, jsx_runtime_1.jsx)(SearchField_1.SearchField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText, inputRef: localRef })) : ((0, jsx_runtime_1.jsx)(InputField_1.InputField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText, inputRef: localRef })), options: localOptions, renderOption: renderOption, noOptionsText: noOptionsText, loadingText: loadingText, ...rest })] }));
123
129
  }
@@ -1,10 +1,6 @@
1
1
  "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
2
  Object.defineProperty(exports, "__esModule", { value: true });
6
3
  exports.CustomFieldUI = CustomFieldUI;
7
- const react_1 = __importDefault(require("react"));
8
4
  const CustomFieldUtils_1 = require("./CustomFieldUtils");
9
5
  /**
10
6
  * CustomFieldUI component
@@ -13,17 +9,14 @@ const CustomFieldUtils_1 = require("./CustomFieldUtils");
13
9
  */
14
10
  function CustomFieldUI(props) {
15
11
  // Destruct
16
- const { fields, onChange, value } = props;
17
- const data = react_1.default.useRef({});
18
- const getValue = react_1.default.useCallback((field) => {
12
+ const { fields, onChange, value = {} } = props;
13
+ // Layout
14
+ return CustomFieldUtils_1.CustomFieldUtils.create(fields, {}, (field) => {
19
15
  if (!field.name)
20
16
  return undefined;
21
- return value?.[field.name];
22
- }, [value]);
23
- const doChange = react_1.default.useCallback((name, value) => {
24
- data.current[name] = value;
25
- onChange?.(data.current, name, value);
26
- }, []);
27
- // Layout
28
- return CustomFieldUtils_1.CustomFieldUtils.create(fields, {}, getValue, doChange);
17
+ return value[field.name];
18
+ }, (name, fieldValue) => {
19
+ value[name] = fieldValue;
20
+ onChange?.(value, name, fieldValue);
21
+ });
29
22
  }
@@ -39,7 +39,7 @@ const FieldCombobox = ({ field, mref, onChange, defaultValue }) => {
39
39
  return ((0, jsx_runtime_1.jsxs)(Typography_1.default, { children: ["No name for FieldCombobox ", JSON.stringify(field)] }));
40
40
  }
41
41
  const { required, inputRequired, ...mainRests } = field.mainSlotProps || {};
42
- return ((0, jsx_runtime_1.jsx)(ComboBoxMultiple_1.ComboBoxMultiple, { label: field.label ?? "", inputHelperText: field.helperText, name: name, options: field.options, fullWidth: true, idValues: ids, inputRequired: required || inputRequired, onChange: (_event, value) => {
42
+ return ((0, jsx_runtime_1.jsx)(ComboBoxMultiple_1.ComboBoxMultiple, { label: field.label ?? "", inputHelperText: field.helperText, inputRequired: required || inputRequired, name: name, options: field.options, fullWidth: true, idValues: ids, onChange: (_event, value) => {
43
43
  const ids = value.map((v) => v.id);
44
44
  setIds(ids);
45
45
  onChange(name, ids);
@@ -26,6 +26,7 @@ export function ComboBoxMultiple(props) {
26
26
  const { search = false, autoAddBlankItem = search, idField = "id", idValue, idValues, inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputReset, inputVariant, defaultValue, label, labelField = "label", loadData, onLoadData, name, inputAutoComplete = "off", options, dataReadonly = true, readOnly, onChange, openOnFocus = true, value, disableCloseOnSelect = true, renderOption = ({ key, ...restProps }, option, { selected }) => (_jsxs("li", { ...restProps, children: [_jsx(Checkbox, { icon: icon, checkedIcon: checkedIcon, style: { marginRight: 8 }, checked: selected }), `${option[labelField]}`] }, key)), getOptionLabel = (option) => `${option[labelField]}`, getOptionKey = (option) => `${option[idField]}`, sx = { minWidth: "150px" }, noOptionsText = labels?.noOptions, loadingText = labels?.loading, disabled, ...rest } = props;
27
27
  // Value input ref
28
28
  const inputRef = React.createRef();
29
+ const localRef = React.useRef(undefined);
29
30
  // Options state
30
31
  const [localOptions, setOptions] = React.useState(options ?? []);
31
32
  const isMounted = React.useRef(true);
@@ -38,6 +39,11 @@ export function ComboBoxMultiple(props) {
38
39
  // State
39
40
  // null for controlled
40
41
  const [stateValue, setStateValue] = React.useState(null);
42
+ const selectedCount = stateValue?.length ?? 0;
43
+ React.useEffect(() => {
44
+ if (localRef.current && inputRequired)
45
+ localRef.current.required = selectedCount === 0;
46
+ }, [inputRequired, selectedCount]);
41
47
  React.useEffect(() => {
42
48
  const localValue = idValue != null
43
49
  ? localOptions.filter((o) => o[idField] === idValue)
@@ -113,5 +119,5 @@ export function ComboBoxMultiple(props) {
113
119
  // Custom
114
120
  if (onChange != null)
115
121
  onChange(event, value, reason, details);
116
- }, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? (_jsx(SearchField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })) : (_jsx(InputField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })), options: localOptions, renderOption: renderOption, noOptionsText: noOptionsText, loadingText: loadingText, ...rest })] }));
122
+ }, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? (_jsx(SearchField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText, inputRef: localRef })) : (_jsx(InputField, { ...addReadOnly(params), label: label, name: name + "Input", margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText, inputRef: localRef })), options: localOptions, renderOption: renderOption, noOptionsText: noOptionsText, loadingText: loadingText, ...rest })] }));
117
123
  }
@@ -1,4 +1,3 @@
1
- import React from "react";
2
1
  import { CustomFieldUtils } from "./CustomFieldUtils";
3
2
  /**
4
3
  * CustomFieldUI component
@@ -7,17 +6,14 @@ import { CustomFieldUtils } from "./CustomFieldUtils";
7
6
  */
8
7
  export function CustomFieldUI(props) {
9
8
  // Destruct
10
- const { fields, onChange, value } = props;
11
- const data = React.useRef({});
12
- const getValue = React.useCallback((field) => {
9
+ const { fields, onChange, value = {} } = props;
10
+ // Layout
11
+ return CustomFieldUtils.create(fields, {}, (field) => {
13
12
  if (!field.name)
14
13
  return undefined;
15
- return value?.[field.name];
16
- }, [value]);
17
- const doChange = React.useCallback((name, value) => {
18
- data.current[name] = value;
19
- onChange?.(data.current, name, value);
20
- }, []);
21
- // Layout
22
- return CustomFieldUtils.create(fields, {}, getValue, doChange);
14
+ return value[field.name];
15
+ }, (name, fieldValue) => {
16
+ value[name] = fieldValue;
17
+ onChange?.(value, name, fieldValue);
18
+ });
23
19
  }
@@ -33,7 +33,7 @@ export const FieldCombobox = ({ field, mref, onChange, defaultValue }) => {
33
33
  return (_jsxs(Typography, { children: ["No name for FieldCombobox ", JSON.stringify(field)] }));
34
34
  }
35
35
  const { required, inputRequired, ...mainRests } = field.mainSlotProps || {};
36
- return (_jsx(ComboBoxMultiple, { label: field.label ?? "", inputHelperText: field.helperText, name: name, options: field.options, fullWidth: true, idValues: ids, inputRequired: required || inputRequired, onChange: (_event, value) => {
36
+ return (_jsx(ComboBoxMultiple, { label: field.label ?? "", inputHelperText: field.helperText, inputRequired: required || inputRequired, name: name, options: field.options, fullWidth: true, idValues: ids, onChange: (_event, value) => {
37
37
  const ids = value.map((v) => v.id);
38
38
  setIds(ids);
39
39
  onChange(name, ids);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/materialui",
3
- "version": "1.6.18",
3
+ "version": "1.6.20",
4
4
  "description": "TypeScript Material-UI Implementation",
5
5
  "main": "lib/cjs/index.js",
6
6
  "module": "lib/mjs/index.js",
@@ -132,6 +132,7 @@ export function ComboBoxMultiple<
132
132
 
133
133
  // Value input ref
134
134
  const inputRef = React.createRef<HTMLInputElement>();
135
+ const localRef = React.useRef<HTMLInputElement>(undefined);
135
136
 
136
137
  // Options state
137
138
  const [localOptions, setOptions] = React.useState(options ?? []);
@@ -148,6 +149,12 @@ export function ComboBoxMultiple<
148
149
  // null for controlled
149
150
  const [stateValue, setStateValue] = React.useState<T[] | null>(null);
150
151
 
152
+ const selectedCount = stateValue?.length ?? 0;
153
+ React.useEffect(() => {
154
+ if (localRef.current && inputRequired)
155
+ localRef.current.required = selectedCount === 0;
156
+ }, [inputRequired, selectedCount]);
157
+
151
158
  React.useEffect(() => {
152
159
  const localValue: T[] | null | undefined =
153
160
  idValue != null
@@ -273,6 +280,7 @@ export function ComboBoxMultiple<
273
280
  required={inputRequired}
274
281
  error={inputError}
275
282
  helperText={inputHelperText}
283
+ inputRef={localRef}
276
284
  />
277
285
  ) : (
278
286
  <InputField
@@ -284,6 +292,7 @@ export function ComboBoxMultiple<
284
292
  required={inputRequired}
285
293
  error={inputError}
286
294
  helperText={inputHelperText}
295
+ inputRef={localRef}
287
296
  />
288
297
  )
289
298
  }
@@ -1,5 +1,4 @@
1
1
  import { CustomFieldData } from "@etsoo/appscript";
2
- import React from "react";
3
2
  import { CustomFieldUtils } from "./CustomFieldUtils";
4
3
 
5
4
  /**
@@ -38,23 +37,19 @@ export function CustomFieldUI<D extends CustomFieldData = CustomFieldData>(
38
37
  props: CustomFieldUIProps<D>
39
38
  ) {
40
39
  // Destruct
41
- const { fields, onChange, value } = props;
40
+ const { fields, onChange, value = {} } = props;
42
41
 
43
- const data = React.useRef<Record<string, unknown>>({});
44
-
45
- const getValue = React.useCallback(
46
- (field: CustomFieldData) => {
42
+ // Layout
43
+ return CustomFieldUtils.create(
44
+ fields,
45
+ {},
46
+ (field) => {
47
47
  if (!field.name) return undefined;
48
- return value?.[field.name];
48
+ return value[field.name];
49
49
  },
50
- [value]
50
+ (name, fieldValue) => {
51
+ value[name] = fieldValue;
52
+ onChange?.(value, name, fieldValue);
53
+ }
51
54
  );
52
-
53
- const doChange = React.useCallback((name: string, value: unknown) => {
54
- data.current[name] = value;
55
- onChange?.(data.current, name, value);
56
- }, []);
57
-
58
- // Layout
59
- return CustomFieldUtils.create(fields, {}, getValue, doChange);
60
55
  }
@@ -50,11 +50,11 @@ export const FieldCombobox: ICustomFieldReact<IdType[]> = ({
50
50
  <ComboBoxMultiple
51
51
  label={field.label ?? ""}
52
52
  inputHelperText={field.helperText}
53
+ inputRequired={required || inputRequired}
53
54
  name={name}
54
55
  options={field.options}
55
56
  fullWidth
56
57
  idValues={ids}
57
- inputRequired={required || inputRequired}
58
58
  onChange={(_event, value) => {
59
59
  const ids = value.map((v) => v.id);
60
60
  setIds(ids);