@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
@@ -1,3 +1,4 @@
1
+ import { DataTypes } from '@etsoo/shared';
1
2
  import React from 'react';
2
3
  import {
3
4
  Align,
@@ -9,8 +10,10 @@ import {
9
10
  import { GridMethodRef } from '../mu/GridMethodRef';
10
11
  import { GridLoadDataProps, GridLoader, GridLoaderStates } from './GridLoader';
11
12
 
12
- export interface ScrollerGridItemRendererProps<T>
13
- extends Omit<GridChildComponentProps<T>, 'data'> {
13
+ export type ScrollerGridItemRendererProps<T> = Omit<
14
+ GridChildComponentProps<T>,
15
+ 'data'
16
+ > & {
14
17
  /**
15
18
  * Selected items
16
19
  */
@@ -20,64 +23,65 @@ export interface ScrollerGridItemRendererProps<T>
20
23
  * Data
21
24
  */
22
25
  data?: T;
23
- }
26
+ };
24
27
 
25
28
  /**
26
29
  * Scroller vertical grid props
27
30
  */
28
- export interface ScrollerGridProps<T>
29
- extends GridLoader<T>,
30
- Omit<
31
- VariableSizeGridProps<T>,
32
- 'children' | 'rowCount' | 'rowHeight' | 'ref'
33
- > {
34
- /**
35
- * Default order by asc
36
- * @default true
37
- */
38
- defaultOrderByAsc?: boolean;
39
-
40
- /**
41
- * Footer renderer
42
- */
43
- footerRenderer?: (
44
- rows: T[],
45
- states: GridLoaderStates<T>
46
- ) => React.ReactNode;
47
-
48
- /**
49
- * Header renderer
50
- */
51
- headerRenderer?: (states: GridLoaderStates<T>) => React.ReactNode;
52
-
53
- /**
54
- * Id field
55
- * @default id
56
- */
57
- idField?: string & keyof T;
58
-
59
- /**
60
- * Item renderer
61
- */
62
- itemRenderer: (
63
- props: ScrollerGridItemRendererProps<T>
64
- ) => React.ReactElement;
65
-
66
- /**
67
- * Methods
68
- */
69
- mRef?: React.Ref<ScrollerGridForwardRef>;
70
-
71
- /**
72
- * On items select change
73
- */
74
- onSelectChange?: (selectedItems: T[]) => void;
75
-
76
- /**
77
- * Returns the height of the specified row.
78
- */
79
- rowHeight?: ((index: number) => number) | number;
80
- }
31
+ export type ScrollerGridProps<
32
+ T extends object,
33
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
34
+ > = GridLoader<T> &
35
+ Omit<
36
+ VariableSizeGridProps<T>,
37
+ 'children' | 'rowCount' | 'rowHeight' | 'ref'
38
+ > & {
39
+ /**
40
+ * Default order by asc
41
+ * @default true
42
+ */
43
+ defaultOrderByAsc?: boolean;
44
+
45
+ /**
46
+ * Footer renderer
47
+ */
48
+ footerRenderer?: (
49
+ rows: T[],
50
+ states: GridLoaderStates<T>
51
+ ) => React.ReactNode;
52
+
53
+ /**
54
+ * Header renderer
55
+ */
56
+ headerRenderer?: (states: GridLoaderStates<T>) => React.ReactNode;
57
+
58
+ /**
59
+ * Id field
60
+ */
61
+ idField?: D;
62
+
63
+ /**
64
+ * Item renderer
65
+ */
66
+ itemRenderer: (
67
+ props: ScrollerGridItemRendererProps<T>
68
+ ) => React.ReactElement;
69
+
70
+ /**
71
+ * Methods
72
+ */
73
+ mRef?: React.Ref<ScrollerGridForwardRef>;
74
+
75
+ /**
76
+ * On items select change
77
+ */
78
+ onSelectChange?: (selectedItems: T[]) => void;
79
+
80
+ /**
81
+ * Returns the height of the specified row.
82
+ */
83
+ rowHeight?: ((index: number) => number) | number;
84
+ };
81
85
 
82
86
  /**
83
87
  * Scroller grid forward ref
@@ -143,8 +147,11 @@ export interface ScrollerGridForwardRef extends GridMethodRef {
143
147
  * @param props Props
144
148
  * @returns Component
145
149
  */
146
- export const ScrollerGrid = <T extends Record<string, unknown>>(
147
- props: ScrollerGridProps<T>
150
+ export const ScrollerGrid = <
151
+ T extends object,
152
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
153
+ >(
154
+ props: ScrollerGridProps<T, D>
148
155
  ) => {
149
156
  // Destruct
150
157
  const {
@@ -154,7 +161,7 @@ export const ScrollerGrid = <T extends Record<string, unknown>>(
154
161
  footerRenderer,
155
162
  headerRenderer,
156
163
  itemRenderer,
157
- idField = 'id',
164
+ idField = 'id' as D,
158
165
  loadBatchSize,
159
166
  loadData,
160
167
  mRef,
@@ -20,7 +20,7 @@ import {
20
20
  /**
21
21
  * Scroller vertical list props
22
22
  */
23
- export interface ScrollerListProps<T>
23
+ export interface ScrollerListProps<T extends object>
24
24
  extends GridLoader<T>,
25
25
  Omit<
26
26
  ListProps<T>,
@@ -98,9 +98,7 @@ const calculateBatchSize = (
98
98
  * @param props Props
99
99
  * @returns Component
100
100
  */
101
- export const ScrollerList = <T extends Record<string, any>>(
102
- props: ScrollerListProps<T>
103
- ) => {
101
+ export const ScrollerList = <T extends object>(props: ScrollerListProps<T>) => {
104
102
  // Destruct
105
103
  const {
106
104
  autoLoad = true,
@@ -5,20 +5,17 @@ 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<
10
- AutocompleteProps<T, undefined, false, false>,
11
- 'renderInput' | 'options'
12
- > {
13
- /**
14
- * Id field, default is id
15
- */
16
- idField?: string & keyof T;
17
-
8
+ export type AutocompleteExtendedProps<
9
+ T extends object,
10
+ D extends DataTypes.Keys<T>
11
+ > = Omit<
12
+ AutocompleteProps<T, undefined, false, false>,
13
+ 'renderInput' | 'options'
14
+ > & {
18
15
  /**
19
16
  * Id value
20
17
  */
21
- idValue?: DataTypes.IdType;
18
+ idValue?: T[D];
22
19
 
23
20
  /**
24
21
  * Autocomplete for the input
@@ -78,4 +75,10 @@ export interface AutocompleteExtendedProps<T extends Record<string, unknown>>
78
75
  * Is search field?
79
76
  */
80
77
  search?: boolean;
81
- }
78
+ } & (T extends { id: DataTypes.IdType }
79
+ ? {
80
+ idField?: D;
81
+ }
82
+ : {
83
+ idField: D;
84
+ });
@@ -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 type ComboBoxProps<
14
+ T extends object,
15
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
16
+ > = AutocompleteExtendedProps<T, D> & {
16
17
  /**
17
18
  * Auto add blank item
18
19
  */
@@ -23,11 +24,6 @@ export interface ComboBoxProps<T extends {}>
23
24
  */
24
25
  dataReadonly?: boolean;
25
26
 
26
- /**
27
- * Label field
28
- */
29
- labelField?: string & keyof T;
30
-
31
27
  /**
32
28
  * Load data callback
33
29
  */
@@ -42,19 +38,28 @@ export interface ComboBoxProps<T extends {}>
42
38
  * Array of options.
43
39
  */
44
40
  options?: ReadonlyArray<T>;
45
- }
41
+ } & (T extends { label: string }
42
+ ? {
43
+ labelField?: D;
44
+ }
45
+ : {
46
+ labelField: D;
47
+ });
46
48
 
47
49
  /**
48
50
  * ComboBox
49
51
  * @param props Props
50
52
  * @returns Component
51
53
  */
52
- export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
54
+ export function ComboBox<
55
+ T extends object = DataTypes.IdLabelItem,
56
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
57
+ >(props: ComboBoxProps<T, D>) {
53
58
  // Destruct
54
59
  const {
55
60
  search = false,
56
61
  autoAddBlankItem = search,
57
- idField = 'id',
62
+ idField = 'id' as D,
58
63
  idValue,
59
64
  inputError,
60
65
  inputHelperText,
@@ -64,7 +69,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
64
69
  inputVariant,
65
70
  defaultValue,
66
71
  label,
67
- labelField = 'label',
72
+ labelField = 'label' as D,
68
73
  loadData,
69
74
  onLoadData,
70
75
  name,
@@ -75,7 +80,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
75
80
  onChange,
76
81
  openOnFocus = true,
77
82
  value,
78
- getOptionLabel = (option: T) => String(Reflect.get(option, labelField)),
83
+ getOptionLabel = (option: T) => `${option[labelField]}`,
79
84
  sx = { minWidth: '150px' },
80
85
  ...rest
81
86
  } = props;
@@ -97,7 +102,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
97
102
  // Local default value
98
103
  let localValue =
99
104
  idValue != null
100
- ? localOptions.find((o) => Reflect.get(o, idField) === idValue)
105
+ ? localOptions.find((o) => o[idField] === idValue)
101
106
  : defaultValue ?? value;
102
107
 
103
108
  if (localValue === undefined) localValue = null;
@@ -108,7 +113,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
108
113
 
109
114
  // Current id value
110
115
  // One time calculation for input's default value (uncontrolled)
111
- const localIdValue = stateValue && Reflect.get(stateValue, idField);
116
+ const localIdValue = stateValue && stateValue[idField];
112
117
 
113
118
  React.useEffect(() => {
114
119
  if (localValue != null) setStateValue(localValue);
@@ -147,8 +152,7 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
147
152
  const input = inputRef.current;
148
153
  if (input) {
149
154
  // Update value
150
- const newValue =
151
- value != null ? `${Reflect.get(value, idField)}` : '';
155
+ const newValue = value != null ? `${value[idField]}` : '';
152
156
 
153
157
  if (newValue !== input.value) {
154
158
  // Different value, trigger change event
@@ -186,16 +190,16 @@ export function ComboBox<T extends {} = IdLabelDto>(props: ComboBoxProps<T>) {
186
190
  type="text"
187
191
  style={{ display: 'none' }}
188
192
  name={name}
189
- value={localIdValue ?? ''}
193
+ value={`${localIdValue ?? ''}`}
190
194
  readOnly
191
195
  onChange={inputOnChange}
192
196
  />
193
197
  {/* Previous input will reset first with "disableClearable = false", next input trigger change works */}
194
- <Autocomplete
198
+ <Autocomplete<T, undefined, false, false>
195
199
  value={stateValue}
196
200
  getOptionLabel={getOptionLabel}
197
201
  isOptionEqualToValue={(option: T, value: T) =>
198
- Reflect.get(option, idField) === Reflect.get(value, idField)
202
+ option[idField] === value[idField]
199
203
  }
200
204
  onChange={(event, value, reason, details) => {
201
205
  // Set value
@@ -1,5 +1,5 @@
1
1
  import { css } from '@emotion/css';
2
- import { Utils } from '@etsoo/shared';
2
+ import { DataTypes, Utils } from '@etsoo/shared';
3
3
  import {
4
4
  Box,
5
5
  BoxProps,
@@ -30,24 +30,24 @@ import { MouseEventWithDataHandler } from './MUGlobal';
30
30
  /**
31
31
  * Footer item renderer props
32
32
  */
33
- export interface DataGridExFooterItemRendererProps<
34
- T extends Record<string, any>
35
- > {
33
+ export type DataGridExFooterItemRendererProps<T extends object> = {
36
34
  column: GridColumn<T>;
37
35
  index: number;
38
36
  states: GridLoaderStates<T>;
39
37
  cellProps: any;
40
38
  checkable: boolean;
41
- }
39
+ };
42
40
 
43
41
  /**
44
42
  * Extended DataGrid with VariableSizeGrid props
45
43
  */
46
- export interface DataGridExProps<T extends Record<string, any>>
47
- extends Omit<
48
- ScrollerGridProps<T>,
49
- 'itemRenderer' | 'columnCount' | 'columnWidth' | 'width'
50
- > {
44
+ export type DataGridExProps<
45
+ T extends object,
46
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
47
+ > = Omit<
48
+ ScrollerGridProps<T, D>,
49
+ 'itemRenderer' | 'columnCount' | 'columnWidth' | 'width'
50
+ > & {
51
51
  /**
52
52
  * Alternating colors for odd/even rows
53
53
  */
@@ -124,7 +124,7 @@ export interface DataGridExProps<T extends Record<string, any>>
124
124
  * Width
125
125
  */
126
126
  width?: number;
127
- }
127
+ };
128
128
 
129
129
  // Borders
130
130
  const boldBorder = '2px solid rgba(224, 224, 224, 1)';
@@ -210,9 +210,10 @@ export function DataGridExCalColumns<T>(columns: GridColumn<T>[]) {
210
210
  * @param props Props
211
211
  * @returns Component
212
212
  */
213
- export function DataGridEx<T extends Record<string, any>>(
214
- props: DataGridExProps<T>
215
- ) {
213
+ export function DataGridEx<
214
+ T extends object,
215
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
216
+ >(props: DataGridExProps<T, D>) {
216
217
  // Theme
217
218
  const theme = useTheme();
218
219
 
@@ -360,7 +361,7 @@ export function DataGridEx<T extends Record<string, any>>(
360
361
  footerItemRenderer = DataGridRenderers.defaultFooterItemRenderer,
361
362
  hideFooter = false,
362
363
  hoverColor = '#f6f9fb',
363
- idField = 'id',
364
+ idField = 'id' as D,
364
365
  mRef = React.createRef(),
365
366
  onClick,
366
367
  onDoubleClick,
@@ -372,7 +373,7 @@ export function DataGridEx<T extends Record<string, any>>(
372
373
 
373
374
  if (checkable) {
374
375
  const cbColumn: GridColumn<T> = {
375
- field: 'selected',
376
+ field: 'selected' as any, // Avoid validation from data model
376
377
  header: '',
377
378
  sortable: false,
378
379
  width: 50,
@@ -442,7 +443,7 @@ export function DataGridEx<T extends Record<string, any>>(
442
443
  };
443
444
 
444
445
  // Reset
445
- const reset = (add: {}) => {
446
+ const reset = (add: object) => {
446
447
  refs.current.ref?.reset(add);
447
448
  };
448
449
 
@@ -632,7 +633,7 @@ export function DataGridEx<T extends Record<string, any>>(
632
633
  : undefined;
633
634
 
634
635
  return (
635
- <ScrollerGrid<T>
636
+ <ScrollerGrid<T, D>
636
637
  className={Utils.mergeClasses(
637
638
  'DataGridEx-Body',
638
639
  'DataGridEx-CustomBar',
@@ -117,7 +117,7 @@ export namespace DataGridRenderers {
117
117
  * @param location Renderer location (column index)
118
118
  * @returns Component
119
119
  */
120
- export function defaultFooterItemRenderer<T>(
120
+ export function defaultFooterItemRenderer<T extends object>(
121
121
  _rows: T[],
122
122
  { index, states, checkable }: DataGridExFooterItemRendererProps<T>,
123
123
  location: number = 0
@@ -79,7 +79,7 @@ export const DnDItemStyle = (
79
79
  /**
80
80
  * DnD list forward ref
81
81
  */
82
- export interface DnDListRef<D extends {}> {
82
+ export interface DnDListRef<D extends object> {
83
83
  /**
84
84
  * Add item
85
85
  * @param item New item
@@ -109,7 +109,7 @@ export interface DnDListRef<D extends {}> {
109
109
  /**
110
110
  * DnD sortable list properties
111
111
  */
112
- export interface DnDListPros<D extends {}, K extends DataTypes.Keys<D>> {
112
+ export interface DnDListPros<D extends object, K extends DataTypes.Keys<D>> {
113
113
  /**
114
114
  * Get list item style callback
115
115
  */
@@ -22,7 +22,7 @@ import { LoadingButton } from './LoadingButton';
22
22
  * ListMoreDisplay props
23
23
  */
24
24
  export interface ListMoreDisplayProps<
25
- T,
25
+ T extends object,
26
26
  F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
27
27
  > extends Omit<CardProps, 'children'>,
28
28
  GridLoader<T> {
@@ -63,7 +63,7 @@ type states<T> = {
63
63
  * @returns Component
64
64
  */
65
65
  export function ListMoreDisplay<
66
- T extends {},
66
+ T extends object,
67
67
  F extends DataTypes.BasicTemplate = DataTypes.BasicTemplate
68
68
  >(props: ListMoreDisplayProps<T, F>) {
69
69
  // Destruct
@@ -92,7 +92,7 @@ export class MUGlobal {
92
92
  * @param input Input object
93
93
  * @returns Updated object
94
94
  */
95
- static half(input: {}) {
95
+ static half(input: object) {
96
96
  const newObj = { ...input };
97
97
  Object.entries(newObj).forEach(([key, value]) => {
98
98
  if (typeof value === 'number') {
@@ -107,7 +107,7 @@ export class MUGlobal {
107
107
  * @param input Input object
108
108
  * @returns Updated object
109
109
  */
110
- static reverse(input: {}) {
110
+ static reverse(input: object) {
111
111
  const newObj = { ...input };
112
112
  Object.entries(newObj).forEach(([key, value]) => {
113
113
  if (typeof value === 'number') {
@@ -124,7 +124,7 @@ export class MUGlobal {
124
124
  * @param field Specific field
125
125
  * @returns Updated object
126
126
  */
127
- static increase(input: {}, adjust: number | {}, field?: string) {
127
+ static increase(input: object, adjust: number | object, field?: string) {
128
128
  const newObj = { ...input };
129
129
  Object.entries(newObj).forEach(([key, value]) => {
130
130
  if (typeof value === 'number') {
@@ -152,7 +152,7 @@ export class MUGlobal {
152
152
  */
153
153
  static adjustWithTheme(
154
154
  size: number,
155
- adjust: {},
155
+ adjust: object,
156
156
  updateFunc: (value: number) => string
157
157
  ) {
158
158
  const newObj = { ...adjust };
@@ -185,7 +185,7 @@ export class MUGlobal {
185
185
  * @param theme Theme
186
186
  * @returns Result
187
187
  */
188
- static getSpace(spaces: {}, theme: Theme) {
188
+ static getSpace(spaces: object, theme: Theme) {
189
189
  const start = this.breakpoints.length - 1;
190
190
  for (let i = start; i >= 0; i--) {
191
191
  const key = this.breakpoints[i];
@@ -1,4 +1,3 @@
1
- import { IdLabelDto } from '@etsoo/appscript';
2
1
  import { DataTypes, Utils } from '@etsoo/shared';
3
2
  import {
4
3
  Checkbox,
@@ -15,35 +14,25 @@ import React from 'react';
15
14
  /**
16
15
  * OptionGroup props
17
16
  */
18
- export interface OptionGroupProps<
19
- T extends Record<string, any> = IdLabelDto,
20
- D extends DataTypes.IdType = string
21
- > extends Omit<FormControlProps<'fieldset'>, 'defaultValue'> {
17
+ export type OptionGroupProps<
18
+ T extends object = DataTypes.IdLabelItem,
19
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
20
+ > = Omit<FormControlProps<'fieldset'>, 'defaultValue'> & {
22
21
  /**
23
22
  * Default value
24
23
  */
25
- defaultValue?: D | D[];
24
+ defaultValue?: T[D] | T[D][];
26
25
 
27
26
  /**
28
27
  * Get option label function
29
28
  */
30
29
  getOptionLabel?: (option: T) => string;
31
30
 
32
- /**
33
- * Id field, default is id
34
- */
35
- idField?: string & keyof T;
36
-
37
31
  /**
38
32
  * Label
39
33
  */
40
34
  label?: string;
41
35
 
42
- /**
43
- * Label field, default is label
44
- */
45
- labelField?: string & keyof T;
46
-
47
36
  /**
48
37
  * Multiple choose item
49
38
  */
@@ -57,7 +46,7 @@ export interface OptionGroupProps<
57
46
  /**
58
47
  * On value change handler
59
48
  */
60
- onValueChange?: (value: D | D[] | undefined) => void;
49
+ onValueChange?: (value: T[D] | T[D][] | undefined) => void;
61
50
 
62
51
  /**
63
52
  * Array of options.
@@ -73,7 +62,20 @@ export interface OptionGroupProps<
73
62
  * Display group of elements in a compact row
74
63
  */
75
64
  row?: boolean;
76
- }
65
+ } & (T extends { id: DataTypes.IdType }
66
+ ? {
67
+ idField?: D;
68
+ }
69
+ : {
70
+ idField: D;
71
+ }) &
72
+ (T extends { label: string }
73
+ ? {
74
+ labelField?: D;
75
+ }
76
+ : {
77
+ labelField: D;
78
+ });
77
79
 
78
80
  /**
79
81
  * OptionGroup
@@ -81,16 +83,16 @@ export interface OptionGroupProps<
81
83
  * @returns Component
82
84
  */
83
85
  export function OptionGroup<
84
- T extends Record<string, unknown> = IdLabelDto,
85
- D extends DataTypes.IdType = string
86
+ T extends object = DataTypes.IdLabelItem,
87
+ D extends DataTypes.Keys<T> = DataTypes.Keys<T>
86
88
  >(props: OptionGroupProps<T, D>) {
87
89
  // Destruct
88
90
  const {
89
91
  getOptionLabel,
90
92
  defaultValue,
91
- idField = 'id',
93
+ idField = 'id' as D,
92
94
  label,
93
- labelField = 'label',
95
+ labelField = 'label' as D,
94
96
  multiple = false,
95
97
  name,
96
98
  onValueChange,
@@ -103,10 +105,10 @@ export function OptionGroup<
103
105
 
104
106
  // Get option value
105
107
  // D type should be the source id type
106
- const getOptionValue = (option: T): D | null => {
108
+ const getOptionValue = (option: T): T[D] | null => {
107
109
  const value = DataTypes.getValue(option, idField);
108
110
  if (value == null) return null;
109
- return value as D;
111
+ return value as T[D];
110
112
  };
111
113
 
112
114
  // Checkbox values
@@ -142,7 +144,7 @@ export function OptionGroup<
142
144
  onChange={(event) => {
143
145
  if (firstOptionValue == null) return;
144
146
 
145
- const typeValue = Utils.parseString<D>(
147
+ const typeValue = Utils.parseString(
146
148
  event.target.value,
147
149
  firstOptionValue
148
150
  );
@@ -175,7 +177,7 @@ export function OptionGroup<
175
177
 
176
178
  // Value, convert to string
177
179
  // Will fail when type is number
178
- const value = getOptionValue(option);
180
+ const value = getOptionValue(option) as unknown as React.Key;
179
181
 
180
182
  return (
181
183
  <FormControlLabel
@@ -197,7 +199,7 @@ export function OptionGroup<
197
199
  value={values[0]}
198
200
  onChange={(_event, value) => {
199
201
  if (firstOptionValue == null) return;
200
- const typeValue = Utils.parseString<D>(value, firstOptionValue);
202
+ const typeValue = Utils.parseString(value, firstOptionValue);
201
203
  if (onValueChange) onValueChange(typeValue);
202
204
  setValues([typeValue]);
203
205
  }}