@thecb/components 10.12.6 → 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 (179) hide show
  1. package/README.md +14 -6
  2. package/dist/index.cjs.js +1309 -1481
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.esm.js +1309 -1482
  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/checkbox/Checkbox.mdx +15 -0
  23. package/src/components/atoms/checkbox/Checkbox.oldstories.js +34 -0
  24. package/src/components/atoms/checkbox/Checkbox.stories.js +140 -25
  25. package/src/components/atoms/country-dropdown/CountryDropdown.mdx +36 -0
  26. package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +61 -27
  27. package/src/components/atoms/detail/Detail.js +0 -26
  28. package/src/components/atoms/detail/Detail.mdx +32 -0
  29. package/src/components/atoms/detail/Detail.stories.js +156 -0
  30. package/src/components/atoms/display-box/DisplayBox.mdx +11 -0
  31. package/src/components/atoms/display-box/DisplayBox.stories.js +65 -21
  32. package/src/components/atoms/display-card/DisplayCard.mdx +13 -0
  33. package/src/components/atoms/display-card/DisplayCard.stories.js +163 -22
  34. package/src/components/atoms/dropdown/Dropdown.mdx +65 -0
  35. package/src/components/atoms/dropdown/Dropdown.stories.js +91 -10
  36. package/src/components/atoms/form-layouts/FormInput.mdx +38 -0
  37. package/src/components/atoms/form-layouts/FormInput.stories.js +212 -26
  38. package/src/components/atoms/form-select/FormSelect.mdx +42 -0
  39. package/src/components/atoms/form-select/FormSelect.stories.js +55 -29
  40. package/src/components/atoms/formatted-address/FormattedAddress.mdx +13 -0
  41. package/src/components/atoms/formatted-address/FormattedAddress.stories.js +133 -27
  42. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.mdx +17 -0
  43. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.stories.js +57 -0
  44. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.mdx +40 -0
  45. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.stories.js +74 -0
  46. package/src/components/atoms/icons/Icons.mdx +40 -0
  47. package/src/components/atoms/icons/Icons.stories.js +325 -0
  48. package/src/components/atoms/labeled-amount/LabeledAmount.mdx +23 -0
  49. package/src/components/atoms/labeled-amount/LabeledAmount.stories.js +110 -34
  50. package/src/components/atoms/line-item/LineItem.mdx +28 -0
  51. package/src/components/atoms/line-item/LineItem.stories.js +89 -22
  52. package/src/components/atoms/link/Link.mdx +19 -0
  53. package/src/components/atoms/link/Link.stories.js +155 -49
  54. package/src/components/atoms/loading/Loading.mdx +13 -0
  55. package/src/components/atoms/loading/Loading.stories.js +22 -0
  56. package/src/components/atoms/loading-line/LoadingLine.js +14 -10
  57. package/src/components/atoms/loading-line/LoadingLine.mdx +15 -0
  58. package/src/components/atoms/loading-line/LoadingLine.stories.js +132 -28
  59. package/src/components/atoms/nav-footer/.DS_Store +0 -0
  60. package/src/components/atoms/nav-footer/NavFooter.mdx +15 -0
  61. package/src/components/atoms/nav-footer/NavFooter.stories.js +235 -22
  62. package/src/components/atoms/nav-header/NavHeader.mdx +13 -0
  63. package/src/components/atoms/nav-header/NavHeader.stories.js +122 -21
  64. package/src/components/atoms/nav-tabs/NavTabs.mdx +30 -0
  65. package/src/components/atoms/nav-tabs/NavTabs.stories.js +49 -0
  66. package/src/components/atoms/password-requirements/PasswordRequirements.mdx +39 -0
  67. package/src/components/atoms/password-requirements/PasswordRequirements.stories.js +108 -44
  68. package/src/components/atoms/placeholder/Placeholder.mdx +19 -0
  69. package/src/components/atoms/placeholder/Placeholder.stories.js +164 -36
  70. package/src/components/atoms/searchable-select/SearchableSelect.mdx +44 -0
  71. package/src/components/atoms/searchable-select/SearchableSelect.stories.js +103 -28
  72. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.mdx +36 -0
  73. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.stories.js +65 -40
  74. package/src/components/atoms/table/Table.mdx +71 -0
  75. package/src/components/atoms/table/Table.oldstories.js +84 -0
  76. package/src/components/atoms/table/Table.stories.js +59 -75
  77. package/src/components/atoms/table/TableRow.js +1 -0
  78. package/src/components/atoms/title/Title.js +0 -23
  79. package/src/components/atoms/title/Title.mdx +26 -0
  80. package/src/components/atoms/title/Title.stories.js +144 -0
  81. package/src/components/atoms/toggle-switch/ToggleSwitch.mdx +17 -0
  82. package/src/components/atoms/toggle-switch/ToggleSwitch.stories.js +103 -20
  83. package/src/components/atoms/toggle-switch/ToggleSwitch.theme.js +8 -5
  84. package/src/components/atoms/typeahead-input/TypeaheadInput.mdx +13 -0
  85. package/src/components/atoms/typeahead-input/TypeaheadInput.stories.js +63 -0
  86. package/src/components/molecules/.DS_Store +0 -0
  87. package/src/components/molecules/address-form/AddressForm.mdx +18 -0
  88. package/src/components/molecules/address-form/AddressForm.stories.js +223 -20
  89. package/src/components/molecules/banner/Banner.mdx +23 -0
  90. package/src/components/molecules/banner/Banner.stories.js +122 -26
  91. package/src/components/molecules/change-password-form/ChangePasswordForm.mdx +15 -0
  92. package/src/components/molecules/change-password-form/ChangePasswordForm.stories.js +203 -19
  93. package/src/components/molecules/collapsible-section/CollapsibleSection.mdx +15 -0
  94. package/src/components/molecules/collapsible-section/CollapsibleSection.stories.js +210 -61
  95. package/src/components/molecules/edit-name-form/EditNameForm.mdx +13 -0
  96. package/src/components/molecules/edit-name-form/EditNameForm.stories.js +117 -0
  97. package/src/components/molecules/idle-modal/IdleModal.js +101 -0
  98. package/src/components/molecules/idle-modal/IdleModal.mdx +17 -0
  99. package/src/components/molecules/idle-modal/IdleModal.stories.js +180 -0
  100. package/src/components/molecules/idle-modal/index.d.ts +16 -0
  101. package/src/components/molecules/idle-modal/index.js +3 -0
  102. package/src/components/molecules/index.js +1 -0
  103. package/src/components/molecules/link-card/LinkCard.mdx +17 -0
  104. package/src/components/molecules/link-card/LinkCard.stories.js +287 -72
  105. package/src/components/molecules/login-form/LoginForm.mdx +16 -0
  106. package/src/components/molecules/login-form/LoginForm.stories.js +117 -21
  107. package/src/components/molecules/modal/Modal.mdx +17 -0
  108. package/src/components/molecules/modal/Modal.stories.js +342 -128
  109. package/src/components/molecules/module/Module.mdx +17 -0
  110. package/src/components/molecules/module/Module.stories.js +267 -25
  111. package/src/components/molecules/obligation/.DS_Store +0 -0
  112. package/src/components/molecules/obligation/Obligation.mdx +23 -0
  113. package/src/components/molecules/obligation/Obligation.stories.js +460 -0
  114. package/src/components/molecules/obligation/icons/PropertyPersonalIcon.js +1 -1
  115. package/src/components/molecules/pagination/Pagination.mdx +15 -0
  116. package/src/components/molecules/pagination/Pagination.stories.js +177 -28
  117. package/src/components/molecules/popover/Popover.mdx +15 -0
  118. package/src/components/molecules/popover/Popover.stories.js +220 -0
  119. package/src/components/molecules/tabs/Tabs.mdx +17 -0
  120. package/src/components/molecules/tabs/Tabs.stories.js +135 -227
  121. package/src/components/molecules/toast-notification/Toast.mdx +15 -0
  122. package/src/components/molecules/toast-notification/Toast.stories.js +183 -0
  123. package/src/util/idleTimerUtils.js +36 -0
  124. package/src/util/index.js +3 -1
  125. package/src/components/molecules/edit-name-form/EdidNameForm.stories.js +0 -24
  126. package/src/components/molecules/toast-notification/ToastNotification.stories.js +0 -105
  127. /package/src/components/atoms/add-obligation/{AddObligation.stories.js → AddObligation.oldstories.js} +0 -0
  128. /package/src/components/atoms/amount-callout/{AmountCallout.stories.js → AmountCallout.oldstories.js} +0 -0
  129. /package/src/components/atoms/checkbox-list/{CheckboxList.stories.js → CheckboxList.oldstories.js} +0 -0
  130. /package/src/components/atoms/form-layouts/{FormLayouts.stories.js → FormLayouts.oldstories.js} +0 -0
  131. /package/src/components/atoms/hamburger-button/{HamburgerButton.stories.js → HamburgerButton.oldstories.js} +0 -0
  132. /package/src/components/atoms/heading/{Heading.stories.js → Heading.oldstories.js} +0 -0
  133. /package/src/components/atoms/icons/{icons.stories.js → icons.oldstories.js} +0 -0
  134. /package/src/components/atoms/layouts/examples/box-example/{BoxExample.stories.js → BoxExample.oldstories.js} +0 -0
  135. /package/src/components/atoms/layouts/examples/center-example/{CenterExample.stories.js → CenterExample.oldstories.js} +0 -0
  136. /package/src/components/atoms/layouts/examples/cluster-example/{ClusterExample.stories.js → ClusterExample.oldstories.js} +0 -0
  137. /package/src/components/atoms/layouts/examples/cover-example/{CoverExample.stories.js → CoverExample.oldstories.js} +0 -0
  138. /package/src/components/atoms/layouts/examples/frame-example/{FrameExample.stories.js → FrameExample.oldstories.js} +0 -0
  139. /package/src/components/atoms/layouts/examples/grid-example/{GridExample.stories.js → GridExample.oldstories.js} +0 -0
  140. /package/src/components/atoms/layouts/examples/imposter-example/{ImposterExample.stories.js → ImposterExample.oldstories.js} +0 -0
  141. /package/src/components/atoms/layouts/examples/motion-example/{MotionExample.stories.js → MotionExample.oldstories.js} +0 -0
  142. /package/src/components/atoms/layouts/examples/reel-example/{ReelExample.stories.js → ReelExample.oldstories.js} +0 -0
  143. /package/src/components/atoms/layouts/examples/sidebar-example/{SidebarExample.stories.js → SidebarExample.oldstories.js} +0 -0
  144. /package/src/components/atoms/layouts/examples/stack-example/{StackExample.stories.js → StackExample.oldstories.js} +0 -0
  145. /package/src/components/atoms/layouts/examples/switcher-example/{SwitcherExample.stories.js → SwitcherExample.oldstories.js} +0 -0
  146. /package/src/components/atoms/paragraph/{Paragraph.stories.js → Paragraph.oldstories.js} +0 -0
  147. /package/src/components/atoms/processing-fee/{ProcessingFee.stories.js → ProcessingFee.oldstories.js} +0 -0
  148. /package/src/components/atoms/search/{Search.stories.js → Search.oldstories.js} +0 -0
  149. /package/src/components/atoms/solid-divider/{SolidDivider.stories.js → SolidDivider.oldstories.js} +0 -0
  150. /package/src/components/atoms/sortable-table-heading/{SortableTableHeading.stories.js → SortableTableHeading.oldstories.js} +0 -0
  151. /package/src/components/atoms/spinner/{Spinner.stories.js → Spinner.oldstories.js} +0 -0
  152. /package/src/components/atoms/tab/{Tab.stories.js → Tab.oldstories.js} +0 -0
  153. /package/src/components/atoms/text/{Text.stories.js → Text.oldstories.js} +0 -0
  154. /package/src/components/atoms/typeahead-input/{TypeaheadIinput.stories.js → TypeaheadIinput.oldstories.js} +0 -0
  155. /package/src/components/atoms/wallet-name/{WalletName.stories.js → WalletName.oldstories.js} +0 -0
  156. /package/src/components/molecules/account-and-routing-modal/{AccountAndRoutingModal.stories.js → AccountAndRoutingModal.oldstories.js} +0 -0
  157. /package/src/components/molecules/editable-list/{EditableList.stories.js → EditableList.oldstories.js} +0 -0
  158. /package/src/components/molecules/email-form/{EmailForm.stories.js → EmailForm.oldstories.js} +0 -0
  159. /package/src/components/molecules/forgot-password-form/{ForgotPasswordForm.stories.js → ForgotPasswordForm.oldstories.js} +0 -0
  160. /package/src/components/molecules/highlight-tab-row/{HighlightTabRow.stories.js → HighlightTabRow.oldstories.js} +0 -0
  161. /package/src/components/molecules/multiple-select-filter/{MultipleSelectFilter.stories.js → MultipleSelectFilter.oldstories.js} +0 -0
  162. /package/src/components/molecules/obligation/modules/{AmountModule.stories.js → AmountModule.oldstories.js} +0 -0
  163. /package/src/components/molecules/payment-button-bar/{PaymentButtonBar.stories.js → PaymentButtonBar.oldstories.js} +0 -0
  164. /package/src/components/molecules/payment-details/{PaymentDetails.stories.js → PaymentDetails.oldstories.js} +0 -0
  165. /package/src/components/molecules/payment-form-ach/{PaymentFormACH.stories.js → PaymentFormACH.oldstories.js} +0 -0
  166. /package/src/components/molecules/payment-form-card/{PaymentFormCard.stories.js → PaymentFormCard.oldstories.js} +0 -0
  167. /package/src/components/molecules/periscope-dashboard-iframe/{PeriscopeDashBoardIframe.stories.js → PeriscopeDashBoardIframe.oldstories.js} +0 -0
  168. /package/src/components/molecules/phone-form/{PhoneForm.stories.js → PhoneForm.oldstories.js} +0 -0
  169. /package/src/components/molecules/popup-menu/{PopupMenu.stories.js → PopupMenu.oldstories.js} +0 -0
  170. /package/src/components/molecules/radio-group/{RadioGroup.stories.js → RadioGroup.oldstories.js} +0 -0
  171. /package/src/components/molecules/radio-section/{RadioSection.stories.js → RadioSection.oldstories.js} +0 -0
  172. /package/src/components/molecules/registration-form/{RegistrationForm.stories.js → RegistrationForm.oldstories.js} +0 -0
  173. /package/src/components/molecules/reset-confirmation-form/{ResetConfirmationForm.stories.js → ResetConfirmationForm.oldstories.js} +0 -0
  174. /package/src/components/molecules/reset-password-form/{ResetPasswordForm.stories.js → ResetPasswordForm.oldstories.js} +0 -0
  175. /package/src/components/molecules/reset-password-success/{ResetPasswordSuccess.stories.js → ResetPasswordSuccess.oldstories.js} +0 -0
  176. /package/src/components/molecules/tab-sidebar/{TabSidebar.stories.js → TabSidebar.oldstories.js} +0 -0
  177. /package/src/components/molecules/terms-and-conditions/{TermsAndConditions.stories.js → TermsAndConditions.oldstories.js} +0 -0
  178. /package/src/components/molecules/terms-and-conditions-modal/{TermsAndConditionsModal.stories.js → TermsAndConditionsModal.oldstories.js} +0 -0
  179. /package/src/components/molecules/workflow-tile/{WorkflowTile.stories.js → WorkflowTile.oldstories.js} +0 -0
