@skyscanner/backpack-web 41.8.0 → 41.10.0-beta-v1

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 (129) hide show
  1. package/bpk-component-badge/src/BpkBadge.js +2 -1
  2. package/bpk-component-banner-alert/src/BpkBannerAlert.js +2 -0
  3. package/bpk-component-banner-alert/src/BpkBannerAlertDismissable.js +2 -0
  4. package/bpk-component-banner-alert/src/BpkBannerAlertExpandable.js +2 -0
  5. package/bpk-component-blockquote/src/BpkBlockquote.js +2 -1
  6. package/bpk-component-boilerplate/src/BpkBoilerplate.js +2 -1
  7. package/bpk-component-bottom-sheet/src/BpkBottomSheet.js +2 -1
  8. package/bpk-component-breadcrumb/src/BpkBreadcrumb.js +2 -1
  9. package/bpk-component-breadcrumb/src/BpkBreadcrumbItem.js +2 -1
  10. package/bpk-component-button/src/BpkButtonV2/BpkButton.js +3 -1
  11. package/bpk-component-card/src/BpkCard.js +4 -1
  12. package/bpk-component-card/src/BpkCardWrapper.js +2 -1
  13. package/bpk-component-card/src/BpkDividedCard.js +2 -1
  14. package/bpk-component-card-button/src/BpkSaveButton.js +2 -1
  15. package/bpk-component-card-list/src/BpkCardList.js +2 -1
  16. package/bpk-component-card-list/src/BpkCardListGridStack/BpkCardListGridStack.js +2 -1
  17. package/bpk-component-card-list/src/BpkCardListRowRail/BpkCardListCarousel.js +13 -8
  18. package/bpk-component-card-list/src/BpkCardListRowRail/BpkCardListCarousel.module.css +1 -1
  19. package/bpk-component-card-list/src/BpkCardListRowRail/BpkCardListRowRailContainer.js +2 -1
  20. package/bpk-component-carousel/src/BpkCarousel.js +2 -1
  21. package/bpk-component-carousel/src/BpkCarouselContainer.js +3 -1
  22. package/bpk-component-carousel/src/BpkCarouselImage.js +2 -1
  23. package/bpk-component-checkbox/src/BpkCheckbox.js +2 -1
  24. package/bpk-component-close-button/src/BpkCloseButton.js +2 -1
  25. package/bpk-component-code/src/BpkCode.js +2 -1
  26. package/bpk-component-code/src/BpkCodeBlock.js +2 -1
  27. package/bpk-component-content-cards/src/BpkContentCard.js +2 -1
  28. package/bpk-component-content-cards/src/BpkContentCards.js +2 -1
  29. package/bpk-component-datatable/src/BpkDataTable.js +2 -1
  30. package/bpk-component-datatable/src/BpkDataTableHeader.js +2 -1
  31. package/bpk-component-datepicker/src/BpkDatepicker.js +2 -1
  32. package/bpk-component-description-list/src/BpkDescriptionDetails.js +2 -1
  33. package/bpk-component-description-list/src/BpkDescriptionList.js +2 -1
  34. package/bpk-component-description-list/src/BpkDescriptionTerm.js +2 -1
  35. package/bpk-component-dialog/src/BpkDialog.js +2 -1
  36. package/bpk-component-drawer/src/BpkDrawer.js +2 -1
  37. package/bpk-component-fieldset/src/BpkFieldset.js +2 -1
  38. package/bpk-component-floating-notification/src/BpkFloatingNotification.js +2 -1
  39. package/bpk-component-graphic-promotion/src/BpkGraphicPromo.js +2 -1
  40. package/bpk-component-image/src/BpkBackgroundImage.js +2 -1
  41. package/bpk-component-image/src/BpkImage.js +2 -1
  42. package/bpk-component-info-banner/src/BpkInfoBanner.js +2 -0
  43. package/bpk-component-info-banner/src/BpkInfoBannerDismissable.js +2 -0
  44. package/bpk-component-info-banner/src/BpkInfoBannerExpandable.js +2 -0
  45. package/bpk-component-input/src/BpkInput.js +2 -1
  46. package/bpk-component-inset-banner/src/BpkInsetBanner.js +2 -1
  47. package/bpk-component-inset-banner/src/BpkInsetBannerV2/BpkInsetBannerSponsored.js +2 -1
  48. package/bpk-component-journey-arrow/src/BpkJourneyArrow.js +2 -1
  49. package/bpk-component-label/src/BpkLabel.js +2 -1
  50. package/bpk-component-layout/index.d.ts +18 -0
  51. package/bpk-component-layout/index.js +29 -0
  52. package/bpk-component-layout/src/BpkBox.d.ts +3 -0
  53. package/bpk-component-layout/src/BpkBox.js +33 -0
  54. package/bpk-component-layout/src/BpkFlex.d.ts +3 -0
  55. package/bpk-component-layout/src/BpkFlex.js +51 -0
  56. package/bpk-component-layout/src/BpkGrid.d.ts +3 -0
  57. package/bpk-component-layout/src/BpkGrid.js +57 -0
  58. package/bpk-component-layout/src/BpkGridItem.d.ts +3 -0
  59. package/bpk-component-layout/src/BpkGridItem.js +45 -0
  60. package/bpk-component-layout/src/BpkProvider.d.ts +14 -0
  61. package/bpk-component-layout/src/BpkProvider.js +42 -0
  62. package/bpk-component-layout/src/BpkStack.constant.d.ts +2 -0
  63. package/bpk-component-layout/src/BpkStack.constant.js +22 -0
  64. package/bpk-component-layout/src/BpkStack.d.ts +5 -0
  65. package/bpk-component-layout/src/BpkStack.js +57 -0
  66. package/bpk-component-layout/src/BpkVessel.d.ts +46 -0
  67. package/bpk-component-layout/src/BpkVessel.js +70 -0
  68. package/bpk-component-layout/src/commonProps.d.ts +86 -0
  69. package/bpk-component-layout/src/commonProps.js +1 -0
  70. package/bpk-component-layout/src/theme.d.ts +36 -0
  71. package/bpk-component-layout/src/theme.js +229 -0
  72. package/bpk-component-layout/src/tokenUtils.d.ts +108 -0
  73. package/bpk-component-layout/src/tokenUtils.js +323 -0
  74. package/bpk-component-layout/src/tokens.d.ts +96 -0
  75. package/bpk-component-layout/src/tokens.js +138 -0
  76. package/bpk-component-layout/src/types.d.ts +236 -0
  77. package/bpk-component-layout/src/types.js +1 -0
  78. package/bpk-component-link/src/BpkButtonLink.js +2 -1
  79. package/bpk-component-link/src/BpkLink.js +2 -1
  80. package/bpk-component-list/index.d.ts +5 -0
  81. package/bpk-component-list/index.js +3 -1
  82. package/bpk-component-list/src/BpkList.d.ts +11 -0
  83. package/bpk-component-list/src/BpkList.js +10 -15
  84. package/bpk-component-list/src/BpkListItem.d.ts +7 -0
  85. package/bpk-component-list/src/BpkListItem.js +2 -5
  86. package/bpk-component-loading-button/src/BpkLoadingButton.js +2 -1
  87. package/bpk-component-mobile-scroll-container/src/BpkMobileScrollContainer.js +2 -1
  88. package/bpk-component-modal/src/BpkModal.js +2 -1
  89. package/bpk-component-modal/src/BpkModalV2/BpkModal.js +2 -1
  90. package/bpk-component-navigation-bar/src/BpkNavigationBar.js +2 -1
  91. package/bpk-component-navigation-bar/src/BpkNavigationBarButtonLink.js +2 -0
  92. package/bpk-component-navigation-bar/src/BpkNavigationBarIconButton.js +2 -0
  93. package/bpk-component-navigation-tab-group/src/BpkNavigationTabGroup.js +2 -1
  94. package/bpk-component-nudger/src/BpkNudger.js +2 -1
  95. package/bpk-component-overlay/src/BpkOverlay.js +2 -1
  96. package/bpk-component-page-indicator/src/BpkPageIndicator.js +2 -1
  97. package/bpk-component-panel/src/BpkPanel.js +2 -1
  98. package/bpk-component-popover/src/BpkPopover.js +2 -1
  99. package/bpk-component-price-range/index.d.ts +2 -3
  100. package/bpk-component-price-range/index.js +2 -2
  101. package/bpk-component-price-range/src/BpkPriceRange.d.ts +14 -6
  102. package/bpk-component-price-range/src/BpkPriceRange.js +34 -14
  103. package/bpk-component-price-range/src/common-types.d.ts +5 -0
  104. package/bpk-component-price-range/src/common-types.js +4 -0
  105. package/bpk-component-rating/src/BpkRating.js +2 -1
  106. package/bpk-component-rtl-toggle/src/BpkRtlToggle.js +2 -0
  107. package/bpk-component-section-header/src/BpkSectionHeader.js +2 -1
  108. package/bpk-component-segmented-control/src/BpkSegmentedControl.js +2 -1
  109. package/bpk-component-skeleton/src/BpkBaseSkeleton.js +2 -1
  110. package/bpk-component-slider/src/BpkSlider.js +2 -1
  111. package/bpk-component-snippet/src/BpkSnippet.js +2 -1
  112. package/bpk-component-spinner/src/BpkExtraLargeSpinner.js +2 -1
  113. package/bpk-component-spinner/src/BpkLargeSpinner.js +2 -1
  114. package/bpk-component-spinner/src/BpkSpinner.js +2 -1
  115. package/bpk-component-split-input/src/BpkInputField.js +2 -1
  116. package/bpk-component-split-input/src/BpkSplitInput.js +2 -1
  117. package/bpk-component-swap-button/src/BpkSwapButton.js +2 -1
  118. package/bpk-component-switch/src/BpkSwitch.js +2 -1
  119. package/bpk-component-text/src/BpkText.js +2 -1
  120. package/bpk-component-textarea/src/BpkTextarea.js +2 -1
  121. package/bpk-component-theme-toggle/src/BpkThemeToggle.js +2 -0
  122. package/bpk-component-visually-hidden/src/BpkVisuallyHidden.js +2 -1
  123. package/bpk-react-utils/index.d.ts +5 -1
  124. package/bpk-react-utils/index.js +4 -2
  125. package/bpk-react-utils/src/BpkDialogWrapper/BpkDialogWrapper.js +2 -0
  126. package/bpk-react-utils/src/getDataComponentAttribute.d.ts +20 -0
  127. package/bpk-react-utils/src/getDataComponentAttribute.js +38 -0
  128. package/bpk-scrim-utils/src/BpkScrim.js +2 -1
  129. package/package.json +2 -1
