@jsonforms/material-renderers 3.1.0-alpha.1 → 3.1.0-alpha.3

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 (123) hide show
  1. package/README.md +16 -17
  2. package/lib/additional/ListWithDetailMasterItem.d.ts +2 -0
  3. package/lib/additional/MaterialListWithDetailRenderer.d.ts +1 -1
  4. package/lib/additional/index.d.ts +2 -2
  5. package/lib/additional/unwrapped.d.ts +5 -0
  6. package/lib/cells/index.d.ts +1 -1
  7. package/lib/complex/CombinatorProperties.d.ts +1 -2
  8. package/lib/complex/DeleteDialog.d.ts +5 -1
  9. package/lib/complex/MaterialAllOfRenderer.d.ts +1 -1
  10. package/lib/complex/MaterialAnyOfRenderer.d.ts +1 -1
  11. package/lib/complex/MaterialArrayControlRenderer.d.ts +2 -1
  12. package/lib/complex/MaterialEnumArrayRenderer.d.ts +1 -1
  13. package/lib/complex/MaterialObjectRenderer.d.ts +1 -1
  14. package/lib/complex/MaterialOneOfRenderer.d.ts +1 -1
  15. package/lib/complex/MaterialTableControl.d.ts +4 -2
  16. package/lib/complex/NoBorderTableCell.d.ts +2 -2
  17. package/lib/complex/TableToolbar.d.ts +3 -2
  18. package/lib/complex/index.d.ts +11 -16
  19. package/lib/complex/unwrapped.d.ts +9 -0
  20. package/lib/controls/MaterialBooleanControl.d.ts +1 -1
  21. package/lib/controls/MaterialBooleanToggleControl.d.ts +1 -1
  22. package/lib/controls/index.d.ts +8 -26
  23. package/lib/controls/unwrapped.d.ts +19 -0
  24. package/lib/index.d.ts +34 -1
  25. package/lib/jsonforms-react-material.cjs.js +690 -599
  26. package/lib/jsonforms-react-material.cjs.js.map +1 -1
  27. package/lib/jsonforms-react-material.esm.js +620 -557
  28. package/lib/jsonforms-react-material.esm.js.map +1 -1
  29. package/lib/layouts/ArrayToolbar.d.ts +3 -1
  30. package/lib/layouts/ExpandPanelRenderer.d.ts +3 -1
  31. package/lib/layouts/MaterialGroupLayout.d.ts +1 -1
  32. package/lib/layouts/MaterialHorizontalLayout.d.ts +1 -1
  33. package/lib/layouts/MaterialVerticalLayout.d.ts +1 -1
  34. package/lib/layouts/index.d.ts +3 -1
  35. package/lib/layouts/unwrapped.d.ts +10 -0
  36. package/lib/mui-controls/MuiCheckbox.d.ts +1 -1
  37. package/lib/mui-controls/MuiInputInteger.d.ts +1 -1
  38. package/lib/mui-controls/MuiInputNumber.d.ts +1 -1
  39. package/lib/mui-controls/MuiInputNumberFormat.d.ts +1 -1
  40. package/lib/mui-controls/MuiInputText.d.ts +1 -1
  41. package/lib/mui-controls/MuiInputTime.d.ts +1 -1
  42. package/lib/mui-controls/MuiSelect.d.ts +1 -1
  43. package/lib/mui-controls/MuiToggle.d.ts +1 -1
  44. package/lib/mui-controls/index.d.ts +3 -1
  45. package/lib/util/layout.d.ts +2 -3
  46. package/package.json +16 -9
  47. package/src/additional/ListWithDetailMasterItem.tsx +31 -23
  48. package/src/additional/MaterialLabelRenderer.tsx +8 -15
  49. package/src/additional/MaterialListWithDetailRenderer.tsx +8 -5
  50. package/src/additional/index.ts +12 -4
  51. package/src/additional/unwrapped.ts +32 -0
  52. package/src/cells/MaterialBooleanCell.tsx +1 -1
  53. package/src/cells/MaterialBooleanToggleCell.tsx +2 -2
  54. package/src/cells/MaterialDateCell.tsx +4 -12
  55. package/src/cells/MaterialEnumCell.tsx +13 -6
  56. package/src/cells/MaterialIntegerCell.tsx +1 -1
  57. package/src/cells/MaterialNumberCell.tsx +1 -1
  58. package/src/cells/MaterialNumberFormatCell.tsx +1 -1
  59. package/src/cells/MaterialOneOfEnumCell.tsx +17 -7
  60. package/src/cells/MaterialTextCell.tsx +1 -1
  61. package/src/cells/MaterialTimeCell.tsx +1 -1
  62. package/src/cells/index.ts +7 -7
  63. package/src/complex/CombinatorProperties.tsx +20 -9
  64. package/src/complex/DeleteDialog.tsx +48 -37
  65. package/src/complex/MaterialAllOfRenderer.tsx +2 -2
  66. package/src/complex/MaterialAnyOfRenderer.tsx +3 -3
  67. package/src/complex/MaterialArrayControlRenderer.tsx +27 -11
  68. package/src/complex/MaterialEnumArrayRenderer.tsx +6 -8
  69. package/src/complex/MaterialObjectRenderer.tsx +6 -3
  70. package/src/complex/MaterialOneOfRenderer.tsx +105 -88
  71. package/src/complex/MaterialTableControl.tsx +145 -97
  72. package/src/complex/NoBorderTableCell.tsx +3 -5
  73. package/src/complex/TableToolbar.tsx +24 -25
  74. package/src/complex/ValidationIcon.tsx +10 -18
  75. package/src/complex/index.ts +35 -32
  76. package/src/complex/unwrapped.ts +39 -0
  77. package/src/controls/MaterialAnyOfStringOrEnumControl.tsx +19 -11
  78. package/src/controls/MaterialBooleanControl.tsx +22 -16
  79. package/src/controls/MaterialBooleanToggleControl.tsx +22 -16
  80. package/src/controls/MaterialDateControl.tsx +16 -19
  81. package/src/controls/MaterialDateTimeControl.tsx +24 -23
  82. package/src/controls/MaterialEnumControl.tsx +21 -15
  83. package/src/controls/MaterialInputControl.tsx +7 -8
  84. package/src/controls/MaterialIntegerControl.tsx +1 -1
  85. package/src/controls/MaterialNativeControl.tsx +12 -9
  86. package/src/controls/MaterialNumberControl.tsx +1 -1
  87. package/src/controls/MaterialOneOfEnumControl.tsx +21 -15
  88. package/src/controls/MaterialOneOfRadioGroupControl.tsx +5 -3
  89. package/src/controls/MaterialRadioGroup.tsx +11 -17
  90. package/src/controls/MaterialRadioGroupControl.tsx +8 -3
  91. package/src/controls/MaterialSliderControl.tsx +17 -16
  92. package/src/controls/MaterialTextControl.tsx +1 -1
  93. package/src/controls/MaterialTimeControl.tsx +19 -22
  94. package/src/controls/index.ts +36 -72
  95. package/src/controls/unwrapped.ts +57 -0
  96. package/src/index.ts +41 -22
  97. package/src/layouts/ArrayToolbar.tsx +38 -42
  98. package/src/layouts/ExpandPanelRenderer.tsx +96 -67
  99. package/src/layouts/MaterialArrayLayout.tsx +21 -16
  100. package/src/layouts/MaterialArrayLayoutRenderer.tsx +6 -9
  101. package/src/layouts/MaterialCategorizationLayout.tsx +52 -21
  102. package/src/layouts/MaterialCategorizationStepperLayout.tsx +60 -44
  103. package/src/layouts/MaterialGroupLayout.tsx +25 -6
  104. package/src/layouts/MaterialHorizontalLayout.tsx +18 -4
  105. package/src/layouts/MaterialVerticalLayout.tsx +18 -4
  106. package/src/layouts/index.ts +18 -7
  107. package/src/layouts/unwrapped.ts +41 -0
  108. package/src/mui-controls/MuiAutocomplete.tsx +51 -35
  109. package/src/mui-controls/MuiCheckbox.tsx +5 -3
  110. package/src/mui-controls/MuiInputInteger.tsx +31 -32
  111. package/src/mui-controls/MuiInputNumber.tsx +16 -16
  112. package/src/mui-controls/MuiInputNumberFormat.tsx +51 -42
  113. package/src/mui-controls/MuiInputText.tsx +30 -19
  114. package/src/mui-controls/MuiInputTime.tsx +11 -12
  115. package/src/mui-controls/MuiSelect.tsx +15 -6
  116. package/src/mui-controls/MuiToggle.tsx +5 -3
  117. package/src/mui-controls/index.ts +3 -1
  118. package/src/util/datejs.tsx +41 -20
  119. package/src/util/debounce.ts +26 -11
  120. package/src/util/focus.ts +7 -7
  121. package/src/util/i18nDefaults.ts +2 -2
  122. package/src/util/layout.tsx +47 -42
  123. package/src/util/theme.ts +2 -2
