@thecb/components 10.5.0-beta.5 → 10.5.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecb/components",
3
- "version": "10.5.0-beta.5",
3
+ "version": "10.5.0",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "typings": "dist/index.d.ts",
@@ -9,7 +9,6 @@ const IconQuitLarge = ({ fill = "#091325" }) => (
9
9
  xmlns="http://www.w3.org/2000/svg"
10
10
  xmlnsXlink="http://www.w3.org/1999/xlink"
11
11
  >
12
- <title>Icon/X</title>
13
12
  <defs>
14
13
  <polygon
15
14
  id="quit-large-path-1"
@@ -68,9 +68,9 @@ export const modalV2 = () => (
68
68
  defaultWrapper={boolean("defaultWrapper", true, groupId)}
69
69
  hideModal={noop}
70
70
  maxHeight={text("maxHeight", "", groupId)}
71
- modalBodyBg={text("modalBodyBg", "#F6F6F9", groupId)}
71
+ modalBodyBg={text("modalBodyBg", "", groupId)}
72
72
  modalBodyText={text("modalBodyText", "Modal Body Text", groupId)}
73
- modalHeaderBg={text("modalHeaderBg", "white", groupId)}
73
+ modalHeaderBg={text("modalHeaderBg", "", groupId)}
74
74
  modalHeaderText={text("modalHeaderText", "Modal Header Text", groupId)}
75
75
  modalOpen={boolean("modalOpen", true, groupId)}
76
76
  noButtons={boolean("noButtons", false, groupId)}
@@ -3,11 +3,11 @@ import AriaModal from "react-aria-modal";
3
3
  import { ThemeContext } from "styled-components";
4
4
  import { WHITE, ATHENS_GREY, SILVER_GREY } from "../../../constants/colors";
5
5
  import {
6
+ BORDER_RADIUS,
6
7
  BORDER_THIN,
7
- CORNER_STANDARD,
8
+ FONT_SIZE,
8
9
  FONT_WEIGHT_SEMIBOLD,
9
- SPACING_NORMAL,
10
- SPACING_XS
10
+ SPACING
11
11
  } from "../../../constants/style_constants";
12
12
  import { noop } from "../../../util/general";
13
13
  import Paragraph from "../../atoms/paragraph";
@@ -51,9 +51,9 @@ const Modal = ({
51
51
  isContinueActionDisabled = false,
52
52
  isLoading = false,
53
53
  maxHeight = "",
54
- modalBodyBg = ATHENS_GREY,
54
+ modalBodyBg = "",
55
55
  modalBodyText = "",
56
- modalHeaderBg = WHITE,
56
+ modalHeaderBg = "",
57
57
  modalHeaderText = "",
58
58
  modalOpen = false,
59
59
  noButtons = false, // for instances where modal is closed automatically
@@ -105,8 +105,8 @@ const Modal = ({
105
105
  WebkitBackdropFilter: blurUnderlay ? "blur(4px)" : "none"
106
106
  }}
107
107
  dialogStyle={{
108
- borderRadius: CORNER_STANDARD,
109
- margin: SPACING_XS,
108
+ borderRadius: BORDER_RADIUS.MD,
109
+ margin: SPACING.XS,
110
110
  overflow: "auto",
111
111
  width: isMobile ? "" : customWidth || "615px"
112
112
  }}
@@ -117,20 +117,24 @@ const Modal = ({
117
117
  >
118
118
  <Box padding="0" boxShadow="inset 0px -2px 0px 0px rgb(0, 80, 149)">
119
119
  <Box
120
- background={modalHeaderBg}
120
+ background={modalHeaderBg || WHITE}
121
121
  borderColor={SILVER_GREY}
122
122
  borderWidthOverride={`0 0 ${BORDER_THIN} 0`}
123
- padding={`${SPACING_XS} ${SPACING_NORMAL}`}
123
+ padding={`${SPACING.XS} ${SPACING.MD}`}
124
124
  >
125
125
  <Cluster justify="flex-start" align="center">
126
- <Title as="h2" weight={FONT_WEIGHT_SEMIBOLD} fontSize="1.25rem">
126
+ <Title
127
+ as="h2"
128
+ weight={FONT_WEIGHT_SEMIBOLD}
129
+ fontSize={isMobile ? FONT_SIZE.MD : FONT_SIZE.LG}
130
+ >
127
131
  {modalHeaderText}
128
132
  </Title>
129
133
  </Cluster>
130
134
  </Box>
131
- <Box background={modalBodyBg} padding="0">
135
+ <Box background={modalBodyBg || ATHENS_GREY} padding="0">
132
136
  <Box
133
- padding={SPACING_NORMAL}
137
+ padding={SPACING.MD}
134
138
  borderWidthOverride={!noButtons && `0 0 ${BORDER_THIN} 0`}
135
139
  borderColor={!noButtons && SILVER_GREY}
136
140
  extraStyles={
@@ -138,9 +142,11 @@ const Modal = ({
138
142
  }
139
143
  >
140
144
  {defaultWrapper ? (
141
- <Paragraph variant="p">{modalBodyText}</Paragraph>
145
+ <Paragraph variant={isMobile ? "pS" : "p"}>
146
+ {modalBodyText}
147
+ </Paragraph>
142
148
  ) : (
143
- <Box padding={maxHeight ? `0 0 ${SPACING_XS} 0` : "0"}>
149
+ <Box padding={maxHeight ? `0 0 ${SPACING.XS} 0` : "0"}>
144
150
  {modalBodyText}
145
151
  </Box>
146
152
  )}
@@ -1,5 +1,5 @@
1
1
  import React from "react";
2
- import { SPACING_NORMAL } from "../../../../constants/style_constants";
2
+ import { SPACING } from "../../../../constants/style_constants";
3
3
  import { Box, Stack } from "../../../atoms/layouts";
4
4
 
5
5
  export const ButtonLayoutWrapper = ({ children = [], isMobile = false }) => {
@@ -7,7 +7,7 @@ export const ButtonLayoutWrapper = ({ children = [], isMobile = false }) => {
7
7
  const flexGrow = isMobile ? "flex-grow: 1;" : "";
8
8
 
9
9
  return (
10
- <Box padding={SPACING_NORMAL}>
10
+ <Box padding={SPACING.MD}>
11
11
  <Stack childGap="1rem" direction="row" justify="flex-end">
12
12
  {safeChildren.map((child, index) => {
13
13
  return (
@@ -1,5 +1,8 @@
1
1
  import React from "react";
2
- import { CORNER_STANDARD } from "../../../../constants/style_constants";
2
+ import {
3
+ BORDER_RADIUS,
4
+ FONT_SIZE
5
+ } from "../../../../constants/style_constants";
3
6
  import { noop } from "../../../../util/general";
4
7
  import ButtonWithAction from "../../../atoms/button-with-action/ButtonWithAction";
5
8
 
@@ -10,18 +13,20 @@ export const CancelButton = ({
10
13
  hideModal = noop,
11
14
  isMobile = false
12
15
  }) => {
13
- const fullWidth = isMobile ? "width: 100%;" : "";
16
+ const fontSize = `font-size: ${isMobile ? FONT_SIZE.XS : FONT_SIZE.SM};`;
17
+ const width = isMobile ? "width: 100%;" : "";
14
18
 
15
19
  return (
16
20
  <ButtonWithAction
17
21
  action={cancelAction ? cancelAction : hideModal}
18
- borderRadius={CORNER_STANDARD}
22
+ borderRadius={BORDER_RADIUS.MD}
19
23
  className="modal-cancel-button"
20
24
  dataQa={cancelButtonText}
21
- extraStyles={`${buttonExtraStyles}; margin: 0; ${fullWidth}`}
25
+ extraStyles={`${buttonExtraStyles}; margin: 0; ${width}`}
22
26
  name={cancelButtonText}
23
27
  role="button"
24
28
  text={cancelButtonText}
29
+ textExtraStyles={`${fontSize}`}
25
30
  variant="secondary"
26
31
  />
27
32
  );
@@ -1,5 +1,8 @@
1
1
  import React from "react";
2
- import { CORNER_STANDARD } from "../../../../constants/style_constants";
2
+ import {
3
+ BORDER_RADIUS,
4
+ FONT_SIZE
5
+ } from "../../../../constants/style_constants";
3
6
  import { noop } from "../../../../util/general";
4
7
  import ButtonWithAction from "../../../atoms/button-with-action/ButtonWithAction";
5
8
 
@@ -9,18 +12,20 @@ export const CloseButton = ({
9
12
  hideModal = noop,
10
13
  isMobile = false
11
14
  }) => {
12
- const fullWidth = isMobile ? "width: 100%;" : "";
15
+ const fontSize = `font-size: ${isMobile ? FONT_SIZE.XS : FONT_SIZE.SM};`;
16
+ const width = isMobile ? "width: 100%;" : "";
13
17
 
14
18
  return (
15
19
  <ButtonWithAction
16
20
  action={hideModal}
17
- borderRadius={CORNER_STANDARD}
21
+ borderRadius={BORDER_RADIUS.MD}
18
22
  className="modal-close-button"
19
23
  dataQa={closeButtonText}
20
- extraStyles={`${buttonExtraStyles}; margin: 0; ${fullWidth}`}
24
+ extraStyles={`${buttonExtraStyles}; margin: 0; ${width}`}
21
25
  name={closeButtonText}
22
26
  role="button"
23
27
  text={closeButtonText}
28
+ textExtraStyles={`${fontSize}`}
24
29
  variant="primary"
25
30
  />
26
31
  );
@@ -1,5 +1,8 @@
1
1
  import React from "react";
2
- import { CORNER_STANDARD } from "../../../../constants/style_constants";
2
+ import {
3
+ BORDER_RADIUS,
4
+ FONT_SIZE
5
+ } from "../../../../constants/style_constants";
3
6
  import { noop } from "../../../../util/general";
4
7
  import ButtonWithAction from "../../../atoms/button-with-action/ButtonWithAction";
5
8
  import ButtonWithLink from "../../../atoms/button-with-link/ButtonWithLink";
@@ -15,21 +18,23 @@ export const ContinueButton = ({
15
18
  useDangerButton = false
16
19
  }) => {
17
20
  const ContinueButtonAtom = continueURL ? ButtonWithLink : ButtonWithAction;
18
- const fullWidth = isMobile ? "width: 100%;" : "";
21
+ const fontSize = `font-size: ${isMobile ? FONT_SIZE.XS : FONT_SIZE.SM};`;
22
+ const width = isMobile ? "width: 100%;" : "";
19
23
 
20
24
  return (
21
25
  <ContinueButtonAtom
22
26
  action={continueAction}
23
- borderRadius={CORNER_STANDARD}
27
+ borderRadius={BORDER_RADIUS.MD}
24
28
  className="modal-continue-button"
25
29
  dataQa={continueButtonText}
26
30
  disabled={isContinueActionDisabled}
27
- extraStyles={`${buttonExtraStyles}; margin: 0; ${fullWidth}`}
31
+ extraStyles={`${buttonExtraStyles}; margin: 0; ${width}`}
28
32
  isLoading={isLoading}
29
- linkExtraStyles={`display: inline-block; ${fullWidth}`}
33
+ linkExtraStyles={`display: inline-block; ${width}`}
30
34
  name={continueButtonText}
31
35
  role="button"
32
36
  text={continueButtonText}
37
+ textExtraStyles={`${fontSize}`}
33
38
  url={continueURL}
34
39
  variant={useDangerButton ? "danger" : "primary"}
35
40
  />
@@ -29,7 +29,8 @@ const ToastNotification = ({
29
29
  maxWidth = "350px",
30
30
  height = "56px",
31
31
  childGap = "1rem",
32
- backgroundColor
32
+ backgroundColor,
33
+ role = "alert"
33
34
  }) => (
34
35
  <Box
35
36
  onClick={closeToastNotification}
@@ -55,18 +56,21 @@ const ToastNotification = ({
55
56
  ${extraStyles};
56
57
  cursor: pointer;
57
58
  `}
59
+ role={role}
58
60
  >
59
- <Cluster align="center" childGap={childGap}>
60
- {variant === VARIANTS.SUCCESS && <SuccessfulIconMedium />}
61
- {variant === VARIANTS.ERROR && <ErroredIcon />}
62
- <Box padding="1rem 0" maxWidth={maxWidth}>
63
- <Paragraph
64
- weight={FONT_WEIGHT_SEMIBOLD}
65
- extraStyles={"word-break: break-word;"}
66
- >
67
- {message}
68
- </Paragraph>
69
- </Box>
61
+ <Cluster align="center" childGap={childGap} justify="space-between">
62
+ <Cluster align="center" childGap={childGap}>
63
+ {variant === VARIANTS.SUCCESS && <SuccessfulIconMedium />}
64
+ {variant === VARIANTS.ERROR && <ErroredIcon />}
65
+ <Box padding="1rem 0" maxWidth={maxWidth}>
66
+ <Paragraph
67
+ weight={FONT_WEIGHT_SEMIBOLD}
68
+ extraStyles={"word-break: break-word;"}
69
+ >
70
+ {message}
71
+ </Paragraph>
72
+ </Box>
73
+ </Cluster>
70
74
  <IconQuitLarge />
71
75
  </Cluster>
72
76
  </Box>
@@ -3,6 +3,9 @@ import ToastNotification from "./ToastNotification";
3
3
  import page from "../../../../.storybook/page";
4
4
  import { useToastNotification } from "../../../hooks";
5
5
  import { ToastVariants } from "../../../types/common";
6
+ import { text } from "@storybook/addon-knobs";
7
+
8
+ const groupId = "props";
6
9
 
7
10
  export const toastNotificationSuccess = () => {
8
11
  const {
@@ -26,6 +29,9 @@ export const toastNotificationSuccess = () => {
26
29
  message={toastMessage}
27
30
  toastOpen={isToastOpen}
28
31
  closeToastNotification={() => hideToast()}
32
+ role={text("role", "alert", groupId)}
33
+ minWidth={text("minWidth", null, groupId)}
34
+ maxWidth={text("maxWidth", null, groupId)}
29
35
  />
30
36
  );
31
37
  };
@@ -54,11 +60,43 @@ export const toastNotificationError = () => {
54
60
  message={toastMessage}
55
61
  toastOpen={isToastOpen}
56
62
  closeToastNotification={() => hideToast()}
63
+ role={text("role", "alert", groupId)}
64
+ minWidth={text("minWidth", null, groupId)}
65
+ maxWidth={text("maxWidth", null, groupId)}
57
66
  />
58
67
  );
59
68
  };
60
69
  toastNotificationError.storyName = "Error Toast";
61
70
 
71
+ export const toastNotificationNoAutoHide = () => {
72
+ const {
73
+ isToastOpen,
74
+ toastMessage,
75
+ showToast,
76
+ hideToast
77
+ } = useToastNotification({ timeout: 0 });
78
+
79
+ useEffect(() => {
80
+ showToast({
81
+ message: "Success!",
82
+ variant: ToastVariants.SUCCESS
83
+ });
84
+ }, []);
85
+
86
+ return (
87
+ <ToastNotification
88
+ message={toastMessage}
89
+ toastOpen={isToastOpen}
90
+ closeToastNotification={() => hideToast()}
91
+ role={text("role", "alert", groupId)}
92
+ minWidth={text("minWidth", null, groupId)}
93
+ maxWidth={text("maxWidth", null, groupId)}
94
+ />
95
+ );
96
+ };
97
+
98
+ toastNotificationNoAutoHide.storyName = "No auto-hide";
99
+
62
100
  const story = page({
63
101
  title: "Components|Molecules/ToastNotification",
64
102
  Component: ToastNotification
@@ -1,7 +1,16 @@
1
1
  type StyleDeclaration = string;
2
2
 
3
+ interface StyleOptions {
4
+ XS?: string;
5
+ SM?: string;
6
+ MD?: string;
7
+ LG?: string;
8
+ XL?: string;
9
+ }
10
+
11
+ export const BORDER_RADIUS: StyleOptions;
3
12
  export const BORDER_THIN: StyleDeclaration;
4
- export const CORNER_STANDARD: StyleDeclaration;
13
+ export const FONT_SIZE: StyleOptions;
5
14
  export const FONT_WEIGHT_REGULAR: StyleDeclaration;
6
15
  export const FONT_WEIGHT_SEMIBOLD: StyleDeclaration;
7
16
  export const FONT_WEIGHT_BOLD: StyleDeclaration;
@@ -11,5 +20,4 @@ export const COMPACT_JUMBO_HEIGHT: StyleDeclaration;
11
20
  export const JUMBO_HEIGHT: StyleDeclaration;
12
21
  export const SPACER_HEIGHT: StyleDeclaration;
13
22
  export const LINK_TEXT_DECORATION: StyleDeclaration;
14
- export const SPACING_XS: StyleDeclaration;
15
- export const SPACING_NORMAL: StyleDeclaration;
23
+ export const SPACING: StyleOptions;
@@ -1,7 +1,15 @@
1
1
  /* These are constants used by nav frontend components */
2
2
 
3
+ export const BORDER_RADIUS = {
4
+ MD: "4px" // Figma: Corners/Standard Corner
5
+ };
3
6
  export const BORDER_THIN = "1px";
4
- export const CORNER_STANDARD = "4px";
7
+ export const FONT_SIZE = {
8
+ XS: "0.750rem", // 12px
9
+ SM: "0.875rem", // 14px
10
+ MD: "1.000rem", // 16px
11
+ LG: "1.125rem" // 18px
12
+ };
5
13
  export const FONT_WEIGHT_REGULAR = "400";
6
14
  export const FONT_WEIGHT_SEMIBOLD = "600";
7
15
  export const FONT_WEIGHT_BOLD = "700";
@@ -11,5 +19,7 @@ export const COMPACT_JUMBO_HEIGHT = "65px";
11
19
  export const JUMBO_HEIGHT = "300px";
12
20
  export const SPACER_HEIGHT = "65px";
13
21
  export const LINK_TEXT_DECORATION = "underline solid 1px";
14
- export const SPACING_XS = "1.0rem";
15
- export const SPACING_NORMAL = "1.5rem";
22
+ export const SPACING = {
23
+ XS: "1.0rem", // Figma: Spacing/XS
24
+ MD: "1.5rem" // Figma: Spacing/Normal
25
+ };
@@ -10,7 +10,7 @@ const useToastNotification = ({ timeout = 5000 } = {}) => {
10
10
  const [toastState, setToastState] = useState(initialToastState);
11
11
 
12
12
  useEffect(() => {
13
- if (toastState.isOpen) {
13
+ if (toastState.isOpen && timeout > 0) {
14
14
  setTimeout(() => {
15
15
  setToastState(initialToastState);
16
16
  }, timeout);