@skyscanner/backpack-web 9.3.0 → 11.1.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 (226) hide show
  1. package/bpk-animate-height/package.json +3 -3
  2. package/bpk-component-accordion/package.json +8 -8
  3. package/bpk-component-accordion/src/BpkAccordion.module.scss +1 -1
  4. package/bpk-component-accordion/src/BpkAccordionItem.module.scss +1 -1
  5. package/bpk-component-aria-live/README.md +2 -2
  6. package/bpk-component-aria-live/index.js +0 -1
  7. package/bpk-component-aria-live/package.json +8 -9
  8. package/bpk-component-aria-live/src/BpkAriaLive.js +21 -20
  9. package/bpk-component-aria-live/src/BpkAriaLive.module.scss +1 -1
  10. package/bpk-component-autosuggest/package.json +5 -5
  11. package/bpk-component-autosuggest/src/BpkAutosuggest.module.scss +2 -2
  12. package/bpk-component-badge/package.json +6 -6
  13. package/bpk-component-badge/src/BpkBadge.module.scss +1 -1
  14. package/bpk-component-banner-alert/package.json +10 -10
  15. package/bpk-component-banner-alert/src/BpkAnimateAndFade.module.scss +1 -1
  16. package/bpk-component-banner-alert/src/BpkBannerAlert.module.scss +3 -3
  17. package/bpk-component-barchart/package.json +9 -9
  18. package/bpk-component-barchart/src/BpkBarchartBar.module.scss +3 -1
  19. package/bpk-component-barchart/src/BpkChartAxis.module.scss +1 -1
  20. package/bpk-component-barchart/src/BpkChartDataTable.module.scss +1 -1
  21. package/bpk-component-barchart/src/BpkChartGridLines.module.scss +2 -2
  22. package/bpk-component-blockquote/package.json +3 -3
  23. package/bpk-component-blockquote/src/BpkBlockquote.module.scss +1 -1
  24. package/bpk-component-breadcrumb/package.json +6 -6
  25. package/bpk-component-breadcrumb/src/BpkBreadcrumb.module.scss +1 -1
  26. package/bpk-component-breadcrumb/src/BpkBreadcrumbItem.module.scss +1 -1
  27. package/bpk-component-breakpoint/package.json +4 -4
  28. package/bpk-component-button/package.json +3 -3
  29. package/bpk-component-button/src/BpkButtonBase.module.scss +2 -2
  30. package/bpk-component-button/src/BpkButtonDestructive.module.scss +1 -1
  31. package/bpk-component-button/src/BpkButtonFeatured.module.scss +1 -1
  32. package/bpk-component-button/src/BpkButtonLink.module.scss +1 -1
  33. package/bpk-component-button/src/BpkButtonLinkOnDark.module.scss +1 -1
  34. package/bpk-component-button/src/BpkButtonOutline.module.scss +1 -1
  35. package/bpk-component-button/src/BpkButtonPrimaryOnDark.module.scss +1 -1
  36. package/bpk-component-button/src/BpkButtonPrimaryOnLight.module.scss +1 -1
  37. package/bpk-component-button/src/BpkButtonSecondary.module.scss +1 -1
  38. package/bpk-component-button/src/BpkButtonSecondaryOnDark.module.scss +1 -1
  39. package/bpk-component-calendar/DOCS.md +1 -7
  40. package/bpk-component-calendar/README.md +0 -10
  41. package/bpk-component-calendar/index.js +0 -2
  42. package/bpk-component-calendar/package.json +10 -10
  43. package/bpk-component-calendar/src/BpkCalendar.module.scss +2 -2
  44. package/bpk-component-calendar/src/BpkCalendarDate.js +0 -15
  45. package/bpk-component-calendar/src/BpkCalendarDate.module.scss +18 -51
  46. package/bpk-component-calendar/src/BpkCalendarGrid.module.scss +8 -7
  47. package/bpk-component-calendar/src/BpkCalendarGridHeader.module.scss +2 -2
  48. package/bpk-component-calendar/src/BpkCalendarGridTransition.module.scss +2 -2
  49. package/bpk-component-calendar/src/BpkCalendarNav.module.scss +3 -3
  50. package/bpk-component-calendar/src/_variables.scss +2 -4
  51. package/bpk-component-card/package.json +5 -5
  52. package/bpk-component-card/src/BpkCard.module.scss +1 -1
  53. package/bpk-component-checkbox/package.json +6 -6
  54. package/bpk-component-checkbox/src/BpkCheckbox.module.scss +1 -1
  55. package/bpk-component-chip/package.json +6 -6
  56. package/bpk-component-chip/src/BpkSelectableChip.module.scss +1 -1
  57. package/bpk-component-close-button/package.json +5 -5
  58. package/bpk-component-close-button/src/BpkCloseButton.module.scss +3 -2
  59. package/bpk-component-code/package.json +3 -3
  60. package/bpk-component-code/src/BpkCode.module.scss +1 -1
  61. package/bpk-component-code/src/BpkCodeBlock.module.scss +1 -1
  62. package/bpk-component-content-cards/{index.ts → index.js} +0 -0
  63. package/bpk-component-content-cards/package.json +5 -5
  64. package/bpk-component-content-cards/src/{BpkContentCard/BpkContentCard.tsx → BpkContentCard.js} +10 -11
  65. package/bpk-component-content-cards/src/{BpkContentCard/BpkContentCard.module.scss → BpkContentCard.module.scss} +1 -1
  66. package/bpk-component-content-cards/src/{BpkContentCards.tsx → BpkContentCards.js} +11 -11
  67. package/bpk-component-content-cards/src/BpkContentCards.module.scss +1 -1
  68. package/bpk-component-content-container/package.json +3 -3
  69. package/bpk-component-content-container/src/BpkContentContainer.module.scss +1 -1
  70. package/bpk-component-datatable/README.md +78 -21
  71. package/bpk-component-datatable/package.json +6 -7
  72. package/bpk-component-datatable/src/BpkDataTable.js +176 -143
  73. package/bpk-component-datatable/src/BpkDataTable.module.scss +11 -16
  74. package/bpk-component-datatable/src/BpkDataTableColumn.js +37 -40
  75. package/bpk-component-datatable/src/BpkDataTableHeader.js +143 -0
  76. package/bpk-component-datatable/src/{BpkDataTableColumn.module.scss → BpkDataTableHeader.module.scss} +12 -12
  77. package/bpk-component-datatable/src/common-types.js +33 -11
  78. package/bpk-component-datatable/src/sort-types.js +6 -0
  79. package/bpk-component-datatable/src/utils.js +66 -9
  80. package/bpk-component-datepicker/package.json +10 -10
  81. package/bpk-component-datepicker/src/BpkDatepicker.module.scss +1 -1
  82. package/bpk-component-description-list/package.json +3 -3
  83. package/bpk-component-description-list/src/BpkDescriptionList.module.scss +1 -1
  84. package/bpk-component-dialog/package.json +9 -9
  85. package/bpk-component-dialog/src/BpkDialog.module.scss +1 -1
  86. package/bpk-component-dialog/src/BpkDialogInner.module.scss +3 -1
  87. package/bpk-component-drawer/package.json +10 -10
  88. package/bpk-component-drawer/src/BpkDrawer.module.scss +1 -1
  89. package/bpk-component-drawer/src/BpkDrawerContent.module.scss +1 -1
  90. package/bpk-component-fieldset/package.json +13 -13
  91. package/bpk-component-fieldset/src/BpkFieldset.module.scss +1 -1
  92. package/bpk-component-flare/package.json +5 -5
  93. package/bpk-component-flare/src/bpk-content-bubble.module.scss +2 -1
  94. package/bpk-component-flare/src/bpk-flare-bar.module.scss +2 -1
  95. package/bpk-component-floating-notification/README.md +0 -8
  96. package/bpk-component-floating-notification/index.js +0 -2
  97. package/bpk-component-floating-notification/package.json +6 -6
  98. package/bpk-component-floating-notification/src/BpkFloatingNotification.js +7 -26
  99. package/bpk-component-floating-notification/src/BpkFloatingNotification.module.scss +5 -18
  100. package/bpk-component-form-validation/package.json +11 -11
  101. package/bpk-component-form-validation/src/BpkFormValidation.module.scss +1 -1
  102. package/bpk-component-graphic-promotion/{index.ts → index.js} +0 -0
  103. package/bpk-component-graphic-promotion/package.json +7 -6
  104. package/bpk-component-graphic-promotion/src/{BpkGraphicPromo.tsx → BpkGraphicPromo.js} +26 -16
  105. package/bpk-component-graphic-promotion/src/BpkGraphicPromo.module.scss +1 -1
  106. package/bpk-component-grid/package.json +3 -3
  107. package/bpk-component-grid/src/BpkGridColumn.module.scss +1 -1
  108. package/bpk-component-grid/src/BpkGridContainer.module.scss +1 -1
  109. package/bpk-component-grid/src/BpkGridRow.module.scss +1 -1
  110. package/bpk-component-grid-toggle/package.json +4 -4
  111. package/bpk-component-grid-toggle/src/BpkGridToggle.module.scss +1 -1
  112. package/bpk-component-horizontal-nav/package.json +7 -7
  113. package/bpk-component-horizontal-nav/src/BpkHorizontalNav.module.scss +3 -3
  114. package/bpk-component-horizontal-nav/src/BpkHorizontalNavItem.module.scss +15 -15
  115. package/bpk-component-icon/README.md +1 -1
  116. package/bpk-component-icon/package.json +8 -8
  117. package/bpk-component-icon/src/BpkIcon.module.scss +1 -1
  118. package/bpk-component-icon/src/withDescription.module.scss +1 -1
  119. package/bpk-component-image/package.json +7 -7
  120. package/bpk-component-image/src/BpkBackgroundImage.module.scss +1 -1
  121. package/bpk-component-image/src/BpkImage.module.scss +1 -1
  122. package/bpk-component-infinite-scroll/package.json +7 -7
  123. package/bpk-component-infinite-scroll/src/withInfiniteScroll.module.scss +1 -1
  124. package/bpk-component-input/package.json +7 -7
  125. package/bpk-component-input/src/BpkClearButton.module.scss +2 -2
  126. package/bpk-component-input/src/BpkInput.module.scss +1 -1
  127. package/bpk-component-label/package.json +3 -3
  128. package/bpk-component-label/src/BpkLabel.module.scss +1 -1
  129. package/bpk-component-link/package.json +5 -5
  130. package/bpk-component-link/src/BpkLink.module.scss +1 -1
  131. package/bpk-component-list/README.md +8 -5
  132. package/bpk-component-list/package.json +3 -3
  133. package/bpk-component-list/src/BpkList.js +18 -2
  134. package/bpk-component-list/src/BpkList.module.scss +1 -1
  135. package/bpk-component-loading-button/package.json +7 -7
  136. package/bpk-component-loading-button/src/BpkLoadingButton.module.scss +1 -1
  137. package/bpk-component-map/package.json +7 -7
  138. package/bpk-component-map/src/BpkIconMarker.module.scss +3 -2
  139. package/bpk-component-map/src/BpkIconMarkerBackground.module.scss +1 -1
  140. package/bpk-component-map/src/BpkMap.js +1 -0
  141. package/bpk-component-map/src/BpkPriceMarker.module.scss +3 -1
  142. package/bpk-component-map/src/DefaultLoadingElement.module.scss +1 -1
  143. package/bpk-component-mobile-scroll-container/README.md +1 -1
  144. package/bpk-component-mobile-scroll-container/package.json +4 -4
  145. package/bpk-component-mobile-scroll-container/src/BpkMobileScrollContainer.module.scss +3 -1
  146. package/bpk-component-modal/package.json +10 -10
  147. package/bpk-component-modal/src/BpkModal.module.scss +1 -1
  148. package/bpk-component-modal/src/BpkModalInner.module.scss +3 -1
  149. package/bpk-component-navigation-bar/package.json +9 -9
  150. package/bpk-component-navigation-bar/src/BpkNavigationBar.module.scss +4 -4
  151. package/bpk-component-navigation-bar/src/BpkNavigationBarButtonLink.module.scss +5 -5
  152. package/bpk-component-navigation-bar/src/BpkNavigationBarIconButton.module.scss +4 -4
  153. package/bpk-component-nudger/package.json +8 -8
  154. package/bpk-component-nudger/src/BpkNudger.module.scss +1 -1
  155. package/bpk-component-overlay/package.json +5 -5
  156. package/bpk-component-overlay/src/BpkOverlay.module.scss +1 -1
  157. package/bpk-component-pagination/package.json +5 -5
  158. package/bpk-component-pagination/src/BpkPaginationList.module.scss +1 -1
  159. package/bpk-component-pagination/src/BpkPaginationNudger.module.scss +2 -2
  160. package/bpk-component-pagination/src/BpkPaginationPage.module.scss +1 -1
  161. package/bpk-component-panel/package.json +3 -3
  162. package/bpk-component-panel/src/BpkPanel.module.scss +1 -1
  163. package/bpk-component-phone-input/package.json +10 -10
  164. package/bpk-component-phone-input/src/BpkPhoneInput.module.scss +1 -1
  165. package/bpk-component-popover/package.json +9 -9
  166. package/bpk-component-popover/src/BpkPopover.module.scss +1 -2
  167. package/bpk-component-price/package.json +4 -4
  168. package/bpk-component-price/src/BpkPrice.module.scss +1 -1
  169. package/bpk-component-progress/package.json +6 -6
  170. package/bpk-component-progress/src/BpkProgress.module.scss +1 -1
  171. package/bpk-component-radio/package.json +5 -5
  172. package/bpk-component-radio/src/BpkRadio.module.scss +1 -2
  173. package/bpk-component-rating/package.json +5 -5
  174. package/bpk-component-rating/src/BpkRating.module.scss +1 -1
  175. package/bpk-component-rtl-toggle/package.json +3 -3
  176. package/bpk-component-scrollable-calendar/package.json +7 -7
  177. package/bpk-component-scrollable-calendar/src/BpkScrollableCalendarGrid.module.scss +1 -1
  178. package/bpk-component-scrollable-calendar/src/BpkScrollableCalendarGridList.module.scss +1 -2
  179. package/bpk-component-section-list/package.json +7 -7
  180. package/bpk-component-section-list/src/BpkSectionListItem.module.scss +1 -1
  181. package/bpk-component-section-list/src/BpkSectionListSection.module.scss +1 -1
  182. package/bpk-component-select/package.json +4 -4
  183. package/bpk-component-select/src/BpkSelect.module.scss +1 -1
  184. package/bpk-component-skip-link/package.json +3 -3
  185. package/bpk-component-skip-link/src/BpkSkipLink.module.scss +2 -1
  186. package/bpk-component-slider/package.json +5 -5
  187. package/bpk-component-slider/src/BpkSlider.module.scss +1 -2
  188. package/bpk-component-spinner/package.json +4 -4
  189. package/bpk-component-spinner/src/BpkSpinner.module.scss +1 -1
  190. package/bpk-component-split-input/package.json +4 -4
  191. package/bpk-component-split-input/src/BpkInputField.module.scss +1 -1
  192. package/bpk-component-split-input/src/BpkSplitInput.module.scss +1 -1
  193. package/bpk-component-star-rating/package.json +6 -6
  194. package/bpk-component-star-rating/src/BpkInteractiveStar.module.scss +3 -3
  195. package/bpk-component-star-rating/src/BpkStar.module.scss +1 -1
  196. package/bpk-component-switch/README.md +1 -1
  197. package/bpk-component-switch/package.json +3 -3
  198. package/bpk-component-switch/src/BpkSwitch.js +14 -13
  199. package/bpk-component-switch/src/BpkSwitch.module.scss +18 -12
  200. package/bpk-component-table/package.json +3 -3
  201. package/bpk-component-table/src/BpkTable.module.scss +1 -1
  202. package/bpk-component-text/package.json +3 -3
  203. package/bpk-component-text/src/BpkText.module.scss +1 -1
  204. package/bpk-component-textarea/package.json +5 -5
  205. package/bpk-component-textarea/src/BpkTextarea.module.scss +1 -1
  206. package/bpk-component-theme-toggle/package.json +6 -6
  207. package/bpk-component-theme-toggle/src/BpkThemeToggle.module.scss +1 -1
  208. package/bpk-component-ticket/package.json +5 -5
  209. package/bpk-component-ticket/src/BpkTicket.module.scss +1 -1
  210. package/bpk-component-tooltip/package.json +5 -5
  211. package/bpk-component-tooltip/src/BpkTooltip.module.scss +3 -2
  212. package/bpk-react-utils/README.md +1 -1
  213. package/bpk-react-utils/package.json +1 -1
  214. package/bpk-scrim-utils/package.json +3 -3
  215. package/bpk-scrim-utils/src/bpk-scrim-content.module.scss +1 -1
  216. package/bpk-scrim-utils/src/bpk-scrim.module.scss +1 -1
  217. package/bpk-theming/package.json +2 -2
  218. package/package.json +4 -4
  219. package/bpk-component-content-cards/src/BpkContentCard/BpkContentCard-test.tsx +0 -88
  220. package/bpk-component-content-cards/src/BpkContentCard/index.ts +0 -19
  221. package/bpk-component-content-cards/src/BpkContentCards-test.tsx +0 -126
  222. package/bpk-component-content-cards/src/accessibility-test.tsx +0 -64
  223. package/bpk-component-datatable/src/bpkHeaderRenderer.js +0 -110
  224. package/bpk-component-datatable/src/sorter.js +0 -166
  225. package/bpk-component-graphic-promotion/src/BpkGraphicPromo-test.tsx +0 -134
  226. package/bpk-component-graphic-promotion/src/accessibility-test.tsx +0 -147
