@thecb/components 3.5.14 → 3.5.17

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.
Files changed (31) hide show
  1. package/.storybook/main.js +1 -1
  2. package/.storybook/page.js +2 -0
  3. package/.tool-versions +1 -0
  4. package/dist/index.cjs.js +116 -102
  5. package/package.json +2 -2
  6. package/src/components/atoms/breadcrumb/Breadcrumb.js +4 -1
  7. package/src/components/atoms/button-with-action/ButtonWithAction.js +2 -2
  8. package/src/components/atoms/checkbox/Checkbox.js +1 -0
  9. package/src/components/atoms/checkbox-list/CheckboxList.js +3 -1
  10. package/src/components/atoms/dropdown/Dropdown.js +4 -4
  11. package/src/components/atoms/dropdown/Dropdown.stories.js +10 -33
  12. package/src/components/atoms/form-layouts/FormInput.js +7 -4
  13. package/src/components/atoms/form-layouts/FormLayouts.stories.js +5 -5
  14. package/src/components/atoms/hamburger-button/HamburgerButton.js +4 -3
  15. package/src/components/atoms/icons/AccountsIconSmall.js +6 -13
  16. package/src/components/atoms/icons/icons.stories.js +1 -1
  17. package/src/components/atoms/layouts/Box.styled.js +1 -0
  18. package/src/components/atoms/layouts/Cluster.styled.js +5 -1
  19. package/src/components/atoms/layouts/Sidebar.styled.js +7 -1
  20. package/src/components/atoms/radio-button/RadioButton.js +1 -0
  21. package/src/components/atoms/radio-button/RadioButton.stories.js +26 -61
  22. package/src/components/atoms/toggle-switch/ToggleSwitch.js +1 -0
  23. package/src/components/atoms/toggle-switch/ToggleSwitch.stories.js +10 -51
  24. package/src/components/molecules/editable-list/EditableList.js +11 -8
  25. package/src/components/molecules/nav-menu/NavMenuDesktop.js +2 -1
  26. package/src/components/molecules/nav-menu/NavMenuMobile.js +7 -1
  27. package/src/deprecated/components/radio-button/radio-button.js +5 -1
  28. package/src/deprecated/icons/IconInvalid.js +7 -31
  29. package/src/deprecated/icons/IconNeutral.js +5 -4
  30. package/src/deprecated/icons/IconValid.js +8 -33
  31. package/src/util/general.js +10 -1