@@ -1,59 +1,55 @@
1
- import {
2
- Grid,
3
- IconButton,
4
- Toolbar,
5
- Tooltip,
6
- Typography
7
- } from '@mui/material';
1
+ import { Grid, IconButton, Toolbar, Tooltip, Typography } from '@mui/material';
8
2
  import AddIcon from '@mui/icons-material/Add';
9
3
  import React from 'react';
10
4
  import ValidationIcon from '../complex/ValidationIcon';
5
+ import { ArrayTranslations } from '@jsonforms/core';
11
6
  export interface ArrayLayoutToolbarProps {
12
7
  label: string;
13
8
  errors: string;
14
9
  path: string;
15
10
  addItem(path: string, data: any): () => void;
16
11
  createDefault(): any;
12
+ translations: ArrayTranslations;
17
13
  }
18
- export const ArrayLayoutToolbar = React.memo(
19
- ({
20
- label,
21
- errors,
22
- addItem,
23
- path,
24
- createDefault
25
- }: ArrayLayoutToolbarProps) => {
26
- return (
27
- <Toolbar disableGutters={true}>
28
- <Grid container alignItems='center' justifyContent='space-between'>
14
+ export const ArrayLayoutToolbar = React.memo(function ArrayLayoutToolbar({
15
+ label,
16
+ errors,
17
+ addItem,
18
+ path,
19
+ createDefault,
20
+ translations,
21
+ }: ArrayLayoutToolbarProps) {
22
+ return (
23
+ <Toolbar disableGutters={true}>
24
+ <Grid container alignItems='center' justifyContent='space-between'>
25
+ <Grid item>
26
+ <Typography variant={'h6'}>{label}</Typography>
27
+ </Grid>
28
+ {errors.length !== 0 && (
29
29
  <Grid item>
30
- <Typography variant={'h6'}>{label}</Typography>
30
+ <ValidationIcon id='tooltip-validation' errorMessages={errors} />
31
31
  </Grid>
32
- {errors.length !== 0 &&
32
+ )}
33
+ <Grid item>
34
+ <Grid container>
33
35
  <Grid item>
34
- <ValidationIcon id='tooltip-validation' errorMessages={errors} />
35
- </Grid>
36
- }
37
- <Grid item>
38
- <Grid container>
39
- <Grid item>
40
- <Tooltip
41
- id='tooltip-add'
42
- title={`Add to ${label}`}
43
- placement='bottom'
36
+ <Tooltip
37
+ id='tooltip-add'
38
+ title={translations.addTooltip}
39
+ placement='bottom'
40
+ >
41
+ <IconButton
42
+ aria-label={translations.addAriaLabel}
43
+ onClick={addItem(path, createDefault())}
44
+ size='large'
44
45
  >
45
- <IconButton
46
- aria-label={`Add to ${label}`}
47
- onClick={addItem(path, createDefault())}
48
- size='large'>
49
- <AddIcon />
50
- </IconButton>
51
- </Tooltip>
52
- </Grid>
46
+ <AddIcon />
47
+ </IconButton>
48
+ </Tooltip>
53
49
  </Grid>
54
50
  </Grid>
55
51
  </Grid>
56
- </Toolbar>
57
- );
58
- }
59
- );
52
+ </Grid>
53
+ </Toolbar>
54
+ );
55
+ });
@@ -1,10 +1,19 @@
1
1
  import merge from 'lodash/merge';