@@ -19,9 +19,9 @@
19
19
  import React from 'react';
20
20
 
21
21
  // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
22
- import BpkText from '../../../bpk-component-text';
22
+ import BpkText from '../../bpk-component-text';
23
23
  // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
24
- import { cssModules } from '../../../bpk-react-utils';
24
+ import { cssModules } from '../../bpk-react-utils';
25
25
 
26
26
  import STYLES from './BpkContentCard.module.scss';
27
27
 
@@ -32,14 +32,14 @@ type CardLayout = 'HORIZONTAL' | 'VERTICAL';
32
32
  type Props = {
33
33
  card: {
34
34
  image: {
35
- url: string;
36
- alt?: string;
37
- };
38
- headline: string;
39
- description: string;
40
- href: string;
41
- };
42
- layout: CardLayout;
35
+ url: string,
36
+ alt?: string,
37
+ },
38
+ headline: string,
39
+ description: string,
40
+ href: string,
41
+ },
42
+ layout: CardLayout,
43
43
  };
44
44
 
45
45
  const BpkContentCard = ({ card, layout }: Props) => (
@@ -55,7 +55,6 @@ const BpkContentCard = ({ card, layout }: Props) => (
55
55
  rel="noreferrer"
56
56
  >
57
57
  <div className={getClassName('bpk-content-card--image-container')}>
58
- {/* eslint-disable-next-line jsx-a11y/img-redundant-alt */}
59
58
  <img
60
59
  className={getClassName('bpk-content-card--image')}
61
60
  alt={card.image.alt || ''}
@@ -15,7 +15,7 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- @import '~bpk-mixins/index';
18
+ @import '~bpk-mixins/index.scss';
19
19
 
20
20
  $bpk-spacing-v2: true;
21
21
 
@@ -15,6 +15,7 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
+ /* eslint react/no-array-index-key: 0 */
18
19
 
19
20
  import React from 'react';
20
21
 
@@ -29,16 +30,16 @@ import STYLES from './BpkContentCards.module.scss';
29
30
  const getClassName = cssModules(STYLES);
30
31
 
31
32
  type Props = {
32
- heading: string;
33
+ heading: string,
33
34
  cards: Array<{
34
35
  image: {
35
- url: string;
36
- alt?: string;
37
- };
38
- headline: string;
39
- description: string;
40
- href: string;
41
- }>;
36
+ url: string,
37
+ alt?: string,
38
+ },
39
+ headline: string,
40
+ description: string,
41
+ href: string,
42
+ }>,
42
43
  };
