@etsoo/react 1.4.50 → 1.4.55

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.
@@ -114,9 +114,10 @@ export declare class ReactApp<S extends IAppSettings, D extends IUser, P extends
114
114
  };
115
115
  /**
116
116
  * Get money format props
117
+ * @param currency Currency, if undefined, default currency applied
117
118
  * @returns Props
118
119
  */
119
- getMoneyFormatProps(): {
120
+ getMoneyFormatProps(currency?: string): {
120
121
  culture: string;
121
122
  currency: string;
122
123
  };
@@ -150,10 +150,11 @@ export class ReactApp extends CoreApp {
150
150
  }
151
151
  /**
152
152
  * Get money format props
153
+ * @param currency Currency, if undefined, default currency applied
153
154
  * @returns Props
154
155
  */
155
- getMoneyFormatProps() {
156
- return { culture: this.culture, currency: this.currency };
156
+ getMoneyFormatProps(currency) {
157
+ return { culture: this.culture, currency: currency !== null && currency !== void 0 ? currency : this.currency };
157
158
  }
158
159
  /**
159
160
  * Fresh countdown UI
package/lib/index.d.ts CHANGED
@@ -65,6 +65,7 @@ export * from './mu/SearchField';
65
65
  export * from './mu/SearchOptionGroup';
66
66
  export * from './mu/SelectEx';
67
67
  export * from './mu/Switch';
68
+ export * from './mu/SwitchAnt';
68
69
  export * from './mu/TabBox';
69
70
  export * from './mu/TableEx';
70
71
  export * from './mu/TextFieldEx';
package/lib/index.js CHANGED
@@ -68,6 +68,7 @@ export * from './mu/SearchField';
68
68
  export * from './mu/SearchOptionGroup';
69
69
  export * from './mu/SelectEx';
70
70
  export * from './mu/Switch';
71
+ export * from './mu/SwitchAnt';
71
72
  export * from './mu/TabBox';
72
73
  export * from './mu/TableEx';
73
74
  export * from './mu/TextFieldEx';
@@ -5,6 +5,10 @@ import { AutocompleteExtendedProps } from './AutocompleteExtendedProps';
5
5
  * ComboBox props
6
6
  */
7
7
  export interface ComboBoxProps<T extends {}> extends AutocompleteExtendedProps<T> {
8
+ /**
9
+ * Data readonly
10
+ */
11
+ dataReadonly?: boolean;
8
12
  /**
9
13
  * Label field
10
14
  */
@@ -1,3 +1,4 @@
1
+ import { Keyboard } from '@etsoo/shared';
1
2
  import { Autocomplete } from '@mui/material';
2
3
  import React from 'react';
3
4
  import { Utils } from '../app/Utils';
@@ -10,7 +11,7 @@ import { SearchField } from './SearchField';
10
11
  */
11
12
  export function ComboBox(props) {
12
13
  // Destruct
13
- const { search = false, idField = 'id', idValue, inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, defaultValue, label, labelField = 'label', loadData, onLoadData, name, inputAutoComplete = 'off', options, readOnly = true, onChange, value, getOptionLabel = (option) => String(Reflect.get(option, labelField)), sx = { minWidth: '150px' }, ...rest } = props;
14
+ const { search = false, 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;
14
15
  // Value input ref
15
16
  const inputRef = React.createRef();
16
17
  // Options state
@@ -47,6 +48,13 @@ export function ComboBox(props) {
47
48
  Object.assign(params.inputProps, { 'data-reset': true });
48
49
  }
49
50
  }
51
+ if (dataReadonly) {
52
+ params.inputProps.onKeyDown = (event) => {
53
+ if (Keyboard.isTypingContent(event.key)) {
54
+ event.preventDefault();
55
+ }
56
+ };
57
+ }
50
58
  // https://stackoverflow.com/questions/15738259/disabling-chrome-autofill
51
59
  // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html
52
60
  Object.assign(params.inputProps, { autoComplete: inputAutoComplete });
@@ -89,5 +97,5 @@ export function ComboBox(props) {
89
97
  // Custom
90
98
  if (onChange != null)
91
99
  onChange(event, value, reason, details);
92
- }, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { ...addReadOnly(params), label: label, name: name + 'Input', margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })) : (React.createElement(InputField, { ...addReadOnly(params), label: label, name: name + 'Input', margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })), options: localOptions, ...rest })));
100
+ }, openOnFocus: openOnFocus, sx: sx, renderInput: (params) => search ? (React.createElement(SearchField, { ...addReadOnly(params), label: label, name: name + 'Input', margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })) : (React.createElement(InputField, { ...addReadOnly(params), label: label, name: name + 'Input', margin: inputMargin, variant: inputVariant, required: inputRequired, error: inputError, helperText: inputHelperText })), options: localOptions, ...rest })));
93
101
  }
