@thecb/components 8.4.11-beta.9 → 9.0.0-beta.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.
- package/dist/index.cjs.js +224 -160
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.d.ts +15 -0
- package/dist/index.esm.js +224 -160
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/atoms/alert/Alert.js +1 -0
- package/src/components/atoms/checkbox/Checkbox.js +4 -3
- package/src/components/atoms/country-dropdown/CountryDropdown.js +2 -2
- package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +0 -1
- package/src/components/atoms/display-box/DisplayBox.js +7 -1
- package/src/components/atoms/dropdown/Dropdown.js +25 -19
- package/src/components/atoms/dropdown/index.d.ts +32 -0
- package/src/components/atoms/form-layouts/FormInput.js +25 -11
- package/src/components/atoms/form-layouts/index.d.ts +8 -0
- package/src/components/atoms/form-select/FormSelect.js +20 -9
- package/src/components/atoms/form-select/index.d.ts +7 -0
- package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.js +5 -2
- package/src/components/atoms/state-province-dropdown/index.d.ts +26 -0
- package/src/components/molecules/account-and-routing-modal/AccountAndRoutingModal.js +4 -1
- package/src/components/molecules/address-form/AddressForm.js +12 -16
- package/src/components/molecules/change-password-form/ChangePasswordForm.js +3 -3
- package/src/components/molecules/edit-name-form/EditNameForm.js +4 -2
- package/src/components/molecules/email-form/EmailForm.js +2 -1
- package/src/components/molecules/forgot-password-form/ForgotPasswordForm.js +1 -1
- package/src/components/molecules/login-form/LoginForm.js +2 -2
- package/src/components/molecules/modal/Modal.js +3 -2
- package/src/components/molecules/payment-form-ach/PaymentFormACH.js +13 -5
- package/src/components/molecules/payment-form-card/PaymentFormCard.js +12 -5
- package/src/components/molecules/phone-form/PhoneForm.js +2 -3
- package/src/components/molecules/registration-form/RegistrationForm.js +5 -5
- package/src/components/molecules/reset-password-form/ResetPasswordForm.js +2 -2
- package/src/components/molecules/terms-and-conditions/TermsAndConditionsControlV1.js +4 -2
- package/src/components/molecules/terms-and-conditions/TermsAndConditionsControlV2.js +14 -10
package/package.json
CHANGED
|
@@ -94,7 +94,8 @@ const Checkbox = ({
|
|
|
94
94
|
error = false,
|
|
95
95
|
checkboxMargin = "0 16px 0 0",
|
|
96
96
|
extraStyles,
|
|
97
|
-
textExtraStyles
|
|
97
|
+
textExtraStyles,
|
|
98
|
+
dataQa = "Checkbox Label"
|
|
98
99
|
}) => {
|
|
99
100
|
const [focused, setFocused] = useState(false);
|
|
100
101
|
|
|
@@ -115,7 +116,7 @@ const Checkbox = ({
|
|
|
115
116
|
background={themeValues.backgroundColor}
|
|
116
117
|
extraStyles={`outline: none; ${extraStyles}; margin: ${checkboxMargin};`}
|
|
117
118
|
>
|
|
118
|
-
<CheckboxLabelContainer>
|
|
119
|
+
<CheckboxLabelContainer data-qa={dataQa}>
|
|
119
120
|
<CheckboxContainer data-qa="Checkbox">
|
|
120
121
|
<HiddenCheckbox
|
|
121
122
|
id={`checkbox-${name}`}
|
|
@@ -126,7 +127,7 @@ const Checkbox = ({
|
|
|
126
127
|
onChange={onChange}
|
|
127
128
|
tabIndex="-1"
|
|
128
129
|
aria-invalid={error}
|
|
129
|
-
aria-describedby={name}
|
|
130
|
+
aria-describedby={error ? `${name}-error-message` : ""}
|
|
130
131
|
/>
|
|
131
132
|
<StyledCheckbox
|
|
132
133
|
error={error}
|
|
@@ -10,18 +10,18 @@ const CountryDropdown = ({
|
|
|
10
10
|
fieldActions,
|
|
11
11
|
showErrors,
|
|
12
12
|
onChange,
|
|
13
|
-
|
|
13
|
+
dataQa = "Country Dropdown"
|
|
14
14
|
}) => (
|
|
15
15
|
<FormSelect
|
|
16
16
|
options={options}
|
|
17
17
|
field={field}
|
|
18
18
|
fieldActions={fieldActions}
|
|
19
19
|
labelTextWhenNoError={labelTextWhenNoError}
|
|
20
|
+
dataQa={dataQa}
|
|
20
21
|
errorMessages={errorMessages}
|
|
21
22
|
showErrors={showErrors}
|
|
22
23
|
onChange={onChange}
|
|
23
24
|
autocompleteValue="country-name"
|
|
24
|
-
{...rest}
|
|
25
25
|
/>
|
|
26
26
|
);
|
|
27
27
|
export default CountryDropdown;
|
|
@@ -4,7 +4,12 @@ import { fallbackValues } from "./DisplayBox.theme";
|
|
|
4
4
|
import { themeComponent } from "../../../util/themeUtils";
|
|
5
5
|
import { RED } from "../../../constants/colors";
|
|
6
6
|
|
|
7
|
-
const DisplayBox = ({
|
|
7
|
+
const DisplayBox = ({
|
|
8
|
+
children,
|
|
9
|
+
themeValues,
|
|
10
|
+
showError,
|
|
11
|
+
dataQa = "DisplayBox"
|
|
12
|
+
}) => (
|
|
8
13
|
<Box padding="0.5rem 0 1.5rem 0">
|
|
9
14
|
<Box
|
|
10
15
|
padding="1.5rem"
|
|
@@ -13,6 +18,7 @@ const DisplayBox = ({ children, themeValues, showError }) => (
|
|
|
13
18
|
borderColor={showError && RED}
|
|
14
19
|
borderRadius="4px"
|
|
15
20
|
boxShadow={themeValues.boxShadow}
|
|
21
|
+
dataQa={dataQa}
|
|
16
22
|
>
|
|
17
23
|
{children}
|
|
18
24
|
</Box>
|
|
@@ -3,6 +3,7 @@ import { Box, Stack } from "../layouts";
|
|
|
3
3
|
import Text from "../text";
|
|
4
4
|
import {
|
|
5
5
|
noop,
|
|
6
|
+
createIdFromString,
|
|
6
7
|
inputDisabledStyle,
|
|
7
8
|
inputPlaceholderTextStyle
|
|
8
9
|
} from "../../../util/general";
|
|
@@ -16,8 +17,7 @@ import {
|
|
|
16
17
|
GREY_CHATEAU,
|
|
17
18
|
STORM_GREY,
|
|
18
19
|
MINESHAFT_GREY,
|
|
19
|
-
ERROR_COLOR
|
|
20
|
-
CHARADE_GREY
|
|
20
|
+
ERROR_COLOR
|
|
21
21
|
} from "../../../constants/colors";
|
|
22
22
|
import { fallbackValues } from "./Dropdown.theme";
|
|
23
23
|
import { themeComponent } from "../../../util/themeUtils";
|
|
@@ -104,8 +104,9 @@ const Dropdown = ({
|
|
|
104
104
|
autoEraseTypeAhead = true,
|
|
105
105
|
ariaLabelledby,
|
|
106
106
|
ariaDescribedby,
|
|
107
|
-
autocompleteValue =
|
|
108
|
-
smoothScroll = true
|
|
107
|
+
autocompleteValue = null, // browser autofill value, like country-name
|
|
108
|
+
smoothScroll = true,
|
|
109
|
+
ariaInvalid = false
|
|
109
110
|
}) => {
|
|
110
111
|
const [inputValue, setInputValue] = useState("");
|
|
111
112
|
const [optionsState, setOptionsState] = useState([]);
|
|
@@ -283,18 +284,19 @@ const Dropdown = ({
|
|
|
283
284
|
}}
|
|
284
285
|
onKeyDown={onKeyDown}
|
|
285
286
|
width="100%"
|
|
287
|
+
dataQa={`${ariaLabelledby}-dropdown`}
|
|
286
288
|
>
|
|
287
289
|
<Box
|
|
288
290
|
as="input"
|
|
289
291
|
aria-multiline="false"
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
292
|
+
autoComplete={autocompleteValue}
|
|
293
|
+
aria-controls={`${createIdFromString(ariaLabelledby)}_listbox`}
|
|
294
|
+
aria-activedescendant="focused_option"
|
|
295
|
+
aria-owns={`${ariaLabelledby}_listbox`}
|
|
294
296
|
aria-haspopup="listbox"
|
|
295
297
|
aria-labelledby={ariaLabelledby}
|
|
296
298
|
aria-describedby={ariaDescribedby}
|
|
297
|
-
|
|
299
|
+
aria-expanded={isOpen}
|
|
298
300
|
background={isOpen ? themeValues.hoverColor : WHITE}
|
|
299
301
|
borderRadius="2px"
|
|
300
302
|
borderSize="1px"
|
|
@@ -315,7 +317,6 @@ const Dropdown = ({
|
|
|
315
317
|
minHeight="48px"
|
|
316
318
|
minWidth="100%"
|
|
317
319
|
name={autocompleteValue}
|
|
318
|
-
// aria-expanded={isOpen}
|
|
319
320
|
onChange={e => {
|
|
320
321
|
// support autofill and copy/paste
|
|
321
322
|
if (e.target.value !== inputValue) {
|
|
@@ -325,6 +326,7 @@ const Dropdown = ({
|
|
|
325
326
|
}}
|
|
326
327
|
padding="12px"
|
|
327
328
|
placeholder={getSelection()}
|
|
329
|
+
role="combobox"
|
|
328
330
|
themeValues={themeValues}
|
|
329
331
|
title={hasTitles ? getSelection() : null}
|
|
330
332
|
type="text"
|
|
@@ -332,6 +334,9 @@ const Dropdown = ({
|
|
|
332
334
|
value={inputValue}
|
|
333
335
|
width="100%"
|
|
334
336
|
dataQa={placeholder}
|
|
337
|
+
required={options.required}
|
|
338
|
+
aria-required={options.required}
|
|
339
|
+
aria-invalid={ariaInvalid}
|
|
335
340
|
/>
|
|
336
341
|
<IconWrapper open={isOpen} onClick={onClick}>
|
|
337
342
|
<DropdownIcon />
|
|
@@ -374,11 +379,12 @@ const Dropdown = ({
|
|
|
374
379
|
selected={choice.value === value}
|
|
375
380
|
aria-selected={choice.value === value}
|
|
376
381
|
disabled={disabledValues.includes(choice.value)}
|
|
382
|
+
aria-disabled={disabledValues.includes(choice.value)}
|
|
377
383
|
data-qa={choice.text}
|
|
378
384
|
themeValues={themeValues}
|
|
379
385
|
title={hasTitles ? choice.text : null}
|
|
380
|
-
role="option"
|
|
381
386
|
onFocus={() => setFocusedRef(optionRefs.current[i])}
|
|
387
|
+
role="option"
|
|
382
388
|
>
|
|
383
389
|
<Text
|
|
384
390
|
variant="p"
|
|
@@ -390,14 +396,14 @@ const Dropdown = ({
|
|
|
390
396
|
: MINESHAFT_GREY
|
|
391
397
|
}
|
|
392
398
|
extraStyles={`padding-left: 16px;
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
399
|
+
cursor: ${
|
|
400
|
+
disabledValues.includes(choice.value)
|
|
401
|
+
? "default"
|
|
402
|
+
: "pointer"
|
|
403
|
+
};
|
|
404
|
+
white-space: nowrap;
|
|
405
|
+
overflow: hidden;
|
|
406
|
+
text-overflow: ellipsis;`}
|
|
401
407
|
>
|
|
402
408
|
{choice.text}
|
|
403
409
|
</Text>
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Expand from "../../../util/expand";
|
|
3
|
+
|
|
4
|
+
export interface DropdownOption {
|
|
5
|
+
text: string;
|
|
6
|
+
value: string;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export interface DropdownProps {
|
|
10
|
+
placeholder?: string;
|
|
11
|
+
options?: DropdownOption[];
|
|
12
|
+
value?: string;
|
|
13
|
+
isOpen?: boolean;
|
|
14
|
+
isError?: boolean;
|
|
15
|
+
onSelect?: (event: React.SyntheticEvent<HTMLElement>) => void;
|
|
16
|
+
disabledValues?: string[];
|
|
17
|
+
onClick?: (event: React.MouseEvent<HTMLElement>) => void;
|
|
18
|
+
themeValues?: object;
|
|
19
|
+
maxHeight?: string;
|
|
20
|
+
widthFitOptions?: boolean;
|
|
21
|
+
disabled?: boolean;
|
|
22
|
+
hasTitles?: boolean;
|
|
23
|
+
autoEraseTypeAhead?: true;
|
|
24
|
+
ariaLabelledby?: string;
|
|
25
|
+
ariaDescribedby?: string;
|
|
26
|
+
autocompleteValue?: string;
|
|
27
|
+
smoothScroll?: boolean;
|
|
28
|
+
ariaInvalid?: boolean;
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
export const Dropdown: React.FC<Expand<DropdownProps> &
|
|
32
|
+
React.HTMLAttributes<HTMLElement>>;
|
|
@@ -112,9 +112,10 @@ const FormInput = ({
|
|
|
112
112
|
themeValues,
|
|
113
113
|
background,
|
|
114
114
|
customHeight,
|
|
115
|
-
|
|
115
|
+
autocompleteValue = "",
|
|
116
116
|
extraStyles,
|
|
117
117
|
removeFromValue, // regex of characters to remove before setting value
|
|
118
|
+
dataQa = "Form Input",
|
|
118
119
|
...props
|
|
119
120
|
}) => {
|
|
120
121
|
const [showPassword, setShowPassword] = useState(false);
|
|
@@ -127,7 +128,7 @@ const FormInput = ({
|
|
|
127
128
|
};
|
|
128
129
|
|
|
129
130
|
return (
|
|
130
|
-
<Stack childGap="0.25rem"
|
|
131
|
+
<Stack childGap="0.25rem">
|
|
131
132
|
<Box padding="0">
|
|
132
133
|
{helperModal ? (
|
|
133
134
|
<Cluster justify="space-between" align="center">
|
|
@@ -178,8 +179,9 @@ const FormInput = ({
|
|
|
178
179
|
hoverStyles={themeValues.hoverFocusStyles}
|
|
179
180
|
extraStyles={`cursor: pointer; &:focus { outline-offset: -2px; }`}
|
|
180
181
|
onClick={() => setShowPassword(!showPassword)}
|
|
181
|
-
aria-label="Show password"
|
|
182
182
|
tabIndex="0"
|
|
183
|
+
aria-label={showPassword ? "Hide Password" : "Show password"}
|
|
184
|
+
aria-live="polite"
|
|
183
185
|
onKeyPress={e =>
|
|
184
186
|
e.key === "Enter" && setShowPassword(!showPassword)
|
|
185
187
|
}
|
|
@@ -194,11 +196,14 @@ const FormInput = ({
|
|
|
194
196
|
</Box>
|
|
195
197
|
)}
|
|
196
198
|
</Box>
|
|
197
|
-
<Box padding="0"
|
|
199
|
+
<Box padding="0">
|
|
198
200
|
{formatter ? (
|
|
199
201
|
<FormattedInputField
|
|
200
202
|
aria-labelledby={createIdFromString(labelTextWhenNoError)}
|
|
201
|
-
aria-describedby={createIdFromString(
|
|
203
|
+
aria-describedby={createIdFromString(
|
|
204
|
+
labelTextWhenNoError,
|
|
205
|
+
"error message"
|
|
206
|
+
)}
|
|
202
207
|
aria-invalid={
|
|
203
208
|
(field.dirty && field.hasErrors) ||
|
|
204
209
|
(field.hasErrors && showErrors)
|
|
@@ -211,17 +216,20 @@ const FormInput = ({
|
|
|
211
216
|
field={field}
|
|
212
217
|
formatter={formatter}
|
|
213
218
|
showErrors={showErrors}
|
|
214
|
-
data-qa={labelTextWhenNoError}
|
|
215
219
|
themeValues={themeValues}
|
|
216
220
|
$customHeight={customHeight}
|
|
217
221
|
$extraStyles={extraStyles}
|
|
218
|
-
|
|
222
|
+
data-qa={dataQa}
|
|
223
|
+
autoComplete={autocompleteValue}
|
|
219
224
|
{...props}
|
|
220
225
|
/>
|
|
221
226
|
) : (
|
|
222
227
|
<InputField
|
|
223
228
|
aria-labelledby={createIdFromString(labelTextWhenNoError)}
|
|
224
|
-
aria-describedby={createIdFromString(
|
|
229
|
+
aria-describedby={createIdFromString(
|
|
230
|
+
labelTextWhenNoError,
|
|
231
|
+
"error message"
|
|
232
|
+
)}
|
|
225
233
|
aria-invalid={
|
|
226
234
|
(field.dirty && field.hasErrors) ||
|
|
227
235
|
(field.hasErrors && showErrors)
|
|
@@ -233,17 +241,23 @@ const FormInput = ({
|
|
|
233
241
|
inputMode={isNum ? "numeric" : isEmail ? "email" : "text"}
|
|
234
242
|
field={field}
|
|
235
243
|
showErrors={showErrors}
|
|
236
|
-
data-qa={labelTextWhenNoError}
|
|
237
244
|
themeValues={themeValues}
|
|
238
245
|
background={background}
|
|
239
246
|
$customHeight={customHeight}
|
|
240
247
|
$extraStyles={extraStyles}
|
|
241
|
-
|
|
248
|
+
data-qa={dataQa}
|
|
249
|
+
autoComplete={autocompleteValue}
|
|
242
250
|
{...props}
|
|
243
251
|
/>
|
|
244
252
|
)}
|
|
245
253
|
</Box>
|
|
246
|
-
<Stack
|
|
254
|
+
<Stack
|
|
255
|
+
direction="row"
|
|
256
|
+
justify="space-between"
|
|
257
|
+
aria-live="polite"
|
|
258
|
+
aria-atomic={true}
|
|
259
|
+
data-qa={`${labelTextWhenNoError} errors`}
|
|
260
|
+
>
|
|
247
261
|
{(field.hasErrors && field.dirty) || (field.hasErrors && showErrors) ? (
|
|
248
262
|
<Text
|
|
249
263
|
color={ERROR_COLOR}
|
|
@@ -18,6 +18,14 @@ export interface FormInputProps {
|
|
|
18
18
|
labelTextWhenNoError?: string;
|
|
19
19
|
showErrors?: boolean;
|
|
20
20
|
type?: string;
|
|
21
|
+
formatter?: string | null;
|
|
22
|
+
decorator?: boolean;
|
|
23
|
+
themeValues?: object;
|
|
24
|
+
background?: string;
|
|
25
|
+
customHeight?: string;
|
|
26
|
+
autocompleteValue?: string;
|
|
27
|
+
removeFromValue?: RegExp;
|
|
28
|
+
dataQa?: string;
|
|
21
29
|
}
|
|
22
30
|
|
|
23
31
|
export const FormInput: React.FC<Expand<FormInputProps> &
|
|
@@ -21,8 +21,9 @@ const FormSelect = ({
|
|
|
21
21
|
disabled,
|
|
22
22
|
themeValues,
|
|
23
23
|
hasTitles = false,
|
|
24
|
-
autocompleteValue, // browser autofill value, like country-name or address-level1 for state
|
|
25
|
-
smoothScroll = true // whether the browser should animate scroll to selected item on first open
|
|
24
|
+
autocompleteValue = "", // browser autofill value, like country-name or address-level1 for state
|
|
25
|
+
smoothScroll = true, // whether the browser should animate scroll to selected item on first open
|
|
26
|
+
dataQa = "FormSelect"
|
|
26
27
|
}) => {
|
|
27
28
|
const [open, setOpen] = useState(false);
|
|
28
29
|
const dropdownRef = useRef(null);
|
|
@@ -41,7 +42,7 @@ const FormSelect = ({
|
|
|
41
42
|
});
|
|
42
43
|
|
|
43
44
|
return (
|
|
44
|
-
<SelectContainer ref={dropdownRef} disabled={disabled}>
|
|
45
|
+
<SelectContainer ref={dropdownRef} disabled={disabled} data-qa={dataQa}>
|
|
45
46
|
<Box padding="0" minWidth="100%">
|
|
46
47
|
<Cluster justify="space-between" align="center">
|
|
47
48
|
<Text
|
|
@@ -61,8 +62,11 @@ const FormSelect = ({
|
|
|
61
62
|
</Cluster>
|
|
62
63
|
</Box>
|
|
63
64
|
<Dropdown
|
|
64
|
-
ariaLabelledby={
|
|
65
|
-
|
|
65
|
+
ariaLabelledby={labelTextWhenNoError}
|
|
66
|
+
ariaDescribedBy={createIdFromString(
|
|
67
|
+
labelTextWhenNoError,
|
|
68
|
+
"error message"
|
|
69
|
+
)}
|
|
66
70
|
maxHeight={dropdownMaxHeight}
|
|
67
71
|
hasTitles={hasTitles}
|
|
68
72
|
placeholder={options[0] ? options[0].text : ""}
|
|
@@ -73,6 +77,9 @@ const FormSelect = ({
|
|
|
73
77
|
isError={
|
|
74
78
|
(field.hasErrors && field.dirty) || (field.hasErrors && showErrors)
|
|
75
79
|
}
|
|
80
|
+
ariaInvalid={
|
|
81
|
+
(field.hasErrors && field.dirty) || (field.hasErrors && showErrors)
|
|
82
|
+
}
|
|
76
83
|
onSelect={
|
|
77
84
|
onChange ? value => onChange(value) : value => fieldActions.set(value)
|
|
78
85
|
}
|
|
@@ -80,19 +87,23 @@ const FormSelect = ({
|
|
|
80
87
|
disabled={disabled}
|
|
81
88
|
autocompleteValue={autocompleteValue}
|
|
82
89
|
smoothScroll={smoothScroll}
|
|
83
|
-
required={options.required}
|
|
84
90
|
/>
|
|
85
|
-
<Stack direction="row" justify="space-between"
|
|
91
|
+
<Stack direction="row" justify="space-between">
|
|
86
92
|
<Text
|
|
87
93
|
color={ERROR_COLOR}
|
|
88
94
|
variant="pXS"
|
|
89
95
|
weight={themeValues.fontWeight}
|
|
90
|
-
extraStyles={`
|
|
96
|
+
extraStyles={`
|
|
97
|
+
word-break: break-word;
|
|
91
98
|
font-family: Public Sans;
|
|
92
99
|
&::first-letter {
|
|
93
100
|
text-transform: uppercase;
|
|
94
|
-
}
|
|
101
|
+
}
|
|
102
|
+
`}
|
|
95
103
|
id={createIdFromString(labelTextWhenNoError, "error message")}
|
|
104
|
+
aria-live="polite"
|
|
105
|
+
aria-atomic={true}
|
|
106
|
+
data-qa={createIdFromString(labelTextWhenNoError, "error message")}
|
|
96
107
|
>
|
|
97
108
|
{(field.hasErrors && field.dirty) || (field.hasErrors && showErrors)
|
|
98
109
|
? errorMessages[field.errors[0]]
|
|
@@ -16,6 +16,13 @@ export interface FormSelectProps {
|
|
|
16
16
|
showErrors?: boolean;
|
|
17
17
|
errorMessages?: ErrorMessageDictionary;
|
|
18
18
|
field?: Field;
|
|
19
|
+
onChange?: (event: React.ChangeEvent<HTMLSelectElement>) => void;
|
|
20
|
+
disabledValues?: string[];
|
|
21
|
+
themeValues?: object;
|
|
22
|
+
hasTitles?: boolean;
|
|
23
|
+
autocompleteValue?: string;
|
|
24
|
+
smoothScroll?: boolean;
|
|
25
|
+
dataQa?: string;
|
|
19
26
|
}
|
|
20
27
|
|
|
21
28
|
export const FormSelect: React.FC<Expand<FormSelectProps> &
|
|
@@ -10,7 +10,8 @@ const FormStateDropdown = ({
|
|
|
10
10
|
fieldActions,
|
|
11
11
|
showErrors,
|
|
12
12
|
countryCode,
|
|
13
|
-
|
|
13
|
+
autocompleteValue = "administrative-area",
|
|
14
|
+
dataQa = "StateProvinceDropdown"
|
|
14
15
|
}) => {
|
|
15
16
|
const placeholder =
|
|
16
17
|
countryCode === "US" ? placeHolderOptionUS : placeHolderOption;
|
|
@@ -23,7 +24,9 @@ const FormStateDropdown = ({
|
|
|
23
24
|
labelTextWhenNoError={labelTextWhenNoError}
|
|
24
25
|
errorMessages={errorMessages}
|
|
25
26
|
showErrors={showErrors}
|
|
26
|
-
|
|
27
|
+
aria-invalid={!!errorMessages?.length}
|
|
28
|
+
autocompleteValue={autocompleteValue}
|
|
29
|
+
dataQa={dataQa}
|
|
27
30
|
/>
|
|
28
31
|
);
|
|
29
32
|
};
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
|
|
3
|
+
import {
|
|
4
|
+
ErrorMessageDictionary,
|
|
5
|
+
Field,
|
|
6
|
+
FieldActions,
|
|
7
|
+
FormSelectOption
|
|
8
|
+
} from "../../../types/common";
|
|
9
|
+
import Expand from "../../../util/expand";
|
|
10
|
+
|
|
11
|
+
export interface StateProvinceDropdownProps {
|
|
12
|
+
labelTextWhenNoError?: string;
|
|
13
|
+
errorMessages?: ErrorMessageDictionary;
|
|
14
|
+
field?: Field;
|
|
15
|
+
fieldActions?: FieldActions;
|
|
16
|
+
options?: FormSelectOption[];
|
|
17
|
+
showErrors?: boolean;
|
|
18
|
+
countryCode?: string;
|
|
19
|
+
autocompleteValue?: string;
|
|
20
|
+
dataQa?: string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
export const StateProvinceDropdown: React.FC<Expand<
|
|
24
|
+
StateProvinceDropdownProps
|
|
25
|
+
> &
|
|
26
|
+
React.HTMLAttributes<HTMLElement>>;
|
|
@@ -16,13 +16,15 @@ const AccountAndRoutingModal = ({
|
|
|
16
16
|
acceptText,
|
|
17
17
|
content,
|
|
18
18
|
imageType,
|
|
19
|
-
themeValues
|
|
19
|
+
themeValues,
|
|
20
|
+
dataQa = "AccountAndRoutingModal"
|
|
20
21
|
}) => (
|
|
21
22
|
<Modal
|
|
22
23
|
modalOpen={isOpen}
|
|
23
24
|
hideModal={() => toggleOpen(false)}
|
|
24
25
|
showModal={() => toggleOpen(true)}
|
|
25
26
|
modalHeaderText={title}
|
|
27
|
+
dataQa={dataQa}
|
|
26
28
|
modalBodyText={
|
|
27
29
|
<Box extraStyles="overflow: scroll; max-height: 20rem;">
|
|
28
30
|
<Stack>
|
|
@@ -50,6 +52,7 @@ const AccountAndRoutingModal = ({
|
|
|
50
52
|
}}
|
|
51
53
|
>
|
|
52
54
|
<Text
|
|
55
|
+
role="button"
|
|
53
56
|
variant="pS"
|
|
54
57
|
onClick={() => toggleOpen(true)}
|
|
55
58
|
onKeyPress={e => e.key === "Enter" && toggleOpen(true)}
|
|
@@ -4,7 +4,6 @@ import StateProvinceDropdown from "../../atoms/state-province-dropdown";
|
|
|
4
4
|
import Checkbox from "../../atoms/checkbox";
|
|
5
5
|
import CountryDropdown from "../../atoms/country-dropdown";
|
|
6
6
|
import { zipFormat } from "../../../util/formats";
|
|
7
|
-
import { noop } from "../../../util/general";
|
|
8
7
|
import {
|
|
9
8
|
FormInput,
|
|
10
9
|
FormContainer,
|
|
@@ -64,18 +63,17 @@ const AddressForm = ({
|
|
|
64
63
|
}
|
|
65
64
|
}}
|
|
66
65
|
showErrors={showErrors}
|
|
67
|
-
|
|
66
|
+
dataQa="Country"
|
|
68
67
|
/>
|
|
69
68
|
<FormInput
|
|
70
69
|
labelTextWhenNoError="Address"
|
|
71
70
|
errorMessages={street1ErrorMessages}
|
|
72
|
-
required={true}
|
|
73
71
|
field={fields.street1}
|
|
74
72
|
fieldActions={actions.fields.street1}
|
|
75
73
|
showErrors={showErrors}
|
|
76
74
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
77
|
-
|
|
78
|
-
|
|
75
|
+
autocompleteValue="address-line1"
|
|
76
|
+
dataQa="Address Line 1"
|
|
79
77
|
/>
|
|
80
78
|
<FormInput
|
|
81
79
|
labelTextWhenNoError="Apt, Suite, Unit, Floor, etc. (Optional)"
|
|
@@ -83,19 +81,18 @@ const AddressForm = ({
|
|
|
83
81
|
fieldActions={actions.fields.street2}
|
|
84
82
|
showErrors={showErrors}
|
|
85
83
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
86
|
-
|
|
87
|
-
|
|
84
|
+
autocompleteValue="address-line2"
|
|
85
|
+
dataQa="Address Line 2"
|
|
88
86
|
/>
|
|
89
87
|
<FormInput
|
|
90
88
|
labelTextWhenNoError="City"
|
|
91
|
-
required={true}
|
|
92
89
|
errorMessages={cityErrorMessages}
|
|
93
90
|
field={fields.city}
|
|
94
91
|
fieldActions={actions.fields.city}
|
|
95
92
|
showErrors={showErrors}
|
|
96
93
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
97
|
-
|
|
98
|
-
|
|
94
|
+
autocompleteValue="city"
|
|
95
|
+
dataQa="City"
|
|
99
96
|
/>
|
|
100
97
|
<StateProvinceDropdown
|
|
101
98
|
labelTextWhenNoError={isUS ? "State" : "State or Province"}
|
|
@@ -105,8 +102,8 @@ const AddressForm = ({
|
|
|
105
102
|
fieldActions={actions.fields.stateProvince}
|
|
106
103
|
showErrors={showErrors}
|
|
107
104
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
108
|
-
|
|
109
|
-
|
|
105
|
+
autocompleteValue="administrative-area"
|
|
106
|
+
dataQa="State or Province"
|
|
110
107
|
/>
|
|
111
108
|
<FormInput
|
|
112
109
|
isNum={isUS}
|
|
@@ -117,14 +114,13 @@ const AddressForm = ({
|
|
|
117
114
|
fieldActions={actions.fields.zip}
|
|
118
115
|
showErrors={showErrors}
|
|
119
116
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
required={true}
|
|
117
|
+
autocompleteValue="postal-code"
|
|
118
|
+
dataQa="Zip code"
|
|
123
119
|
/>
|
|
124
120
|
{showWalletCheckbox && (
|
|
125
121
|
<Checkbox
|
|
126
122
|
name="address checkbox"
|
|
127
|
-
title="Save address to
|
|
123
|
+
title="Save address to wallet"
|
|
128
124
|
checked={walletCheckboxMarked}
|
|
129
125
|
onChange={saveToWallet}
|
|
130
126
|
/>
|
|
@@ -91,7 +91,7 @@ const ChangePasswordForm = ({
|
|
|
91
91
|
showErrors={showErrors}
|
|
92
92
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
93
93
|
type="password"
|
|
94
|
-
|
|
94
|
+
autocompleteValue="current-password"
|
|
95
95
|
/>
|
|
96
96
|
<FormInput
|
|
97
97
|
labelTextWhenNoError="New password"
|
|
@@ -101,7 +101,7 @@ const ChangePasswordForm = ({
|
|
|
101
101
|
showErrors={showErrors}
|
|
102
102
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
103
103
|
type="password"
|
|
104
|
-
|
|
104
|
+
autocompleteValue="new-password"
|
|
105
105
|
/>
|
|
106
106
|
<FormInput
|
|
107
107
|
labelTextWhenNoError="Confirm password"
|
|
@@ -111,7 +111,7 @@ const ChangePasswordForm = ({
|
|
|
111
111
|
showErrors={showErrors}
|
|
112
112
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
113
113
|
type="password"
|
|
114
|
-
|
|
114
|
+
autocompleteValue="new-password"
|
|
115
115
|
/>
|
|
116
116
|
</FormInputColumn>
|
|
117
117
|
<Box padding={isMobile ? "1rem 0 0" : "1.5rem 0 0"}>
|
|
@@ -30,21 +30,23 @@ const EditNameForm = ({
|
|
|
30
30
|
<FormInputColumn>
|
|
31
31
|
<FormInput
|
|
32
32
|
labelTextWhenNoError="First Name"
|
|
33
|
+
dataQa="Edit First Name"
|
|
33
34
|
errorMessages={firstNameErrorMessages}
|
|
34
35
|
field={fields.firstName}
|
|
35
36
|
fieldActions={actions.fields.firstName}
|
|
36
37
|
showErrors={showErrors}
|
|
37
38
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
38
|
-
|
|
39
|
+
autocompleteValue="given-name"
|
|
39
40
|
/>
|
|
40
41
|
<FormInput
|
|
41
42
|
labelTextWhenNoError="Last Name"
|
|
43
|
+
dataQa="Edit Last Name"
|
|
42
44
|
errorMessages={lastNameErrorMessages}
|
|
43
45
|
field={fields.lastName}
|
|
44
46
|
fieldActions={actions.fields.lastName}
|
|
45
47
|
showErrors={showErrors}
|
|
46
48
|
onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
|
|
47
|
-
|
|
49
|
+
autocompleteValue="family-name"
|
|
48
50
|
/>
|
|
49
51
|
</FormInputColumn>
|
|
50
52
|
</FormContainer>
|