@@ -103,7 +103,7 @@ const ButtonWithAction = ({
103
103
  `;
104
104
  const disabledStyles = `
105
105
  background-clor: #6E727E;
106
- border-clor: #6E727E;
106
+ border-color: #6E727E;
107
107
  color: #FFFFFF;
108
108
  &:focus {
109
109
  box-shadow: 0 0 10px #6E727E;
@@ -123,7 +123,7 @@ const ButtonWithAction = ({
123
123
  activeStyles={activeStyles}
124
124
  disabledStyles={disabledStyles}
125
125
  as="button"
126
- onClick={action}
126
+ onClick={!isLoading && action}
127
127
  borderRadius="2px"
128
128
  theme={themeContext}
129
129
  extraStyles={isLoading ? loadingExtraStyles : extraStyles}
@@ -103,6 +103,7 @@ const Checkbox = ({
103
103
  id={`checkbox-${name}`}
104
104
  disabled={disabled}
105
105
  name={name}
106
+ aria-label={name}
106
107
  checked={checked}
107
108
  onChange={onChange}
108
109
  tabIndex="-1"
@@ -35,6 +35,7 @@ const CheckboxListItem = ({
35
35
  name,
36
36
  imageUrl,
37
37
  image,
38
+ imageAlt = "checkbox icon",
38
39
  disabled,
39
40
  borderColor,
40
41
  color,
@@ -57,6 +58,7 @@ const CheckboxListItem = ({
57
58
  <HiddenCheckboxInput id={`checkbox-${name}-${index}`} />
58
59
  <CheckboxLabel
59
60
  name={name}
61
+ aria-label={name}
60
62
  htmlFor={`checkbox-${name}-${index}`}
61
63
  onClick={disabled ? noop : onSelect}
62
64
  onKeyDown={disabled ? noop : onSelect}
@@ -73,7 +75,7 @@ const CheckboxListItem = ({
73
75
  </CheckboxLabel>
74
76
  <Box padding="0rem 0.5rem 0rem 0rem" hiddenStyles={!imageUrl}>
75
77
  <Cluster justify="flex-start" align="center">
76
- <CheckboxItemIcon src={imageUrl} />
78
+ <CheckboxItemIcon src={imageUrl} alt={imageAlt} />
77
79
  </Cluster>
78
80
  </Box>
79
81
  <Box padding="0rem 0.5rem 0rem 0rem" hiddenStyles={!image}>
@@ -44,7 +44,7 @@ const DropdownItemWrapper = styled.div`
44
44
  background-color: ${({ selected, themeValues }) =>
45
45
  selected ? themeValues.selectedColor : WHITE};
46
46
  text-align: start;
47
- border-size: 0px;
47
+ border-width: 0px;
48
48
  border-color: transparent;
49
49
  box-shadow: none;
50
50
  padding: 1rem;
@@ -200,7 +200,7 @@ const Dropdown = ({
200
200
  tabIndex={0}
201
201
  padding="0"
202
202
  width="100%"
203
- focusStyles={`background-color: ${themeValues.hoverColor};`}
203
+ hoverStyles={`background-color: ${themeValues.hoverColor};`}
204
204
  aria-expanded={isOpen}
205
205
  >
206
206
  <Box
@@ -209,7 +209,6 @@ const Dropdown = ({
209
209
  width="100%"
210
210
  padding="12px"
211
211
  hoverStyles={`background-color: ${themeValues.hoverColor};`}
212
- focusStyles={`background-color: ${themeValues.hoverColor};`}
213
212
  borderSize="1px"
214
213
  borderColor={
215
214
  isError
@@ -225,6 +224,7 @@ const Dropdown = ({
225
224
  <Stack direction="row" bottomItem={2}>
226
225
  {isOpen ? (
227
226
  <SearchInput
227
+ aria-label={inputValue || "Dropdown awaiting search value"}
228
228
  value={inputValue}
229
229
  onChange={noop}
230
230
  themeValues={themeValues}
@@ -242,7 +242,7 @@ const Dropdown = ({
242
242
  </Stack>
243
243
  </Box>
244
244
  {isOpen ? (
245
- <DropdownContentWrapper open={isOpen} ref={dropdownRef} tabIndex={-1}>
245
+ <DropdownContentWrapper open={isOpen} ref={dropdownRef} tabIndex={0}>
246
246
  <Stack childGap="0">
247
247
  {filteredOptions.map((choice, i) => (
248
248
  <DropdownItemWrapper
@@ -1,37 +1,6 @@
1
1
  import React, { useState, useEffect } from "react";
2
- import { withKnobs, text } from "@storybook/addon-knobs";
3
2
  import Dropdown from "./Dropdown";
4
- import { Cover, Center } from "../layouts";
5
- import { ThemeProvider } from "styled-components";
6
-
7
- const fakeTheme = {
8
- Dropdown: {
9
- selectedColor: "#15749D",
10
- hoverColor: "#EFFAFF"
11
- }
12
- };
13
-
14
- export default {
15
- title: "Dropdown",
16
- component: Dropdown,
17
- decorators: [
18
- withKnobs,
19
- storyFn => (
20
- <ThemeProvider
21
- theme={{
22
- name: text("Theme Name", "default"),
23
- values: fakeTheme
24
- }}
25
- >
26
- <Cover>
27
- <div />
28
- <Center>{storyFn()}</Center>
29
- <div />
30
- </Cover>
31
- </ThemeProvider>
32
- )
33
- ]
34
- };
3
+ import page from "../../../../.storybook/page";
35
4
 
36
5
  const options = [
37
6
  { text: "Please select an option", value: "" },
@@ -42,7 +11,7 @@ const options = [
42
11
 
43
12
  const disabledValues = ["DISABLED_OPTION"];
44
13
 
45
- export const dropdownDefault = () => {
14
+ export const dropdown = () => {
46
15
  const [isOpen, setOpen] = useState(false);
47
16
  const [value, setValue] = useState(null);
48
17
  const [isError, setError] = useState(false);
@@ -68,3 +37,11 @@ export const dropdownDefault = () => {
68
37
  />
69
38
  );
70
39
  };
40
+
41
+ const story = page({
42
+ title: "Components|Atoms/Dropdown",
43
+ Component: Dropdown,
44
+ height: "500px"
45
+ });
46
+
47
+ export default story;
@@ -46,7 +46,7 @@ const InputField = styled.input`
46
46
  `;
47
47
 
48
48
  // eslint-disable-next-line no-unused-vars
49
- const FormattedInputField = styled(({ showErrors, ...props }) => (
49
+ const FormattedInputField = styled(({ showErrors, themeValues, ...props }) => (
50
50
  <FormattedInput {...props} />
51
51
  ))`
52
52
  border: 1px solid
@@ -106,6 +106,7 @@ const FormInput = ({
106
106
  {helperModal ? (
107
107
  <Cluster justify="space-between" align="center">
108
108
  <Text
109
+ as="label"
109
110
  color={themeValues.labelColor}
110
111
  variant="pS"
111
112
  weight={themeValues.fontWeight}
@@ -114,6 +115,7 @@ const FormInput = ({
114
115
  &::first-letter {
115
116
  text-transform: uppercase;
116
117
  }`}
118
+ id={labelTextWhenNoError.replace(/\s+/g, "-")}
117
119
  >
118
120
  {labelTextWhenNoError}
119
121
  </Text>
@@ -129,6 +131,7 @@ const FormInput = ({
129
131
  <Box padding="0" minWidth="100%">
130
132
  <Cluster justify="space-between" align="center">
131
133
  <Text
134
+ as="label"
132
135
  color={themeValues.labelColor}
133
136
  variant="pS"
134
137
  fontWeight={themeValues.fontWeight}
@@ -137,7 +140,7 @@ const FormInput = ({
137
140
  &::first-letter {
138
141
  text-transform: uppercase;
139
142
  }`}
140
- id={labelTextWhenNoError}
143
+ id={labelTextWhenNoError.replace(/\s+/g, "-")}
141
144
  >
142
145
  {labelTextWhenNoError}
143
146
  </Text>
@@ -169,7 +172,7 @@ const FormInput = ({
169
172
  <Box padding="0">
170
173
  {formatter ? (
171
174
  <FormattedInputField
172
- aria-labelledby={labelTextWhenNoError}
175
+ aria-labelledby={labelTextWhenNoError.replace(/\s+/g, "-")}
173
176
  onChange={e => fieldActions.set(e)}
174
177
  type={type}
175
178
  value={field.rawValue}
@@ -186,7 +189,7 @@ const FormInput = ({
186
189
  />
187
190
  ) : (
188
191
  <InputField
189
- aria-labelledby={labelTextWhenNoError}
192
+ aria-labelledby={labelTextWhenNoError.replace(/\s+/g, "-")}
190
193
  onChange={e => fieldActions.set(e.target.value)}
191
194
  type={type === "password" && showPassword ? "text" : type}
192
195
  value={field.rawValue}
@@ -30,7 +30,7 @@ export const formLayouts = () => {
30
30
  >
31
31
  <FormInputRow childGap={text("rowChildGap", "1rem", "props")}>
32
32
  <FormInput
33
- labelTextWhenNoError="Form Layouts"
33
+ labelTextWhenNoError="Form Layouts 1"
34
34
  errorMessages="Error"
35
35
  field={data.test}
36
36
  />
@@ -38,24 +38,24 @@ export const formLayouts = () => {
38
38
  <FormInputRow childGap={text("rowChildGap", "1rem", "props")}>
39
39
  <FormInputColumn childGap={text("columnChildGap", "0.5rem", "props")}>
40
40
  <FormInput
41
- labelTextWhenNoError="Form Layouts"
41
+ labelTextWhenNoError="Form Layouts 2"
42
42
  errorMessages="Error"
43
43
  field={data.test}
44
44
  />
45
45
  <FormInput
46
- labelTextWhenNoError="Form Layouts"
46
+ labelTextWhenNoError="Form Layouts 3"
47
47
  errorMessages="Error"
48
48
  field={data.test}
49
49
  />
50
50
  </FormInputColumn>
51
51
  <FormInputColumn childGap={text("columnChildGap", "0.5rem", "props")}>
52
52
  <FormInput
53
- labelTextWhenNoError="Form Layouts"
53
+ labelTextWhenNoError="Form Layouts 4"
54
54
  errorMessages="Error"
55
55
  field={data.test}
56
56
  />
57
57
  <FormInput
58
- labelTextWhenNoError="Form Layouts"
58
+ labelTextWhenNoError="Form Layouts 5"
59
59
  errorMessages="Error"
60
60
  field={data.test}
61
61
  />
@@ -97,14 +97,15 @@ const HamburgerButton = ({
97
97
  activeColor,
98
98
  inactiveColor,
99
99
  isActive,
100
- onClick = noop
100
+ onClick = noop,
101
+ controls
101
102
  }) => (
102
103
  <Hamburger
103
104
  className={isActive === true ? "active" : ""}
104
105
  onClick={onClick}
105
106
  type="button"
106
- ariaLabel="Menu"
107
- ariaControls="navigation"
107
+ aria-label="Menu"
108
+ aria-controls={controls}
108
109
  >
109
110
  <HamburgerBox>
110
111
  <HamburgerInner
@@ -22,25 +22,18 @@ const AccountsIconSmall = ({ themeValues }) => {
22
22
  height="27"
23
23
  ></rect>
24
24
  </defs>
25
- <g
26
- id="Random-Icon-Work"
27
- stroke="none"
28
- strokeWidth="1"
29
- fill="none"
30
- fillRule="evenodd"
31
- >
32
- <g id="Header/Desktop/Menu">
33
- <g id="Header/Desktop/Menu/Accounts-Tab">
25
+ <g stroke="none" strokeWidth="1" fill="none" fillRule="evenodd">
26
+ <g>
27
+ <g>
34
28
  <g>
35
- <g id="Payments">
36
- <g id="folder-open">
29
+ <g>
30
+ <g>
37
31
  <mask id="mask-2-accountssmall" fill="white">
38
32
  <use xlinkHref="#path-1-accountssmall"></use>
39
33
  </mask>
40
- <g id="Mask"></g>
34
+ <g></g>
41
35
  <path
42
36
  d="M1.875,17.9609424 L4.30077547,13.8125148 C4.60546242,13.2968908 5.01561733,12.8867359 5.53124128,12.5820489 C6.04686523,12.277362 6.60936389,12.1250188 7.21873726,12.1250188 L7.21873726,12.1250188 L18.7499598,12.1250188 L18.7499598,10.4375228 C18.7499598,9.9687741 18.5858975,9.57033719 18.2577734,9.24221315 C17.9296494,8.91408911 17.5312125,8.75002682 17.0624638,8.75002682 L17.0624638,8.75002682 L11.4374772,8.75002682 L9.18748257,6.50003219 L3.56249598,6.50003219 C3.09374727,6.50003219 2.69531037,6.66409447 2.36718633,6.99221851 C2.03906229,7.32034255 1.875,7.71877946 1.875,8.18752816 L1.875,8.18752816 L1.875,17.9609424 Z M17.519494,20 C17.9179303,20 18.2929296,19.900391 18.6444913,19.7011726 C18.9960529,19.5019541 19.2655837,19.2265643 19.4530831,18.8750027 L19.4530831,18.8750027 L22.0194832,14.5156381 C22.1835455,14.2343887 22.1835455,13.9531394 22.0194832,13.6718901 C21.8554209,13.3906408 21.6093278,13.2500161 21.2812037,13.2500161 L21.2812037,13.2500161 L7.21873726,13.2500161 C6.82030089,13.2500161 6.4453016,13.3496251 6.09373994,13.5488435 C5.74217828,13.748062 5.47264749,14.0234517 5.28514812,14.3750134 L5.28514812,14.3750134 L2.71874799,18.734378 C2.5546857,19.0156273 2.5546857,19.2968767 2.71874799,19.578126 C2.88281028,19.8593753 3.12890344,20 3.45702748,20 L3.45702748,20 L17.519494,20 Z"
43
- id="f"
44
37
  fill={themeValues.singleIconColor}
45
38
  fillRule="nonzero"
46
39
  mask="url(#mask-2-accountssmall)"
@@ -48,5 +48,5 @@ export const routingNumberImage = () => <RoutingNumberImage />;
48
48
  export const checkmarkIcon = () => <CheckmarkIcon />;
49
49
  export const bankIcon = () => <BankIcon />;
50
50
  export const genericCard = () => <GenericCard />;
51
- export const paymentIco = () => <PaymentIcon />;
51
+ export const paymentIcon = () => <PaymentIcon />;
52
52
  export const autopayOnIcon = () => <AutopayOnIcon />;
@@ -26,6 +26,7 @@ export const BoxWrapper = styled(
26
26
  minWidth,
27
27
  maxWidth,
28
28
  padding,
29
+ hiddenStyles,
29
30
  ...props
30
31
  }) => <div {...props} />
31
32
  )`
@@ -1,6 +1,10 @@
1
+ import React from "react";
1
2
  import styled from "styled-components";
2
3
 
3
- export const ClusterWrapper = styled.div`
4
+ /* eslint-disable no-unused-vars */
5
+ export const ClusterWrapper = styled(({ overflow, ...props }) => (
6
+ <div {...props} />
7
+ ))`
4
8
  overflow: ${({ overflow }) => (overflow ? "visible" : "hidden")};
5
9
  box-sizing: border-box;
6
10
  `;
@@ -1,3 +1,4 @@
1
+ import React from "react";
1
2
  import styled from "styled-components";
2
3
 
3
4
  export const SidebarWrapper = styled.div`
@@ -7,7 +8,12 @@ export const SidebarWrapper = styled.div`
7
8
  ${({ fullHeight }) => (fullHeight ? `height: 100%;` : ``)}
8
9
  `;
9
10
 
10
- export const SidebarInnerWrapper = styled.div`
11
+ export const SidebarInnerWrapper = styled(
12
+ // eslint-disable-next-line no-unused-vars
13
+ ({ onRight, childGap, contentMinWidth, minHeight, fullHeight, ...props }) => (
14
+ <div {...props} />
15
+ )
16
+ )`
11
17
  display: flex;
12
18
  flex-wrap: wrap;
13
19
  box-sizing: border-box;
@@ -77,6 +77,7 @@ const RadioButton = ({
77
77
  >
78
78
  <HiddenRadioButton
79
79
  id={`#radio-${name}`}
80
+ aria-label={name}
80
81
  disabled={disabled}
81
82
  onClick={toggleRadio}
82
83
  tabIndex="-1"
@@ -1,69 +1,34 @@
1
1
  import React, { useState } from "react";
2
- import { withKnobs, text, radios } from "@storybook/addon-knobs";
2
+ import { boolean } from "@storybook/addon-knobs";
3
3
  import RadioButton from "./RadioButton";
4
- import { Box, Cover, Center } from "../layouts";
5
- import { ThemeProvider } from "styled-components";
6
-
7
- const fakeTheme = {
8
- RadioButton: {
9
- activeColor: "#15749D",
10
- inactiveColor: "#959CA8"
11
- }
12
- };
13
-
14
- export default {
15
- title: "Radio Button",
16
- component: RadioButton,
17
- decorators: [
18
- withKnobs,
19
- storyFn => (
20
- <ThemeProvider
21
- theme={{
22
- name: text("Theme Name", "default"),
23
- values: fakeTheme
24
- }}
25
- >
26
- <Cover>
27
- <div />
28
- <Center>{storyFn()}</Center>
29
- <div />
30
- </Cover>
31
- </ThemeProvider>
32
- )
33
- ]
34
- };
4
+ import { Box } from "../layouts";
5
+ import page from "../../../../.storybook/page";
35
6
 
36
7
  export const radioButtonsDefault = () => {
37
- const buttons = 3;
38
-
39
8
  const [selected, setSelected] = useState(null);
40
9
  const [focused, setFocused] = useState(null);
41
10
 
42
- return [...Array(buttons).keys()].map(i => {
43
- const name = `radio-button-${i}`;
44
- return (
45
- <Box
46
- key={name}
47
- onFocus={() => setFocused(name)}
48
- onBlur={() => setFocused(null)}
49
- extraStyles="outline: none;"
50
- tabIndex="0"
51
- >
52
- <RadioButton
53
- name={name}
54
- radioOn={selected === name}
55
- radioFocused={focused === name}
56
- toggleRadio={() => setSelected(name)}
57
- disabled={
58
- radios(
59
- "Disable Radio Buttons",
60
- { Enabled: "enabled", Disabled: "disabled" },
61
- "enabled",
62
- "RADIO-GROUP-1"
63
- ) === "disabled"
64
- }
65
- />
66
- </Box>
67
- );
68
- });
11
+ return (
12
+ <Box
13
+ onFocus={() => setFocused(name)}
14
+ onBlur={() => setFocused(null)}
15
+ extraStyles="outline: none;"
16
+ tabIndex="0"
17
+ >
18
+ <RadioButton
19
+ name="demo"
20
+ radioOn={selected === name}
21
+ radioFocused={focused === name}
22
+ toggleRadio={() => setSelected(name)}
23
+ disabled={boolean("disabled", false, "props")}
24
+ />
25
+ </Box>
26
+ );
69
27
  };
28
+
29
+ const story = page({
30
+ title: "Components|Atoms/RadioButton",
31
+ Component: RadioButton
32
+ });
33
+
34
+ export default story;
@@ -171,6 +171,7 @@ const ToggleSwitch = ({
171
171
  dataQa={dataQa}
172
172
  >
173
173
  <HiddenToggleSwitchBox
174
+ aria-label={name}
174
175
  checked={isOn}
175
176
  onChange={disabled ? noop : onToggle}
176
177
  disabled={disabled}
@@ -1,60 +1,12 @@
1
1
  import React, { useState, Fragment } from "react";
2
- import { withKnobs, text, radios } from "@storybook/addon-knobs";
2
+ import { boolean } from "@storybook/addon-knobs";
3
3
  import ToggleSwitch from "./ToggleSwitch";
4
- import { Cover, Center, Stack } from "../layouts";
5
- import { ThemeProvider } from "styled-components";
6
-
7
- const fakeTheme = {
8
- ToggleSwitch: {
9
- onBackground: "#15749D",
10
- disabledBackground: "#D5D8DC",
11
- white: "white",
12
- offBackground: "#959EA7",
13
- rightLabelStyles: `display: flex;
14
- justify-content: flex-start;
15
- align-items: center;
16
- flex-direction: row;`,
17
- leftLabelStyles: `display: flex;
18
- justify-content: flex-start;
19
- align-items: center;
20
- flex-direction: row-reverse;`
21
- }
22
- };
23
-
24
- export default {
25
- title: "Toggle Switch",
26
- component: ToggleSwitch,
27
- decorators: [
28
- withKnobs,
29
- storyFn => (
30
- <ThemeProvider
31
- theme={{
32
- name: text("Theme Name", "default"),
33
- values: fakeTheme
34
- }}
35
- >
36
- <Cover>
37
- <div />
38
- <Center>
39
- <Stack>{storyFn()}</Stack>
40
- </Center>
41
- <div />
42
- </Cover>
43
- </ThemeProvider>
44
- )
45
- ]
46
- };
4
+ import page from "../../../../.storybook/page";
47
5
 
48
6
  export const toggleSwitchDefault = () => {
49
7
  const [isOn, onToggle] = useState(false);
50
8
 
51
- const disabled =
52
- radios(
53
- "Disable Toggle Switch",
54
- { Enabled: "enabled", Disabled: "disabled" },
55
- "enabled",
56
- "RADIO-GROUP-1"
57
- ) === "disabled";
9
+ const disabled = boolean("disabled", false, "props");
58
10
 
59
11
  return (
60
12
  <Fragment>
@@ -68,3 +20,10 @@ export const toggleSwitchDefault = () => {
68
20
  </Fragment>
69
21
  );
70
22
  };
23
+
24
+ const story = page({
25
+ title: "Components|Atoms/ToggleSwitch",
26
+ Component: ToggleSwitch
27
+ });
28
+
29
+ export default story;
@@ -55,24 +55,25 @@ const EditableList = ({
55
55
  extraStyles={`box-shadow: 0px 2px 14px 0px rgb(246, 246, 249),
56
56
  0px 3px 8px 0px rgb(202, 206, 216);`}
57
57
  >
58
- {items.map(props => {
58
+ {items.map(item => {
59
59
  const [modalOpen, toggleModal] = useState(false);
60
60
  return (
61
61
  <EditableListItem
62
62
  listItemSize={
63
- !!props.id && props.id === autoPayMethod ? "big" : listItemSize
63
+ !!item.id && item.id === autoPayMethod ? "big" : listItemSize
64
64
  }
65
- key={props.id}
65
+ key={item.id || item}
66
66
  >
67
67
  <Text variant="p" color={CHARADE_GREY}>
68
- {renderItem(props)}
68
+ {renderItem(item)}
69
69
  </Text>
70
70
  <EditableListItemControls>
71
- {props.isPrimary && (
71
+ {item.isPrimary && (
72
72
  <Text
73
73
  variant="p"
74
74
  color={STORM_GREY}
75
75
  extraStyles={`font-style: italic;`}
76
+ key={`Default ${itemName}`}
76
77
  >
77
78
  Default {itemName}
78
79
  </Text>
@@ -83,10 +84,11 @@ const EditableList = ({
83
84
  border="2px solid transparent"
84
85
  extraStyles={`:not(:first-child) { border-left: 2px solid ${BOSTON_BLUE};}`}
85
86
  dataQa={qaPrefix + " Remove"}
87
+ key={`Remove ${item.id}`}
86
88
  >
87
89
  {useModal ? (
88
90
  <Modal
89
- item={{ ...props }}
91
+ item={{ ...item }}
90
92
  {...modalProps}
91
93
  modalOpen={modalOpen}
92
94
  toggleModal={toggleModal}
@@ -95,7 +97,7 @@ const EditableList = ({
95
97
  <ButtonWithAction
96
98
  variant="smallGhost"
97
99
  text="Remove"
98
- action={() => removeItem(props.id)}
100
+ action={() => removeItem(item.id)}
99
101
  extraStyles={`min-width: 0;`}
100
102
  />
101
103
  )}
@@ -107,11 +109,12 @@ const EditableList = ({
107
109
  border="2px solid transparent"
108
110
  extraStyles={`:not(:first-child) { border-left: 2px solid ${BOSTON_BLUE};}`}
109
111
  dataQa={qaPrefix + " Edit"}
112
+ key={`Edit ${item.id}`}
110
113
  >
111
114
  <ButtonWithAction
112
115
  variant="smallGhost"
113
116
  text="Edit"
114
- action={() => editItem(props.id)}
117
+ action={() => editItem(item.id)}
115
118
  extraStyles={`min-width: 0;`}
116
119
  />
117
120
  </Box>
@@ -4,6 +4,7 @@ import { fallbackValues } from "./NavMenu.theme.js";
4
4
  import { themeComponent } from "../../../util/themeUtils";
5
5
 
6
6
  const NavMenuDesktop = ({
7
+ id,
7
8
  top = "125%",
8
9
  left = "-100%",
9
10
  menuContent = [],
@@ -17,7 +18,7 @@ const NavMenuDesktop = ({
17
18
  const menuCarat = `&:after { bottom: 100%; right: 10px; border: solid transparent; content: " "; height: 0; width: 0; position: absolute; pointer-events: none; border-color: ${themeValues.backgroundColor}00; border-bottom-color: ${themeValues.backgroundColor}; border-width: 10px; margin-left: -10px; }`;
18
19
 
19
20
  return (
20
- <Imposter breakout top={top} left={left} visible={visible}>
21
+ <Imposter id={id} breakout top={top} left={left} visible={visible}>
21
22
  <Box
22
23
  minWidth="240px"
23
24
  padding="1rem 0.5rem"
@@ -42,9 +42,15 @@ const ImposterMenu = styled(menu)`
42
42
  top: 72px;
43
43
  `;
44
44
 
45
- const NavMenuMobile = ({ menuContent = [], visible = false, themeValues }) => {
45
+ const NavMenuMobile = ({
46
+ id,
47
+ menuContent = [],
48
+ visible = false,
49
+ themeValues
50
+ }) => {
46
51
  return (
47
52
  <ImposterMenu
53
+ id={id}
48
54
  initialPose="invisible"
49
55
  pose={visible ? "visible" : "invisible"}
50
56
  >
@@ -36,7 +36,11 @@ const RadioButtonCenter = styled.div`
36
36
  RadioButtonCenter.defaultProps = defaultTheme;
37
37
 
38
38
  const RadioButton = ({ isSelected, name }) => (
39
- <RadioButtonBorder isSelected={isSelected} name={name}>
39
+ <RadioButtonBorder
40
+ isSelected={isSelected}
41
+ name={name}
42
+ aria-checked={isSelected}
43
+ >
40
44
  {isSelected && <RadioButtonCenter />}
41
45
  </RadioButtonBorder>
42
46
  );