@thecb/components 9.2.2-beta.3 → 9.2.3-beta.3
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.
- package/dist/index.cjs.js +97 -40
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +97 -40
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/atoms/checkbox/Checkbox.js +3 -1
- package/src/components/atoms/checkbox/Checkbox.stories.js +3 -2
- package/src/components/atoms/country-dropdown/CountryDropdown.js +3 -1
- package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +1 -0
- package/src/components/atoms/dropdown/Dropdown.js +13 -7
- package/src/components/atoms/form-layouts/FormInput.js +3 -0
- package/src/components/atoms/form-select/FormSelect.js +22 -9
- package/src/components/atoms/form-select/FormSelect.stories.js +2 -2
- package/src/components/atoms/radio-button-with-label/RadioButtonWithLabel.js +9 -6
- package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.js +4 -1
- package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.stories.js +1 -0
- package/src/components/molecules/address-form/AddressForm.js +6 -0
- package/src/components/molecules/payment-form-ach/PaymentFormACH.js +6 -0
- package/src/components/molecules/payment-form-card/PaymentFormCard.js +6 -0
- package/src/components/molecules/radio-group/RadioGroup.js +1 -1
- package/src/components/molecules/radio-section/RadioSection.js +1 -0
- package/src/components/molecules/radio-section/RadioSection.stories.js +3 -2
- package/src/components/molecules/radio-section/radio-button/RadioButton.js +4 -1
package/package.json
CHANGED
|
@@ -95,7 +95,8 @@ const Checkbox = ({
|
|
|
95
95
|
checkboxMargin = "0 16px 0 0",
|
|
96
96
|
extraStyles,
|
|
97
97
|
textExtraStyles,
|
|
98
|
-
dataQa = null
|
|
98
|
+
dataQa = null,
|
|
99
|
+
isRequired = false
|
|
99
100
|
}) => {
|
|
100
101
|
const [focused, setFocused] = useState(false);
|
|
101
102
|
|
|
@@ -142,6 +143,7 @@ const Checkbox = ({
|
|
|
142
143
|
disabledStyles={themeValues.disabledStyles}
|
|
143
144
|
disabledCheckedStyles={themeValues.disabledCheckedStyles}
|
|
144
145
|
focusedStyles={themeValues.focusedStyles}
|
|
146
|
+
aria-required={isRequired}
|
|
145
147
|
>
|
|
146
148
|
<CheckboxIcon
|
|
147
149
|
viewBox="0 0 24 24"
|
|
@@ -13,12 +13,13 @@ const groupId = "props";
|
|
|
13
13
|
export const checkbox = () => (
|
|
14
14
|
<Checkbox
|
|
15
15
|
variant={select(variantsLabel, variants, defaultValue, groupId)}
|
|
16
|
-
title={text("title", "Checkbox", "props")}
|
|
17
|
-
name={text("name", "Checkbox", "props")}
|
|
16
|
+
title={text("title", "Checkbox Title", "props")}
|
|
17
|
+
name={text("name", "Checkbox Name", "props")}
|
|
18
18
|
checked={boolean("checked", false, "props")}
|
|
19
19
|
error={boolean("error", false, "props")}
|
|
20
20
|
disabled={boolean("disabled", false, "props")}
|
|
21
21
|
focused={boolean("focused", false, "props")}
|
|
22
|
+
isRequired={boolean("isRequired", true, "props")}
|
|
22
23
|
/>
|
|
23
24
|
);
|
|
24
25
|
|
|
@@ -10,7 +10,8 @@ const CountryDropdown = ({
|
|
|
10
10
|
fieldActions,
|
|
11
11
|
showErrors,
|
|
12
12
|
onChange,
|
|
13
|
-
dataQa = null
|
|
13
|
+
dataQa = null,
|
|
14
|
+
isRequired = false
|
|
14
15
|
}) => (
|
|
15
16
|
<FormSelect
|
|
16
17
|
options={options}
|
|
@@ -22,6 +23,7 @@ const CountryDropdown = ({
|
|
|
22
23
|
showErrors={showErrors}
|
|
23
24
|
onChange={onChange}
|
|
24
25
|
autocompleteValue="country-name"
|
|
26
|
+
isRequired={isRequired}
|
|
25
27
|
/>
|
|
26
28
|
);
|
|
27
29
|
export default CountryDropdown;
|
|
@@ -133,8 +133,10 @@ const Dropdown = ({
|
|
|
133
133
|
ariaDescribedby,
|
|
134
134
|
autocompleteValue, // browser autofill value, like country-name
|
|
135
135
|
smoothScroll = true,
|
|
136
|
-
ariaInvalid = false
|
|
136
|
+
ariaInvalid = false,
|
|
137
|
+
isRequired = false
|
|
137
138
|
}) => {
|
|
139
|
+
const required = options.required || isRequired;
|
|
138
140
|
const [inputValue, setInputValue] = useState("");
|
|
139
141
|
const [optionsState, setOptionsState] = useState([]);
|
|
140
142
|
const [filteredOptions, setFilteredOptions] = useState([]);
|
|
@@ -262,11 +264,13 @@ const Dropdown = ({
|
|
|
262
264
|
useEffect(() => {
|
|
263
265
|
if (autoEraseTypeAhead) {
|
|
264
266
|
clearTimeout(timer);
|
|
265
|
-
setTimer(setTimeout(() => setInputValue(""),
|
|
267
|
+
setTimer(setTimeout(() => setInputValue(""), 3000));
|
|
266
268
|
}
|
|
267
269
|
setFilteredOptions(
|
|
268
|
-
options.filter(
|
|
269
|
-
option
|
|
270
|
+
options.filter(
|
|
271
|
+
option =>
|
|
272
|
+
option.value.toLowerCase().startsWith(inputValue.toLowerCase()) ||
|
|
273
|
+
option.text.toLowerCase().startsWith(inputValue.toLowerCase())
|
|
270
274
|
)
|
|
271
275
|
);
|
|
272
276
|
}, [inputValue]);
|
|
@@ -299,7 +303,7 @@ const Dropdown = ({
|
|
|
299
303
|
<Box
|
|
300
304
|
padding="0"
|
|
301
305
|
background={isOpen ? themeValues.hoverColor : WHITE}
|
|
302
|
-
extraStyles={`position: relative
|
|
306
|
+
extraStyles={`position: relative;`}
|
|
303
307
|
minWidth="100%"
|
|
304
308
|
onClick={() => {
|
|
305
309
|
if (!isOpen) {
|
|
@@ -322,7 +326,7 @@ const Dropdown = ({
|
|
|
322
326
|
aria-labelledby={ariaLabelledby}
|
|
323
327
|
aria-describedby={ariaDescribedby}
|
|
324
328
|
aria-expanded={isOpen}
|
|
325
|
-
aria-required={
|
|
329
|
+
aria-required={required}
|
|
326
330
|
aria-invalid={ariaInvalid}
|
|
327
331
|
background={isOpen ? themeValues.hoverColor : WHITE}
|
|
328
332
|
borderRadius="2px"
|
|
@@ -354,7 +358,6 @@ const Dropdown = ({
|
|
|
354
358
|
}}
|
|
355
359
|
padding="12px"
|
|
356
360
|
placeholder={getSelection()}
|
|
357
|
-
required={options.required}
|
|
358
361
|
role="combobox"
|
|
359
362
|
themeValues={themeValues}
|
|
360
363
|
title={hasTitles ? getSelection() : null}
|
|
@@ -362,6 +365,8 @@ const Dropdown = ({
|
|
|
362
365
|
tabIndex={0}
|
|
363
366
|
value={inputValue}
|
|
364
367
|
width="100%"
|
|
368
|
+
/* Non-semantic elements need the aria-* version of the attribute */
|
|
369
|
+
aria-disabled={disabledValues.includes(inputValue)}
|
|
365
370
|
/>
|
|
366
371
|
<IconWrapper open={isOpen} onClick={onClick}>
|
|
367
372
|
<DropdownIcon />
|
|
@@ -376,6 +381,7 @@ const Dropdown = ({
|
|
|
376
381
|
tabIndex={0}
|
|
377
382
|
role="listbox"
|
|
378
383
|
id={`${ariaLabelledby}_listbox`}
|
|
384
|
+
required={required}
|
|
379
385
|
>
|
|
380
386
|
<Stack childGap="0" as="ul">
|
|
381
387
|
{filteredOptions.map((choice, i) => {
|
|
@@ -116,6 +116,7 @@ const FormInput = ({
|
|
|
116
116
|
extraStyles,
|
|
117
117
|
removeFromValue, // regex of characters to remove before setting value
|
|
118
118
|
dataQa = null,
|
|
119
|
+
isRequired = false,
|
|
119
120
|
...props
|
|
120
121
|
}) => {
|
|
121
122
|
const [showPassword, setShowPassword] = useState(false);
|
|
@@ -221,6 +222,7 @@ const FormInput = ({
|
|
|
221
222
|
$extraStyles={extraStyles}
|
|
222
223
|
data-qa={dataQa || labelTextWhenNoError}
|
|
223
224
|
autoComplete={autocompleteValue}
|
|
225
|
+
required={isRequired}
|
|
224
226
|
{...props}
|
|
225
227
|
/>
|
|
226
228
|
) : (
|
|
@@ -247,6 +249,7 @@ const FormInput = ({
|
|
|
247
249
|
$extraStyles={extraStyles}
|
|
248
250
|
data-qa={dataQa || labelTextWhenNoError}
|
|
249
251
|
autoComplete={autocompleteValue}
|
|
252
|
+
required={isRequired}
|
|
250
253
|
{...props}
|
|
251
254
|
/>
|
|
252
255
|
)}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect } from "react";
|
|
1
|
+
import React, { useState, useMemo, useRef, useEffect } from "react";
|
|
2
2
|
import Dropdown from "../dropdown";
|
|
3
3
|
import Text from "../text";
|
|
4
4
|
import { ERROR_COLOR } from "../../../constants/colors";
|
|
@@ -24,10 +24,25 @@ const FormSelect = ({
|
|
|
24
24
|
autocompleteValue, // browser autofill value, like country-name
|
|
25
25
|
smoothScroll = true, // whether the browser should animate scroll to selected item on first open
|
|
26
26
|
dataQa = null,
|
|
27
|
-
widthFitOptions = false
|
|
27
|
+
widthFitOptions = false,
|
|
28
|
+
isRequired = false
|
|
28
29
|
}) => {
|
|
29
30
|
const [open, setOpen] = useState(false);
|
|
30
31
|
const dropdownRef = useRef(null);
|
|
32
|
+
const required = options?.required || isRequired;
|
|
33
|
+
|
|
34
|
+
const labelId = useMemo(
|
|
35
|
+
() => labelTextWhenNoError => createIdFromString(labelTextWhenNoError),
|
|
36
|
+
[labelTextWhenNoError]
|
|
37
|
+
);
|
|
38
|
+
|
|
39
|
+
const descriptionId = useMemo(
|
|
40
|
+
() => (field, labelTextWhenNoError) =>
|
|
41
|
+
field.hasErrors && field.dirty
|
|
42
|
+
? labelId(labelTextWhenNoError) + "error-message"
|
|
43
|
+
: "",
|
|
44
|
+
[field, labelTextWhenNoError]
|
|
45
|
+
);
|
|
31
46
|
|
|
32
47
|
const handleClickAway = event => {
|
|
33
48
|
if (dropdownRef.current && !dropdownRef.current.contains(event.target)) {
|
|
@@ -45,8 +60,8 @@ const FormSelect = ({
|
|
|
45
60
|
return (
|
|
46
61
|
<SelectContainer
|
|
47
62
|
ref={dropdownRef}
|
|
63
|
+
aria-role="group"
|
|
48
64
|
disabled={disabled}
|
|
49
|
-
aria-disabled={disabled}
|
|
50
65
|
data-qa={dataQa}
|
|
51
66
|
>
|
|
52
67
|
<Box padding="0" minWidth="100%">
|
|
@@ -61,18 +76,15 @@ const FormSelect = ({
|
|
|
61
76
|
&::first-letter {
|
|
62
77
|
text-transform: uppercase;
|
|
63
78
|
}`}
|
|
64
|
-
id={
|
|
79
|
+
id={labelId(labelTextWhenNoError)}
|
|
65
80
|
>
|
|
66
81
|
{labelTextWhenNoError}
|
|
67
82
|
</Text>
|
|
68
83
|
</Cluster>
|
|
69
84
|
</Box>
|
|
70
85
|
<Dropdown
|
|
71
|
-
ariaLabelledby={
|
|
72
|
-
ariaDescribedby={
|
|
73
|
-
labelTextWhenNoError,
|
|
74
|
-
"error message"
|
|
75
|
-
)}
|
|
86
|
+
ariaLabelledby={labelId(labelTextWhenNoError)}
|
|
87
|
+
ariaDescribedby={descriptionId(field, labelTextWhenNoError)}
|
|
76
88
|
maxHeight={dropdownMaxHeight}
|
|
77
89
|
widthFitOptions={widthFitOptions}
|
|
78
90
|
hasTitles={hasTitles}
|
|
@@ -94,6 +106,7 @@ const FormSelect = ({
|
|
|
94
106
|
disabled={disabled}
|
|
95
107
|
autocompleteValue={autocompleteValue}
|
|
96
108
|
smoothScroll={smoothScroll}
|
|
109
|
+
isRequired={required}
|
|
97
110
|
/>
|
|
98
111
|
<Stack direction="row" justify="space-between">
|
|
99
112
|
{(field.hasErrors && field.dirty) || (field.hasErrors && showErrors) ? (
|
|
@@ -12,7 +12,7 @@ const { mapStateToProps, mapDispatchToProps, reducer } = createFormState({
|
|
|
12
12
|
}
|
|
13
13
|
});
|
|
14
14
|
const errorMessages = {
|
|
15
|
-
[required.error]: "
|
|
15
|
+
[required.error]: "This field is required."
|
|
16
16
|
};
|
|
17
17
|
const options = [
|
|
18
18
|
{ value: "", text: "choose name" },
|
|
@@ -34,7 +34,7 @@ const story = page({
|
|
|
34
34
|
const FormWrapper = props => (
|
|
35
35
|
<FormSelect
|
|
36
36
|
autocompleteValue={props.autocompleteValue}
|
|
37
|
-
labelTextWhenNoError="Form Select"
|
|
37
|
+
labelTextWhenNoError="Form Select Label"
|
|
38
38
|
errorMessages={errorMessages}
|
|
39
39
|
options={options}
|
|
40
40
|
field={props.fields.thing}
|
|
@@ -18,7 +18,7 @@ const Circle = styled.div`
|
|
|
18
18
|
flex-shrink: 0;
|
|
19
19
|
margin-right: 8px;
|
|
20
20
|
width: 1.5rem;
|
|
21
|
-
height 1.5rem;
|
|
21
|
+
height: 1.5rem;
|
|
22
22
|
border: ${({ inactiveBorderColor }) => `1px solid ${inactiveBorderColor}`};
|
|
23
23
|
border-radius: 50%;
|
|
24
24
|
box-sizing: border-box;
|
|
@@ -30,21 +30,24 @@ const Circle = styled.div`
|
|
|
30
30
|
display: block;
|
|
31
31
|
background: ${({ activeColor }) => activeColor};
|
|
32
32
|
border-radius: 50%;
|
|
33
|
-
transform: scale(0);
|
|
34
|
-
}
|
|
33
|
+
transform: scale(0);
|
|
34
|
+
}
|
|
35
35
|
`;
|
|
36
36
|
|
|
37
37
|
const InputAndLabelContainer = styled(Cluster)`
|
|
38
38
|
overflow: visible;
|
|
39
|
+
|
|
39
40
|
${HiddenRadioInput}:checked + label ${Circle}:after {
|
|
40
41
|
transform: scale(0.85);
|
|
41
42
|
transition: transform 0.15s;
|
|
42
43
|
}
|
|
44
|
+
|
|
43
45
|
${HiddenRadioInput}:checked + label ${Circle} {
|
|
44
|
-
border: ${({ activeColor }) =>
|
|
46
|
+
border: ${({ activeColor }) => "1px solid " + activeColor};
|
|
45
47
|
}
|
|
46
|
-
|
|
47
|
-
|
|
48
|
+
|
|
49
|
+
${HiddenRadioInput}:focus + label ${Circle} {
|
|
50
|
+
box-shadow: ${({ activeColor }) => "0px 0px 2px 1px " + activeColor};
|
|
48
51
|
}
|
|
49
52
|
`;
|
|
50
53
|
|
|
@@ -9,11 +9,13 @@ const FormStateDropdown = ({
|
|
|
9
9
|
field,
|
|
10
10
|
fieldActions,
|
|
11
11
|
showErrors,
|
|
12
|
-
countryCode
|
|
12
|
+
countryCode,
|
|
13
|
+
isRequired = false
|
|
13
14
|
}) => {
|
|
14
15
|
const placeholder =
|
|
15
16
|
countryCode === "US" ? placeHolderOptionUS : placeHolderOption;
|
|
16
17
|
const options = [placeholder, ...getOptions(countryCode)];
|
|
18
|
+
|
|
17
19
|
return (
|
|
18
20
|
<FormSelect
|
|
19
21
|
options={options}
|
|
@@ -23,6 +25,7 @@ const FormStateDropdown = ({
|
|
|
23
25
|
errorMessages={errorMessages}
|
|
24
26
|
showErrors={showErrors}
|
|
25
27
|
autocompleteValue="address-level1"
|
|
28
|
+
isRequired={isRequired}
|
|
26
29
|
/>
|
|
27
30
|
);
|
|
28
31
|
};
|
|
@@ -58,6 +58,7 @@ const AddressForm = ({
|
|
|
58
58
|
labelTextWhenNoError="Country"
|
|
59
59
|
errorMessages={countryErrorMessages}
|
|
60
60
|
field={fields.country}
|
|
61
|
+
isRequired={true}
|
|
61
62
|
onChange={value => {
|
|
62
63
|
actions.fields.country.set(value);
|
|
63
64
|
// temporary measure to not dirty fields until
|
|
@@ -81,6 +82,7 @@ const AddressForm = ({
|
|
|
81
82
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
82
83
|
autocompleteValue="address-line1"
|
|
83
84
|
dataQa="Address"
|
|
85
|
+
isRequired={true}
|
|
84
86
|
/>
|
|
85
87
|
<FormInput
|
|
86
88
|
labelTextWhenNoError="Apt, Suite, Unit, Floor, etc. (Optional)"
|
|
@@ -90,6 +92,7 @@ const AddressForm = ({
|
|
|
90
92
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
91
93
|
autocompleteValue="address-line2"
|
|
92
94
|
dataQa="Address Line 2"
|
|
95
|
+
isRequired={false}
|
|
93
96
|
/>
|
|
94
97
|
<FormInput
|
|
95
98
|
labelTextWhenNoError="City"
|
|
@@ -100,6 +103,7 @@ const AddressForm = ({
|
|
|
100
103
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
101
104
|
autocompleteValue="address-level2"
|
|
102
105
|
dataQa="City"
|
|
106
|
+
isRequired={true}
|
|
103
107
|
/>
|
|
104
108
|
<StateProvinceDropdown
|
|
105
109
|
labelTextWhenNoError={isUS ? "State" : "State or Province"}
|
|
@@ -110,6 +114,7 @@ const AddressForm = ({
|
|
|
110
114
|
showErrors={showErrors}
|
|
111
115
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
112
116
|
dataQa="State or Province"
|
|
117
|
+
isRequired={true}
|
|
113
118
|
/>
|
|
114
119
|
<FormInput
|
|
115
120
|
isNum={isUS}
|
|
@@ -122,6 +127,7 @@ const AddressForm = ({
|
|
|
122
127
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
123
128
|
autocompleteValue="postal-code"
|
|
124
129
|
dataQa="Zip code"
|
|
130
|
+
isRequired={true}
|
|
125
131
|
/>
|
|
126
132
|
{showWalletCheckbox && (
|
|
127
133
|
<Checkbox
|
|
@@ -76,6 +76,7 @@ const PaymentFormACH = ({
|
|
|
76
76
|
showErrors={showErrors}
|
|
77
77
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
78
78
|
autocompleteValue="name"
|
|
79
|
+
isRequired={true}
|
|
79
80
|
/>
|
|
80
81
|
<FormInput
|
|
81
82
|
labelTextWhenNoError="Routing number"
|
|
@@ -97,6 +98,7 @@ const PaymentFormACH = ({
|
|
|
97
98
|
/>
|
|
98
99
|
)}
|
|
99
100
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
101
|
+
isRequired={true}
|
|
100
102
|
/>
|
|
101
103
|
<FormInput
|
|
102
104
|
labelTextWhenNoError="Confirm routing number"
|
|
@@ -106,6 +108,7 @@ const PaymentFormACH = ({
|
|
|
106
108
|
fieldActions={actions.fields.confirmRoutingNumber}
|
|
107
109
|
showErrors={showErrors}
|
|
108
110
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
111
|
+
isRequired={true}
|
|
109
112
|
isNum
|
|
110
113
|
/>
|
|
111
114
|
<FormInput
|
|
@@ -115,6 +118,7 @@ const PaymentFormACH = ({
|
|
|
115
118
|
field={fields.accountNumber}
|
|
116
119
|
fieldActions={actions.fields.accountNumber}
|
|
117
120
|
showErrors={showErrors}
|
|
121
|
+
isRequired={true}
|
|
118
122
|
isNum
|
|
119
123
|
helperModal={() => (
|
|
120
124
|
<AccountAndRoutingModal
|
|
@@ -132,6 +136,7 @@ const PaymentFormACH = ({
|
|
|
132
136
|
<FormInput
|
|
133
137
|
labelTextWhenNoError="Confirm account number"
|
|
134
138
|
dataQa="Confirm account number"
|
|
139
|
+
isRequired={true}
|
|
135
140
|
errorMessages={confirmAccountNumberErrors}
|
|
136
141
|
field={fields.confirmAccountNumber}
|
|
137
142
|
fieldActions={actions.fields.confirmAccountNumber}
|
|
@@ -142,6 +147,7 @@ const PaymentFormACH = ({
|
|
|
142
147
|
{allowBankAccountType && (
|
|
143
148
|
<FormSelect
|
|
144
149
|
labelTextWhenNoError="Account type"
|
|
150
|
+
isRequired={true}
|
|
145
151
|
dataQa="Account type"
|
|
146
152
|
options={[
|
|
147
153
|
{ text: "Select account type", value: "" },
|
|
@@ -98,6 +98,7 @@ const PaymentFormCard = ({
|
|
|
98
98
|
{!hideZipCode && (
|
|
99
99
|
<CountryDropdown
|
|
100
100
|
labelTextWhenNoError="Country"
|
|
101
|
+
isRequired={true}
|
|
101
102
|
errorMessages={countryErrorMessages}
|
|
102
103
|
field={fields.country}
|
|
103
104
|
onChange={value => {
|
|
@@ -121,8 +122,10 @@ const PaymentFormCard = ({
|
|
|
121
122
|
showErrors={showErrors}
|
|
122
123
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
123
124
|
autocompleteValue="cc-name"
|
|
125
|
+
isRequired={true}
|
|
124
126
|
/>
|
|
125
127
|
<FormInput
|
|
128
|
+
isRequired={true}
|
|
126
129
|
labelTextWhenNoError="Credit card number"
|
|
127
130
|
dataQa="Credit card number"
|
|
128
131
|
errorMessages={creditCardNumberErrors}
|
|
@@ -150,6 +153,7 @@ const PaymentFormCard = ({
|
|
|
150
153
|
isNum
|
|
151
154
|
removeFromValue={/\//} // removes "/" from browser autofill
|
|
152
155
|
autocompleteValue="cc-exp"
|
|
156
|
+
isRequired={true}
|
|
153
157
|
/>
|
|
154
158
|
<FormInput
|
|
155
159
|
labelTextWhenNoError="CVV"
|
|
@@ -166,6 +170,7 @@ const PaymentFormCard = ({
|
|
|
166
170
|
}
|
|
167
171
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
168
172
|
autocompleteValue="cc-csc"
|
|
173
|
+
isRequired={true}
|
|
169
174
|
/>
|
|
170
175
|
</FormInputRow>
|
|
171
176
|
{!hideZipCode && (
|
|
@@ -184,6 +189,7 @@ const PaymentFormCard = ({
|
|
|
184
189
|
showErrors={showErrors}
|
|
185
190
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
186
191
|
autocompleteValue="billing postal-code"
|
|
192
|
+
isRequired={true}
|
|
187
193
|
/>
|
|
188
194
|
</Box>
|
|
189
195
|
)}
|
|
@@ -49,9 +49,10 @@ const sections = [
|
|
|
49
49
|
title: "New Card",
|
|
50
50
|
content: <p>The form to add a credit card would go here.</p>,
|
|
51
51
|
rightIconsLabel: cardIconsLabel,
|
|
52
|
-
rightIcons: cardIcons
|
|
52
|
+
rightIcons: cardIcons,
|
|
53
|
+
required: true
|
|
53
54
|
},
|
|
54
|
-
{ id: "bar", title: "Bar", content: <div>Content 1</div
|
|
55
|
+
{ id: "bar", title: "Bar", content: <div>Content 1</div>, required: true },
|
|
55
56
|
{ id: "baz", title: "Baz", content: <div>Content 2</div> }
|
|
56
57
|
];
|
|
57
58
|
|
|
@@ -19,7 +19,8 @@ const RadioButton = ({
|
|
|
19
19
|
ariaDescribedBy = "",
|
|
20
20
|
themeValues,
|
|
21
21
|
ariaLabelledBy = "",
|
|
22
|
-
ariaLabel = null
|
|
22
|
+
ariaLabel = null,
|
|
23
|
+
required = false
|
|
23
24
|
}) => {
|
|
24
25
|
const buttonBorder = {
|
|
25
26
|
onFocused: {
|
|
@@ -90,6 +91,8 @@ const RadioButton = ({
|
|
|
90
91
|
type="radio"
|
|
91
92
|
id={`radio-${name}`}
|
|
92
93
|
disabled={disabled}
|
|
94
|
+
required={required}
|
|
95
|
+
aria-required={required}
|
|
93
96
|
onClick={toggleRadio}
|
|
94
97
|
aria-describedby={ariaDescribedBy}
|
|
95
98
|
tabIndex="-1"
|