Skip to content

Commit fc2d67f

Browse files
authored
Rework React Material pickers
Reworks date, time and date-time support in the React Material renderer set. The controls now support many customization options and can be invoked separately via the ui schema. We now use the much smaller 'dayjs' library (compared to 'moment') for Javascript date support. It can be configured globally and is therefore easily customizable on client side. The date, time and date-time controls now use a similar layout structure as normal controls, leading to a unified layout. Also streamlines the label prop which was only supporting string for a long time now. Additionally the unnecessary uuid dependency is removed from React Material.
1 parent d6edf4b commit fc2d67f

29 files changed

+882
-198
lines changed

package-lock.json

Lines changed: 13 additions & 18 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/angular/src/abstract-control.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import {
2626
Actions,
2727
computeLabel,
2828
ControlElement,
29-
isPlainLabel,
3029
JsonFormsState,
3130
JsonSchema,
3231
OwnPropsOfControl,
@@ -110,7 +109,7 @@ export abstract class JsonFormsAbstractControl<
110109
config
111110
} = props;
112111
this.label = computeLabel(
113-
isPlainLabel(label) ? label : label.default,
112+
label,
114113
required,
115114
config ? config.hideRequiredAsterisk : false
116115
);

packages/core/src/testers/testers.ts

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -284,13 +284,6 @@ export const isOneOfControl = and(
284284
schemaMatches(schema => schema.hasOwnProperty('oneOf'))
285285
);
286286

287-
/**
288-
* Tests whether the given UI schema is of type Control and if the schema
289-
* has a 'date' format.
290-
* @type {Tester}
291-
*/
292-
export const isDateControl = and(uiTypeIs('Control'), formatIs('date'));
293-
294287
/**
295288
* Tests whether the given UI schema is of type Control and if the schema
296289
* has an enum.
@@ -352,20 +345,33 @@ export const isMultiLineControl = and(
352345
);
353346

354347
/**
355-
* Tests whether the given UI schema is of type Control and if the schema
356-
* has a 'time' format.
348+
* Tests whether the given UI schema is of type Control and whether the schema
349+
* or uischema options has a 'date' format.
357350
* @type {Tester}
358351
*/
359-
export const isTimeControl = and(uiTypeIs('Control'), formatIs('time'));
352+
export const isDateControl = and(
353+
uiTypeIs('Control'),
354+
or(formatIs('date'), optionIs('format', 'date'))
355+
);
360356

361357
/**
362-
* Tests whether the given UI schema is of type Control and if the schema
363-
* has a 'date-time' format.
358+
* Tests whether the given UI schema is of type Control and whether the schema
359+
* or the uischema options has a 'time' format.
360+
* @type {Tester}
361+
*/
362+
export const isTimeControl = and(
363+
uiTypeIs('Control'),
364+
or(formatIs('time'), optionIs('format', 'time'))
365+
);
366+
367+
/**
368+
* Tests whether the given UI schema is of type Control and whether the schema
369+
* or the uischema options has a 'date-time' format.
364370
* @type {Tester}
365371
*/
366372
export const isDateTimeControl = and(
367373
uiTypeIs('Control'),
368-
formatIs('date-time')
374+
or(formatIs('date-time'), optionIs('format', 'date-time'))
369375
);
370376

371377
/**

packages/core/src/util/renderer.ts

Lines changed: 1 addition & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,6 @@ import { JsonFormsState } from '../store';
5757

5858
export { JsonFormsRendererRegistryEntry, JsonFormsCellRendererRegistryEntry };
5959

60-
export interface Labels {
61-
default: string;
62-
[additionalLabels: string]: string;
63-
}
64-
65-
export const isPlainLabel = (label: string | Labels): label is string => {
66-
return typeof label === 'string';
67-
};
68-
6960
const isRequired = (
7061
schema: JsonSchema,
7162
schemaPath: string,
@@ -317,7 +308,7 @@ export interface StatePropsOfControl extends StatePropsOfScopedRenderer {
317308
/**
318309
* The label for the rendered element.
319310
*/
320-
label: string | Labels;
311+
label: string;
321312

