@jsonforms/material-renderers 3.0.0-beta.3 → 3.0.0-rc.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 (68) hide show
  1. package/README.md +71 -13
  2. package/docs/assets/js/search.json +1 -1
  3. package/docs/globals.html +174 -80
  4. package/docs/index.html +85 -13
  5. package/docs/interfaces/categorizationstate.html +1 -1
  6. package/docs/interfaces/categorizationstepperstate.html +1 -1
  7. package/docs/interfaces/inputref.html +168 -0
  8. package/docs/interfaces/materialcategorizationlayoutrendererprops.html +49 -4
  9. package/docs/interfaces/materialcategorizationstepperlayoutrendererprops.html +46 -1
  10. package/docs/interfaces/materiallabelablelayoutrendererprops.html +328 -0
  11. package/docs/interfaces/materiallayoutrendererprops.html +5 -0
  12. package/docs/interfaces/withoptionlabel.html +3 -3
  13. package/lib/additional/MaterialLabelRenderer.d.ts +3 -3
  14. package/lib/cells/MaterialEnumCell.d.ts +2 -1
  15. package/lib/cells/MaterialOneOfEnumCell.d.ts +2 -1
  16. package/lib/controls/MaterialEnumControl.d.ts +2 -1
  17. package/lib/controls/MaterialOneOfEnumControl.d.ts +2 -1
  18. package/lib/controls/index.d.ts +2 -2
  19. package/lib/jsonforms-react-material.cjs.js +125 -61
  20. package/lib/jsonforms-react-material.cjs.js.map +1 -1
  21. package/lib/jsonforms-react-material.esm.js +124 -58
  22. package/lib/jsonforms-react-material.esm.js.map +1 -1
  23. package/lib/layouts/MaterialArrayLayoutRenderer.d.ts +1 -1
  24. package/lib/layouts/MaterialCategorizationLayout.d.ts +4 -3
  25. package/lib/layouts/MaterialCategorizationStepperLayout.d.ts +4 -3
  26. package/lib/layouts/MaterialGroupLayout.d.ts +2 -2
  27. package/lib/layouts/MaterialHorizontalLayout.d.ts +1 -1
  28. package/lib/layouts/MaterialVerticalLayout.d.ts +1 -1
  29. package/lib/mui-controls/MuiAutocomplete.d.ts +2 -2
  30. package/lib/mui-controls/MuiSelect.d.ts +2 -1
  31. package/lib/util/datejs.d.ts +17 -1
  32. package/lib/util/i18nDefaults.d.ts +3 -0
  33. package/lib/util/index.d.ts +1 -0
  34. package/lib/util/layout.d.ts +3 -0
  35. package/package.json +7 -7
  36. package/src/additional/MaterialLabelRenderer.tsx +5 -7
  37. package/src/cells/MaterialEnumCell.tsx +4 -3
  38. package/src/cells/MaterialOneOfEnumCell.tsx +3 -3
  39. package/src/complex/MaterialTableControl.tsx +1 -1
  40. package/src/controls/MaterialDateControl.tsx +23 -6
  41. package/src/controls/MaterialDateTimeControl.tsx +23 -6
  42. package/src/controls/MaterialEnumControl.tsx +12 -5
  43. package/src/controls/MaterialOneOfEnumControl.tsx +13 -5
  44. package/src/controls/MaterialTimeControl.tsx +24 -7
  45. package/src/layouts/ExpandPanelRenderer.tsx +2 -1
  46. package/src/layouts/MaterialArrayLayoutRenderer.tsx +3 -25
  47. package/src/layouts/MaterialCategorizationLayout.tsx +18 -9
  48. package/src/layouts/MaterialCategorizationStepperLayout.tsx +19 -12
  49. package/src/layouts/MaterialGroupLayout.tsx +6 -5
  50. package/src/mui-controls/MuiAutocomplete.tsx +81 -37
  51. package/src/mui-controls/MuiInputText.tsx +4 -1
  52. package/src/mui-controls/MuiSelect.tsx +10 -5
  53. package/src/util/datejs.tsx +73 -0
  54. package/src/util/i18nDefaults.ts +3 -0
  55. package/src/util/index.ts +1 -0
  56. package/src/util/layout.tsx +4 -0
  57. package/stats.html +1 -1
  58. package/test/renderers/MaterialArrayLayout.test.tsx +36 -5
  59. package/test/renderers/MaterialCategorizationLayout.test.tsx +17 -7
  60. package/test/renderers/MaterialCategorizationStepperLayout.test.tsx +21 -11
  61. package/test/renderers/MaterialDateControl.test.tsx +27 -0
  62. package/test/renderers/MaterialDateTimeControl.test.tsx +27 -0
  63. package/test/renderers/MaterialGroupLayout.test.tsx +4 -1
  64. package/test/renderers/MaterialInputControl.test.tsx +4 -0
  65. package/test/renderers/MaterialLabelRenderer.test.tsx +2 -1
  66. package/test/renderers/MaterialTimeControl.test.tsx +27 -0
  67. package/test/renderers/util.ts +5 -0
  68. package/src/util/datejs.ts +0 -32
