@thecb/components 10.12.3-beta.0 → 10.12.3

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 (211) hide show
  1. package/README.md +0 -4
  2. package/dist/index.cjs.js +2526 -1617
  3. package/dist/index.cjs.js.map +1 -1
  4. package/dist/index.d.ts +4 -5
  5. package/dist/index.esm.js +2527 -1617
  6. package/dist/index.esm.js.map +1 -1
  7. package/package.json +13 -25
  8. package/src/components/atoms/alert/Alert.stories.js +26 -148
  9. package/src/components/atoms/badge/Badge.js +2 -2
  10. package/src/components/atoms/badge/Badge.stories.js +29 -143
  11. package/src/components/atoms/breadcrumb/Breadcrumb.stories.js +29 -38
  12. package/src/components/atoms/button-with-action/ButtonWithAction.stories.js +55 -108
  13. package/src/components/atoms/button-with-link/ButtonWithLink.stories.js +31 -160
  14. package/src/components/atoms/checkbox/Checkbox.stories.js +29 -148
  15. package/src/components/atoms/country-dropdown/CountryDropdown.stories.js +27 -61
  16. package/src/components/atoms/detail/Detail.js +26 -0
  17. package/src/components/atoms/display-box/DisplayBox.stories.js +21 -65
  18. package/src/components/atoms/display-card/DisplayCard.stories.js +22 -163
  19. package/src/components/atoms/dropdown/Dropdown.stories.js +10 -91
  20. package/src/components/atoms/form-layouts/FormInput.stories.js +26 -212
  21. package/src/components/atoms/form-select/FormSelect.stories.js +29 -55
  22. package/src/components/atoms/formatted-address/FormattedAddress.stories.js +27 -133
  23. package/src/components/atoms/icons/icons.stories.js +116 -0
  24. package/src/components/atoms/labeled-amount/LabeledAmount.stories.js +34 -110
  25. package/src/components/atoms/line-item/LineItem.stories.js +22 -89
  26. package/src/components/atoms/link/Link.stories.js +49 -155
  27. package/src/components/atoms/loading-line/LoadingLine.js +10 -14
  28. package/src/components/atoms/loading-line/LoadingLine.stories.js +28 -132
  29. package/src/components/atoms/nav-footer/NavFooter.stories.js +22 -235
  30. package/src/components/atoms/nav-header/NavHeader.stories.js +21 -122
  31. package/src/components/atoms/password-requirements/PasswordRequirements.stories.js +44 -108
  32. package/src/components/atoms/placeholder/Placeholder.stories.js +36 -164
  33. package/src/components/atoms/searchable-select/SearchableSelect.stories.js +28 -103
  34. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.stories.js +40 -65
  35. package/src/components/atoms/table/Table.stories.js +75 -59
  36. package/src/components/atoms/table/TableRow.js +0 -1
  37. package/src/components/atoms/title/Title.js +23 -0
  38. package/src/components/atoms/toggle-switch/ToggleSwitch.stories.js +20 -103
  39. package/src/components/atoms/toggle-switch/ToggleSwitch.theme.js +5 -8
  40. package/src/components/molecules/address-form/AddressForm.stories.js +20 -223
  41. package/src/components/molecules/banner/Banner.stories.js +26 -122
  42. package/src/components/molecules/change-password-form/ChangePasswordForm.stories.js +19 -203
  43. package/src/components/molecules/collapsible-section/CollapsibleSection.stories.js +61 -210
  44. package/src/components/molecules/edit-name-form/EdidNameForm.stories.js +24 -0
  45. package/src/components/molecules/index.js +0 -1
  46. package/src/components/molecules/link-card/LinkCard.stories.js +72 -287
  47. package/src/components/molecules/login-form/LoginForm.stories.js +21 -117
  48. package/src/components/molecules/modal/Modal.stories.js +128 -342
  49. package/src/components/molecules/module/Module.stories.js +25 -267
  50. package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.js +61 -295
  51. package/src/components/molecules/multiple-select-filter/{MultipleSelectFilter.oldstories.js → MultipleSelectFilter.stories.js} +1 -1
  52. package/src/components/molecules/multiple-select-filter/MultipleSelectFilter.styled.js +4 -4
  53. package/src/components/molecules/multiple-select-filter/__private__/ActionLinkButton.js +24 -0
  54. package/src/components/molecules/multiple-select-filter/__private__/FilterButton.js +85 -0
  55. package/src/components/molecules/multiple-select-filter/__private__/FilterDropdown.js +23 -0
  56. package/src/components/molecules/multiple-select-filter/__private__/FilterableList.js +144 -0
  57. package/src/components/molecules/multiple-select-filter/__private__/FilterableListItem.js +67 -0
  58. package/src/components/molecules/multiple-select-filter/__private__/SearchBox.js +38 -0
  59. package/src/components/molecules/multiple-select-filter/__private__/useKeyboardNavigation.js +84 -0
  60. package/src/components/molecules/multiple-select-filter/__private__/util.js +31 -0
  61. package/src/components/molecules/obligation/icons/PropertyPersonalIcon.js +1 -1
  62. package/src/components/molecules/pagination/Pagination.stories.js +28 -177
  63. package/src/components/molecules/tabs/Tabs.stories.js +227 -135
  64. package/src/components/molecules/toast-notification/ToastNotification.stories.js +105 -0
  65. package/src/hooks/use-outside-click/index.js +4 -5
  66. package/src/util/index.js +1 -3
  67. package/src/components/atoms/alert/Alert.mdx +0 -19
  68. package/src/components/atoms/badge/Badge.mdx +0 -27
  69. package/src/components/atoms/breadcrumb/Breadcrumb.mdx +0 -21
  70. package/src/components/atoms/button-with-link/ButtonWithLink.mdx +0 -21
  71. package/src/components/atoms/card/Card.mdx +0 -41
  72. package/src/components/atoms/card/Card.stories.js +0 -360
  73. package/src/components/atoms/checkbox/Checkbox.mdx +0 -15
  74. package/src/components/atoms/checkbox/Checkbox.oldstories.js +0 -30
  75. package/src/components/atoms/country-dropdown/CountryDropdown.mdx +0 -36
  76. package/src/components/atoms/detail/Detail.mdx +0 -32
  77. package/src/components/atoms/detail/Detail.stories.js +0 -156
  78. package/src/components/atoms/display-box/DisplayBox.mdx +0 -11
  79. package/src/components/atoms/display-card/DisplayCard.mdx +0 -13
  80. package/src/components/atoms/dropdown/Dropdown.mdx +0 -65
  81. package/src/components/atoms/form-layouts/FormInput.mdx +0 -38
  82. package/src/components/atoms/form-select/FormSelect.mdx +0 -42
  83. package/src/components/atoms/formatted-address/FormattedAddress.mdx +0 -13
  84. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.mdx +0 -17
  85. package/src/components/atoms/formatted-bank-account/FormattedBankAccount.stories.js +0 -57
  86. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.mdx +0 -40
  87. package/src/components/atoms/formatted-credit-card/FormattedCreditCard.stories.js +0 -74
  88. package/src/components/atoms/icons/Icons.mdx +0 -40
  89. package/src/components/atoms/icons/Icons.stories.js +0 -325
  90. package/src/components/atoms/labeled-amount/LabeledAmount.mdx +0 -23
  91. package/src/components/atoms/line-item/LineItem.mdx +0 -28
  92. package/src/components/atoms/link/Link.mdx +0 -19
  93. package/src/components/atoms/loading/Loading.mdx +0 -13
  94. package/src/components/atoms/loading/Loading.stories.js +0 -22
  95. package/src/components/atoms/loading-line/LoadingLine.mdx +0 -15
  96. package/src/components/atoms/nav-footer/NavFooter.mdx +0 -15
  97. package/src/components/atoms/nav-header/NavHeader.mdx +0 -13
  98. package/src/components/atoms/nav-tabs/NavTabs.mdx +0 -30
  99. package/src/components/atoms/nav-tabs/NavTabs.stories.js +0 -49
  100. package/src/components/atoms/password-requirements/PasswordRequirements.mdx +0 -39
  101. package/src/components/atoms/placeholder/Placeholder.mdx +0 -19
  102. package/src/components/atoms/searchable-select/SearchableSelect.mdx +0 -44
  103. package/src/components/atoms/state-province-dropdown/StateProvinceDropdown.mdx +0 -36
  104. package/src/components/atoms/table/Table.mdx +0 -71
  105. package/src/components/atoms/table/Table.oldstories.js +0 -84
  106. package/src/components/atoms/title/Title.mdx +0 -26
  107. package/src/components/atoms/title/Title.stories.js +0 -144
  108. package/src/components/atoms/toggle-switch/ToggleSwitch.mdx +0 -17
  109. package/src/components/atoms/typeahead-input/TypeaheadInput.mdx +0 -13
  110. package/src/components/atoms/typeahead-input/TypeaheadInput.stories.js +0 -63
  111. package/src/components/molecules/address-form/AddressForm.mdx +0 -18
  112. package/src/components/molecules/banner/Banner.mdx +0 -23
  113. package/src/components/molecules/change-password-form/ChangePasswordForm.mdx +0 -15
  114. package/src/components/molecules/collapsible-section/CollapsibleSection.mdx +0 -15
  115. package/src/components/molecules/edit-name-form/EditNameForm.mdx +0 -13
  116. package/src/components/molecules/edit-name-form/EditNameForm.stories.js +0 -117
  117. package/src/components/molecules/idle-modal/IdleModal.js +0 -101
  118. package/src/components/molecules/idle-modal/IdleModal.mdx +0 -17
  119. package/src/components/molecules/idle-modal/IdleModal.stories.js +0 -180
  120. package/src/components/molecules/idle-modal/index.d.ts +0 -16
  121. package/src/components/molecules/idle-modal/index.js +0 -3
  122. package/src/components/molecules/link-card/LinkCard.mdx +0 -17
  123. package/src/components/molecules/login-form/LoginForm.mdx +0 -16
  124. package/src/components/molecules/modal/Modal.mdx +0 -17
  125. package/src/components/molecules/module/Module.mdx +0 -17
  126. package/src/components/molecules/obligation/Obligation.mdx +0 -23
  127. package/src/components/molecules/obligation/Obligation.stories.js +0 -460
  128. package/src/components/molecules/pagination/Pagination.mdx +0 -15
  129. package/src/components/molecules/popover/Popover.mdx +0 -15
  130. package/src/components/molecules/popover/Popover.stories.js +0 -220
  131. package/src/components/molecules/tabs/Tabs.mdx +0 -17
  132. package/src/components/molecules/toast-notification/Toast.mdx +0 -15
  133. package/src/components/molecules/toast-notification/Toast.stories.js +0 -183
  134. package/src/stories/Button.stories.ts +0 -53
  135. package/src/stories/Button.tsx +0 -48
  136. package/src/stories/Configure.mdx +0 -364
  137. package/src/stories/Header.stories.ts +0 -33
  138. package/src/stories/Header.tsx +0 -56
  139. package/src/stories/Page.stories.ts +0 -32
  140. package/src/stories/Page.tsx +0 -73
  141. package/src/stories/assets/accessibility.png +0 -0
  142. package/src/stories/assets/accessibility.svg +0 -5
  143. package/src/stories/assets/addon-library.png +0 -0
  144. package/src/stories/assets/assets.png +0 -0
  145. package/src/stories/assets/avif-test-image.avif +0 -0
  146. package/src/stories/assets/context.png +0 -0
  147. package/src/stories/assets/discord.svg +0 -15
  148. package/src/stories/assets/docs.png +0 -0
  149. package/src/stories/assets/figma-plugin.png +0 -0
  150. package/src/stories/assets/github.svg +0 -3
  151. package/src/stories/assets/share.png +0 -0
  152. package/src/stories/assets/styling.png +0 -0
  153. package/src/stories/assets/testing.png +0 -0
  154. package/src/stories/assets/theming.png +0 -0
  155. package/src/stories/assets/tutorials.svg +0 -12
  156. package/src/stories/assets/youtube.svg +0 -4
  157. package/src/stories/button.css +0 -30
  158. package/src/stories/header.css +0 -32
  159. package/src/stories/page.css +0 -69
  160. package/src/util/idleTimerUtils.js +0 -36
  161. /package/src/components/atoms/add-obligation/{AddObligation.oldstories.js → AddObligation.stories.js} +0 -0
  162. /package/src/components/atoms/amount-callout/{AmountCallout.oldstories.js → AmountCallout.stories.js} +0 -0
  163. /package/src/components/atoms/checkbox-list/{CheckboxList.oldstories.js → CheckboxList.stories.js} +0 -0
  164. /package/src/components/atoms/form-layouts/{FormLayouts.oldstories.js → FormLayouts.stories.js} +0 -0
  165. /package/src/components/atoms/hamburger-button/{HamburgerButton.oldstories.js → HamburgerButton.stories.js} +0 -0
  166. /package/src/components/atoms/heading/{Heading.oldstories.js → Heading.stories.js} +0 -0
  167. /package/src/components/atoms/layouts/examples/box-example/{BoxExample.oldstories.js → BoxExample.stories.js} +0 -0
  168. /package/src/components/atoms/layouts/examples/center-example/{CenterExample.oldstories.js → CenterExample.stories.js} +0 -0
  169. /package/src/components/atoms/layouts/examples/cluster-example/{ClusterExample.oldstories.js → ClusterExample.stories.js} +0 -0
  170. /package/src/components/atoms/layouts/examples/cover-example/{CoverExample.oldstories.js → CoverExample.stories.js} +0 -0
  171. /package/src/components/atoms/layouts/examples/frame-example/{FrameExample.oldstories.js → FrameExample.stories.js} +0 -0
  172. /package/src/components/atoms/layouts/examples/grid-example/{GridExample.oldstories.js → GridExample.stories.js} +0 -0
  173. /package/src/components/atoms/layouts/examples/imposter-example/{ImposterExample.oldstories.js → ImposterExample.stories.js} +0 -0
  174. /package/src/components/atoms/layouts/examples/motion-example/{MotionExample.oldstories.js → MotionExample.stories.js} +0 -0
  175. /package/src/components/atoms/layouts/examples/reel-example/{ReelExample.oldstories.js → ReelExample.stories.js} +0 -0
  176. /package/src/components/atoms/layouts/examples/sidebar-example/{SidebarExample.oldstories.js → SidebarExample.stories.js} +0 -0
  177. /package/src/components/atoms/layouts/examples/stack-example/{StackExample.oldstories.js → StackExample.stories.js} +0 -0
  178. /package/src/components/atoms/layouts/examples/switcher-example/{SwitcherExample.oldstories.js → SwitcherExample.stories.js} +0 -0
  179. /package/src/components/atoms/paragraph/{Paragraph.oldstories.js → Paragraph.stories.js} +0 -0
  180. /package/src/components/atoms/processing-fee/{ProcessingFee.oldstories.js → ProcessingFee.stories.js} +0 -0
  181. /package/src/components/atoms/search/{Search.oldstories.js → Search.stories.js} +0 -0
  182. /package/src/components/atoms/solid-divider/{SolidDivider.oldstories.js → SolidDivider.stories.js} +0 -0
  183. /package/src/components/atoms/sortable-table-heading/{SortableTableHeading.oldstories.js → SortableTableHeading.stories.js} +0 -0
  184. /package/src/components/atoms/spinner/{Spinner.oldstories.js → Spinner.stories.js} +0 -0
  185. /package/src/components/atoms/tab/{Tab.oldstories.js → Tab.stories.js} +0 -0
  186. /package/src/components/atoms/text/{Text.oldstories.js → Text.stories.js} +0 -0
  187. /package/src/components/atoms/typeahead-input/{TypeaheadIinput.oldstories.js → TypeaheadIinput.stories.js} +0 -0
  188. /package/src/components/atoms/wallet-name/{WalletName.oldstories.js → WalletName.stories.js} +0 -0
  189. /package/src/components/molecules/account-and-routing-modal/{AccountAndRoutingModal.oldstories.js → AccountAndRoutingModal.stories.js} +0 -0
  190. /package/src/components/molecules/editable-list/{EditableList.oldstories.js → EditableList.stories.js} +0 -0
  191. /package/src/components/molecules/email-form/{EmailForm.oldstories.js → EmailForm.stories.js} +0 -0
  192. /package/src/components/molecules/forgot-password-form/{ForgotPasswordForm.oldstories.js → ForgotPasswordForm.stories.js} +0 -0
  193. /package/src/components/molecules/highlight-tab-row/{HighlightTabRow.oldstories.js → HighlightTabRow.stories.js} +0 -0
  194. /package/src/components/molecules/obligation/modules/{AmountModule.oldstories.js → AmountModule.stories.js} +0 -0
  195. /package/src/components/molecules/payment-button-bar/{PaymentButtonBar.oldstories.js → PaymentButtonBar.stories.js} +0 -0
  196. /package/src/components/molecules/payment-details/{PaymentDetails.oldstories.js → PaymentDetails.stories.js} +0 -0
  197. /package/src/components/molecules/payment-form-ach/{PaymentFormACH.oldstories.js → PaymentFormACH.stories.js} +0 -0
  198. /package/src/components/molecules/payment-form-card/{PaymentFormCard.oldstories.js → PaymentFormCard.stories.js} +0 -0
  199. /package/src/components/molecules/periscope-dashboard-iframe/{PeriscopeDashBoardIframe.oldstories.js → PeriscopeDashBoardIframe.stories.js} +0 -0
  200. /package/src/components/molecules/phone-form/{PhoneForm.oldstories.js → PhoneForm.stories.js} +0 -0
  201. /package/src/components/molecules/popup-menu/{PopupMenu.oldstories.js → PopupMenu.stories.js} +0 -0
  202. /package/src/components/molecules/radio-group/{RadioGroup.oldstories.js → RadioGroup.stories.js} +0 -0
  203. /package/src/components/molecules/radio-section/{RadioSection.oldstories.js → RadioSection.stories.js} +0 -0
  204. /package/src/components/molecules/registration-form/{RegistrationForm.oldstories.js → RegistrationForm.stories.js} +0 -0
  205. /package/src/components/molecules/reset-confirmation-form/{ResetConfirmationForm.oldstories.js → ResetConfirmationForm.stories.js} +0 -0
  206. /package/src/components/molecules/reset-password-form/{ResetPasswordForm.oldstories.js → ResetPasswordForm.stories.js} +0 -0
  207. /package/src/components/molecules/reset-password-success/{ResetPasswordSuccess.oldstories.js → ResetPasswordSuccess.stories.js} +0 -0
  208. /package/src/components/molecules/tab-sidebar/{TabSidebar.oldstories.js → TabSidebar.stories.js} +0 -0
  209. /package/src/components/molecules/terms-and-conditions/{TermsAndConditions.oldstories.js → TermsAndConditions.stories.js} +0 -0
  210. /package/src/components/molecules/terms-and-conditions-modal/{TermsAndConditionsModal.oldstories.js → TermsAndConditionsModal.stories.js} +0 -0
  211. /package/src/components/molecules/workflow-tile/{WorkflowTile.oldstories.js → WorkflowTile.stories.js} +0 -0