@@ -1,31 +1,244 @@
1
+ import NavFooter from "./NavFooter";
2
+ import { Box, Cluster, Stack } from "../layouts";
3
+ import ButtonWithAction from "../button-with-action";
1
4
  import React from "react";
2
- import { text, select, boolean } from "@storybook/addon-knobs";
5
+ import { fn } from "@storybook/test";
6
+ import ImageBox from "../image-box/ImageBox";
7
+ import {
8
+ BRIGHT_GREY,
9
+ DUSTY_GREY,
10
+ ROYAL_BLUE_VIVID,
11
+ WHITE
12
+ } from "../../../constants/colors";
13
+ import { FONT_WEIGHT_SEMIBOLD } from "../../../constants/style_constants";
14
+ import ExternalLink from "../link/ExternalLink";
15
+ import ExternalLinkIcon from "../icons/ExternalLinkIcon";
16
+ import Text from "../text";
3
17
 
4
- import NavFooter from "./NavFooter";
5
- import page from "../../../../.storybook/page";
6
- import * as colors from "../../../constants/colors";
18
+ const meta = {
19
+ title: "Atoms/NavFooter",
20
+ component: NavFooter,
21
+ parameters: {
22
+ layout: "centered",
23
+ controls: { expanded: true }
24
+ },
25
+ tags: ["!autodocs"],
26
+ args: {
27
+ leftContent: undefined,
28
+ rightContent: undefined,
29
+ footerMinHeight: "104px",
30
+ largeSide: "right",
31
+ largeSideSize: "2",
32
+ footerPadding: "1.5rem 1rem",
33
+ isMobile: false,
34
+ backgroundColor: undefined,
35
+ footerWidth: undefined
36
+ },
37
+ argTypes: {
38
+ leftContent: {
39
+ description: "Content that appears on the left side of the footer",
40
+ table: {
41
+ type: { summary: "React Component" },
42
+ defaultValue: { summary: undefined }
43
+ }
44
+ },
45
+ rightContent: {
46
+ description: "Content that appears on the right side of the footer",
47
+ table: {
48
+ type: { summary: "React Component" },
49
+ defaultValue: { summary: undefined }
50
+ }
51
+ },
52
+ footerMinHeight: {
53
+ description: "Minimum height of the footer",
54
+ table: {
55
+ type: { summary: "string" },
56
+ defaultValue: { summary: "105px" }
57
+ }
58
+ },
59
+ isMobile: {
60
+ description:
61
+ "Whether the page is currently displaying on a mobile device",
62
+ table: {
63
+ type: { summary: "boolean" },
64
+ defaultValue: { summary: false }
65
+ }
66
+ },
67
+ backgroundColor: {
68
+ description: "Background color of the footer",
69
+ table: {
70
+ type: { summary: "string" },
71
+ defaultValue: { summary: undefined }
72
+ }
73
+ },
74
+ footerWidth: {
75
+ description:
76
+ "Optional value for maximum width of inner container. Component uses 76.5rem or 1224px if not specified. If page is larger than max width, container will be centered within.",
77
+ table: {
78
+ type: { summary: "string" },
79
+ defaultValue: { summary: undefined }
80
+ }
81
+ }
82
+ }
83
+ };
7
84
 
