Skip to content

Commit 103a1bf

Browse files
committed
feat: add readOnly mode to form fields
KDBEV-1485 this will be used instead of disabling fields when form is in view mode so that fields are still tabbable and content is not greyed out
1 parent 80ab0dd commit 103a1bf

28 files changed

Lines changed: 1617 additions & 1405 deletions

src/components/DropDownSelect/__snapshots__/index.stories.tsx.snap

Lines changed: 66 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,17 @@ exports[`Disabled snapshot 1`] = `
108108
tabindex="-1"
109109
value="apple"
110110
/>
111-
<span
112-
class="Mui-disabled MuiSelect-icon MuiSelect-iconStandard css-XXXX-MuiNativeSelect-root-MuiSelect-icon"
113-
/>
111+
<svg
112+
aria-hidden="true"
113+
class="Mui-disabled MuiSelect-icon MuiSelect-iconStandard MuiSvgIcon-fontSizeSmall MuiSvgIcon-root css-XXXX-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon"
114+
data-testid="ArrowDropDownIcon"
115+
focusable="false"
116+
viewBox="0 0 24 24"
117+
>
118+
<path
119+
d="m7 10 5 5 5-5z"
120+
/>
121+
</svg>
114122
</div>
115123
<p
116124
class="Mui-disabled MuiFormHelperText-filled MuiFormHelperText-root MuiFormHelperText-sizeMedium css-XXXX-MuiFormHelperText-root"
@@ -176,6 +184,61 @@ exports[`Empty snapshot 1`] = `
176184
</div>
177185
`;
178186

187+
exports[`ReadOnly snapshot 1`] = `
188+
<div>
189+
<div
190+
class="MuiFormControl-root css-XXXX-MuiFormControl-root option-select"
191+
>
192+
<label
193+
class="MuiFormLabel-colorPrimary MuiFormLabel-filled MuiFormLabel-root MuiInputLabel-animated MuiInputLabel-formControl MuiInputLabel-root MuiInputLabel-shrink MuiInputLabel-standard css-XXXX-MuiFormLabel-root-MuiInputLabel-root"
194+
data-shrink="true"
195+
for="option-select-"
196+
>
197+
Fruit
198+
</label>
199+
<div
200+
class="Mui-readOnly MuiInput-root MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-readOnly MuiInputBase-root MuiSelect-root css-XXXX-MuiInputBase-root-MuiInput-root"
201+
>
202+
<div
203+
aria-expanded="false"
204+
aria-haspopup="listbox"
205+
class="Mui-readOnly MuiInput-input MuiInputBase-input MuiInputBase-readOnly MuiSelect-select MuiSelect-standard css-XXXX-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiInput-input"
206+
role="combobox"
207+
tabindex="0"
208+
>
209+
<div
210+
class="MuiListItemText-root css-XXXX-MuiListItemText-root"
211+
>
212+
<span
213+
class="MuiListItemText-primary MuiTypography-body1 MuiTypography-root css-XXXX-MuiTypography-root"
214+
>
215+
apple
216+
</span>
217+
<p
218+
class="MuiListItemText-secondary MuiTypography-body2 MuiTypography-root css-XXXX-MuiTypography-root option-select__option-description"
219+
/>
220+
</div>
221+
</div>
222+
<input
223+
aria-hidden="true"
224+
aria-invalid="false"
225+
class="MuiSelect-nativeInput css-XXXX-MuiSelect-nativeInput"
226+
id="option-select-"
227+
name=""
228+
tabindex="-1"
229+
value="apple"
230+
/>
231+
<span
232+
class="MuiSelect-icon MuiSelect-iconStandard css-XXXX-MuiNativeSelect-root-MuiSelect-icon"
233+
/>
234+
</div>
235+
<p
236+
class="MuiFormHelperText-filled MuiFormHelperText-root MuiFormHelperText-sizeMedium css-XXXX-MuiFormHelperText-root"
237+
/>
238+
</div>
239+
</div>
240+
`;
241+
179242
exports[`WithCustomIcon snapshot 1`] = `
180243
<div>
181244
<div