43
44
 
44
45
  const BpkContentCards = ({ cards, heading }: Props) => {
@@ -55,10 +56,9 @@ const BpkContentCards = ({ cards, heading }: Props) => {
55
56
  {heading}
56
57
  </BpkText>
57
58
  <div role="list" className={getClassName('bpk-content-cards--layout')}>
58
- {cards.map((card) => (
59
- <div role="listitem">
59
+ {cards.map((card, index) => (
60
+ <div role="listitem" key={index}>
60
61
  <BpkContentCard
61
- key={card.image.url}
62
62
  card={card}
63
63
  layout={cards.length === 1 ? 'HORIZONTAL' : 'VERTICAL'}
64
64
  />
@@ -18,7 +18,7 @@
18
18
 
19
19
  /* stylelint-disable selector-class-pattern */
20
20
  /* stylelint-disable selector-max-compound-selectors */
21
- @import '~bpk-mixins/index';
21
+ @import '~bpk-mixins/index.scss';
22
22
 
23
23
  $bpk-spacing-v2: true;
24
24
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bpk-component-content-container",
3
- "version": "6.0.2",
3
+ "version": "6.0.5",
4
4
  "description": "Backpack content container component.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -14,8 +14,8 @@
14
14
  },
15
15
  "gitHead": "5c156b97cb0ba5e75851d3c763334578714c895e",
16
16
  "dependencies": {
17
- "bpk-mixins": "^31.5.0",
18
- "bpk-react-utils": "^7.0.0",
17
+ "bpk-mixins": "^31.6.3",
18
+ "bpk-react-utils": "^7.0.1",
19
19
  "prop-types": "^15.7.2"
20
20
  },
21
21
  "peerDependencies": {
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- @import '~bpk-mixins/index';
19
+ @import '~bpk-mixins/index.scss';
20
20
 
21
21
  .bpk-content-container {
22
22
  > {
@@ -38,12 +38,11 @@ export default () => (
38
38
  );
39
39
  ```
40
40
 
41
- By default `BpkDataTable` sorts the column using the value of `dataKey`. For use cases where the data might more complex and requires custom sorting you can pass a `sort` function along with `sortBy` and `sortDirection` and they will be handled as explained in react-virtualized's [docs] (https://github.com/bvaughn/react-virtualized/blob/main/docs/Table.md#prop-types)
41
+ By default `BpkDataTable` sorts the column using the value of `dataKey`. For use cases where the data might more complex and requires custom sorting you can pass a `sort` function along with `sortBy` and `sortDirection`.
42
42
 
43
43
  ```js
44
44
  import React from 'react';
45
45
  import { BpkDataTable, BpkDataTableColumn } from 'bpk-component-datatable';
46
- import _sortBy from 'lodash/sortBy';
47
46
 
48
47
  const complexRows = [
49
48
  {
@@ -65,21 +64,16 @@ const complexRows = [
65
64
 
66
65
  let sortByValue = 'seat';
67
66
  let sortDirectionValue = 'DESC';
68
- const sortFunction = ({ sortBy, sortDirection }) => {
69
- if (sortBy === 'seat') {
70
- complexRows = _sortBy(complexRows, [
71
- row => row.seat.office,
72
- row => row.seat.desk,
73
- ]);
67
+ const sortFunction = (rowA, rowB, id, desc) => {
68
+ const deskA = rowA.values.seat.desk;
69
+ const deskB = rowB.values.seat.desk;
70
+
71
+ if (deskA === deskB) {
72
+ return 0;
74
73
  } else {
75
- complexRows = _sortBy(complexRows, sortBy);
76
- }
77
- if (sortDirection === 'DESC') {
78
- complexRows.reverse();
74
+ return deskA > deskB ? 1 : -1;
79
75
  }
80
- sortByValue = sortBy;
81
- sortDirectionValue = sortDirection;
82
- };
76
+ }
83
77
 
84
78
  export default () => (
85
79
  <BpkDataTable
@@ -118,10 +112,6 @@ export default () => (
118
112
 
119
113
  ### BpkDataTable
120
114
 
121
- Supports all properties defined in [`Table`](https://github.com/bvaughn/react-virtualized/blob/main/docs/Table.md) (from `react-virtualized`),
122
- in addition to the following:
123
-
124
-
125
115
  | Property | PropType | Required | Default Value |
126
116
  | ---------------------- | --------------------------- | -------- | -------------------- |
127
117
  | rows | arrayOf(Object) | true | - |
@@ -130,12 +120,79 @@ in addition to the following:
130
120
  | width | number | false | full width of parent |
131
121
  | headerHeight | number | false | 60 |
132
122
  | rowHeight | number | false | 60 |
123
+ | rowStyle | object | false | {} |
124
+ | onRowClick | func | false | null |
125
+ | className | string | false | null |
133
126
  | defaultColumnSortIndex | number | false | 0 |
134
127
  | sort | func | false | null |
135
128
  | sortBy | string | false | null |
136
- | sortDirection | oneOf('ASC', 'DESC') | false | null |
129
+ | sortDirection | oneOf('ASC', 'DESC') | false | 'ASC' |
137
130
 
138
131
 
139
132
  ### BpkDataTableColumn
140
133
 
141
- Supports all properties defined in [`Column`](https://github.com/bvaughn/react-virtualized/blob/master/docs/Column.md) (from `react-virtualized`)
134
+ | Property | PropType | Required | Default Value |
135
+ | ---------------------- | --------------------------- | -------- | -------------------- |
136
+ | dataKey | string | true | - |
137
+ | width | number | true | - |
138
+ | flexGrow | number | false | 0 |
139
+ | label | string | false | null |
140
+ | headerRenderer | func | false | null |
141
+ | headerClassName | string | false | null |
142
+ | headerStyle | object | false | {} |
143
+ | cellRenderer | func | false | null |
144
+ | cellDataGetter | func | false | null |
145
+ | disableSort | bool | false | false |
146
+ | defaultSortDirection | oneOf('ASC', 'DESC') | false | 'ASC' |
147
+ | className | string | false | null |
148
+
149
+ ### Prop Details
150
+
151
+
152
+ #### sort, sortBy, sortDirection
153
+
154
+ For custom sorting, pass a `sort` function.
155
+ Use `sortBy` to specify which column the custom sorting will be applied to.
156
+ Use `sortDirection` to set the direction of sorting. By default, it will be ascending.
157
+
158
+ #### defaultColumnSortIndex
159
+
160
+ The data will be sorted by default based on this column.
161
+
162
+ #### headerRenderer
163
+
164
+ To handle more complex header data that needs any custom processing, pass a function or component to `headerRenderer` prop. This will only be formatting the header value - all styling will be handled by the component.
165
+ It should implement the following signature:
166
+
167
+ ```
168
+ function ({
169
+ dataKey: string, disableSort: boolean, label: string
170
+ }): element
171
+ ```
172
+
173
+ #### cellDataGetter
174
+
175
+ To handle more complex cell data that needs any custom processing, pass a function or component to `cellDataGetter` prop. This will only be formatting the cell value - all styling will be handled by the component.
176
+ It should implement the following signature:
177
+
178
+ ```
179
+ function ({
180
+ dataKey: string,
181
+ rowData: any
182
+ }): any
183
+ ```
184
+
185
+ #### cellRenderer
186
+
187
+ To handle more complex cell data that needs any custom processing, pass a function or component to `cellRenderer` prop. This will only be formatting the cell value - all styling will be handled by the component. To maintain backward compatibility, both `cellRenderer` and `cellDataGetter` will be supported, however, they are interchangeable as they both can only format the cell value.
188
+ It should implement the following signature:
189
+
190
+ ```
191
+ function ({
192
+ cellData: any,
193
+ columnIndex: number,
194
+ dataKey: string,
195
+ rowData: any,
196
+ rowIndex: any,
197
+ }): node
198
+ ```
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bpk-component-datatable",
3
- "version": "5.0.2",
3
+ "version": "6.0.2",
4
4
  "description": "Backpack datatable component.",
5
5
  "license": "Apache-2.0",
6
6
  "repository": {
@@ -14,17 +14,16 @@
14
14
  },
15
15
  "gitHead": "f9f94f86d7cfc75e43bc6ad5eb01b23e62a89cc8",
16
16
  "dependencies": {
17
- "bpk-component-icon": "^10.0.2",
18
- "bpk-mixins": "^31.5.0",
19
- "bpk-react-utils": "^7.0.0",
20
- "lodash": "^4.17.20",
17
+ "bpk-component-icon": "^10.0.5",
18
+ "bpk-mixins": "^31.6.3",
19
+ "bpk-react-utils": "^7.0.1",
21
20
  "prop-types": "^15.7.2",
22
- "react-virtualized": "^9.22.3"
21
+ "react-table": "^7.8.0"
23
22
  },
24
23
  "peerDependencies": {
25
24
  "react": "^17.0.2"
26
25
  },
27
26
  "devDependencies": {
28
- "@skyscanner/bpk-foundations-web": "^9.0.0"
27
+ "@skyscanner/bpk-foundations-web": "^9.3.0"
29
28
  }
30
29
  }
@@ -18,180 +18,213 @@
18
18
  /* @flow strict */
19
19
 
20
20
  import PropTypes from 'prop-types';
21
- import React, { Component } from 'react';
22
- import { Table, AutoSizer } from 'react-virtualized';
23
- import _omit from 'lodash/omit';
21
+ import React, { useMemo, useState } from 'react';
22
+ import { useTable, useSortBy } from 'react-table';
24
23
 
25
24
  import { cssModules } from '../../bpk-react-utils';
26
25
 
27
26
  import STYLES from './BpkDataTable.module.scss';
28
- import BpkDataTableColumn from './BpkDataTableColumn';
29
- import hasChildrenOfType from './hasChildrenOfType';
30
- import makeSorter, { type Sorter } from './sorter';
31
27
  import type { Props } from './common-types';
28
+ import { SORT_DIRECTION_TYPES } from './sort-types';
29
+ import BpkDataTableHeader from './BpkDataTableHeader';
30
+ import { getColumns } from './utils';
32
31
 
33
32
  const getClassName = cssModules(STYLES);
34
- const omittedTableProps = ['rowGetter', 'rowCount', 'onHeaderClick'];
35
33
 
36
- type State<Row> = {
37
- sorter: Sorter<Row>,
38
- rowSelected: ?number,
34
+ const KEYCODES = {
35
+ ENTER: 13,
36
+ SPACEBAR: 32,
39
37
  };
40
38
 
41
- class BpkDataTable<Row> extends Component<Props<Row>, State<Row>> {
42
- static defaultProps = {
43
- ...Table.defaultProps,
44
- width: null,
45
- headerHeight: 60,
46
- rowHeight: 60,
47
- gridStyle: { direction: undefined }, // This is required for rows to automatically respect rtl
48
- defaultColumnSortIndex: 0,
49
- sort: null,
50
- sortBy: null,
51
- sortDirection: null,
52
- };
53
-
54
- constructor(props: Props<Row>) {
55
- super();
56
-
57
- this.state = {
58
- sorter: makeSorter(props),
59
- rowSelected: undefined,
60
- };
61
- }
62
-
63
- UNSAFE_componentWillReceiveProps(nextProps: Props<Row>) {
64
- if (nextProps.rows !== this.props.rows) {
65
- this.state.sorter.propsChange(nextProps);
66
- }
67
- }
68
-
69
- onRowClicked = ({ index }: { index: number }) => {
70
- if (this.state.rowSelected === index) {
71
- this.setState({ rowSelected: undefined });
72
- } else {
73
- this.setState({ rowSelected: index });
74
- }
75
- if (this.props.onRowClick !== undefined) {
76
- this.props.onRowClick(this.state.sorter.getRow(index));
77
- }
39
+ const BpkDataTable = (props: Props) => {
40
+ const {
41
+ children,
42
+ className,
43
+ defaultColumnSortIndex,
44
+ height,
45
+ rows: data,
46
+ sort,
47
+ sortBy,
48
+ sortDirection,
49
+ width,
50
+ ...restOfProps
51
+ } = props;
52
+
53
+ const [rowSelected, updateRowSelected] = useState(undefined);
54
+
55
+ const classNames = getClassName('bpk-data-table', className);
56
+
57
+ const getRowClassNames = (
58
+ consumerClassName: ?string | ?(({ index: number }) => string),
59
+ index: number,
60
+ ) => {
61
+ const rowClassNames = getClassName(
62
+ 'bpk-data-table__row',
63
+ rowSelected === index && 'bpk-data-table__row--selected',
64
+ props.onRowClick !== undefined && 'bpk-data-table__row--clickable',
65
+ index === -1 && 'bpk-data-table__header-row',
66
+ consumerClassName &&
67
+ (typeof consumerClassName === 'function'
68
+ ? consumerClassName({ index })
69
+ : consumerClassName),
70
+ );
71
+ return rowClassNames;
78
72
  };
79
73
 
80
- onHeaderClick = ({
81
- dataKey: sortBy,
82
- event,
83
- }: {
84
- dataKey: string,
85
- event: SyntheticEvent<HTMLDivElement>,
86
- }) => {
87
- const column = React.Children.toArray(this.props.children).find(
88
- (child) => child.props.dataKey === sortBy,
74
+ const headerClassNames = getClassName(
75
+ 'bpk-data-table__row',
76
+ 'bpk-data-table__header-row',
77
+ props.headerClassName,
78
+ );
79
+
80
+ const columns = useMemo(() => getColumns(children), [children]);
81
+
82
+ const { getTableBodyProps, getTableProps, headerGroups, prepareRow, rows } =
83
+ useTable(
84
+ {
85
+ columns,
86
+ data,
87
+ initialState: {
88
+ sortBy: useMemo(
89
+ () => [
90
+ ...(sort
91
+ ? []
92
+ : [
93
+ {
94
+ id: columns[defaultColumnSortIndex].accessor,
95
+ desc:
96
+ columns[defaultColumnSortIndex].defaultSortDirection ===
97
+ 'DESC' || false,
98
+ },
99
+ ]),
100
+ ],
101
+ [defaultColumnSortIndex, columns, sort],
102
+ ),
103
+ },
104
+ },
105
+ useSortBy,
89
106
  );
90
107
 
91
- if (!column) {
92
- return;
93
- }
94
-
95
- if (column.props.disableSort === true) {
96
- return;
108
+ const onRowClicked = (index: number) => {
109
+ if (rowSelected === index) {
110
+ updateRowSelected(undefined);
111
+ } else {
112
+ updateRowSelected(index);
97
113
  }
98
-
99
- // See: https://reactjs.org/docs/legacy-event-pooling.html
100
- const eventTarget = event.target;
101
- if (eventTarget instanceof Element) {
102
- this.setState((prevState) => ({
103
- sorter: prevState.sorter.onHeaderClick(sortBy, eventTarget, column),
104
- }));
114
+ if (props.onRowClick !== undefined) {
115
+ props.onRowClick(rows[index].original);
105
116
  }
106
117
  };
107
118
 
108
- rowClassName = (
109
- consumerClassName: ?string | ?(({ index: number }) => string),
110
- { index }: { index: number },
119
+ const handleKeyboardEvent = (
120
+ event: React.KeyboardEvent<HTMLElement>,
121
+ i: number,
111
122
  ) => {
112
- const classNames = [getClassName('bpk-data-table__row')];
113
- if (this.state.rowSelected === index) {
114
- classNames.push(getClassName('bpk-data-table__row--selected'));
115
- }
116
- if (this.props.onRowClick !== undefined) {
117
- classNames.push(getClassName('bpk-data-table__row--clickable'));
118
- }
119
- if (index === -1) {
120
- classNames.push(getClassName('bpk-data-table__header-row'));
121
- }
122
- if (consumerClassName) {
123
- if (typeof consumerClassName === 'function') {
124
- classNames.push(consumerClassName({ index }));
125
- } else {
126
- classNames.push(consumerClassName);
127
- }
123
+ if (
124
+ event.keyCode === KEYCODES.ENTER ||
125
+ event.keyCode === KEYCODES.SPACEBAR
126
+ ) {
127
+ event.preventDefault();
128
+ onRowClicked(i);
128
129
  }
129
- return classNames;
130
130
  };
131
131
 
132
- renderTable(width: ?number) {
133
- const {
134
- children,
135
- className,
136
- headerClassName,
137
- rowClassName,
138
- sort,
139
- ...restOfProps
140
- } = this.props;
141
-
142
- const classNames = [getClassName('bpk-data-table')];
143
- if (className) {
144
- classNames.push(className);
145
- }
146
-
147
- const headerClassNames = [getClassName('bpk-data-table__header-column')];
148
- if (headerClassName) {
149
- headerClassNames.push(headerClassName);
150
- }
151
-
152
- return (
153
- // $FlowFixMe[cannot-spread-inexact]
154
- <Table
155
- {...restOfProps}
156
- className={classNames.join(' ')}
157
- width={width}
158
- rowCount={this.state.sorter.rowCount}
159
- rowGetter={({ index }) => this.state.sorter.getRow(index)}
160
- headerClassName={headerClassNames.join(' ')}
161
- rowClassName={(row) => this.rowClassName(rowClassName, row)}
162
- onRowClick={this.onRowClicked}
163
- onHeaderClick={this.onHeaderClick}
164
- {...this.state.sorter.sortProps}
165
- >
166
- {React.Children.map(children, BpkDataTableColumn.toColumn)}
167
- </Table>
168
- );
169
- }
170
-
171
- render() {
172
- if (this.props.width !== null) {
173
- return this.renderTable(this.props.width);
174
- }
175
-
176
- return (
177
- <AutoSizer disableHeight>
178
- {({ width }) => this.renderTable(width)}
179
- </AutoSizer>
180
- );
181
- }
182
- }
132
+ return (
133
+ <div
134
+ {...getTableProps({
135
+ style: { width, height },
136
+ className: classNames,
137
+ })}
138
+ {...restOfProps}
139
+ >
140
+ <div>
141
+ {headerGroups.map((headerGroup) => (
142
+ <div
143
+ {...headerGroup.getHeaderGroupProps({
144
+ style: { height: props.headerHeight },
145
+ className: headerClassNames,
146
+ })}
147
+ >
148
+ {headerGroup.headers.map((column) => {
149
+ if (sort && sortBy) {
150
+ if (column.id === sortBy) {
151
+ column.sortType = sort; // eslint-disable-line no-param-reassign
152
+ column.sortDirection = sortDirection; // eslint-disable-line no-param-reassign
153
+ }
154
+ }
155
+ return <BpkDataTableHeader key={column.id} column={column} />;
156
+ })}
157
+ </div>
158
+ ))}
159
+ </div>
160
+ <div {...getTableBodyProps()}>
161
+ {rows.map((row, i) => {
162
+ prepareRow(row);
163
+ const cellClassNames = [getClassName('bpk-data-table__cell')];
164
+ return (
165
+ <div
166
+ onClick={() => onRowClicked(i)}
167
+ role="button"
168
+ onKeyDown={(event) => handleKeyboardEvent(event, i)}
169
+ tabIndex={0}
170
+ {...row.getRowProps({
171
+ style: {
172
+ ...props.rowStyle,
173
+ height: props.rowHeight,
174
+ },
175
+ className: getRowClassNames(props.rowClassName, i),
176
+ })}
177
+ >
178
+ {row.cells.map((cell) => {
179
+ if (cell.column.className) {
180
+ cellClassNames.push(cell.column.className);
181
+ }
182
+ return (
183
+ <div
184
+ {...cell.getCellProps({
185
+ style: {
186
+ width: cell.column.width,
187
+ minWidth: cell.column.minWidth,
188
+ flexGrow: cell.column.flexGrow,
189
+ },
190
+ className: cellClassNames.join(' '),
191
+ })}
192
+ >
193
+ {cell.render('Cell')}
194
+ </div>
195
+ );
196
+ })}
197
+ </div>
198
+ );
199
+ })}
200
+ </div>
201
+ </div>
202
+ );
203
+ };
183
204
 
184
205
  BpkDataTable.propTypes = {
185
- ..._omit(Table.propTypes, omittedTableProps),
186
206
  rows: PropTypes.arrayOf(Object).isRequired,
187
- children: hasChildrenOfType(BpkDataTableColumn),
207
+ children: PropTypes.node.isRequired,
208
+ height: PropTypes.number.isRequired,
188
209
  width: PropTypes.number,
189
210
  headerHeight: PropTypes.number,
211
+ rowHeight: PropTypes.number,
190
212
  className: PropTypes.string,
191
213
  defaultColumnSortIndex: PropTypes.number,
192
214
  sort: PropTypes.func,
193
215
  sortBy: PropTypes.string,
194
- sortDirection: PropTypes.oneOf(['ASC', 'DESC']),
216
+ sortDirection: PropTypes.oneOf(Object.keys(SORT_DIRECTION_TYPES)),
217
+ };
218
+
219
+ BpkDataTable.defaultProps = {
220
+ width: null,
221
+ headerHeight: 60,
222
+ rowHeight: 60,
223
+ className: null,
224
+ defaultColumnSortIndex: 0,
225
+ sort: null,
226
+ sortBy: null,
227
+ sortDirection: SORT_DIRECTION_TYPES.ASC,
195
228
  };
196
229
 
197
230
  export default BpkDataTable;