@jsonforms/material-renderers 3.0.0-beta.4 → 3.0.0-rc.1

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 (65) hide show
  1. package/docs/assets/js/search.json +1 -1
  2. package/docs/globals.html +167 -40
  3. package/docs/index.html +15 -0
  4. package/docs/interfaces/categorizationstate.html +1 -1
  5. package/docs/interfaces/categorizationstepperstate.html +1 -1
  6. package/docs/interfaces/inputref.html +168 -0
  7. package/docs/interfaces/materialcategorizationlayoutrendererprops.html +49 -4
  8. package/docs/interfaces/materialcategorizationstepperlayoutrendererprops.html +46 -1
  9. package/docs/interfaces/materiallabelablelayoutrendererprops.html +328 -0
  10. package/docs/interfaces/materiallayoutrendererprops.html +5 -0
  11. package/docs/interfaces/withoptionlabel.html +3 -3
  12. package/lib/additional/MaterialLabelRenderer.d.ts +3 -3
  13. package/lib/cells/MaterialEnumCell.d.ts +2 -1
  14. package/lib/cells/MaterialOneOfEnumCell.d.ts +2 -1
  15. package/lib/controls/MaterialEnumControl.d.ts +2 -1
  16. package/lib/controls/MaterialOneOfEnumControl.d.ts +2 -1
  17. package/lib/controls/index.d.ts +2 -2
  18. package/lib/jsonforms-react-material.cjs.js +143 -65
  19. package/lib/jsonforms-react-material.cjs.js.map +1 -1
  20. package/lib/jsonforms-react-material.esm.js +137 -57
  21. package/lib/jsonforms-react-material.esm.js.map +1 -1
  22. package/lib/layouts/MaterialCategorizationLayout.d.ts +4 -3
  23. package/lib/layouts/MaterialCategorizationStepperLayout.d.ts +4 -3
  24. package/lib/layouts/MaterialGroupLayout.d.ts +2 -2
  25. package/lib/layouts/MaterialHorizontalLayout.d.ts +1 -1
  26. package/lib/layouts/MaterialVerticalLayout.d.ts +1 -1
  27. package/lib/mui-controls/MuiAutocomplete.d.ts +2 -2
  28. package/lib/mui-controls/MuiSelect.d.ts +2 -1
  29. package/lib/util/datejs.d.ts +17 -1
  30. package/lib/util/i18nDefaults.d.ts +3 -0
  31. package/lib/util/index.d.ts +1 -0
  32. package/lib/util/layout.d.ts +3 -0
  33. package/package.json +9 -9
  34. package/src/additional/MaterialLabelRenderer.tsx +5 -7
  35. package/src/additional/MaterialListWithDetailRenderer.tsx +4 -0
  36. package/src/cells/MaterialEnumCell.tsx +4 -3
  37. package/src/cells/MaterialOneOfEnumCell.tsx +3 -3
  38. package/src/controls/MaterialDateControl.tsx +30 -12
  39. package/src/controls/MaterialDateTimeControl.tsx +32 -13
  40. package/src/controls/MaterialEnumControl.tsx +12 -5
  41. package/src/controls/MaterialOneOfEnumControl.tsx +13 -5
  42. package/src/controls/MaterialRadioGroup.tsx +1 -1
  43. package/src/controls/MaterialTimeControl.tsx +31 -13
  44. package/src/layouts/MaterialCategorizationLayout.tsx +18 -9
  45. package/src/layouts/MaterialCategorizationStepperLayout.tsx +19 -12
  46. package/src/layouts/MaterialGroupLayout.tsx +6 -5
  47. package/src/mui-controls/MuiAutocomplete.tsx +81 -37
  48. package/src/mui-controls/MuiInputText.tsx +4 -1
  49. package/src/mui-controls/MuiSelect.tsx +10 -5
  50. package/src/util/datejs.tsx +73 -0
  51. package/src/util/i18nDefaults.ts +3 -0
  52. package/src/util/index.ts +1 -0
  53. package/src/util/layout.tsx +4 -0
  54. package/stats.html +1 -1
  55. package/test/renderers/MaterialArrayLayout.test.tsx +4 -4
  56. package/test/renderers/MaterialCategorizationLayout.test.tsx +17 -7
  57. package/test/renderers/MaterialCategorizationStepperLayout.test.tsx +21 -11
  58. package/test/renderers/MaterialDateControl.test.tsx +27 -0
  59. package/test/renderers/MaterialDateTimeControl.test.tsx +29 -2
  60. package/test/renderers/MaterialGroupLayout.test.tsx +4 -1
  61. package/test/renderers/MaterialInputControl.test.tsx +4 -0
  62. package/test/renderers/MaterialLabelRenderer.test.tsx +2 -1
  63. package/test/renderers/MaterialTimeControl.test.tsx +28 -1
  64. package/test/renderers/util.ts +5 -0
  65. package/src/util/datejs.ts +0 -32
