@jsonforms/material-renderers 3.3.0-alpha.1 → 3.3.0-beta.0

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 (29) hide show
  1. package/lib/jsonforms-react-material.cjs.js +144 -83
  2. package/lib/jsonforms-react-material.cjs.js.map +1 -1
  3. package/lib/jsonforms-react-material.esm.js +149 -85
  4. package/lib/jsonforms-react-material.esm.js.map +1 -1
  5. package/lib/layouts/ExpandPanelRenderer.d.ts +5 -1
  6. package/package.json +5 -5
  7. package/src/additional/ListWithDetailMasterItem.tsx +13 -6
  8. package/src/additional/MaterialLabelRenderer.tsx +5 -6
  9. package/src/additional/MaterialListWithDetailRenderer.tsx +10 -4
  10. package/src/complex/MaterialAllOfRenderer.tsx +14 -12
  11. package/src/complex/MaterialAnyOfRenderer.tsx +7 -3
  12. package/src/complex/MaterialArrayControlRenderer.tsx +6 -3
  13. package/src/complex/MaterialEnumArrayRenderer.tsx +56 -55
  14. package/src/complex/MaterialObjectRenderer.tsx +14 -12
  15. package/src/complex/MaterialOneOfRenderer.tsx +7 -3
  16. package/src/complex/MaterialTableControl.tsx +34 -33
  17. package/src/controls/MaterialBooleanControl.tsx +7 -8
  18. package/src/controls/MaterialBooleanToggleControl.tsx +7 -8
  19. package/src/controls/MaterialInputControl.tsx +32 -30
  20. package/src/controls/MaterialNativeControl.tsx +23 -21
  21. package/src/controls/MaterialRadioGroup.tsx +39 -38
  22. package/src/controls/MaterialSliderControl.tsx +44 -43
  23. package/src/layouts/ExpandPanelRenderer.tsx +48 -11
  24. package/src/layouts/MaterialArrayLayoutRenderer.tsx +6 -4
  25. package/src/layouts/MaterialCategorizationLayout.tsx +7 -3
  26. package/src/layouts/MaterialCategorizationStepperLayout.tsx +8 -3
  27. package/src/layouts/MaterialGroupLayout.tsx +17 -14
  28. package/src/mui-controls/MuiAutocomplete.tsx +6 -3
  29. package/src/util/layout.tsx +16 -18
@@ -29,7 +29,7 @@ import {
29
29
  isDescriptionHidden,
30
30
  } from '@jsonforms/core';
31
31
 
32
- import { Hidden, InputLabel, FormControl, FormHelperText } from '@mui/material';
32
+ import { InputLabel, FormControl, FormHelperText } from '@mui/material';
33
33
  import merge from 'lodash/merge';
34
34
  import { useFocus, useInputVariant } from '../util';
35
35
 
@@ -69,36 +69,38 @@ export const MaterialInputControl = (props: ControlProps & WithInput) => {
69
69
  const secondFormHelperText = showDescription && !isValid ? errors : null;
70
70
  const InnerComponent = input;
71
71
 
72
+ if (!visible) {
73
+ return null;
74
+ }
75
+
72
76
  return (
73
- <Hidden xsUp={!visible}>
74
- <FormControl
75
- fullWidth={!appliedUiSchemaOptions.trim}
76
- onFocus={onFocus}
77
- onBlur={onBlur}
78
- variant={variant}
79
- id={id}
77
+ <FormControl
78
+ fullWidth={!appliedUiSchemaOptions.trim}
79
+ onFocus={onFocus}
80
+ onBlur={onBlur}
81
+ variant={variant}
82
+ id={id}
83
+ >
84
+ <InputLabel
85
+ htmlFor={id + '-input'}
86
+ error={!isValid}
87
+ required={showAsRequired(
88
+ required,
89
+ appliedUiSchemaOptions.hideRequiredAsterisk
90
+ )}
80
91
  >
81
- <InputLabel
82
- htmlFor={id + '-input'}
83
- error={!isValid}
84
- required={showAsRequired(
85
- required,
86
- appliedUiSchemaOptions.hideRequiredAsterisk
87
- )}
88
- >
89
- {label}
90
- </InputLabel>
91
- <InnerComponent
92
- {...props}
93
- id={id + '-input'}
94
- isValid={isValid}
95
- visible={visible}
96
- />
97
- <FormHelperText error={!isValid && !showDescription}>
98
- {firstFormHelperText}
99
- </FormHelperText>
100
- <FormHelperText error={!isValid}>{secondFormHelperText}</FormHelperText>
101
- </FormControl>
102
- </Hidden>
92
+ {label}
93
+ </InputLabel>
94
+ <InnerComponent
95
+ {...props}
96
+ id={id + '-input'}
97
+ isValid={isValid}
98
+ visible={visible}
99
+ />
100
+ <FormHelperText error={!isValid && !showDescription}>
101
+ {firstFormHelperText}
102
+ </FormHelperText>
103
+ <FormHelperText error={!isValid}>{secondFormHelperText}</FormHelperText>
104
+ </FormControl>
103
105
  );
104
106
  };
