@thecb/components 2.2.1 → 3.1.1

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 (90) hide show
  1. package/.github/workflows/bump-version.yml +30 -0
  2. package/.github/workflows/create-release/build-body.sh +35 -0
  3. package/.github/workflows/create-release.yml +52 -0
  4. package/.github/workflows/disabled-workflows/publish-update.yml +73 -0
  5. package/README.md +68 -90
  6. package/dist/index.cjs.js +31180 -3325
  7. package/package.json +15 -35
  8. package/rollup.config.js +3 -1
  9. package/src/components/atoms/breadcrumb/Breadcrumb.js +0 -2
  10. package/src/components/atoms/button-with-action/ButtonWithAction.js +30 -4
  11. package/src/components/atoms/button-with-action/ButtonWithAction.theme.js +64 -234
  12. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.js +53 -0
  13. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.theme.js +9 -0
  14. package/src/components/atoms/formatted-credit-card/index.js +3 -0
  15. package/src/components/atoms/icons/AccountNumberImage.js +95 -0
  16. package/src/components/atoms/icons/BankIcon.js +82 -0
  17. package/src/components/atoms/icons/CheckmarkIcon.js +55 -0
  18. package/src/components/atoms/icons/GenericCard.js +39 -0
  19. package/src/components/atoms/icons/PaymentIcon.js +50 -0
  20. package/src/components/atoms/icons/RoutingNumberImage.js +95 -0
  21. package/src/components/atoms/icons/index.js +14 -1
  22. package/src/components/atoms/index.js +3 -0
  23. package/src/components/atoms/jumbo/Jumbo.js +76 -0
  24. package/src/components/atoms/jumbo/index.js +3 -0
  25. package/src/components/atoms/layouts/Box.js +0 -2
  26. package/src/components/atoms/layouts/Box.styled.js +1 -17
  27. package/src/components/atoms/layouts/Motion.styled.js +2 -5
  28. package/src/components/atoms/link/ExternalLink.js +3 -3
  29. package/src/components/atoms/link/ExternalLink.styled.js +9 -2
  30. package/src/components/atoms/link/InternalLink.js +2 -4
  31. package/src/components/atoms/link/InternalLink.styled.js +13 -15
  32. package/src/components/atoms/link/Link.theme.js +7 -1
  33. package/src/components/atoms/loading/Loading.js +17 -0
  34. package/src/components/atoms/loading/index.js +3 -0
  35. package/src/components/atoms/nav-header/NavHeader.js +1 -1
  36. package/src/components/atoms/placeholder/Placeholder.js +2 -1
  37. package/src/components/atoms/text/Text.js +0 -2
  38. package/src/components/atoms/text/Text.styled.js +2 -8
  39. package/src/components/atoms/toggle-switch/ToggleSwitch.js +1 -1
  40. package/src/components/index.js +1 -0
  41. package/src/components/molecules/account-and-routing-modal/AccountAndRoutingModal.js +74 -0
  42. package/src/components/molecules/account-and-routing-modal/AccountAndRoutingModal.theme.js +24 -0
  43. package/src/components/molecules/account-and-routing-modal/index.js +3 -0
  44. package/src/components/molecules/address-form/AddressForm.js +2 -1
  45. package/src/components/molecules/address-form/index.js +6 -6
  46. package/src/components/molecules/change-password-form/ChangePasswordForm.js +2 -1
  47. package/src/components/molecules/change-password-form/index.js +1 -1
  48. package/src/components/molecules/collapsible-section/CollapsibleSection.js +1 -1
  49. package/src/components/molecules/edit-name-form/EditNameForm.js +2 -1
  50. package/src/components/molecules/edit-name-form/index.js +1 -1
  51. package/src/components/molecules/editable-list/EditableList.js +139 -0
  52. package/src/components/molecules/editable-list/EditableList.styled.js +31 -0
  53. package/src/components/molecules/editable-list/index.js +3 -0
  54. package/src/components/molecules/editable-table/EditableTable.js +30 -0
  55. package/src/components/molecules/editable-table/EditableTable.styled.js +80 -0
  56. package/src/components/molecules/editable-table/TableListItem.js +64 -0
  57. package/src/components/molecules/editable-table/index.js +4 -0
  58. package/src/components/molecules/email-form/EmailForm.js +2 -1
  59. package/src/components/molecules/email-form/index.js +1 -1
  60. package/src/components/molecules/forgot-password-form/ForgotPasswordForm.js +2 -1
  61. package/src/components/molecules/forgot-password-form/index.js +1 -1
  62. package/src/components/molecules/index.js +5 -0
  63. package/src/components/molecules/login-form/LoginForm.js +2 -1
  64. package/src/components/molecules/login-form/index.js +1 -1
  65. package/src/components/molecules/module/Module.js +1 -3
  66. package/src/components/molecules/partial-amount-form/PartialAmountForm.js +73 -0
  67. package/src/components/molecules/partial-amount-form/PartialAmountForm.state.js +51 -0
  68. package/src/components/molecules/partial-amount-form/index.js +4 -0
  69. package/src/components/molecules/payment-form-ach/PaymentFormACH.js +189 -0
  70. package/src/components/molecules/payment-form-ach/PaymentFormACH.state.js +38 -0
  71. package/src/components/molecules/payment-form-ach/index.js +11 -0
  72. package/src/components/molecules/payment-form-card/PaymentFormCard.js +132 -0
  73. package/src/components/molecules/payment-form-card/PaymentFormCard.state.js +39 -0
  74. package/src/components/molecules/payment-form-card/index.js +11 -0
  75. package/src/components/molecules/phone-form/PhoneForm.js +2 -1
  76. package/src/components/molecules/phone-form/index.js +1 -1
  77. package/src/components/molecules/radio-section/RadioSection.js +1 -1
  78. package/src/components/molecules/registration-form/RegistrationForm.js +2 -1
  79. package/src/components/molecules/registration-form/index.js +1 -1
  80. package/src/components/molecules/reset-password-form/ResetPasswordForm.js +3 -1
  81. package/src/components/molecules/reset-password-form/index.js +1 -1
  82. package/src/components/molecules/tab-sidebar/TabSidebar.js +10 -5
  83. package/src/components/molecules/terms-and-conditions-modal/TermsAndConditionsModal.js +0 -1
  84. package/src/constants/index.js +4 -0
  85. package/src/index.js +3 -1
  86. package/src/util/formats.js +54 -2
  87. package/src/util/general.js +27 -4
  88. package/src/util/index.js +4 -0
  89. package/src/util/inputValidationUtils.js +0 -167
  90. package/src/util/router-utils.js +0 -23
