@etsoo/react 1.5.75 → 1.5.78

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/lib/app/CommonApp.d.ts +2 -2
  2. package/lib/app/Labels.d.ts +1 -1
  3. package/lib/app/ServiceApp.d.ts +2 -2
  4. package/lib/components/GridColumn.d.ts +10 -10
  5. package/lib/components/GridLoader.d.ts +7 -8
  6. package/lib/components/ScrollerGrid.d.ts +7 -7
  7. package/lib/components/ScrollerList.d.ts +2 -2
  8. package/lib/mu/AutocompleteExtendedProps.d.ts +9 -7
  9. package/lib/mu/ComboBox.d.ts +10 -8
  10. package/lib/mu/ComboBox.js +6 -6
  11. package/lib/mu/DataGridEx.d.ts +6 -5
  12. package/lib/mu/DataGridRenderers.d.ts +1 -1
  13. package/lib/mu/DnDList.d.ts +2 -2
  14. package/lib/mu/ListMoreDisplay.d.ts +2 -2
  15. package/lib/mu/MUGlobal.d.ts +5 -5
  16. package/lib/mu/OptionGroup.d.ts +17 -14
  17. package/lib/mu/ResponsibleContainer.d.ts +5 -5
  18. package/lib/mu/ScrollerListEx.d.ts +11 -9
  19. package/lib/mu/ScrollerListEx.js +1 -1
  20. package/lib/mu/SearchOptionGroup.d.ts +1 -2
  21. package/lib/mu/SelectBool.d.ts +2 -2
  22. package/lib/mu/SelectBool.js +1 -1
  23. package/lib/mu/SelectEx.d.ts +16 -12
  24. package/lib/mu/SelectEx.js +2 -2
  25. package/lib/mu/TableEx.d.ts +10 -7
  26. package/lib/mu/TableEx.js +1 -2
  27. package/lib/mu/Tiplist.d.ts +4 -5
  28. package/lib/mu/Tiplist.js +4 -6
  29. package/lib/mu/pages/CommonPageProps.d.ts +1 -1
  30. package/lib/mu/pages/DataGridPage.d.ts +1 -1
  31. package/lib/mu/pages/DataGridPageProps.d.ts +2 -2
  32. package/lib/mu/pages/FixedListPage.d.ts +1 -1
  33. package/lib/mu/pages/ListPage.d.ts +1 -1
  34. package/lib/mu/pages/ListPageProps.d.ts +1 -2
  35. package/lib/mu/pages/ResponsivePage.d.ts +1 -1
  36. package/lib/mu/pages/ResponsivePageProps.d.ts +2 -2
  37. package/lib/mu/pages/SearchPageProps.d.ts +2 -2
  38. package/lib/mu/pages/TablePage.d.ts +1 -1
  39. package/lib/mu/pages/TablePageProps.d.ts +1 -2
  40. package/lib/mu/pages/ViewPage.d.ts +5 -4
  41. package/lib/states/IState.d.ts +1 -1
  42. package/lib/uses/useCombinedRefs.d.ts +1 -1
  43. package/package.json +11 -11
  44. package/src/app/CommonApp.ts +2 -2
  45. package/src/app/Labels.ts +1 -1
  46. package/src/app/ServiceApp.ts +2 -2
  47. package/src/components/GridColumn.ts +10 -11
  48. package/src/components/GridLoader.ts +7 -7
  49. package/src/components/ScrollerGrid.tsx +66 -59
  50. package/src/components/ScrollerList.tsx +2 -4
  51. package/src/mu/AutocompleteExtendedProps.ts +15 -12
  52. package/src/mu/ComboBox.tsx +25 -21
  53. package/src/mu/DataGridEx.tsx +19 -18
  54. package/src/mu/DataGridRenderers.tsx +1 -1
  55. package/src/mu/DnDList.tsx +2 -2
  56. package/src/mu/ListMoreDisplay.tsx +2 -2
  57. package/src/mu/MUGlobal.ts +5 -5
  58. package/src/mu/OptionGroup.tsx +29 -27
  59. package/src/mu/ResponsibleContainer.tsx +18 -21
  60. package/src/mu/ScrollerListEx.tsx +24 -20
  61. package/src/mu/SearchOptionGroup.tsx +2 -3
  62. package/src/mu/SelectBool.tsx +13 -5
  63. package/src/mu/SelectEx.tsx +27 -20
  64. package/src/mu/TableEx.tsx +61 -59
  65. package/src/mu/Tiplist.tsx +20 -17
  66. package/src/mu/pages/CommonPageProps.ts +1 -1
  67. package/src/mu/pages/DataGridPage.tsx +14 -10
  68. package/src/mu/pages/DataGridPageProps.ts +16 -13
  69. package/src/mu/pages/FixedListPage.tsx +1 -1
  70. package/src/mu/pages/ListPage.tsx +1 -1
  71. package/src/mu/pages/ListPageProps.ts +4 -3
  72. package/src/mu/pages/ResponsivePage.tsx +5 -4
  73. package/src/mu/pages/ResponsivePageProps.ts +9 -6
  74. package/src/mu/pages/SearchPageProps.ts +5 -3
  75. package/src/mu/pages/TablePage.tsx +1 -1
  76. package/src/mu/pages/TablePageProps.ts +4 -3
  77. package/src/mu/pages/ViewPage.tsx +8 -6
  78. package/src/states/IState.ts +1 -1
  79. package/src/states/UserState.ts +1 -1
  80. package/src/uses/useCombinedRefs.ts +3 -3