@@ -0,0 +1,144 @@
1
+ import React, { useState, useEffect } from "react";
2
+ import { Box } from "../../../atoms";
3
+ import FilterableListItem from "./FilterableListItem";
4
+ import useKeyboardNavigation from "./useKeyboardNavigation";
5
+ import {
6
+ sortItemsList,
7
+ filterItemsList,
8
+ selectOption,
9
+ isChecked,
10
+ isMaxSelectionReached
11
+ } from "./util";
12
+ import { GHOST_GREY } from "../../../../constants/colors";
13
+
14
+ const FilterableList = ({
15
+ id,
16
+ options,
17
+ appliedOptions,
18
+ selectedOptions,
19
+ maxSelections,
20
+ name,
21
+ setSelectedOptions,
22
+ searchTerm,
23
+ themeValues
24
+ }) => {
25
+ const [filteredOptions, setFilteredOptions] = useState([]);
26
+ const [filteredAppliedOptions, setFilteredAppliedOptions] = useState([]);
27
+
28
+ useEffect(() => {
29
+ setFilteredOptions(options);
30
+ setFilteredAppliedOptions(appliedOptions);
31
+ }, [options, appliedOptions]);
32
+
33
+ useEffect(() => {
34
+ const filteredOptionItems = filterItemsList(options, searchTerm?.rawValue);
35
+ const filteredAppliedItems = filterItemsList(
36
+ appliedOptions,
37
+ searchTerm?.rawValue
38
+ );
39
+
40
+ setFilteredOptions(
41
+ filteredOptionItems.length ? filteredOptionItems : filteredOptions
42
+ );
43
+ setFilteredAppliedOptions(filteredAppliedItems);
44
+ }, [searchTerm.rawValue]);
45
+
46
+ const handleSelectOption = option =>
47
+ selectOption(option, selectedOptions, setSelectedOptions);
48
+
49
+ const isAppliedOption = option =>
50
+ filteredAppliedOptions?.some(
51
+ appliedItem => appliedItem?.name === option?.name
52
+ );
53
+
54
+ const currentFilteredOptions = filteredOptions.filter(
55
+ option => !isAppliedOption(option)
56
+ );
57
+
58
+ const sortedOptions = sortItemsList(currentFilteredOptions);
59
+ const sortedAppliedOptions = sortItemsList(filteredAppliedOptions);
60
+
61
+ const { itemRefs, focusedIndex, handleKeyDown } = useKeyboardNavigation({
62
+ options: sortedOptions,
63
+ appliedOptions: sortedAppliedOptions,
64
+ selectedOptions,
65
+ maxSelections
66
+ });
67
+
68
+ return (
69
+ <Box
70
+ id={id}
71
+ role="listbox"
72
+ padding="0"
73
+ extraStyles={`
74
+ overflow-y: auto;
75
+ max-height: 250px;
76
+ display: flex;
77
+ flex-flow: column;
78
+ `}
79
+ onKeyDown={handleKeyDown}
80
+ >
81
+ {sortedAppliedOptions?.length > 0 && (
82
+ <Box
83
+ padding="0"
84
+ extraStyles={
85
+ sortedOptions.length > 0 && `border-bottom: 1px solid ${GHOST_GREY}`
86
+ }
87
+ >
88
+ {sortedAppliedOptions.map((option, index) => {
89
+ const checked = isChecked(option, selectedOptions);
90
+ const tabIndex =
91
+ index === focusedIndex || (index === 0 && focusedIndex === -1)
92
+ ? "0"
93
+ : "-1";
94
+ return (
95
+ <FilterableListItem
96
+ key={index}
97
+ ref={el => (itemRefs.current[index] = el)}
98
+ index={index}
99
+ option={option}
100
+ checked={checked}
101
+ selectOption={handleSelectOption}
102
+ tabIndex={tabIndex}
103
+ name={name}
104
+ themeValues={themeValues}
105
+ ></FilterableListItem>
106
+ );
107
+ })}
108
+ </Box>
109
+ )}
110
+ {sortedOptions.map((option, index) => {
111
+ const checked = isChecked(option, selectedOptions);
112
+ const isDisabled =
113
+ isMaxSelectionReached(maxSelections, selectedOptions) && !checked;
114
+ const indexOffset = sortedAppliedOptions?.length
115
+ ? sortedAppliedOptions?.length
116
+ : 0;
117
+ const currentIndex = index === 0 ? indexOffset : index + indexOffset;
118
+ const tabIndex =
119
+ currentIndex === focusedIndex ||
120
+ (indexOffset === 0 &&
121
+ currentIndex === indexOffset &&
122
+ focusedIndex === -1)
123
+ ? "0"
124
+ : "-1";
125
+ return (
126
+ <FilterableListItem
127
+ key={currentIndex}
128
+ ref={el => (itemRefs.current[currentIndex] = el)}
129
+ index={currentIndex}
130
+ option={option}
131
+ checked={checked}
132
+ selectOption={isDisabled ? noop : handleSelectOption}
133
+ disabled={isDisabled}
134
+ tabIndex={tabIndex}
135
+ name={name}
136
+ themeValues={themeValues}
137
+ ></FilterableListItem>
138
+ );
139
+ })}
140
+ </Box>
141
+ );
142
+ };
143
+
144
+ export default React.memo(FilterableList);
@@ -0,0 +1,67 @@
1
+ import React, { forwardRef } from "react";
2
+ import Checkbox from "../../../atoms/checkbox";
3
+ import { Box } from "../../../atoms";
4
+
5
+ const FilterableListItem = forwardRef(
6
+ (
7
+ {
8
+ index,
9
+ option,
10
+ checked,
11
+ selectOption,
12
+ disabled,
13
+ tabIndex,
14
+ name,
15
+ themeValues
16
+ },
17
+ ref
18
+ ) => {
19
+ return (
20
+ <Box
21
+ padding="0"
22
+ key={index}
23
+ extraStyles={`
24
+ :hover,
25
+ :active,
26
+ :focus {
27
+ background-color: ${themeValues.primaryColor};
28
+ }
29
+ `}
30
+ >
31
+ <Checkbox
32
+ ref={ref}
33
+ title={option.name}
34
+ name={option.name}
35
+ checked={checked}
36
+ onChange={() => selectOption(option)}
37
+ textExtraStyles={`font-size: 0.875rem; margin: 0;`}
38
+ disabled={disabled}
39
+ extraStyles={`
40
+ padding: 0.075rem 0.325rem;
41
+ margin: 0;
42
+ :hover,
43
+ :active,
44
+ :focus {
45
+ background-color: ${themeValues.primaryColor};
46
+ }
47
+ `}
48
+ checkboxMargin="0.3rem"
49
+ role="option"
50
+ checkboxExtraStyles={`
51
+ width: 1.375rem;
52
+ height: 1.375rem;
53
+ ${
54
+ checked && !disabled
55
+ ? `background: ` + themeValues.secondaryColor + `;`
56
+ : ""
57
+ }
58
+ `}
59
+ tabIndex={tabIndex}
60
+ dataQa={`${name}-option-${index}`}
61
+ />
62
+ </Box>
63
+ );
64
+ }
65
+ );
66
+
67
+ export default FilterableListItem;
@@ -0,0 +1,38 @@
1
+ import React from "react";
2
+ import { Box, FormInput } from "../../../atoms";
3
+ import { GHOST_GREY } from "../../../../constants/colors";
4
+
5
+ const SearchBox = ({
6
+ autocompleteValue,
7
+ fields,
8
+ actions,
9
+ placeholder,
10
+ disabled,
11
+ showSearchBox
12
+ }) => {
13
+ return (
14
+ <Box padding="0 0 0.5rem">
15
+ {showSearchBox && (
16
+ <FormInput
17
+ autocompleteValue={autocompleteValue}
18
+ showFieldErrorRow={false}
19
+ errorMessages={{}}
20
+ field={fields.searchTerm}
21
+ fieldActions={actions.fields.searchTerm}
22
+ placeholder={placeholder}
23
+ disabled={disabled}
24
+ extraStyles={`
25
+ height: 2.875rem;
26
+ border: 0;
27
+ border-radius: 0;
28
+ padding: 0.45rem;
29
+ font-size: 0.875rem;
30
+ border-bottom: 1px solid ${GHOST_GREY};
31
+ `}
32
+ />
33
+ )}
34
+ </Box>
35
+ );
36
+ };
37
+
38
+ export default SearchBox;
@@ -0,0 +1,84 @@
1
+ import React, { useRef, useState, useEffect } from "react";
2
+ import { isMaxSelectionReached } from "./util";
3
+
4
+ const useKeyboardNavigation = ({
5
+ options,
6
+ appliedOptions,
7
+ selectedOptions,
8
+ maxSelections
9
+ }) => {
10
+ const [focusedIndex, setFocusedIndex] = useState(-1);
11
+ const itemRefs = useRef([]);
12
+ const totalItemsLength = options.length + appliedOptions.length;
13
+
14
+ const handleArrowUp = event => {
15
+ event.preventDefault();
16
+ setFocusedIndex(prevIndex =>
17
+ prevIndex > 0 ? prevIndex - 1 : totalItemsLength - 1
18
+ );
19
+ };
20
+
21
+ const handleArrowDown = event => {
22
+ event.preventDefault();
23
+ setFocusedIndex(prevIndex =>
24
+ prevIndex < totalItemsLength - 1 ? prevIndex + 1 : 0
25
+ );
26
+ };
27
+
28
+ const handleSpacebar = event => {
29
+ event.preventDefault();
30
+ const validFocusedIndex = focusedIndex < 0 ? 0 : focusedIndex;
31
+ // Select option on spacebar press if the maximum selection hasn't been reached.
32
+ if (
33
+ !isMaxSelectionReached(maxSelections, selectedOptions) &&
34
+ itemRefs.current &&
35
+ itemRefs.current[validFocusedIndex]
36
+ ) {
37
+ const nestedInput = itemRefs.current[validFocusedIndex].querySelector(
38
+ "input"
39
+ );
40
+ if (nestedInput) {
41
+ nestedInput.click();
42
+ }
43
+ }
44
+ };
45
+
46
+ const handleTab = event => {
47
+ // Reset focus when tabbing out of the list.
48
+ setFocusedIndex(-1);
49
+ };
50
+
51
+ const keyActions = {
52
+ " ": event => handleSpacebar(event),
53
+ Space: event => handleSpacebar(event),
54
+ Tab: event => handleTab(event),
55
+ ArrowUp: event => handleArrowUp(event),
56
+ ArrowDown: event => handleArrowDown(event)
57
+ };
58
+
59
+ const handleKeyDown = event => {
60
+ const eventKey = event.code || event.key;
61
+ const action = keyActions[eventKey];
62
+ if (action) {
63
+ action(event);
64
+ }
65
+ };
66
+
67
+ useEffect(() => {
68
+ if (
69
+ focusedIndex !== -1 &&
70
+ itemRefs.current &&
71
+ itemRefs.current[focusedIndex]
72
+ ) {
73
+ itemRefs.current[focusedIndex].focus(); // move focus to the active option
74
+ }
75
+ }, [focusedIndex]);
76
+
77
+ return {
78
+ itemRefs,
79
+ focusedIndex,
80
+ handleKeyDown
81
+ };
82
+ };
83
+
84
+ export default useKeyboardNavigation;
@@ -0,0 +1,31 @@
1
+ export const filterItemsList = (list, searchTerm) =>
2
+ list.filter(item =>
3
+ item?.name?.toLowerCase().includes(searchTerm?.toLowerCase())
4
+ );
5
+
6
+ export const sortItemsList = list =>
7
+ list
8
+ .slice()
9
+ .sort((a, b) => a.name.toLowerCase().localeCompare(b.name.toLowerCase()));
10
+
11
+ export const isMaxSelectionReached = (maxSelection, selectedOptions) =>
12
+ maxSelection && maxSelection === selectedOptions?.length;
13
+
14
+ export const isChecked = (option, selectedOptions) =>
15
+ selectedOptions?.some(
16
+ selectedOption => selectedOption?.name === option?.name
17
+ );
18
+
19
+ export const selectValues = items => items.map(item => item.value);
20
+
21
+ export const selectOption = (option, selectedOptions, setSelectedOptions) => {
22
+ if (selectValues(selectedOptions).includes(option.value)) {
23
+ const fewerOptions = selectedOptions.filter(
24
+ selectedOption => selectedOption.value !== option.value
25
+ );
26
+ setSelectedOptions(fewerOptions);
27
+ } else {
28
+ const moreOptions = selectedOptions.concat(option);
29
+ setSelectedOptions(moreOptions);
30
+ }
31
+ };
@@ -1,6 +1,6 @@
1
1
  import React from "react";