@@ -1,17 +1,18 @@
1
- import React from 'react';
1
+ /// <reference types="react" />
2
2
  import { RankedTester, StatePropsOfLayout, Tester } from '@jsonforms/core';
3
+ import { TranslateProps } from '@jsonforms/react';
3
4
  import { AjvProps } from '../util/layout';
4
5
  export declare const isSingleLevelCategorization: Tester;
5
6
  export declare const materialCategorizationTester: RankedTester;
6
7
  export interface CategorizationState {
7
8
  activeCategory: number;
8
9
  }
9
- export interface MaterialCategorizationLayoutRendererProps extends StatePropsOfLayout, AjvProps {
10
+ export interface MaterialCategorizationLayoutRendererProps extends StatePropsOfLayout, AjvProps, TranslateProps {
10
11
  selected?: number;
11
12
  ownState?: boolean;
12
13
  data?: any;
13
14
  onChange?(selected: number, prevSelected: number): void;
14
15
  }
15
16
  export declare const MaterialCategorizationLayoutRenderer: (props: MaterialCategorizationLayoutRendererProps) => JSX.Element;
16
- declare const _default: React.ComponentType<import("@jsonforms/core").OwnPropsOfLayout>;
17
+ declare const _default: (props: MaterialCategorizationLayoutRendererProps & import("@jsonforms/core").OwnPropsOfLayout) => JSX.Element;
17
18
  export default _default;
@@ -1,13 +1,14 @@
1
- import React from 'react';
1
+ /// <reference types="react" />
2
2
  import { RankedTester, StatePropsOfLayout } from '@jsonforms/core';
3
+ import { TranslateProps } from '@jsonforms/react';
3
4
  import { AjvProps } from '../util/layout';
4
5
  export declare const materialCategorizationStepperTester: RankedTester;
5
6
  export interface CategorizationStepperState {
6
7
  activeCategory: number;
7
8
  }
8
- export interface MaterialCategorizationStepperLayoutRendererProps extends StatePropsOfLayout, AjvProps {
9
+ export interface MaterialCategorizationStepperLayoutRendererProps extends StatePropsOfLayout, AjvProps, TranslateProps {
9
10
  data: any;
10
11
  }
11
12
  export declare const MaterialCategorizationStepperLayoutRenderer: (props: MaterialCategorizationStepperLayoutRendererProps) => JSX.Element;
12
- declare const _default: React.ComponentType<import("@jsonforms/core").OwnPropsOfLayout>;
13
+ declare const _default: (props: MaterialCategorizationStepperLayoutRendererProps & import("@jsonforms/core").OwnPropsOfLayout) => JSX.Element;
13
14
  export default _default;
@@ -1,7 +1,7 @@
1
1
  import React from 'react';
2
2
  import { LayoutProps, RankedTester } from '@jsonforms/core';
3
3
  export declare const groupTester: RankedTester;
4
- export declare const MaterializedGroupLayoutRenderer: ({ uischema, schema, path, visible, enabled, renderers, cells, direction }: LayoutProps) => JSX.Element;
5
- declare const _default: React.ComponentType<import("@jsonforms/core").OwnPropsOfLayout>;
4
+ export declare const MaterializedGroupLayoutRenderer: ({ uischema, schema, path, visible, enabled, renderers, cells, direction, label }: LayoutProps) => JSX.Element;
5
+ declare const _default: React.ComponentType<LayoutProps & import("@jsonforms/core").OwnPropsOfLayout>;
6
6
  export default _default;
7
7
  export declare const materialGroupTester: RankedTester;
@@ -6,5 +6,5 @@ import { LayoutProps, RankedTester } from '@jsonforms/core';
6
6
  */
7
7
  export declare const materialHorizontalLayoutTester: RankedTester;
8
8
  export declare const MaterialHorizontalLayoutRenderer: ({ uischema, renderers, cells, schema, path, enabled, visible }: LayoutProps) => JSX.Element;
9
- declare const _default: React.ComponentType<import("@jsonforms/core").OwnPropsOfLayout>;
9
+ declare const _default: React.ComponentType<LayoutProps & import("@jsonforms/core").OwnPropsOfLayout>;
10
10
  export default _default;
@@ -6,5 +6,5 @@ import { LayoutProps, RankedTester } from '@jsonforms/core';
6
6
  */
7
7
  export declare const materialVerticalLayoutTester: RankedTester;
8
8
  export declare const MaterialVerticalLayoutRenderer: ({ uischema, schema, path, enabled, visible, renderers, cells }: LayoutProps) => JSX.Element;
9
- declare const _default: React.ComponentType<import("@jsonforms/core").OwnPropsOfLayout>;
9
+ declare const _default: React.ComponentType<LayoutProps & import("@jsonforms/core").OwnPropsOfLayout>;
10
10
  export default _default;
@@ -1,9 +1,9 @@
1
1
  import React, { ReactNode } from 'react';
2
- import { EnumCellProps, EnumOption, WithClassname } from '@jsonforms/core';
2
+ import { ControlProps, EnumCellProps, EnumOption, WithClassname } from '@jsonforms/core';
3
3
  import { AutocompleteRenderOptionState, FilterOptionsState } from '@mui/material';
4
4
  export interface WithOptionLabel {
5
5
  getOptionLabel?(option: EnumOption): string;
6
6
  renderOption?(props: React.HTMLAttributes<HTMLLIElement>, option: EnumOption, state: AutocompleteRenderOptionState): ReactNode;
7
7
  filterOptions?(options: EnumOption[], state: FilterOptionsState<EnumOption>): EnumOption[];
8
8
  }
9
- export declare const MuiAutocomplete: (props: EnumCellProps & WithClassname & WithOptionLabel) => JSX.Element;
9
+ export declare const MuiAutocomplete: (props: ControlProps & EnumCellProps & WithClassname & WithOptionLabel) => JSX.Element;
@@ -1,3 +1,4 @@
1
1
  import React from 'react';
2
2
  import { EnumCellProps, WithClassname } from '@jsonforms/core';
3
- export declare const MuiSelect: React.MemoExoticComponent<(props: EnumCellProps & WithClassname) => JSX.Element>;
3
+ import { TranslateProps } from '@jsonforms/react';
4
+ export declare const MuiSelect: React.MemoExoticComponent<(props: EnumCellProps & WithClassname & TranslateProps) => JSX.Element>;
@@ -1,3 +1,19 @@
1
+ import { TextFieldProps } from '@mui/material';
1
2
  import dayjs from 'dayjs';
2
- export declare const createOnChangeHandler: (path: string, handleChange: (path: string, value: any) => void, saveFormat: string | undefined) => (time: dayjs.Dayjs) => void;
3
+ import React from 'react';
4
+ export declare const createOnChangeHandler: (path: string, handleChange: (path: string, value: any) => void, saveFormat: string | undefined) => (time: dayjs.Dayjs, textInputValue: string) => void;
3
5
  export declare const getData: (data: any, saveFormat: string | undefined) => dayjs.Dayjs | null;
6
+ declare type ResettableTextFieldProps = TextFieldProps & {
7
+ rawValue: any;
8
+ dayjsValueIsValid: boolean;
9
+ valueInInputFormat: string;
10
+ focused: boolean;
11
+ };
12
+ /**
13
+ * The dayjs formatter/parser is very lenient and for example ignores additional digits and/or characters.
14
+ * In these cases the input text can look vastly different than the actual value stored in the data.
15
+ * The 'ResettableTextField' component adjusts the text field to reflect the actual value stored in the data
16
+ * once it's no longer 'focused', i.e. when the user stops editing.
17
+ */
18
+ export declare const ResettableTextField: React.FC<ResettableTextFieldProps>;
19
+ export {};
@@ -0,0 +1,3 @@
1
+ export declare const i18nDefaults: {
2
+ 'enum.none': string;
3
+ };
@@ -3,3 +3,4 @@ export * from './layout';
3
3
  export * from './theme';
4
4
  export * from './debounce';
5
5
  export * from './focus';
6
+ export * from './i18nDefaults';
@@ -13,3 +13,6 @@ export interface AjvProps {
13
13
  ajv: Ajv;
14
14
  }
15
15
  export declare const withAjvProps: <P extends {}>(Component: React.ComponentType<AjvProps & P>) => (props: P) => JSX.Element;
16
+ export interface MaterialLabelableLayoutRendererProps extends MaterialLayoutRendererProps {
17
+ label?: string;
18
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@jsonforms/material-renderers",
3
- "version": "3.0.0-beta.4",
3
+ "version": "3.0.0-rc.1",
4
4
  "description": "Material Renderer Set for JSON Forms",
5
5
  "repository": "https://github.com/eclipsesource/jsonforms",
6
6
  "bugs": "https://github.com/eclipsesource/jsonforms/issues",
@@ -76,20 +76,20 @@
76
76
  "peerDependencies": {
77
77
  "@emotion/react": "^11.4.1",
78
78
  "@emotion/styled": "^11.3.0",
79
- "@jsonforms/core": "3.0.0-beta.4",
80
- "@jsonforms/react": "3.0.0-beta.4",
79
+ "@jsonforms/core": "3.0.0-rc.1",
80
+ "@jsonforms/react": "3.0.0-rc.1",
81
81
  "@mui/icons-material": "^5.0.0",
82
- "@mui/lab": "^5.0.0-alpha.54",
83
- "@mui/material": "^5.0.0"
82
+ "@mui/material": "^5.0.0",
83
+ "@mui/x-date-pickers": "^5.0.0-beta.5"
84
84
  },
85
85
  "devDependencies": {
86
86
  "@emotion/react": "^11.5.0",
87
87
  "@emotion/styled": "^11.3.0",
88
- "@jsonforms/core": "^3.0.0-beta.4",
89
- "@jsonforms/react": "^3.0.0-beta.4",
88
+ "@jsonforms/core": "^3.0.0-rc.1",
89
+ "@jsonforms/react": "^3.0.0-rc.1",
90
90
  "@mui/icons-material": "^5.2.0",
91
- "@mui/lab": "^5.0.0-alpha.58",
92
91
  "@mui/material": "^5.2.2",
92
+ "@mui/x-date-pickers": "^5.0.0-beta.5",
93
93
  "@types/enzyme": "^3.10.3",
94
94
  "@types/react-dom": "^17.0.9",
95
95
  "@wojtekmaj/enzyme-adapter-react-17": "^0.6.3",
@@ -114,5 +114,5 @@
114
114
  "webpack-cli": "^3.2.1",
115
115
  "webpack-dev-server": "^3.9.0"
116
116
  },
117
- "gitHead": "413b9767ea8e2c0b6adb3919f5e6b76263d4be31"
117
+ "gitHead": "852057ca1706007bee24bcb1b53b88c7231628a0"
118
118
  }
@@ -24,13 +24,12 @@
24
24
  */
25
25
  import React from 'react';
26
26
  import {
27
- LabelElement,
28
- OwnPropsOfRenderer,
27
+ LabelProps,
29
28
  RankedTester,
30
29
  rankWith,
31
30
  uiTypeIs,
32
31
  } from '@jsonforms/core';
33
- import { withJsonFormsLayoutProps } from '@jsonforms/react';
32
+ import { withJsonFormsLabelProps } from '@jsonforms/react';
34
33
  import {
35
34
  Hidden,
36
35
  Typography
@@ -45,15 +44,14 @@ export const materialLabelRendererTester: RankedTester = rankWith(1, uiTypeIs('L
45
44
  /**
46
45
  * Default renderer for a label.
47
46
  */
48
- export const MaterialLabelRenderer = ({ uischema, visible }: OwnPropsOfRenderer) => {
49
- const labelElement: LabelElement = uischema as LabelElement;
47
+ export const MaterialLabelRenderer = ({ text, visible }: LabelProps ) => {
50
48
  return (
51
49
  <Hidden xsUp={!visible}>
52
50
  <Typography variant='h6'>
53
- {labelElement.text !== undefined && labelElement.text !== null && labelElement.text}
51
+ {text}
54
52
  </Typography>
55
53
  </Hidden>
56
54
  );
57
55
  };
58
56
 
59
- export default withJsonFormsLayoutProps(MaterialLabelRenderer);
57
+ export default withJsonFormsLabelProps(MaterialLabelRenderer);
@@ -98,6 +98,10 @@ export const MaterialListWithDetailRenderer = ({
98
98
  );
99
99
  const appliedUiSchemaOptions = merge({}, config, uischema.options);
100
100
 
101
+ React.useEffect(() => {
102
+ setSelectedIndex(undefined);
103
+ }, [schema]);
104
+
101
105
  return (
102
106
  <Hidden xsUp={!visible}>
103
107
  <ArrayLayoutToolbar
@@ -30,10 +30,10 @@ import {
30
30
  rankWith,
31
31
  WithClassname
32
32
  } from '@jsonforms/core';
33
- import { withJsonFormsEnumCellProps } from '@jsonforms/react';
33
+ import { TranslateProps, withJsonFormsEnumCellProps, withTranslateProps } from '@jsonforms/react';
34
34
  import { MuiSelect } from '../mui-controls/MuiSelect';
35
35
 
36
- export const MaterialEnumCell = (props: EnumCellProps & WithClassname) => (
36
+ export const MaterialEnumCell = (props: EnumCellProps & WithClassname & TranslateProps) => (
37
37
  <MuiSelect {...props} />
38
38
  );
39
39
 
@@ -43,4 +43,5 @@ export const MaterialEnumCell = (props: EnumCellProps & WithClassname) => (
43
43
  */
44
44
  export const materialEnumCellTester: RankedTester = rankWith(2, isEnumControl);
45
45
 
46
- export default withJsonFormsEnumCellProps(MaterialEnumCell);
46
+ // HOC order can be reversed with https://github.com/eclipsesource/jsonforms/issues/1987
47
+ export default withJsonFormsEnumCellProps(withTranslateProps(React.memo(MaterialEnumCell)), false);
@@ -30,10 +30,10 @@ import {
30
30
  rankWith,
31
31
  WithClassname
32
32
  } from '@jsonforms/core';
33
- import { withJsonFormsOneOfEnumCellProps } from '@jsonforms/react';
33
+ import { TranslateProps, withJsonFormsOneOfEnumCellProps, withTranslateProps } from '@jsonforms/react';
34
34
  import { MuiSelect } from '../mui-controls/MuiSelect';
35
35
 
36
- export const MaterialOneOfEnumCell = (props: EnumCellProps & WithClassname) => (
36
+ export const MaterialOneOfEnumCell = (props: EnumCellProps & WithClassname & TranslateProps) => (
37
37
  <MuiSelect {...props} />
38
38
  );
39
39
 
@@ -43,4 +43,4 @@ export const MaterialOneOfEnumCell = (props: EnumCellProps & WithClassname) => (
43
43
  */
44
44
  export const materialOneOfEnumCellTester: RankedTester = rankWith(2, isOneOfEnumControl);
45
45
 
46
- export default withJsonFormsOneOfEnumCellProps(MaterialOneOfEnumCell);
46
+ export default withJsonFormsOneOfEnumCellProps(withTranslateProps(React.memo(MaterialOneOfEnumCell)), false);
@@ -32,13 +32,18 @@ import {
32
32
  rankWith,
33
33
  } from '@jsonforms/core';
34
34
  import { withJsonFormsControlProps } from '@jsonforms/react';
35
- import { FormHelperText, Hidden, TextField } from '@mui/material';
35
+ import { FormHelperText, Hidden } from '@mui/material';
36
36
  import {
37
37
  DatePicker,
38
38
  LocalizationProvider
39
- } from '@mui/lab';
40
- import AdapterDayjs from '@mui/lab/AdapterDayjs';
41
- import { createOnChangeHandler, getData, useFocus } from '../util';
39
+ } from '@mui/x-date-pickers';
40
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
41
+ import {
42
+ createOnChangeHandler,
43
+ getData,
44
+ ResettableTextField,
45
+ useFocus,
46
+ } from '../util';
42
47
 
43
48
  export const MaterialDateControl = (props: ControlProps)=> {
44
49
  const [focused, onFocus, onBlur] = useFocus();
@@ -68,6 +73,8 @@ export const MaterialDateControl = (props: ControlProps)=> {
68
73
  const format = appliedUiSchemaOptions.dateFormat ?? 'YYYY-MM-DD';
69
74
  const saveFormat = appliedUiSchemaOptions.dateSaveFormat ?? 'YYYY-MM-DD';
70
75
 
76
+ const views = appliedUiSchemaOptions.views ?? ['year', 'day'];
77
+
71
78
  const firstFormHelperText = showDescription
72
79
  ? description
73
80
  : !isValid
@@ -80,30 +87,41 @@ export const MaterialDateControl = (props: ControlProps)=> {
80
87
  saveFormat
81
88
  ),[path, handleChange, saveFormat]);
82
89
 
90
+ const value = getData(data, saveFormat);
91
+ const valueInInputFormat = value ? value.format(format) : '';
92
+
83
93
  return (
84
94
  <Hidden xsUp={!visible}>
85
95
  <LocalizationProvider dateAdapter={AdapterDayjs}>
86
96
  <DatePicker
87
97
  label={label}
88
- value={getData(data, saveFormat)}
89
- clearable
98
+ value={value}
90
99
  onChange={onChange}
91
100
  inputFormat={format}
92
101
  disableMaskedInput
93
- views={appliedUiSchemaOptions.views}
102
+ views={views}
94
103
  disabled={!enabled}
95
- cancelText={appliedUiSchemaOptions.cancelLabel}
96
- clearText={appliedUiSchemaOptions.clearLabel}
97
- okText={appliedUiSchemaOptions.okLabel}
104
+ componentsProps={{
105
+ actionBar: {
106
+ actions: (variant) => (variant === 'desktop' ? [] : ['clear', 'cancel', 'accept'])
107
+ }
108
+ }}
98
109
  renderInput={params => (
99
- <TextField
110
+ <ResettableTextField
100
111
  {...params}
112
+ rawValue={data}
113
+ dayjsValueIsValid={value !== null}
114
+ valueInInputFormat={valueInInputFormat}
115
+ focused={focused}
101
116
  id={id + '-input'}
102
117
  required={required && !appliedUiSchemaOptions.hideRequiredAsterisk}
103
118
  autoFocus={appliedUiSchemaOptions.focus}
104
119
  error={!isValid}
105
120
  fullWidth={!appliedUiSchemaOptions.trim}
106
- inputProps={{ ...params.inputProps, type: 'text' }}
121
+ inputProps={{
122
+ ...params.inputProps,
123
+ type: 'text',
124
+ }}
107
125
  InputLabelProps={data ? { shrink: true } : undefined}
108
126
  onFocus={onFocus}
109
127
  onBlur={onBlur}
@@ -32,13 +32,18 @@ import {
32
32
  rankWith
33
33
  } from '@jsonforms/core';
34
34
  import { withJsonFormsControlProps } from '@jsonforms/react';
35
- import { FormHelperText, Hidden, TextField } from '@mui/material';
35
+ import { FormHelperText, Hidden } from '@mui/material';
36
36
  import {
37
37
  DateTimePicker,
38
38
  LocalizationProvider
39
- } from '@mui/lab';
40
- import AdapterDayjs from '@mui/lab/AdapterDayjs';
41
- import { createOnChangeHandler, getData, useFocus } from '../util';
39
+ } from '@mui/x-date-pickers';
40
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
41
+ import {
42
+ createOnChangeHandler,
43
+ getData,
44
+ ResettableTextField,
45
+ useFocus
46
+ } from '../util';
42
47
 
43
48
  export const MaterialDateTimeControl = (props: ControlProps) => {
44
49
  const [focused, onFocus, onBlur] = useFocus();
@@ -69,6 +74,8 @@ export const MaterialDateTimeControl = (props: ControlProps) => {
69
74
  const format = appliedUiSchemaOptions.dateTimeFormat ?? 'YYYY-MM-DD HH:mm';
70
75
  const saveFormat = appliedUiSchemaOptions.dateTimeSaveFormat ?? undefined;
71
76
 
77
+ const views = appliedUiSchemaOptions.views ?? ['year', 'day', 'hours', 'minutes'];
78
+
72
79
  const firstFormHelperText = showDescription
73
80
  ? description
74
81
  : !isValid
@@ -82,37 +89,49 @@ export const MaterialDateTimeControl = (props: ControlProps) => {
82
89
  saveFormat
83
90
  ),[path, handleChange, saveFormat]);
84
91
 
92
+ const value = getData(data, saveFormat);
93
+ const valueInInputFormat = value ? value.format(format) : '';
94
+
85
95
  return (
86
96
  <Hidden xsUp={!visible}>
87
97
  <LocalizationProvider dateAdapter={AdapterDayjs}>
88
98
  <DateTimePicker
89
99
  label={label}
90
- value={getData(data, saveFormat)}
91
- clearable
100
+ value={value}
92
101
  onChange={onChange}
93
102
  inputFormat={format}
94
103
  disableMaskedInput
95
104
  ampm={!!appliedUiSchemaOptions.ampm}
96
- views={appliedUiSchemaOptions.views}
105
+ views={views}
97
106
  disabled={!enabled}
98
- cancelText={appliedUiSchemaOptions.cancelLabel}
99
- clearText={appliedUiSchemaOptions.clearLabel}
100
- okText={appliedUiSchemaOptions.okLabel}
107
+ componentsProps={{
108
+ actionBar: {
109
+ actions: (variant) => (variant === 'desktop' ? [] : ['clear', 'cancel', 'accept'])
110
+ }
111
+ }}
101
112
  renderInput={params => (
102
- <TextField
113
+ <ResettableTextField
103
114
  {...params}
115
+ rawValue={data}
116
+ dayjsValueIsValid={value !== null}
117
+ valueInInputFormat={valueInInputFormat}
118
+ focused={focused}
104
119
  id={id + '-input'}
105
120
  required={required && !appliedUiSchemaOptions.hideRequiredAsterisk}
106
121
  autoFocus={appliedUiSchemaOptions.focus}
107
122
  error={!isValid}
108
123
  fullWidth={!appliedUiSchemaOptions.trim}
109
- inputProps={{ ...params.inputProps, type: 'text' }}
124
+ inputProps={{
125
+ ...params.inputProps,
126
+ type: 'text',
127
+ }}
110
128
  InputLabelProps={data ? { shrink: true } : undefined}
111
129
  onFocus={onFocus}
112
130
  onBlur={onBlur}
113
131
  variant={'standard'}
114
132
  />
115
- )}
133
+ )
134
+ }
116
135
  />
117
136
  <FormHelperText error={!isValid && !showDescription}>
118
137
  {firstFormHelperText}
@@ -30,19 +30,25 @@ import {
30
30
  RankedTester,
31
31
  rankWith,
32
32
  } from '@jsonforms/core';
33
- import { withJsonFormsEnumProps } from '@jsonforms/react';
33
+ import { TranslateProps, withJsonFormsEnumProps, withTranslateProps } from '@jsonforms/react';
34
34
  import { MuiSelect } from '../mui-controls/MuiSelect';
35
35
  import merge from 'lodash/merge';
36
36
  import { MaterialInputControl } from './MaterialInputControl';
37
37
  import { MuiAutocomplete, WithOptionLabel } from '../mui-controls/MuiAutocomplete';
38
38
 
39
- export const MaterialEnumControl = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel) => {
40
- const {config, uischema} = props;
39
+ export const MaterialEnumControl = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel & TranslateProps) => {
40
+ const {config, uischema, errors} = props;
41
41
  const appliedUiSchemaOptions = merge({}, config, uischema.options);
42
+ const isValid = errors.length === 0;
42
43
  return (
44
+ appliedUiSchemaOptions.autocomplete === false ?
43
45
  <MaterialInputControl
44
46
  {...props}
45
- input={appliedUiSchemaOptions.autocomplete === false ? MuiSelect : MuiAutocomplete}
47
+ input={MuiSelect}
48
+ />:
49
+ <MuiAutocomplete
50
+ {...props}
51
+ isValid={isValid}
46
52
  />
47
53
  );
48
54
  };
@@ -52,4 +58,5 @@ export const materialEnumControlTester: RankedTester = rankWith(
52
58
  isEnumControl
53
59
  );
54
60
 
55
- export default withJsonFormsEnumProps(MaterialEnumControl);
61
+ // HOC order can be reversed with https://github.com/eclipsesource/jsonforms/issues/1987
62
+ export default withJsonFormsEnumProps(withTranslateProps(React.memo(MaterialEnumControl)), false);
@@ -30,19 +30,26 @@ import {
30
30
  RankedTester,
31
31
  rankWith,
32
32
  } from '@jsonforms/core';
33
- import { withJsonFormsOneOfEnumProps } from '@jsonforms/react';
33
+ import { TranslateProps, withJsonFormsOneOfEnumProps, withTranslateProps } from '@jsonforms/react';
34
34
  import { MuiAutocomplete, WithOptionLabel } from '../mui-controls/MuiAutocomplete';
35
35
  import { MuiSelect } from '../mui-controls/MuiSelect';
36
36
  import { MaterialInputControl } from '../controls/MaterialInputControl';
37
37
  import merge from 'lodash/merge';
38
38
 
39
- export const MaterialOneOfEnumControl = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel) => {
40
- const {config, uischema} = props;
39
+ export const MaterialOneOfEnumControl = (props: ControlProps & OwnPropsOfEnum & WithOptionLabel & TranslateProps) => {
40
+ const {config, uischema, errors} = props;
41
41
  const appliedUiSchemaOptions = merge({}, config, uischema.options);
42
+ const isValid = errors.length === 0;
43
+
42
44
  return (
45
+ appliedUiSchemaOptions.autocomplete === false ?
43
46
  <MaterialInputControl
44
47
  {...props}
45
- input={appliedUiSchemaOptions.autocomplete === false ? MuiSelect : MuiAutocomplete}
48
+ input={MuiSelect}
49
+ />:
50
+ <MuiAutocomplete
51
+ {...props}
52
+ isValid={isValid}
46
53
  />
47
54
  );
48
55
  };
@@ -52,4 +59,5 @@ export const materialOneOfEnumControlTester: RankedTester = rankWith(
52
59
  isOneOfEnumControl
53
60
  );
54
61
 
55
- export default withJsonFormsOneOfEnumProps(MaterialOneOfEnumControl);
62
+ // HOC order can be reversed with https://github.com/eclipsesource/jsonforms/issues/1987
63
+ export default withJsonFormsOneOfEnumProps(withTranslateProps(React.memo(MaterialOneOfEnumControl)), false);
@@ -90,7 +90,7 @@ export const MaterialRadioGroup = (props: ControlProps & OwnPropsOfEnum) => {
90
90
  </FormLabel>
91
91
 
92
92
  <RadioGroup
93
- value={props.data}
93
+ value={props.data ?? ''}
94
94
  onChange={onChange}
95
95
  row={true}
96
96
  >
@@ -32,13 +32,18 @@ import {
32
32
  rankWith
33
33
  } from '@jsonforms/core';
34
34
  import { withJsonFormsControlProps } from '@jsonforms/react';
35
- import { FormHelperText, Hidden, TextField } from '@mui/material';
35
+ import { FormHelperText, Hidden } from '@mui/material';
36
36
  import {
37
37
  TimePicker,
38
38
  LocalizationProvider
39
- } from '@mui/lab';
40
- import AdapterDayjs from '@mui/lab/AdapterDayjs';
41
- import { createOnChangeHandler, getData, useFocus } from '../util';
39
+ } from '@mui/x-date-pickers';
40
+ import { AdapterDayjs } from '@mui/x-date-pickers/AdapterDayjs';
41
+ import {
42
+ createOnChangeHandler,
43
+ getData,
44
+ ResettableTextField,
45
+ useFocus
46
+ } from '../util';
42
47
 
43
48
  export const MaterialTimeControl = (props: ControlProps) => {
44
49
  const [focused, onFocus, onBlur] = useFocus();
@@ -67,7 +72,9 @@ export const MaterialTimeControl = (props: ControlProps) => {
67
72
  );
68
73
 
69
74
  const format = appliedUiSchemaOptions.timeFormat ?? 'HH:mm';
70
- const saveFormat = appliedUiSchemaOptions.timeSaveFormat ?? 'HH:mm:ss';
75
+ const saveFormat = appliedUiSchemaOptions.timeSaveFormat ?? 'HH:mm:ss';
76
+
77
+ const views = appliedUiSchemaOptions.views ?? ['hours', 'minutes'];
71
78
 
72
79
  const firstFormHelperText = showDescription
73
80
  ? description
@@ -82,31 +89,42 @@ export const MaterialTimeControl = (props: ControlProps) => {
82
89
  saveFormat
83
90
  ),[path, handleChange, saveFormat]);
84
91
 
92
+ const value = getData(data, saveFormat);
93
+ const valueInInputFormat = value ? value.format(format) : '';
94
+
85
95
  return (
86
96
  <Hidden xsUp={!visible}>
87
97
  <LocalizationProvider dateAdapter={AdapterDayjs}>
88
98
  <TimePicker
89
99
  label={label}
90
- value={getData(data, saveFormat)}
91
- clearable
100
+ value={value}
92
101
  onChange={onChange}
93
102
  inputFormat={format}
94
103
  disableMaskedInput
95
104
  ampm={!!appliedUiSchemaOptions.ampm}
96
- views={appliedUiSchemaOptions.views}
105
+ views={views}
97
106
  disabled={!enabled}
98
- cancelText={appliedUiSchemaOptions.cancelLabel}
99
- clearText={appliedUiSchemaOptions.clearLabel}
100
- okText={appliedUiSchemaOptions.okLabel}
107
+ componentsProps={{
108
+ actionBar: {
109
+ actions: (variant) => (variant === 'desktop' ? [] : ['clear', 'cancel', 'accept'])
110
+ }
111
+ }}
101
112
  renderInput={params => (
102
- <TextField
113
+ <ResettableTextField
103
114
  {...params}
115
+ rawValue={data}
116
+ dayjsValueIsValid={value !== null}
117
+ valueInInputFormat={valueInInputFormat}
118
+ focused={focused}
104
119
  id={id + '-input'}
105
120
  required={required && !appliedUiSchemaOptions.hideRequiredAsterisk}
106
121
  autoFocus={appliedUiSchemaOptions.focus}
107
122
  error={!isValid}
108
123
  fullWidth={!appliedUiSchemaOptions.trim}
109
- inputProps={{ ...params.inputProps, type: 'text' }}
124
+ inputProps={{
125
+ ...params.inputProps,
126
+ type: 'text'
127
+ }}
110
128
  InputLabelProps={data ? { shrink: true } : undefined}
111
129
  onFocus={onFocus}
112
130
  onBlur={onBlur}