@@ -12,5 +12,6 @@ export declare function MobileListItemRenderer<T>({ data, itemHeight, margins }:
12
12
  string,
13
13
  string | undefined,
14
14
  React.ReactNode | (ListItemReact | boolean)[],
15
- React.ReactNode
15
+ React.ReactNode,
16
+ React.ReactNode?
16
17
  ]): JSX.Element;
@@ -23,7 +23,7 @@ export function MobileListItemRenderer({ data, itemHeight, margins }, renderer)
23
23
  if (data == null)
24
24
  return React.createElement(LinearProgress, null);
25
25
  // Elements
26
- const [title, subheader, actions, children] = renderer(data);
26
+ const [title, subheader, actions, children, cardActions] = renderer(data);
27
27
  return (React.createElement(Card, { sx: {
28
28
  height: itemHeight,
29
29
  ...margins
@@ -62,5 +62,6 @@ export function MobileListItemRenderer({ data, itemHeight, margins }, renderer)
62
62
  } })) : (actions), title: title, titleTypographyProps: { variant: 'body2' }, subheader: subheader, subheaderTypographyProps: { variant: 'caption' } }),
63
63
  React.createElement(CardContent, { sx: {
64
64
  paddingTop: 0
65
- } }, children)));
65
+ } }, children),
66
+ cardActions && cardActions));
66
67
  }
package/lib/mu/Switch.js CHANGED
@@ -8,13 +8,20 @@ import MuiSwitch from '@mui/material/Switch';
8
8
  * @returns Component
9
9
  */
