@etsoo/react 1.5.75 → 1.5.76

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.
@@ -4,15 +4,15 @@ import { ChangeEventHandler } from 'react';
4
4
  /**
5
5
  * Autocomplete extended props
6
6
  */
7
- export interface AutocompleteExtendedProps<T extends Record<string, unknown>> extends Omit<AutocompleteProps<T, undefined, false, false>, 'renderInput' | 'options'> {
7
+ export interface AutocompleteExtendedProps<T extends {}, D extends DataTypes.Keys<T>> extends Omit<AutocompleteProps<T, undefined, false, false>, 'renderInput' | 'options'> {
8
8
  /**
9
9
  * Id field, default is id
10
10
  */
11
- idField?: string & keyof T;
11
+ idField: D;
12
12
  /**
13
13
  * Id value
14
14
  */
15
- idValue?: DataTypes.IdType;
15
+ idValue?: T[D];
16
16
  /**
17
17
  * Autocomplete for the input
18
18
  */
@@ -1,10 +1,10 @@
1
1
  /// <reference types="react" />
2
- import { IdLabelDto } from '@etsoo/appscript';
2
+ import { DataTypes } from '@etsoo/shared';
3
3
  import { AutocompleteExtendedProps } from './AutocompleteExtendedProps';
4
4
  /**
5
5
  * ComboBox props
6
6
  */
7
- export interface ComboBoxProps<T extends {}> extends AutocompleteExtendedProps<T> {
7
+ export interface ComboBoxProps<T extends {}, D extends DataTypes.Keys<T> = DataTypes.Keys<T>> extends AutocompleteExtendedProps<T, D> {
8
8
  /**
9
9
  * Auto add blank item
10
10
  */
@@ -16,7 +16,7 @@ export interface ComboBoxProps<T extends {}> extends AutocompleteExtendedProps<T
16
16
  /**
17
17
  * Label field
18
18
  */
19
- labelField?: string & keyof T;
19
+ labelField: D;
20
20
  /**
21
21
  * Load data callback
22
22
  */
@@ -35,4 +35,4 @@ export interface ComboBoxProps<T extends {}> extends AutocompleteExtendedProps<T
35
35
  * @param props Props
36
36
  * @returns Component
37
37
  */
38
- export declare function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>): JSX.Element;
38
+ export declare function ComboBox<T extends {} = DataTypes.IdLabelItem, D extends DataTypes.Keys<T> = DataTypes.Keys<T>>(props: ComboBoxProps<T, D>): JSX.Element;
@@ -12,7 +12,7 @@ import { ReactUtils } from '../app/ReactUtils';
12
12
  */
13
13
  export function ComboBox(props) {
14
14
  // Destruct
15
- const { search = false, autoAddBlankItem = search, idField = 'id', idValue, inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, defaultValue, label, labelField = 'label', loadData, onLoadData, name, inputAutoComplete = 'off', options, dataReadonly = true, readOnly, onChange, openOnFocus = true, value, getOptionLabel = (option) => String(Reflect.get(option, labelField)), sx = { minWidth: '150px' }, ...rest } = props;
15
+ const { search = false, autoAddBlankItem = search, idField, idValue, inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, defaultValue, label, labelField, loadData, onLoadData, name, inputAutoComplete = 'off', options, dataReadonly = true, readOnly, onChange, openOnFocus = true, value, getOptionLabel = (option) => `${option[labelField]}`, sx = { minWidth: '150px' }, ...rest } = props;
16
16
  // Value input ref
17
17
  const inputRef = React.createRef();
18
18
  // Options state
@@ -27,7 +27,7 @@ export function ComboBox(props) {
27
27
  }, [JSON.stringify(options), propertyWay]);
28
28
  // Local default value
29
29
  let localValue = idValue != null
30
- ? localOptions.find((o) => Reflect.get(o, idField) === idValue)
30
+ ? localOptions.find((o) => o[idField] === idValue)
31
31
  : defaultValue !== null && defaultValue !== void 0 ? defaultValue : value;
32
32
  if (localValue === undefined)
33
33
  localValue = null;
@@ -36,7 +36,7 @@ export function ComboBox(props) {
36
36
  const [stateValue, setStateValue] = React.useState(null);
37
37
  // Current id value
38
38
  // One time calculation for input's default value (uncontrolled)
39
- const localIdValue = stateValue && Reflect.get(stateValue, idField);
39
+ const localIdValue = stateValue && stateValue[idField];
40
40
  React.useEffect(() => {
41
41
  if (localValue != null)
42
42
  setStateValue(localValue);
@@ -68,7 +68,7 @@ export function ComboBox(props) {
68
68
  const input = inputRef.current;
69
69
  if (input) {
70
70
  // Update value
71
- const newValue = value != null ? `${Reflect.get(value, idField)}` : '';
71
+ const newValue = value != null ? `${value[idField]}` : '';
72
72
  if (newValue !== input.value) {
73
73
  // Different value, trigger change event
74
74
  ReactUtils.triggerChange(input, newValue, false);
@@ -97,8 +97,8 @@ export function ComboBox(props) {
97
97
  }, []);
98
98
  // Layout
99
99
  return (React.createElement("div", null,
100
- React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: 'none' }, name: name, value: localIdValue !== null && localIdValue !== void 0 ? localIdValue : '', readOnly: true, onChange: inputOnChange }),
101
- React.createElement(Autocomplete, { value: stateValue, getOptionLabel: getOptionLabel, isOptionEqualToValue: (option, value) => Reflect.get(option, idField) === Reflect.get(value, idField), onChange: (event, value, reason, details) => {
100
+ React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: 'none' }, name: name, value: `${localIdValue !== null && localIdValue !== void 0 ? localIdValue : ''}`, readOnly: true, onChange: inputOnChange }),
101
+ React.createElement(Autocomplete, { value: stateValue, getOptionLabel: getOptionLabel, isOptionEqualToValue: (option, value) => option[idField] === value[idField], onChange: (event, value, reason, details) => {
102
102
  // Set value
103
103
  setInputValue(value);
104
104
  // Custom
@@ -18,5 +18,5 @@ export function SelectBool(props) {
18
18
  if (autoAddBlankItem)
19
19
  Utils.addBlankItem(options);
20
20
  // Layout
21
- return React.createElement(SelectEx, { options: options, search: search, ...rest });
21
+ return (React.createElement(SelectEx, { options: options, search: search, ...rest }));
22
22
  }
@@ -1,26 +1,26 @@
1
1
  import { SelectProps } from '@mui/material';
2
2
  import React from 'react';
3
- import { IdLabelDto } from '@etsoo/appscript';
3
+ import { DataTypes } from '@etsoo/shared';
4
4
  /**
5
5
  * Extended select component props
6
6
  */
7
- export interface SelectExProps<T extends {}> extends Omit<SelectProps, 'labelId' | 'input' | 'native'> {
7
+ export interface SelectExProps<T extends {}, D extends DataTypes.Keys<T> = DataTypes.Keys<T>> extends Omit<SelectProps, 'labelId' | 'input' | 'native'> {
8
8
  /**
9
9
  * Auto add blank item
10
10
  */
11
11
  autoAddBlankItem?: boolean;
12
12
  /**
13
- * Id field, default is id
13
+ * Id field
14
14
  */
15
- idField?: string & keyof T;
15
+ idField: D;
16
16
  /**
17
17
  * Item icon renderer
18
18
  */
19
19
  itemIconRenderer?: (id: unknown) => React.ReactNode;
20
20
  /**
21
- * Label field, default is label
21
+ * Label field
22
22
  */
23
- labelField?: ((option: T) => string) | (string & keyof T);
23
+ labelField: ((option: T) => string) | D;
24
24
  /**
25
25
  * Load data callback
26
26
  */
@@ -47,4 +47,4 @@ export interface SelectExProps<T extends {}> extends Omit<SelectProps, 'labelId'
47
47
  * @param props Props
48
48
  * @returns Component
49
49
  */
50
- export declare function SelectEx<T extends {} = IdLabelDto>(props: SelectExProps<T>): JSX.Element;
50
+ export declare function SelectEx<T extends {} = DataTypes.IdLabelItem, D extends DataTypes.Keys<T> = DataTypes.Keys<T>>(props: SelectExProps<T, D>): JSX.Element;
@@ -12,7 +12,7 @@ import { ReactUtils } from '../app/ReactUtils';
12
12
  export function SelectEx(props) {
13
13
  var _a;
14
14
  // Destruct
15
- const { defaultValue, idField = 'id', itemIconRenderer, label, labelField = 'label', loadData, onItemClick, onLoadData, multiple = false, name, options = [], search = false, autoAddBlankItem = search, value, onChange, fullWidth, ...rest } = props;
15
+ const { defaultValue, idField, itemIconRenderer, label, labelField, loadData, onItemClick, onLoadData, multiple = false, name, options = [], search = false, autoAddBlankItem = search, value, onChange, fullWidth, ...rest } = props;
16
16
  // Options state
17
17
  const [localOptions, setOptions] = React.useState(options);
18
18
  const isMounted = React.useRef(true);
@@ -71,13 +71,13 @@ export function SelectEx(props) {
71
71
  };
72
72
  // Get option id
73
73
  const getId = (option) => {
74
- return Reflect.get(option, idField);
74
+ return option[idField];
75
75
  };
76
76
  // Get option label
77
77
  const getLabel = (option) => {
78
78
  return typeof labelField === 'function'
79
79
  ? labelField(option)
80
- : Reflect.get(option, labelField);
80
+ : new String(option[labelField]);
81
81
  };
82
82
  // Refs
83
83
  const divRef = React.useRef();
@@ -1,19 +1,18 @@
1
1
  /// <reference types="react" />
2
- import { IdLabelDto } from '@etsoo/appscript';
3
2
  import { DataTypes } from '@etsoo/shared';
4
3
  import { AutocompleteExtendedProps } from './AutocompleteExtendedProps';
5
4
  /**
6
5
  * Tiplist props
7
6
  */
8
- export interface TiplistProps<T extends {}> extends Omit<AutocompleteExtendedProps<T>, 'open'> {
7
+ export interface TiplistProps<T extends {}, D extends DataTypes.Keys<T>> extends Omit<AutocompleteExtendedProps<T, D>, 'open'> {
9
8
  /**
10
9
  * Load data callback
11
10
  */
12
- loadData: (keyword?: string, id?: DataTypes.IdType) => PromiseLike<T[] | null | undefined>;
11
+ loadData: (keyword?: string, id?: T[D]) => PromiseLike<T[] | null | undefined>;
13
12
  }
14
13
  /**
15
14
  * Tiplist
16
15
  * @param props Props
17
16
  * @returns Component
18
17
  */
19
- export declare function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>): JSX.Element;
18
+ export declare function Tiplist<T extends {}, D extends DataTypes.Keys<T>>(props: TiplistProps<T, D>): JSX.Element;
package/lib/mu/Tiplist.js CHANGED
@@ -12,7 +12,7 @@ import { SearchField } from './SearchField';
12
12
  */
13
13
  export function Tiplist(props) {
14
14
  // Destruct
15
- const { search = false, idField = 'id', idValue, inputAutoComplete = 'off', inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, label, loadData, defaultValue, value, name, readOnly, onChange, openOnFocus = true, sx = { minWidth: '180px' }, ...rest } = props;
15
+ const { search = false, idField, idValue, inputAutoComplete = 'off', inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, label, loadData, defaultValue, value, name, readOnly, onChange, openOnFocus = true, sx = { minWidth: '180px' }, ...rest } = props;
16
16
  // Value input ref
17
17
  const inputRef = React.createRef();
18
18
  // Local value
@@ -20,7 +20,7 @@ export function Tiplist(props) {
20
20
  if (localValue === undefined)
21
21
  localValue = null;
22
22
  // One time calculation for input's default value (uncontrolled)
23
- const localIdValue = idValue !== null && idValue !== void 0 ? idValue : (localValue && Reflect.get(localValue, idField));
23
+ const localIdValue = idValue !== null && idValue !== void 0 ? idValue : (localValue && localValue[idField]);
24
24
  // Changable states
25
25
  const [states, stateUpdate] = React.useReducer((currentState, newState) => {
26
26
  return { ...currentState, ...newState };
@@ -31,7 +31,7 @@ export function Tiplist(props) {
31
31
  value: null
32
32
  });
33
33
  // Input value
34
- const inputValue = React.useMemo(() => states.value && Reflect.get(states.value, idField), [states.value]);
34
+ const inputValue = React.useMemo(() => states.value && states.value[idField], [states.value]);
35
35
  React.useEffect(() => {
36
36
  if (localValue != null)
37
37
  stateUpdate({ value: localValue });
@@ -128,7 +128,7 @@ export function Tiplist(props) {
128
128
  }, []);
129
129
  // Layout
130
130
  return (React.createElement("div", null,
131
- React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: 'none' }, name: name, value: inputValue !== null && inputValue !== void 0 ? inputValue : '', readOnly: true, onChange: inputOnChange }),
131
+ React.createElement("input", { ref: inputRef, "data-reset": "true", type: "text", style: { display: 'none' }, name: name, value: `${inputValue !== null && inputValue !== void 0 ? inputValue : ''}`, readOnly: true, onChange: inputOnChange }),
132
132
  React.createElement(Autocomplete, { filterOptions: (options, _state) => options, value: states.value, options: states.options, onChange: (event, value, reason, details) => {
133
133
  // Set value
134
134
  setInputValue(value);
@@ -150,7 +150,7 @@ export function Tiplist(props) {
150
150
  if (loading)
151
151
  loadDataDirect(undefined, states.value == null
152
152
  ? undefined
153
- : Reflect.get(states.value, idField));
153
+ : states.value[idField]);
154
154
  }, onClose: () => {
155
155
  stateUpdate({
156
156
  open: false,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.5.75",
3
+ "version": "1.5.76",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -51,9 +51,9 @@
51
51
  "@emotion/css": "^11.10.0",
52
52
  "@emotion/react": "^11.10.0",
53
53
  "@emotion/styled": "^11.10.0",
54
- "@etsoo/appscript": "^1.2.78",
54
+ "@etsoo/appscript": "^1.2.79",
55
55
  "@etsoo/notificationbase": "^1.1.6",
56
- "@etsoo/shared": "^1.1.45",
56
+ "@etsoo/shared": "^1.1.46",
57
57
  "@mui/icons-material": "^5.8.4",
58
58
  "@mui/material": "^5.10.1",
59
59
  "@types/pica": "^9.0.1",
@@ -5,20 +5,22 @@ import { ChangeEventHandler } from 'react';
5
5
  /**
6
6
  * Autocomplete extended props
7
7
  */
8
- export interface AutocompleteExtendedProps<T extends Record<string, unknown>>
9
- extends Omit<
8
+ export interface AutocompleteExtendedProps<
9
+ T extends {},
10
+ D extends DataTypes.Keys<T>
11
+ > extends Omit<
10
12
  AutocompleteProps<T, undefined, false, false>,
11
13
  'renderInput' | 'options'
12
14
  > {
13
15
  /**
14
16
  * Id field, default is id
15
17
  */
16
- idField?: string & keyof T;
18
+ idField: D;
17
19
 
18
20
  /**
19
21
  * Id value
20
22
  */
21
- idValue?: DataTypes.IdType;
23
+ idValue?: T[D];
22
24
 
23
25
  /**
24
26
  * Autocomplete for the input
@@ -1,5 +1,4 @@
1
- import { IdLabelDto } from '@etsoo/appscript';
2
- import { Keyboard } from '@etsoo/shared';
1
+ import { DataTypes, Keyboard } from '@etsoo/shared';
3
2
  import { Autocomplete, AutocompleteRenderInputParams } from '@mui/material';
4
3
  import React from 'react';
5
4
  import { Utils as SharedUtils } from '@etsoo/shared';
@@ -11,8 +10,10 @@ import { ReactUtils } from '../app/ReactUtils';
11
10
  /**
12
11
  * ComboBox props
13
12
  */
14
- export interface ComboBoxProps<T extends {}>
15
- extends AutocompleteExtendedProps<T> {
13
+ export interface ComboBoxProps<
14
+ T extends {},
15
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
16
+ > extends AutocompleteExtendedProps<T, D> {
16
17
  /**
17
18
  * Auto add blank item
18
19
  */
@@ -26,7 +27,7 @@ export interface ComboBoxProps<T extends {}>
26
27
  /**
27
28
  * Label field
28
29
  */
29
- labelField?: string & keyof T;
30
+ labelField: D;
30
31
 
31
32
  /**
32
33
  * Load data callback
@@ -49,12 +50,15 @@ export interface ComboBoxProps<T extends {}>
49
50
  * @param props Props
50
51
  * @returns Component
51
52
  */
52
- export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
53
+ export function ComboBox<
54
+ T extends {} = DataTypes.IdLabelItem,
55
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
56
+ >(props: ComboBoxProps<T, D>) {
53
57
  // Destruct
54
58
  const {
55
59
  search = false,
56
60
  autoAddBlankItem = search,
57
- idField = 'id',
61
+ idField,
58
62
  idValue,
59
63
  inputError,
60
64
  inputHelperText,
@@ -64,7 +68,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
64
68
  inputVariant,
65
69
  defaultValue,
66
70
  label,
67
- labelField = 'label',
71
+ labelField,
68
72
  loadData,
69
73
  onLoadData,
70
74
  name,
@@ -75,7 +79,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
75
79
  onChange,
76
80
  openOnFocus = true,
77
81
  value,
78
- getOptionLabel = (option: T) => String(Reflect.get(option, labelField)),
82
+ getOptionLabel = (option: T) => `${option[labelField]}`,
79
83
  sx = { minWidth: '150px' },
80
84
  ...rest
81
85
  } = props;
@@ -97,7 +101,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
97
101
  // Local default value
98
102
  let localValue =
99
103
  idValue != null
100
- ? localOptions.find((o) => Reflect.get(o, idField) === idValue)
104
+ ? localOptions.find((o) => o[idField] === idValue)
101
105
  : defaultValue ?? value;
102
106
 
103
107
  if (localValue === undefined) localValue = null;
@@ -108,7 +112,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
108
112
 
109
113
  // Current id value
110
114
  // One time calculation for input's default value (uncontrolled)
111
- const localIdValue = stateValue && Reflect.get(stateValue, idField);
115
+ const localIdValue = stateValue && stateValue[idField];
112
116
 
113
117
  React.useEffect(() => {
114
118
  if (localValue != null) setStateValue(localValue);
@@ -147,8 +151,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
147
151
  const input = inputRef.current;
148
152
  if (input) {
149
153
  // Update value
150
- const newValue =
151
- value != null ? `${Reflect.get(value, idField)}` : '';
154
+ const newValue = value != null ? `${value[idField]}` : '';
152
155
 
153
156
  if (newValue !== input.value) {
154
157
  // Different value, trigger change event
@@ -186,7 +189,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
186
189
  type="text"
187
190
  style={{ display: 'none' }}
188
191
  name={name}
189
- value={localIdValue ?? ''}
192
+ value={`${localIdValue ?? ''}`}
190
193
  readOnly
191
194
  onChange={inputOnChange}
192
195
  />
@@ -195,7 +198,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
195
198
  value={stateValue}
196
199
  getOptionLabel={getOptionLabel}
197
200
  isOptionEqualToValue={(option: T, value: T) =>
198
- Reflect.get(option, idField) === Reflect.get(value, idField)
201
+ option[idField] === value[idField]
199
202
  }
200
203
  onChange={(event, value, reason, details) => {
201
204
  // Set value
@@ -28,5 +28,11 @@ export function SelectBool(props: SelectBoolProps) {
28
28
  if (autoAddBlankItem) Utils.addBlankItem(options);
29
29
 
30
30
  // Layout
31
- return <SelectEx options={options} search={search} {...rest} />;
31
+ return (
32
+ <SelectEx<IdLabelDto<string>>
33
+ options={options}
34
+ search={search}
35
+ {...rest}
36
+ />
37
+ );
32
38
  }
@@ -11,25 +11,26 @@ import {
11
11
  } from '@mui/material';
12
12
  import React from 'react';
13
13
  import { MUGlobal } from './MUGlobal';
14
- import { IdLabelDto } from '@etsoo/appscript';
15
14
  import { ListItemRightIcon } from './ListItemRightIcon';
16
- import { Utils } from '@etsoo/shared';
15
+ import { DataTypes, Utils } from '@etsoo/shared';
17
16
  import { ReactUtils } from '../app/ReactUtils';
18
17
 
19
18
  /**
20
19
  * Extended select component props
21
20
  */
22
- export interface SelectExProps<T extends {}>
23
- extends Omit<SelectProps, 'labelId' | 'input' | 'native'> {
21
+ export interface SelectExProps<
22
+ T extends {},
23
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
24
+ > extends Omit<SelectProps, 'labelId' | 'input' | 'native'> {
24
25
  /**
25
26
  * Auto add blank item
26
27
  */
27
28
  autoAddBlankItem?: boolean;
28
29
 
29
30
  /**
30
- * Id field, default is id
31
+ * Id field
31
32
  */
32
- idField?: string & keyof T;
33
+ idField: D;
33
34
 
34
35
  /**
35
36
  * Item icon renderer
@@ -37,9 +38,9 @@ export interface SelectExProps<T extends {}>
37
38
  itemIconRenderer?: (id: unknown) => React.ReactNode;
38
39
 
39
40
  /**
40
- * Label field, default is label
41
+ * Label field
41
42
  */
42
- labelField?: ((option: T) => string) | (string & keyof T);
43
+ labelField: ((option: T) => string) | D;
43
44
 
44
45
  /**
45
46
  * Load data callback
@@ -72,14 +73,17 @@ export interface SelectExProps<T extends {}>
72
73
  * @param props Props
73
74
  * @returns Component
74
75
  */
75
- export function SelectEx<T extends {} = IdLabelDto>(props: SelectExProps<T>) {
76
+ export function SelectEx<
77
+ T extends {} = DataTypes.IdLabelItem,
78
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
79
+ >(props: SelectExProps<T, D>) {
76
80
  // Destruct
77
81
  const {
78
82
  defaultValue,
79
- idField = 'id',
83
+ idField,
80
84
  itemIconRenderer,
81
85
  label,
82
- labelField = 'label',
86
+ labelField,
83
87
  loadData,
84
88
  onItemClick,
85
89
  onLoadData,
@@ -153,14 +157,14 @@ export function SelectEx<T extends {} = IdLabelDto>(props: SelectExProps<T>) {
153
157
 
154
158
  // Get option id
155
159
  const getId = (option: T) => {
156
- return Reflect.get(option, idField);
160
+ return option[idField] as unknown as React.Key;
157
161
  };
158
162
 
159
163
  // Get option label
160
164
  const getLabel = (option: T) => {
161
165
  return typeof labelField === 'function'
162
166
  ? labelField(option)
163
- : Reflect.get(option, labelField);
167
+ : new String(option[labelField]);
164
168
  };
165
169
 
166
170
  // Refs
@@ -1,4 +1,3 @@
1
- import { IdLabelDto } from '@etsoo/appscript';
2
1
  import { DataTypes } from '@etsoo/shared';
3
2
  import { Autocomplete, AutocompleteRenderInputParams } from '@mui/material';
4
3
  import React from 'react';
@@ -11,14 +10,14 @@ import { SearchField } from './SearchField';
11
10
  /**
12
11
  * Tiplist props
13
12
  */
14
- export interface TiplistProps<T extends {}>
15
- extends Omit<AutocompleteExtendedProps<T>, 'open'> {
13
+ export interface TiplistProps<T extends {}, D extends DataTypes.Keys<T>>
14
+ extends Omit<AutocompleteExtendedProps<T, D>, 'open'> {
16
15
  /**
17
16
  * Load data callback
18
17
  */
19
18
  loadData: (
20
19
  keyword?: string,
21
- id?: DataTypes.IdType
20
+ id?: T[D]
22
21
  ) => PromiseLike<T[] | null | undefined>;
23
22
  }
24
23
 
@@ -35,11 +34,13 @@ interface States<T extends {}> {
35
34
  * @param props Props
36
35
  * @returns Component
37
36
  */
38
- export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
37
+ export function Tiplist<T extends {}, D extends DataTypes.Keys<T>>(
38
+ props: TiplistProps<T, D>
39
+ ) {
39
40
  // Destruct
40
41
  const {
41
42
  search = false,
42
- idField = 'id',
43
+ idField,
43
44
  idValue,
44
45
  inputAutoComplete = 'off',
45
46
  inputError,
@@ -68,8 +69,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
68
69
  if (localValue === undefined) localValue = null;
69
70
 
70
71
  // One time calculation for input's default value (uncontrolled)
71
- const localIdValue =
72
- idValue ?? (localValue && Reflect.get(localValue, idField));
72
+ const localIdValue = idValue ?? (localValue && localValue[idField]);
73
73
 
74
74
  // Changable states
75
75
  const [states, stateUpdate] = React.useReducer(
@@ -86,7 +86,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
86
86
 
87
87
  // Input value
88
88
  const inputValue = React.useMemo(
89
- () => states.value && Reflect.get(states.value, idField),
89
+ () => states.value && states.value[idField],
90
90
  [states.value]
91
91
  );
92
92
 
@@ -130,7 +130,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
130
130
  };
131
131
 
132
132
  // Directly load data
133
- const loadDataDirect = (keyword?: string, id?: DataTypes.IdType) => {
133
+ const loadDataDirect = (keyword?: string, id?: T[D]) => {
134
134
  // Reset options
135
135
  // setOptions([]);
136
136
 
@@ -181,7 +181,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
181
181
  }
182
182
  };
183
183
 
184
- if (localIdValue != null && localIdValue !== '') {
184
+ if (localIdValue != null && (localIdValue as any) !== '') {
185
185
  if (state.idLoaded) {
186
186
  // Set default
187
187
  if (!state.idSet && states.options.length == 1) {
@@ -211,7 +211,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
211
211
  type="text"
212
212
  style={{ display: 'none' }}
213
213
  name={name}
214
- value={inputValue ?? ''}
214
+ value={`${inputValue ?? ''}`}
215
215
  readOnly
216
216
  onChange={inputOnChange}
217
217
  />
@@ -250,7 +250,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
250
250
  undefined,
251
251
  states.value == null
252
252
  ? undefined
253
- : Reflect.get(states.value, idField)
253
+ : states.value[idField]
254
254
  );
255
255
  }}
256
256
  onClose={() => {
@@ -291,7 +291,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
291
291
  />
292
292
  )
293
293
  }
294
- isOptionEqualToValue={(option: any, value: any) =>
294
+ isOptionEqualToValue={(option: T, value: T) =>
295
295
  option[idField] === value[idField]
296
296
  }
297
297
  {...rest}