@@ -33,7 +33,7 @@ import {
33
33
  RankedTester,
34
34
  rankWith,
35
35
  } from '@jsonforms/core';
36
- import { Hidden, TextField } from '@mui/material';
36
+ import { TextField } from '@mui/material';
37
37
  import { withJsonFormsControlProps } from '@jsonforms/react';
38
38
  import merge from 'lodash/merge';
39
39
  import { useDebouncedChange, useFocus } from '../util';
@@ -70,27 +70,29 @@ export const MaterialNativeControl = (props: ControlProps) => {
70
70
  appliedUiSchemaOptions.showUnfocusedDescription
71
71
  );
72
72
 
73
+ if (!visible) {
74
+ return null;
75
+ }
76
+
73
77
  return (
74
- <Hidden xsUp={!visible}>
75
- <TextField
76
- required={showAsRequired(
77
- required,
78
- appliedUiSchemaOptions.hideRequiredAsterisk
79
- )}
80
- id={id + '-input'}
81
- label={label}
82
- type={fieldType}
83
- error={!isValid}
84
- disabled={!enabled}
85
- fullWidth={!appliedUiSchemaOptions.trim}
86
- onFocus={onFocus}
87
- onBlur={onBlur}
88
- helperText={!isValid ? errors : showDescription ? description : null}
89
- InputLabelProps={{ shrink: true }}
90
- value={inputValue}
91
- onChange={onChange}
92
- />
93
- </Hidden>
78
+ <TextField
79
+ required={showAsRequired(
80
+ required,
81
+ appliedUiSchemaOptions.hideRequiredAsterisk
82
+ )}
83
+ id={id + '-input'}
84
+ label={label}
85
+ type={fieldType}
86
+ error={!isValid}
87
+ disabled={!enabled}
88
+ fullWidth={!appliedUiSchemaOptions.trim}
89
+ onFocus={onFocus}
90
+ onBlur={onBlur}
91
+ helperText={!isValid ? errors : showDescription ? description : null}
92
+ InputLabelProps={{ shrink: true }}
93
+ value={inputValue}
94
+ onChange={onChange}
95
+ />
94
96
  );
95
97
  };
96
98
 
@@ -35,7 +35,6 @@ import {
35
35
  FormControlLabel,
36
36
  FormHelperText,
37
37
  FormLabel,
38
- Hidden,
39
38
  Radio,
40
39
  RadioGroup,
41
40
  } from '@mui/material';
@@ -65,45 +64,47 @@ export const MaterialRadioGroup = (props: ControlProps & OwnPropsOfEnum) => {
65
64
  appliedUiSchemaOptions.showUnfocusedDescription
66
65
  );
67
66
 