10
10
  export function Switch(props) {
11
+ var _a;
11
12
  // Destruct
12
- const { defaultChecked, defaultValue, readOnly, size, checkbox = false, value = 'true', ...rest } = props;
13
+ const { checked, defaultChecked, defaultValue, onChange, readOnly, size, checkbox = false, value = 'true', ...rest } = props;
13
14
  // Checked state
14
- const [controlChecked, setControlChecked] = React.useState(defaultChecked !== null && defaultChecked !== void 0 ? defaultChecked : defaultValue == value);
15
+ const [controlChecked, setControlChecked] = React.useState((_a = checked !== null && checked !== void 0 ? checked : defaultChecked) !== null && _a !== void 0 ? _a : defaultValue == value);
16
+ React.useEffect(() => {
17
+ if (checked)
18
+ setControlChecked(checked);
19
+ }, [checked]);
15
20
  // Handle change
16
- const handleChange = (event) => {
17
- setControlChecked(event.target.checked);
21
+ const handleChange = (event, checked) => {
22
+ if (onChange)
23
+ onChange(event, checked);
24
+ setControlChecked(checked);
18
25
  };
19
26
  // Control
20
27
  const control = checkbox ? (React.createElement(MuiCheckbox, { readOnly: readOnly, checked: controlChecked, onChange: handleChange, size: size, value: value })) : (React.createElement(MuiSwitch, { readOnly: readOnly, checked: controlChecked, onChange: handleChange, size: size, value: value }));
@@ -0,0 +1,25 @@
1
+ /// <reference types="react" />
2
+ import { SwitchProps } from '@mui/material/Switch';
3
+ /**
4
+ * Ant style switch props
5
+ */
6
+ export interface SwitchAntProps extends SwitchProps {
7
+ /**
8
+ *
9
+ */
10
+ activeColor?: string;
11
+ /**
12
+ * Start label
13
+ */
14
+ startLabel: string;
15
+ /**
16
+ * End label
17
+ */
18
+ endLabel: string;
19
+ }
20
+ /**
21
+ * Ant style switch
22
+ * @param props Props
23
+ * @returns Component
24
+ */
25
+ export declare function SwitchAnt(props: SwitchAntProps): JSX.Element;
@@ -0,0 +1,40 @@
1
+ import { Stack, Typography } from '@mui/material';
2
+ import Switch from '@mui/material/Switch';
3
+ import React from 'react';
4
+ /**
5
+ * Ant style switch
6
+ * @param props Props
7
+ * @returns Component
8
+ */
9
+ export function SwitchAnt(props) {
10
+ var _a;
11
+ // Destruct
12
+ const { activeColor, checked, defaultChecked, defaultValue, endLabel, startLabel, onChange, value = 'true', ...rest } = props;
13
+ // Checked state
14
+ const [controlChecked, setControlChecked] = React.useState((_a = checked !== null && checked !== void 0 ? checked : defaultChecked) !== null && _a !== void 0 ? _a : defaultValue == value);
15
+ React.useEffect(() => {
16
+ if (checked)
17
+ setControlChecked(checked);
18
+ }, [checked]);
19
+ // On change
20
+ const onChangeLocal = (event, checked) => {
21
+ if (onChange)
22
+ onChange(event, checked);
23
+ setControlChecked(checked);
24
+ };
25
+ // Layout
26
+ return (React.createElement(Stack, { direction: "row", spacing: 1, alignItems: "center" },
27
+ React.createElement(Typography, { onClick: () => setControlChecked(false), sx: {
28
+ cursor: 'pointer',
29
+ color: controlChecked
30
+ ? undefined
31
+ : (theme) => activeColor !== null && activeColor !== void 0 ? activeColor : theme.palette.warning.main
32
+ } }, startLabel),
33
+ React.createElement(Switch, { checked: controlChecked, value: value, onChange: onChangeLocal, ...rest }),
34
+ React.createElement(Typography, { onClick: () => setControlChecked(true), sx: {
35
+ cursor: 'pointer',
36
+ color: controlChecked
37
+ ? (theme) => activeColor !== null && activeColor !== void 0 ? activeColor : theme.palette.warning.main
38
+ : undefined
39
+ } }, endLabel)));
40
+ }
@@ -3,6 +3,7 @@ import { IconButton, InputAdornment, TextField } from '@mui/material';
3
3
  import { MUGlobal } from './MUGlobal';
4
4
  import { Clear, Visibility } from '@mui/icons-material';
5
5
  import useCombinedRefs from '../uses/useCombinedRefs';
6
+ import { Keyboard } from '@etsoo/shared';
6
7
  export const TextFieldEx = React.forwardRef((props, ref) => {
7
8
  // Destructure
8
9
  const { changeDelay, error, fullWidth = true, helperText, InputProps = {}, onChange, onKeyPress, onEnter, inputRef, readOnly, showClear, showPassword, type, variant = MUGlobal.textFieldVariant, ...rest } = props;
@@ -71,7 +72,7 @@ export const TextFieldEx = React.forwardRef((props, ref) => {
71
72
  const onKeyPressEx = onEnter == null
72
73
  ? onKeyPress
73
74
  : (e) => {
74
- if (e.key === 'Enter') {
75
+ if (e.key === Keyboard.Keys.Enter) {
75
76
  // Enter press callback
76
77
  onEnter(e);
77
78
  }
package/lib/mu/Tiplist.js CHANGED
@@ -11,7 +11,7 @@ import { SearchField } from './SearchField';
11
11
  */
12
12
  export function Tiplist(props) {
13
13
  // Destruct
14
- const { search = false, idField = 'id', idValue, inputAutoComplete = 'off', inputError, inputHelperText, inputMargin, inputOnChange, inputRequired, inputVariant, label, loadData, defaultValue, value, name, readOnly, onChange, sx = { minWidth: '180px' }, ...rest } = props;
14
+ 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
15
  // Value input ref
16
16
  const inputRef = React.createRef();
17
17
  // Local value
@@ -145,7 +145,7 @@ export function Tiplist(props) {
145
145
  stateUpdate({ options: [] });
146
146
  loadDataDirect();
147
147
  }
148
- }, open: states.open, onOpen: () => {
148
+ }, open: states.open, openOnFocus: openOnFocus, onOpen: () => {
149
149
  // Should load
150
150
  const loading = states.loading
151
151
  ? true
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@etsoo/react",
3
- "version": "1.4.50",
3
+ "version": "1.4.55",
4
4
  "description": "TypeScript ReactJs framework",
5
5
  "main": "lib/index.js",
6
6
  "types": "lib/index.d.ts",
@@ -50,9 +50,9 @@
50
50
  "@emotion/react": "^11.7.1",
51
51
  "@emotion/style": "^0.8.0",
52
52
  "@emotion/styled": "^11.6.0",
53
- "@etsoo/appscript": "^1.2.25",
53
+ "@etsoo/appscript": "^1.2.27",
54
54
  "@etsoo/notificationbase": "^1.1.0",
55
- "@etsoo/shared": "^1.1.5",
55
+ "@etsoo/shared": "^1.1.6",
56
56
  "@mui/icons-material": "^5.3.0",
57
57
  "@mui/material": "^5.3.0",
58
58
  "@reach/router": "^1.3.4",
@@ -77,9 +77,9 @@
77
77
  },
78
78
  "devDependencies": {
79
79
  "@babel/cli": "^7.16.8",
80
- "@babel/core": "^7.16.7",
81
- "@babel/plugin-transform-runtime": "^7.16.8",
82
- "@babel/preset-env": "^7.16.8",
80
+ "@babel/core": "^7.16.10",
81
+ "@babel/plugin-transform-runtime": "^7.16.10",
82
+ "@babel/preset-env": "^7.16.11",
83
83
  "@babel/runtime-corejs3": "^7.16.8",
84
84
  "@types/jest": "^27.4.0",
85
85
  "@types/react-test-renderer": "^17.0.1",
@@ -92,6 +92,6 @@
92
92
  "jest": "^27.4.7",
93
93
  "react-test-renderer": "^17.0.2",
94
94
  "ts-jest": "^27.1.3",
95
- "typescript": "^4.5.4"
95
+ "typescript": "^4.5.5"
96
96
  }
97
97
  }
@@ -292,10 +292,11 @@ export class ReactApp<
292
292
 
293
293
  /**
294
294
  * Get money format props
295
+ * @param currency Currency, if undefined, default currency applied
295
296
  * @returns Props
296
297
  */
297
- getMoneyFormatProps() {
298
- return { culture: this.culture, currency: this.currency };
298
+ getMoneyFormatProps(currency?: string) {
299
+ return { culture: this.culture, currency: currency ?? this.currency };
299
300
  }
300
301
 
301
302
  /**
package/src/index.ts CHANGED
@@ -72,6 +72,7 @@ export * from './mu/SearchField';
72
72
  export * from './mu/SearchOptionGroup';
73
73
  export * from './mu/SelectEx';
74
74
  export * from './mu/Switch';
75
+ export * from './mu/SwitchAnt';
75
76
  export * from './mu/TabBox';
76
77
  export * from './mu/TableEx';
77
78
  export * from './mu/TextFieldEx';
@@ -1,4 +1,5 @@
1
1
  import { IdLabelDto } from '@etsoo/appscript';
2
+ import { Keyboard } from '@etsoo/shared';
2
3
  import { Autocomplete, AutocompleteRenderInputParams } from '@mui/material';
3
4
  import React from 'react';
4
5
  import { Utils } from '../app/Utils';
@@ -11,6 +12,11 @@ import { SearchField } from './SearchField';
11
12
  */
12
13
  export interface ComboBoxProps<T extends {}>
13
14
  extends AutocompleteExtendedProps<T> {
15
+ /**
16
+ * Data readonly
17
+ */
18
+ dataReadonly?: boolean;
19
+
14
20
  /**
15
21
  * Label field
16
22
  */
@@ -57,8 +63,10 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
57
63
  name,
58
64
  inputAutoComplete = 'off',
59
65
  options,
60
- readOnly = true,
66
+ dataReadonly = true,
67
+ readOnly,
61
68
  onChange,
69
+ openOnFocus = true,
62
70
  value,
63
71
  getOptionLabel = (option: T) => String(Reflect.get(option, labelField)),
64
72
  sx = { minWidth: '150px' },
@@ -109,6 +117,14 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
109
117
  }
110
118
  }
111
119
 
120
+ if (dataReadonly) {
121
+ params.inputProps.onKeyDown = (event) => {
122
+ if (Keyboard.isTypingContent(event.key)) {
123
+ event.preventDefault();
124
+ }
125
+ };
126
+ }
127
+
112
128
  // https://stackoverflow.com/questions/15738259/disabling-chrome-autofill
113
129
  // https://html.spec.whatwg.org/multipage/form-control-infrastructure.html
114
130
  Object.assign(params.inputProps, { autoComplete: inputAutoComplete });
@@ -176,6 +192,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
176
192
  if (onChange != null)
177
193
  onChange(event, value, reason, details);
178
194
  }}
195
+ openOnFocus={openOnFocus}
179
196
  sx={sx}
180
197
  renderInput={(params) =>
181
198
  search ? (
@@ -29,14 +29,15 @@ export function MobileListItemRenderer<T>(
29
29
  string,
30
30
  string | undefined,
31
31
  React.ReactNode | (ListItemReact | boolean)[],
32
- React.ReactNode
32
+ React.ReactNode,
33
+ React.ReactNode?
33
34
  ]
34
35
  ) {
35
36
  // Loading
36
37
  if (data == null) return <LinearProgress />;
37
38
 
38
39
  // Elements
39
- const [title, subheader, actions, children] = renderer(data);
40
+ const [title, subheader, actions, children, cardActions] = renderer(data);
40
41
 
41
42
  return (
42
43
  <Card
@@ -105,6 +106,7 @@ export function MobileListItemRenderer<T>(
105
106
  >
106
107
  {children}
107
108
  </CardContent>
109
+ {cardActions && cardActions}
108
110
  </Card>
109
111
  );
110
112
  }
package/src/mu/Switch.tsx CHANGED
@@ -36,8 +36,10 @@ export interface SwitchProps extends Omit<FormControlLabelProps, 'control'> {
36
36
  export function Switch(props: SwitchProps) {
37
37
  // Destruct
38
38
  const {
39
+ checked,
39
40
  defaultChecked,
40
41
  defaultValue,
42
+ onChange,
41
43
  readOnly,
42
44
  size,
43
45
  checkbox = false,
@@ -47,12 +49,20 @@ export function Switch(props: SwitchProps) {
47
49
 
48
50
  // Checked state
49
51
  const [controlChecked, setControlChecked] = React.useState(
50
- defaultChecked ?? defaultValue == value
52
+ checked ?? defaultChecked ?? defaultValue == value
51
53
  );
52
54
 
55
+ React.useEffect(() => {
56
+ if (checked) setControlChecked(checked);
57
+ }, [checked]);
58
+
53
59
  // Handle change
54
- const handleChange = (event: React.ChangeEvent<HTMLInputElement>) => {
55
- setControlChecked(event.target.checked);
60
+ const handleChange = (
61
+ event: React.ChangeEvent<HTMLInputElement>,
62
+ checked: boolean
63
+ ) => {
64
+ if (onChange) onChange(event, checked);
65
+ setControlChecked(checked);
56
66
  };
57
67
 
58
68
  // Control
@@ -0,0 +1,95 @@
1
+ import { Stack, Typography } from '@mui/material';
2
+ import Switch, { SwitchProps } from '@mui/material/Switch';
3
+ import React from 'react';
4
+
5
+ /**
6
+ * Ant style switch props
7
+ */
8
+ export interface SwitchAntProps extends SwitchProps {
9
+ /**
10
+ *
11
+ */
12
+ activeColor?: string;
13
+
14
+ /**
15
+ * Start label
16
+ */
17
+ startLabel: string;
18
+
19
+ /**
20
+ * End label
21
+ */
22
+ endLabel: string;
23
+ }
24
+
25
+ /**
26
+ * Ant style switch
27
+ * @param props Props
28
+ * @returns Component
29
+ */
30
+ export function SwitchAnt(props: SwitchAntProps) {
31
+ // Destruct
32
+ const {
33
+ activeColor,
34
+ checked,
35
+ defaultChecked,
36
+ defaultValue,
37
+ endLabel,
38
+ startLabel,
39
+ onChange,
40
+ value = 'true',
41
+ ...rest
42
+ } = props;
43
+
44
+ // Checked state
45
+ const [controlChecked, setControlChecked] = React.useState(
46
+ checked ?? defaultChecked ?? defaultValue == value
47
+ );
48
+
49
+ React.useEffect(() => {
50
+ if (checked) setControlChecked(checked);
51
+ }, [checked]);
52
+
53
+ // On change
54
+ const onChangeLocal = (
55
+ event: React.ChangeEvent<HTMLInputElement>,
56
+ checked: boolean
57
+ ) => {
58
+ if (onChange) onChange(event, checked);
59
+ setControlChecked(checked);
60
+ };
61
+
62
+ // Layout
63
+ return (
64
+ <Stack direction="row" spacing={1} alignItems="center">
65
+ <Typography
66
+ onClick={() => setControlChecked(false)}
67
+ sx={{
68
+ cursor: 'pointer',
69
+ color: controlChecked
70
+ ? undefined
71
+ : (theme) => activeColor ?? theme.palette.warning.main
72
+ }}
73
+ >
74
+ {startLabel}
75
+ </Typography>
76
+ <Switch
77
+ checked={controlChecked}
78
+ value={value}
79
+ onChange={onChangeLocal}
80
+ {...rest}
81
+ />
82
+ <Typography
83
+ onClick={() => setControlChecked(true)}
84
+ sx={{
85
+ cursor: 'pointer',
86
+ color: controlChecked
87
+ ? (theme) => activeColor ?? theme.palette.warning.main
88
+ : undefined
89
+ }}
90
+ >
91
+ {endLabel}
92
+ </Typography>
93
+ </Stack>
94
+ );
95
+ }
@@ -8,6 +8,7 @@ import {
8
8
  import { MUGlobal } from './MUGlobal';
9
9
  import { Clear, Visibility } from '@mui/icons-material';
10
10
  import useCombinedRefs from '../uses/useCombinedRefs';
11
+ import { Keyboard } from '@etsoo/shared';
11
12
 
12
13
  /**
13
14
  * Extended text field props
@@ -166,7 +167,7 @@ export const TextFieldEx = React.forwardRef<
166
167
  onEnter == null
167
168
  ? onKeyPress
168
169
  : (e: React.KeyboardEvent<HTMLDivElement>) => {
169
- if (e.key === 'Enter') {
170
+ if (e.key === Keyboard.Keys.Enter) {
170
171
  // Enter press callback
171
172
  onEnter(e);
172
173
  }
@@ -54,6 +54,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
54
54
  name,
55
55
  readOnly,
56
56
  onChange,
57
+ openOnFocus = true,
57
58
  sx = { minWidth: '180px' },
58
59
  ...rest
59
60
  } = props;
@@ -242,6 +243,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
242
243
  }
243
244
  }}
244
245
  open={states.open}
246
+ openOnFocus={openOnFocus}
245
247
  onOpen={() => {
246
248
  // Should load
247
249
  const loading = states.loading