@thecb/components 12.0.2-beta.2 → 12.0.2

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": "12.0.2-beta.2",
3
+ "version": "12.0.2",
4
4
  "description": "Common lib for CityBase react components",
5
5
  "main": "dist/index.cjs.js",
6
6
  "typings": "dist/index.d.ts",
@@ -1,5 +1,6 @@
1
1
  import React from "react";
2
2
  import { Box, Stack } from "../../atoms/layouts";
3
+ import { ExternalLink, InternalLink } from "../../atoms/link";
3
4
  import { themeComponent } from "../../../util/themeUtils";
4
5
  import { fallbackValues } from "./LinkCard.theme";
5
6
  import * as Styled from "./LinkCard.styled";
@@ -25,79 +26,102 @@ const LinkCard = ({
25
26
  const regex = /\W/g;
26
27
  const locatorSlug = title?.toLowerCase?.()?.replaceAll?.(regex, "-");
27
28
 
28
- return (
29
- <Styled.StyledAnchor
30
- key={`link-card-${locatorSlug}`}
31
- href={disabled ? undefined : href}
32
- rel={isExternalLink ? "noopener noreferrer" : undefined}
33
- target={isExternalLink ? "_blank" : undefined}
34
- tabIndex={disabled ? -1 : 0}
35
- aria-disabled={disabled}
36
- $disabled={disabled}
37
- aria-label={`${title}, ${subtitle}`}
38
- data-qa={`link-card-${locatorSlug}`}
39
- $theme={themeValues}
40
- $extraStyles={
41
- disabled ? `pointer-events: none; ${extraStyles}` : extraStyles
42
- }
43
- $hoverStyles={extraHoverStyles}
44
- $activeStyles={extraActiveStyles}
29
+ const baseStyles = Styled.getCardBaseStyles(
30
+ themeValues,
31
+ disabled,
32
+ extraStyles
33
+ );
34
+ const hoverActiveStyles = Styled.getCardHoverActiveStyles(
35
+ themeValues,
36
+ disabled,
37
+ extraHoverStyles,
38
+ extraActiveStyles
39
+ );
40
+
41
+ const cardContent = (
42
+ <Stack
43
+ childGap={0}
44
+ bottomItem={3}
45
+ justify="space-between"
46
+ style={{ width: "100%" }}
47
+ fullHeight
45
48
  >
46
49
  <Stack
47
- childGap={0}
48
- bottomItem={3}
49
- justify="space-between"
50
- style={{ width: "100%" }}
51
- fullHeight
50
+ direction="row"
51
+ childGap="0.5rem"
52
+ extraStyles={`align-items: center;`}
52
53
  >
53
- <Stack
54
- direction="row"
55
- childGap="0.5rem"
56
- extraStyles={`align-items: center;`}
54
+ <Styled.Title
55
+ variant={titleVariant}
56
+ $theme={themeValues}
57
+ margin={0}
58
+ $disabled={disabled}
57
59
  >
58
- <Styled.Title
59
- variant={titleVariant}
60
- $theme={themeValues}
61
- margin={0}
62
- $disabled={disabled}
63
- >
64
- {title}
65
- </Styled.Title>
66
- {isExternalLink && (
67
- <ExternalLinkIcon
68
- linkColor={themeValues.color}
69
- text={locatorSlug}
70
- style={{ height: "1.125rem", width: "1.125rem" }}
71
- />
72
- )}
73
- </Stack>
74
- <Box padding={subtitlePadding} width="100%">
75
- <Styled.Subtitle
76
- variant="pS"
77
- $theme={themeValues}
78
- $disabled={disabled}
79
- >
80
- {subtitle}
81
- </Styled.Subtitle>
82
- </Box>
83
- <Box
84
- background="transparent"
85
- borderWidthOverride="0 0 0 0"
86
- padding="0"
87
- width="100%"
88
- >
89
- <Styled.Footer direction="row" childGap="6px" justify="space-between">
90
- {/* To keep rightContent aligned right, use an empty Box as leftContent if none is provided */}
91
- {showLeft && !!leftContent ? (
92
- leftContent
93
- ) : (
94
- <Box extraStyles="margin-right: auto;" />
95
- )}
96
- {showRight && !!rightContent && rightContent}
97
- </Styled.Footer>
98
- </Box>
60
+ {title}
61
+ </Styled.Title>
62
+ {isExternalLink && (
63
+ <ExternalLinkIcon
64
+ linkColor={themeValues.color}
65
+ text={locatorSlug}
66
+ style={{ height: "1.125rem", width: "1.125rem" }}
67
+ />
68
+ )}
99
69
  </Stack>
100
- </Styled.StyledAnchor>
70
+ <Box padding={subtitlePadding} width="100%">
71
+ <Styled.Subtitle variant="pS" $theme={themeValues} $disabled={disabled}>
72
+ {subtitle}
73
+ </Styled.Subtitle>
74
+ </Box>
75
+ <Box
76
+ background="transparent"
77
+ borderWidthOverride="0 0 0 0"
78
+ padding="0"
79
+ width="100%"
80
+ >
81
+ <Styled.Footer direction="row" childGap="6px" justify="space-between">
82
+ {/* To keep rightContent aligned right, use an empty Box as leftContent if none is provided */}
83
+ {showLeft && !!leftContent ? (
84
+ leftContent
85
+ ) : (
86
+ <Box extraStyles="margin-right: auto;" />
87
+ )}
88
+ {showRight && !!rightContent && rightContent}
89
+ </Styled.Footer>
90
+ </Box>
91
+ </Stack>
92
+ );
93
+
94
+ if (isExternalLink) {
95
+ return (
96
+ <ExternalLink
97
+ key={`link-card-${locatorSlug}`}
98
+ href={disabled ? undefined : href}
99
+ newTab={true}
100
+ isUnderlined={false}
101
+ tabIndex={disabled ? "-1" : "0"}
102
+ ariaLabel={`${title}, ${subtitle}`}
103
+ dataQa={`link-card-${locatorSlug}`}
104
+ extraStyles={`${baseStyles} ${hoverActiveStyles}`}
105
+ >
106
+ {cardContent}
107
+ </ExternalLink>
108
+ );
109
+ }
110
+
111
+ return (
112
+ <InternalLink
113
+ key={`link-card-${locatorSlug}`}
114
+ to={disabled ? undefined : href}
115
+ isUnderlined={false}
116
+ hoverUnderline={false}
117
+ tabIndex={disabled ? "-1" : "0"}
118
+ aria-label={`${title}, ${subtitle}`}
119
+ aria-disabled={disabled}
120
+ data-qa={`link-card-${locatorSlug}`}
121
+ extraStyles={`${baseStyles} ${hoverActiveStyles}`}
122
+ >
123
+ {cardContent}
124
+ </InternalLink>
101
125
  );
102
126
  };
103
127
 
@@ -8,7 +8,6 @@ import {
8
8
  import { Box } from "../../atoms/layouts";
9
9
  import LinkCard from "./LinkCard";
10
10
  import Badge from "../../atoms/badge/Badge";
11
- import { fn } from "@storybook/test";
12
11
  import AutopayIcon from "../../atoms/icons/AutopayIcon";
13
12
  import ArrowRightIcon from "../../atoms/icons/ArrowRightIcon";
14
13
  import PlusCircleIcon from "../../atoms/icons/PlusCircleIcon";
@@ -24,11 +23,11 @@ const meta = {
24
23
  args: {
25
24
  title: "Test Workflow",
26
25
  subtitle: "Link your benefit plan",
26
+ href: "/test-workflow",
27
27
  showLeft: undefined,
28
28
  leftContent: undefined,
29
29
  showRight: undefined,
30
30
  rightContent: undefined,
31
- onClick: fn(),
32
31
  extraStyles: "",
33
32
  extraActiveStyles: "",
34
33
  extraHoverStyles: "",
@@ -51,6 +50,14 @@ const meta = {
51
50
  defaultValue: { summary: "Link your benefit plan" }
52
51
  }
53
52
  },
53
+ href: {
54
+ description:
55
+ "URL or path for the LinkCard. Internal path for InternalLink, full URL for ExternalLink",
56
+ table: {
57
+ type: { summary: "string" },
58
+ defaultValue: { summary: undefined }
59
+ }
60
+ },
54
61
  showLeft: {
55
62
  description: "Whether to show the LinkCard's left content",
56
63
  table: {
@@ -79,13 +86,6 @@ const meta = {
79
86
  defaultValue: { summary: undefined }
80
87
  }
81
88
  },
82
- onClick: {
83
- description: "Function to execute on click of LinkCard",
84
- table: {
85
- type: { summary: "function" },
86
- defaultValue: { summary: undefined }
87
- }
88
- },
89
89
  extraStyles: {
90
90
  description: "Extra styles to apply to the LinkCard",
91
91
  table: {
@@ -139,7 +139,8 @@ export default meta;
139
139
  export const BasicLinkCard = {
140
140
  args: {
141
141
  title: "Construction Permits",
142
- subtitle: "Cityville Department of Building Inspection"
142
+ subtitle: "Cityville Department of Building Inspection",
143
+ href: "/permits/construction"
143
144
  },
144
145
  render: args => {
145
146
  return (
@@ -196,7 +197,8 @@ export const BasicLinkCard = {
196
197
  export const ExternalLinkCard = {
197
198
  args: {
198
199
  title: "Construction Permits",
199
- subtitle: "Cityville Department of Building Inspection"
200
+ subtitle: "Cityville Department of Building Inspection",
201
+ href: "https://example.com/permits/construction"
200
202
  },
201
203
  render: args => {
202
204
  return (
@@ -254,7 +256,8 @@ export const ExternalLinkCard = {
254
256
  export const CompleteLinkCard = {
255
257
  args: {
256
258
  title: "Water Bills - Autopay",
257
- subittle: "Cityville Water Management"
259
+ subittle: "Cityville Water Management",
260
+ href: "/water-bills/autopay"
258
261
  },
259
262
  render: args => {
260
263
  return (
@@ -312,7 +315,8 @@ export const CompleteLinkCard = {
312
315
  export const DisabledLinkCard = {
313
316
  args: {
314
317
  title: "Property Tax - Autopay",
315
- subtitle: ""
318
+ subtitle: "",
319
+ href: "/property-tax/autopay"
316
320
  },
317
321
  render: args => {
318
322
  return (
@@ -7,16 +7,7 @@ import {
7
7
  FONT_WEIGHT_REGULAR
8
8
  } from "../../../constants/style_constants";
9
9
 
10
- export const StyledAnchor = styled("a")`
11
- ${({
12
- $disabled: disabled,
13
- $theme: theme,
14
- $extraStyles: extraStyles,
15
- $disabledStyles: disabledStyles,
16
- $hoverStyles: hoverStyles,
17
- $activeStyles: activeStyles
18
- }) => `
19
- display: flex;
10
+ export const getCardBaseStyles = (theme, disabled, extraStyles) => `
20
11
  flex-direction: column;
21
12
  align-items: flex-start;
22
13
  gap: 40px;
@@ -25,51 +16,60 @@ export const StyledAnchor = styled("a")`
25
16
  align-self: stretch;
26
17
  border-radius: 8px;
27
18
  text-decoration: none;
19
+ font-size: inherit;
20
+ color: inherit;
21
+ font-weight: inherit;
22
+ line-height: inherit;
28
23
  background-color: ${
29
24
  disabled ? theme.disabledBackgroundColor : theme.backgroundColor
30
25
  };
31
26
  border: 1px solid
32
27
  ${disabled ? theme.disabledBorderColor : theme.borderColor};
33
28
  transition: all 0.2s ease-in-out;
29
+ ${disabled ? `pointer-events: none;` : ""}
34
30
  ${extraStyles || ""}
31
+ `;
35
32
 
36
- ${
37
- disabled
38
- ? `
39
- &:hover,
40
- &:active {
41
- cursor: default;
42
- box-shadow: none;
43
- border: 1px solid ${theme.disabledBorderColor};
44
- ${disabledStyles || ""}
45
- }
46
- `
47
- : `
48
- &:hover,
49
- &:active {
50
- cursor: pointer;
51
- box-shadow: 0px 0px 0px 0px rgba(41, 42, 51, 0.1),
52
- 0px 5px 11px 0px rgba(41, 42, 51, 0.1),
53
- 0px 4px 19px 0px rgba(41, 42, 51, 0.09),
54
- 0px 27px 26px 0px rgba(41, 42, 51, 0.05),
55
- 0px 56px 31px 0px rgba(41, 42, 51, 0.01),
56
- 0px 80px 33px 0px rgba(41, 42, 51, 0);
57
- }
58
- ${hoverStyles || ""}
33
+ export const getCardHoverActiveStyles = (
34
+ theme,
35
+ disabled,
36
+ hoverStyles,
37
+ activeStyles
38
+ ) => {
39
+ if (disabled) {
40
+ return `
41
+ &:hover,
42
+ &:active {
43
+ cursor: default;
44
+ box-shadow: none;
45
+ border: 1px solid ${theme.disabledBorderColor};
46
+ }
47
+ `;
48
+ }
49
+ return `
50
+ &:hover,
51
+ &:active {
52
+ cursor: pointer;
53
+ box-shadow: 0px 0px 0px 0px rgba(41, 42, 51, 0.1),
54
+ 0px 5px 11px 0px rgba(41, 42, 51, 0.1),
55
+ 0px 4px 19px 0px rgba(41, 42, 51, 0.09),
56
+ 0px 27px 26px 0px rgba(41, 42, 51, 0.05),
57
+ 0px 56px 31px 0px rgba(41, 42, 51, 0.01),
58
+ 0px 80px 33px 0px rgba(41, 42, 51, 0);
59
+ }
60
+ ${hoverStyles || ""}
59
61
 
60
- &:hover:not(:active) {
61
- border: 1px solid ${theme.borderColor};
62
- }
62
+ &:hover:not(:active) {
63
+ border: 1px solid ${theme.borderColor};
64
+ }
63
65
 
64
- &:active {
65
- background-color: ${theme.activeBackgroundColor};
66
- border: 1px solid ${theme.borderColor};
67
- ${activeStyles || ""}
68
- }
69
- `
70
- }
71
- `}
72
- `;
66
+ &:active {
67
+ background-color: ${theme.activeBackgroundColor};
68
+ border: 1px solid ${theme.borderColor};
69
+ ${activeStyles || ""}
70
+ }
71
+ `;
72
+ };
73
73
 
74
74
  export const Title = styled(Heading)`
75
75
  display: -webkit-box;
@@ -1,6 +1,7 @@
1
1
  import {
2
2
  CORNFLOWER_BLUE,
3
3
  LINK_WATER,
4
+ MOON_RAKER,
4
5
  ROYAL_BLUE_VIVID,
5
6
  MANATEE_GREY,
6
7
  GHOST_GREY,
@@ -13,7 +14,7 @@ const disabledBorderColor = GHOST_GREY;
13
14
  const disabledColor = MANATEE_GREY;
14
15
  const activeBackgroundColor = CORNFLOWER_BLUE;
15
16
  const backgroundColor = LINK_WATER;
16
- const borderColor = MANATEE_GREY;
17
+ const borderColor = MOON_RAKER;
17
18
  const color = ROYAL_BLUE_VIVID;
18
19
  const textColor = BRIGHT_GREY;
19
20
 
@@ -5,16 +5,19 @@ export interface LinkCardProps {
5
5
  variant?: string; // "default" is only one
6
6
  title?: string; // title
7
7
  subtitle?: string; // beneath title
8
+ subtitlePadding?: string;
8
9
  themeValues?: any;
9
10
  showLeft?: boolean;
10
11
  leftContent?: JSX.Element;
11
12
  showRight?: boolean;
12
13
  rightContent?: JSX.Element;
13
- onClick: () => void;
14
+ href?: string;
14
15
  extraHoverStyles?: string;
15
16
  extraStyles?: string;
16
17
  extraActiveStyles?: string;
17
18
  titleVariant?: string;
19
+ disabled?: boolean;
20
+ isExternalLink?: boolean;
18
21
  }
19
22
 
20
23
  export const LinkCard: React.FC<Expand<LinkCardProps> &