2
2
 
3
- const PropertyPersonalIcon = () => (
3
+ const PropertyBusinessIcon = () => (
4
4
  <svg
5
5
  width="48"
6
6
  height="48"
@@ -1,181 +1,32 @@
1
- import React, { useState } from "react";
2
- import { WHITE, GHOST_GREY } from "../../../constants/colors";
3
- import { Box } from "../../atoms/layouts";
1
+ import React from "react";
2
+ import { number, text } from "@storybook/addon-knobs";
4
3
  import Pagination from "./Pagination";
5
- import { fn } from "@storybook/test";
6
- import { FONT_WEIGHT_SEMIBOLD } from "../../../constants/style_constants";
4
+ import page from "../../../../.storybook/page";
7
5
 
8
- const meta = {
9
- title: "Molecules/Pagination",
10
- component: Pagination,
11
- parameters: {
12
- layout: "centered"
13
- },
14
- tags: ["!autodocs"],
15
- args: {
16
- activeBorderWidth: "3px",
17
- ariaLabel: undefined,
18
- arrowColor: undefined,
19
- borderRadius: "3px",
20
- buttonHeight: "44px",
21
- buttonWidth: "44px",
22
- childGap: "24px",
23
- currentPage: undefined,
24
- fontSize: "17px",
25
- fontWeight: "900",
26
- numberColor: undefined,
27
- pageCount: undefined,
28
- pageNext: fn(),
29
- pagePrevious: fn(),
30
- setCurrentPage: fn()
31
- },
32
- argTypes: {
33
- activeBorderWidth: {
34
- description: "The width of the border around the active page number",
35
- table: {
36
- type: { summary: "string" },
37
- defaultValue: { summary: "3px" }
38
- }
39
- },
40
- ariaLabel: {
41
- description: "aria-label value for pagination container",
42
- table: {
43
- type: { summary: "string" },
44
- defaultValue: { summary: undefined }
45
- }
46
- },
47
- arrowColor: {
48
- description:
49
- "Override for arrow color, if undefined component uses themed values",
50
- table: {
51
- type: { summary: "string" },
52
- defaultValue: { summary: undefined }
53
- }
54
- },
55
- borderRadius: {
56
- description: "Border radius of the border around pagination controls",
57
- table: {
58
- type: { summary: "string" },
59
- defaultValue: { summary: "3px" }
60
- }
61
- },
62
- buttonHeight: {
63
- description: "Height of pagination buttons",
64
- table: {
65
- type: { summary: "string" },
66
- defaultValue: { summary: "44px" }
67
- }
68
- },
69
- buttonWidth: {
70
- description: "Width of pagination buttons",
71
- table: {
72
- type: { summary: "string" },
73
- defaultValue: { summary: "44px" }
74
- }
75
- },
76
- childGap: {
77
- description: "Gap between pagination buttons",
78
- table: {
79
- type: { summary: "string" },
80
- defaultValue: { summary: "24px" }
81
- }
82
- },
83
- currentPage: {
84
- description: "Current active page",
85
- table: {
86
- type: { summary: "number" },
87
- defaultValue: { summary: undefined }
88
- }
89
- },
90
- fontSize: {
91
- descripton: "Font size of page buttons",
92
- table: {
93
- type: { summary: "string" },
94
- defaultValue: { summary: "17px" }
95
- }
96
- },
97
- fontWeight: {
98
- description: "Font weight of page buttons",
99
- table: {
100
- type: { summary: "string" },
101
- defaultValue: { summary: "900" }
102
- }
103
- },
104
- numberColor: {
105
- description:
106
- "Override for color of pagination number buttons, if undefined will use themed values",
107
- table: {
108
- type: { summary: "string" },
109
- defaultValue: { summary: undefined }
110
- }
111
- },
112
- pageCount: {
113
- description: "Total number of pages",
114
- table: {
115
- type: { summary: "number" },
116
- defaultValue: { summary: undefined }
117
- }
118
- },
119
- pageNext: {
120
- description: "Function to call when next button is clicked",
121
- table: {
122
- type: { summary: "function" },
123
- defaultValue: { summary: undefined }
124
- }
125
- },
126
- pagePrevious: {
127
- description: "Function to call when previous button is clicked",
128
- table: {
129
- type: { summary: "function" },
130
- defaultValue: { summary: undefined }
131
- }
132
- },
133
- setCurrentPage: {
134
- description: "Function to call when user selects a numerical page button",
135
- table: {
136
- type: { summary: "function" },
137
- defaultValue: { summary: undefined }
138
- }
139
- }
140
- }
141
- };
6
+ export const pagination = () => (
7
+ <Pagination
8
+ activeBorderWidth={text("activeBorderWidth", "3px", "props")}
9
+ ariaLabel={text("ariaLabel", "Aria Label", "props")}
10
+ arrowColor={text("arrowColor", "#FFFFFF", "props")}
11
+ borderRadius={text("borderRadius", "3px", "props")}
12
+ buttonHeight={text("buttonHeight", "44px", "props")}
13
+ buttonWidth={text("buttonWidth", "44px", "props")}
14
+ childGap={text("childGap", "24px", "props")}
15
+ currentPage={number("currentPage", 2)}
16
+ fontSize={text("fontSize", "17px", "props")}
17
+ fontWeight={text("fontWeight", "900", "props")}
18
+ numberColor={text("numberColor", "#15749D", "props")}
19
+ pageCount={number("pageCount", 3)}
20
+ pageNext={() => {}}
21
+ pagePrevious={() => {}}
22
+ setCurrentPage={() => {}}
23
+ // themeValues
24
+ />
25
+ );
142
26
 
143
- export default meta;
27
+ const story = page({
28
+ title: "Components|Molecules/Pagination",
29
+ Component: Pagination
30
+ });
144
31
 
145
- export const BasicPagination = {
146
- args: {
147
- activeBorderWidth: "3px",
148
- childGap: "24px",
149
- borderRadius: "4px",
150
- fontSize: "14px",
151
- buttonHeight: "44px",
152
- buttonWidth: "44px",
153
- fontWeight: FONT_WEIGHT_SEMIBOLD,
154
- pageCount: 12,
155
- ariaLabel: "Pagination"
156
- },
157
- render: args => {
158
- const [currentPage, setCurrentPage] = useState(5);
159
-
160
- return (
161
- <Box
162
- background={WHITE}
163
- borderRadius="4px"
164
- boxShadow={`0px 0px 5px 0px ${GHOST_GREY}`}
165
- padding={"24px"}
166
- >
167
- <Pagination
168
- {...args}
169
- currentPage={currentPage}
170
- pageNext={() =>
171
- currentPage < 12 ? setCurrentPage(currentPage + 1) : fn()
172
- }
173
- pagePrevious={() =>
174
- currentPage > 1 ? setCurrentPage(currentPage - 1) : fn()
175
- }
176
- setCurrentPage={page => setCurrentPage(page.pageNumber)}
177
- />
178
- </Box>
179
- );
180
- }
181
- };
32
+ export default story;