@thecb/components 8.4.11-beta.2 → 8.4.11-beta.21

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecb/components",
3
- "version": "8.4.11-beta.2",
3
+ "version": "8.4.11-beta.21",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "typings": "dist/index.d.ts",
@@ -92,6 +92,8 @@ const Alert = ({
92
92
  borderSize={noBorder ? "0px" : "1px"}
93
93
  boxShadow={enableBoxShadow ? generateShadows()?.inset?.base : ""}
94
94
  extraStyles={extraStyles}
95
+ role="alert"
96
+ aria-atomic={true}
95
97
  >
96
98
  {maxContentWidth ? (
97
99
  <Center maxWidth={maxContentWidth}>{content}</Center>
@@ -125,8 +125,6 @@ const Checkbox = ({
125
125
  checked={checked}
126
126
  onChange={onChange}
127
127
  tabIndex="-1"
128
- aria-invalid={error}
129
- aria-describedBy={error ? `${name}-error-message` : ""}
130
128
  />
131
129
  <StyledCheckbox
132
130
  error={error}
@@ -9,20 +9,18 @@ const CountryDropdown = ({
9
9
  field,
10
10
  fieldActions,
11
11
  showErrors,
12
- onChange,
13
- ...rest
12
+ onChange
14
13
  }) => (
15
14
  <FormSelect
16
15
  options={options}
17
16
  field={field}
18
17
  fieldActions={fieldActions}
19
18
  labelTextWhenNoError={labelTextWhenNoError}
19
+ dataQa={labelTextWhenNoError}
20
20
  errorMessages={errorMessages}
21
21
  showErrors={showErrors}
22
22
  onChange={onChange}
23
23
  autocompleteValue="country-name"
24
- autoComplete="country-name"
25
- {...rest}
26
24
  />
27
25
  );
28
26
  export default CountryDropdown;
@@ -26,6 +26,7 @@ const story = page({
26
26
  const CountryFormWrapper = ({ fields, actions }) => (
27
27
  <Box minHeight="300px">
28
28
  <CountryDropdown
29
+ labelTextWhenNoError="Country"
29
30
  errorMessages={errorMessages}
30
31
  options={options}
31
32
  field={fields.country}
@@ -287,7 +287,7 @@ const Dropdown = ({
287
287
  <Box
288
288
  as="input"
289
289
  aria-multiline="false"
290
- aria-autocomplete="list"
290
+ autoComplete={autocompleteValue}
291
291
  aria-controls={`${ariaLabelledby}_listbox`}
292
292
  aria-activedescendant="focused_option"
293
293
  aria-owns={`${ariaLabelledby}_listbox`}
@@ -295,10 +295,6 @@ const Dropdown = ({
295
295
  aria-labelledby={ariaLabelledby}
296
296
  aria-describedby={ariaDescribedby}
297
297
  aria-expanded={isOpen}
298
- aria-live="assertive"
299
- role="combobox"
300
- disabled={disabled}
301
- autoComplete={autocompleteValue}
302
298
  background={isOpen ? themeValues.hoverColor : WHITE}
303
299
  borderRadius="2px"
304
300
  borderSize="1px"
@@ -328,6 +324,7 @@ const Dropdown = ({
328
324
  }}
329
325
  padding="12px"
330
326
  placeholder={getSelection()}
327
+ role="combobox"
331
328
  themeValues={themeValues}
332
329
  title={hasTitles ? getSelection() : null}
333
330
  type="text"
@@ -335,6 +332,7 @@ const Dropdown = ({
335
332
  value={inputValue}
336
333
  width="100%"
337
334
  dataQa={placeholder}
335
+ required={options.required}
338
336
  />
339
337
  <IconWrapper open={isOpen} onClick={onClick}>
340
338
  <DropdownIcon />
@@ -367,7 +365,7 @@ const Dropdown = ({
367
365
  }
368
366
  key={choice.value}
369
367
  ref={optionRefs.current[i]}
370
- tabIndex={0}
368
+ tabIndex={-1}
371
369
  onClick={e => handleItemSelection(e, choice, i)}
372
370
  onKeyDown={e => {
373
371
  if (e.keyCode === 13) {
@@ -377,11 +375,12 @@ const Dropdown = ({
377
375
  selected={choice.value === value}
378
376
  aria-selected={choice.value === value}
379
377
  disabled={disabledValues.includes(choice.value)}
378
+ aria-disabled={disabledValues.includes(choice.value)}
380
379
  data-qa={choice.text}
381
380
  themeValues={themeValues}
382
381
  title={hasTitles ? choice.text : null}
383
- role="option"
384
382
  onFocus={() => setFocusedRef(optionRefs.current[i])}
383
+ role="option"
385
384
  >
386
385
  <Text
387
386
  variant="p"
@@ -393,14 +392,14 @@ const Dropdown = ({
393
392
  : MINESHAFT_GREY
394
393
  }
395
394
  extraStyles={`padding-left: 16px;
396
- cursor: ${
397
- disabledValues.includes(choice.value)
398
- ? "default"
399
- : "pointer"
400
- };
401
- white-space: nowrap;
402
- overflow: hidden;
403
- text-overflow: ellipsis;`}
395
+ cursor: ${
396
+ disabledValues.includes(choice.value)
397
+ ? "default"
398
+ : "pointer"
399
+ };
400
+ white-space: nowrap;
401
+ overflow: hidden;
402
+ text-overflow: ellipsis;`}
404
403
  >
405
404
  {choice.text}
406
405
  </Text>
@@ -162,10 +162,11 @@ const FormInput = ({
162
162
  variant="pS"
163
163
  fontWeight={themeValues.fontWeight}
164
164
  extraStyles={`word-break: break-word;
165
- font-family: Public Sans;
166
- &::first-letter {
167
- text-transform: uppercase;
168
- }`}
165
+ font-family: Public Sans;
166
+ &::first-letter {
167
+ text-transform: uppercase;
168
+ }
169
+ `}
169
170
  id={createIdFromString(labelTextWhenNoError)}
170
171
  >
171
172
  {labelTextWhenNoError}
@@ -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
  }
@@ -214,7 +216,7 @@ const FormInput = ({
214
216
  field={field}
215
217
  formatter={formatter}
216
218
  showErrors={showErrors}
217
- data-qa={labelTextWhenNoError}
219
+ dataQa={labelTextWhenNoError}
218
220
  themeValues={themeValues}
219
221
  $customHeight={customHeight}
220
222
  $extraStyles={extraStyles}
@@ -239,17 +241,22 @@ const FormInput = ({
239
241
  inputMode={isNum ? "numeric" : isEmail ? "email" : "text"}
240
242
  field={field}
241
243
  showErrors={showErrors}
242
- data-qa={labelTextWhenNoError}
244
+ dataQa={labelTextWhenNoError}
243
245
  themeValues={themeValues}
244
246
  background={background}
245
247
  $customHeight={customHeight}
246
248
  $extraStyles={extraStyles}
247
- autoComplete={autocomplete}
249
+ autocomplete={autocomplete}
248
250
  {...props}
249
251
  />
250
252
  )}
251
253
  </Box>
252
- <Stack direction="row" justify="space-between" role="alert">
254
+ <Stack
255
+ direction="row"
256
+ justify="space-between"
257
+ aria-live="polite"
258
+ aria-atomic={true}
259
+ >
253
260
  {(field.hasErrors && field.dirty) || (field.hasErrors && showErrors) ? (
254
261
  <Text
255
262
  color={ERROR_COLOR}
@@ -22,8 +22,7 @@ const FormSelect = ({
22
22
  themeValues,
23
23
  hasTitles = false,
24
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
- ...rest
25
+ smoothScroll = true // whether the browser should animate scroll to selected item on first open
27
26
  }) => {
28
27
  const [open, setOpen] = useState(false);
29
28
  const dropdownRef = useRef(null);
@@ -42,7 +41,11 @@ const FormSelect = ({
42
41
  });
43
42
 
44
43
  return (
45
- <SelectContainer ref={dropdownRef} disabled={disabled} {...rest}>
44
+ <SelectContainer
45
+ ref={dropdownRef}
46
+ disabled={disabled}
47
+ className="form-select-component"
48
+ >
46
49
  <Box padding="0" minWidth="100%">
47
50
  <Cluster justify="space-between" align="center">
48
51
  <Text
@@ -62,8 +65,9 @@ const FormSelect = ({
62
65
  </Cluster>
63
66
  </Box>
64
67
  <Dropdown
65
- aria-labelledBy={createIdFromString(labelTextWhenNoError)}
66
- aria-describedBy={createIdFromString(
68
+ data-qa={labelTextWhenNoError}
69
+ ariaLabelledby={createIdFromString(labelTextWhenNoError)}
70
+ aria-describedby={createIdFromString(
67
71
  labelTextWhenNoError,
68
72
  "error message"
69
73
  )}
@@ -77,27 +81,34 @@ const FormSelect = ({
77
81
  isError={
78
82
  (field.hasErrors && field.dirty) || (field.hasErrors && showErrors)
79
83
  }
84
+ aria-invalid={
85
+ (field.hasErrors && field.dirty) || (field.hasErrors && showErrors)
86
+ }
80
87
  onSelect={
81
88
  onChange ? value => onChange(value) : value => fieldActions.set(value)
82
89
  }
83
90
  onClick={() => setOpen(!open)}
91
+ disabled={disabled}
84
92
  aria-disabled={disabled}
85
93
  autocompleteValue={autocompleteValue}
86
94
  smoothScroll={smoothScroll}
87
95
  required={options.required}
88
96
  />
89
- <Stack direction="row" justify="space-between" aria-live="assertive">
97
+ <Stack direction="row" justify="space-between">
90
98
  <Text
91
99
  color={ERROR_COLOR}
92
100
  variant="pXS"
93
101
  weight={themeValues.fontWeight}
94
- extraStyles={`word-break: break-word;
102
+ extraStyles={`
103
+ word-break: break-word;
95
104
  font-family: Public Sans;
96
105
  &::first-letter {
97
106
  text-transform: uppercase;
98
- }`}
107
+ }
108
+ `}
99
109
  id={createIdFromString(labelTextWhenNoError, "error message")}
100
- aria-live="assertive"
110
+ aria-live="polite"
111
+ data-qa={labelTextWhenNoError}
101
112
  >
102
113
  {(field.hasErrors && field.dirty) || (field.hasErrors && showErrors)
103
114
  ? errorMessages[field.errors[0]]
@@ -17,12 +17,15 @@ const FormStateDropdown = ({
17
17
  const options = [placeholder, ...getOptions(countryCode)];
18
18
  return (
19
19
  <FormSelect
20
+ aria-live="polite"
21
+ aria-atomic={true}
20
22
  options={options}
21
23
  field={field}
22
24
  fieldActions={fieldActions}
23
25
  labelTextWhenNoError={labelTextWhenNoError}
24
26
  errorMessages={errorMessages}
25
27
  showErrors={showErrors}
28
+ aria-invalid={!!errorMessages?.length}
26
29
  autocompleteValue={autocomplete}
27
30
  />
28
31
  );
@@ -50,6 +50,7 @@ const AccountAndRoutingModal = ({
50
50
  }}
51
51
  >
52
52
  <Text
53
+ role="button"
53
54
  variant="pS"
54
55
  onClick={() => toggleOpen(true)}
55
56
  onKeyPress={e => e.key === "Enter" && toggleOpen(true)}
@@ -27,7 +27,7 @@ const AddressForm = ({
27
27
  }
28
28
 
29
29
  const street1ErrorMessages = {
30
- [required.error]: "Street is required"
30
+ [required.error]: "Street address is required"
31
31
  };
32
32
  const cityErrorMessages = {
33
33
  [required.error]: "City is required"
@@ -64,7 +64,6 @@ const AddressForm = ({
64
64
  }
65
65
  }}
66
66
  showErrors={showErrors}
67
- aria-label="country"
68
67
  />
69
68
  <FormInput
70
69
  labelTextWhenNoError="Address"
@@ -74,8 +73,8 @@ const AddressForm = ({
74
73
  fieldActions={actions.fields.street1}
75
74
  showErrors={showErrors}
76
75
  onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
77
- autoComplete="address-line1"
78
- aria-label="address line 1"
76
+ autocomplete="address-line1"
77
+ aria-label="Address Line 1"
79
78
  />
80
79
  <FormInput
81
80
  labelTextWhenNoError="Apt, Suite, Unit, Floor, etc. (Optional)"
@@ -83,8 +82,8 @@ const AddressForm = ({
83
82
  fieldActions={actions.fields.street2}
84
83
  showErrors={showErrors}
85
84
  onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
86
- autoComplete="address-line2"
87
- aria-label="address line 2"
85
+ autocomplete="address-line2"
86
+ aria-label="Address Line 2"
88
87
  />
89
88
  <FormInput
90
89
  labelTextWhenNoError="City"
@@ -94,8 +93,8 @@ const AddressForm = ({
94
93
  fieldActions={actions.fields.city}
95
94
  showErrors={showErrors}
96
95
  onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
97
- autoComplete="locality"
98
- aria-label="city"
96
+ autocomplete="city"
97
+ aria-label="City"
99
98
  />
100
99
  <StateProvinceDropdown
101
100
  labelTextWhenNoError={isUS ? "State" : "State or Province"}
@@ -105,9 +104,9 @@ const AddressForm = ({
105
104
  fieldActions={actions.fields.stateProvince}
106
105
  showErrors={showErrors}
107
106
  onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
108
- autoComplete="administrative-area"
109
- aria-label={isUS ? "state" : "state or province"}
107
+ aria-label={isUS ? "State" : "State or Province"}
110
108
  required={true}
109
+ autocomplete="administrative-area"
111
110
  />
112
111
  <FormInput
113
112
  isNum={isUS}
@@ -118,13 +117,14 @@ const AddressForm = ({
118
117
  fieldActions={actions.fields.zip}
119
118
  showErrors={showErrors}
120
119
  onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
121
- aria-label="zip code"
122
- autoComplete="postal-code"
120
+ aria-label="Zip code"
121
+ autocomplete="postal-code"
122
+ required={true}
123
123
  />
124
124
  {showWalletCheckbox && (
125
125
  <Checkbox
126
126
  name="address checkbox"
127
- title="Save address to Wallet"
127
+ title="Save address to wallet"
128
128
  checked={walletCheckboxMarked}
129
129
  onChange={saveToWallet}
130
130
  />
@@ -69,6 +69,7 @@ const PaymentFormACH = ({
69
69
  <FormInputColumn>
70
70
  <FormInput
71
71
  labelTextWhenNoError="Name on checking account"
72
+ data-qa={"Name on checking account"}
72
73
  errorMessages={nameErrors}
73
74
  field={fields.name}
74
75
  fieldActions={actions.fields.name}
@@ -78,6 +79,7 @@ const PaymentFormACH = ({
78
79
  />
79
80
  <FormInput
80
81
  labelTextWhenNoError="Routing number"
82
+ data-qa={"Routing number"}
81
83
  errorMessages={routingNumberErrors}
82
84
  field={fields.routingNumber}
83
85
  fieldActions={actions.fields.routingNumber}
@@ -87,8 +89,7 @@ const PaymentFormACH = ({
87
89
  <AccountAndRoutingModal
88
90
  link="What is this?"
89
91
  title="Where is my routing number?"
90
- content="Your routing number is the 9-digit number in the bottom left
91
- corner of your check."
92
+ content="Your routing number is the 9-digit number in the bottom left corner of your check."
92
93
  imageType="Routing"
93
94
  isOpen={showRouting}
94
95
  toggleOpen={toggleShowRouting}
@@ -98,6 +99,7 @@ const PaymentFormACH = ({
98
99
  />
99
100
  <FormInput
100
101
  labelTextWhenNoError="Confirm routing number"
102
+ data-qa={"Confirm routing number"}
101
103
  errorMessages={confirmRoutingNumberErrors}
102
104
  field={fields.confirmRoutingNumber}
103
105
  fieldActions={actions.fields.confirmRoutingNumber}
@@ -107,6 +109,7 @@ const PaymentFormACH = ({
107
109
  />
108
110
  <FormInput
109
111
  labelTextWhenNoError="Account number"
112
+ data-qa={"Account number"}
110
113
  errorMessages={accountNumberErrors}
111
114
  field={fields.accountNumber}
112
115
  fieldActions={actions.fields.accountNumber}
@@ -127,6 +130,7 @@ const PaymentFormACH = ({
127
130
  />
128
131
  <FormInput
129
132
  labelTextWhenNoError="Confirm account number"
133
+ data-qa={"Confirm account number"}
130
134
  errorMessages={confirmAccountNumberErrors}
131
135
  field={fields.confirmAccountNumber}
132
136
  fieldActions={actions.fields.confirmAccountNumber}
@@ -137,6 +141,7 @@ const PaymentFormACH = ({
137
141
  {allowBankAccountType && (
138
142
  <FormSelect
139
143
  labelTextWhenNoError="Account type"
144
+ data-qa={"Account type"}
140
145
  options={[
141
146
  { text: "Select account type", value: "" },
142
147
  { text: "Checking", value: "CHECKING" },
@@ -151,6 +156,7 @@ const PaymentFormACH = ({
151
156
  {!hideDefaultPayment && (
152
157
  <Checkbox
153
158
  title="Save as Default Payment Method"
159
+ data-qa={"default-payment-ach"}
154
160
  name="default-payment-ach"
155
161
  onChange={toggleCheckbox}
156
162
  checked={defaultMethod.value}
@@ -162,6 +168,7 @@ const PaymentFormACH = ({
162
168
  {showWalletCheckbox && (
163
169
  <Checkbox
164
170
  name="bank checkbox"
171
+ data-qa={"Save checking account to wallet"}
165
172
  title="Save checking account to wallet."
166
173
  checked={walletCheckboxMarked}
167
174
  onChange={saveToWallet}
@@ -113,6 +113,7 @@ const PaymentFormCard = ({
113
113
  )}
114
114
  <FormInput
115
115
  labelTextWhenNoError="Name on card"
116
+ data-qa={"Name on card"}
116
117
  errorMessages={nameOnCardErrors}
117
118
  field={fields.nameOnCard}
118
119
  fieldActions={actions.fields.nameOnCard}
@@ -122,6 +123,7 @@ const PaymentFormCard = ({
122
123
  />
123
124
  <FormInput
124
125
  labelTextWhenNoError="Credit card number"
126
+ data-qa={"Credit card number"}
125
127
  errorMessages={creditCardNumberErrors}
126
128
  field={fields.creditCardNumber}
127
129
  fieldActions={actions.fields.creditCardNumber}
@@ -137,6 +139,7 @@ const PaymentFormCard = ({
137
139
  >
138
140
  <FormInput
139
141
  labelTextWhenNoError="Expiration date (MM/YY)"
142
+ data-qa={"Expiration date"}
140
143
  errorMessages={expirationDateErrors}
141
144
  field={fields.expirationDate}
142
145
  fieldActions={actions.fields.expirationDate}
@@ -149,6 +152,7 @@ const PaymentFormCard = ({
149
152
  />
150
153
  <FormInput
151
154
  labelTextWhenNoError="CVV"
155
+ data-qa={"CVV"}
152
156
  errorMessages={cvvErrors}
153
157
  field={fields.cvv}
154
158
  fieldActions={actions.fields.cvv}
@@ -172,12 +176,13 @@ const PaymentFormCard = ({
172
176
  isNum={isUS}
173
177
  formatter={isUS ? zipFormat : null}
174
178
  labelTextWhenNoError="Zip code"
179
+ data-qa={"Zip code"}
175
180
  errorMessages={zipCodeErrors}
176
181
  field={fields.zipCode}
177
182
  fieldActions={actions.fields.zipCode}
178
183
  showErrors={showErrors}
179
184
  onKeyDown={e => e.key === "Enter" && handleSubmit(e)}
180
- autocomplete="billing postal-code"
185
+ autoComplete="billing postal-code"
181
186
  />
182
187
  </Box>
183
188
  )}
@@ -186,6 +191,7 @@ const PaymentFormCard = ({
186
191
  {showWalletCheckbox && (
187
192
  <Checkbox
188
193
  name="credit card checkbox"
194
+ data-qa={"Save credit card to wallet"}
189
195
  title="Save credit card to wallet."
190
196
  checked={walletCheckboxMarked}
191
197
  onChange={saveToWallet}
@@ -40,8 +40,8 @@ const PhoneForm = ({
40
40
  showErrors={showErrors}
41
41
  formatter={createFormat(phoneFormats, formatDelimiter)}
42
42
  onKeyUp={e => e.key === "Enter" && handleSubmit(e)}
43
- isNum
44
43
  autocomplete="tel"
44
+ isPhone={true}
45
45
  />
46
46
  {showWalletCheckbox && (
47
47
  <Checkbox
@@ -19,6 +19,7 @@ const TermsAndConditionsControlV1 = ({
19
19
  <Checkbox
20
20
  name="terms"
21
21
  title="Terms and Conditions"
22
+ dataQa="Terms and Conditions"
22
23
  error={error}
23
24
  checked={isChecked}
24
25
  onChange={onCheck}
@@ -78,15 +78,17 @@ const TermsAndConditionsControlV2 = ({
78
78
  />
79
79
  )}
80
80
  </Cluster>
81
- {showCheckbox && hasError && (
82
- <Text
83
- variant="pXS"
84
- color={ERROR_COLOR}
85
- id={`${id}-error-message`}
86
- >
87
- {errorMessage}
88
- </Text>
89
- )}
81
+ <div aria-live="polite" aria-atomic={true}>
82
+ {showCheckbox && hasError && (
83
+ <Text
84
+ variant="pXS"
85
+ color={ERROR_COLOR}
86
+ id={`${id}-error-message`}
87
+ >
88
+ {errorMessage}
89
+ </Text>
90
+ )}
91
+ </div>
90
92
  </Stack>
91
93
  </Cluster>
92
94
  </Stack>