@thecb/components 6.2.7 → 6.3.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/dist/index.cjs.js +14910 -14741
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +14908 -14740
- package/dist/index.esm.js.map +1 -1
- package/package.json +1 -1
- package/src/components/atoms/display-card/DisplayCard.js +34 -9
- package/src/components/atoms/text/Text.js +2 -0
- package/src/components/atoms/welcome-card/index.js +6 -6
- package/src/components/molecules/index.js +2 -1
- package/src/components/molecules/popover/Popover.js +119 -0
- package/src/components/molecules/popover/Popover.theme.js +9 -0
- package/src/components/molecules/popover/index.js +3 -0
- package/src/components/withWindowSize.js +1 -14
- package/src/util/general.js +14 -0
- package/src/util/index.js +2 -1
- package/src/util/useOutsideClickHook.js +36 -0
package/package.json
CHANGED
|
@@ -6,7 +6,8 @@ import Paragraph from "../paragraph";
|
|
|
6
6
|
import Cluster from "../layouts/Cluster";
|
|
7
7
|
import ButtonWithAction from "../button-with-action";
|
|
8
8
|
import ButtonWithLink from "../button-with-link";
|
|
9
|
-
import { WHITE, CHARADE_GREY } from "../../../constants/colors";
|
|
9
|
+
import { WHITE, CHARADE_GREY, STORM_GREY } from "../../../constants/colors";
|
|
10
|
+
import { Popover } from "../../molecules";
|
|
10
11
|
|
|
11
12
|
const DisplayCard = ({
|
|
12
13
|
title,
|
|
@@ -14,18 +15,34 @@ const DisplayCard = ({
|
|
|
14
15
|
buttonText,
|
|
15
16
|
buttonAction,
|
|
16
17
|
url,
|
|
17
|
-
link = false
|
|
18
|
+
link = false,
|
|
19
|
+
helpText,
|
|
20
|
+
usePopover = false,
|
|
21
|
+
popoverTriggerText = "",
|
|
22
|
+
popoverContent = "",
|
|
23
|
+
popoverExtraStyles,
|
|
24
|
+
popoverTextExtraStyles
|
|
18
25
|
}) => (
|
|
19
26
|
<Box padding="0 0 16px">
|
|
20
27
|
<Stack childGap="0rem">
|
|
21
28
|
<Box padding="0 0 8px 0">
|
|
22
|
-
<
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
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
|
+
{usePopover && (
|
|
38
|
+
<Popover
|
|
39
|
+
triggerText={popoverTriggerText}
|
|
40
|
+
content={popoverContent}
|
|
41
|
+
popoverExtraStyles={popoverExtraStyles}
|
|
42
|
+
popoverTextExtraStyles={popoverTextExtraStyles}
|
|
43
|
+
/>
|
|
44
|
+
)}
|
|
45
|
+
</Cluster>
|
|
29
46
|
</Box>
|
|
30
47
|
<Box padding="0">
|
|
31
48
|
<Box
|
|
@@ -56,6 +73,14 @@ const DisplayCard = ({
|
|
|
56
73
|
dataQa={buttonText}
|
|
57
74
|
extraStyles={`min-width: 0;`}
|
|
58
75
|
/>
|
|
76
|
+
) : helpText ? (
|
|
77
|
+
<Text
|
|
78
|
+
variant="p"
|
|
79
|
+
color={STORM_GREY}
|
|
80
|
+
extraStyles={`font-style: italic;`}
|
|
81
|
+
>
|
|
82
|
+
{helpText}
|
|
83
|
+
</Text>
|
|
59
84
|
) : (
|
|
60
85
|
<Fragment />
|
|
61
86
|
)}
|
|
@@ -18,6 +18,7 @@ const Text = ({
|
|
|
18
18
|
as,
|
|
19
19
|
dataQa,
|
|
20
20
|
children,
|
|
21
|
+
variant = "p",
|
|
21
22
|
...rest
|
|
22
23
|
}) => (
|
|
23
24
|
<TextSpan
|
|
@@ -32,6 +33,7 @@ const Text = ({
|
|
|
32
33
|
onKeyPress={onKeyPress}
|
|
33
34
|
data-qa={dataQa}
|
|
34
35
|
$textWrap={textWrap}
|
|
36
|
+
$variant={variant}
|
|
35
37
|
{...rest}
|
|
36
38
|
>
|
|
37
39
|
{safeChildren(children, <span />)}
|
|
@@ -5,8 +5,8 @@ export const cardRegistry = {
|
|
|
5
5
|
accounts: props => (
|
|
6
6
|
<Card
|
|
7
7
|
icon="accounts"
|
|
8
|
-
heading="
|
|
9
|
-
buttonText="
|
|
8
|
+
heading="Find Your Account"
|
|
9
|
+
buttonText="Find Account"
|
|
10
10
|
text="Find and attach your accounts to make your payments simple."
|
|
11
11
|
cardAction="/profile/accounts"
|
|
12
12
|
{...props}
|
|
@@ -15,8 +15,8 @@ export const cardRegistry = {
|
|
|
15
15
|
properties: props => (
|
|
16
16
|
<Card
|
|
17
17
|
icon="properties"
|
|
18
|
-
heading="
|
|
19
|
-
buttonText="
|
|
18
|
+
heading="Find Your Property"
|
|
19
|
+
buttonText="Find Property"
|
|
20
20
|
text="Find and attach your properties to make your tax payments simple."
|
|
21
21
|
cardAction="/profile/properties"
|
|
22
22
|
{...props}
|
|
@@ -25,8 +25,8 @@ export const cardRegistry = {
|
|
|
25
25
|
payment: props => (
|
|
26
26
|
<Card
|
|
27
27
|
icon="payment"
|
|
28
|
-
heading="
|
|
29
|
-
buttonText="
|
|
28
|
+
heading="Manage Your Wallet"
|
|
29
|
+
buttonText="Go to Wallet"
|
|
30
30
|
text="Add your personal information and payment methods to make fast payments."
|
|
31
31
|
cardAction="/profile/settings"
|
|
32
32
|
{...props}
|
|
@@ -20,7 +20,9 @@ export { default as PaymentButtonBar } from "./payment-button-bar";
|
|
|
20
20
|
export { default as PaymentDetails } from "./payment-details";
|
|
21
21
|
export { default as PaymentFormACH } from "./payment-form-ach";
|
|
22
22
|
export { default as PaymentFormCard } from "./payment-form-card";
|
|
23
|
+
export { default as PeriscopeDashboardIframe } from "./periscope-dashboard-iframe";
|
|
23
24
|
export { default as PhoneForm } from "./phone-form";
|
|
25
|
+
export { default as Popover } from "./popover";
|
|
24
26
|
export { default as RadioSection } from "./radio-section";
|
|
25
27
|
export { default as RegistrationForm } from "./registration-form";
|
|
26
28
|
export { default as ResetConfirmationForm } from "./reset-confirmation-form";
|
|
@@ -33,4 +35,3 @@ export { default as TermsAndConditionsModal } from "./terms-and-conditions-modal
|
|
|
33
35
|
export { default as Timeout } from "./timeout";
|
|
34
36
|
export { default as WelcomeModule } from "./welcome-module";
|
|
35
37
|
export { default as WorkflowTile } from "./workflow-tile";
|
|
36
|
-
export { default as PeriscopeDashboardIframe } from "./periscope-dashboard-iframe";
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
import React, { useState, useContext } 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 { useOutsideClickHook } from "../../../util";
|
|
8
|
+
import { noop } from "../../../util/general";
|
|
9
|
+
import { fallbackValues } from "./Popover.theme";
|
|
10
|
+
|
|
11
|
+
const Popover = ({
|
|
12
|
+
themeValues,
|
|
13
|
+
triggerText = "",
|
|
14
|
+
content = "",
|
|
15
|
+
useIcon = false,
|
|
16
|
+
icon: Icon,
|
|
17
|
+
iconHelpText = "", // for screen-readers, required if using an icon for trigger
|
|
18
|
+
popoverID = 0,
|
|
19
|
+
popoverFocus = false,
|
|
20
|
+
extraStyles,
|
|
21
|
+
textExtraStyles,
|
|
22
|
+
minWidth = "250px",
|
|
23
|
+
maxWidth = "300px",
|
|
24
|
+
height = "auto",
|
|
25
|
+
position // { top: string, right: string, bottom: string, left: string }
|
|
26
|
+
}) => {
|
|
27
|
+
const { hoverColor, activeColor, popoverTriggerColor } = themeValues;
|
|
28
|
+
const { top = "-110px", right = "auto", bottom = "auto", left = "-225px" } =
|
|
29
|
+
position ?? {};
|
|
30
|
+
|
|
31
|
+
const [popoverOpen, togglePopover] = useState(false);
|
|
32
|
+
|
|
33
|
+
const handleTogglePopover = popoverState => {
|
|
34
|
+
if (popoverOpen !== popoverState) {
|
|
35
|
+
togglePopover(popoverState);
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
const triggerRef = useOutsideClickHook(() => handleTogglePopover(false));
|
|
40
|
+
|
|
41
|
+
return (
|
|
42
|
+
<Box padding="0" extraStyles={`position: relative; ${extraStyles}`}>
|
|
43
|
+
<ButtonWithAction
|
|
44
|
+
action={() => noop}
|
|
45
|
+
onFocus={() => {
|
|
46
|
+
console.log("on focus") || handleTogglePopover(true);
|
|
47
|
+
}}
|
|
48
|
+
onBlur={() => {
|
|
49
|
+
console.log("on blur") || handleTogglePopover(false);
|
|
50
|
+
}}
|
|
51
|
+
onKeyDown={e => {
|
|
52
|
+
if (e.keyCode === 27) {
|
|
53
|
+
console.log("on key down") || handleTogglePopover(false);
|
|
54
|
+
}
|
|
55
|
+
}}
|
|
56
|
+
onTouchStart={() =>
|
|
57
|
+
console.log("on touch start") || handleTogglePopover(true)
|
|
58
|
+
}
|
|
59
|
+
onTouchEnd={() =>
|
|
60
|
+
console.log("on touch end") || handleTogglePopover(false)
|
|
61
|
+
}
|
|
62
|
+
onMouseEnter={() => handleTogglePopover(true)}
|
|
63
|
+
onMouseLeave={() => handleTogglePopover(false)}
|
|
64
|
+
contentOverride
|
|
65
|
+
variant="smallGhost"
|
|
66
|
+
tabIndex="0"
|
|
67
|
+
id={`btnPopover${popoverID}`}
|
|
68
|
+
aria-expanded={popoverOpen}
|
|
69
|
+
aria-labelledby={`btnPopover${popoverID}_info Disclosure${popoverID}`}
|
|
70
|
+
aria-describedby={`Disclosure${popoverID}`}
|
|
71
|
+
aria-controls={`Disclosed${popoverID}`}
|
|
72
|
+
ref={triggerRef}
|
|
73
|
+
>
|
|
74
|
+
{useIcon && <Icon />}
|
|
75
|
+
{useIcon && (
|
|
76
|
+
<Box padding="0" srOnly>
|
|
77
|
+
<Text id={`btnPopover${popoverID}_info`}>{iconHelpText}</Text>
|
|
78
|
+
</Box>
|
|
79
|
+
)}
|
|
80
|
+
{!useIcon && (
|
|
81
|
+
<Text
|
|
82
|
+
color={popoverTriggerColor}
|
|
83
|
+
extraStyles={`&:active { color: ${activeColor}; } &:hover { color: ${hoverColor} }; ${textExtraStyles}`}
|
|
84
|
+
>
|
|
85
|
+
{triggerText}
|
|
86
|
+
</Text>
|
|
87
|
+
)}
|
|
88
|
+
</ButtonWithAction>
|
|
89
|
+
<Box
|
|
90
|
+
background="white"
|
|
91
|
+
borderRadius="4px"
|
|
92
|
+
boxShadow="0px 2px 14px 0px rgb(246, 246, 249), 0px 3px 8px 0px rgb(202, 206, 216)"
|
|
93
|
+
id={`Disclosed${popoverID}`}
|
|
94
|
+
role={"region"}
|
|
95
|
+
aria-describedby={`Disclosure${popoverID}`}
|
|
96
|
+
tabIndex={popoverFocus && popoverOpen ? "0" : "-1"}
|
|
97
|
+
minWidth={minWidth}
|
|
98
|
+
maxWidth={maxWidth}
|
|
99
|
+
extraStyles={`
|
|
100
|
+
display: ${popoverOpen ? "block" : "none"};
|
|
101
|
+
position: absolute;
|
|
102
|
+
top: ${top};
|
|
103
|
+
right: ${right};
|
|
104
|
+
bottom: ${bottom};
|
|
105
|
+
left: ${left};
|
|
106
|
+
height: ${height}
|
|
107
|
+
`}
|
|
108
|
+
>
|
|
109
|
+
<Paragraph>{content}</Paragraph>
|
|
110
|
+
<Box
|
|
111
|
+
padding="0"
|
|
112
|
+
extraStyles={`position: absolute; content: ""; width: 0; height: 0; border-left: 8px solid transparent; border-right: 8px solid transparent; border-top: 8px solid rgba(255, 255, 255, 0.85); filter: drop-shadow(2px 8px 14px black); bottom: -8px; right: 10px;`}
|
|
113
|
+
/>
|
|
114
|
+
</Box>
|
|
115
|
+
</Box>
|
|
116
|
+
);
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
export default themeComponent(Popover, "Popover", fallbackValues);
|
|
@@ -1,19 +1,6 @@
|
|
|
1
1
|
import React, { useState, useLayoutEffect, useRef } from "react";
|
|
2
2
|
import { ThemeProvider } from "styled-components";
|
|
3
|
-
|
|
4
|
-
const MOBILE_WIDTH = 768;
|
|
5
|
-
|
|
6
|
-
const throttle = (delay, fn) => {
|
|
7
|
-
let lastCall = 0;
|
|
8
|
-
return (...args) => {
|
|
9
|
-
const now = new Date().getTime();
|
|
10
|
-
if (now - lastCall < delay) {
|
|
11
|
-
return;
|
|
12
|
-
}
|
|
13
|
-
lastCall = now;
|
|
14
|
-
return fn(...args);
|
|
15
|
-
};
|
|
16
|
-
};
|
|
3
|
+
import { MOBILE_WIDTH, throttle } from "../util/general";
|
|
17
4
|
|
|
18
5
|
const withWindowSize = Child => ({ ...props }) => {
|
|
19
6
|
const [state, setState] = useState({
|
package/src/util/general.js
CHANGED
|
@@ -130,3 +130,17 @@ export const inputDisabledStyle = `
|
|
|
130
130
|
background-color: #f7f7f7;
|
|
131
131
|
pointer-events: none;
|
|
132
132
|
`;
|
|
133
|
+
|
|
134
|
+
export const MOBILE_WIDTH = 768;
|
|
135
|
+
|
|
136
|
+
export const throttle = (delay, fn) => {
|
|
137
|
+
let lastCall = 0;
|
|
138
|
+
return (...args) => {
|
|
139
|
+
const now = new Date().getTime();
|
|
140
|
+
if (now - lastCall < delay) {
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
lastCall = now;
|
|
144
|
+
return fn(...args);
|
|
145
|
+
};
|
|
146
|
+
};
|
package/src/util/index.js
CHANGED
|
@@ -2,5 +2,6 @@ import * as formats from "./formats";
|
|
|
2
2
|
import * as general from "./general";
|
|
3
3
|
import * as theme from "./themeUtils";
|
|
4
4
|
import useFocusInvalidInput from "./focusFirstInvalidInputHook";
|
|
5
|
+
import useOutsideClickHook from "./useOutsideClickHook";
|
|
5
6
|
|
|
6
|
-
export { formats, general, theme, useFocusInvalidInput };
|
|
7
|
+
export { formats, general, theme, useFocusInvalidInput, useOutsideClickHook };
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import { useRef, useEffect } from "react";
|
|
2
|
+
|
|
3
|
+
/*
|
|
4
|
+
Hook that assigns an onPointerUp event listener to the main document element
|
|
5
|
+
Returns a ref to attach to another element (like an icon/button that triggers a popover)
|
|
6
|
+
If a pointerup event gets captured by the document and the assigned element isn't the target
|
|
7
|
+
hook will run whatever handler is passed (eg a function that closes a popover)
|
|
8
|
+
|
|
9
|
+
See tooltip component for implementation
|
|
10
|
+
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
const useOutsideClickHook = handler => {
|
|
14
|
+
const ref = useRef();
|
|
15
|
+
|
|
16
|
+
useEffect(() => {
|
|
17
|
+
const handleOutsideClick = e => {
|
|
18
|
+
if (ref.current && !ref.current.contains(e.target)) {
|
|
19
|
+
console.log("in outside click handler");
|
|
20
|
+
console.log("ref", ref);
|
|
21
|
+
console.log("target", e.target);
|
|
22
|
+
handler();
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
document.addEventListener("click", handleOutsideClick, true);
|
|
26
|
+
|
|
27
|
+
return () => {
|
|
28
|
+
document.removeEventListener("click", handleOutsideClick, true);
|
|
29
|
+
};
|
|
30
|
+
};
|
|
31
|
+
}, [ref]);
|
|
32
|
+
|
|
33
|
+
return ref;
|
|
34
|
+
};
|
|
35
|
+
|
|
36
|
+
export default useOutsideClickHook;
|