@@ -30,18 +30,14 @@ import { SearchBar } from './SearchBar';
30
30
  /**
31
31
  * ResponsibleContainer props
32
32
  */
33
- export interface ResponsibleContainerProps<
34
- T extends {},
35
- F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
36
- > extends Omit<
37
- DataGridExProps<T>,
38
- | 'height'
39
- | 'itemKey'
40
- | 'loadData'
41
- | 'mRef'
42
- | 'onScroll'
43
- | 'onItemsRendered'
44
- > {
33
+ export type ResponsibleContainerProps<
34
+ T extends object,
35
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
36
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
37
+ > = Omit<
38
+ DataGridExProps<T, D>,
39
+ 'height' | 'itemKey' | 'loadData' | 'mRef' | 'onScroll' | 'onItemsRendered'
40
+ > & {
45
41
  /**
46
42
  * Height will be deducted
47
43
  * @param height Current calcuated height
@@ -57,7 +53,7 @@ export interface ResponsibleContainerProps<
57
53
  * Container box SX (dataGrid determines the case)
58
54
  */
59
55
  containerBoxSx?: (
60
- paddings: {},
56
+ paddings: Record<string, string | number>,
61
57
  hasFields: boolean,
62
58
  dataGrid?: boolean
63
59
  ) => SxProps<Theme>;
@@ -119,7 +115,7 @@ export interface ResponsibleContainerProps<
119
115
  /**
120
116
  * Paddings
121
117
  */
122
- paddings?: {};
118
+ paddings?: Record<string, string | number>;
123
119
 
124
120
  /**
125
121
  * Pull to refresh data
@@ -135,7 +131,7 @@ export interface ResponsibleContainerProps<
135
131
  * Size ready to read miliseconds span
136
132
  */
137
133
  sizeReadyMiliseconds?: number;
138
- }
134
+ };
139
135
 