src/components/DropDownSelect/index.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ export const Disabled = WithValue.extend({
3636
args: { disabled: true },
3737
});
3838

39+
export const ReadOnly = WithValue.extend({
40+
args: { readOnly: true },
41+
});
42+
3943
export const WithError = WithValue.extend({
4044
args: { error: true, helperText: 'bad value' },
4145
});

src/components/DropDownSelect/index.tsx

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ interface DropDownSelectProps {
8787
value?: string;
8888
/** Material UI Select variant (outlined, filled, standard) */
8989
variant?: React.ComponentProps<typeof FormControl>['variant'];
90+
readOnly?: boolean;
9091
}
9192

9293
/**
@@ -110,6 +111,7 @@ function DropDownSelect(props: DropDownSelectProps) {
110111
className = '',
111112
disabled = false,
112113
IconComponent = ArrowDropDownIcon,
114+
readOnly,
113115
} = props;
114116

115117
const optionsDisplay = options.map((option) => children(option, disabled));
@@ -140,12 +142,14 @@ function DropDownSelect(props: DropDownSelectProps) {
140142
{label}
141143
</InputLabel>
142144
<Select
143-
IconComponent={disabled
145+
disableUnderline={readOnly}
146+
IconComponent={readOnly
144147
? 'span'
145148
: IconComponent}
146149
input={<InputComponent id={`option-select-${name}`} name={name} />}
147150
inputProps={innerProps}
148-
onChange={onChange}
151+
onChange={!readOnly ? onChange : undefined}
152+
readOnly={readOnly}
149153
style={{
150154
fontSize: dense ? '0.8125rem' : '',
151155
}}

src/components/FormField/BooleanField.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,10 @@ export const Disabled = False.extend({
2626
args: { disabled: true },
2727
});
2828

29+
export const ReadOnly = False.extend({
30+
args: { readOnly: true },
31+
});
32+
2933
export const WithError = False.extend({
3034
args: { error: true, helperText: 'bad value' },
3135
});

src/components/FormField/BooleanField.tsx

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ interface BooleanFieldProps {
2424
required?: boolean;
2525
/** the current value */
2626
value?: string | boolean;
27+
readOnly?: boolean;
2728
}
2829

