@thecb/components 10.12.6-beta.0 → 11.0.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/README.md +14 -6
- package/dist/index.cjs.js +1311 -1482
- package/dist/index.cjs.js.map +1 -1
- package/dist/index.esm.js +1311 -1483
- package/dist/index.esm.js.map +1 -1
- package/package.json +25 -13
- package/src/.DS_Store +0 -0
- package/src/components/.DS_Store +0 -0
- package/src/components/atoms/.DS_Store +0 -0
- package/src/components/atoms/alert/Alert.mdx +19 -0
- package/src/components/atoms/alert/Alert.stories.js +148 -26
- package/src/components/atoms/badge/Badge.js +2 -2
- package/src/components/atoms/badge/Badge.mdx +27 -0
- package/src/components/atoms/badge/Badge.stories.js +143 -29
- package/src/components/atoms/breadcrumb/Breadcrumb.mdx +21 -0
- package/src/components/atoms/breadcrumb/Breadcrumb.stories.js +38 -29
- package/src/components/atoms/button-with-action/ButtonWithAction.stories.js +108 -55
- package/src/components/atoms/button-with-link/ButtonWithLink.mdx +21 -0
- package/src/components/atoms/button-with-link/ButtonWithLink.stories.js +160 -31
- package/src/components/atoms/card/Card.mdx +41 -0
- package/src/components/atoms/card/Card.stories.js +351 -0
- package/src/components/atoms/card/CardText.js +6 -1
- package/src/components/atoms/checkbox/Checkbox.mdx +15 -0
- package/src/components/atoms/checkbox/Checkbox.oldstories.js +34 -0
- package/src/components/atoms/checkbox/Checkbox.stories.js +140 -25
- package/src/components/atoms/country-dropdown/CountryDropdown.mdx +36 -0
- package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +61 -27
- package/src/components/atoms/detail/Detail.js +0 -26
- package/src/components/atoms/detail/Detail.mdx +32 -0
- package/src/components/atoms/detail/Detail.stories.js +156 -0
- package/src/components/atoms/display-box/DisplayBox.mdx +11 -0
- package/src/components/atoms/display-box/DisplayBox.stories.js +65 -21
- package/src/components/atoms/display-card/DisplayCard.mdx +13 -0
- package/src/components/atoms/display-card/DisplayCard.stories.js +163 -22
- package/src/components/atoms/dropdown/Dropdown.mdx +65 -0
- package/src/components/atoms/dropdown/Dropdown.stories.js +91 -10
- package/src/components/atoms/form-layouts/FormInput.mdx +38 -0
- package/src/components/atoms/form-layouts/FormInput.stories.js +212 -26
- package/src/components/atoms/form-select/FormSelect.mdx +42 -0
- package/src/components/atoms/form-select/FormSelect.stories.js +55 -29
- package/src/components/atoms/formatted-address/FormattedAddress.mdx +13 -0
- package/src/components/atoms/formatted-address/FormattedAddress.stories.js +133 -27
- package/src/components/atoms/formatted-bank-account/FormattedBankAccount.mdx +17 -0
- package/src/components/atoms/formatted-bank-account/FormattedBankAccount.stories.js +57 -0
- package/src/components/atoms/formatted-credit-card/FormattedCreditCard.mdx +40 -0
- package/src/components/atoms/formatted-credit-card/FormattedCreditCard.stories.js +74 -0
- package/src/components/atoms/icons/Icons.mdx +40 -0
- package/src/components/atoms/icons/Icons.stories.js +325 -0
- package/src/components/atoms/labeled-amount/LabeledAmount.mdx +23 -0
- package/src/components/atoms/labeled-amount/LabeledAmount.stories.js +110 -34
- package/src/components/atoms/line-item/LineItem.mdx +28 -0
- package/src/components/atoms/line-item/LineItem.stories.js +89 -22
- package/src/components/atoms/link/Link.mdx +19 -0
- package/src/components/atoms/link/Link.stories.js +155 -49
- package/src/components/atoms/loading/Loading.mdx +13 -0
- package/src/components/atoms/loading/Loading.stories.js +22 -0
- package/src/components/atoms/loading-line/LoadingLine.js +14 -10
- package/src/components/atoms/loading-line/LoadingLine.mdx +15 -0
- package/src/components/atoms/loading-line/LoadingLine.stories.js +132 -28
- package/src/components/atoms/nav-footer/.DS_Store +0 -0
- package/src/components/atoms/nav-footer/NavFooter.mdx +15 -0
- package/src/components/atoms/nav-footer/NavFooter.stories.js +235 -22
- package/src/components/atoms/nav-header/NavHeader.mdx +13 -0
- package/src/components/atoms/nav-header/NavHeader.stories.js +122 -21
- package/src/components/atoms/nav-tabs/NavTabs.mdx +30 -0
- package/src/components/atoms/nav-tabs/NavTabs.stories.js +49 -0
- package/src/components/atoms/password-requirements/PasswordRequirements.mdx +39 -0
- package/src/components/atoms/password-requirements/PasswordRequirements.stories.js +108 -44
- package/src/components/atoms/placeholder/Placeholder.mdx +19 -0
- package/src/components/atoms/placeholder/Placeholder.stories.js +164 -36
- package/src/components/atoms/searchable-select/SearchableSelect.mdx +44 -0
- package/src/components/atoms/searchable-select/SearchableSelect.stories.js +103 -28
- package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.mdx +36 -0
- package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.stories.js +65 -40
- package/src/components/atoms/table/Table.mdx +71 -0
- package/src/components/atoms/table/Table.oldstories.js +84 -0
- package/src/components/atoms/table/Table.stories.js +59 -75
- package/src/components/atoms/table/TableRow.js +1 -0
- package/src/components/atoms/title/Title.js +0 -23
- package/src/components/atoms/title/Title.mdx +26 -0
- package/src/components/atoms/title/Title.stories.js +144 -0
- package/src/components/atoms/toggle-switch/ToggleSwitch.mdx +17 -0
- package/src/components/atoms/toggle-switch/ToggleSwitch.stories.js +103 -20
- package/src/components/atoms/toggle-switch/ToggleSwitch.theme.js +8 -5
- package/src/components/atoms/typeahead-input/TypeaheadInput.mdx +13 -0
- package/src/components/atoms/typeahead-input/TypeaheadInput.stories.js +63 -0
- package/src/components/molecules/.DS_Store +0 -0
- package/src/components/molecules/address-form/AddressForm.mdx +18 -0
- package/src/components/molecules/address-form/AddressForm.stories.js +223 -20
- package/src/components/molecules/banner/Banner.mdx +23 -0
- package/src/components/molecules/banner/Banner.stories.js +122 -26
- package/src/components/molecules/change-password-form/ChangePasswordForm.mdx +15 -0
- package/src/components/molecules/change-password-form/ChangePasswordForm.stories.js +203 -19
- package/src/components/molecules/collapsible-section/CollapsibleSection.mdx +15 -0
- package/src/components/molecules/collapsible-section/CollapsibleSection.stories.js +210 -61
- package/src/components/molecules/edit-name-form/EditNameForm.mdx +13 -0
- package/src/components/molecules/edit-name-form/EditNameForm.stories.js +117 -0
- package/src/components/molecules/idle-modal/IdleModal.js +101 -0
- package/src/components/molecules/idle-modal/IdleModal.mdx +17 -0
- package/src/components/molecules/idle-modal/IdleModal.stories.js +180 -0
- package/src/components/molecules/idle-modal/index.d.ts +16 -0
- package/src/components/molecules/idle-modal/index.js +3 -0
- package/src/components/molecules/index.js +1 -0
- package/src/components/molecules/link-card/LinkCard.mdx +17 -0
- package/src/components/molecules/link-card/LinkCard.stories.js +287 -72
- package/src/components/molecules/login-form/LoginForm.mdx +16 -0
- package/src/components/molecules/login-form/LoginForm.stories.js +117 -21
- package/src/components/molecules/modal/Modal.mdx +17 -0
- package/src/components/molecules/modal/Modal.stories.js +342 -128
- package/src/components/molecules/module/Module.mdx +17 -0
- package/src/components/molecules/module/Module.stories.js +267 -25
- package/src/components/molecules/obligation/.DS_Store +0 -0
- package/src/components/molecules/obligation/Obligation.mdx +23 -0
- package/src/components/molecules/obligation/Obligation.stories.js +460 -0
- package/src/components/molecules/obligation/icons/PropertyPersonalIcon.js +1 -1
- package/src/components/molecules/pagination/Pagination.mdx +15 -0
- package/src/components/molecules/pagination/Pagination.stories.js +177 -28
- package/src/components/molecules/popover/Popover.mdx +15 -0
- package/src/components/molecules/popover/Popover.stories.js +220 -0
- package/src/components/molecules/tabs/Tabs.mdx +17 -0
- package/src/components/molecules/tabs/Tabs.stories.js +135 -227
- package/src/components/molecules/toast-notification/Toast.mdx +15 -0
- package/src/components/molecules/toast-notification/Toast.stories.js +183 -0
- package/src/util/idleTimerUtils.js +36 -0
- package/src/util/index.js +3 -1
- package/src/components/molecules/edit-name-form/EdidNameForm.stories.js +0 -24
- package/src/components/molecules/toast-notification/ToastNotification.stories.js +0 -105
- /package/src/components/atoms/add-obligation/{AddObligation.stories.js → AddObligation.oldstories.js} +0 -0
- /package/src/components/atoms/amount-callout/{AmountCallout.stories.js → AmountCallout.oldstories.js} +0 -0
- /package/src/components/atoms/checkbox-list/{CheckboxList.stories.js → CheckboxList.oldstories.js} +0 -0
- /package/src/components/atoms/form-layouts/{FormLayouts.stories.js → FormLayouts.oldstories.js} +0 -0
- /package/src/components/atoms/hamburger-button/{HamburgerButton.stories.js → HamburgerButton.oldstories.js} +0 -0
- /package/src/components/atoms/heading/{Heading.stories.js → Heading.oldstories.js} +0 -0
- /package/src/components/atoms/icons/{icons.stories.js → icons.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/box-example/{BoxExample.stories.js → BoxExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/center-example/{CenterExample.stories.js → CenterExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/cluster-example/{ClusterExample.stories.js → ClusterExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/cover-example/{CoverExample.stories.js → CoverExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/frame-example/{FrameExample.stories.js → FrameExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/grid-example/{GridExample.stories.js → GridExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/imposter-example/{ImposterExample.stories.js → ImposterExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/motion-example/{MotionExample.stories.js → MotionExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/reel-example/{ReelExample.stories.js → ReelExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/sidebar-example/{SidebarExample.stories.js → SidebarExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/stack-example/{StackExample.stories.js → StackExample.oldstories.js} +0 -0
- /package/src/components/atoms/layouts/examples/switcher-example/{SwitcherExample.stories.js → SwitcherExample.oldstories.js} +0 -0
- /package/src/components/atoms/paragraph/{Paragraph.stories.js → Paragraph.oldstories.js} +0 -0
- /package/src/components/atoms/processing-fee/{ProcessingFee.stories.js → ProcessingFee.oldstories.js} +0 -0
- /package/src/components/atoms/search/{Search.stories.js → Search.oldstories.js} +0 -0
- /package/src/components/atoms/solid-divider/{SolidDivider.stories.js → SolidDivider.oldstories.js} +0 -0
- /package/src/components/atoms/sortable-table-heading/{SortableTableHeading.stories.js → SortableTableHeading.oldstories.js} +0 -0
- /package/src/components/atoms/spinner/{Spinner.stories.js → Spinner.oldstories.js} +0 -0
- /package/src/components/atoms/tab/{Tab.stories.js → Tab.oldstories.js} +0 -0
- /package/src/components/atoms/text/{Text.stories.js → Text.oldstories.js} +0 -0
- /package/src/components/atoms/typeahead-input/{TypeaheadIinput.stories.js → TypeaheadIinput.oldstories.js} +0 -0
- /package/src/components/atoms/wallet-name/{WalletName.stories.js → WalletName.oldstories.js} +0 -0
- /package/src/components/molecules/account-and-routing-modal/{AccountAndRoutingModal.stories.js → AccountAndRoutingModal.oldstories.js} +0 -0
- /package/src/components/molecules/editable-list/{EditableList.stories.js → EditableList.oldstories.js} +0 -0
- /package/src/components/molecules/email-form/{EmailForm.stories.js → EmailForm.oldstories.js} +0 -0
- /package/src/components/molecules/forgot-password-form/{ForgotPasswordForm.stories.js → ForgotPasswordForm.oldstories.js} +0 -0
- /package/src/components/molecules/highlight-tab-row/{HighlightTabRow.stories.js → HighlightTabRow.oldstories.js} +0 -0
- /package/src/components/molecules/multiple-select-filter/{MultipleSelectFilter.stories.js → MultipleSelectFilter.oldstories.js} +0 -0
- /package/src/components/molecules/obligation/modules/{AmountModule.stories.js → AmountModule.oldstories.js} +0 -0
- /package/src/components/molecules/payment-button-bar/{PaymentButtonBar.stories.js → PaymentButtonBar.oldstories.js} +0 -0
- /package/src/components/molecules/payment-details/{PaymentDetails.stories.js → PaymentDetails.oldstories.js} +0 -0
- /package/src/components/molecules/payment-form-ach/{PaymentFormACH.stories.js → PaymentFormACH.oldstories.js} +0 -0
- /package/src/components/molecules/payment-form-card/{PaymentFormCard.stories.js → PaymentFormCard.oldstories.js} +0 -0
- /package/src/components/molecules/periscope-dashboard-iframe/{PeriscopeDashBoardIframe.stories.js → PeriscopeDashBoardIframe.oldstories.js} +0 -0
- /package/src/components/molecules/phone-form/{PhoneForm.stories.js → PhoneForm.oldstories.js} +0 -0
- /package/src/components/molecules/popup-menu/{PopupMenu.stories.js → PopupMenu.oldstories.js} +0 -0
- /package/src/components/molecules/radio-group/{RadioGroup.stories.js → RadioGroup.oldstories.js} +0 -0
- /package/src/components/molecules/radio-section/{RadioSection.stories.js → RadioSection.oldstories.js} +0 -0
- /package/src/components/molecules/registration-form/{RegistrationForm.stories.js → RegistrationForm.oldstories.js} +0 -0
- /package/src/components/molecules/reset-confirmation-form/{ResetConfirmationForm.stories.js → ResetConfirmationForm.oldstories.js} +0 -0
- /package/src/components/molecules/reset-password-form/{ResetPasswordForm.stories.js → ResetPasswordForm.oldstories.js} +0 -0
- /package/src/components/molecules/reset-password-success/{ResetPasswordSuccess.stories.js → ResetPasswordSuccess.oldstories.js} +0 -0
- /package/src/components/molecules/tab-sidebar/{TabSidebar.stories.js → TabSidebar.oldstories.js} +0 -0
- /package/src/components/molecules/terms-and-conditions/{TermsAndConditions.stories.js → TermsAndConditions.oldstories.js} +0 -0
- /package/src/components/molecules/terms-and-conditions-modal/{TermsAndConditionsModal.stories.js → TermsAndConditionsModal.oldstories.js} +0 -0
- /package/src/components/molecules/workflow-tile/{WorkflowTile.stories.js → WorkflowTile.oldstories.js} +0 -0
|
@@ -0,0 +1,101 @@
|
|
|
1
|
+
import React from "react";
|
|
2
|
+
import Modal from "../modal";
|
|
3
|
+
import { Box, Motion, Stack } from "../../atoms/layouts";
|
|
4
|
+
import Paragraph from "../../atoms/paragraph";
|
|
5
|
+
|
|
6
|
+
const IdleModal = ({
|
|
7
|
+
modalOpen,
|
|
8
|
+
toggleModal,
|
|
9
|
+
timeLeftToLogout = 0,
|
|
10
|
+
totalLogoutTime = 30,
|
|
11
|
+
logout,
|
|
12
|
+
cancelLogout,
|
|
13
|
+
useCheckoutContent
|
|
14
|
+
}) => {
|
|
15
|
+
const percent =
|
|
16
|
+
(totalLogoutTime - timeLeftToLogout) * (100 / totalLogoutTime);
|
|
17
|
+
const transition = {
|
|
18
|
+
ease: "easeInOut",
|
|
19
|
+
duration: totalLogoutTime
|
|
20
|
+
};
|
|
21
|
+
const variants = {
|
|
22
|
+
enter: {
|
|
23
|
+
x: "-100%",
|
|
24
|
+
backgroundColor: "#317D4F"
|
|
25
|
+
},
|
|
26
|
+
animate: {
|
|
27
|
+
x: ["-100%", `${percent}%`],
|
|
28
|
+
backgroundColor: ["#317D4F", "#93A441", "#F4CB32", "#E36E43", "#D11053"],
|
|
29
|
+
times: [0, 0.4, 0.5, 0.6, 0.8],
|
|
30
|
+
transition
|
|
31
|
+
}
|
|
32
|
+
};
|
|
33
|
+
|
|
34
|
+
const continueText = useCheckoutContent ? "Continue" : "Stay Logged In";
|
|
35
|
+
|
|
36
|
+
const cancelText = useCheckoutContent ? "End Session" : "Log Off";
|
|
37
|
+
|
|
38
|
+
const paragraphText = useCheckoutContent
|
|
39
|
+
? `Are you still there? Your payment will be cancelled in ${timeLeftToLogout} seconds.`
|
|
40
|
+
: `Are you still there? For your security, you will be logged out in ${timeLeftToLogout} seconds.`;
|
|
41
|
+
|
|
42
|
+
const modalBody = (
|
|
43
|
+
<Box padding="0">
|
|
44
|
+
<Stack>
|
|
45
|
+
<Paragraph>{paragraphText}</Paragraph>
|
|
46
|
+
<Motion>
|
|
47
|
+
<Box
|
|
48
|
+
padding="0 0 1px 0"
|
|
49
|
+
minHeight="10px"
|
|
50
|
+
width="100%"
|
|
51
|
+
borderRadius="6px"
|
|
52
|
+
extraStyles="position: relative; overflow: hidden;"
|
|
53
|
+
>
|
|
54
|
+
<Motion
|
|
55
|
+
padding="0 0 1px 0"
|
|
56
|
+
height="10px"
|
|
57
|
+
width="100%"
|
|
58
|
+
borderRadius="6px"
|
|
59
|
+
extraStyles="position: absolute;"
|
|
60
|
+
variants={variants}
|
|
61
|
+
initial="enter"
|
|
62
|
+
animate={modalOpen ? "animate" : "enter"}
|
|
63
|
+
exit="enter"
|
|
64
|
+
/>
|
|
65
|
+
</Box>
|
|
66
|
+
</Motion>
|
|
67
|
+
</Stack>
|
|
68
|
+
</Box>
|
|
69
|
+
);
|
|
70
|
+
const modalExtraProps = {
|
|
71
|
+
modalHeaderText: "Your session is about to expire!",
|
|
72
|
+
modalBodyText: modalBody,
|
|
73
|
+
continueButtonText: continueText,
|
|
74
|
+
cancelButtonText: cancelText,
|
|
75
|
+
continueAction: () => {
|
|
76
|
+
cancelLogout();
|
|
77
|
+
toggleModal(false);
|
|
78
|
+
},
|
|
79
|
+
cancelAction: () => {
|
|
80
|
+
logout();
|
|
81
|
+
toggleModal(false);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
return (
|
|
85
|
+
<Modal
|
|
86
|
+
showModal={() => toggleModal(true)}
|
|
87
|
+
hideModal={() => {
|
|
88
|
+
cancelLogout();
|
|
89
|
+
toggleModal(false);
|
|
90
|
+
}}
|
|
91
|
+
modalOpen={modalOpen}
|
|
92
|
+
defaultWrapper={false}
|
|
93
|
+
underlayClickExits={false}
|
|
94
|
+
{...modalExtraProps}
|
|
95
|
+
>
|
|
96
|
+
<Box padding="0" />
|
|
97
|
+
</Modal>
|
|
98
|
+
);
|
|
99
|
+
};
|
|
100
|
+
|
|
101
|
+
export default IdleModal;
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as IdleModalStories from './IdleModal.stories.js';
|
|
4
|
+
|
|
5
|
+
<Meta of={IdleModalStories} />
|
|
6
|
+
|
|
7
|
+
<Title />
|
|
8
|
+
|
|
9
|
+
The IdleModal is a molecule used to display an animated progress bar and a message informing a user that they will shortly be logged out of an application due to idleness. The modal is a "dumb" component that requires the countdown timer be managed in the parent component. CB Components has a useful react hook contained in the `idleTimerUtils.js` file that NFE uses to help manage the running of the IdleModal.
|
|
10
|
+
|
|
11
|
+
For detecting user inactivity, an application can either implement its own mouse/keyboard event tracking, or rely on a third party package like react-idle-timer. An implementation example is available in the component's story file.
|
|
12
|
+
|
|
13
|
+
As of August 2024, all three of the applications (NFE, RevM, POS) to use the IdleModal use customized versions that live within the application code. A backlog ticket has been created to unify all existing implementations to the CB Components standard.
|
|
14
|
+
|
|
15
|
+
<Controls />
|
|
16
|
+
|
|
17
|
+
<Story />
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
import React, { useState } from "react";
|
|
2
|
+
import IdleModal from "./IdleModal";
|
|
3
|
+
import { fn } from "@storybook/test";
|
|
4
|
+
import { ButtonWithAction } from "../../atoms";
|
|
5
|
+
import { Box, Stack } from "../../atoms/layouts";
|
|
6
|
+
import Text from "../../atoms/text";
|
|
7
|
+
import useLogoutTimers from "../../../util/idleTimerUtils";
|
|
8
|
+
|
|
9
|
+
export default {
|
|
10
|
+
title: "Molecules/IdleModal",
|
|
11
|
+
component: IdleModal,
|
|
12
|
+
tags: ["!autodocs"],
|
|
13
|
+
parameters: {
|
|
14
|
+
layout: "centered",
|
|
15
|
+
controls: { expanded: true }
|
|
16
|
+
},
|
|
17
|
+
args: {
|
|
18
|
+
modalOpen: undefined,
|
|
19
|
+
toggleModal: fn(),
|
|
20
|
+
timeLeftToLogout: 0,
|
|
21
|
+
totalLogoutTime: 30,
|
|
22
|
+
logout: fn(),
|
|
23
|
+
cancelLogout: fn(),
|
|
24
|
+
useCheckoutContent: undefined
|
|
25
|
+
},
|
|
26
|
+
argTypes: {
|
|
27
|
+
modalOpen: {
|
|
28
|
+
description: "Whether the modal is open",
|
|
29
|
+
table: {
|
|
30
|
+
type: { summary: "boolean" },
|
|
31
|
+
defaultValue: { summary: undefined }
|
|
32
|
+
}
|
|
33
|
+
},
|
|
34
|
+
toggleModal: {
|
|
35
|
+
description: "Function to toggle the modal open or closed",
|
|
36
|
+
table: {
|
|
37
|
+
type: { summary: "function" },
|
|
38
|
+
defaultValue: { summary: undefined }
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
timeLeftToLogout: {
|
|
42
|
+
description:
|
|
43
|
+
"Amount of time remaining before logout function is called. Should be supplied by parent component using setInterval or other mechanism to decrement a counter.",
|
|
44
|
+
table: {
|
|
45
|
+
type: { summary: "number" },
|
|
46
|
+
defaultValue: { summary: 0 }
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
totalLogoutTime: {
|
|
50
|
+
description:
|
|
51
|
+
"Total amount of time before logout function is called. Used with timeLeftToLogout in order to animate the progress bar.",
|
|
52
|
+
table: {
|
|
53
|
+
type: { summary: "number" },
|
|
54
|
+
defaultValue: { summary: 30 }
|
|
55
|
+
}
|
|
56
|
+
},
|
|
57
|
+
logout: {
|
|
58
|
+
description:
|
|
59
|
+
"Function to run when timer reaches zero. Typically a redux action dispatcher, but can be a wrapping function that handles the logout sequence itself.",
|
|
60
|
+
table: {
|
|
61
|
+
type: { summary: "function" },
|
|
62
|
+
defaultValue: { summary: undefined }
|
|
63
|
+
}
|
|
64
|
+
},
|
|
65
|
+
cancelLogout: {
|
|
66
|
+
description:
|
|
67
|
+
"Function to run if user closes or cancels modal early. Typically a redux action dispatcher, but can be a wrapping function.",
|
|
68
|
+
table: {
|
|
69
|
+
type: { summary: "function" },
|
|
70
|
+
defaultValue: { summary: undefined }
|
|
71
|
+
}
|
|
72
|
+
},
|
|
73
|
+
useCheckoutContent: {
|
|
74
|
+
description:
|
|
75
|
+
"Whether text of modal should reference checkout experience / user's payment.",
|
|
76
|
+
table: {
|
|
77
|
+
type: { summary: "boolean" },
|
|
78
|
+
defaultValue: { summary: undefined }
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
};
|
|
83
|
+
|
|
84
|
+
const IdleModalComponent = args => {
|
|
85
|
+
const { totalLogoutTime, ...rest } = args;
|
|
86
|
+
const [modalOpen, setModalOpen] = useState(false);
|
|
87
|
+
const [logoutTriggered, setLogoutTriggered] = useState(false);
|
|
88
|
+
const [cancelLogoutTriggered, setCancelLogoutTriggered] = useState(false);
|
|
89
|
+
const [timeLeftToLogout, setTimeLeftToLogout] = useState(totalLogoutTime);
|
|
90
|
+
const [logoutTimerOn, setLogoutTimerOn] = useState(false);
|
|
91
|
+
|
|
92
|
+
const runIdleModal = () => {
|
|
93
|
+
setLogoutTriggered(false);
|
|
94
|
+
setCancelLogoutTriggered(false);
|
|
95
|
+
setModalOpen(true);
|
|
96
|
+
setLogoutTimerOn(true);
|
|
97
|
+
};
|
|
98
|
+
|
|
99
|
+
const resetLogoutTimer = () => {
|
|
100
|
+
clearInterval(logoutTimers.interval);
|
|
101
|
+
clearTimeout(logoutTimers.timer);
|
|
102
|
+
setTimeLeftToLogout(totalLogoutTime);
|
|
103
|
+
};
|
|
104
|
+
|
|
105
|
+
const handleLogout = () => {
|
|
106
|
+
setModalOpen(false);
|
|
107
|
+
setLogoutTriggered(true);
|
|
108
|
+
setLogoutTimerOn(false);
|
|
109
|
+
resetLogoutTimer();
|
|
110
|
+
};
|
|
111
|
+
|
|
112
|
+
const handleCancelLogout = () => {
|
|
113
|
+
setModalOpen(false);
|
|
114
|
+
setCancelLogoutTriggered(true);
|
|
115
|
+
setLogoutTimerOn(false);
|
|
116
|
+
resetLogoutTimer();
|
|
117
|
+
};
|
|
118
|
+
|
|
119
|
+
const logoutTimers = useLogoutTimers({
|
|
120
|
+
logoutTimerOn,
|
|
121
|
+
action: handleLogout,
|
|
122
|
+
timeLeftToLogout,
|
|
123
|
+
handleSetTimeLeft: setTimeLeftToLogout,
|
|
124
|
+
initialTimeLeftToLogout: totalLogoutTime
|
|
125
|
+
});
|
|
126
|
+
|
|
127
|
+
let userStatus = "is logged in";
|
|
128
|
+
|
|
129
|
+
if (logoutTriggered) {
|
|
130
|
+
userStatus = "has logged out";
|
|
131
|
+
}
|
|
132
|
+
if (cancelLogoutTriggered) {
|
|
133
|
+
userStatus = "has cancelled log out";
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
return (
|
|
137
|
+
<Box>
|
|
138
|
+
<Stack childGap="10rem">
|
|
139
|
+
<Box>
|
|
140
|
+
<Text>{`User Status: ${userStatus}`}</Text>
|
|
141
|
+
</Box>
|
|
142
|
+
<Box>
|
|
143
|
+
<ButtonWithAction
|
|
144
|
+
action={() => runIdleModal()}
|
|
145
|
+
text="Trigger Idle Modal"
|
|
146
|
+
/>
|
|
147
|
+
</Box>
|
|
148
|
+
<Box>
|
|
149
|
+
<IdleModal
|
|
150
|
+
{...rest}
|
|
151
|
+
totalLogoutTime={totalLogoutTime}
|
|
152
|
+
timeLeftToLogout={timeLeftToLogout}
|
|
153
|
+
modalOpen={modalOpen}
|
|
154
|
+
toggleModal={() => setModalOpen(!modalOpen)}
|
|
155
|
+
logout={() => handleLogout()}
|
|
156
|
+
cancelLogout={() => handleCancelLogout()}
|
|
157
|
+
/>
|
|
158
|
+
</Box>
|
|
159
|
+
</Stack>
|
|
160
|
+
</Box>
|
|
161
|
+
);
|
|
162
|
+
};
|
|
163
|
+
|
|
164
|
+
export const BasicIdleModal = {
|
|
165
|
+
render: args => IdleModalComponent(args)
|
|
166
|
+
};
|
|
167
|
+
|
|
168
|
+
export const CheckoutIdleModal = {
|
|
169
|
+
args: {
|
|
170
|
+
useCheckoutContent: true
|
|
171
|
+
},
|
|
172
|
+
render: args => IdleModalComponent(args)
|
|
173
|
+
};
|
|
174
|
+
|
|
175
|
+
export const LengthyIdleModal = {
|
|
176
|
+
args: {
|
|
177
|
+
totalLogoutTime: 300
|
|
178
|
+
},
|
|
179
|
+
render: args => IdleModalComponent(args)
|
|
180
|
+
};
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import React, { HTMLAttributes } from "react";
|
|
2
|
+
import Expand from "../../../util/expand";
|
|
3
|
+
import { ReduxAction } from "../../../types/common";
|
|
4
|
+
|
|
5
|
+
export interface IdleModalProps {
|
|
6
|
+
modalOpen: boolean;
|
|
7
|
+
toggleModal: (modalOpen: boolean) => void;
|
|
8
|
+
timeLeftToLogout?: number; // in seconds
|
|
9
|
+
totalLogoutTime?: number; // in seconds
|
|
10
|
+
logout: () => ReduxAction;
|
|
11
|
+
cancelLogout: () => ReduxAction;
|
|
12
|
+
useCheckoutContent?: boolean;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const IdleModal: React.FC<Expand<IdleModalProps> &
|
|
16
|
+
HTMLAttributes<HTMLElement>>;
|
|
@@ -10,6 +10,7 @@ export { default as EmailForm } from "./email-form";
|
|
|
10
10
|
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
|
+
export { default as IdleModal } from "./idle-modal";
|
|
13
14
|
export { iconsMap as ObligationIcons } from "./obligation/icons";
|
|
14
15
|
export { default as LinkCard } from "./link-card";
|
|
15
16
|
export { default as LoginForm } from "./login-form";
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
|
|
2
|
+
|
|
3
|
+
import * as LinkCardStories from './LinkCard.stories.js';
|
|
4
|
+
|
|
5
|
+
<Meta of={LinkCardStories} />
|
|
6
|
+
|
|
7
|
+
<Title />
|
|
8
|
+
|
|
9
|
+
The LinkCard is a variant of the Card component that has been built to display a title, subtitle, and optionally additional content like a badge or icon. When clicked, the onClick function is called. Typically this function is used to navigate the user within the application.
|
|
10
|
+
|
|
11
|
+
Currently, the LinkCard is used in NFE on the /find page to assist users in finding accounts to link to their profile or to make one-time payments on. The LinkCard can take arbitrary child components for both its left and right content, which makes it very flexible and useful for any application where a grid of tiles is needed.
|
|
12
|
+
|
|
13
|
+
<Controls />
|
|
14
|
+
|
|
15
|
+
<div style={{ marginBottom: "2em"}}>
|
|
16
|
+
<Story />
|
|
17
|
+
</div>
|