@thecb/components 11.8.0-beta.4 → 11.8.1-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": "11.8.0-beta.4",
3
+ "version": "11.8.1-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",
@@ -81,8 +81,8 @@
81
81
  "vite": "^5.2.11"
82
82
  },
83
83
  "peerDependencies": {
84
- "react": "^16.13.1",
85
- "react-dom": "^16.13.1",
84
+ "react": "^16.13.1 || ^17.0.0",
85
+ "react-dom": "^16.13.1 || ^17.0.0",
86
86
  "react-router-dom": "^6.3.0",
87
87
  "styled-components": "^5.1.1",
88
88
  "styled-theming": "^2.2.0"
@@ -0,0 +1,88 @@
1
+ import React, { Fragment } from "react";
2
+ import Stack from "../layouts/Stack";
3
+ import Box from "../layouts/Box";
4
+ import Text from "../text";
5
+ import Paragraph from "../paragraph";
6
+ import Cluster from "../layouts/Cluster";
7
+ import ButtonWithAction from "../button-with-action";
8
+ import ButtonWithLink from "../button-with-link";
9
+ import { WHITE, CHARADE_GREY, STORM_GREY } from "../../../constants/colors";
10
+ import Popover from "../../molecules/popover";
11
+
12
+ const DisplayCard = ({
13
+ title,
14
+ item,
15
+ buttonText,
16
+ buttonAction,
17
+ url,
18
+ link = false,
19
+ helpText,
20
+ hasPopover = false,
21
+ popoverTriggerText = "",
22
+ popoverContent = "",
23
+ popoverExtraStyles,
24
+ popoverTextExtraStyles
25
+ }) => (
26
+ <Box padding="0 0 16px">
27
+ <Stack childGap="0rem">
28
+ <Box padding="0 0 8px 0">
29
+ <Cluster justify="space-between" align="center" overflow>
30
+ <Paragraph
31
+ variant="pL"
32
+ color={CHARADE_GREY}
33
+ extraStyles={`letter-spacing: 0.29px`}
34
+ >
35
+ {title}
36
+ </Paragraph>
37
+ {hasPopover && (
38
+ <Popover
39
+ triggerText={popoverTriggerText}
40
+ content={popoverContent}
41
+ popoverExtraStyles={popoverExtraStyles}
42
+ popoverTextExtraStyles={popoverTextExtraStyles}
43
+ />
44
+ )}
45
+ </Cluster>
46
+ </Box>
47
+ <Box padding="0">
48
+ <Box
49
+ padding="24px"
50
+ borderSize="1px"
51
+ borderRadius="4px"
52
+ background={WHITE}
53
+ boxShadow="0px 2px 14px 0px rgb(246, 246, 249),
54
+ 0px 3px 8px 0px rgb(202, 206, 216)"
55
+ >
56
+ <Cluster justify="space-between" align="center">
57
+ <Text color={CHARADE_GREY}>{item}</Text>
58
+ {link ? (
59
+ <ButtonWithLink
60
+ text={buttonText}
61
+ url={url}
62
+ variant="smallGhost"
63
+ dataQa={buttonText}
64
+ extraStyles={`min-width: 0;`}
65
+ />
66
+ ) : buttonAction ? (
67
+ <ButtonWithAction
68
+ text={buttonText}
69
+ action={buttonAction}
70
+ variant="smallGhost"
71
+ dataQa={buttonText}
72
+ extraStyles={`min-width: 0;`}
73
+ />
74
+ ) : helpText ? (
75
+ <Text color={STORM_GREY} extraStyles={`font-style: italic;`}>
76
+ {helpText}
77
+ </Text>
78
+ ) : (
79
+ <Fragment />
80
+ )}
81
+ </Cluster>
82
+ </Box>
83
+ </Box>
84
+ </Stack>
85
+ </Box>
86
+ );
87
+
88
+ export default DisplayCard;
@@ -0,0 +1,13 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as DisplayCardStories from './DisplayCard.stories.js';
4
+
5
+ <Meta of={DisplayCardStories} />
6
+
7
+ <Title />
8
+
9
+ The DisplayCard component offers a consistent box style for text content. A link, button, or "help" text is also supported, which will be displayed with the text in a flexbox with any extra space rendered in-between. DisplayCard also supports an optional tooltip with the Popover molecule, and a title.
10
+
11
+ Note: DisplyCard is _not_ themeable or styleable except for the Popover box.
12
+
13
+ <Story />
@@ -0,0 +1,165 @@
1
+ import DisplayCard from "./DisplayCard";
2
+ import React from "react";
3
+ import { fn } from "@storybook/test";
4
+
5
+ const meta = {
6
+ title: "Atoms/DisplayCard",
7
+ component: DisplayCard,
8
+ parameters: {
9
+ layout: "centered",
10
+ controls: { expanded: true }
11
+ },
12
+ tags: ["!autodocs"],
13
+ args: {
14
+ title: "Display Card",
15
+ item: "Item text",
16
+ buttonText: undefined,
17
+ buttonAction: undefined,
18
+ url: undefined,
19
+ link: false,
20
+ helpText: undefined,
21
+ hasPopover: false,
22
+ popoverTriggerText: "",
23
+ popoverContent: "",
24
+ popoverExtraStyles: undefined,
25
+ popoverTextExtraStyles: undefined
26
+ },
27
+ argTypes: {
28
+ title: {
29
+ description: "Text that appears above the box",
30
+ table: {
31
+ type: { summary: "string" },
32
+ defaultValue: { summary: undefined }
33
+ }
34
+ },
35
+ item: {
36
+ description: "Text that appears in the box",
37
+ table: {
38
+ type: { summary: "string" },
39
+ defaultValue: { summary: undefined }
40
+ }
41
+ },
42
+ buttonText: {
43
+ description: "Text for the button or link",
44
+ table: {
45
+ type: { summary: "string" },
46
+ defaultValue: { summary: undefined }
47
+ }
48
+ },
49
+ buttonAction: {
50
+ description: "Callback function for the button",
51
+ table: {
52
+ type: { summary: "function" },
53
+ defaultValue: { summary: undefined }
54
+ }
55
+ },
56
+ url: {
57
+ description: "URL for the link",
58
+ table: {
59
+ type: { summary: "string" },
60
+ defaultValue: { summary: undefined }
61
+ }
62
+ },
63
+ link: {
64
+ description:
65
+ "Whether or not to display a link, uses the `url` and `buttonText` props",
66
+ table: {
67
+ type: { summary: "boolean" },
68
+ defaultValue: { summary: false }
69
+ }
70
+ },
71
+ helpText: {
72
+ description:
73
+ "Text rendered to the right of the `item` text and styled as italic.",
74
+ table: {
75
+ type: { summary: "string" },
76
+ defaultValue: { summary: undefined }
77
+ }
78
+ },
79
+ hasPopover: {
80
+ description: "Whether or not to render Popover component",
81
+ table: {
82
+ type: { summary: "boolean" },
83
+ defaultValue: { summary: false }
84
+ }
85
+ },
86
+ popoverTriggerText: {
87
+ table: {
88
+ type: { summary: "string" },
89
+ defaultValue: { summary: "" }
90
+ }
91
+ },
92
+ popoverContent: {
93
+ table: {
94
+ type: { summary: "string" },
95
+ defaultValue: { summary: "" }
96
+ }
97
+ },
98
+ popoverExtraStyles: {
99
+ description: "Styles for the Box that wraps the Popover content.",
100
+ table: {
101
+ type: { summary: "string" },
102
+ defaultValue: { summary: undefined }
103
+ }
104
+ },
105
+ popoverTextExtraStyles: {
106
+ description: "Prop passed to the Popover component, but is not used.",
107
+ table: {
108
+ type: { summary: "string" },
109
+ defaultValue: { summary: undefined }
110
+ }
111
+ }
112
+ }
113
+ };
114
+
115
+ export default meta;
116
+
117
+ export const Basic = {
118
+ render: args => <DisplayCard {...args} />
119
+ };
120
+
121
+ export const WithLink = {
122
+ args: {
123
+ buttonText: "Link",
124
+ url: "https://example.com",
125
+ link: true
126
+ },
127
+ render: args => <DisplayCard {...args} />
128
+ };
129
+
130
+ export const WithButtonAction = {
131
+ args: {
132
+ buttonText: "Button",
133
+ buttonAction: fn()
134
+ },
135
+ render: args => <DisplayCard {...args} />
136
+ };
137
+
138
+ export const WithHelpText = {
139
+ parameters: {
140
+ layout: "padded"
141
+ },
142
+ args: {
143
+ helpText: "Help!"
144
+ },
145
+ render: args => <DisplayCard {...args} />
146
+ };
147
+
148
+ export const WithPopover = {
149
+ args: {
150
+ hasPopover: true,
151
+ popoverTriggerText: "Popover",
152
+ popoverContent: "This is example popover content!"
153
+ },
154
+ render: args => <DisplayCard {...args} />
155
+ };
156
+
157
+ export const WithPopoverAndExtraStyles = {
158
+ args: {
159
+ hasPopover: true,
160
+ popoverTriggerText: "Popover",
161
+ popoverContent: "This is example popover content!",
162
+ popoverExtraStyles: "padding: 4px 8px"
163
+ },
164
+ render: args => <DisplayCard {...args} />
165
+ };
@@ -0,0 +1,3 @@
1
+ import DisplayCard from "./DisplayCard";
2
+
3
+ export default DisplayCard;
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- const IconAdd = ({ stroke = "none", strokeWidth = 1 }) => (
3
+ const IconAdd = ({ strokeWidth = 1 }) => (
4
4
  <svg
5
5
  xmlns="http://www.w3.org/2000/svg"
6
6
  xmlnsXlink="http://www.w3.org/1999/xlink"
@@ -15,7 +15,7 @@ const IconAdd = ({ stroke = "none", strokeWidth = 1 }) => (
15
15
  d="M7.91666623 4.78508747L4.78508747 4.78508747 4.78508747 7.91666623 3.74122788 7.91666623 3.74122788 4.78508747 0.609649123 4.78508747 0.609649123 3.74122788 3.74122788 3.74122788 3.74122788 0.609649123 4.78508747 0.609649123 4.78508747 3.74122788 7.91666623 3.74122788z"
16
16
  ></path>
17
17
  </defs>
18
- <g fill="none" fillRule="evenodd" stroke={stroke} strokeWidth={strokeWidth}>
18
+ <g fill="none" fillRule="evenodd" stroke="none" strokeWidth={strokeWidth}>
19
19
  <g transform="translate(-407 -563)">
20
20
  <g transform="translate(408 562)">
21
21
  <g transform="translate(0 2)">
@@ -13,6 +13,7 @@ export { default as SortableTableHeading } from "./sortable-table-heading";
13
13
  export { default as CountryDropdown } from "./country-dropdown";
14
14
  export { default as Detail } from "./detail";
15
15
  export { default as DisplayBox } from "./display-box";
16
+ export { default as DisplayCard } from "./display-card";
16
17
  export { default as Dropdown } from "./dropdown";
17
18
  export * from "./form-layouts";
18
19
  export { default as FormSelect } from "./form-select";
@@ -47,4 +47,3 @@ export { default as MultipleSelectFilter } from "./multiple-select-filter";
47
47
  export { default as ContactCard } from "./contact-card";
48
48
  export { default as HeroImage } from "./hero-image";
49
49
  export { default as TurnstileWidget } from "./turnstile-widget/TurnstileWidget";
50
- export { default as Tooltip } from "./tooltip";
@@ -36,7 +36,7 @@ const SidebarStackContent = ({
36
36
  >
37
37
  <Cover centerOverride={!sidebarVerticalCenter} key="page-cover">
38
38
  {header ? header : <Box padding="0" key="header-box" />}
39
- <Box padding="0" minWidth="100%" key="content-box" role="main">
39
+ <Box padding="0" minWidth="100%" key="content-box">
40
40
  {subHeader && !(isMobile && hideMobileSubHeader) ? (
41
41
  subHeader
42
42
  ) : (
@@ -1,149 +0,0 @@
1
- import React, { useState } from "react";
2
- import { themeComponent } from "../../../util/themeUtils";
3
- import Text from "../../atoms/text";
4
- import Paragraph from "../../atoms/paragraph";
5
- import { Box } from "../../atoms/layouts";
6
- import ButtonWithAction from "../../atoms/button-with-action";
7
- import { noop } from "../../../util/general";
8
- import { ESCAPE } from "../../../constants/keyboard";
9
- import { fallbackValues } from "./Tooltip.theme";
10
- import WarningIconXS from "../../atoms/icons/WarningIconXS";
11
- import { SELECTIVE_YELLOW } from "../../../constants/colors";
12
-
13
- const arrowBorder = (borderColor, direction, width = "8px") => {
14
- const angle = `${width} solid transparent`;
15
- const straight = `${width} solid ${borderColor}`;
16
- if (direction == "down") {
17
- return `border-left: ${angle}; border-right: ${angle}; border-top: ${straight}`;
18
- } else if (direction == "up") {
19
- return `border-left: ${angle}; border-right: ${angle}; border-bottom: ${straight}`;
20
- } else if (direction == "left") {
21
- return `border-top: ${angle}; border-bottom: ${angle}; border-right: ${straight}`;
22
- } else if (direction == "right") {
23
- return `border-top: ${angle}; border-bottom: ${angle}; border-left: ${straight}`;
24
- }
25
- };
26
-
27
- const Tooltip = ({
28
- themeValues,
29
- triggerText = "",
30
- content = "",
31
- hasIconTrigger = false,
32
- IconTrigger = WarningIconXS,
33
- iconHelpText = "",
34
- tooltipID = "tooltip-content",
35
- extraStyles = "",
36
- textExtraStyles = "",
37
- minWidth = "250px",
38
- maxWidth = "300px",
39
- height = "auto",
40
- arrowDirection = "down",
41
- arrowPosition = {
42
- arrowTop: "auto",
43
- arrowRight: "10px",
44
- arrowBottom: "-8px",
45
- arrowLeft: "auto"
46
- },
47
- position = {
48
- top: "-110px",
49
- right: "auto",
50
- bottom: "auto",
51
- left: "-225px"
52
- },
53
- iconColor = SELECTIVE_YELLOW,
54
- buttonExtraStyles,
55
- backgroundColor = "white",
56
- borderColor = "rgba(255, 255, 255, 0.85)",
57
- tooltipContentExtraStyles
58
- }) => {
59
- const { hoverColor, activeColor, tooltipTriggerColor } = themeValues;
60
- const { top, right, bottom, left } = position ?? {};
61
- const { arrowTop, arrowRight, arrowBottom, arrowLeft } = arrowPosition ?? {};
62
-
63
- const [tooltipOpen, setTooltipOpen] = useState(false);
64
-
65
- const handleToggleTooltip = tooltipState => {
66
- if (tooltipOpen !== tooltipState) {
67
- setTooltipOpen(tooltipState);
68
- }
69
- };
70
-
71
- const handleKeyboardEvent = e => {
72
- if (e.keyCode === ESCAPE || e.keyCode === 9) {
73
- handleToggleTooltip(false);
74
- }
75
- };
76
-
77
- return (
78
- <Box padding="0" extraStyles={`position: relative; ${extraStyles}`}>
79
- <ButtonWithAction
80
- action={() => noop}
81
- onFocus={() => handleToggleTooltip(true)}
82
- onBlur={() => handleToggleTooltip(false)}
83
- onKeyDown={handleKeyboardEvent}
84
- onTouchStart={() => handleToggleTooltip(true)}
85
- onTouchEnd={() => handleToggleTooltip(false)}
86
- onMouseEnter={() => handleToggleTooltip(true)}
87
- onMouseLeave={() => handleToggleTooltip(false)}
88
- contentOverride
89
- variant="smallGhost"
90
- tabIndex="0"
91
- aria-describedby={tooltipID}
92
- extraStyles={buttonExtraStyles}
93
- >
94
- {hasIconTrigger && (
95
- <>
96
- <Box aria-label="Trigger Popover">
97
- <IconTrigger color={iconColor} />
98
- </Box>
99
- <Box padding="0" srOnly aria-hidden="true">
100
- <Text>{iconHelpText}</Text>
101
- </Box>
102
- </>
103
- )}
104
- {!hasIconTrigger && (
105
- <Text extraStyles={textExtraStyles}>{triggerText}</Text>
106
- )}
107
- </ButtonWithAction>
108
- <Box
109
- background={backgroundColor}
110
- borderRadius="4px"
111
- boxShadow="0px 2px 14px 0px rgb(246, 246, 249), 0px 3px 8px 0px rgb(202, 206, 216)"
112
- id={tooltipID}
113
- role="tooltip"
114
- minWidth={minWidth}
115
- maxWidth={maxWidth}
116
- aria-hidden={!tooltipOpen}
117
- extraStyles={`
118
- display: ${tooltipOpen ? "block" : "none"};
119
- position: absolute;
120
- top: ${top};
121
- right: ${right};
122
- bottom: ${bottom};
123
- left: ${left};
124
- height: ${height};
125
- ${tooltipContentExtraStyles};
126
- `}
127
- >
128
- <Paragraph>{content}</Paragraph>
129
- <Box
130
- padding="0"
131
- extraStyles={`
132
- position: absolute;
133
- content: "";
134
- width: 0;
135
- height: 0;
136
- ${arrowBorder(borderColor, arrowDirection, "8px")};
137
- filter: drop-shadow(2px 8px 14px black);
138
- bottom: ${arrowBottom};
139
- right: ${arrowRight};
140
- top: ${arrowTop};
141
- left: ${arrowLeft};
142
- `}
143
- />
144
- </Box>
145
- </Box>
146
- );
147
- };
148
-
149
- export default themeComponent(Tooltip, "Tooltip", fallbackValues);
@@ -1,15 +0,0 @@
1
- import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
-
3
- import * as TooltipStories from './Tooltip.stories.js';
4
-
5
- <Meta of={TooltipStories} />
6
-
7
- <Title />
8
-
9
- The Tooltip is a fully accessible tooltip widget that displays additional information when a user hovers over or focuses on a specified trigger element. The trigger can either be text supplied using the `triggerText` prop, or a custom Icon component supplied using the `icon` prop. The trigger is rendered as a `ButtonWithAction` with the `smallGhost` variant.
10
-
11
- The Tooltip uses the WAI-ARIA tooltip pattern (`role="tooltip"` and `aria-describedby`) for accessibility. It can be positioned anywhere around the trigger element using the position props. Content and style of the tooltip are customizable.
12
-
13
- <Controls />
14
-
15
- <Story />