322313
/**
323314
* Description of input cell

packages/example/src/index.tsx

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,11 @@ import { getExamples } from '@jsonforms/examples';
4141
import { AdditionalStoreParams, exampleReducer } from './reduxUtil';
4242
import { enhanceExample, ReactExampleDescription } from './util';
4343

44+
import dayjs from 'dayjs';
45+
import 'dayjs/locale/de';
46+
import 'dayjs/locale/en';
47+
dayjs.locale('de');
48+
4449
const setupStore = (
4550
exampleData: ReactExampleDescription[],
4651
cells: JsonFormsCellRendererRegistryEntry[],

packages/examples/src/dates.ts

Lines changed: 81 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -23,22 +23,46 @@
2323
THE SOFTWARE.
2424
*/
2525
import { registerExamples } from './register';
26-
import moment from 'moment';
2726

2827
const schema = {
2928
type: 'object',
3029
properties: {
31-
date: {
32-
type: 'string',
33-
format: 'date'
34-
},
35-
time: {
36-
type: 'string',
37-
format: 'time'
30+
schemaBased: {
31+
type: 'object',
32+
properties: {
33+
date: {
34+
type: 'string',
35+
format: 'date',
36+
description: 'schema-based date picker'
37+
},
38+
time: {
39+
type: 'string',
40+
format: 'time',
41+
description: 'schema-based time picker'
42+
},
43+
datetime: {
44+
type: 'string',
45+
format: 'date-time',
46+
description: 'schema-based datetime picker'
47+
}
48+
}
3849
},
39-
datetime: {
40-
type: 'string',
41-
format: 'date-time'
50+
uiSchemaBased: {
51+
type: 'object',
52+
properties: {
53+
date: {
54+
type: 'string',
55+
description: 'does not allow to select days'
56+
},
57+
time: {
58+
type: 'string',
59+
description: '24 hour format'
60+
},
61+
datetime: {
62+
type: 'string',
63+
description: 'uischema-based datetime picker'
64+
}
65+
}
4266
}
4367
}
4468
};
@@ -50,11 +74,15 @@ const uischema = {
5074
elements: [
5175
{
5276
type: 'Control',
53-
scope: '#/properties/date'
77+
scope: '#/properties/schemaBased/properties/date'
78+
},
79+
{
80+
type: 'Control',
81+
scope: '#/properties/schemaBased/properties/time'
5482
},
5583
{
5684
type: 'Control',
57-
scope: '#/properties/time'
85+
scope: '#/properties/schemaBased/properties/datetime'
5886
}
5987
]
6088
},
@@ -63,16 +91,52 @@ const uischema = {
6391
elements: [
6492
{
6593
type: 'Control',
66-
scope: '#/properties/datetime'
94+
scope: '#/properties/uiSchemaBased/properties/date',
95+
label: 'Year Month Picker',
96+
options: {
97+
format: 'date',
98+
clearLabel: 'Clear it!',
99+
cancelLabel: 'Abort',
100+
okLabel: 'Do it',
101+
views: ['year', 'month'],
102+
dateFormat: 'YYYY.MM',
103+
dateSaveFormat: 'YYYY-MM'
104+
},
105+
},
106+
{
107+
type: 'Control',
108+
scope: '#/properties/uiSchemaBased/properties/time',
109+
options: {
110+
format: 'time',
111+
ampm: true
112+
}
113+
},
114+
{
115+
type: 'Control',
116+
scope: '#/properties/uiSchemaBased/properties/datetime',
117+
options: {
118+
format: 'date-time',
119+
dateTimeFormat: 'DD-MM-YY hh:mm:a',
120+
dateTimeSaveFormat: 'YYYY/MM/DD h:mm a',
121+
ampm: true
122+
}
67123
}
68124
]
69125
}
70126
]
71127
};
128+
72129
const data = {
73-
date: new Date().toISOString().substr(0, 10),
74-
time: '13:37',
75-
datetime: moment().format()
130+
schemaBased: {
131+
date: new Date().toISOString().substr(0, 10),
132+
time: '13:37',
133+
datetime: new Date().toISOString()
134+
},
135+
uiSchemaBased: {
136+
date: new Date().toISOString().substr(0, 10),
137+
time: '13:37',
138+
datetime: '1999/12/11 10:05 am'
139+
}
76140
};
77141
registerExamples([
78142
{

packages/material/package.json

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -65,17 +65,15 @@
6565
]
6666
},
6767
"dependencies": {
68-
"@date-io/moment": "1.3.11",
69-
"@material-ui/pickers": "^3.2.8",
70-
"@types/uuid": "^3.4.6",
71-
"moment": "^2.24.0",
72-
"uuid": "^3.3.3"
68+
"@date-io/dayjs": "1.3.13",
69+
"dayjs": "1.10.6"
7370
},
7471
"peerDependencies": {
7572
"@jsonforms/core": "^3.0.0-alpha.0",
7673
"@jsonforms/react": "^3.0.0-alpha.0",
7774
"@material-ui/core": "^4.7.0",
78-
"@material-ui/icons": "^4.5.1"
75+
"@material-ui/icons": "^4.5.1",
76+
"@material-ui/pickers": "^3.3.10"
7977
},
8078
"optionalPeerDependencies": {
8179
"@material-ui/lab": "^4.0.0-alpha.56"
@@ -85,6 +83,7 @@
8583
"@jsonforms/react": "^3.0.0-alpha.0",
8684
"@material-ui/core": "^4.7.0",
8785
"@material-ui/icons": "^4.5.1",
86+
"@material-ui/pickers": "^3.2.8",
8887
"@material-ui/lab": "^4.0.0-alpha.56",
8988
"@types/enzyme": "^3.10.3",
9089
"@types/enzyme-adapter-react-16": "^1.0.5",

packages/material/src/additional/MaterialListWithDetailRenderer.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,6 @@ import {
3030
createDefaultValue,
3131
findUISchema,
3232
isObjectArray,
33-
isPlainLabel,
3433
RankedTester,
3534
rankWith,
3635
uiTypeIs
@@ -101,7 +100,7 @@ export const MaterialListWithDetailRenderer = ({
101100
<Hidden xsUp={!visible}>
102101
<ArrayLayoutToolbar
103102
label={computeLabel(
104-
isPlainLabel(label) ? label : label.default,
103+
label,
105104
required,
106105
appliedUiSchemaOptions.hideRequiredAsterisk
107106
)}

packages/material/src/complex/MaterialObjectRenderer.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
findUISchema,
2828
GroupLayout,
2929
isObjectControl,
30-
isPlainLabel,
3130
RankedTester,
3231
rankWith,
3332
StatePropsOfControlWithDetail
@@ -64,7 +63,7 @@ const MaterialObjectRenderer = ({
6463
if (isEmpty(path)) {
6564
detailUiSchema.type = 'VerticalLayout';
6665
} else {
67-
(detailUiSchema as GroupLayout).label = isPlainLabel(label) ? label : label.default;
66+
(detailUiSchema as GroupLayout).label = label;
6867
}
6968
return (
7069
<Hidden xsUp={!visible}>

packages/material/src/complex/TableToolbar.tsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,6 @@ import {
2727
ControlElement,
2828
createDefaultValue,
2929
JsonSchema,
30-
Labels
3130
} from '@jsonforms/core';
3231
import IconButton from '@material-ui/core/IconButton';
3332
import { Grid, Hidden, Typography } from '@material-ui/core';
@@ -40,7 +39,7 @@ import NoBorderTableCell from './NoBorderTableCell';
4039
export interface MaterialTableToolbarProps {
4140
numColumns: number;
4241
errors: string;
43-
label: string | Labels;
42+
label: string;
4443
path: string;
4544
uischema: ControlElement;
4645
schema: JsonSchema;

0 commit comments

Comments
 (0)