8
- const story = page({
9
- title: "Components|Atoms/NavFooter",
10
- Component: NavFooter
11
- });
12
- export default story;
85
+ export default meta;
13
86
 
14
- const Left = () => (
15
- <div style={{ border: "2px solid black", width: "50px" }}>Left Content</div>
87
+ const logo = (
88
+ <ImageBox
89
+ maxWidth="150px"
90
+ minHeight="50px"
91
+ image={{
92
+ url:
93
+ "https://cb-public-assets.s3-us-west-2.amazonaws.com/cityville/logo-footer-white.svg",
94
+ altText: "Cityville Payment Portal Logo"
95
+ }}
96
+ />
16
97
  );
17
98
 
18
- const Right = () => (
19
- <div style={{ border: "2px solid black", width: "50px" }}>Right Content</div>
99
+ const copyright = (
100
+ <Box padding="0.5rem">
101
+ <Text variant="pXS" color={WHITE}>
102
+ © 2024 City of Cityville
103
+ </Text>
104
+ </Box>
20
105
  );
21
106
 
22
- export const navFooter = () => (
23
- <NavFooter
24
- leftContent={<Left />}
25
- rightContent={<Right />}
26
- $headerHeight={text("headerHeight", "105px", "props")}
27
- backgroundColor={select("activeColor", colors, "white", "props")}
28
- footerPadding={text("footerPadding", "1.5rem 1rem", "props")}
29
- isMobile={boolean("isMobile", false, "props")}
30
- />
107
+ const logoutButton = (
108
+ <Box padding="0">
109
+ <ButtonWithAction
110
+ action={() => fn()}
111
+ variant="whitePrimary"
112
+ text="Log Out"
113
+ extraStyles={`
114
+ padding: 0.75rem 2rem;
115
+ border: 2px solid ${WHITE};
116
+ color: ${WHITE};
117
+ &:hover {
118
+ background-color: rgba(255, 255, 255, 0.1);
119
+ > * > span {
120
+ color: ${WHITE};
121
+ background-color: transparent;
122
+ }
123
+ }
124
+ &:active {
125
+ border: 2px solid ${WHITE};
126
+ background-color: rgba(255, 255, 255, 0.25);
127
+ > * > span {
128
+ color: ${WHITE};
129
+ background-color: transparent;
130
+ }
131
+ };
132
+ &:focus {
133
+ outline: 3px solid ${WHITE};
134
+ outline-offset: 2px;
135
+ }
136
+ > * > span {
137
+ color: ${WHITE};
138
+ }`}
139
+ />
140
+ </Box>
141
+ );
142
+
143
+ const subfooterLinkList = [
144
+ {
145
+ text: "Demo Home",
146
+ link: "/"
147
+ },
148
+ {
149
+ text: "Privacy Policy",
150
+ link: "/"
151
+ },
152
+ {
153
+ text: "Join Cityville Utilities",
154
+ link: "/"
155
+ },
156
+ {
157
+ text: "Utility Blog",
158
+ link: "/"
159
+ },
160
+ {
161
+ text: "Report an Outage",
162
+ link: "/"
163
+ }
164
+ ];
165
+
166
+ const subfooterLinks = subfooterLinkList.map((item, index) => (
167
+ <Box
168
+ padding="0"
169
+ key={`link-${item.text}`}
170
+ extraStyles={`max-height: 1.25rem;`}
171
+ >
172
+ <ExternalLink
173
+ newTab
174
+ href={item.link}
175
+ color={WHITE}
176
+ hoverColor={WHITE}
177
+ extraStyles={`text-decoration: none;
178
+ &:focus {
179
+ outline: 3px solid ${WHITE};
180
+ outline-offset: 2px;
181
+ }`}
182
+ size="0.875rem"
183
+ lineHeight="1.25rem"
184
+ weight={FONT_WEIGHT_SEMIBOLD}
185
+ ariaLabel={`Link to ${item.text} (opens in a new window)`}
186
+ >
187
+ <Cluster childGap="0.5rem" justify="center" align="center">
188
+ <Text
189
+ variant="pXS"
190
+ color={WHITE}
191
+ weight={FONT_WEIGHT_SEMIBOLD}
192
+ extraStyles={`cursor: pointer;
193
+ &:focus {
194
+ outline: 3px solid ${WHITE};
195
+ outline-offset: 2px;
196
+ }`}
197
+ >
198
+ {item.text}
199
+ </Text>
200
+ <ExternalLinkIcon linkColor={WHITE} text={`link-icon-${index}`} />
201
+ </Cluster>
202
+ </ExternalLink>
203
+ </Box>
204
+ ));
205
+
206
+ const subfooterLeftContent = (
207
+ <Cluster justify="flex-start" align="center" key="subfooter-left">
208
+ <Box padding={"0.5rem"} minWidth="100%">
209
+ <Stack direction={"row"} childGap={"2rem"}>
210
+ {[...subfooterLinks]}
211
+ </Stack>
212
+ </Box>
213
+ </Cluster>
31
214
  );
215
+
216
+ export const BasicFooter = {
217
+ render: args => (
218
+ <Box minWidth="1200px">
219
+ <NavFooter
220
+ {...args}
221
+ leftContent={logo}
222
+ rightContent={logoutButton}
223
+ backgroundColor={ROYAL_BLUE_VIVID}
224
+ />
225
+ </Box>
226
+ )
227
+ };
228
+
229
+ export const BasicSubfooter = {
230
+ render: args => (
231
+ <Box minWidth="1200px" backgroundColor={DUSTY_GREY}>
232
+ <NavFooter
233
+ {...args}
234
+ leftContent={subfooterLeftContent}
235
+ rightContent={copyright}
236
+ backgroundColor={BRIGHT_GREY}
237
+ footerMinHeight="45px"
238
+ largeSide="left"
239
+ largeSideSize="4"
240
+ footerPadding="0 1rem"
241
+ />
242
+ </Box>
243
+ )
244
+ };
@@ -0,0 +1,13 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as NavHeaderStories from './NavHeader.stories.js';
4
+
5
+ <Meta of={NavHeaderStories} />
6
+
7
+ <Title />
8
+
9
+ The NavHeader component is a wrapper designed to create a page header. The component accepts children components for its left and right side and sizes itself to the width of the page. The component can take a maxWidth value that will center the header within it, no matter the overall size of the screen.
10
+
11
+ <Controls />
12
+
13
+ <Story />
@@ -1,29 +1,130 @@
1
+ import NavHeader from "./NavHeader";
2
+ import { Box, Cover } from "../layouts";
3
+ import HamburgerButton from "../hamburger-button";
1
4
  import React from "react";
2
- import { text, number, select } from "@storybook/addon-knobs";
5
+ import { fn } from "@storybook/test";
6
+ import ImageBox from "../image-box/ImageBox";
7
+ import {
8
+ CATSKILL_WHITE,
9
+ DUSTY_GREY,
10
+ ROYAL_BLUE_VIVID,
11
+ SEASHELL_WHITE
12
+ } from "../../../constants/colors";
3
13
 
4
- import NavHeader from "./NavHeader";
5
- import page from "../../../../.storybook/page";
6
- import * as colors from "../../../constants/colors";
14
+ const meta = {
15
+ title: "Atoms/NavHeader",
16
+ component: NavHeader,
17
+ parameters: {
18
+ layout: "centered",
19
+ controls: { expanded: true }
20
+ },
21
+ tags: ["!autodocs"],
22
+ args: {
23
+ leftContent: undefined,
24
+ rightContent: undefined,
25
+ headerHeight: "105px",
26
+ isMobile: false,
27
+ backgroundColor: undefined,
28
+ headerWidth: undefined
29
+ },
30
+ argTypes: {
31
+ leftContent: {
32
+ description: "Content that appears on the left side of the header",
33
+ table: {
34
+ type: { summary: "React Component" },
35
+ defaultValue: { summary: undefined }
36
+ }
37
+ },
38
+ rightContent: {
39
+ description: "Content that appears on the right side of the header",
40
+ table: {
41
+ type: { summary: "React Component" },
42
+ defaultValue: { summary: undefined }
43
+ }
44
+ },
45
+ headerHeight: {
46
+ description: "Height of the header container in pixels",
47
+ table: {
48
+ type: { summary: "string" },
49
+ defaultValue: { summary: "105px" }
50
+ }
51
+ },
52
+ isMobile: {
53
+ description:
54
+ "Whether the page is currently displaying on a mobile device",
55
+ table: {
56
+ type: { summary: "boolean" },
57
+ defaultValue: { summary: false }
58
+ }
59
+ },
60
+ backgroundColor: {
61
+ description: "Background color of the header",
62
+ table: {
63
+ type: { summary: "string" },
64
+ defaultValue: { summary: undefined }
65
+ }
66
+ },
67
+ headerWidth: {
68
+ description:
69
+ "Optional value for maximum width of inner container. Component uses 76.5rem or 1224px if not specified. If page is larger than max width, container will be centered within.",
70
+ table: {
71
+ type: { summary: "string" },
72
+ defaultValue: { summary: undefined }
73
+ }
74
+ }
75
+ }
76
+ };
7
77
 
8
- const story = page({
9
- title: "Components|Atoms/NavHeader",
10
- Component: NavHeader
11
- });
12
- export default story;
78
+ export default meta;
13
79
 
14
- const Left = () => (
15
- <div style={{ border: "2px solid black", width: "50px" }}>Left Content</div>
80
+ const logo = (
81
+ <ImageBox
82
+ maxWidth="150px"
83
+ minHeight="50px"
84
+ image={{
85
+ url:
86
+ "https://cb-public-assets.s3-us-west-2.amazonaws.com/cityville/logo-blue.svg",
87
+ altText: "Cityville Payment Portal Logo"
88
+ }}
89
+ />
16
90
  );
17
91
 
18
- const Right = () => (
19
- <div style={{ border: "2px solid black", width: "50px" }}>Right Content</div>
92
+ const hamburger = (
93
+ <Box padding="0">
94
+ <Cover singleChild fillCenter>
95
+ <HamburgerButton
96
+ isActive={false}
97
+ onClick={() => fn()}
98
+ activeColor={ROYAL_BLUE_VIVID}
99
+ inactiveColor={ROYAL_BLUE_VIVID}
100
+ />
101
+ </Cover>
102
+ </Box>
20
103
  );
21
104
 
22
- export const navHeader = () => (
23
- <NavHeader
24
- leftContent={<Left />}
25
- rightContent={<Right />}
26
- headerHeight={text("headerHeight", "105px", "props")}
27
- backgroundColor={select("activeColor", colors, "white", "props")}
28
- />
29
- );
105
+ export const BasicHeader = {
106
+ render: args => (
107
+ <Box minWidth="1200px">
108
+ <NavHeader
109
+ {...args}
110
+ leftContent={logo}
111
+ rightContent={hamburger}
112
+ backgroundColor={SEASHELL_WHITE}
113
+ />
114
+ </Box>
115
+ )
116
+ };
117
+
118
+ export const HeaderSmallerThanPage = {
119
+ render: args => (
120
+ <Box minWidth="1200px" backgroundColor={DUSTY_GREY}>
121
+ <NavHeader
122
+ {...args}
123
+ leftContent={logo}
124
+ rightContent={hamburger}
125
+ backgroundColor={CATSKILL_WHITE}
126
+ headerWidth="800px"
127
+ />
128
+ </Box>
129
+ )
130
+ };
@@ -0,0 +1,30 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as NavTabsStories from './NavTabs.stories.js';
4
+
5
+ <Meta of={NavTabsStories} />
6
+
7
+ <Title />
8
+
9
+ The NavTabs component renders a configurable row of links on desktop, and a stack of links on mobile.
10
+
11
+ - The links are horizontally centered
12
+ - Each tab uses the `InternalLink` component, which uses the `Link` component from `react-router-dom`.
13
+ - The current, or active, page is determined by checking if `location.pathname` from the `useLocation` hook from `react-router-dom` includes a tab's `path`.
14
+ - There is no default gap between links on desktop, so it's recommended to always provide a value for `tabGap`.
15
+ - The font, link color, and active color are themeable.
16
+ - Expands to fit the width of it's containing element.
17
+
18
+ ## Example `tabsConfig` Format
19
+
20
+ ```
21
+ const tabs = [
22
+ { label: "Home", path: "/" },
23
+ { label: "About", path: "/about" },
24
+ { label: "Contact", path: "/contact" }
25
+ ];
26
+ ```
27
+
28
+ <Story />
29
+
30
+ <Controls />
@@ -0,0 +1,49 @@
1
+ import NavTabs from "./NavTabs";
2
+
3
+ const meta = {
4
+ title: "Atoms/NavTabs",
5
+ component: NavTabs,
6
+ tags: ["!autodocs"],
7
+ parameters: {
8
+ layout: "centered",
9
+ controls: { expanded: true }
10
+ },
11
+ args: {
12
+ tabsConfig: undefined,
13
+ tabGap: undefined
14
+ },
15
+ argTypes: {
16
+ tabsConfig: {
17
+ description: "Array of tab objects",
18
+ control: { type: "object" },
19
+ table: {
20
+ type: { summary: "array" },
21
+ defaultValue: { summary: undefined }
22
+ }
23
+ },
24
+ tabGap: {
25
+ description:
26
+ "Gap between tabs. Passed to the Cluster component that wraps the tabs on desktop screens.",
27
+ control: { type: "text" },
28
+ table: {
29
+ type: { summary: "string" },
30
+ defaultValue: { summary: undefined }
31
+ }
32
+ }
33
+ }
34
+ };
35
+
36
+ const tabs = [
37
+ { label: "Home", path: "/" },
38
+ { label: "About", path: "/about" },
39
+ { label: "Contact", path: "/contact" }
40
+ ];
41
+
42
+ export default meta;
43
+
44
+ export const Basic = {
45
+ args: {
46
+ tabsConfig: tabs,
47
+ tabGap: "2rem"
48
+ }
49
+ };
@@ -0,0 +1,39 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as PasswordRequirementsStories from './PasswordRequirements.stories.js';
4
+
5
+ <Meta of={PasswordRequirementsStories} />
6
+
7
+ <Title />
8
+
9
+ PasswordRequirements is a small widget that can be used in addition to a form that requires a user to set a password. The widget displays a box listing requirements for the user's password, and whether the entered password meets those requirements.
10
+
11
+ The requirements are currently hardcoded to meet the requirements for Navigate Frontend: passwords must be a minimum length of 8 characters and contain a number, uppercase letter, lowercase letter, and special character. Requirements can be changed or added to by modifying the code in the PasswordRequirements component.
12
+
13
+ This component is *not* to be used with applications that support Okta SSO for user authentication, _unless_ they also support non-SSO-sign-on using User Management Service. For applications that exclusively use Okta SSO to manage user authentication, Okta provides its own password validation experience that can be used wholesale or forked.
14
+
15
+
16
+ ## Form Integration
17
+
18
+ In order to properly demonstrate functionality, the PasswordRequirements story includes two FormInput components and Redux Freeform integration. The `password` prop required by PasswordRequirements takes the form of a Redux Freeform field object. This object _can_ be generated with [redux-freeform](https://github.com/CityBaseInc/redux-freeform). Below are example values for each prop with the minimum properties needed for a password field object.
19
+
20
+ ### field
21
+
22
+ ```
23
+ {
24
+ "dirty": false,
25
+ "rawValue": "",
26
+ "errors": [
27
+ "error/REQUIRED",
28
+ "error/HAS_LENGTH",
29
+ "error/HAS_NUMBER",
30
+ "error/HAS_UPPERCASE_LETTER",
31
+ "error/HAS_LOWERCASE_LETTER",
32
+ "error/HAS_SPECIAL_CHARACTER"
33
+ ],
34
+ "hasErrors": true
35
+ }
36
+ ```
37
+ <Controls />
38
+
39
+ <Story />