@thecb/components 10.12.2-beta.0 → 10.12.3-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 (223) hide show
  1. package/README.md +4 -0
  2. package/dist/index.cjs.js +1476 -2489
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.d.ts +8 -6
  5. package/dist/index.esm.js +1476 -2488
  6. package/dist/index.esm.js.map +1 -1
  7. package/package.json +25 -13
  8. package/src/components/atoms/.DS_Store +0 -0
  9. package/src/components/atoms/alert/Alert.mdx +19 -0
  10. package/src/components/atoms/alert/Alert.stories.js +148 -26
  11. package/src/components/atoms/badge/Badge.js +2 -2
  12. package/src/components/atoms/badge/Badge.mdx +27 -0
  13. package/src/components/atoms/badge/Badge.stories.js +143 -29
  14. package/src/components/atoms/breadcrumb/Breadcrumb.mdx +21 -0
  15. package/src/components/atoms/breadcrumb/Breadcrumb.stories.js +38 -29
  16. package/src/components/atoms/button-with-action/ButtonWithAction.stories.js +108 -55
  17. package/src/components/atoms/button-with-link/ButtonWithLink.mdx +21 -0
  18. package/src/components/atoms/button-with-link/ButtonWithLink.stories.js +160 -31
  19. package/src/components/atoms/card/Card.js +13 -1
  20. package/src/components/atoms/card/Card.mdx +41 -0
  21. package/src/components/atoms/card/Card.stories.js +360 -0
  22. package/src/components/atoms/card/Card.theme.js +2 -0
  23. package/src/components/atoms/card/index.d.ts +1 -0
  24. package/src/components/atoms/checkbox/Checkbox.js +8 -14
  25. package/src/components/atoms/checkbox/Checkbox.mdx +15 -0
  26. package/src/components/atoms/checkbox/Checkbox.oldstories.js +30 -0
  27. package/src/components/atoms/checkbox/Checkbox.stories.js +148 -29
  28. package/src/components/atoms/country-dropdown/CountryDropdown.mdx +36 -0
  29. package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +61 -27
  30. package/src/components/atoms/detail/Detail.js +0 -26
  31. package/src/components/atoms/detail/Detail.mdx +32 -0
  32. package/src/components/atoms/detail/Detail.stories.js +156 -0
  33. package/src/components/atoms/display-box/DisplayBox.mdx +11 -0
  34. package/src/components/atoms/display-box/DisplayBox.stories.js +65 -21
  35. package/src/components/atoms/display-card/DisplayCard.mdx +13 -0
  36. package/src/components/atoms/display-card/DisplayCard.stories.js +163 -22
  37. package/src/components/atoms/dropdown/Dropdown.mdx +65 -0
  38. package/src/components/atoms/dropdown/Dropdown.stories.js +91 -10
  39. package/src/components/atoms/form-layouts/FormInput.mdx +38 -0
  40. package/src/components/atoms/form-layouts/FormInput.stories.js +212 -26
  41. package/src/components/atoms/form-select/FormSelect.mdx +42 -0
  42. package/src/components/atoms/form-select/FormSelect.stories.js +55 -29
  43. package/src/components/atoms/formatted-address/FormattedAddress.mdx +13 -0
  44. package/src/components/atoms/formatted-address/FormattedAddress.stories.js +133 -27
  45. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.mdx +17 -0
  46. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.stories.js +57 -0
  47. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.mdx +40 -0
  48. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.stories.js +74 -0
  49. package/src/components/atoms/icons/Icons.mdx +40 -0
  50. package/src/components/atoms/icons/Icons.stories.js +325 -0
  51. package/src/components/atoms/icons/index.js +1 -5
  52. package/src/components/atoms/labeled-amount/LabeledAmount.mdx +23 -0
  53. package/src/components/atoms/labeled-amount/LabeledAmount.stories.js +110 -34
  54. package/src/components/atoms/line-item/LineItem.mdx +28 -0
  55. package/src/components/atoms/line-item/LineItem.stories.js +89 -22
  56. package/src/components/atoms/link/Link.mdx +19 -0
  57. package/src/components/atoms/link/Link.stories.js +155 -49
  58. package/src/components/atoms/loading/Loading.mdx +13 -0
  59. package/src/components/atoms/loading/Loading.stories.js +22 -0
  60. package/src/components/atoms/loading-line/LoadingLine.js +14 -10
  61. package/src/components/atoms/loading-line/LoadingLine.mdx +15 -0
  62. package/src/components/atoms/loading-line/LoadingLine.stories.js +132 -28
  63. package/src/components/atoms/nav-footer/NavFooter.mdx +15 -0
  64. package/src/components/atoms/nav-footer/NavFooter.stories.js +235 -22
  65. package/src/components/atoms/nav-header/NavHeader.mdx +13 -0
  66. package/src/components/atoms/nav-header/NavHeader.stories.js +122 -21
  67. package/src/components/atoms/nav-tabs/NavTabs.mdx +30 -0
  68. package/src/components/atoms/nav-tabs/NavTabs.stories.js +49 -0
  69. package/src/components/atoms/password-requirements/PasswordRequirements.mdx +39 -0
  70. package/src/components/atoms/password-requirements/PasswordRequirements.stories.js +108 -44
  71. package/src/components/atoms/placeholder/Placeholder.mdx +19 -0
  72. package/src/components/atoms/placeholder/Placeholder.stories.js +164 -36
  73. package/src/components/atoms/searchable-select/SearchableSelect.mdx +44 -0
  74. package/src/components/atoms/searchable-select/SearchableSelect.stories.js +103 -28
  75. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.mdx +36 -0
  76. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.stories.js +65 -40
  77. package/src/components/atoms/table/Table.mdx +71 -0
  78. package/src/components/atoms/table/Table.oldstories.js +84 -0
  79. package/src/components/atoms/table/Table.stories.js +59 -75
  80. package/src/components/atoms/table/TableRow.js +1 -0
  81. package/src/components/atoms/title/Title.js +0 -23
  82. package/src/components/atoms/title/Title.mdx +26 -0
  83. package/src/components/atoms/title/Title.stories.js +144 -0
  84. package/src/components/atoms/toggle-switch/ToggleSwitch.mdx +17 -0
  85. package/src/components/atoms/toggle-switch/ToggleSwitch.stories.js +103 -20
  86. package/src/components/atoms/toggle-switch/ToggleSwitch.theme.js +8 -5
  87. package/src/components/atoms/typeahead-input/TypeaheadInput.mdx +13 -0
  88. package/src/components/atoms/typeahead-input/TypeaheadInput.stories.js +63 -0
  89. package/src/components/molecules/address-form/AddressForm.mdx +18 -0
  90. package/src/components/molecules/address-form/AddressForm.stories.js +223 -20
  91. package/src/components/molecules/banner/Banner.mdx +23 -0
  92. package/src/components/molecules/banner/Banner.stories.js +122 -26
  93. package/src/components/molecules/change-password-form/ChangePasswordForm.mdx +15 -0
  94. package/src/components/molecules/change-password-form/ChangePasswordForm.stories.js +203 -19
  95. package/src/components/molecules/collapsible-section/CollapsibleSection.mdx +15 -0
  96. package/src/components/molecules/collapsible-section/CollapsibleSection.stories.js +210 -61
  97. package/src/components/molecules/edit-name-form/EditNameForm.mdx +13 -0
  98. package/src/components/molecules/edit-name-form/EditNameForm.stories.js +117 -0
  99. package/src/components/molecules/idle-modal/IdleModal.js +101 -0
  100. package/src/components/molecules/idle-modal/IdleModal.mdx +17 -0
  101. package/src/components/molecules/idle-modal/IdleModal.stories.js +180 -0
  102. package/src/components/molecules/idle-modal/index.d.ts +16 -0
  103. package/src/components/molecules/idle-modal/index.js +3 -0
  104. package/src/components/molecules/index.js +1 -0
  105. package/src/components/molecules/link-card/LinkCard.mdx +17 -0
  106. package/src/components/molecules/link-card/LinkCard.stories.js +287 -72
  107. package/src/components/molecules/login-form/LoginForm.mdx +16 -0
  108. package/src/components/molecules/login-form/LoginForm.stories.js +117 -21
  109. package/src/components/molecules/modal/Modal.mdx +17 -0
  110. package/src/components/molecules/modal/Modal.stories.js +342 -128
  111. package/src/components/molecules/module/Module.mdx +17 -0
  112. package/src/components/molecules/module/Module.stories.js +267 -25
  113. package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.js +309 -77
  114. package/src/components/molecules/multiple-select-filter/{MultipleSelectFilter.stories.js → MultipleSelectFilter.oldstories.js} +4 -2
  115. package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.styled.js +6 -6
  116. package/src/components/molecules/multiple-select-filter/index.d.ts +2 -2
  117. package/src/components/molecules/obligation/Obligation.mdx +23 -0
  118. package/src/components/molecules/obligation/Obligation.stories.js +460 -0
  119. package/src/components/molecules/obligation/icons/PropertyPersonalIcon.js +1 -1
  120. package/src/components/molecules/pagination/Pagination.mdx +15 -0
  121. package/src/components/molecules/pagination/Pagination.stories.js +177 -28
  122. package/src/components/molecules/popover/Popover.mdx +15 -0
  123. package/src/components/molecules/popover/Popover.stories.js +220 -0
  124. package/src/components/molecules/tabs/Tabs.mdx +17 -0
  125. package/src/components/molecules/tabs/Tabs.stories.js +135 -227
  126. package/src/components/molecules/toast-notification/Toast.mdx +15 -0
  127. package/src/components/molecules/toast-notification/Toast.stories.js +183 -0
  128. package/src/hooks/use-outside-click/index.js +5 -4
  129. package/src/stories/Button.stories.ts +53 -0
  130. package/src/stories/Button.tsx +48 -0
  131. package/src/stories/Configure.mdx +364 -0
  132. package/src/stories/Header.stories.ts +33 -0
  133. package/src/stories/Header.tsx +56 -0
  134. package/src/stories/Page.stories.ts +32 -0
  135. package/src/stories/Page.tsx +73 -0
  136. package/src/stories/assets/accessibility.png +0 -0
  137. package/src/stories/assets/accessibility.svg +5 -0
  138. package/src/stories/assets/addon-library.png +0 -0
  139. package/src/stories/assets/assets.png +0 -0
  140. package/src/stories/assets/avif-test-image.avif +0 -0
  141. package/src/stories/assets/context.png +0 -0
  142. package/src/stories/assets/discord.svg +15 -0
  143. package/src/stories/assets/docs.png +0 -0
  144. package/src/stories/assets/figma-plugin.png +0 -0
  145. package/src/stories/assets/github.svg +3 -0
  146. package/src/stories/assets/share.png +0 -0
  147. package/src/stories/assets/styling.png +0 -0
  148. package/src/stories/assets/testing.png +0 -0
  149. package/src/stories/assets/theming.png +0 -0
  150. package/src/stories/assets/tutorials.svg +12 -0
  151. package/src/stories/assets/youtube.svg +4 -0
  152. package/src/stories/button.css +30 -0
  153. package/src/stories/header.css +32 -0
  154. package/src/stories/page.css +69 -0
  155. package/src/util/idleTimerUtils.js +36 -0
  156. package/src/util/index.js +3 -1
  157. package/src/components/atoms/icons/CheckboxCheckmarkIcon.js +0 -45
  158. package/src/components/atoms/icons/PaymentStatusIcon.d.ts +0 -1
  159. package/src/components/atoms/icons/PaymentStatusIcon.js +0 -28
  160. package/src/components/atoms/icons/PersonIcon.d.ts +0 -1
  161. package/src/components/atoms/icons/PersonIcon.js +0 -28
  162. package/src/components/atoms/icons/icons.stories.js +0 -120
  163. package/src/components/molecules/edit-name-form/EdidNameForm.stories.js +0 -24
  164. package/src/components/molecules/multiple-select-filter/__private__/ActionLinkButton.js +0 -27
  165. package/src/components/molecules/multiple-select-filter/__private__/FilterButton.js +0 -89
  166. package/src/components/molecules/multiple-select-filter/__private__/FilterDropdown.js +0 -27
  167. package/src/components/molecules/multiple-select-filter/__private__/FilterableList.js +0 -146
  168. package/src/components/molecules/multiple-select-filter/__private__/FilterableListItem.js +0 -79
  169. package/src/components/molecules/multiple-select-filter/__private__/SearchBox.js +0 -41
  170. package/src/components/molecules/multiple-select-filter/__private__/useKeyboardNavigation.js +0 -84
  171. package/src/components/molecules/multiple-select-filter/__private__/util.js +0 -31
  172. package/src/components/molecules/toast-notification/ToastNotification.stories.js +0 -105
  173. /package/src/components/atoms/add-obligation/{AddObligation.stories.js → AddObligation.oldstories.js} +0 -0
  174. /package/src/components/atoms/amount-callout/{AmountCallout.stories.js → AmountCallout.oldstories.js} +0 -0
  175. /package/src/components/atoms/checkbox-list/{CheckboxList.stories.js → CheckboxList.oldstories.js} +0 -0
  176. /package/src/components/atoms/form-layouts/{FormLayouts.stories.js → FormLayouts.oldstories.js} +0 -0
  177. /package/src/components/atoms/hamburger-button/{HamburgerButton.stories.js → HamburgerButton.oldstories.js} +0 -0
  178. /package/src/components/atoms/heading/{Heading.stories.js → Heading.oldstories.js} +0 -0
  179. /package/src/components/atoms/layouts/examples/box-example/{BoxExample.stories.js → BoxExample.oldstories.js} +0 -0
  180. /package/src/components/atoms/layouts/examples/center-example/{CenterExample.stories.js → CenterExample.oldstories.js} +0 -0
  181. /package/src/components/atoms/layouts/examples/cluster-example/{ClusterExample.stories.js → ClusterExample.oldstories.js} +0 -0
  182. /package/src/components/atoms/layouts/examples/cover-example/{CoverExample.stories.js → CoverExample.oldstories.js} +0 -0
  183. /package/src/components/atoms/layouts/examples/frame-example/{FrameExample.stories.js → FrameExample.oldstories.js} +0 -0
  184. /package/src/components/atoms/layouts/examples/grid-example/{GridExample.stories.js → GridExample.oldstories.js} +0 -0
  185. /package/src/components/atoms/layouts/examples/imposter-example/{ImposterExample.stories.js → ImposterExample.oldstories.js} +0 -0
  186. /package/src/components/atoms/layouts/examples/motion-example/{MotionExample.stories.js → MotionExample.oldstories.js} +0 -0
  187. /package/src/components/atoms/layouts/examples/reel-example/{ReelExample.stories.js → ReelExample.oldstories.js} +0 -0
  188. /package/src/components/atoms/layouts/examples/sidebar-example/{SidebarExample.stories.js → SidebarExample.oldstories.js} +0 -0
  189. /package/src/components/atoms/layouts/examples/stack-example/{StackExample.stories.js → StackExample.oldstories.js} +0 -0
  190. /package/src/components/atoms/layouts/examples/switcher-example/{SwitcherExample.stories.js → SwitcherExample.oldstories.js} +0 -0
  191. /package/src/components/atoms/paragraph/{Paragraph.stories.js → Paragraph.oldstories.js} +0 -0
  192. /package/src/components/atoms/processing-fee/{ProcessingFee.stories.js → ProcessingFee.oldstories.js} +0 -0
  193. /package/src/components/atoms/search/{Search.stories.js → Search.oldstories.js} +0 -0
  194. /package/src/components/atoms/solid-divider/{SolidDivider.stories.js → SolidDivider.oldstories.js} +0 -0
  195. /package/src/components/atoms/sortable-table-heading/{SortableTableHeading.stories.js → SortableTableHeading.oldstories.js} +0 -0
  196. /package/src/components/atoms/spinner/{Spinner.stories.js → Spinner.oldstories.js} +0 -0
  197. /package/src/components/atoms/tab/{Tab.stories.js → Tab.oldstories.js} +0 -0
  198. /package/src/components/atoms/text/{Text.stories.js → Text.oldstories.js} +0 -0
  199. /package/src/components/atoms/typeahead-input/{TypeaheadIinput.stories.js → TypeaheadIinput.oldstories.js} +0 -0
  200. /package/src/components/atoms/wallet-name/{WalletName.stories.js → WalletName.oldstories.js} +0 -0
  201. /package/src/components/molecules/account-and-routing-modal/{AccountAndRoutingModal.stories.js → AccountAndRoutingModal.oldstories.js} +0 -0
  202. /package/src/components/molecules/editable-list/{EditableList.stories.js → EditableList.oldstories.js} +0 -0
  203. /package/src/components/molecules/email-form/{EmailForm.stories.js → EmailForm.oldstories.js} +0 -0
  204. /package/src/components/molecules/forgot-password-form/{ForgotPasswordForm.stories.js → ForgotPasswordForm.oldstories.js} +0 -0
  205. /package/src/components/molecules/highlight-tab-row/{HighlightTabRow.stories.js → HighlightTabRow.oldstories.js} +0 -0
  206. /package/src/components/molecules/obligation/modules/{AmountModule.stories.js → AmountModule.oldstories.js} +0 -0
  207. /package/src/components/molecules/payment-button-bar/{PaymentButtonBar.stories.js → PaymentButtonBar.oldstories.js} +0 -0
  208. /package/src/components/molecules/payment-details/{PaymentDetails.stories.js → PaymentDetails.oldstories.js} +0 -0
  209. /package/src/components/molecules/payment-form-ach/{PaymentFormACH.stories.js → PaymentFormACH.oldstories.js} +0 -0
  210. /package/src/components/molecules/payment-form-card/{PaymentFormCard.stories.js → PaymentFormCard.oldstories.js} +0 -0
  211. /package/src/components/molecules/periscope-dashboard-iframe/{PeriscopeDashBoardIframe.stories.js → PeriscopeDashBoardIframe.oldstories.js} +0 -0
  212. /package/src/components/molecules/phone-form/{PhoneForm.stories.js → PhoneForm.oldstories.js} +0 -0
  213. /package/src/components/molecules/popup-menu/{PopupMenu.stories.js → PopupMenu.oldstories.js} +0 -0
  214. /package/src/components/molecules/radio-group/{RadioGroup.stories.js → RadioGroup.oldstories.js} +0 -0
  215. /package/src/components/molecules/radio-section/{RadioSection.stories.js → RadioSection.oldstories.js} +0 -0
  216. /package/src/components/molecules/registration-form/{RegistrationForm.stories.js → RegistrationForm.oldstories.js} +0 -0
  217. /package/src/components/molecules/reset-confirmation-form/{ResetConfirmationForm.stories.js → ResetConfirmationForm.oldstories.js} +0 -0
  218. /package/src/components/molecules/reset-password-form/{ResetPasswordForm.stories.js → ResetPasswordForm.oldstories.js} +0 -0
  219. /package/src/components/molecules/reset-password-success/{ResetPasswordSuccess.stories.js → ResetPasswordSuccess.oldstories.js} +0 -0
  220. /package/src/components/molecules/tab-sidebar/{TabSidebar.stories.js → TabSidebar.oldstories.js} +0 -0
  221. /package/src/components/molecules/terms-and-conditions/{TermsAndConditions.stories.js → TermsAndConditions.oldstories.js} +0 -0
  222. /package/src/components/molecules/terms-and-conditions-modal/{TermsAndConditionsModal.stories.js → TermsAndConditionsModal.oldstories.js} +0 -0
  223. /package/src/components/molecules/workflow-tile/{WorkflowTile.stories.js → WorkflowTile.oldstories.js} +0 -0