@@ -1,6 +1,6 @@
1
1
  import React from 'react';
2
2
  import { ArrayLayoutProps, RankedTester } from '@jsonforms/core';
3
- export declare const MaterialArrayLayoutRenderer: ({ visible, enabled, id, uischema, schema, label, rootSchema, renderers, cells, data, path, errors, uischemas, addItem }: ArrayLayoutProps) => JSX.Element;
3
+ export declare const MaterialArrayLayoutRenderer: ({ visible, addItem, ...props }: ArrayLayoutProps) => JSX.Element;
4
4
  export declare const materialArrayLayoutTester: RankedTester;
5
5
  declare const _default: React.ComponentType<import("@jsonforms/core").OwnPropsOfControl>;
6
6
  export default _default;
@@ -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.3",
3
+ "version": "3.0.0-rc.0",
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",
@@ -74,10 +74,10 @@
74
74
  "dayjs": "1.10.6"
75
75
  },
76
76
  "peerDependencies": {
77
- "@emotion/react": "^11.5.0",
77
+ "@emotion/react": "^11.4.1",
78
78
  "@emotion/styled": "^11.3.0",
79
- "@jsonforms/core": "3.0.0-beta.3",
80
- "@jsonforms/react": "3.0.0-beta.3",
79
+ "@jsonforms/core": "3.0.0-rc.0",
80
+ "@jsonforms/react": "3.0.0-rc.0",
81
81
  "@mui/icons-material": "^5.0.0",
82
82
  "@mui/lab": "^5.0.0-alpha.54",
83
83
  "@mui/material": "^5.0.0"
@@ -85,8 +85,8 @@
85
85
  "devDependencies": {
86
86
  "@emotion/react": "^11.5.0",
87
87
  "@emotion/styled": "^11.3.0",
88
- "@jsonforms/core": "^3.0.0-beta.3",
89
- "@jsonforms/react": "^3.0.0-beta.3",
88
+ "@jsonforms/core": "^3.0.0-rc.0",
89
+ "@jsonforms/react": "^3.0.0-rc.0",
90
90
  "@mui/icons-material": "^5.2.0",
91
91
  "@mui/lab": "^5.0.0-alpha.58",
92
92
  "@mui/material": "^5.2.2",
@@ -114,5 +114,5 @@
114
114
  "webpack-cli": "^3.2.1",
115
115
  "webpack-dev-server": "^3.9.0"
116
116
  },
117
- "gitHead": "78ef46d070f9c5ac1db1f04772db1293858ce2a4"
117
+ "gitHead": "5ef030e8b3f91bcdc3e6b8d232a0b191bf1195ce"
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);
@@ -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);
@@ -370,7 +370,7 @@ const TableRows = ({
370
370
  moveDownCreator={moveDown}
371
371
  enableUp={index !== 0}
372
372
  enableDown={index !== data - 1}
373
- showSortButtons={appliedUiSchemaOptions.showSortButtons}
373
+ showSortButtons={appliedUiSchemaOptions.showSortButtons || appliedUiSchemaOptions.showArrayTableSortButtons}
374
374
  enabled={enabled}
375
375
  cells={cells}
376
376
  path={path}
@@ -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
39
  } from '@mui/lab';
40
40
  import AdapterDayjs from '@mui/lab/AdapterDayjs';
41
- import { createOnChangeHandler, getData, useFocus } from '../util';
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,40 @@ 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)}
98
+ value={value}
89
99
  clearable
