@thecb/components 8.3.0-beta.0 → 8.4.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@thecb/components",
3
- "version": "8.3.0-beta.0",
3
+ "version": "8.4.0-beta.0",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "typings": "dist/index.d.ts",
@@ -21,6 +21,7 @@ const StyledBadge = styled(Text)`
21
21
  font-weight: 400;
22
22
  line-height: 150%; /* 15px */
23
23
  letter-spacing: 0.2px;
24
+ white-space: nowrap;
24
25
 
25
26
  @media screen and (min-width: 1049px) {
26
27
  font-size: 12px;
@@ -4,7 +4,7 @@ import {
4
4
  HINT_GREEN,
5
5
  INFO_BLUE,
6
6
  MATISSE_BLUE,
7
- ROYAL_BLUE,
7
+ ROYAL_BLUE_VIVID,
8
8
  SEA_GREEN,
9
9
  ZEST_ORANGE
10
10
  } from "../../../constants/colors";
@@ -19,7 +19,7 @@ const background = {
19
19
  const color = {
20
20
  info: `${MATISSE_BLUE}`,
21
21
  warn: `${ZEST_ORANGE}`,
22
- primary: `${ROYAL_BLUE}`,
22
+ primary: `${ROYAL_BLUE_VIVID}`,
23
23
  success: `${SEA_GREEN}`
24
24
  };
25
25
 
@@ -1,13 +1,17 @@
1
1
  import React from "react";
2
2
  import Expand from "../../../util/expand";
3
- import { ErrorMessage, Field, FieldActions } from "../../../types/common";
3
+ import {
4
+ ErrorMessageDictionary,
5
+ Field,
6
+ FieldActions
7
+ } from "../../../types/common";
4
8
 
5
9
  export interface FormInputProps {
6
10
  extraStyles?: string;
7
11
  field?: Field;
8
12
  fieldActions?: FieldActions;
9
13
  disabled?: boolean;
10
- errorMessages?: ErrorMessage[];
14
+ errorMessages?: ErrorMessageDictionary;
11
15
  helperModal?: boolean;
12
16
  isEmail?: boolean;
13
17
  isNum?: boolean;
@@ -1,20 +1,20 @@
1
1
  import React from "react";
2
2
  import Expand from "../../../util/expand";
3
- import { ErrorMessage, Field, FieldActions } from "../../../types/common";
4
-
5
- interface Option {
6
- text?: string;
7
- value?: string | number;
8
- }
3
+ import {
4
+ ErrorMessageDictionary,
5
+ Field,
6
+ FieldActions,
7
+ FormSelectOption
8
+ } from "../../../types/common";
9
9
 
10
10
  export interface FormSelectProps {
11
11
  disabled?: boolean;
12
12
  dropdownMaxHeight?: string;
13
13
  labelTextWhenNoError?: string;
14
- options?: Option[];
14
+ options?: FormSelectOption[];
15
15
  fieldActions?: FieldActions;
16
16
  showErrors?: boolean;
17
- errorMessages?: ErrorMessage[];
17
+ errorMessages?: ErrorMessageDictionary;
18
18
  field?: Field;
19
19
  }
20
20
 
@@ -0,0 +1,41 @@
1
+ import React from "react";
2
+ import { ROYAL_BLUE_VIVID } from "../../../constants/colors";
3
+
4
+ const ArrowRightIcon = ({ color = ROYAL_BLUE_VIVID }) => {
5
+ return (
6
+ <svg
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="20"
9
+ height="20"
10
+ viewBox="0 0 20 20"
11
+ fill="none"
12
+ >
13
+ <path
14
+ fillRule="evenodd"
15
+ clipRule="evenodd"
16
+ d="M9.17828 4.15501C8.98314 4.35015 8.983 4.66649 9.17796 4.8618L13.475 9.16659H3.83337C3.55723 9.16659 3.33337 9.39044 3.33337 9.66659V10.3333C3.33337 10.6094 3.55723 10.8333 3.83337 10.8333H13.475L9.17796 15.138C8.983 15.3333 8.98314 15.6497 9.17828 15.8448L9.64649 16.313C9.84175 16.5083 10.1583 16.5083 10.3536 16.313L16.3132 10.3535C16.5084 10.1582 16.5084 9.84163 16.3132 9.64637L10.3536 3.6868C10.1583 3.49154 9.84175 3.49154 9.64649 3.68681L9.17828 4.15501Z"
17
+ fill={color}
18
+ />
19
+ <mask
20
+ id="mask0_6329_1483"
21
+ style={{ maskType: "luminance" }}
22
+ maskUnits="userSpaceOnUse"
23
+ x="3"
24
+ y="3"
25
+ width="14"
26
+ height="14"
27
+ >
28
+ <path
29
+ fillRule="evenodd"
30
+ clipRule="evenodd"
31
+ d="M9.17828 4.15501C8.98314 4.35015 8.983 4.66649 9.17796 4.8618L13.475 9.16659H3.83337C3.55723 9.16659 3.33337 9.39044 3.33337 9.66659V10.3333C3.33337 10.6094 3.55723 10.8333 3.83337 10.8333H13.475L9.17796 15.138C8.983 15.3333 8.98314 15.6497 9.17828 15.8448L9.64649 16.313C9.84175 16.5083 10.1583 16.5083 10.3536 16.313L16.3132 10.3535C16.5084 10.1582 16.5084 9.84163 16.3132 9.64637L10.3536 3.6868C10.1583 3.49154 9.84175 3.49154 9.64649 3.68681L9.17828 4.15501Z"
32
+ fill="white"
33
+ />
34
+ </mask>
35
+ <g mask="url(#mask0_6329_1483)">
36
+ <rect width="20" height="20" fill={color} />
37
+ </g>
38
+ </svg>
39
+ );
40
+ };
41
+ export default ArrowRightIcon;
@@ -0,0 +1,22 @@
1
+ import React from "react";
2
+ import { ROYAL_BLUE_VIVID } from "../../../constants/colors";
3
+
4
+ const PlusCircleIcon = ({ color = ROYAL_BLUE_VIVID }) => {
5
+ return (
6
+ <svg
7
+ xmlns="http://www.w3.org/2000/svg"
8
+ width="20"
9
+ height="20"
10
+ viewBox="0 0 20 20"
11
+ fill="none"
12
+ >
13
+ <path
14
+ fillRule="evenodd"
15
+ clipRule="evenodd"
16
+ d="M10 1.25C5.16751 1.25 1.25 5.16751 1.25 10C1.25 14.8325 5.16751 18.75 10 18.75C14.8325 18.75 18.75 14.8325 18.75 10C18.75 5.16751 14.8325 1.25 10 1.25ZM2.75 10C2.75 5.99594 5.99594 2.75 10 2.75C14.0041 2.75 17.25 5.99594 17.25 10C17.25 14.0041 14.0041 17.25 10 17.25C5.99594 17.25 2.75 14.0041 2.75 10ZM10.75 9.25V5.25H9.25V9.25H5.25V10.75H9.25V14.75H10.75V10.75H14.75V9.25H10.75Z"
17
+ fill={color}
18
+ />
19
+ </svg>
20
+ );
21
+ };
22
+ export default PlusCircleIcon;
@@ -75,6 +75,7 @@ import XCircleIconSmall from "./XCircleIconSmall";
75
75
  import SuccessfulIconSmall from "./SuccessfulIconSmall";
76
76
  import ArrowLeftCircleIconSmall from "./ArrowLeftCircleIconSmall";
77
77
  import ArrowRightCircleIconSmall from "./ArrowRightCircleIconSmall";
78
+ import ArrowRightIcon from "./ArrowRightIcon";
78
79
  import ArrowUpCircleIconSmall from "./ArrowUpCircleIconSmall";
79
80
  import ArrowDownCircleIconSmall from "./ArrowDownCircleIconSmall";
80
81
  import SuccessfulIconMedium from "./SuccessfulIconMedium";
@@ -83,6 +84,7 @@ import RefundIconMedium from "./RefundIconMedium";
83
84
  import ArrowLeftCircleIconMedium from "./ArrowLeftCircleIconMedium";
84
85
  import ChargebackIconMedium from "./ChargebackIconMedium";
85
86
  import ChargebackReversalIconMedium from "./ChargebackReversalIconMedium";
87
+ import PlusCircleIcon from "./PlusCircleIcon";
86
88
 
87
89
  export {
88
90
  AccountsIcon,
@@ -162,6 +164,7 @@ export {
162
164
  SuccessfulIconSmall,
163
165
  ArrowLeftCircleIconSmall,
164
166
  ArrowRightCircleIconSmall,
167
+ ArrowRightIcon,
165
168
  ArrowUpCircleIconSmall,
166
169
  ArrowDownCircleIconSmall,
167
170
  SuccessfulIconMedium,
@@ -169,5 +172,6 @@ export {
169
172
  RefundIconMedium,
170
173
  ArrowLeftCircleIconMedium,
171
174
  ChargebackIconMedium,
172
- ChargebackReversalIconMedium
175
+ ChargebackReversalIconMedium,
176
+ PlusCircleIcon
173
177
  };
@@ -11,6 +11,7 @@ export { default as FooterWithSubfooter } from "./footer-with-subfooter";
11
11
  export { default as ForgotPasswordForm } from "./forgot-password-form";
12
12
  export { default as HighlightTabRow } from "./highlight-tab-row";
13
13
  export { iconsMap as ObligationIcons } from "./obligation/icons";
14
+ export { default as LinkCard } from "./link-card";
14
15
  export { default as LoginForm } from "./login-form";
15
16
  export { default as Modal } from "./modal";
16
17
  export { default as Module } from "./module";
@@ -0,0 +1,128 @@
1
+ import React from "react";
2
+ import { useNavigate } from "react-router-dom";
3
+ import Heading from "../../atoms/heading";
4
+ import Paragraph from "../../atoms/paragraph";
5
+ import Text from "../../atoms/text/Text";
6
+ import { ROYAL_BLUE_VIVID } from "../../../constants/colors";
7
+ import { FONT_WEIGHT_SEMIBOLD } from "../../../constants/style_constants";
8
+ import { Box, Stack } from "../../atoms/layouts";
9
+ import Badge from "../../atoms/badge/Badge";
10
+ import { PlusCircleIcon, AutopayIcon, ArrowRightIcon } from "../../atoms/icons";
11
+ import { themeComponent } from "../../../util/themeUtils";
12
+ import { fallbackValues } from "./LinkCard.theme";
13
+
14
+ const LinkCard = ({
15
+ variant = "default",
16
+ workflowName = "Test Workflow",
17
+ workflowDescription = "Link your benefit plan",
18
+ workflowActionName = "Find",
19
+ themeValues,
20
+ slug
21
+ }) => {
22
+ const navigate = useNavigate();
23
+
24
+ return (
25
+ <Box
26
+ background="#FEFEFE" // --grays-cool-gray-00
27
+ border="1px solid #C4CEF4;" // --primary-color-primary-30
28
+ padding={0}
29
+ borderRadius="8px"
30
+ dataQa={`link-card-${workflowDescription}`}
31
+ hoverStyles={`
32
+ border-radius: 8px;
33
+ cursor: pointer;
34
+ border: 1px solid ${ROYAL_BLUE_VIVID};
35
+ background: var(--primary-color-primary-10, #EBEFFB);
36
+ /* Primitives/New Shadow/3-Pressed-New */
37
+ box-shadow: 0px 0px 0px 0px rgba(41, 42, 51, 0.10), 0px 5px 11px 0px rgba(41, 42, 51, 0.10), 0px 4px 19px 0px rgba(41, 42, 51, 0.09), 0px 27px 26px 0px rgba(41, 42, 51, 0.05), 0px 56px 31px 0px rgba(41, 42, 51, 0.01), 0px 80px 33px 0px rgba(41, 42, 51, 0.00);
38
+ .show-on-hover {color: ${ROYAL_BLUE_VIVID};}
39
+ `}
40
+ extraStyles="display: flex;
41
+ width: 288px;
42
+ min-width: 240px;
43
+ max-width: 288px;
44
+ min-height: 141px;
45
+ padding: 16px 24px;
46
+ flex-direction: column;
47
+ align-items: flex-start;
48
+ gap: 40px;
49
+ flex-shrink: 0;
50
+ align-self: stretch;"
51
+ onClick={() => {
52
+ // @TODO replace with something valid like navigate
53
+ console.log("attempting navigation...");
54
+ // window.location.pathname = `/service/${slug}`;
55
+ navigate(`/service/${slug}`);
56
+ }}
57
+ >
58
+ <Stack childGap={0} bottomItem={3} fullHeight>
59
+ <Box padding={"1rem 1rem 0 1rem"}>
60
+ <Heading
61
+ variant="h6"
62
+ weight={FONT_WEIGHT_SEMIBOLD}
63
+ color={themeValues.color}
64
+ margin={"0 0 0.5rem 0"}
65
+ extraStyles="display: -webkit-box; -webkit-box-orient: vertical; -webkit-line-clamp: 2; align-self: stretch; overflow: hidden; text-overflow: ellipsis; font-family: Public Sans; font-size: 16px; font-style: normal; font-weight: 600; line-height: 150%;"
66
+ >
67
+ {workflowName}
68
+ </Heading>
69
+ </Box>
70
+ <Box padding={"0 1rem 1rem"} minHeight={"4.25rem"}>
71
+ <Paragraph
72
+ variant="pS"
73
+ color={themeValues.color}
74
+ extraStyles="overflow: hidden;
75
+ text-overflow: ellipsis;
76
+ display: -webkit-box;
77
+ -webkit-box-orient: vertical;
78
+ -webkit-line-clamp: 2;
79
+ align-self: stretch;
80
+
81
+ /* CB Standard/Desktop/D - P Small - Regular */
82
+ font-family: Public Sans;
83
+ font-size: 14px;
84
+ font-style: normal;
85
+ font-weight: 400;
86
+ line-height: 150%; /* 21px */
87
+ letter-spacing: 0.14px;"
88
+ >
89
+ {workflowDescription}
90
+ </Paragraph>
91
+ </Box>
92
+ <Box
93
+ background="transparent"
94
+ borderWidthOverride="0 0 0 0"
95
+ padding="1.5rem 0 1.5rem 1rem"
96
+ >
97
+ <Stack direction="row" justify="space-between">
98
+ <Box
99
+ background="transparent"
100
+ borderWidthOverride="0 0 0 0"
101
+ padding="0"
102
+ >
103
+ <Badge label="Autopay Available" Icon={AutopayIcon} />
104
+ </Box>
105
+ <Stack direction="row" childGap="6px">
106
+ <Text
107
+ variant="pS"
108
+ color={themeValues.color}
109
+ extraStyles="text-align: right; color: transparent;"
110
+ className="show-on-hover"
111
+ >
112
+ {workflowActionName}
113
+ </Text>
114
+ {workflowActionName === "Find" && (
115
+ <PlusCircleIcon color={themeValues.color} />
116
+ )}
117
+ {workflowActionName === "Pay" && (
118
+ <ArrowRightIcon color={themeValues.color} />
119
+ )}
120
+ </Stack>
121
+ </Stack>
122
+ </Box>
123
+ </Stack>
124
+ </Box>
125
+ );
126
+ };
127
+
128
+ export default themeComponent(LinkCard, "LinkCard", fallbackValues, "default");
@@ -0,0 +1,26 @@
1
+ import React from "react";
2
+ import LinkCard from "./LinkCard";
3
+ import page from "../../../../.storybook/page";
4
+ import { text } from "@storybook/addon-knobs";
5
+
6
+ const groupId = "props";
7
+
8
+ export const linkCard = () => (
9
+ <LinkCard
10
+ workflowName={text("workflowName", "Workflow Name", "props")}
11
+ workflowDescription={text(
12
+ "workflowDescription",
13
+ "Workflow description",
14
+ groupId
15
+ )}
16
+ workflowActionName={text("workflowActionName", "Find", "props")}
17
+ slug={text("slug", "animal-care-and-control", "props")}
18
+ />
19
+ );
20
+
21
+ const story = page({
22
+ title: "Components|Molecules/LinkCard",
23
+ Component: LinkCard
24
+ });
25
+
26
+ export default story;
@@ -0,0 +1,9 @@
1
+ import { ROYAL_BLUE_VIVID, WHITE } from "../../../constants/colors";
2
+
3
+ const background = { default: `${WHITE}` };
4
+ const color = { default: `${ROYAL_BLUE_VIVID}` };
5
+
6
+ export const fallbackValues = {
7
+ background,
8
+ color
9
+ };
@@ -0,0 +1,14 @@
1
+ import React, { HTMLAttributes } from "react";
2
+ import Expand from "../../../util/expand";
3
+
4
+ export interface LinkCardProps {
5
+ variant?: string; // "default" is only one
6
+ workflowName?: string; // title
7
+ workflowDescription?: string; // beneath title
8
+ workflowActionName: "Find" | "Pay";
9
+ slug: string; // path segment of button on click (/service/${slug})
10
+ themeValues?: any;
11
+ }
12
+
13
+ export const LinkCard: React.FC<Expand<LinkCardProps> &
14
+ HTMLAttributes<HTMLElement>>;
@@ -0,0 +1,3 @@
1
+ import LinkCard from "./LinkCard";
2
+
3
+ export default LinkCard;
@@ -40,7 +40,6 @@ const COOL_GREY_05 = "#fbfcfd"; // CBS-050
40
40
  const CLOUDBURST_BLUE = "#26395c";
41
41
  const ZODIAC_BLUE = "#14284b";
42
42
  const CONGRESS_BLUE = "#005095";
43
- const ROYAL_BLUE = "#3B5BDB";
44
43
  const SCIENCE_BLUE = "#0074D9";
45
44
  const MARINER_BLUE = "#2E75D2";
46
45
  const CURIOUS_BLUE = "#27A9E1";
@@ -55,7 +54,8 @@ const INFO_BLUE = "#E4F4FD";
55
54
  const CORNFLOWER_BLUE = "#EBEFFB";
56
55
  const HOVER_LIGHT_BLUE = "#EFFAFF";
57
56
  const MATISSE_BLUE = "#15749D";
58
-
57
+ const ROYAL_BLUE = "#3181E3";
58
+ const ROYAL_BLUE_VIVID = "#3B5BDB";
59
59
  const ASTRAL_BLUE = "#3176AA";
60
60
  const SAPPHIRE_BLUE = "#116285";
61
61
  const PEACOCK_BLUE = "#0E506D";
@@ -188,6 +188,7 @@ export {
188
188
  HOVER_LIGHT_BLUE,
189
189
  MATISSE_BLUE,
190
190
  ROYAL_BLUE,
191
+ ROYAL_BLUE_VIVID,
191
192
  ASTRAL_BLUE,
192
193
  SAPPHIRE_BLUE,
193
194
  PEACOCK_BLUE,
package/src/index.d.ts CHANGED
@@ -1 +1,2 @@
1
1
  export * from "./components";
2
+ export * from "./types/common";
@@ -0,0 +1,3 @@
1
+ export default interface ErrorMessageDictionary {
2
+ [fieldName: string]: string;
3
+ }
@@ -4,24 +4,24 @@ import ReduxAction from "./ReduxAction";
4
4
  * These types should be moved to and referenced from redux-freeform if it implements TypeScript
5
5
  */
6
6
 
7
- type ValidatorFn = (value: string) => boolean;
7
+ export type ValidatorFn = (value: string) => boolean;
8
8
 
9
- interface FieldActionPayload {
9
+ export interface FieldActionPayload {
10
10
  fieldName: string;
11
11
  value?: string;
12
12
  validator?: ValidatorFn;
13
13
  }
14
14
 
15
- type SetAction = ReduxAction<"field/SET", FieldActionPayload>;
16
- type AddValidatorAction = ReduxAction<
15
+ export type SetAction = ReduxAction<"field/SET", FieldActionPayload>;
16
+ export type AddValidatorAction = ReduxAction<
17
17
  "field/ADD_VALIDATOR",
18
18
  FieldActionPayload
19
19
  >;
20
- type RemoveValidatorAction = ReduxAction<
20
+ export type RemoveValidatorAction = ReduxAction<
21
21
  "field/REMOVE_VALIDATOR",
22
22
  FieldActionPayload
23
23
  >;
24
- type ClearAction = ReduxAction<"field/CLEAR">;
24
+ export type ClearAction = ReduxAction<"field/CLEAR">;
25
25
 
26
26
  export default interface FieldActions {
27
27
  set?: (fieldName: string) => (value: string) => SetAction;
@@ -0,0 +1,4 @@
1
+ export default interface FormSelectOption {
2
+ text?: string;
3
+ value?: string;
4
+ }
@@ -1,4 +1,6 @@
1
1
  export { default as Field } from "./Field";
2
2
  export { default as ReduxAction } from "./ReduxAction";
3
3
  export { default as FieldActions } from "./FieldActions";
4
- export { default as ErrorMessage } from "./ErrorMessage";
4
+ export { default as FormSelectOption } from "./FormSelectOption";
5
+ export { default as ErrorMessageDictionary } from "./ErrorMessageDictionary";
6
+ export * from "./FieldActions";
@@ -1,3 +0,0 @@
1
- export default interface ErrorMessage {
2
- [fieldName: string]: string;
3
- }