@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.
Files changed (180) hide show
  1. package/README.md +14 -6
  2. package/dist/index.cjs.js +1311 -1482
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.js +1311 -1483
  5. package/dist/index.esm.js.map +1 -1
  6. package/package.json +25 -13
  7. package/src/.DS_Store +0 -0
  8. package/src/components/.DS_Store +0 -0
  9. package/src/components/atoms/.DS_Store +0 -0
  10. package/src/components/atoms/alert/Alert.mdx +19 -0
  11. package/src/components/atoms/alert/Alert.stories.js +148 -26
  12. package/src/components/atoms/badge/Badge.js +2 -2
  13. package/src/components/atoms/badge/Badge.mdx +27 -0
  14. package/src/components/atoms/badge/Badge.stories.js +143 -29
  15. package/src/components/atoms/breadcrumb/Breadcrumb.mdx +21 -0
  16. package/src/components/atoms/breadcrumb/Breadcrumb.stories.js +38 -29
  17. package/src/components/atoms/button-with-action/ButtonWithAction.stories.js +108 -55
  18. package/src/components/atoms/button-with-link/ButtonWithLink.mdx +21 -0
  19. package/src/components/atoms/button-with-link/ButtonWithLink.stories.js +160 -31
  20. package/src/components/atoms/card/Card.mdx +41 -0
  21. package/src/components/atoms/card/Card.stories.js +351 -0
  22. package/src/components/atoms/card/CardText.js +6 -1
  23. package/src/components/atoms/checkbox/Checkbox.mdx +15 -0
  24. package/src/components/atoms/checkbox/Checkbox.oldstories.js +34 -0
  25. package/src/components/atoms/checkbox/Checkbox.stories.js +140 -25
  26. package/src/components/atoms/country-dropdown/CountryDropdown.mdx +36 -0
  27. package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +61 -27
  28. package/src/components/atoms/detail/Detail.js +0 -26
  29. package/src/components/atoms/detail/Detail.mdx +32 -0
  30. package/src/components/atoms/detail/Detail.stories.js +156 -0
  31. package/src/components/atoms/display-box/DisplayBox.mdx +11 -0
  32. package/src/components/atoms/display-box/DisplayBox.stories.js +65 -21
  33. package/src/components/atoms/display-card/DisplayCard.mdx +13 -0
  34. package/src/components/atoms/display-card/DisplayCard.stories.js +163 -22
  35. package/src/components/atoms/dropdown/Dropdown.mdx +65 -0
  36. package/src/components/atoms/dropdown/Dropdown.stories.js +91 -10
  37. package/src/components/atoms/form-layouts/FormInput.mdx +38 -0
  38. package/src/components/atoms/form-layouts/FormInput.stories.js +212 -26
  39. package/src/components/atoms/form-select/FormSelect.mdx +42 -0
  40. package/src/components/atoms/form-select/FormSelect.stories.js +55 -29
  41. package/src/components/atoms/formatted-address/FormattedAddress.mdx +13 -0
  42. package/src/components/atoms/formatted-address/FormattedAddress.stories.js +133 -27
  43. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.mdx +17 -0
  44. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.stories.js +57 -0
  45. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.mdx +40 -0
  46. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.stories.js +74 -0
  47. package/src/components/atoms/icons/Icons.mdx +40 -0
  48. package/src/components/atoms/icons/Icons.stories.js +325 -0
  49. package/src/components/atoms/labeled-amount/LabeledAmount.mdx +23 -0
  50. package/src/components/atoms/labeled-amount/LabeledAmount.stories.js +110 -34
  51. package/src/components/atoms/line-item/LineItem.mdx +28 -0
  52. package/src/components/atoms/line-item/LineItem.stories.js +89 -22
  53. package/src/components/atoms/link/Link.mdx +19 -0
  54. package/src/components/atoms/link/Link.stories.js +155 -49
  55. package/src/components/atoms/loading/Loading.mdx +13 -0
  56. package/src/components/atoms/loading/Loading.stories.js +22 -0
  57. package/src/components/atoms/loading-line/LoadingLine.js +14 -10
  58. package/src/components/atoms/loading-line/LoadingLine.mdx +15 -0
  59. package/src/components/atoms/loading-line/LoadingLine.stories.js +132 -28
  60. package/src/components/atoms/nav-footer/.DS_Store +0 -0
  61. package/src/components/atoms/nav-footer/NavFooter.mdx +15 -0
  62. package/src/components/atoms/nav-footer/NavFooter.stories.js +235 -22
  63. package/src/components/atoms/nav-header/NavHeader.mdx +13 -0
  64. package/src/components/atoms/nav-header/NavHeader.stories.js +122 -21
  65. package/src/components/atoms/nav-tabs/NavTabs.mdx +30 -0
  66. package/src/components/atoms/nav-tabs/NavTabs.stories.js +49 -0
  67. package/src/components/atoms/password-requirements/PasswordRequirements.mdx +39 -0
  68. package/src/components/atoms/password-requirements/PasswordRequirements.stories.js +108 -44
  69. package/src/components/atoms/placeholder/Placeholder.mdx +19 -0
  70. package/src/components/atoms/placeholder/Placeholder.stories.js +164 -36
  71. package/src/components/atoms/searchable-select/SearchableSelect.mdx +44 -0
  72. package/src/components/atoms/searchable-select/SearchableSelect.stories.js +103 -28
  73. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.mdx +36 -0
  74. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.stories.js +65 -40
  75. package/src/components/atoms/table/Table.mdx +71 -0
  76. package/src/components/atoms/table/Table.oldstories.js +84 -0
  77. package/src/components/atoms/table/Table.stories.js +59 -75
  78. package/src/components/atoms/table/TableRow.js +1 -0
  79. package/src/components/atoms/title/Title.js +0 -23
  80. package/src/components/atoms/title/Title.mdx +26 -0
  81. package/src/components/atoms/title/Title.stories.js +144 -0
  82. package/src/components/atoms/toggle-switch/ToggleSwitch.mdx +17 -0
  83. package/src/components/atoms/toggle-switch/ToggleSwitch.stories.js +103 -20
  84. package/src/components/atoms/toggle-switch/ToggleSwitch.theme.js +8 -5
  85. package/src/components/atoms/typeahead-input/TypeaheadInput.mdx +13 -0
  86. package/src/components/atoms/typeahead-input/TypeaheadInput.stories.js +63 -0
  87. package/src/components/molecules/.DS_Store +0 -0
  88. package/src/components/molecules/address-form/AddressForm.mdx +18 -0
  89. package/src/components/molecules/address-form/AddressForm.stories.js +223 -20
  90. package/src/components/molecules/banner/Banner.mdx +23 -0
  91. package/src/components/molecules/banner/Banner.stories.js +122 -26
  92. package/src/components/molecules/change-password-form/ChangePasswordForm.mdx +15 -0
  93. package/src/components/molecules/change-password-form/ChangePasswordForm.stories.js +203 -19
  94. package/src/components/molecules/collapsible-section/CollapsibleSection.mdx +15 -0
  95. package/src/components/molecules/collapsible-section/CollapsibleSection.stories.js +210 -61
  96. package/src/components/molecules/edit-name-form/EditNameForm.mdx +13 -0
  97. package/src/components/molecules/edit-name-form/EditNameForm.stories.js +117 -0
  98. package/src/components/molecules/idle-modal/IdleModal.js +101 -0
  99. package/src/components/molecules/idle-modal/IdleModal.mdx +17 -0
  100. package/src/components/molecules/idle-modal/IdleModal.stories.js +180 -0
  101. package/src/components/molecules/idle-modal/index.d.ts +16 -0
  102. package/src/components/molecules/idle-modal/index.js +3 -0
  103. package/src/components/molecules/index.js +1 -0
  104. package/src/components/molecules/link-card/LinkCard.mdx +17 -0
  105. package/src/components/molecules/link-card/LinkCard.stories.js +287 -72
  106. package/src/components/molecules/login-form/LoginForm.mdx +16 -0
  107. package/src/components/molecules/login-form/LoginForm.stories.js +117 -21
  108. package/src/components/molecules/modal/Modal.mdx +17 -0
  109. package/src/components/molecules/modal/Modal.stories.js +342 -128
  110. package/src/components/molecules/module/Module.mdx +17 -0
  111. package/src/components/molecules/module/Module.stories.js +267 -25
  112. package/src/components/molecules/obligation/.DS_Store +0 -0
  113. package/src/components/molecules/obligation/Obligation.mdx +23 -0
  114. package/src/components/molecules/obligation/Obligation.stories.js +460 -0
  115. package/src/components/molecules/obligation/icons/PropertyPersonalIcon.js +1 -1
  116. package/src/components/molecules/pagination/Pagination.mdx +15 -0
  117. package/src/components/molecules/pagination/Pagination.stories.js +177 -28
  118. package/src/components/molecules/popover/Popover.mdx +15 -0
  119. package/src/components/molecules/popover/Popover.stories.js +220 -0
  120. package/src/components/molecules/tabs/Tabs.mdx +17 -0
  121. package/src/components/molecules/tabs/Tabs.stories.js +135 -227
  122. package/src/components/molecules/toast-notification/Toast.mdx +15 -0
  123. package/src/components/molecules/toast-notification/Toast.stories.js +183 -0
  124. package/src/util/idleTimerUtils.js +36 -0
  125. package/src/util/index.js +3 -1
  126. package/src/components/molecules/edit-name-form/EdidNameForm.stories.js +0 -24
  127. package/src/components/molecules/toast-notification/ToastNotification.stories.js +0 -105
  128. /package/src/components/atoms/add-obligation/{AddObligation.stories.js → AddObligation.oldstories.js} +0 -0
  129. /package/src/components/atoms/amount-callout/{AmountCallout.stories.js → AmountCallout.oldstories.js} +0 -0
  130. /package/src/components/atoms/checkbox-list/{CheckboxList.stories.js → CheckboxList.oldstories.js} +0 -0
  131. /package/src/components/atoms/form-layouts/{FormLayouts.stories.js → FormLayouts.oldstories.js} +0 -0
  132. /package/src/components/atoms/hamburger-button/{HamburgerButton.stories.js → HamburgerButton.oldstories.js} +0 -0
  133. /package/src/components/atoms/heading/{Heading.stories.js → Heading.oldstories.js} +0 -0
  134. /package/src/components/atoms/icons/{icons.stories.js → icons.oldstories.js} +0 -0
  135. /package/src/components/atoms/layouts/examples/box-example/{BoxExample.stories.js → BoxExample.oldstories.js} +0 -0
  136. /package/src/components/atoms/layouts/examples/center-example/{CenterExample.stories.js → CenterExample.oldstories.js} +0 -0
  137. /package/src/components/atoms/layouts/examples/cluster-example/{ClusterExample.stories.js → ClusterExample.oldstories.js} +0 -0
  138. /package/src/components/atoms/layouts/examples/cover-example/{CoverExample.stories.js → CoverExample.oldstories.js} +0 -0
  139. /package/src/components/atoms/layouts/examples/frame-example/{FrameExample.stories.js → FrameExample.oldstories.js} +0 -0
  140. /package/src/components/atoms/layouts/examples/grid-example/{GridExample.stories.js → GridExample.oldstories.js} +0 -0
  141. /package/src/components/atoms/layouts/examples/imposter-example/{ImposterExample.stories.js → ImposterExample.oldstories.js} +0 -0
  142. /package/src/components/atoms/layouts/examples/motion-example/{MotionExample.stories.js → MotionExample.oldstories.js} +0 -0
  143. /package/src/components/atoms/layouts/examples/reel-example/{ReelExample.stories.js → ReelExample.oldstories.js} +0 -0
  144. /package/src/components/atoms/layouts/examples/sidebar-example/{SidebarExample.stories.js → SidebarExample.oldstories.js} +0 -0
  145. /package/src/components/atoms/layouts/examples/stack-example/{StackExample.stories.js → StackExample.oldstories.js} +0 -0
  146. /package/src/components/atoms/layouts/examples/switcher-example/{SwitcherExample.stories.js → SwitcherExample.oldstories.js} +0 -0
  147. /package/src/components/atoms/paragraph/{Paragraph.stories.js → Paragraph.oldstories.js} +0 -0
  148. /package/src/components/atoms/processing-fee/{ProcessingFee.stories.js → ProcessingFee.oldstories.js} +0 -0
  149. /package/src/components/atoms/search/{Search.stories.js → Search.oldstories.js} +0 -0
  150. /package/src/components/atoms/solid-divider/{SolidDivider.stories.js → SolidDivider.oldstories.js} +0 -0
  151. /package/src/components/atoms/sortable-table-heading/{SortableTableHeading.stories.js → SortableTableHeading.oldstories.js} +0 -0
  152. /package/src/components/atoms/spinner/{Spinner.stories.js → Spinner.oldstories.js} +0 -0
  153. /package/src/components/atoms/tab/{Tab.stories.js → Tab.oldstories.js} +0 -0
  154. /package/src/components/atoms/text/{Text.stories.js → Text.oldstories.js} +0 -0
  155. /package/src/components/atoms/typeahead-input/{TypeaheadIinput.stories.js → TypeaheadIinput.oldstories.js} +0 -0
  156. /package/src/components/atoms/wallet-name/{WalletName.stories.js → WalletName.oldstories.js} +0 -0
  157. /package/src/components/molecules/account-and-routing-modal/{AccountAndRoutingModal.stories.js → AccountAndRoutingModal.oldstories.js} +0 -0
  158. /package/src/components/molecules/editable-list/{EditableList.stories.js → EditableList.oldstories.js} +0 -0
  159. /package/src/components/molecules/email-form/{EmailForm.stories.js → EmailForm.oldstories.js} +0 -0
  160. /package/src/components/molecules/forgot-password-form/{ForgotPasswordForm.stories.js → ForgotPasswordForm.oldstories.js} +0 -0
  161. /package/src/components/molecules/highlight-tab-row/{HighlightTabRow.stories.js → HighlightTabRow.oldstories.js} +0 -0
  162. /package/src/components/molecules/multiple-select-filter/{MultipleSelectFilter.stories.js → MultipleSelectFilter.oldstories.js} +0 -0
  163. /package/src/components/molecules/obligation/modules/{AmountModule.stories.js → AmountModule.oldstories.js} +0 -0
  164. /package/src/components/molecules/payment-button-bar/{PaymentButtonBar.stories.js → PaymentButtonBar.oldstories.js} +0 -0
  165. /package/src/components/molecules/payment-details/{PaymentDetails.stories.js → PaymentDetails.oldstories.js} +0 -0
  166. /package/src/components/molecules/payment-form-ach/{PaymentFormACH.stories.js → PaymentFormACH.oldstories.js} +0 -0
  167. /package/src/components/molecules/payment-form-card/{PaymentFormCard.stories.js → PaymentFormCard.oldstories.js} +0 -0
  168. /package/src/components/molecules/periscope-dashboard-iframe/{PeriscopeDashBoardIframe.stories.js → PeriscopeDashBoardIframe.oldstories.js} +0 -0
  169. /package/src/components/molecules/phone-form/{PhoneForm.stories.js → PhoneForm.oldstories.js} +0 -0
  170. /package/src/components/molecules/popup-menu/{PopupMenu.stories.js → PopupMenu.oldstories.js} +0 -0
  171. /package/src/components/molecules/radio-group/{RadioGroup.stories.js → RadioGroup.oldstories.js} +0 -0
  172. /package/src/components/molecules/radio-section/{RadioSection.stories.js → RadioSection.oldstories.js} +0 -0
  173. /package/src/components/molecules/registration-form/{RegistrationForm.stories.js → RegistrationForm.oldstories.js} +0 -0
  174. /package/src/components/molecules/reset-confirmation-form/{ResetConfirmationForm.stories.js → ResetConfirmationForm.oldstories.js} +0 -0
  175. /package/src/components/molecules/reset-password-form/{ResetPasswordForm.stories.js → ResetPasswordForm.oldstories.js} +0 -0
  176. /package/src/components/molecules/reset-password-success/{ResetPasswordSuccess.stories.js → ResetPasswordSuccess.oldstories.js} +0 -0
  177. /package/src/components/molecules/tab-sidebar/{TabSidebar.stories.js → TabSidebar.oldstories.js} +0 -0
  178. /package/src/components/molecules/terms-and-conditions/{TermsAndConditions.stories.js → TermsAndConditions.oldstories.js} +0 -0
  179. /package/src/components/molecules/terms-and-conditions-modal/{TermsAndConditionsModal.stories.js → TermsAndConditionsModal.oldstories.js} +0 -0
  180. /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>>;
@@ -0,0 +1,3 @@
1
+ import IdleModal from "./IdleModal";
2
+
3
+ export default IdleModal;
@@ -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>