90
100
  onChange={onChange}
91
101
  inputFormat={format}
92
102
  disableMaskedInput
93
- views={appliedUiSchemaOptions.views}
103
+ views={views}
94
104
  disabled={!enabled}
95
105
  cancelText={appliedUiSchemaOptions.cancelLabel}
96
106
  clearText={appliedUiSchemaOptions.clearLabel}
97
107
  okText={appliedUiSchemaOptions.okLabel}
98
108
  renderInput={params => (
99
- <TextField
109
+ <ResettableTextField
100
110
  {...params}
111
+ rawValue={data}
112
+ dayjsValueIsValid={value !== null}
113
+ valueInInputFormat={valueInInputFormat}
114
+ focused={focused}
101
115
  id={id + '-input'}
102
116
  required={required && !appliedUiSchemaOptions.hideRequiredAsterisk}
103
117
  autoFocus={appliedUiSchemaOptions.focus}
104
118
  error={!isValid}
105
119
  fullWidth={!appliedUiSchemaOptions.trim}
106
- inputProps={{ ...params.inputProps, type: 'text' }}
120
+ inputProps={{
121
+ ...params.inputProps,
122
+ type: 'text',
123
+ }}
107
124
  InputLabelProps={data ? { shrink: true } : undefined}
108
125
  onFocus={onFocus}
109
126
  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
39
  } from '@mui/lab';
40
40
  import AdapterDayjs from '@mui/lab/AdapterDayjs';
41
- import { createOnChangeHandler, getData, useFocus } from '../util';
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,31 +89,41 @@ 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)}
100
+ value={value}
91
101
  clearable
92
102
  onChange={onChange}
93
103
  inputFormat={format}
94
104
  disableMaskedInput
95
105
  ampm={!!appliedUiSchemaOptions.ampm}
96
- views={appliedUiSchemaOptions.views}
106
+ views={views}
97
107
  disabled={!enabled}
98
108
  cancelText={appliedUiSchemaOptions.cancelLabel}
99
109
  clearText={appliedUiSchemaOptions.clearLabel}
100
110
  okText={appliedUiSchemaOptions.okLabel}
101
111
  renderInput={params => (
102
- <TextField
112
+ <ResettableTextField
103
113
  {...params}
114
+ rawValue={data}
115
+ dayjsValueIsValid={value !== null}
116
+ valueInInputFormat={valueInInputFormat}
117
+ focused={focused}
104
118
  id={id + '-input'}
105
119
  required={required && !appliedUiSchemaOptions.hideRequiredAsterisk}
106
120
  autoFocus={appliedUiSchemaOptions.focus}
107
121
  error={!isValid}
108
122
  fullWidth={!appliedUiSchemaOptions.trim}
109
- inputProps={{ ...params.inputProps, type: 'text' }}
123
+ inputProps={{
124
+ ...params.inputProps,
125
+ type: 'text',
126
+ }}
110
127
  InputLabelProps={data ? { shrink: true } : undefined}
111
128
  onFocus={onFocus}
112
129
  onBlur={onBlur}
@@ -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);
@@ -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
39
  } from '@mui/lab';