@@ -23,7 +23,6 @@ const Box = ({
23
23
  border,
24
24
  textAlign,
25
25
  hoverStyles,
26
- focusStyles,
27
26
  activeStyles,
28
27
  disabledStyles,
29
28
  variant,
@@ -57,7 +56,6 @@ const Box = ({
57
56
  borderWidthOverride={borderWidthOverride}
58
57
  border={border}
59
58
  hoverStyles={hoverStyles}
60
- focusStyles={focusStyles}
61
59
  activeStyles={activeStyles}
62
60
  disabledStyles={disabledStyles}
63
61
  variant={variant}
@@ -13,7 +13,6 @@ import styled, { css } from "styled-components";
13
13
  export const BoxWrapper = styled(
14
14
  ({
15
15
  activeStyles,
16
- focusStyles,
17
16
  hoverStyles,
18
17
  disabledStyles,
19
18
  extraStyles,
@@ -48,7 +47,7 @@ export const BoxWrapper = styled(
48
47
  border: ${({ border }) => border};
49
48
  text-align: ${({ textAlign }) => textAlign};
50
49
 
51
- &:hover {
50
+ &:hover, &:focus {
52
51
  ${({ hoverStyles, as }) =>
53
52
  css`
54
53
  ${hoverStyles}
@@ -63,21 +62,6 @@ export const BoxWrapper = styled(
63
62
  `}
64
63
  }
65
64
 
66
- &:focus {
67
- ${({ focusStyles, as }) =>
68
- css`
69
- ${focusStyles}
70
- ${as === "button"
71
- ? `> * > span {
72
- ${focusStyles}
73
- border: none;
74
- outline: none;
75
- box-shadow: none;
76
- }`
77
- : ``}
78
- `}
79
- }
80
-
81
65
  &:active {
82
66
  ${({ activeStyles, as }) =>
83
67
  css`
@@ -21,7 +21,8 @@ export const MotionWrapper = styled(motion.div)`
21
21
  text-align: ${({ textAlign }) => textAlign};
22
22
  margin: ${({ margin }) => margin};
23
23
 
24
- &:hover {
24
+ &:hover,
25
+ &:focus {
25
26
  ${({ hoverStyles }) => hoverStyles};
26
27
  }
27
28
 
@@ -29,10 +30,6 @@ export const MotionWrapper = styled(motion.div)`
29
30
  ${({ activeStyles }) => activeStyles};
30
31
  }
31
32
 
32
- &:focus {
33
- ${({ focusStyles }) => focusStyles};
34
- }
35
-
36
33
  &:disabled {
37
34
  ${({ disabledStyles }) => disabledStyles};
38
35
  }
@@ -4,7 +4,7 @@ import { fallbackValues } from "./Link.theme";
4
4
  import { createThemeValues } from "../../../util/themeUtils";
5
5
  import { StyledExternalLink } from "./ExternalLink.styled";
6
6
  import { FONT_WEIGHT_REGULAR } from "../../../constants/style_constants";
7
- import { CONGRESS_BLUE, SCIENCE_BLUE } from "../../../constants/colors";
7
+ import { CONGRESS_BLUE } from "../../../constants/colors";
8
8
  import { safeChildren } from "../../../util/general";
9
9
 
10
10
  const ExternalLink = ({
@@ -14,7 +14,6 @@ const ExternalLink = ({
14
14
  size = "1rem",
15
15
  lineHeight = "1.5rem",
16
16
  weight = FONT_WEIGHT_REGULAR,
17
- hoverColor = SCIENCE_BLUE,
18
17
  extraStyles = ``,
19
18
  variant = "primary",
20
19
  tabIndex = "0",
@@ -36,7 +35,8 @@ const ExternalLink = ({
36
35
  size={size}
37
36
  lineheight={lineHeight}
38
37
  weight={weight}
39
- hovercolor={hoverColor}
38
+ hovercolor={themeValues.hoverColor}
39
+ activeColor={themeValues.activeColor}
40
40
  fontFamily={themeValues.fontFamily}
41
41
  tabIndex={tabIndex}
42
42
  extrastyles={extraStyles}
@@ -8,7 +8,7 @@ import styled from "styled-components";
8
8
 
9
9
  /* eslint-disable no-unused-vars */
10
10
  export const StyledExternalLink = styled(
11
- ({ hoverColor, extraStyles, ...props }) => <a {...props} />
11
+ ({ hoverColor, activeColor, extraStyles, ...props }) => <a {...props} />
12
12
  )`
13
13
  display: flex;
14
14
  font-size: ${({ size }) => size};
@@ -17,8 +17,15 @@ export const StyledExternalLink = styled(
17
17
  font-family: ${({ fontFamily }) => fontFamily};
18
18
  line-height: ${({ lineheight }) => lineheight};
19
19
 
20
- &:hover {
20
+ &:hover,
21
+ &:focus {
21
22
  color: ${({ hovercolor }) => hovercolor};
23
+ text-decoration: underline;
24
+ }
25
+
26
+ &:active {
27
+ text-decoration: underline;
28
+ color: ${({ activeColor }) => activeColor};
22
29
  }
23
30
 
24
31
  ${({ extrastyles }) => extrastyles}
@@ -9,14 +9,12 @@ const InternalLink = ({
9
9
  to = "",
10
10
  color,
11
11
  children,
12
- activeStyles,
13
12
  active,
14
13
  fontSize,
15
14
  lineheight,
16
15
  fontWeight,
17
16
  variant = "primary",
18
17
  margin,
19
- hoverStyles,
20
18
  tabIndex = "0",
21
19
  extraStyles = ``
22
20
  }) => {
@@ -33,13 +31,13 @@ const InternalLink = ({
33
31
  to={to}
34
32
  color={color}
35
33
  lineheight={lineheight}
36
- activeStyles={activeStyles}
37
34
  active={active}
38
35
  fontWeight={fontWeight}
39
36
  fontSize={fontSize}
40
37
  fontFamily={themeValues.fontFamily}
41
38
  margin={margin}
42
- hoverStyles={hoverStyles}
39
+ hoverColor={themeValues.hoverColor}
40
+ activeColor={themeValues.activeColor}
43
41
  tabIndex={tabIndex}
44
42
  extrastyles={extraStyles}
45
43
  >
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import styled, { css } from "styled-components";
2
+ import styled from "styled-components";
3
3
  import { Link } from "react-router-dom";
4
4
 
5
5
  /*
@@ -9,30 +9,28 @@ import { Link } from "react-router-dom";
9
9
 
10
10
  /* eslint-disable no-unused-vars */
11
11
  export const StyledInternalLink = styled(
12
- ({ hoverStyles, activeStyles, active, ...props }) => <Link {...props} />
12
+ ({ hoverColor, activeColor, active, ...props }) => <Link {...props} />
13
13
  )`
14
14
  display: flex;
15
- color: ${({ color }) => color};
15
+ color: ${({ color, active, activeColor }) =>
16
+ active === true ? activeColor : color};
16
17
  font-weight: ${({ fontWeight }) => fontWeight};
17
18
  line-height: ${({ lineheight }) => lineheight};
18
19
  font-size: ${({ fontSize }) => fontSize};
19
20
  font-family: ${({ fontFamily }) => fontFamily};
20
21
  margin: ${({ margin }) => margin};
22
+ text-decoration: ${({ active }) => (active === true ? "underline" : "none")};
21
23
 
22
- &:hover {
23
- ${({ hoverStyles }) =>
24
- css`
25
- ${hoverStyles}
26
- `}
24
+ &:hover,
25
+ &:focus {
26
+ color: ${({ hovercolor }) => hovercolor};
27
+ text-decoration: underline;
27
28
  }
28
29
 
29
- ${({ activeStyles, active }) =>
30
- active === "true" &&
31
- css`
32
- ${activeStyles}
33
- cursor: default;
34
- pointer-events: none;
35
- `}
30
+ &:active {
31
+ text-decoration: underline;
32
+ color: ${({ activeColor }) => activeColor};
33
+ }
36
34
 
37
35
  ${({ extrastyles }) => extrastyles}
38
36
  `;
@@ -3,6 +3,12 @@ const fontFamily = {
3
3
  secondary: "Open Sans"
4
4
  };
5
5
 
6
+ const hoverColor = "#116285";
7
+
8
+ const activeColor = "#0E506D";
9
+
6
10
  export const fallbackValues = {
7
- fontFamily
11
+ fontFamily,
12
+ hoverColor,
13
+ activeColor
8
14
  };
@@ -0,0 +1,17 @@
1
+ import React from "react";
2
+ import Spinner from "../spinner";
3
+ import { Box, Cover, Center } from "../layouts";
4
+
5
+ const Loading = () => (
6
+ <Box key="spinner-container">
7
+ <Cover minHeight="100%" singleChild>
8
+ <Center intrinsic>
9
+ <Box>
10
+ <Spinner size="100" />
11
+ </Box>
12
+ </Center>
13
+ </Cover>
14
+ </Box>
15
+ );
16
+
17
+ export default Loading;
@@ -0,0 +1,3 @@
1
+ import Loading from "./Loading";
2
+
3
+ export default Loading;
@@ -10,7 +10,7 @@ const NavHeader = ({
10
10
  ...rest
11
11
  }) => (
12
12
  <Box
13
- padding="0 1rem 0.25rem 1rem"
13
+ padding="0 16px 4px"
14
14
  background={backgroundColor}
15
15
  extraStyles={
16
16
  isMobile
@@ -6,7 +6,7 @@ import { Box, Switcher, Center, Cluster } from "../layouts";
6
6
  import { fallbackValues } from "./Placeholder.theme";
7
7
  import { themeComponent } from "../../../util/themeUtils";
8
8
  import { IconAdd } from "../../../deprecated/icons";
9
- import { STORM_GREY } from "../../../constants/colors";
9
+ import { STORM_GREY, GRECIAN_GREY } from "../../../constants/colors";
10
10
  import { AccountsAddIcon, PropertiesAddIcon } from "../icons";
11
11
  import { FONT_WEIGHT_REGULAR } from "../../../constants/style_constants";
12
12
  import withWindowSize from "../../withWindowSize";
@@ -72,6 +72,7 @@ const Placeholder = ({
72
72
  display: flex;
73
73
  justify-content: center;
74
74
  align-items:center;`}
75
+ hoverStyles={`background-color: ${GRECIAN_GREY};`}
75
76
  >
76
77
  <PlaceholderContentWrapper
77
78
  isLink={isLink}
@@ -12,7 +12,6 @@ const Text = ({
12
12
  color = FIREFLY_GREY,
13
13
  extraStyles = ``,
14
14
  hoverStyles,
15
- focusStyles,
16
15
  onClick,
17
16
  dataQa,
18
17
  children,
@@ -25,7 +24,6 @@ const Text = ({
25
24
  fontFamily={themeValues.fontFamily}
26
25
  extraStyles={extraStyles}
27
26
  hoverStyles={hoverStyles}
28
- focusStyles={focusStyles}
29
27
  onClick={onClick}
30
28
  data-qa={dataQa}
31
29
  {...rest}
@@ -8,20 +8,14 @@ export const TextSpan = styled.span`
8
8
  font-family: ${({ fontFamily }) => fontFamily};
9
9
  color: ${({ color }) => color};
10
10
 
11
- &:hover {
11
+ &:hover,
12
+ &:focus {
12
13
  ${({ hoverStyles }) =>
13
14
  css`
14
15
  ${hoverStyles}
15
16
  `}
16
17
  }
17
18
 
18
- &:focus {
19
- ${({ focusStyles }) =>
20
- css`
21
- ${focusStyles}
22
- `}
23
- }
24
-
25
19
  ${({ disabled, disabledStyles }) =>
26
20
  disabled &&
27
21
  css`
@@ -159,7 +159,7 @@ const ToggleSwitch = ({
159
159
  extraStyles={
160
160
  labelLeft ? themeValues.leftLabelStyles : themeValues.rightLabelStyles
161
161
  }
162
- focusStyles={`outline: ${themeValues.onBackground} auto 5px`}
162
+ hoverStyles={`outline: ${themeValues.onBackground} auto 5px`}
163
163
  >
164
164
  <Center>
165
165
  <Cluster justify="stretch" align="center">
@@ -1,3 +1,4 @@
1
1
  export * from "./atoms";
2
2
  export * from "./molecules";
3
3
  export * from "./templates";
4
+ export { default as withWindowSize } from "./withWindowSize";
@@ -0,0 +1,74 @@
1
+ import React, { Fragment } from "react";
2
+ import Modal from "../modal";
3
+ import Text from "../../atoms/text";
4
+ import Paragraph from "../../atoms/paragraph";
5
+ import { Box, Stack, Center } from "../../atoms/layouts";
6
+ import { fallbackValues } from "./AccountAndRoutingModal.theme";
7
+ import { themeComponent } from "../../../util/themeUtils";
8
+ import { AccountNumberImage, RoutingNumberImage } from "../../atoms/icons";
9
+
10
+ const AccountAndRoutingModal = ({
11
+ link,
12
+ title,
13
+ isOpen,
14
+ toggleOpen,
15
+ toggleAccepted,
16
+ acceptText,
17
+ content,
18
+ imageType,
19
+ variant,
20
+ themeValues
21
+ }) => (
22
+ <Modal
23
+ ModalLink={() => (
24
+ <Text
25
+ variant={variant === "default" ? "pS" : "pXS"}
26
+ onClick={() => toggleOpen(true)}
27
+ color={themeValues.linkColor}
28
+ weight={themeValues.fontWeight}
29
+ hoverStyles={themeValues.modalLinkHoverFocus}
30
+ extraStyles={`cursor: pointer;`}
31
+ tabIndex="0"
32
+ onKeyPress={e => e.key === "Enter" && toggleOpen(true)}
33
+ >
34
+ {link}
35
+ </Text>
36
+ )}
37
+ modalOpen={isOpen}
38
+ hideModal={() => toggleOpen(false)}
39
+ showModal={() => toggleOpen(true)}
40
+ modalHeaderText={title}
41
+ modalBodyText={
42
+ <Box extraStyles="overflow: scroll; max-height: 20rem;">
43
+ <Stack>
44
+ <Paragraph variant="p">{content}</Paragraph>
45
+ {imageType === "Account" ? (
46
+ <Center intrinsic>
47
+ <AccountNumberImage />
48
+ </Center>
49
+ ) : imageType === "Routing" ? (
50
+ <Center intrinsic>
51
+ <RoutingNumberImage />
52
+ </Center>
53
+ ) : (
54
+ <Fragment />
55
+ )}
56
+ </Stack>
57
+ </Box>
58
+ }
59
+ defaultWrapper={false}
60
+ onlyCloseButton={!acceptText}
61
+ continueButtonText={acceptText}
62
+ continueAction={() => {
63
+ toggleAccepted(true);
64
+ toggleOpen(false);
65
+ }}
66
+ />
67
+ );
68
+
69
+ export default themeComponent(
70
+ AccountAndRoutingModal,
71
+ "AccountAndRoutingModal",
72
+ fallbackValues,
73
+ "default"
74
+ );
@@ -0,0 +1,24 @@
1
+ import {
2
+ FONT_WEIGHT_REGULAR,
3
+ FONT_WEIGHT_SEMIBOLD
4
+ } from "../../../constants/style_constants";
5
+
6
+ const linkColor = { default: "#357fb8", footer: "#ffffff" };
7
+ const fontSize = { default: "1rem", footer: "0.875rem" };
8
+ const lineHeight = { default: "1.5rem", footer: "1.25rem" };
9
+ const fontWeight = {
10
+ default: FONT_WEIGHT_REGULAR,
11
+ footer: FONT_WEIGHT_SEMIBOLD
12
+ };
13
+ const modalLinkHoverFocus = {
14
+ default: ``,
15
+ footer: `outline: none; text-decoration: underline;`
16
+ };
17
+
18
+ export const fallbackValues = {
19
+ linkColor,
20
+ fontSize,
21
+ lineHeight,
22
+ fontWeight,
23
+ modalLinkHoverFocus
24
+ };
@@ -0,0 +1,3 @@
1
+ import AccountAndRoutingModal from "./AccountAndRoutingModal";
2
+
3
+ export default AccountAndRoutingModal;
@@ -3,6 +3,7 @@ import { required, hasLength } from "redux-freeform";
3
3
  import StateProvinceDropdown from "../../atoms/state-province-dropdown";
4
4
  // import CountryDropdown from "../../atoms/country-dropdown";
5
5
  import { zipFormat } from "../../../util/formats";
6
+ import { noop } from "../../../util/general";
6
7
  import {
7
8
  FormInput,
8
9
  FormContainer,
@@ -15,7 +16,7 @@ const AddressForm = ({
15
16
  actions,
16
17
  clearOnDismount,
17
18
  showErrors,
18
- handleSubmit
19
+ handleSubmit = noop
19
20
  }) => {
20
21
  if (clearOnDismount) {
21
22
  useEffect(() => () => actions.form.clear(), []);
@@ -1,11 +1,11 @@
1
- import AddressFrom from "./AddressForm";
1
+ import AddressForm from "./AddressForm";
2
2
  import {
3
3
  reducer,
4
4
  mapStateToProps,
5
- mapDispatchToProps,
5
+ mapDispatchToProps
6
6
  } from "./AddressForm.state";
7
7
 
8
- AddressFrom.reducer = reducer;
9
- AddressFrom.mapStateToProps = mapStateToProps;
10
- AddressFrom.mapDispatchToProps = mapDispatchToProps;
11
- export default AddressFrom;
8
+ AddressForm.reducer = reducer;
9
+ AddressForm.mapStateToProps = mapStateToProps;
10
+ AddressForm.mapDispatchToProps = mapDispatchToProps;
11
+ export default AddressForm;
@@ -15,12 +15,13 @@ import {
15
15
  } from "../../atoms/form-layouts";
16
16
  import { Box, Cluster } from "../../atoms/layouts";
17
17
  import PasswordRequirements from "../../atoms/password-requirements";
18
+ import { noop } from "../../../util/general";
18
19
 
19
20
  const ChangePasswordForm = ({
20
21
  clearOnDismount,
21
22
  fields,
22
23
  actions,
23
- handleSubmit,
24
+ handleSubmit = noop,
24
25
  showErrors,
25
26
  isMobile
26
27
  }) => {
@@ -2,7 +2,7 @@ import ChangePasswordForm from "./ChangePasswordForm";
2
2
  import {
3
3
  reducer,
4
4
  mapStateToProps,
5
- mapDispatchToProps,
5
+ mapDispatchToProps
6
6
  } from "./ChangePasswordForm.state";
7
7
 
8
8
  ChangePasswordForm.reducer = reducer;
@@ -63,7 +63,7 @@ const CollapsibleSection = ({
63
63
  padding="0"
64
64
  tabIndex="0"
65
65
  onKeyDown={handleKeyDown}
66
- focusStyles={themeValues.focusStyles}
66
+ hoverStyles={themeValues.focusStyles}
67
67
  animate={isOpen ? "open" : "closed"}
68
68
  positionTransition
69
69
  >
@@ -5,13 +5,14 @@ import {
5
5
  FormContainer,
6
6
  FormInputColumn
7
7
  } from "../../atoms/form-layouts";
8
+ import { noop } from "../../../util/general";
8
9
 
9
10
  const EditNameForm = ({
10
11
  fields,
11
12
  actions,
12
13
  clearOnDismount,
13
14
  showErrors,
14
- handleSubmit
15
+ handleSubmit = noop
15
16
  }) => {
16
17
  if (clearOnDismount) {
17
18
  useEffect(() => () => actions.form.clear(), []);
@@ -2,7 +2,7 @@ import EditNameForm from "./EditNameForm";
2
2
  import {
3
3
  reducer,
4
4
  mapStateToProps,
5
- mapDispatchToProps,
5
+ mapDispatchToProps
6
6
  } from "./EditNameForm.state";
7
7
 
8
8
  EditNameForm.reducer = reducer;
@@ -0,0 +1,139 @@
1
+ import React, { useState } from "react";
2
+
3
+ import {
4
+ EditableListItem,
5
+ EditableListItemControls
6
+ } from "./EditableList.styled";
7
+ import { Box, Stack } from "../../atoms/layouts";
8
+ import Placeholder from "../../atoms/placeholder";
9
+ import ButtonWithAction from "../../atoms/button-with-action";
10
+ import Text from "../../atoms/text";
11
+ import Paragraph from "../../atoms/paragraph";
12
+ import {
13
+ STORM_GREY,
14
+ BOSTON_BLUE,
15
+ CHARADE_GREY
16
+ } from "../../../constants/colors";
17
+
18
+ const EditableList = ({
19
+ title = "",
20
+ titleWeight = "400",
21
+ addItem,
22
+ removeItem,
23
+ editItem,
24
+ itemName,
25
+ renderItem,
26
+ items,
27
+ canEdit = true,
28
+ canRemove = true,
29
+ listItemSize = "small",
30
+ maxItems,
31
+ useModal = false,
32
+ modal: Modal,
33
+ modalProps,
34
+ autoPayMethod,
35
+ qaPrefix
36
+ }) => (
37
+ <Box padding="0rem 0rem 1.5rem 0rem">
38
+ <Stack childGap="0rem">
39
+ {title !== "" && (
40
+ <Box padding="0rem 0rem 0.5rem 0rem">
41
+ <Paragraph
42
+ variant="pL"
43
+ weight={titleWeight}
44
+ color={CHARADE_GREY}
45
+ extraStyles="letter-spacing: 0.29px;"
46
+ aria-level="3"
47
+ >
48
+ {title}
49
+ </Paragraph>
50
+ </Box>
51
+ )}
52
+ <Box
53
+ padding="0"
54
+ borderRadius="4px"
55
+ extraStyles={`box-shadow: 0px 2px 14px 0px rgb(246, 246, 249),
56
+ 0px 3px 8px 0px rgb(202, 206, 216);`}
57
+ >
58
+ {items.map(props => {
59
+ const [modalOpen, toggleModal] = useState(false);
60
+ return (
61
+ <EditableListItem
62
+ listItemSize={
63
+ !!props.id && props.id === autoPayMethod ? "big" : listItemSize
64
+ }
65
+ key={props.id}
66
+ >
67
+ <Text variant="p" color={CHARADE_GREY}>
68
+ {renderItem(props)}
69
+ </Text>
70
+ <EditableListItemControls>
71
+ {props.isPrimary && (
72
+ <Text
73
+ variant="p"
74
+ color={STORM_GREY}
75
+ extraStyles={`font-style: italic;`}
76
+ >
77
+ Default {itemName}
78
+ </Text>
79
+ )}
80
+ {canRemove && (
81
+ <Box
82
+ padding="0 0.5rem"
83
+ border="2px solid transparent"
84
+ extraStyles={`:not(:first-child) { border-left: 2px solid ${BOSTON_BLUE};}`}
85
+ dataQa={qaPrefix + " Remove"}
86
+ >
87
+ {useModal ? (
88
+ <Modal
89
+ item={{ ...props }}
90
+ {...modalProps}
91
+ modalOpen={modalOpen}
92
+ toggleModal={toggleModal}
93
+ />
94
+ ) : (
95
+ <ButtonWithAction
96
+ variant="smallGhost"
97
+ text="Remove"
98
+ action={() => removeItem(props.id)}
99
+ extraStyles={`min-width: 0;`}
100
+ />
101
+ )}
102
+ </Box>
103
+ )}
104
+ {canEdit && (
105
+ <Box
106
+ padding="0 0.5rem"
107
+ border="2px solid transparent"
108
+ extraStyles={`:not(:first-child) { border-left: 2px solid ${BOSTON_BLUE};}`}
109
+ dataQa={qaPrefix + " Edit"}
110
+ >
111
+ <ButtonWithAction
112
+ variant="smallGhost"
113
+ text="Edit"
114
+ action={() => editItem(props.id)}
115
+ extraStyles={`min-width: 0;`}
116
+ />
117
+ </Box>
118
+ )}
119
+ </EditableListItemControls>
120
+ </EditableListItem>
121
+ );
122
+ })}
123
+ </Box>
124
+ {(!maxItems || items.length < maxItems) && (
125
+ <Box padding={items.length === 0 ? "0" : "1rem 0 0"}>
126
+ <Placeholder
127
+ text={`Add a${
128
+ itemName[0].match(/[aieouAIEOU]/) ? "n" : ""
129
+ } ${itemName}`}
130
+ action={addItem}
131
+ dataQa={"Add " + qaPrefix}
132
+ />
133
+ </Box>
134
+ )}
135
+ </Stack>
136
+ </Box>
137
+ );
138
+
139
+ export default EditableList;