2
2
  import get from 'lodash/get';
3
- import React, { ComponentType, Dispatch, Fragment, ReducerAction, useMemo, useState, useEffect, useCallback } from 'react';
3
+ import React, {
4
+ ComponentType,
5
+ Dispatch,
6
+ Fragment,
7
+ ReducerAction,
8
+ useMemo,
9
+ useState,
10
+ useEffect,
11
+ useCallback,
12
+ } from 'react';
4
13
  import {
5
14
  JsonFormsDispatch,
6
15
  JsonFormsStateContext,
7
- withJsonFormsContext
16
+ withJsonFormsContext,
8
17
  } from '@jsonforms/react';
9
18
  import {
10
19
  composePaths,
@@ -20,7 +29,8 @@ import {
20
29
  JsonFormsUISchemaRegistryEntry,
21
30
  getFirstPrimitiveProp,
22
31
  createId,
23
- removeId
32
+ removeId,
33
+ ArrayTranslations,
24
34
  } from '@jsonforms/core';
25
35
  import {
26
36
  Accordion,
@@ -28,7 +38,7 @@ import {
28
38
  AccordionDetails,
29
39
  Avatar,
30
40
  Grid,
31
- IconButton
41
+ IconButton,
32
42
  } from '@mui/material';
33
43
  import ExpandMoreIcon from '@mui/icons-material/ExpandMore';
34
44
  import DeleteIcon from '@mui/icons-material/Delete';
@@ -53,6 +63,7 @@ interface OwnPropsOfExpandPanel {
53
63
  config: any;
54
64
  childLabelProp?: string;
55
65
  handleExpansion(panel: string): (event: any, expanded: boolean) => void;
66
+ translations: ArrayTranslations;
56
67
  }
57
68
 
58
69
  interface StatePropsOfExpandPanel extends OwnPropsOfExpandPanel {
@@ -103,7 +114,8 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
103
114
  uischemas,
104
115
  renderers,
105
116
  cells,
106
- config
117
+ config,
118
+ translations,
107
119
  } = props;
108
120
 
109
121
  const foundUISchema = useMemo(
@@ -121,7 +133,9 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
121
133
  );
122
134
 
123
135
  const appliedUiSchemaOptions = merge({}, config, uischema.options);
124
- const showSortButtons = appliedUiSchemaOptions.showSortButtons || appliedUiSchemaOptions.showArrayLayoutSortButtons;
136
+ const showSortButtons =
137
+ appliedUiSchemaOptions.showSortButtons ||
138
+ appliedUiSchemaOptions.showArrayLayoutSortButtons;
125
139
 
126
140
  return (
127
141
  <Accordion
@@ -157,8 +171,9 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
157
171
  onClick={moveUp(path, index)}
158
172
  style={iconStyle}
159
173
  disabled={!enableMoveUp}
160
- aria-label={`Move up`}
161
- size='large'>
174
+ aria-label={translations.upAriaLabel}
175
+ size='large'
176
+ >
162
177
  <ArrowUpward />
163
178
  </IconButton>
164
179
  </Grid>
@@ -167,8 +182,9 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
167
182
  onClick={moveDown(path, index)}
168
183
  style={iconStyle}
169
184
  disabled={!enableMoveDown}
170
- aria-label={`Move down`}
171
- size='large'>
185
+ aria-label={translations.downAriaLabel}
186
+ size='large'
187
+ >
172
188
  <ArrowDownward />
173
189
  </IconButton>
174
190
  </Grid>
@@ -180,8 +196,9 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
180
196
  <IconButton
181
197
  onClick={removeItems(path, [index])}
182
198
  style={iconStyle}
183
- aria-label={`Delete`}
184
- size='large'>
199
+ aria-label={translations.removeAriaLabel}
200
+ size='large'
201
+ >
185
202
  <DeleteIcon />
186
203
  </IconButton>
187
204
  </Grid>
@@ -206,7 +223,7 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
206
223
  );
207
224
  };
208
225
 
209
- const ExpandPanelRenderer = React.memo(ExpandPanelRendererComponent);
226
+ export const ExpandPanelRenderer = React.memo(ExpandPanelRendererComponent);
210
227
 
211
228
  /**
212
229
  * Maps state to dispatch properties of an expand pandel control.
@@ -216,37 +233,49 @@ const ExpandPanelRenderer = React.memo(ExpandPanelRendererComponent);
216
233
  */
217
234
  export const ctxDispatchToExpandPanelProps: (
218
235
  dispatch: Dispatch<ReducerAction<any>>
219
- ) => DispatchPropsOfExpandPanel = dispatch => ({
220
- removeItems: useCallback((path: string, toDelete: number[]) => (event: any): void => {
221
- event.stopPropagation();
222
- dispatch(
223
- update(path, array => {
224
- toDelete
225
- .sort()
226
- .reverse()
227
- .forEach(s => array.splice(s, 1));
228
- return array;
229
- })
230
- );
231
- }, [dispatch]),
232
- moveUp: useCallback((path: string, toMove: number) => (event: any): void => {
233
- event.stopPropagation();
234
- dispatch(
235
- update(path, array => {
236
- moveUp(array, toMove);
237
- return array;
238
- })
239
- );
240
- }, [dispatch]),
241
- moveDown: useCallback((path: string, toMove: number) => (event: any): void => {
242
- event.stopPropagation();
243
- dispatch(
244
- update(path, array => {
245
- moveDown(array, toMove);
246
- return array;
247
- })
248
- );
249
- }, [dispatch])
236
+ ) => DispatchPropsOfExpandPanel = (dispatch) => ({
237
+ removeItems: useCallback(
238
+ (path: string, toDelete: number[]) =>
239
+ (event: any): void => {
240
+ event.stopPropagation();
241
+ dispatch(
242
+ update(path, (array) => {
243
+ toDelete
244
+ .sort()
245
+ .reverse()
246
+ .forEach((s) => array.splice(s, 1));
247
+ return array;
248
+ })
249
+ );
250
+ },
251
+ [dispatch]
252
+ ),
253
+ moveUp: useCallback(
254
+ (path: string, toMove: number) =>
255
+ (event: any): void => {
256
+ event.stopPropagation();
257
+ dispatch(
258
+ update(path, (array) => {
259
+ moveUp(array, toMove);
260
+ return array;
261
+ })
262
+ );
263
+ },
264
+ [dispatch]
265
+ ),
266
+ moveDown: useCallback(
267
+ (path: string, toMove: number) =>
268
+ (event: any): void => {
269
+ event.stopPropagation();
270
+ dispatch(
271
+ update(path, (array) => {
272
+ moveDown(array, toMove);
273
+ return array;
274
+ })
275
+ );
276
+ },
277
+ [dispatch]
278
+ ),
250
279
  });
251
280
 
252
281
  /**
@@ -257,33 +286,33 @@ export const ctxDispatchToExpandPanelProps: (
257
286
  */
258
287
  export const withContextToExpandPanelProps = (
259
288
  Component: ComponentType<ExpandPanelProps>
260
- ): ComponentType<OwnPropsOfExpandPanel> => ({
261
- ctx,
262
- props
263
- }: JsonFormsStateContext & ExpandPanelProps) => {
264
- const dispatchProps = ctxDispatchToExpandPanelProps(ctx.dispatch);
265
- const { childLabelProp, schema, path, index, uischemas } = props;
266
- const childPath = composePaths(path, `${index}`);
267
- const childData = Resolve.data(ctx.core.data, childPath);
268
- const childLabel = childLabelProp
269
- ? get(childData, childLabelProp, '')
270
- : get(childData, getFirstPrimitiveProp(schema), '');
289
+ ): ComponentType<OwnPropsOfExpandPanel> =>
290
+ function WithContextToExpandPanelProps({
291
+ ctx,
292
+ props,
293
+ }: JsonFormsStateContext & ExpandPanelProps) {
294
+ const dispatchProps = ctxDispatchToExpandPanelProps(ctx.dispatch);
295
+ const { childLabelProp, schema, path, index, uischemas } = props;
296
+ const childPath = composePaths(path, `${index}`);
297
+ const childData = Resolve.data(ctx.core.data, childPath);
298
+ const childLabel = childLabelProp
299
+ ? get(childData, childLabelProp, '')
300
+ : get(childData, getFirstPrimitiveProp(schema), '');
271
301
 
272
- return (
273
- <Component
274
- {...props}
275
- {...dispatchProps}
276
- childLabel={childLabel}
277
- childPath={childPath}
278
- uischemas={uischemas}
279
- />
280
- );
281
- };
302
+ return (
303
+ <Component
304
+ {...props}
305
+ {...dispatchProps}
306
+ childLabel={childLabel}
307
+ childPath={childPath}
308
+ uischemas={uischemas}
309
+ />
310
+ );
311
+ };
282
312
 
283
313
  export const withJsonFormsExpandPanelProps = (
284
314
  Component: ComponentType<ExpandPanelProps>
285
315
  ): ComponentType<OwnPropsOfExpandPanel> =>
286
- withJsonFormsContext(
287
- withContextToExpandPanelProps(Component));
316
+ withJsonFormsContext(withContextToExpandPanelProps(Component));
288
317
 
289
318
  export default withJsonFormsExpandPanelProps(ExpandPanelRenderer);
@@ -23,7 +23,7 @@
23
23
  THE SOFTWARE.
24
24
  */
25
25
  import range from 'lodash/range';
26
- import React, {useState, useCallback} from 'react';
26
+ import React, { useState, useCallback } from 'react';
27
27
  import {
28
28
  ArrayLayoutProps,
29
29
  composePaths,
@@ -35,15 +35,21 @@ import { ArrayLayoutToolbar } from './ArrayToolbar';
35
35
  import ExpandPanelRenderer from './ExpandPanelRenderer';
36
36
  import merge from 'lodash/merge';
37
37
 
38
- const MaterialArrayLayoutComponent = (props: ArrayLayoutProps)=> {
39
- const [expanded, setExpanded] = useState<string|boolean>(false);
40
- const innerCreateDefaultValue = useCallback(() => createDefaultValue(props.schema), [props.schema]);
41
- const handleChange = useCallback((panel: string) => (_event: any, expandedPanel: boolean) => {
42
- setExpanded(expandedPanel ? panel : false)
43
- }, []);
44
- const isExpanded = (index: number) =>
38
+ const MaterialArrayLayoutComponent = (props: ArrayLayoutProps) => {
39
+ const [expanded, setExpanded] = useState<string | boolean>(false);
40
+ const innerCreateDefaultValue = useCallback(
41
+ () => createDefaultValue(props.schema),
42
+ [props.schema]
43
+ );
44
+ const handleChange = useCallback(
45
+ (panel: string) => (_event: any, expandedPanel: boolean) => {
46
+ setExpanded(expandedPanel ? panel : false);
47
+ },
48
+ []
49
+ );
50
+ const isExpanded = (index: number) =>
45
51
  expanded === composePaths(props.path, `${index}`);
46
-
52
+
47
53
  const {
48
54
  enabled,
49
55
  data,
@@ -58,17 +64,15 @@ const MaterialArrayLayoutComponent = (props: ArrayLayoutProps)=> {
58
64
  required,
59
65
  rootSchema,
60
66
  config,
61
- uischemas
67
+ uischemas,
68
+ translations,
62
69
  } = props;
63
- const appliedUiSchemaOptions = merge(
64
- {},
65
- config,
66
- props.uischema.options
67
- );
70
+ const appliedUiSchemaOptions = merge({}, config, props.uischema.options);
68
71
 
69
72
  return (
70
73
  <div>
71
74
  <ArrayLayoutToolbar
75
+ translations={translations}
72
76
  label={computeLabel(
73
77
  label,
74
78
  required,
@@ -81,7 +85,7 @@ const MaterialArrayLayoutComponent = (props: ArrayLayoutProps)=> {
81
85
  />
82
86
  <div>
83
87
  {data > 0 ? (
84
- map(range(data), index => {
88
+ map(range(data), (index) => {
85
89
  return (
86
90
  <ExpandPanelRenderer
87
91
  enabled={enabled}
@@ -100,6 +104,7 @@ const MaterialArrayLayoutComponent = (props: ArrayLayoutProps)=> {
100
104
  config={config}
101
105
  childLabelProp={appliedUiSchemaOptions.elementLabelProp}
102
106
  uischemas={uischemas}
107
+ translations={translations}
103
108
  />
104
109
  );
105
110
  })
@@ -28,7 +28,7 @@ import {
28
28
  ArrayLayoutProps,
29
29
  isObjectArrayWithNesting,
30
30
  RankedTester,
31
- rankWith
31
+ rankWith,
32
32
  } from '@jsonforms/core';
33
33
  import { Hidden } from '@mui/material';
34
34
  import { MaterialArrayLayout } from './MaterialArrayLayout';
@@ -39,16 +39,13 @@ export const MaterialArrayLayoutRenderer = ({
39
39
  addItem,
40
40
  ...props
41
41
  }: ArrayLayoutProps) => {
42
- const addItemCb = useCallback((p: string, value: any) => addItem(p, value), [
43
- addItem
44
- ]);
42
+ const addItemCb = useCallback(
43
+ (p: string, value: any) => addItem(p, value),
44
+ [addItem]
45
+ );
45
46
  return (
46
47
  <Hidden xsUp={!visible}>
47
- <MaterialArrayLayout
48
- visible={visible}
49
- addItem={addItemCb}
50
- {...props}
51
- />
48
+ <MaterialArrayLayout visible={visible} addItem={addItemCb} {...props} />
52
49
  </Hidden>
53
50
  );
54
51
  };
@@ -22,7 +22,7 @@
22
22
  OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
23
23
  THE SOFTWARE.
24
24
  */
25
- import React, {useState, useMemo} from 'react';
25
+ import React, { useState, useMemo } from 'react';
26
26
  import { AppBar, Hidden, Tab, Tabs } from '@mui/material';
27
27
  import {
28
28
  and,
@@ -35,14 +35,18 @@ import {
35
35
  StatePropsOfLayout,
36
36
  Tester,
37
37
  UISchemaElement,
38
- uiTypeIs
38
+ uiTypeIs,
39
39
  } from '@jsonforms/core';
40
- import { TranslateProps, withJsonFormsLayoutProps, withTranslateProps } from '@jsonforms/react';
40
+ import {
41
+ TranslateProps,
42
+ withJsonFormsLayoutProps,
43
+ withTranslateProps,
44
+ } from '@jsonforms/react';
41
45
  import {
42
46
  AjvProps,
43
47
  MaterialLayoutRenderer,
44
48
  MaterialLayoutRendererProps,
45
- withAjvProps
49
+ withAjvProps,
46
50
  } from '../util/layout';
47
51
 
48
52
  export const isSingleLevelCategorization: Tester = and(
@@ -69,14 +73,18 @@ export interface CategorizationState {
69
73
  }
70
74
 
71
75
  export interface MaterialCategorizationLayoutRendererProps
72
- extends StatePropsOfLayout, AjvProps, TranslateProps {
76
+ extends StatePropsOfLayout,
77
+ AjvProps,
78
+ TranslateProps {
73
79
  selected?: number;
74
80
  ownState?: boolean;
75
81
  data?: any;
76
82
  onChange?(selected: number, prevSelected: number): void;
77
83
  }
78
84
 
79
- export const MaterialCategorizationLayoutRenderer = (props: MaterialCategorizationLayoutRendererProps) => {
85
+ export const MaterialCategorizationLayoutRenderer = (
86
+ props: MaterialCategorizationLayoutRendererProps
87
+ ) => {
80
88
  const {
81
89
  data,
82
90
  path,
@@ -89,50 +97,73 @@ export const MaterialCategorizationLayoutRenderer = (props: MaterialCategorizati
89
97
  selected,
90
98
  onChange,
91
99
  ajv,
92
- t
100
+ t,
93
101
  } = props;
94
102
  const categorization = uischema as Categorization;
95
- const [activeCategory, setActiveCategory]= useState<number|undefined>(selected??0);
96
- const categories = useMemo(() => categorization.elements.filter((category: Category) =>
97
- isVisible(category, data, undefined, ajv)
98
- ),[categorization, data, ajv]);
103
+ const [previousCategorization, setPreviousCategorization] =
104
+ useState<Categorization>(uischema as Categorization);
105
+ const [activeCategory, setActiveCategory] = useState<number>(selected ?? 0);
106
+ const categories = useMemo(
107
+ () =>
108
+ categorization.elements.filter((category: Category) =>
109
+ isVisible(category, data, undefined, ajv)
110
+ ),
111
+ [categorization, data, ajv]
112
+ );
113
+
114
+ if (categorization !== previousCategorization) {
115
+ setActiveCategory(0);
116
+ setPreviousCategorization(categorization);
117
+ }
118
+
119
+ const safeCategory =
120
+ activeCategory >= categorization.elements.length ? 0 : activeCategory;
121
+
99
122
  const childProps: MaterialLayoutRendererProps = {
100
- elements: categories[activeCategory].elements,
123
+ elements: categories[safeCategory] ? categories[safeCategory].elements : [],
101
124
  schema,
102
125
  path,
103
126
  direction: 'column',
104
127
  enabled,
105
128
  visible,
106
129
  renderers,
107
- cells
130
+ cells,
108
131
  };
109
132
  const onTabChange = (_event: any, value: any) => {
110
133
  if (onChange) {
111
- onChange(value, activeCategory);
134
+ onChange(value, safeCategory);
112
135
  }
113
136
  setActiveCategory(value);
114
137
  };
115
138
 
116
139
  const tabLabels = useMemo(() => {
117
- return categories.map((e: Category) =>
118
- deriveLabelForUISchemaElement(e, t)
119
- )
120
- }, [categories, t])
140
+ return categories.map((e: Category) => deriveLabelForUISchemaElement(e, t));
141
+ }, [categories, t]);
121
142
 
122
143
  return (
123
144
  <Hidden xsUp={!visible}>
124
145
  <AppBar position='static'>
125
- <Tabs value={activeCategory} onChange={onTabChange} textColor='inherit' indicatorColor='secondary' variant='scrollable'>
146
+ <Tabs
147
+ value={safeCategory}
148
+ onChange={onTabChange}
149
+ textColor='inherit'
150
+ indicatorColor='secondary'
151
+ variant='scrollable'
152
+ >
126
153
  {categories.map((_, idx: number) => (
127
154
  <Tab key={idx} label={tabLabels[idx]} />
128
155
  ))}
129
156
  </Tabs>
130
157
  </AppBar>
131
158
  <div style={{ marginTop: '0.5em' }}>
132
- <MaterialLayoutRenderer {...childProps} />
159
+ <MaterialLayoutRenderer {...childProps} key={safeCategory} />
133
160
  </div>
134
161
  </Hidden>
135
162
  );
136
163
  };
137
164
 
138
- export default withAjvProps(withTranslateProps(withJsonFormsLayoutProps(MaterialCategorizationLayoutRenderer)));
165
+ export default withAjvProps(
166
+ withTranslateProps(
167
+ withJsonFormsLayoutProps(MaterialCategorizationLayoutRenderer)
168
+ )
169
+ );