@@ -1,10 +1,9 @@
1
1
  import React from "react";
2
- import { boolean } from "@storybook/addon-knobs";
2
+ import { Box, Cluster } from "../layouts";
3
+ import { FormInput, FormContainer, FormInputColumn } from "../form-layouts";
3
4
  import PasswordRequirements from "./PasswordRequirements";
4
- import { FormInput } from "../form-layouts";
5
- import { Box } from "../layouts";
6
- import page from "../../../../.storybook/page";
7
- import { connect } from "react-redux";
5
+ import { connect, Provider } from "react-redux";
6
+ import { createStore } from "redux";
8
7
  import {
9
8
  createFormState,
10
9
  required,
@@ -12,10 +11,11 @@ import {
12
11
  hasNumber,
13
12
  hasLowercaseLetter,
14
13
  hasUppercaseLetter,
15
- hasSpecialCharacter
14
+ hasSpecialCharacter,
15
+ matchesField
16
16
  } from "redux-freeform";
17
17
 
18
- const formConfig = {
18
+ const { mapStateToProps, mapDispatchToProps, reducer } = createFormState({
19
19
  password: {
20
20
  validators: [
21
21
  required(),
@@ -25,51 +25,115 @@ const formConfig = {
25
25
  hasUppercaseLetter(),
26
26
  hasSpecialCharacter()
27
27
  ]
28
+ },
29
+ confirmPassword: {
30
+ validators: [required(), matchesField("password")]
28
31
  }
29
- };
32
+ });
30
33
 
31
- const passwordForm = createFormState(formConfig);
34
+ const store = createStore(
35
+ reducer,
36
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
37
+ );
32
38
 
33
- const passwordRequirementsWrapper = ({ fields, actions, showErrors }) => {
34
- const passwordErrorMessages = {
35
- [required.error]: "Password is required",
36
- [hasLength.error]: "Password must have at least 8 characters",
37
- [hasNumber.error]: "Password must contain at least one number",
38
- [hasLowercaseLetter.error]:
39
- "Password must contain at least one lowercase letter",
40
- [hasUppercaseLetter.error]:
41
- "Password must contain at least one uppercase letter",
42
- [hasSpecialCharacter.error]:
43
- "Password must contain at least one special character (!@#$%^&*.?)"
44
- };
45
- return (
46
- <Box>
39
+ const passwordErrorMessages = {
40
+ [required.error]: "Password field is required.",
41
+ [hasLength.error]: "Your password must have at least 8 characters",
42
+ [hasNumber.error]: "Your password must contain at least one number",
43
+ [hasLowercaseLetter.error]:
44
+ "Your password must contain at least one lowercase letter",
45
+ [hasUppercaseLetter.error]:
46
+ "Your password must contain at least one uppercase letter",
47
+ [hasSpecialCharacter.error]:
48
+ "Your password must contain at least one special character (!@#$%^&*.?)"
49
+ };
50
+ const confirmPasswordErrorMessages = {
51
+ [matchesField.error]: "Confirm password must match your password"
52
+ };
53
+
54
+ const FormWrapper = props => (
55
+ <FormContainer
56
+ role="form"
57
+ aria-label="Change password"
58
+ extraStyles={`padding: 0;`}
59
+ >
60
+ <FormInputColumn>
47
61
  <FormInput
48
- labelTextWhenNoError="Type in password"
62
+ labelTextWhenNoError="Password"
49
63
  errorMessages={passwordErrorMessages}
50
- field={fields.password}
51
- fieldActions={actions.fields.password}
52
- showErrors={showErrors}
64
+ type="password"
65
+ field={props.fields.password}
66
+ fieldActions={props.actions.fields.password}
67
+ />
68
+ <FormInput
69
+ labelTextWhenNoError="Confirm Password"
70
+ errorMessages={confirmPasswordErrorMessages}
71
+ type="password"
72
+ field={props.fields.confirmPassword}
73
+ fieldActions={props.actions.fields.confirmPassword}
53
74
  />
54
- <PasswordRequirements password={fields.password} />
75
+ </FormInputColumn>
76
+ <Box padding={props.isMobile ? "1rem 0 0" : "1.5rem 0 0"}>
77
+ <Cluster justify="center" align="center">
78
+ <PasswordRequirements
79
+ isMobile={props.isMobile}
80
+ password={props.fields.password}
81
+ />
82
+ </Cluster>
55
83
  </Box>
56
- );
57
- };
84
+ </FormContainer>
85
+ );
58
86
 
59
- const story = page({
60
- title: "Components|Atoms/PasswordRequirements",
61
- Component: PasswordRequirements,
62
- reducer: passwordForm.reducer,
63
- mapStateToProps: passwordForm.mapStateToProps,
64
- mapDispatchToProps: passwordForm.mapDispatchToProps
65
- });
66
- export default story;
87
+ const ConnectedPasswordRequirements = connect(
88
+ mapStateToProps,
89
+ mapDispatchToProps
90
+ )(FormWrapper);
67
91
 
68
- const ConnectedForm = connect(
69
- passwordForm.mapStateToProps,
70
- passwordForm.mapDispatchToProps
71
- )(passwordRequirementsWrapper);
92
+ export default {
93
+ title: "Atoms/PasswordRequirements",
94
+ component: ConnectedPasswordRequirements,
95
+ tags: ["!autodocs"],
96
+ parameters: {
97
+ layout: "centered",
98
+ controls: { expanded: true }
99
+ },
100
+ args: {
101
+ password: undefined,
102
+ isMobile: false
103
+ },
104
+ argTypes: {
105
+ password: {
106
+ description: "A Redux Freeform field for a password",
107
+ table: {
108
+ type: { summary: "Redux Freeform field object" },
109
+ defaultValue: { summary: undefined }
110
+ }
111
+ },
112
+ isMobile: {
113
+ description:
114
+ "Whether user is on a mobile device (typically screen size <768px)",
115
+ table: {
116
+ type: { summary: "boolean" },
117
+ defaultValue: { summary: false }
118
+ }
119
+ }
120
+ },
121
+ decorators: [
122
+ Story => (
123
+ <Provider store={store}>
124
+ <Story />
125
+ </Provider>
126
+ )
127
+ ]
128
+ };
72
129
 
73
- export const passwordRequirements = () => (
74
- <ConnectedForm showErrors={boolean("showErrors", false, "props")} />
130
+ export const BasicPasswordRequirements = args => (
131
+ <ConnectedPasswordRequirements {...args} />
75
132
  );
133
+
134
+ export const MobilePasswordRequirements = {
135
+ args: {
136
+ isMobile: true
137
+ },
138
+ render: args => <ConnectedPasswordRequirements {...args} />
139
+ };
@@ -0,0 +1,19 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as PlaceholderStories from './Placeholder.stories.js';
4
+
5
+ <Meta of={PlaceholderStories} />
6
+
7
+ <Title />
8
+
9
+ The Placeholder component is a component that is used to occupy space that would normally contain some sort of data, like user accounts or payment methods. When the data is in an empty state, the Placeholder can be rendered to inform the user about what content would normally appear, and provide the user with an opportunity to take an action or visit a destination. If the action is unavailable, a Placeholder can be set to a disabled state.
10
+
11
+ Placeholders come with two variants: default and large. The default variant uses only text and a generic plus icon, while the large variant displays text and an icon specific to the Placeholder's use. Currently large Placeholders are only used in NFE in the following varieties: accounts, properties, and payments. New types of large Placeholders can be added by updating the large icons function inside of the Placeholder component.
12
+
13
+ The Placeholder uses flexbox styling and takes its width from its parent container.
14
+
15
+ <Controls />
16
+
17
+ <div style={{ marginBottom: "2em"}}>
18
+ <Story />
19
+ </div>
@@ -1,42 +1,170 @@
1
- import React from "react";
2
- import { boolean, text, select } from "@storybook/addon-knobs";
3
1
  import Placeholder from "./Placeholder";
4
- import page from "../../../../.storybook/page";
2
+ import { Box } from "../layouts";
5
3
 
6
- const variantsLabel = "variant";
7
- const variants = {
8
- default: "default",
9
- large: "large"
4
+ const meta = {
5
+ title: "Atoms/Placeholder",
6
+ component: Placeholder,
7
+ parameters: {
8
+ layout: "centered"
9
+ },
10
+ tags: ["!autodocs"],
11
+ args: {
12
+ text: "Add an Account",
13
+ action: undefined,
14
+ visible: true,
15
+ isLink: false,
16
+ destination: "/",
17
+ variant: undefined,
18
+ largeIcon: undefined,
19
+ isDisabled: false
20
+ },
21
+ argTypes: {
22
+ text: {
23
+ description: "Text to be displayed inside the Placeholder",
24
+ table: {
25
+ type: { summary: "string" },
26
+ defaultValue: { summary: undefined }
27
+ }
28
+ },
29
+ action: {
30
+ description:
31
+ "Function to execute when clicking on Placeholder. Only used if isLink is false.",
32
+ table: {
33
+ type: { summary: "function" },
34
+ defaultValue: { summary: undefined }
35
+ }
36
+ },
37
+ visible: {
38
+ description: "Whether the Placeholder is visible",
39
+ table: {
40
+ type: { summary: "boolean" },
41
+ defaultValue: { summary: true }
42
+ }
43
+ },
44
+ isLink: {
45
+ description:
46
+ "Whether the Placeholder links to a destination, instead of using an action",
47
+ table: {
48
+ type: { summary: "boolean" },
49
+ defaultValue: { summary: false }
50
+ }
51
+ },
52
+ variant: {
53
+ description: "Variant of the Placeholder either `default` or `large`.",
54
+ table: {
55
+ type: { summary: "string" },
56
+ defaultValue: { summary: "default" }
57
+ }
58
+ },
59
+ largeIcon: {
60
+ description:
61
+ "Name of icon to use with 'large' Placeholder variant. One of 'accounts', 'properties', or 'payments'. If not provided and Placeholder variant is set to large, will default to 'accounts'."
62
+ },
63
+ table: {
64
+ type: { summary: "string" },
65
+ defaultValue: { summary: "accounts" }
66
+ },
67
+ destination: {
68
+ description:
69
+ "URL for Placeholder to navigate to if it is a link. Only used if isLink is true.",
70
+ table: {
71
+ type: { summary: "string" },
72
+ defaultValue: { summary: undefined }
73
+ }
74
+ },
75
+ isDisabled: {
76
+ description: "Whether the Placeholder is disabled",
77
+ table: {
78
+ type: { summary: "boolean" },
79
+ defaultValue: { summary: false }
80
+ }
81
+ }
82
+ }
10
83
  };
11
- const defaultValue = "default";
12
- const groupId = "props";
13
84
 
14
- const icons = {
15
- accounts: "accounts",
16
- properties: "properties",
17
- payments: "payments"
85
+ export default meta;
86
+
87
+ export const DefaultPlaceholder = {
88
+ args: {
89
+ action: () => {},
90
+ variant: "default"
91
+ },
92
+ render: args => (
93
+ <Box minWidth="400px">
94
+ <Placeholder {...args} />
95
+ </Box>
96
+ )
97
+ };
98
+
99
+ export const LinkPlaceholder = {
100
+ args: {
101
+ text: "Add an Email Address",
102
+ variant: "default",
103
+ isLink: true,
104
+ destination: "/"
105
+ },
106
+ render: args => (
107
+ <Box minWidth="400px">
108
+ <Placeholder {...args} />
109
+ </Box>
110
+ )
111
+ };
112
+
113
+ export const LargePlaceholder = {
114
+ args: {
115
+ text: "Add or Edit Your Payment Methods",
116
+ variant: "large",
117
+ largeIcon: "payments",
118
+ action: () => {}
119
+ },
120
+ render: args => (
121
+ <Box minWidth="650px">
122
+ <Placeholder {...args} />
123
+ </Box>
124
+ )
18
125
  };
19
126
 
20
- const iconLabel = "largeIcon";
21
-
22
- const defaultIcon = "accounts";
23
-
24
- export const placeholder = () => (
25
- <Placeholder
26
- variant={select(variantsLabel, variants, defaultValue, groupId)}
27
- isLink={boolean("isLink", true, "props")}
28
- destination={text("destination", "add-account", "props")}
29
- text={text("text", "Add an Account", "props")}
30
- largeIcon={select(iconLabel, icons, defaultIcon, groupId)}
31
- key="placeholder"
32
- isDisabled={boolean("isDisabled", false, "props")}
33
- action={() => console.log("placeholder action")}
34
- />
35
- );
36
-
37
- const story = page({
38
- title: "Components|Atoms/Placeholder",
39
- Component: Placeholder
40
- });
41
-
42
- export default story;
127
+ export const LargeLinkPlaceholder = {
128
+ args: {
129
+ text: "Add New Property",
130
+ variant: "large",
131
+ largeIcon: "properties",
132
+ isLink: true,
133
+ destination: "/"
134
+ },
135
+ render: args => (
136
+ <Box minWidth="650px">
137
+ <Placeholder {...args} />
138
+ </Box>
139
+ )
140
+ };
141
+
142
+ export const DisabledPlaceholder = {
143
+ args: {
144
+ text: "Edit Payment Information",
145
+ action: () => {},
146
+ variant: "default",
147
+ isDisabled: true,
148
+ destination: "/"
149
+ },
150
+ render: args => (
151
+ <Box minWidth="400px">
152
+ <Placeholder {...args} />
153
+ </Box>
154
+ )
155
+ };
156
+
157
+ export const DisabledLargePlaceholder = {
158
+ args: {
159
+ text: "Add More to Cart",
160
+ variant: "large",
161
+ isLink: true,
162
+ isDisabled: true,
163
+ destination: "/"
164
+ },
165
+ render: args => (
166
+ <Box minWidth="650px">
167
+ <Placeholder {...args} />
168
+ </Box>
169
+ )
170
+ };
@@ -0,0 +1,44 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as SearchableSelectStories from './SearchableSelect.stories.js';
4
+
5
+ <Meta of={SearchableSelectStories} />
6
+
7
+ <Title />
8
+
9
+ SearchableSelect creates a list of checkboxes from an array of options that is filterable through an input.
10
+
11
+ ## Notes
12
+
13
+ - the `items` array will be sorted by the `name` property
14
+ - a `SELECT_ALL` constant is also exported by SearchableSelect
15
+ - if an item with a name matching `SELECT_ALL` is included in `items` it will be rendered to the top
16
+ - filtering through the input is _always_ case-insensitive
17
+
18
+ ## Form Integration
19
+
20
+ SearchableSelect requires a `fields` and `actions` prop. Both are objects that _can_ be generated with [redux-freeform](https://github.com/CityBaseInc/redux-freeform).
21
+
22
+ Unlike other similar form components where the specific `field` and `fieldActions` for one field are passed as props, SearchableSelect expect the `fields` and `fieldActions` from the entire form to be passed, with a field named `searchTerm`. Below are example values for each prop with the minimum properties needed for a FormSelect component.
23
+
24
+ ### fields
25
+
26
+ ```
27
+ {
28
+ searchTerm: {
29
+ "rawValue": ""
30
+ }
31
+ }
32
+ ```
33
+
34
+ ### actions
35
+
36
+ ```
37
+ {
38
+ searchTerm: {
39
+ set: (value) => {...}
40
+ }
41
+ }
42
+ ```
43
+
44
+ `actions.searchTerm.set()` is used to to update the filter term in the input.
@@ -1,10 +1,9 @@
1
- import React, { useState } from "react";
2
- import { connect } from "react-redux";
3
- import { text } from "@storybook/addon-knobs";
4
- import { createFormState } from "redux-freeform";
5
-
1
+ import React from "react";
6
2
  import SearchableSelect, { SELECT_ALL } from "./SearchableSelect";
7
- import page from "../../../../.storybook/page";
3
+ import { useState } from "react";
4
+ import { connect, Provider } from "react-redux";
5
+ import { createStore } from "redux";
6
+ import { createFormState } from "redux-freeform";
8
7
 
9
8
  const { mapStateToProps, mapDispatchToProps, reducer } = createFormState({
10
9
  searchTerm: {
@@ -12,51 +11,127 @@ const { mapStateToProps, mapDispatchToProps, reducer } = createFormState({
12
11
  }
13
12
  });
14
13
 
14
+ const store = createStore(
15
+ reducer,
16
+ window.__REDUX_DEVTOOLS_EXTENSION__ && window.__REDUX_DEVTOOLS_EXTENSION__()
17
+ );
18
+
19
+ const selectAllItem = { name: SELECT_ALL, value: SELECT_ALL };
20
+
15
21
  const items = [
16
22
  { name: "Foo", value: "foo-value" },
17
23
  { name: "Baz", value: "baz-value" },
18
- { name: SELECT_ALL, value: SELECT_ALL },
24
+ selectAllItem,
19
25
  { name: "Bar", value: "bar-value" }
20
26
  ];
21
27
 
22
28
  const FormWrapper = props => {
23
29
  const [selectedItems, setSelectedItems] = useState(props.selectedItems || []);
24
- const selectValues = items => items.map(item => item.value);
25
30
 
26
- const selectItem = selectedItem => {
27
- if (selectValues(selectedItems).includes(selectedItem.value)) {
28
- const fewerItems = selectedItems.filter(
29
- item => item.value !== selectedItem.value
31
+ const selectItem = selection => {
32
+ if (selectedItems.find(l => l.value === selection.value)) {
33
+ const filtered = selectedItems.filter(
34
+ l => l.value !== selection.value && l.value !== SELECT_ALL
30
35
  );
31
- setSelectedItems(fewerItems);
36
+ setSelectedItems(filtered);
37
+ } else {
38
+ if (selectedItems.length + 1 === items.length - 1) {
39
+ setSelectedItems([...selectedItems, selection, selectAllItem]);
40
+ } else {
41
+ setSelectedItems([...selectedItems, selection]);
42
+ }
43
+ }
44
+ };
45
+
46
+ const toggleSelectAllItems = selectAll => {
47
+ if (selectAll) {
48
+ setSelectedItems(items);
32
49
  } else {
33
- const moreItems = selectedItems.concat(selectedItem);
34
- setSelectedItems(moreItems);
50
+ setSelectedItems([]);
35
51
  }
36
52
  };
37
53
 
54
+ const allSelected = selectedItems.length === items.length ?? false;
55
+
38
56
  return (
39
57
  <SearchableSelect
58
+ {...props}
40
59
  autocompleteValue={props.autocompleteValue}
41
- items={items}
60
+ items={props.items}
61
+ selectedItems={selectedItems}
62
+ selectItem={selectItem}
42
63
  fields={props.fields}
43
64
  actions={props.actions}
44
- selectedItems={selectedItems}
45
- selectItem={item => selectItem(item)}
65
+ allSelected={allSelected}
66
+ toggleSelectAllItems={toggleSelectAllItems}
46
67
  />
47
68
  );
48
69
  };
49
70
 
50
- const story = page({
51
- title: "Components|Atoms/SearchableSelect",
52
- Component: SearchableSelect,
53
- reducer,
71
+ const ConnectedSearchableSelect = connect(
54
72
  mapStateToProps,
55
73
  mapDispatchToProps
56
- });
74
+ )(FormWrapper);
57
75
 
58
- export default story;
59
- const ConnectedForm = connect(mapStateToProps, mapDispatchToProps)(FormWrapper);
60
- export const searchableSelect = () => (
61
- <ConnectedForm autocompleteValue={text("autocompleteValue", null, "props")} />
62
- );
76
+ export default {
77
+ title: "Atoms/SearchableSelect",
78
+ component: ConnectedSearchableSelect,
79
+ tags: ["!autodocs"],
80
+ parameters: {
81
+ controls: { expanded: true }
82
+ },
83
+ args: {
84
+ autocompleteValue: undefined,
85
+ items: items,
86
+ disabled: false,
87
+ themeValues: {},
88
+ placeholder: "Search agencies"
89
+ },
90
+ argTypes: {
91
+ fieldActions: { type: "object" },
92
+ field: { type: "object" },
93
+ selectedItems: {
94
+ description: "Array of objects representing the selected items.",
95
+ table: {
96
+ type: { summary: "array" }
97
+ }
98
+ },
99
+ selectItem: {
100
+ description:
101
+ "Function that will be called when a non-`SELECT_ALL` checkbox is changed.",
102
+ table: {
103
+ type: { summary: "array" }
104
+ }
105
+ },
106
+ allSelected: {
107
+ description:
108
+ "Whether all all items are selected or not. This affects what parameter `toggleSelectAllItems` is called with",
109
+ table: {
110
+ type: { summary: "boolean" }
111
+ }
112
+ },
113
+ toggleSelectAllItems: {
114
+ description:
115
+ "Function called when a checkbox with the name `SELECT_ALL` is changed.",
116
+ table: {
117
+ type: { summary: "function" }
118
+ }
119
+ }
120
+ },
121
+ decorators: [
122
+ Story => (
123
+ <Provider store={store}>
124
+ <Story />
125
+ </Provider>
126
+ )
127
+ ]
128
+ };
129
+
130
+ export const Basic = args => <ConnectedSearchableSelect {...args} />;
131
+
132
+ export const Disabled = {
133
+ args: {
134
+ disabled: true
135
+ },
136
+ render: args => <ConnectedSearchableSelect {...args} />
137
+ };
@@ -0,0 +1,36 @@
1
+ import { Canvas, Meta, Title, Story, Controls } from '@storybook/blocks';
2
+
3
+ import * as StateProvinceDropdownStories from './StateProvinceDropdown.stories.js';
4
+
5
+ <Meta of={StateProvinceDropdownStories} />
6
+
7
+ <Title />
8
+
9
+ StateProvinceDropdown is a wrapper for [FormSelect](?path=/docs/atoms-formselect--docs) that adds a pre-defined array of states or provinces for options. The state/provinces loaded are determined by the `countryCode` prop. These options cannot be modified. A "placeholder" option is added to the top of the list with a value of "". The display name of the placeholder is determined by the country code.
10
+
11
+ ## Form Integration
12
+
13
+ FormInput requires a `field` and `fieldActions` prop. Both are objects that _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 CountryDropdown component.
14
+
15
+ ### field
16
+
17
+ ```
18
+ {
19
+ "dirty": false,
20
+ "rawValue": "",
21
+ "errors": [
22
+ "error/REQUIRED"
23
+ ],
24
+ "hasErrors": true
25
+ }
26
+ ```
27
+
28
+ ### fieldActions
29
+
30
+ ```
31
+ {
32
+ set: (value) => {...}
33
+ }
34
+ ```
35
+
36
+ `fieldActions.set()` is called when an option is selected in the underlying Dropdown component, unless a function is defined for the `onChange` prop.