Skip to content

Commit 83da998

Browse files
authored
Use React Material UI's builtin required
Material UI supports handing over a 'required' prop to their components. We now use this prop instead of appending an asterisk manually to the control labels in the React Material renderer set . Using this approach the asterisk is rendered in a consistent and themeable way. Closes #1695 Signed-off-by: Lukas Boll <[email protected]>
1 parent 5da2f0d commit 83da998

File tree

6 files changed

+41
-27
lines changed

6 files changed

+41
-27
lines changed

packages/core/src/util/renderer.ts

+15
Original file line numberDiff line numberDiff line change
@@ -88,6 +88,7 @@ const isRequired = (
8888
*
8989
* @param {string} label the label string
9090
* @param {boolean} required whether the label belongs to a control which is required
91+
* @param {boolean} hideRequiredAsterisk applied UI Schema option
9192
* @returns {string} the label string
9293
*/
9394
export const computeLabel = (
@@ -98,6 +99,20 @@ export const computeLabel = (
9899
return required && !hideRequiredAsterisk ? label + '*' : label;
99100
};
100101

102+
/**
103+
* Indicates whether to mark a field as required.
104+
*
105+
* @param {boolean} required whether the label belongs to a control which is required
106+
* @param {boolean} hideRequiredAsterisk applied UI Schema option
107+
* @returns {boolean} should the field be marked as required
108+
*/
109+
export const showAsRequired = (
110+
required: boolean,
111+
hideRequiredAsterisk: boolean
112+
): boolean => {
113+
return required && !hideRequiredAsterisk;
114+
};
115+
101116
/**
102117
* Create a default value based on the given scheam.
103118
* @param schema the schema for which to create a default value.

packages/material/src/controls/MaterialInputControl.tsx

+4-6
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
*/
2525
import React from 'react';
2626
import {
27-
computeLabel,
27+
showAsRequired,
2828
ControlProps,
2929
ControlState,
3030
isDescriptionHidden,
@@ -84,12 +84,10 @@ export abstract class MaterialInputControl extends Control<
8484
<InputLabel
8585
htmlFor={id + '-input'}
8686
error={!isValid}
87+
required={showAsRequired(required,
88+
appliedUiSchemaOptions.hideRequiredAsterisk)}
8789
>
88-
{computeLabel(
89-
label,
90-
required,
91-
appliedUiSchemaOptions.hideRequiredAsterisk
92-
)}
90+
{label}
9391
</InputLabel>
9492
<InnerComponent
9593
{...this.props}

packages/material/src/controls/MaterialNativeControl.tsx

+4-6
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
*/
2525
import React from 'react';
2626
import {
27-
computeLabel,
2827
ControlProps,
2928
ControlState,
29+
showAsRequired,
3030
isDateControl,
3131
isDescriptionHidden,
3232
isTimeControl,
@@ -73,12 +73,10 @@ export class MaterialNativeControl extends Control<ControlProps, ControlState> {
7373
return (
7474
<Hidden xsUp={!visible}>
7575
<TextField
76+
required={showAsRequired(required,
77+
appliedUiSchemaOptions.hideRequiredAsterisk)}
7678
id={id + '-input'}
77-
label={computeLabel(
78-
label,
79-
required,
80-
appliedUiSchemaOptions.hideRequiredAsterisk
81-
)}
79+
label={label}
8280
type={fieldType}
8381
error={!isValid}
8482
disabled={!enabled}

packages/material/src/controls/MaterialRadioGroup.tsx

+4-6
Original file line numberDiff line numberDiff line change
@@ -25,9 +25,9 @@
2525
import merge from 'lodash/merge';
2626
import React from 'react';
2727
import {
28-
computeLabel,
2928
ControlProps,
3029
ControlState,
30+
showAsRequired,
3131
isDescriptionHidden,
3232
OwnPropsOfEnum
3333
} from '@jsonforms/core';
@@ -81,12 +81,10 @@ export class MaterialRadioGroup extends Control<
8181
htmlFor={id}
8282
error={!isValid}
8383
component={'legend' as 'label'}
84+
required={showAsRequired(required,
85+
appliedUiSchemaOptions.hideRequiredAsterisk)}
8486
>
85-
{computeLabel(
86-
label,
87-
required,
88-
appliedUiSchemaOptions.hideRequiredAsterisk
89-
)}
87+
{label}
9088
</FormLabel>
9189

9290
<RadioGroup

packages/material/src/controls/MaterialSliderControl.tsx

+13-8
Original file line numberDiff line numberDiff line change
@@ -24,9 +24,9 @@
2424
*/
2525
import React from 'react';
2626
import {
27-
computeLabel,
2827
ControlProps,
2928
ControlState,
29+
showAsRequired,
3030
isDescriptionHidden,
3131
isRangeControl,
3232
RankedTester,
@@ -37,6 +37,7 @@ import { Control, withJsonFormsControlProps } from '@jsonforms/react';
3737
import {
3838
FormControl,
3939
FormHelperText,
40+
FormLabel,
4041
Hidden,
4142
Slider,
4243
Typography
@@ -95,13 +96,17 @@ export class MaterialSliderControl extends Control<ControlProps, ControlState> {
9596
onBlur={this.onBlur}
9697
id={id}
9798
>
98-
<Typography id={id + '-typo'} style={labelStyle} variant='caption'>
99-
{computeLabel(
100-
label,
101-
required,
102-
appliedUiSchemaOptions.hideRequiredAsterisk
103-
)}
104-
</Typography>
99+
<FormLabel
100+
htmlFor={id}
101+
error={!isValid}
102+
component={'legend' as 'label'}
103+
required={showAsRequired(required,
104+
appliedUiSchemaOptions.hideRequiredAsterisk)}
105+
>
106+
<Typography id={id + '-typo'} style={labelStyle} variant='caption'>
107+
{label}
108+
</Typography>
109+
</FormLabel>
105110
<div style={rangeContainerStyle}>
106111
<Typography style={rangeItemStyle} variant='caption' align='left'>
107112
{schema.minimum}

packages/material/test/renderers/MaterialInputControl.test.tsx

+1-1
Original file line numberDiff line numberDiff line change
@@ -283,7 +283,7 @@ describe('Material input control', () => {
283283
</JsonFormsStateProvider>
284284
);
285285
const label = wrapper.find('label').first();
286-
expect(label.text()).toBe('Date Cell*');
286+
expect(label.text()).toBe('Date Cell*');
287287
});
288288

289289
it('should not display a marker for a non-required prop', () => {

0 commit comments

Comments
 (0)