@@ -1,16 +1,24 @@
1
- type Marker = {
1
+ import type { MarkerDisplayType } from './common-types';
2
+ type PriceRangePosition = {
2
3
  price: string;
3
4
  percentage: number;
4
5
  };
5
- export type Props = {
6
+ type MarkerPriceRangePosition = PriceRangePosition & {
7
+ type?: MarkerDisplayType;
8
+ };
9
+ export type BpkPriceRangeProps = {
6
10
  min?: number;
7
11
  max?: number;
12
+ /**
13
+ * @deprecated Use `marker.type` with `MARKER_DISPLAY_TYPES.DOT` instead to hide boundary prices.
14
+ * This prop will be removed in a future major release.
15
+ */
8
16
  showPriceIndicator?: boolean;
9
- marker: Marker;
17
+ marker?: MarkerPriceRangePosition;
10
18
  segments: {
11
- low: Marker;
12
- high: Marker;
19
+ low: PriceRangePosition;
20
+ high: PriceRangePosition;
13
21
  };
14
22
  };
15
- declare const BpkPriceRange: ({ marker, max, min, segments, showPriceIndicator, }: Props) => import("react/jsx-runtime").JSX.Element;
23
+ declare const BpkPriceRange: ({ marker, max, min, segments, showPriceIndicator, }: BpkPriceRangeProps) => import("react/jsx-runtime").JSX.Element;
16
24
  export default BpkPriceRange;
@@ -21,27 +21,39 @@ import clamp from 'lodash/clamp';
21
21
  import BpkText, { TEXT_STYLES } from "../../bpk-component-text/src/BpkText";
22
22
  import { cssModules } from "../../bpk-react-utils";
23
23
  import BpkPriceMarker from "./BpkPriceMarker";
24
- import { MARKER_TYPES } from "./common-types";
24
+ import { MARKER_DISPLAY_TYPES, MARKER_TYPES } from "./common-types";
25
25
  import STYLES from "./BpkPriceRange.module.css";
26
26
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
27
27
  const getClassName = cssModules(STYLES);
28
+ const getShouldShowPriceOnBoundaries = (markerType, showPriceIndicator) => {
29
+ switch (markerType) {
30
+ case MARKER_DISPLAY_TYPES.DOT:
31
+ return false;
32
+ case MARKER_DISPLAY_TYPES.BUBBLE:
33
+ return true;
34
+ case undefined:
35
+ default:
36
+ // TODO: LUNA-3184 return `true` when deprecating `showPriceIndicator`
37
+ return showPriceIndicator ?? true;
38
+ }
39
+ };
28
40
  const BpkPriceRange = ({
29
41
  marker,
30
42
  max = 100,
31
43
  min = 0,
32
44
  segments,
33
- showPriceIndicator = true
45
+ showPriceIndicator
34
46
  }) => {
47
+ const shouldShowPriceOnBoundaries = getShouldShowPriceOnBoundaries(marker?.type, showPriceIndicator);
35
48
  const linesRef = useRef(null);
36
49
  const indicatorRef = useRef(null);
37
50
  const [linesWidth, setLinesWidth] = useState(0);
38
51
  const [prefilledWidth, setPrefilledWidth] = useState(0);
39
52
  const calcPercentage = current => (clamp(current, min, max) - min) / (max - min);
40
- const indicatorPercent = calcPercentage(marker.percentage);
41
53
  let type;
42
- if (marker.percentage < segments.low.percentage) {
54
+ if (marker && marker.percentage < segments.low.percentage) {
43
55
  type = MARKER_TYPES.LOW;
44
- } else if (marker.percentage > segments.high.percentage) {
56
+ } else if (marker && marker.percentage > segments.high.percentage) {
45
57
  type = MARKER_TYPES.HIGH;
46
58
  } else {
47
59
  type = MARKER_TYPES.MEDIUM;
@@ -62,17 +74,25 @@ const BpkPriceRange = ({
62
74
  }, []);
63
75
  useEffect(() => {
64
76
  // to calculate the spacing ahead of the price indicator
65
- if (indicatorRef.current && linesWidth) {
77
+ if (marker && indicatorRef.current && linesWidth) {
78
+ const indicatorPercent = calcPercentage(marker.percentage);
66
79
  const estimatedWidth = indicatorPercent * linesWidth - indicatorRef.current.scrollWidth / 2;
67
80
  const maxPrefilledWidth = linesWidth - indicatorRef.current.scrollWidth;
68
81
  const actualPrefilledWidth = clamp(estimatedWidth, 0, maxPrefilledWidth);
69
82
  setPrefilledWidth(actualPrefilledWidth);
70
83
  }
71
- }, [indicatorPercent, linesWidth]);
72
- const linesClassName = getClassName('bpk-price-range__lines', showPriceIndicator && 'bpk-price-range__lines--large');
73
- const lowClassName = getClassName('bpk-price-range__line--low', showPriceIndicator && 'bpk-price-range__line--lowLarge');
74
- const highClassName = getClassName('bpk-price-range__line--high', showPriceIndicator && 'bpk-price-range__line--highLarge');
84
+ }, [marker?.percentage, linesWidth]);
85
+ const linesClassName = getClassName('bpk-price-range__lines', shouldShowPriceOnBoundaries && 'bpk-price-range__lines--large');
86
+ const lowClassName = getClassName('bpk-price-range__line--low', shouldShowPriceOnBoundaries && 'bpk-price-range__line--lowLarge');
87
+ const highClassName = getClassName('bpk-price-range__line--high', shouldShowPriceOnBoundaries && 'bpk-price-range__line--highLarge');
75
88
  const mediumClassName = getClassName('bpk-price-range__line--medium');
89
+
90
+ // TODO: LUNA-3184 set default to BUBBLE when deprecating `showPriceIndicator`
91
+ const defaultMarkerType = showPriceIndicator ?? true ? MARKER_DISPLAY_TYPES.BUBBLE : MARKER_DISPLAY_TYPES.DOT;
92
+ const markerType = marker?.type || defaultMarkerType;
93
+ const shouldShowMarker = !!marker;
94
+ const shouldShowBubble = shouldShowMarker && markerType === MARKER_DISPLAY_TYPES.BUBBLE;
95
+ const shouldShowDot = shouldShowMarker && markerType === MARKER_DISPLAY_TYPES.DOT;
76
96
  const dotClassName = getClassName(`bpk-price-range__line--${type}`, 'bpk-price-range__line--dot');
77
97
  return /*#__PURE__*/_jsxs("div", {
78
98
  style: {
@@ -80,9 +100,9 @@ const BpkPriceRange = ({
80
100
  '--high': calcPercentage(segments.high.percentage),
81
101
  '--prefilled-width': `${prefilledWidth}px`
82
102
  },
83
- className: getClassName('bpk-price-range', showPriceIndicator && 'bpk-price-range--large'),
103
+ className: getClassName('bpk-price-range', shouldShowPriceOnBoundaries && 'bpk-price-range--large'),
84
104
  ref: linesRef,
85
- children: [showPriceIndicator && /*#__PURE__*/_jsx("div", {
105
+ children: [shouldShowBubble && /*#__PURE__*/_jsx("div", {
86
106
  className: getClassName('bpk-price-range__marker'),
87
107
  children: /*#__PURE__*/_jsx(BpkPriceMarker, {
88
108
  ref: indicatorRef,
@@ -97,11 +117,11 @@ const BpkPriceRange = ({
97
117
  className: mediumClassName
98
118
  }), /*#__PURE__*/_jsx("div", {
99
119
  className: highClassName
100
- }), !showPriceIndicator && /*#__PURE__*/_jsx("div", {
120
+ }), shouldShowDot && /*#__PURE__*/_jsx("div", {
101
121
  className: dotClassName,
102
122
  ref: indicatorRef
103
123
  })]
104
- }), showPriceIndicator && /*#__PURE__*/_jsxs("div", {
124
+ }), shouldShowPriceOnBoundaries && /*#__PURE__*/_jsxs("div", {
105
125
  className: getClassName('bpk-price-range__ranges'),
106
126
  children: [/*#__PURE__*/_jsx(BpkText, {
107
127
  textStyle: TEXT_STYLES.footnote,
@@ -4,3 +4,8 @@ export declare const MARKER_TYPES: {
4
4
  readonly HIGH: "high";
5
5
  };
6
6
  export type MarkerType = (typeof MARKER_TYPES)[keyof typeof MARKER_TYPES];
7
+ export declare const MARKER_DISPLAY_TYPES: {
8
+ readonly BUBBLE: "bubble";
9
+ readonly DOT: "dot";
10
+ };
11
+ export type MarkerDisplayType = (typeof MARKER_DISPLAY_TYPES)[keyof typeof MARKER_DISPLAY_TYPES];
@@ -20,4 +20,8 @@ export const MARKER_TYPES = {
20
20
  LOW: 'low',
21
21
  MEDIUM: 'medium',
22
22
  HIGH: 'high'
23
+ };
24
+ export const MARKER_DISPLAY_TYPES = {
25
+ BUBBLE: 'bubble',
26
+ DOT: 'dot'
23
27
  };
@@ -18,7 +18,7 @@
18
18
 
19
19
  import clamp from 'lodash.clamp';
20
20
  import BpkText, { TEXT_STYLES } from "../../bpk-component-text";
21
- import { cssModules } from "../../bpk-react-utils";
21
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
22
22
  import { RATING_SIZES, RATING_SCALES } from "./common-types";
23
23
  import STYLES from "./BpkRating.module.css";
24
24
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -73,6 +73,7 @@ const BpkRating = ({
73
73
  }
74
74
  return /*#__PURE__*/_jsxs("div", {
75
75
  className: classNames,
76
+ ...getDataComponentAttribute('Rating'),
76
77
  "aria-label": ariaLabel,
77
78
  role: "figure",
78
79
  ...rest,
@@ -18,6 +18,7 @@
18
18
 
19
19
  import { Component } from 'react';
20
20
  import BpkLink from "../../bpk-component-link";
21
+ import { getDataComponentAttribute } from "../../bpk-react-utils";
21
22
  import { getHtmlElement, DIRECTIONS, DIRECTION_CHANGE_EVENT } from "./utils";
22
23
  import { jsxs as _jsxs } from "react/jsx-runtime";
23
24
  const getDirection = () => {
@@ -63,6 +64,7 @@ class BpkRtlToggle extends Component {
63
64
  as: "button",
64
65
  title: "Keyboard Shortcut: ctrl + cmd + r",
65
66
  onClick: this.toggleRtl,
67
+ ...getDataComponentAttribute('RtlToggle'),
66
68
  children: ["RTL ", onOrOff]
67
69
  });
68
70
  }
@@ -17,7 +17,7 @@
17
17
  */
18
18
 
19
19
  import BpkText from "../../bpk-component-text";
20
- import { cssModules } from "../../bpk-react-utils";
20
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
21
21
  import STYLES from "./BpkSectionHeader.module.css";
22
22
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
23
23
  const getClassName = cssModules(STYLES);
@@ -32,6 +32,7 @@ const BpkSectionHeader = ({
32
32
  type = SECTION_TYPES.default
33
33
  }) => /*#__PURE__*/_jsxs("div", {
34
34
  className: getClassName('bpk-section-header'),
35
+ ...getDataComponentAttribute('SectionHeader'),
35
36
  children: [/*#__PURE__*/_jsxs("div", {
36
37
  className: getClassName('bpk-section-header__title-description', `bpk-section-header__title-description--${type}`),
37
38
  children: [/*#__PURE__*/_jsx("h2", {
@@ -17,7 +17,7 @@
17
17
  */
18
18
 
19
19
  import { useId, useMemo, useRef, useState } from 'react';
20
- import { cssModules, isRTL } from "../../bpk-react-utils";
20
+ import { cssModules, isRTL, getDataComponentAttribute } from "../../bpk-react-utils";
21
21
  import STYLES from "./BpkSegmentedControl.module.css";
22
22
  import { jsx as _jsx } from "react/jsx-runtime";
23
23
  const getClassName = cssModules(STYLES);
@@ -166,6 +166,7 @@ const BpkSegmentedControl = ({
166
166
  const containerStyling = getClassName('bpk-segmented-control-group', shadow && 'bpk-segmented-control-group-shadow');
167
167
  return /*#__PURE__*/_jsx("div", {
168
168
  className: containerStyling,
169
+ ...getDataComponentAttribute('SegmentedControl'),
169
170
  ...getContainerAriaProps(providedId, label),
170
171
  children: buttonContents.map((content, index) => {
171
172
  const isSelected = index === selectedButton;
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import STYLES from "./BpkBaseSkeleton.module.css";
21
21
  import { jsx as _jsx } from "react/jsx-runtime";
22
22
  const getClassName = cssModules(STYLES);
@@ -25,6 +25,7 @@ const BpkBaseSkeleton = ({
25
25
  styleObj = undefined
26
26
  }) => /*#__PURE__*/_jsx("div", {
27
27
  className: getClassName('bpk-skeleton', skeletonStyle),
28
+ ...getDataComponentAttribute('BaseSkeleton'),
28
29
  style: styleObj
29
30
  });
30
31
  export default BpkBaseSkeleton;
@@ -18,7 +18,7 @@
18
18
  import { forwardRef, useRef, useEffect, useCallback } from 'react';
19
19
  import { useComposedRefs } from '@radix-ui/react-compose-refs';
20
20
  import * as Slider from '@radix-ui/react-slider';
21
- import { cssModules, isRTL, setNativeValue } from "../../bpk-react-utils";
21
+ import { cssModules, isRTL, setNativeValue, getDataComponentAttribute } from "../../bpk-react-utils";
22
22
  import STYLES from "./BpkSlider.module.css";
23
23
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
24
  const getClassName = cssModules(STYLES);
@@ -114,6 +114,7 @@ const BpkSlider = ({
114
114
  }, []);
115
115
  return /*#__PURE__*/_jsxs(Slider.Root, {
116
116
  className: getClassName('bpk-slider'),
117
+ ...getDataComponentAttribute('Slider'),
117
118
  defaultValue: currentValue,
118
119
  min: min,
119
120
  max: max,
@@ -20,7 +20,7 @@ import BpkBreakpoint, { BREAKPOINTS } from "../../bpk-component-breakpoint";
20
20
  import BpkButton, { BUTTON_TYPES } from "../../bpk-component-button";
21
21
  import BpkImage, { BORDER_RADIUS_STYLES, withLazyLoading } from "../../bpk-component-image";
22
22
  import BpkText, { TEXT_STYLES } from "../../bpk-component-text/src/BpkText";
23
- import { cssModules } from "../../bpk-react-utils";
23
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
24
24
  import STYLES from "./BpkSnippet.module.css";
25
25
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
26
26
  const getClassName = cssModules(STYLES);
@@ -92,6 +92,7 @@ const BpkSnippet = ({
92
92
  query: BREAKPOINTS.MOBILE,
93
93
  children: isMobile => /*#__PURE__*/_jsxs("div", {
94
94
  className: getClassName('bpk-snippet', desktopLayout === 'imageRight' && 'bpk-snippet--row-reverse', desktopLayout === 'vertical' && 'bpk-snippet--vertical'),
95
+ ...getDataComponentAttribute('Snippet'),
95
96
  children: [/*#__PURE__*/_jsx("div", {
96
97
  className: getClassName('bpk-snippet--image', desktopLayout === 'vertical' ? 'bpk-snippet--vertical--container' : 'bpk-snippet--container'),
97
98
  children: /*#__PURE__*/_jsx(LazyLoadedImage, {
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import SPINNER_TYPES from "./spinnerTypes";
21
21
  import XlSpinner from "./spinners/xl";
22
22
  import STYLES from "./BpkSpinner.module.css";
@@ -30,6 +30,7 @@ const BpkExtraLargeSpinner = ({
30
30
  const classNames = getClassName('bpk-spinner', 'bpk-spinner--extra-large', `bpk-spinner--${type}`, className);
31
31
  return /*#__PURE__*/_jsx("span", {
32
32
  className: classNames,
33
+ ...getDataComponentAttribute('ExtraLargeSpinner'),
33
34
  children: /*#__PURE__*/_jsx(XlSpinner, {
34
35
  ...rest
35
36
  })
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import SPINNER_TYPES from "./spinnerTypes";
21
21
  import LgSpinner from "./spinners/lg";
22
22
  import STYLES from "./BpkSpinner.module.css";
@@ -31,6 +31,7 @@ const BpkLargeSpinner = ({
31
31
  const classNames = getClassName('bpk-spinner', 'bpk-spinner--large', `bpk-spinner--${type}`, alignToButton && 'bpk-spinner--align-to-large-button', className);
32
32
  return /*#__PURE__*/_jsx("span", {
33
33
  className: classNames,
34
+ ...getDataComponentAttribute('LargeSpinner'),
34
35
  children: /*#__PURE__*/_jsx(LgSpinner, {
35
36
  ...rest
36
37
  })
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import SPINNER_TYPES from "./spinnerTypes";
21
21
  import SmSpinner from "./spinners/sm";
22
22
  import STYLES from "./BpkSpinner.module.css";
@@ -31,6 +31,7 @@ const BpkSpinner = ({
31
31
  const classNames = getClassName('bpk-spinner', `bpk-spinner--${type}`, alignToButton && 'bpk-spinner--align-to-button', className);
32
32
  return /*#__PURE__*/_jsx("span", {
33
33
  className: classNames,
34
+ ...getDataComponentAttribute('Spinner'),
34
35
  children: /*#__PURE__*/_jsx(SmSpinner, {
35
36
  ...rest
36
37
  })
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { PureComponent } from 'react';
20
20
  import BpkInput from "../../bpk-component-input";
21
- import { cssModules } from "../../bpk-react-utils";
21
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
22
22
  import STYLES from "./BpkInputField.module.css";
23
23
  import { jsx as _jsx } from "react/jsx-runtime";
24
24
  const getClassName = cssModules(STYLES);
@@ -49,6 +49,7 @@ class BpkInputField extends PureComponent {
49
49
  } = this.props;
50
50
  return /*#__PURE__*/_jsx("div", {
51
51
  className: getClassName('bpk-input-field'),
52
+ ...getDataComponentAttribute('InputField'),
52
53
  children: /*#__PURE__*/_jsx(BpkInput, {
53
54
  id: id,
54
55
  autoComplete: "off",
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { Component } from 'react';
20
20
  import { INPUT_TYPES } from "../../bpk-component-input";
21
- import { cssModules } from "../../bpk-react-utils";
21
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
22
22
  import InputField from "./BpkInputField";
23
23
  import STYLES from "./BpkSplitInput.module.css";
24
24
  import { jsx as _jsx } from "react/jsx-runtime";
@@ -203,6 +203,7 @@ class BpkSplitInput extends Component {
203
203
  render() {
204
204
  return /*#__PURE__*/_jsx("div", {
205
205
  className: getClassName('bpk-split-input'),
206
+ ...getDataComponentAttribute('SplitInput'),
206
207
  children: this.renderInputs()
207
208
  });
208
209
  }
@@ -18,7 +18,7 @@
18
18
 
19
19
  import { useState } from 'react';
20
20
  import SwapVertical from "../../bpk-component-icon/sm/swap--vertical";
21
- import { cssModules } from "../../bpk-react-utils";
21
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
22
22
  import STYLES from "./BpkSwapButton.module.css";
23
23
  import { jsx as _jsx } from "react/jsx-runtime";
24
24
  const getClassName = cssModules(STYLES);
@@ -43,6 +43,7 @@ const BpkSwapButton = props => {
43
43
  };
44
44
  return /*#__PURE__*/_jsx("div", {
45
45
  className: getClassName('bpk-swap-button'),
46
+ ...getDataComponentAttribute('SwapButton'),
46
47
  children: /*#__PURE__*/_jsx("button", {
47
48
  type: "button",
48
49
  className: getClassName('bpk-swap-button__button', `bpk-swap-button__button--${swapButtonStyle}`),
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import STYLES from "./BpkSwitch.module.css";
21
21
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
22
22
  const getClassName = cssModules(STYLES);
@@ -29,6 +29,7 @@ const BpkSwitch = ({
29
29
  const switchClassNames = getClassName('bpk-switch__switch', small && 'bpk-switch__switch--small');
30
30
  return /*#__PURE__*/_jsxs("label", {
31
31
  className: getClassName('bpk-switch', className),
32
+ ...getDataComponentAttribute('Switch'),
32
33
  children: [/*#__PURE__*/_jsx("input", {
33
34
  type: "checkbox",
34
35
  className: getClassName('bpk-switch__checkbox'),
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import STYLES from "./BpkText.module.css";
21
21
  import { jsx as _jsx } from "react/jsx-runtime";
22
22
  const getClassName = cssModules(STYLES);
@@ -81,6 +81,7 @@ const BpkText = ({
81
81
  // eslint-disable-next-line @skyscanner/rules/forbid-component-props
82
82
  _jsx(TagName, {
83
83
  className: classNames,
84
+ ...getDataComponentAttribute('Text'),
84
85
  ...rest,
85
86
  children: children
86
87
  })
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import STYLES from "./BpkTextarea.module.css";
21
21
  import { jsx as _jsx } from "react/jsx-runtime";
22
22
  const getClassName = cssModules(STYLES);
@@ -31,6 +31,7 @@ const BpkTextarea = ({
31
31
  const isInvalid = valid === false;
32
32
  return /*#__PURE__*/_jsx("textarea", {
33
33
  className: getClassName('bpk-textarea', isInvalid && 'bpk-textarea--invalid', large && 'bpk-textarea--large', className),
34
+ ...getDataComponentAttribute('Textarea'),
34
35
  "aria-invalid": isInvalid,
35
36
  ...rest
36
37
  });
@@ -21,6 +21,7 @@ import BpkLabel from "../../bpk-component-label";
21
21
  // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
22
22
  import BpkSelect from "../../bpk-component-select";
23
23
  import BpkVisuallyHidden from "../../bpk-component-visually-hidden";
24
+ import { getDataComponentAttribute } from "../../bpk-react-utils";
24
25
  import bpkCustomThemes from "./theming";
25
26
  import { getHtmlElement, THEME_CHANGE_EVENT } from "./utils";
26
27
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
@@ -81,6 +82,7 @@ class BpkThemeToggle extends Component {
81
82
  ...rest
82
83
  } = this.props;
83
84
  return /*#__PURE__*/_jsxs("div", {
85
+ ...getDataComponentAttribute('ThemeToggle'),
84
86
  ...rest,
85
87
  children: [/*#__PURE__*/_jsx(BpkVisuallyHidden, {
86
88
  children: /*#__PURE__*/_jsx(BpkLabel, {
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { cssModules } from "../../bpk-react-utils";
19
+ import { cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import STYLES from "./BpkVisuallyHidden.module.css";
21
21
  import { jsx as _jsx } from "react/jsx-runtime";
22
22
  const getClassName = cssModules(STYLES);
@@ -31,6 +31,7 @@ const BpkVisuallyHidden = ({
31
31
  // eslint-disable-next-line @skyscanner/rules/forbid-component-props
32
32
  _jsx(Element, {
33
33
  className: classNames,
34
+ ...getDataComponentAttribute('VisuallyHidden'),
34
35
  children: children
35
36
  })
36
37
  );
@@ -4,11 +4,12 @@ import TransitionInitialMount from './src/TransitionInitialMount';
4
4
  import cssModules from './src/cssModules';
5
5
  import deprecated from './src/deprecated';
6
6
  import { isDeviceIphone, isDeviceIpad, isDeviceIos } from './src/deviceDetection';
7
+ import { getDataComponentAttribute } from './src/getDataComponentAttribute';
7
8
  import isRTL from './src/isRTL';
8
9
  import { setNativeValue } from './src/nativeEventHandler';
9
10
  import withDefaultProps from './src/withDefaultProps';
10
11
  import wrapDisplayName from './src/wrapDisplayName';
11
- export { Portal, TransitionInitialMount, cssModules, deprecated, withDefaultProps, wrapDisplayName, isDeviceIphone, isDeviceIpad, isDeviceIos, isRTL, BpkDialogWrapper, setNativeValue, };
12
+ export { Portal, TransitionInitialMount, cssModules, deprecated, withDefaultProps, wrapDisplayName, isDeviceIphone, isDeviceIpad, isDeviceIos, isRTL, BpkDialogWrapper, setNativeValue, getDataComponentAttribute, };
12
13
  declare const _default: {
13
14
  Portal: typeof Portal;
14
15
  TransitionInitialMount: ({ appearActiveClassName, appearClassName, children, transitionTimeout, }: {
@@ -39,5 +40,8 @@ declare const _default: {
39
40
  isRTL: () => boolean;
40
41
  BpkDialogWrapper: ({ children, closeOnEscPressed, closeOnScrimClick, dialogClassName, exiting, id, isOpen, onClose, timeout, transitionClassNames, ...ariaProps }: import("./src/BpkDialogWrapper/BpkDialogWrapper").Props) => import("react/jsx-runtime").JSX.Element | null;
41
42
  setNativeValue: typeof setNativeValue;
43
+ getDataComponentAttribute: (componentName: string) => {
44
+ "data-backpack-ds-component": string;
45
+ };
42
46
  };
43
47
  export default _default;
@@ -23,11 +23,12 @@ import cssModules from "./src/cssModules";
23
23
  // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
24
24
  import deprecated from "./src/deprecated";
25
25
  import { isDeviceIphone, isDeviceIpad, isDeviceIos } from "./src/deviceDetection";
26
+ import { getDataComponentAttribute } from "./src/getDataComponentAttribute";
26
27
  import isRTL from "./src/isRTL";
27
28
  import { setNativeValue } from "./src/nativeEventHandler";
28
29
  import withDefaultProps from "./src/withDefaultProps";
29
30
  import wrapDisplayName from "./src/wrapDisplayName";
30
- export { Portal, TransitionInitialMount, cssModules, deprecated, withDefaultProps, wrapDisplayName, isDeviceIphone, isDeviceIpad, isDeviceIos, isRTL, BpkDialogWrapper, setNativeValue };
31
+ export { Portal, TransitionInitialMount, cssModules, deprecated, withDefaultProps, wrapDisplayName, isDeviceIphone, isDeviceIpad, isDeviceIos, isRTL, BpkDialogWrapper, setNativeValue, getDataComponentAttribute };
31
32
  export default {
32
33
  Portal,
33
34
  TransitionInitialMount,
@@ -40,5 +41,6 @@ export default {
40
41
  isDeviceIos,
41
42
  isRTL,
42
43
  BpkDialogWrapper,
43
- setNativeValue
44
+ setNativeValue,
45
+ getDataComponentAttribute
44
46
  };
@@ -19,6 +19,7 @@
19
19
  import { useEffect, useRef, useState } from 'react';
20
20
  import CSSTransition from 'react-transition-group/CSSTransition';
21
21
  import cssModules from "../cssModules";
22
+ import { getDataComponentAttribute } from "../getDataComponentAttribute";
22
23
  import STYLES from "./BpkDialogWrapper.module.css";
23
24
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
25
  const getClassName = cssModules(STYLES);
@@ -121,6 +122,7 @@ export const BpkDialogWrapper = ({
121
122
  };
122
123
  return isOpen ? /*#__PURE__*/_jsxs("div", {
123
124
  className: getClassName('bpk-dialog-wrapper', !dialogSupported && 'bpk-dialog-wrapper--polyfill'),
125
+ ...getDataComponentAttribute('DialogWrapper'),
124
126
  children: [!dialogSupported && /*#__PURE__*/_jsx("div", {
125
127
  id: `${id}-polyfill`,
126
128
  className: getClassName('bpk-dialog-wrapper--backdrop'),
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Returns an object containing the data-backpack-ds-component attribute.
3
+ * Use this to ensure consistent naming and placement across all components.
4
+ *
5
+ * @param {string} componentName - The component name without the "Bpk" prefix (e.g., "Button", "Card")
6
+ * @returns {{Object}} An object with the data-backpack-ds-component attribute
7
+ *
8
+ * @example
9
+ * // In a component:
10
+ * <button {...getDataComponentAttribute('Button')} {...rest}>
11
+ * Click me
12
+ * </button>
13
+ *
14
+ * // Renders:
15
+ * // <button data-backpack-ds-component="Button" ...>Click me</button>
16
+ */
17
+ export declare const getDataComponentAttribute: (componentName: string) => {
18
+ "data-backpack-ds-component": string;
19
+ };
20
+ export default getDataComponentAttribute;
@@ -0,0 +1,38 @@
1
+ /*
2
+ * Backpack - Skyscanner's Design System
3
+ *
4
+ * Copyright 2016 Skyscanner Ltd
5
+ *
6
+ * Licensed under the Apache License, Version 2.0 (the "License");
7
+ * you may not use this file except in compliance with the License.
8
+ * You may obtain a copy of the License at
9
+ *
10
+ * http://www.apache.org/licenses/LICENSE-2.0
11
+ *
12
+ * Unless required by applicable law or agreed to in writing, software
13
+ * distributed under the License is distributed on an "AS IS" BASIS,
14
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
+ * See the License for the specific language governing permissions and
16
+ * limitations under the License.
17
+ */
18
+
19
+ /**
20
+ * Returns an object containing the data-backpack-ds-component attribute.
21
+ * Use this to ensure consistent naming and placement across all components.
22
+ *
23
+ * @param {string} componentName - The component name without the "Bpk" prefix (e.g., "Button", "Card")
24
+ * @returns {{Object}} An object with the data-backpack-ds-component attribute
25
+ *
26
+ * @example
27
+ * // In a component:
28
+ * <button {...getDataComponentAttribute('Button')} {...rest}>
29
+ * Click me
30
+ * </button>
31
+ *
32
+ * // Renders:
33
+ * // <button data-backpack-ds-component="Button" ...>Click me</button>
34
+ */
35
+ export const getDataComponentAttribute = componentName => ({
36
+ 'data-backpack-ds-component': componentName
37
+ });
38
+ export default getDataComponentAttribute;
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { TransitionInitialMount, cssModules } from "../../bpk-react-utils";
19
+ import { TransitionInitialMount, cssModules, getDataComponentAttribute } from "../../bpk-react-utils";
20
20
  import STYLES from "./bpk-scrim.module.css";
21
21
  import { jsx as _jsx } from "react/jsx-runtime";
22
22
  const getClassName = cssModules(STYLES);
@@ -29,6 +29,7 @@ const BpkScrim = ({
29
29
  children: /*#__PURE__*/_jsx("div", {
30
30
  role: "presentation",
31
31
  className: getClassName('bpk-scrim'),
32
+ ...getDataComponentAttribute('Scrim'),
32
33
  onMouseDown: onClose,
33
34
  onTouchStart: onClose
34
35
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyscanner/backpack-web",
3
- "version": "41.8.0",
3
+ "version": "41.10.0-beta-v1",
4
4
  "description": "Backpack Design System web library",
5
5
  "repository": {
6
6
  "type": "git",
@@ -22,6 +22,7 @@
22
22
  "access": "public"
23
23
  },
24
24
  "dependencies": {
25
+ "@chakra-ui/react": "^3.30.0",
25
26
  "@floating-ui/react": "^0.26.12",
26
27
  "@popperjs/core": "^2.11.8",
27
28
  "@radix-ui/react-compose-refs": "^1.1.1",