2930
/**
@@ -39,6 +40,7 @@ const BooleanField = (props: BooleanFieldProps) => {
3940
required = false,
4041
helperText = '',
4142
value: initialValue,
43+
readOnly,
4244
} = props;
4345
const value = initialValue === undefined || initialValue === null
4446
? null
@@ -59,12 +61,30 @@ const BooleanField = (props: BooleanFieldProps) => {
5961
</FormLabel>
6062
<RadioGroup
6163
name={name}
62-
onChange={(e) => onChange(e)}
64+
onChange={!readOnly ? onChange : undefined}
6365
style={{ flexDirection: 'row' }}
6466
value={value}
6567
>
66-
<FormControlLabel control={<Radio checked={value === 'true'} />} label="Yes" value="true" />
67-
<FormControlLabel control={<Radio checked={value === 'false'} />} label="No" value="false" />
68+
<FormControlLabel
69+
control={(
70+
<Radio
71+
checked={value === 'true'}
72+
slotProps={{ input: { readOnly } }}
73+
/>
74+
)}
75+
label="Yes"
76+
value="true"
77+
/>
78+
<FormControlLabel
79+
control={(
80+
<Radio
81+
checked={value === 'false'}
82+
slotProps={{ input: { readOnly } }}
83+
/>
84+
)}
85+
label="No"
86+
value="false"
87+
/>
6888
</RadioGroup>
6989
{helperText && (<FormHelperText>{helperText}</FormHelperText>)}
7090
</FormControl>

src/components/FormField/FilteredRecordAutocomplete/__snapshots__/index.stories.tsx.snap

Lines changed: 134 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,67 @@ exports[`Disabled snapshot 1`] = `
88
<div
99
class="filtered-record-autocomplete__content"
1010
>
11+
<div
12+
class="MuiFormControl-root css-XXXX-MuiFormControl-root filtered-record-autocomplete__select-search-class node-form__class-select option-select"
13+
>
14+
<label
15+
class="Mui-disabled MuiFormLabel-colorPrimary MuiFormLabel-filled MuiFormLabel-root MuiInputLabel-animated MuiInputLabel-formControl MuiInputLabel-root MuiInputLabel-shrink MuiInputLabel-standard css-XXXX-MuiFormLabel-root-MuiInputLabel-root"
16+
data-shrink="true"
17+
for="option-select-search-class"
18+
>
19+
Filter (search) Search by Class
20+
</label>
21+
<div
22+
class="Mui-disabled MuiInput-root MuiInput-underline MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-root MuiSelect-root css-XXXX-MuiInputBase-root-MuiInput-root"
23+
>
24+
<div
25+
aria-disabled="true"
26+
aria-expanded="false"
27+
aria-haspopup="listbox"
28+
aria-labelledby="mui-component-select-search-class"
29+
class="Mui-disabled MuiInput-input MuiInputBase-input MuiSelect-select MuiSelect-standard css-XXXX-MuiNativeSelect-root-MuiSelect-select-MuiInputBase-input-MuiInput-input"
30+
id="mui-component-select-search-class"
31+
role="combobox"
32+
>
33+
<div
34+
class="MuiListItemText-root css-XXXX-MuiListItemText-root"
35+
>
36+
<span
37+
class="MuiListItemText-primary MuiTypography-body1 MuiTypography-root css-XXXX-MuiTypography-root disabled-text"
38+
>
39+
Variant
40+
</span>
41+
<p
42+
class="MuiListItemText-secondary MuiTypography-body2 MuiTypography-root css-XXXX-MuiTypography-root option-select__option-description"
43+
/>
44+
</div>
45+
</div>
46+
<input
47+
aria-hidden="true"
48+
aria-invalid="false"
49+
class="MuiSelect-nativeInput css-XXXX-MuiSelect-nativeInput"
50+
disabled=""
51+
id="option-select-search-class"
52+
name="search-class"
53+
tabindex="-1"
54+
value="Variant"
55+
/>
56+
<svg
57+
aria-hidden="true"
58+
class="Mui-disabled MuiSelect-icon MuiSelect-iconStandard MuiSvgIcon-fontSizeSmall MuiSvgIcon-root css-XXXX-MuiSvgIcon-root-MuiNativeSelect-root-MuiSelect-icon"
59+
data-testid="FilterListIcon"
60+
focusable="false"
61+
viewBox="0 0 24 24"
62+
>
63+
<path
64+
d="M10 18h4v-2h-4zM3 6v2h18V6zm3 7h12v-2H6z"
65+
/>
66+
</svg>
67+
</div>
68+
<p
69+
class="Mui-disabled MuiFormHelperText-filled MuiFormHelperText-root MuiFormHelperText-sizeMedium css-XXXX-MuiFormHelperText-root"
70+
/>
71+
</div>
1172
<div
1273
class="MuiAutocomplete-hasPopupIcon MuiAutocomplete-root css-XXXX-MuiAutocomplete-root record-autocomplete"
1374
>
@@ -21,7 +82,8 @@ exports[`Disabled snapshot 1`] = `
2182
class="detail-chip"
2283
>
2384
<div
24-
class="MuiAutocomplete-tag MuiAutocomplete-tagSizeMedium MuiButtonBase-root MuiChip-clickable MuiChip-clickableColorPrimary MuiChip-colorPrimary MuiChip-outlined MuiChip-outlinedPrimary MuiChip-root MuiChip-sizeSmall css-XXXX-MuiButtonBase-root-MuiChip-root detail-chip__outlined detail-chip__root record-autocomplete__chip record-autocomplete__chip--multi"
85+
aria-disabled="true"
86+
class="Mui-disabled MuiAutocomplete-tag MuiAutocomplete-tagSizeMedium MuiButtonBase-root MuiChip-clickable MuiChip-clickableColorPrimary MuiChip-colorPrimary MuiChip-deletable MuiChip-deletableColorPrimary MuiChip-outlined MuiChip-outlinedPrimary MuiChip-root MuiChip-sizeSmall css-XXXX-MuiButtonBase-root-MuiChip-root detail-chip__outlined detail-chip__root record-autocomplete__chip record-autocomplete__chip--multi"
2587
data-item-index="0"
2688
role="button"
2789
tabindex="-1"
@@ -31,6 +93,17 @@ exports[`Disabled snapshot 1`] = `
3193
>
3294
#15:1
3395
</span>
96+
<svg
97+
aria-hidden="true"
98+
class="MuiChip-deleteIcon MuiChip-deleteIconColorPrimary MuiChip-deleteIconOutlinedColorPrimary MuiChip-deleteIconSmall MuiSvgIcon-fontSizeSmall MuiSvgIcon-root css-XXXX-MuiSvgIcon-root"
99+
data-testid="CancelIcon"
100+
focusable="false"
101+
viewBox="0 0 24 24"
102+
>
103+
<path
104+
d="M12 2C6.47 2 2 6.47 2 12s4.47 10 10 10 10-4.47 10-10S17.53 2 12 2zm5 13.59L15.59 17 12 13.41 8.41 17 7 15.59 10.59 12 7 8.41 8.41 7 12 10.59 15.59 7 17 8.41 13.41 12 17 15.59z"
105+
/>
106+
</svg>
34107
</div>
35108
</div>
36109
<input
@@ -202,6 +275,62 @@ exports[`Empty snapshot 1`] = `
202275
</div>
203276
`;
204277

278+
exports[`ReadOnly snapshot 1`] = `
279+
<div>
280+
<div
281+
class="MuiFormControl-root css-XXXX-MuiFormControl-root filtered-record-autocomplete"
282+
>
283+
<div
284+
class="filtered-record-autocomplete__content"
285+
>
286+
<div
287+
class="MuiAutocomplete-hasPopupIcon MuiAutocomplete-root css-XXXX-MuiAutocomplete-root record-autocomplete"
288+
>
289+
<div
290+
class="MuiFormControl-fullWidth MuiFormControl-root MuiTextField-root css-XXXX-MuiFormControl-root-MuiTextField-root"
291+
>
292+
<div
293+
class="MuiAutocomplete-inputRoot MuiInput-root MuiInputBase-adornedStart MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-fullWidth MuiInputBase-root css-XXXX-MuiInputBase-root-MuiInput-root"
294+
>
295+
<div
296+
class="detail-chip"
297+
>
298+
<div
299+
class="MuiAutocomplete-tag MuiAutocomplete-tagSizeMedium MuiButtonBase-root MuiChip-clickable MuiChip-clickableColorPrimary MuiChip-colorPrimary MuiChip-outlined MuiChip-outlinedPrimary MuiChip-root MuiChip-sizeSmall css-XXXX-MuiButtonBase-root-MuiChip-root detail-chip__outlined detail-chip__root record-autocomplete__chip record-autocomplete__chip--multi"
300+
data-item-index="0"
301+
role="button"
302+
tabindex="-1"
303+
>
304+
<span
305+
class="MuiChip-label MuiChip-labelSmall css-XXXX-MuiChip-label"
306+
>
307+
#15:1
308+
</span>
309+
</div>
310+
</div>
311+
<input
312+
aria-autocomplete="list"
313+
aria-expanded="false"
314+
aria-invalid="false"
315+
autocapitalize="none"
316+
autocomplete="off"
317+
class="MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInput-input MuiInputBase-input MuiInputBase-inputAdornedStart css-XXXX-MuiInputBase-input-MuiInput-input"
318+
id="_r_XXXX_"
319+
placeholder=""
320+
readonly=""
321+
role="combobox"
322+
spellcheck="false"
323+
type="text"
324+
value=""
325+
/>
326+
</div>
327+
</div>
328+
</div>
329+
</div>
330+
</div>
331+
</div>
332+
`;
333+
205334
exports[`WithError snapshot 1`] = `
206335
<div>
207336
<div
@@ -277,7 +406,7 @@ exports[`WithError snapshot 1`] = `
277406
class="MuiFormControl-fullWidth MuiFormControl-root MuiTextField-root css-XXXX-MuiFormControl-root-MuiTextField-root"
278407
>
279408
<div
280-
class="Mui-disabled MuiAutocomplete-inputRoot MuiInput-root MuiInputBase-adornedEnd MuiInputBase-adornedStart MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-fullWidth MuiInputBase-root css-XXXX-MuiInputBase-root-MuiInput-root"
409+
class="MuiAutocomplete-inputRoot MuiInput-root MuiInputBase-adornedEnd MuiInputBase-adornedStart MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-fullWidth MuiInputBase-root css-XXXX-MuiInputBase-root-MuiInput-root"
281410
>
282411
<div
283412
class="detail-chip"
@@ -312,7 +441,7 @@ exports[`WithError snapshot 1`] = `
312441
aria-invalid="false"
313442
autocapitalize="none"
314443
autocomplete="off"
315-
class="Mui-disabled MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInput-input MuiInputBase-input MuiInputBase-inputAdornedEnd MuiInputBase-inputAdornedStart css-XXXX-MuiInputBase-input-MuiInput-input"
444+
class="MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInput-input MuiInputBase-input MuiInputBase-inputAdornedEnd MuiInputBase-inputAdornedStart css-XXXX-MuiInputBase-input-MuiInput-input"
316445
id="_r_XXXX_"
317446
placeholder=""
318447
role="combobox"
@@ -767,7 +896,7 @@ exports[`WithValue snapshot 1`] = `
767896
class="MuiFormControl-fullWidth MuiFormControl-root MuiTextField-root css-XXXX-MuiFormControl-root-MuiTextField-root"
768897
>
769898
<div
770-
class="Mui-disabled MuiAutocomplete-inputRoot MuiInput-root MuiInputBase-adornedEnd MuiInputBase-adornedStart MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-fullWidth MuiInputBase-root css-XXXX-MuiInputBase-root-MuiInput-root"
899+
class="MuiAutocomplete-inputRoot MuiInput-root MuiInputBase-adornedEnd MuiInputBase-adornedStart MuiInputBase-colorPrimary MuiInputBase-formControl MuiInputBase-fullWidth MuiInputBase-root css-XXXX-MuiInputBase-root-MuiInput-root"
771900
>
772901
<div
773902
class="detail-chip"
@@ -802,7 +931,7 @@ exports[`WithValue snapshot 1`] = `
802931
aria-invalid="false"
803932
autocapitalize="none"
804933
autocomplete="off"
805-
class="Mui-disabled MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInput-input MuiInputBase-input MuiInputBase-inputAdornedEnd MuiInputBase-inputAdornedStart css-XXXX-MuiInputBase-input-MuiInput-input"
934+
class="MuiAutocomplete-input MuiAutocomplete-inputFocused MuiInput-input MuiInputBase-input MuiInputBase-inputAdornedEnd MuiInputBase-inputAdornedStart css-XXXX-MuiInputBase-input-MuiInput-input"
806935
id="_r_XXXX_"
807936
placeholder=""
808937
role="combobox"

src/components/FormField/FilteredRecordAutocomplete/index.stories.tsx

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,10 @@ export const Disabled = WithValue.extend({
4444
args: { disabled: true },
4545
});
4646

47+
export const ReadOnly = WithValue.extend({
48+
args: { readOnly: true },
49+
});
50+
4751
export const WithError = WithValue.extend({
4852
args: { error: true, helperText: 'bad value' },
4953
});

0 commit comments

Comments
 (0)