40
40
  import AdapterDayjs from '@mui/lab/AdapterDayjs';
41
- import { createOnChangeHandler, getData, useFocus } from '../util';
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,41 @@ 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)}
100
+ value={value}
91
101
  clearable
92
102
  onChange={onChange}
93
103
  inputFormat={format}
94
104
  disableMaskedInput
95
105
  ampm={!!appliedUiSchemaOptions.ampm}
96
- views={appliedUiSchemaOptions.views}
106
+ views={views}
97
107
  disabled={!enabled}
98
108
  cancelText={appliedUiSchemaOptions.cancelLabel}
99
109
  clearText={appliedUiSchemaOptions.clearLabel}
100
110
  okText={appliedUiSchemaOptions.okLabel}
101
111
  renderInput={params => (
102
- <TextField
112
+ <ResettableTextField
103
113
  {...params}
114
+ rawValue={data}
115
+ dayjsValueIsValid={value !== null}
116
+ valueInInputFormat={valueInInputFormat}
117
+ focused={focused}
104
118
  id={id + '-input'}
105
119
  required={required && !appliedUiSchemaOptions.hideRequiredAsterisk}
106
120
  autoFocus={appliedUiSchemaOptions.focus}
107
121
  error={!isValid}
108
122
  fullWidth={!appliedUiSchemaOptions.trim}
109
- inputProps={{ ...params.inputProps, type: 'text' }}
123
+ inputProps={{
124
+ ...params.inputProps,
125
+ type: 'text'
126
+ }}
110
127
  InputLabelProps={data ? { shrink: true } : undefined}
111
128
  onFocus={onFocus}
112
129
  onBlur={onBlur}
@@ -119,6 +119,7 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
119
119
  );
120
120
 
121
121
  const appliedUiSchemaOptions = merge({}, config, uischema.options);
122
+ const showSortButtons = appliedUiSchemaOptions.showSortButtons || appliedUiSchemaOptions.showArrayLayoutSortButtons;
122
123
 
123
124
  return (
124
125
  <Accordion
@@ -147,7 +148,7 @@ const ExpandPanelRendererComponent = (props: ExpandPanelProps) => {
147
148
  justifyContent='center'
148
149
  alignItems='center'
149
150
  >
150
- {appliedUiSchemaOptions.showSortButtons ? (
151
+ {showSortButtons ? (
151
152
  <Fragment>
152
153
  <Grid item>
153
154
  <IconButton
@@ -36,19 +36,8 @@ import { withJsonFormsArrayLayoutProps } from '@jsonforms/react';
36
36
 
37
37
  export const MaterialArrayLayoutRenderer = ({
38
38
  visible,
39
- enabled,
40
- id,
41
- uischema,
42
- schema,
43
- label,
44
- rootSchema,
45
- renderers,
46
- cells,
47
- data,
48
- path,
49
- errors,
50
- uischemas,
51
- addItem
39
+ addItem,
40
+ ...props
52
41
  }: ArrayLayoutProps) => {
53
42
  const addItemCb = useCallback((p: string, value: any) => addItem(p, value), [
54
43
  addItem
@@ -56,20 +45,9 @@ export const MaterialArrayLayoutRenderer = ({
56
45
  return (
57
46
  <Hidden xsUp={!visible}>
58
47
  <MaterialArrayLayout
59
- label={label}
60
- uischema={uischema}
61
- schema={schema}
62
- id={id}
63
- rootSchema={rootSchema}
64
- errors={errors}
65
- enabled={enabled}
66
48
  visible={visible}
67
- data={data}
68
- path={path}
69
49
  addItem={addItemCb}
70
- renderers={renderers}
71
- cells={cells}
72
- uischemas={uischemas}
50
+ {...props}
73
51
  />
74
52
  </Hidden>
75
53
  );