67
+ if (!visible) {
68
+ return null;
69
+ }
70
+
68
71
  return (
69
- <Hidden xsUp={!visible}>
70
- <FormControl
71
- component='fieldset'
72
- fullWidth={!appliedUiSchemaOptions.trim}
73
- onFocus={onFocus}
74
- onBlur={onBlur}
72
+ <FormControl
73
+ component='fieldset'
74
+ fullWidth={!appliedUiSchemaOptions.trim}
75
+ onFocus={onFocus}
76
+ onBlur={onBlur}
77
+ >
78
+ <FormLabel
79
+ error={!isValid}
80
+ component='legend'
81
+ required={showAsRequired(
82
+ required,
83
+ appliedUiSchemaOptions.hideRequiredAsterisk
84
+ )}
75
85
  >
76
- <FormLabel
77
- error={!isValid}
78
- component='legend'
79
- required={showAsRequired(
80
- required,
81
- appliedUiSchemaOptions.hideRequiredAsterisk
82
- )}
83
- >
84
- {label}
85
- </FormLabel>
86
+ {label}
87
+ </FormLabel>
86
88
 
87
- <RadioGroup value={props.data ?? ''} row={true}>
88
- {options.map((option) => (
89
- <FormControlLabel
90
- value={option.value}
91
- key={option.label}
92
- control={
93
- <Radio
94
- checked={data === option.value}
95
- onChange={() => handleChange(path, option.value)}
96
- />
97
- }
98
- label={option.label}
99
- disabled={!enabled}
100
- />
101
- ))}
102
- </RadioGroup>
103
- <FormHelperText error={!isValid}>
104
- {!isValid ? errors : showDescription ? description : null}
105
- </FormHelperText>
106
- </FormControl>
107
- </Hidden>
89
+ <RadioGroup value={props.data ?? ''} row={true}>
90
+ {options.map((option) => (
91
+ <FormControlLabel
92
+ value={option.value}
93
+ key={option.label}
94
+ control={
95
+ <Radio
96
+ checked={data === option.value}
97
+ onChange={() => handleChange(path, option.value)}
98
+ />
99
+ }
100
+ label={option.label}
101
+ disabled={!enabled}
102
+ />
103
+ ))}
104
+ </RadioGroup>
105
+ <FormHelperText error={!isValid}>
106
+ {!isValid ? errors : showDescription ? description : null}
107
+ </FormHelperText>
108
+ </FormControl>
108
109
  );
109
110
  };
@@ -37,7 +37,6 @@ import {
37
37
  FormControl,
38
38
  FormHelperText,
39
39
  FormLabel,
40
- Hidden,
41
40
  Slider,
42
41
  Typography,
43
42
  } from '@mui/material';
@@ -90,50 +89,52 @@ export const MaterialSliderControl = (props: ControlProps) => {
90
89
  [path, handleChange]
91
90
  );
92
91
 
92
+ if (!visible) {
93
+ return null;
94
+ }
95
+
93
96
  return (
94
- <Hidden xsUp={!visible}>
95
- <FormControl
96
- fullWidth={!appliedUiSchemaOptions.trim}
97
- onFocus={onFocus}
98
- onBlur={onBlur}
99
- id={id}
97
+ <FormControl
98
+ fullWidth={!appliedUiSchemaOptions.trim}
99
+ onFocus={onFocus}
100
+ onBlur={onBlur}
101
+ id={id}
102
+ >
103
+ <FormLabel
104
+ htmlFor={id}
105
+ error={!isValid}
106
+ component='legend'
107
+ required={showAsRequired(
108
+ required,
109
+ appliedUiSchemaOptions.hideRequiredAsterisk
110
+ )}
100
111
  >
101
- <FormLabel
102
- htmlFor={id}
103
- error={!isValid}
104
- component='legend'
105
- required={showAsRequired(
106
- required,
107
- appliedUiSchemaOptions.hideRequiredAsterisk
108
- )}
109
- >
110
- <Typography id={id + '-typo'} style={labelStyle} variant='caption'>
111
- {label}
112
- </Typography>
113
- </FormLabel>
114
- <div style={rangeContainerStyle}>
115
- <Typography style={rangeItemStyle} variant='caption' align='left'>
116
- {schema.minimum}
117
- </Typography>
118
- <Typography style={rangeItemStyle} variant='caption' align='right'>
119
- {schema.maximum}
120
- </Typography>
121
- </div>
122
- <Slider
123
- style={sliderStyle}
124
- min={schema.minimum}
125
- max={schema.maximum}
126
- value={Number(data || schema.default)}
127
- onChange={onChange}
128
- id={id + '-input'}
129
- disabled={!enabled}
130
- step={schema.multipleOf || 1}
131
- />
132
- <FormHelperText error={!isValid}>
133
- {!isValid ? errors : showDescription ? description : null}
134
- </FormHelperText>
135
- </FormControl>
136
- </Hidden>
112
+ <Typography id={id + '-typo'} style={labelStyle} variant='caption'>
113
+ {label}
114
+ </Typography>
115
+ </FormLabel>
116
+ <div style={rangeContainerStyle}>
117
+ <Typography style={rangeItemStyle} variant='caption' align='left'>
118
+ {schema.minimum}
119
+ </Typography>
120
+ <Typography style={rangeItemStyle} variant='caption' align='right'>
121
+ {schema.maximum}
122
+ </Typography>
123
+ </div>
124
+ <Slider
125
+ style={sliderStyle}
126
+ min={schema.minimum}
127
+ max={schema.maximum}
128
+ value={Number(data || schema.default)}
129
+ onChange={onChange}
130
+ id={id + '-input'}
131
+ disabled={!enabled}
132
+ step={schema.multipleOf || 1}
133
+ />
134
+ <FormHelperText error={!isValid}>
135
+ {!isValid ? errors : showDescription ? description : null}
136
+ </FormHelperText>
137
+ </FormControl>
137
138
  );