140
136
  interface LocalRefs {
141
137
  rect?: DOMRect;
@@ -144,7 +140,7 @@ interface LocalRefs {
144
140
  }
145
141
 
146
142
  function defaultContainerBoxSx(
147
- paddings: {},
143
+ paddings: object,
148
144
  hasField: boolean,
149
145
  _dataGrid?: boolean
150
146
  ): SxProps<Theme> {
@@ -162,9 +158,10 @@ function defaultContainerBoxSx(
162
158
  * @returns Layout
163
159
  */
164
160
  export function ResponsibleContainer<
165
- T extends {},
166
- F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
167
- >(props: ResponsibleContainerProps<T, F>) {
161
+ T extends object,
162
+ F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate,
163
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
164
+ >(props: ResponsibleContainerProps<T, F, D>) {
168
165
  // Destruct
169
166
  const {
170
167
  adjustHeight,
@@ -286,7 +283,7 @@ export function ResponsibleContainer<
286
283
 
287
284
  return [
288
285
  <Box className="DataGridBox">
289
- <DataGridEx<T>
286
+ <DataGridEx<T, D>
290
287
  autoLoad={!hasFields}
291
288
  height={heightLocal}
292
289
  width={rect.width}
@@ -319,7 +316,7 @@ export function ResponsibleContainer<
319
316
 
320
317
  return [
321
318
  <Box className="ListBox" sx={{ height: heightLocal }}>
322
- <ScrollerListEx<T>
319
+ <ScrollerListEx<T, D>
323
320
  autoLoad={!hasFields}
324
321
  height={heightLocal}
325
322
  loadData={localLoadData}
@@ -47,7 +47,7 @@ const createGridStyle = (
47
47
  };
48
48
 
49
49
  // Default margin
50
- const defaultMargin = (margin: {}, isNarrow?: boolean) => {
50
+ const defaultMargin = (margin: object, isNarrow?: boolean) => {
51
51
  const half = MUGlobal.half(margin);
52
52
 
53
53
  if (isNarrow == null) {
@@ -100,7 +100,7 @@ export interface ScrollerListExInnerItemRendererProps<T>
100
100
  /**
101
101
  * Default margins
102
102
  */
103
- margins: {};
103
+ margins: object;
104
104
  }
105
105
 
106
106
  /**
@@ -110,25 +110,22 @@ export interface ScrollerListExInnerItemRendererProps<T>
110
110
  * 3. Dynamic calculation
111
111
  */
112
112
  export type ScrollerListExItemSize =
113
- | ((index: number) => [number, number] | [number, number, {}])
113
+ | ((index: number) => [number, number] | [number, number, object])
114
114
  | [number, number]
115
- | [number, {}, boolean?];
115
+ | [number, object, boolean?];
116
116
 
117
117
  /**
118
118
  * Extended ScrollerList Props
119
119
  */
120
- export interface ScrollerListExProps<T>
121
- extends Omit<ScrollerListProps<T>, 'itemRenderer' | 'itemSize'> {
120
+ export type ScrollerListExProps<
121
+ T extends object,
122
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
123
+ > = Omit<ScrollerListProps<T>, 'itemRenderer' | 'itemSize'> & {
122
124
  /**
123
125
  * Alternating colors for odd/even rows
124
126
  */
125
127
  alternatingColors?: [string?, string?];
126
128
 
127
- /**
128
- * Id field
129
- */
130
- idField?: string & keyof T;
131
-
132
129
  /**
133
130
  * Inner item renderer
134
131
  */
@@ -141,6 +138,12 @@ export interface ScrollerListExProps<T>
141
138
  */
142
139
  itemRenderer?: (props: ListChildComponentProps<T>) => React.ReactElement;
143
140
 
141
+ /**
142
+ * Id field
143
+ * Failed: D extends { id: DataTypes.IdType } ? { idField?: D } : { idField: D }
144
+ */
145
+ idField?: D;
146
+
144
147
  /**
145
148
  * Item size, a function indicates its a variable size list
146
149
  */
@@ -165,7 +168,7 @@ export interface ScrollerListExProps<T>
165
168
  * Selected color
166
169
  */
167
170
  selectedColor?: string;
168
- }
171
+ };
169
172
 
170
173
  interface defaultItemRendererProps<T> extends ListChildComponentProps<T> {
171
174
  /**
@@ -203,7 +206,7 @@ interface defaultItemRendererProps<T> extends ListChildComponentProps<T> {
203
206
  /**
204
207
  * Default margins
205
208
  */
206
- margins: {};
209
+ margins: object;
207
210
 
208
211
  /**
209
212
  * Item selected
@@ -260,9 +263,10 @@ function defaultItemRenderer<T>({
260
263
  * @param props Props
261
264
  * @returns Component
262
265
  */
263
- export function ScrollerListEx<T extends Record<string, unknown>>(
264
- props: ScrollerListExProps<T>
265
- ) {
266
+ export function ScrollerListEx<
267
+ T extends object,
268
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
269
+ >(props: ScrollerListExProps<T, D>) {
266
270
  // Selected item ref
267
271
  const selectedItem = React.useRef<[HTMLDivElement, T]>();
268
272
 
@@ -295,11 +299,11 @@ export function ScrollerListEx<T extends Record<string, unknown>>(
295
299
  const {
296
300
  alternatingColors = [undefined, undefined],
297
301
  className,
298
- idField = 'id',
302
+ idField = 'id' as D,
299
303
  innerItemRenderer,
300
304
  itemSize,
301
305
  itemKey = (index: number, data: T) =>
302
- DataTypes.getValue(data, idField) ?? index,
306
+ DataTypes.getIdValue1(data, idField) ?? index,
303
307
  itemRenderer = (itemProps) => {
304
308
  const [itemHeight, space, margins] = calculateItemSize(
305
309
  itemProps.index
@@ -328,7 +332,7 @@ export function ScrollerListEx<T extends Record<string, unknown>>(
328
332
 
329
333
  // Cache calculation
330
334
  const itemSizeResult = React.useMemo(():
331
- | [number, number, {}]
335
+ | [number, number, object]
332
336
  | undefined => {
333
337
  if (typeof itemSize === 'function') return undefined;
334
338
  const [size, spaces, isNarrow] = itemSize;
@@ -347,7 +351,7 @@ export function ScrollerListEx<T extends Record<string, unknown>>(
347
351
  }, [itemSize]);
348
352
 
349
353
  // Calculate size
350
- const calculateItemSize = (index: number): [number, number, {}] => {
354
+ const calculateItemSize = (index: number): [number, number, object] => {
351
355
  // Callback function
352
356
  if (typeof itemSize === 'function') {
353
357
  const result = itemSize(index);
@@ -1,4 +1,3 @@
1
- import { IdLabelDto } from '@etsoo/appscript';
2
1
  import { DataTypes } from '@etsoo/shared';
3
2
  import React from 'react';
4
3
  import { MUGlobal } from './MUGlobal';
@@ -10,8 +9,8 @@ import { OptionGroup, OptionGroupProps } from './OptionGroup';
10
9
  * @returns Component
11
10
  */
12
11
  export function SearchOptionGroup<
13
- T extends Record<string, any> = IdLabelDto,
14
- D extends DataTypes.IdType = string
12
+ T extends object = DataTypes.IdLabelItem,
13
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
15
14
  >(props: OptionGroupProps<T, D>) {
16
15
  // Destruct
17
16
  const {
@@ -1,5 +1,4 @@
1
- import { IdLabelDto } from '@etsoo/appscript';
2
- import { Utils } from '@etsoo/shared';
1
+ import { DataTypes, Utils } from '@etsoo/shared';
3
2
  import React from 'react';
4
3
  import { globalApp } from '..';
5
4
  import { SelectEx, SelectExProps } from './SelectEx';
@@ -8,7 +7,10 @@ import { SelectEx, SelectExProps } from './SelectEx';
8
7
  * SelectBool props
9
8
  */
10
9
  export interface SelectBoolProps
11
- extends Omit<SelectExProps<IdLabelDto<string>>, 'options' | 'loadData'> {}
10
+ extends Omit<
11
+ SelectExProps<DataTypes.IdLabelItem<string>>,
12
+ 'options' | 'loadData'
13
+ > {}
12
14
 
13
15
  /**
14
16
  * SelectBool (yes/no)
@@ -20,7 +22,7 @@ export function SelectBool(props: SelectBoolProps) {
20
22
  const { search = true, autoAddBlankItem = search, ...rest } = props;
21
23
 
22
24
  // Options
23
- const options: IdLabelDto<string>[] = [
25
+ const options: DataTypes.IdLabelItem<string>[] = [
24
26
  { id: 'false', label: globalApp.get('no')! },
25
27
  { id: 'true', label: globalApp.get('yes')! }
26
28
  ];
@@ -28,5 +30,11 @@ export function SelectBool(props: SelectBoolProps) {
28
30
  if (autoAddBlankItem) Utils.addBlankItem(options);
29
31
 
30
32
  // Layout
31
- return <SelectEx options={options} search={search} {...rest} />;
33
+ return (
34
+ <SelectEx<DataTypes.IdLabelItem<string>>
35
+ options={options}
36
+ search={search}
37
+ {...rest}
38
+ />
39
+ );
32
40
  }
@@ -11,36 +11,27 @@ 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 type SelectExProps<
22
+ T extends object,
23
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
24
+ > = Omit<SelectProps, 'labelId' | 'input' | 'native'> & {
24
25
  /**
25
26
  * Auto add blank item
26
27
  */
27
28
  autoAddBlankItem?: boolean;
28
29
 
29
- /**
30
- * Id field, default is id
31
- */
32
- idField?: string & keyof T;
33
-
34
30
  /**
35
31
  * Item icon renderer
36
32
  */
37
33
  itemIconRenderer?: (id: unknown) => React.ReactNode;
38
34
 
39
- /**
40
- * Label field, default is label
41
- */
42
- labelField?: ((option: T) => string) | (string & keyof T);
43
-
44
35
  /**
45
36
  * Load data callback
46
37
  */
@@ -65,21 +56,37 @@ export interface SelectExProps<T extends {}>
65
56
  * Is search case?
66
57
  */
67
58
  search?: boolean;
68
- }
59
+ } & (T extends { id: DataTypes.IdType }
60
+ ? {
61
+ idField?: D;
62
+ }
63
+ : {
64
+ idField: D;
65
+ }) &
66
+ (T extends { label: string }
67
+ ? {
68
+ labelField?: ((option: T) => string) | D;
69
+ }
70
+ : {
71
+ labelField: ((option: T) => string) | D;
72
+ });
69
73
 
70
74
  /**
71
75
  * Extended select component
72
76
  * @param props Props
73
77
  * @returns Component
74
78
  */
75
- export function SelectEx<T extends {} = IdLabelDto>(props: SelectExProps<T>) {
79
+ export function SelectEx<
80
+ T extends object = DataTypes.IdLabelItem,
81
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
82
+ >(props: SelectExProps<T, D>) {
76
83
  // Destruct
77
84
  const {
78
85
  defaultValue,
79
- idField = 'id',
86
+ idField = 'id' as D,
80
87
  itemIconRenderer,
81
88
  label,
82
- labelField = 'label',
89
+ labelField = 'label' as D,
83
90
  loadData,
84
91
  onItemClick,
85
92
  onLoadData,
@@ -153,14 +160,14 @@ export function SelectEx<T extends {} = IdLabelDto>(props: SelectExProps<T>) {
153
160
 
154
161
  // Get option id
155
162
  const getId = (option: T) => {
156
- return Reflect.get(option, idField);
163
+ return option[idField] as unknown as React.Key;
157
164
  };
158
165
 
159
166
  // Get option label
160
167
  const getLabel = (option: T) => {
161
168
  return typeof labelField === 'function'
162
169
  ? labelField(option)
163
- : Reflect.get(option, labelField);
170
+ : new String(option[labelField]);
164
171
  };
165
172
 
166
173
  // Refs
@@ -47,68 +47,70 @@ export interface TableExMethodRef extends GridMethodRef {
47
47
  /**
48
48
  * Extended table props
49
49
  */
50
- export interface TableExProps<T extends Record<string, any>>
51
- extends TableProps,
52
- GridLoader<T> {
53
- /**
54
- * Alternating colors for odd/even rows
55
- */
56
- alternatingColors?: [string?, string?];
57
-
58
- /**
59
- * Columns
60
- */
61
- columns: GridColumn<T>[];
62
-
63
- /**
64
- * Header cells background color and font color
65
- */
66
- headerColors?: [string?, string?];
67
-
68
- /**
69
- * Id field
70
- */
71
- idField?: string & keyof T;
72
-
73
- /**
74
- * Max height
75
- */
76
- maxHeight?: number;
77
-
78
- /**
79
- * Methods
80
- */
81
- mRef?: React.Ref<TableExMethodRef>;
82
-
83
- /**
84
- * On items select change
85
- */
86
- onSelectChange?: (selectedItems: T[]) => void;
87
-
88
- /**
89
- * Row height
90
- */
91
- rowHeight?: number;
92
-
93
- /**
94
- * Header and bottom height
95
- */
96
- otherHeight?: number;
97
- }
50
+ export type TableExProps<
51
+ T extends object,
52
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
53
+ > = TableProps &
54
+ GridLoader<T> & {
55
+ /**
56
+ * Alternating colors for odd/even rows
57
+ */
58
+ alternatingColors?: [string?, string?];
59
+
60
+ /**
61
+ * Columns
62
+ */
63
+ columns: GridColumn<T>[];
64
+
65
+ /**
66
+ * Header cells background color and font color
67
+ */
68
+ headerColors?: [string?, string?];
69
+
70
+ /**
71
+ * Max height
72
+ */
73
+ maxHeight?: number;
74
+
75
+ /**
76
+ * Methods
77
+ */
78
+ mRef?: React.Ref<TableExMethodRef>;
79
+
80
+ /**
81
+ * On items select change
82
+ */
83
+ onSelectChange?: (selectedItems: T[]) => void;
84
+
85
+ /**
86
+ * Row height
87
+ */
88
+ rowHeight?: number;
89
+
90
+ /**
91
+ * Header and bottom height
92
+ */
93
+ otherHeight?: number;
94
+ } & (T extends { id: DataTypes.IdType }
95
+ ? {
96
+ idField?: D;
97
+ }
98
+ : {
99
+ idField: D;
100
+ });
98
101
 
99
102
  /**
100
103
  * Extended Table
101
104
  * @param props Props
102
105
  * @returns Component
103
106
  */
104
- export function TableEx<T extends Record<string, unknown>>(
105
- props: TableExProps<T>
106
- ) {
107
+ export function TableEx<
108
+ T extends object,
109
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
110
+ >(props: TableExProps<T, D>) {
107
111
  // Theme
108
112
  const theme = useTheme();
109
113
 
110
- type keyType = string & keyof T;
111
-
112
114
  // Destruct
113
115
  const {
114
116
  alternatingColors = [theme.palette.action.hover, undefined],
@@ -116,7 +118,7 @@ export function TableEx<T extends Record<string, unknown>>(
116
118
  columns,
117
119
  defaultOrderBy,
118
120
  headerColors = [undefined, undefined],
119
- idField = 'id' as keyType,
121
+ idField = 'id' as D,
120
122
  loadBatchSize,
121
123
  loadData,
122
124
  maxHeight,
@@ -451,7 +453,10 @@ export function TableEx<T extends Record<string, unknown>>(
451
453
  : false;
452
454
 
453
455
  return (
454
- <TableRow key={rowId} selected={isItemSelected}>
456
+ <TableRow
457
+ key={rowId as unknown as React.Key}
458
+ selected={isItemSelected}
459
+ >
455
460
  {selectable && (
456
461
  <TableCell padding="checkbox">
457
462
  {row && (
@@ -522,10 +527,7 @@ export function TableEx<T extends Record<string, unknown>>(
522
527
 
523
528
  return (
524
529
  <TableCell
525
- key={
526
- rowId.toString() +
527
- columnIndex
528
- }
530
+ key={`${rowId}${columnIndex}`}
529
531
  {...cellProps}
530
532
  >
531
533
  {child}
@@ -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,19 +10,21 @@ 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 type TiplistProps<T extends object, D extends DataTypes.Keys<T>> = Omit<
14
+ AutocompleteExtendedProps<T, D>,
15
+ 'open'
16
+ > & {
16
17
  /**
17
18
  * Load data callback
18
19
  */
19
20
  loadData: (
20
21
  keyword?: string,
21
- id?: DataTypes.IdType
22
+ id?: T[D]
22
23
  ) => PromiseLike<T[] | null | undefined>;
23
- }
24
+ };
24
25
 
25
26
  // Multiple states
26
- interface States<T extends {}> {
27
+ interface States<T extends object> {
27
28
  open: boolean;
28
29
  options: T[];
29
30
  value?: T | null;
@@ -35,11 +36,14 @@ interface States<T extends {}> {
35
36
  * @param props Props
36
37
  * @returns Component
37
38
  */
38
- export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
39
+ export function Tiplist<
40
+ T extends object = DataTypes.IdLabelItem,
41
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
42
+ >(props: TiplistProps<T, D>) {
39
43
  // Destruct
40
44
  const {
41
45
  search = false,
42
- idField = 'id',
46
+ idField = 'id' as D,
43
47
  idValue,
44
48
  inputAutoComplete = 'off',
45
49
  inputError,
@@ -65,11 +69,10 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
65
69
 
66
70
  // Local value
67
71
  let localValue = value ?? defaultValue;
68
- if (localValue === undefined) localValue = null;
69
72
 
70
73
  // One time calculation for input's default value (uncontrolled)
71
74
  const localIdValue =
72
- idValue ?? (localValue && Reflect.get(localValue, idField));
75
+ idValue ?? DataTypes.getValue(localValue, idField as any);
73
76
 
74
77
  // Changable states
75
78
  const [states, stateUpdate] = React.useReducer(
@@ -86,7 +89,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
86
89
 
87
90
  // Input value
88
91
  const inputValue = React.useMemo(
89
- () => states.value && Reflect.get(states.value, idField),
92
+ () => states.value && states.value[idField],
90
93
  [states.value]
91
94
  );
92
95
 
@@ -130,7 +133,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
130
133
  };
131
134
 
132
135
  // Directly load data
133
- const loadDataDirect = (keyword?: string, id?: DataTypes.IdType) => {
136
+ const loadDataDirect = (keyword?: string, id?: T[D]) => {
134
137
  // Reset options
135
138
  // setOptions([]);
136
139
 
@@ -181,7 +184,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
181
184
  }
182
185
  };
183
186
 
184
- if (localIdValue != null && localIdValue !== '') {
187
+ if (localIdValue != null && (localIdValue as any) !== '') {
185
188
  if (state.idLoaded) {
186
189
  // Set default
187
190
  if (!state.idSet && states.options.length == 1) {
@@ -211,12 +214,12 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
211
214
  type="text"
212
215
  style={{ display: 'none' }}
213
216
  name={name}
214
- value={inputValue ?? ''}
217
+ value={`${inputValue ?? ''}`}
215
218
  readOnly
216
219
  onChange={inputOnChange}
217
220
  />
218
221
  {/* Previous input will reset first with "disableClearable = false", next input trigger change works */}
219
- <Autocomplete
222
+ <Autocomplete<T, undefined, false, false>
220
223
  filterOptions={(options, _state) => options}
221
224
  value={states.value}
222
225
  options={states.options}
@@ -250,7 +253,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
250
253
  undefined,
251
254
  states.value == null
252
255
  ? undefined
253
- : Reflect.get(states.value, idField)
256
+ : states.value[idField]
254
257
  );
255
258
  }}
256
259
  onClose={() => {
@@ -291,7 +294,7 @@ export function Tiplist<T extends {} = IdLabelDto>(props: TiplistProps<T>) {
291
294
  />
292
295
  )
293
296
  }
294
- isOptionEqualToValue={(option: any, value: any) =>
297
+ isOptionEqualToValue={(option: T, value: T) =>
295
298
  option[idField] === value[idField]
296
299
  }
297
300
  {...rest}
@@ -52,7 +52,7 @@ export interface CommonPageProps extends Omit<ContainerProps, 'id'> {
52
52
  /**
53
53
  * Paddings
54
54
  */
55
- paddings?: {};
55
+ paddings?: Record<string, string | number>;
56
56
 
57
57
  /**
58
58
  * Scroll container