138
139
  };
139
140
  export const materialSliderControlTester: RankedTester = rankWith(
@@ -1,5 +1,4 @@
1
1
  import merge from 'lodash/merge';
2
- import get from 'lodash/get';
3
2
  import React, {
4
3
  ComponentType,
5
4
  Dispatch,
@@ -23,14 +22,13 @@ import {
23
22
  JsonSchema,
24
23
  moveDown,
25
24
  moveUp,
26
- Resolve,
27
25
  update,
28
26
  JsonFormsCellRendererRegistryEntry,
29
27
  JsonFormsUISchemaRegistryEntry,
30
- getFirstPrimitiveProp,
31
28
  createId,
32
29
  removeId,
33
30
  ArrayTranslations,
31
+ computeChildLabel,
34
32
  } from '@jsonforms/core';
35
33
  import {
36
34
  Accordion,
@@ -311,18 +309,56 @@ export const ctxDispatchToExpandPanelProps: (
311
309
  */
312
310
  export const withContextToExpandPanelProps = (
313
311
  Component: ComponentType<ExpandPanelProps>
314
- ): ComponentType<OwnPropsOfExpandPanel> =>
315
- function WithContextToExpandPanelProps({
312
+ ): ComponentType<{
313
+ ctx: JsonFormsStateContext;
314
+ props: OwnPropsOfExpandPanel;
315
+ }> => {
316
+ return function WithContextToExpandPanelProps({
316
317
  ctx,
317
318
  props,
318
- }: JsonFormsStateContext & ExpandPanelProps) {
319
+ }: {
320
+ ctx: JsonFormsStateContext;
321
+ props: ExpandPanelProps;
322
+ }) {
319
323
  const dispatchProps = ctxDispatchToExpandPanelProps(ctx.dispatch);
320
- const { childLabelProp, schema, path, index, uischemas } = props;
324
+ const {
325
+ // eslint is unable to detect that these props are "checked" via Typescript already
326
+ // eslint-disable-next-line react/prop-types
327
+ childLabelProp,
328
+ // eslint-disable-next-line react/prop-types
329
+ schema,
330
+ // eslint-disable-next-line react/prop-types
331
+ uischema,
332
+ // eslint-disable-next-line react/prop-types
333
+ rootSchema,
334
+ // eslint-disable-next-line react/prop-types
335
+ path,
336
+ // eslint-disable-next-line react/prop-types
337
+ index,
338
+ // eslint-disable-next-line react/prop-types
339
+ uischemas,
340
+ } = props;
321
341
  const childPath = composePaths(path, `${index}`);
322
- const childData = Resolve.data(ctx.core.data, childPath);
323
- const childLabel = childLabelProp
324
- ? get(childData, childLabelProp, '')
325
- : get(childData, getFirstPrimitiveProp(schema), '');
342
+
343
+ const childLabel = useMemo(() => {
344
+ return computeChildLabel(
345
+ ctx.core.data,
346
+ childPath,
347
+ childLabelProp,
348
+ schema,
349
+ rootSchema,
350
+ ctx.i18n.translate,
351
+ uischema
352
+ );
353
+ }, [
354
+ ctx.core.data,
355
+ childPath,
356
+ childLabelProp,
357
+ schema,
358
+ rootSchema,
359
+ ctx.i18n.translate,
360
+ uischema,
361
+ ]);
326
362
 
327
363
  return (
328
364
  <Component
@@ -334,6 +370,7 @@ export const withContextToExpandPanelProps = (
334
370
  />
335
371
  );
336
372
  };
373
+ };
337
374
 
338
375
  export const withJsonFormsExpandPanelProps = (
339
376
  Component: ComponentType<ExpandPanelProps>
@@ -30,7 +30,6 @@ import {
30
30
  RankedTester,
31
31
  rankWith,
32
32
  } from '@jsonforms/core';
33
- import { Hidden } from '@mui/material';
34
33
  import { MaterialArrayLayout } from './MaterialArrayLayout';
35
34
  import { withJsonFormsArrayLayoutProps } from '@jsonforms/react';
36
35
 
@@ -43,10 +42,13 @@ export const MaterialArrayLayoutRenderer = ({
43
42
  (p: string, value: any) => addItem(p, value),
44
43
  [addItem]
45
44
  );
45
+
46
+ if (!visible) {
47
+ return null;
48
+ }
49
+
46
50
  return (
47
- <Hidden xsUp={!visible}>
48
- <MaterialArrayLayout visible={visible} addItem={addItemCb} {...props} />
49
- </Hidden>
51
+ <MaterialArrayLayout visible={visible} addItem={addItemCb} {...props} />
50
52
  );
51
53
  };
52
54
 
@@ -23,7 +23,7 @@
23
23
  THE SOFTWARE.
24
24
  */
25
25
  import React, { useState, useMemo } from 'react';
26
- import { AppBar, Hidden, Tab, Tabs } from '@mui/material';
26
+ import { AppBar, Tab, Tabs } from '@mui/material';
27
27
  import {
28
28
  and,
29
29
  Categorization,
@@ -140,8 +140,12 @@ export const MaterialCategorizationLayoutRenderer = (
140
140
  return categories.map((e: Category) => deriveLabelForUISchemaElement(e, t));
141
141
  }, [categories, t]);
142
142
 
143
+ if (!visible) {
144
+ return null;
145
+ }
146
+
143
147
  return (
144
- <Hidden xsUp={!visible}>
148
+ <>
145
149
  <AppBar position='static'>
146
150
  <Tabs
147
151
  value={safeCategory}
@@ -158,7 +162,7 @@ export const MaterialCategorizationLayoutRenderer = (
158
162
  <div style={{ marginTop: '0.5em' }}>
159
163
  <MaterialLayoutRenderer {...childProps} key={safeCategory} />
160
164
  </div>
161
- </Hidden>
165
+ </>
162
166
  );
163
167
  };
164
168
 
@@ -24,7 +24,7 @@
24
24
  */
25
25
  import React, { useState, useMemo } from 'react';
26
26
  import merge from 'lodash/merge';
27
- import { Button, Hidden, Step, StepButton, Stepper } from '@mui/material';
27
+ import { Button, Step, StepButton, Stepper } from '@mui/material';
28
28
  import {
29
29
  and,
30
30
  Categorization,
@@ -123,8 +123,13 @@ export const MaterialCategorizationStepperLayoutRenderer = (
123
123
  const tabLabels = useMemo(() => {
124
124
  return categories.map((e: Category) => deriveLabelForUISchemaElement(e, t));
125
125
  }, [categories, t]);
126
+
127
+ if (!visible) {
128
+ return null;
129
+ }
130
+
126
131
  return (
127
- <Hidden xsUp={!visible}>
132
+ <>
128
133
  <Stepper activeStep={activeCategory} nonLinear>
129
134
  {categories.map((_: Category, idx: number) => (
130
135
  <Step key={tabLabels[idx]}>
@@ -161,7 +166,7 @@ export const MaterialCategorizationStepperLayoutRenderer = (
161
166
  ) : (
162
167
  <></>
163
168
  )}
164
- </Hidden>
169
+ </>
165
170
  );
166
171
  };
167
172
 
@@ -24,7 +24,7 @@
24
24
  */
25
25
  import isEmpty from 'lodash/isEmpty';
26
26
  import React from 'react';
27
- import { Card, CardContent, CardHeader, Hidden } from '@mui/material';
27
+ import { Card, CardContent, CardHeader } from '@mui/material';
28
28
  import {
29
29
  GroupLayout,
30
30
  LayoutProps,
@@ -50,20 +50,23 @@ const GroupComponent = React.memo(function GroupComponent({
50
50
  ...props
51
51
  }: MaterialLabelableLayoutRendererProps) {
52
52
  const groupLayout = uischema as GroupLayout;
53
+
54
+ if (!visible) {
55
+ return null;
56
+ }
57
+
53
58
  return (
54
- <Hidden xsUp={!visible}>
55
- <Card style={style}>
56
- {!isEmpty(label) && <CardHeader title={label} />}
57
- <CardContent>
58
- <MaterialLayoutRenderer
59
- {...props}
60
- visible={visible}
61
- enabled={enabled}
62
- elements={groupLayout.elements}
63
- />
64
- </CardContent>
65
- </Card>
66
- </Hidden>
59
+ <Card style={style}>
60
+ {!isEmpty(label) && <CardHeader title={label} />}
61
+ <CardContent>
62
+ <MaterialLayoutRenderer
63
+ {...props}
64
+ visible={visible}
65
+ enabled={enabled}
66
+ elements={groupLayout.elements}
67
+ />
68
+ </CardContent>
69
+ </Card>
67
70
  );
68
71
  });
69
72
 
@@ -36,7 +36,6 @@ import {
36
36
  AutocompleteRenderOptionState,
37
37
  FilterOptionsState,
38
38
  FormHelperText,
39
- Hidden,
40
39
  TextField,
41
40
  } from '@mui/material';
42
41
  import merge from 'lodash/merge';
@@ -98,8 +97,12 @@ export const MuiAutocomplete = (
98
97
  : null;
99
98
  const secondFormHelperText = showDescription && !isValid ? errors : null;
100
99
 
100
+ if (!visible) {
101
+ return null;
102
+ }
103
+
101
104
  return (
102
- <Hidden xsUp={!visible}>
105
+ <>
103
106
  <Autocomplete
104
107
  className={className}
105
108
  id={id}
@@ -148,6 +151,6 @@ export const MuiAutocomplete = (
148
151
  {firstFormHelperText}
149
152
  </FormHelperText>
150
153
  <FormHelperText error={!isValid}>{secondFormHelperText}</FormHelperText>
151
- </Hidden>
154
+ </>
152
155
  );
153
156
  };
@@ -34,7 +34,7 @@ import {
34
34
  OwnPropsOfRenderer,
35
35
  } from '@jsonforms/core';
36
36
  import { JsonFormsDispatch, useJsonForms } from '@jsonforms/react';
37
- import { Grid, Hidden } from '@mui/material';
37
+ import { Grid } from '@mui/material';
38
38
 
39
39
  export const renderLayoutElements = (
40
40
  elements: UISchemaElement[],
@@ -72,26 +72,24 @@ const MaterialLayoutRendererComponent = ({
72
72
  renderers,
73
73
  cells,
74
74
  }: MaterialLayoutRendererProps) => {
75
- if (isEmpty(elements)) {
75
+ if (isEmpty(elements) || !visible) {
76
76
  return null;
77
77
  } else {
78
78
  return (
79
- <Hidden xsUp={!visible}>
80
- <Grid
81
- container
82
- direction={direction}
83
- spacing={direction === 'row' ? 2 : 0}
84
- >
85
- {renderLayoutElements(
86
- elements,
87
- schema,
88
- path,
89
- enabled,
90
- renderers,
91
- cells
92
- )}
93
- </Grid>
94
- </Hidden>
79
+ <Grid
80
+ container
81
+ direction={direction}
82
+ spacing={direction === 'row' ? 2 : 0}
83
+ >
84
+ {renderLayoutElements(
85
+ elements,
86
+ schema,
87
+ path,
88
+ enabled,
89
+ renderers,
90
+ cells
91
+ )}
92
+ </Grid>
95
93
  );
96
94
  }
97
95
  };