@skyscanner/backpack-web 38.16.0 → 38.18.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 (26) hide show
  1. package/bpk-component-banner-alert/src/AnimateAndFade.d.ts +1 -2
  2. package/bpk-component-banner-alert/src/AnimateAndFade.js +3 -6
  3. package/bpk-component-bottom-sheet/src/BpkBottomSheet.d.ts +3 -3
  4. package/bpk-component-bottom-sheet/src/BpkBottomSheet.js +53 -47
  5. package/bpk-component-calendar/src/BpkCalendarContainer.d.ts +4 -4
  6. package/bpk-component-calendar/src/BpkCalendarContainer.js +14 -14
  7. package/bpk-component-calendar/src/BpkCalendarGrid.d.ts +1 -1
  8. package/bpk-component-calendar/src/BpkCalendarGrid.js +3 -3
  9. package/bpk-component-calendar/src/BpkCalendarGridTransition.d.ts +1 -2
  10. package/bpk-component-calendar/src/BpkCalendarGridTransition.js +12 -11
  11. package/bpk-component-card-list/src/BpkCardList.js +1 -1
  12. package/bpk-component-card-list/src/common-types.d.ts +7 -2
  13. package/bpk-component-datepicker/src/BpkDatepicker.d.ts +6 -9
  14. package/bpk-component-info-banner/src/AnimateAndFade.d.ts +1 -2
  15. package/bpk-component-info-banner/src/AnimateAndFade.js +3 -6
  16. package/bpk-component-page-indicator/src/BpkPageIndicator.d.ts +2 -1
  17. package/bpk-component-page-indicator/src/BpkPageIndicator.js +10 -6
  18. package/bpk-component-page-indicator/src/BpkPageIndicator.module.css +1 -1
  19. package/bpk-component-page-indicator/src/NavButton.d.ts +4 -1
  20. package/bpk-component-page-indicator/src/NavButton.js +3 -2
  21. package/bpk-component-price-range/src/BpkPriceMarker.module.css +1 -1
  22. package/bpk-component-price-range/src/BpkPriceRange.module.css +1 -1
  23. package/bpk-component-scrollable-calendar/src/BpkScrollableCalendar.d.ts +6 -9
  24. package/bpk-react-utils/src/BpkDialogWrapper/BpkDialogWrapper.d.ts +1 -1
  25. package/bpk-react-utils/src/BpkDialogWrapper/BpkDialogWrapper.js +19 -14
  26. package/package.json +1 -1
@@ -22,8 +22,7 @@ declare class AnimateAndFade extends Component<Props, State> {
22
22
  };
23
23
  constructor(props: Props);
24
24
  componentDidMount(): void;
25
- UNSAFE_componentWillReceiveProps(nextProps: Props): void;
26
- componentDidUpdate(): void;
25
+ componentDidUpdate(prevProps: Props): void;
27
26
  onAnimateHeightComplete: () => void;
28
27
  onFadeComplete: () => void;
29
28
  toggle: () => void;
@@ -49,13 +49,10 @@ class AnimateAndFade extends Component {
49
49
  this.toggle();
50
50
  }
51
51
  }
52
- UNSAFE_componentWillReceiveProps(nextProps) {
53
- if (nextProps.show === this.props.show) {
54
- return;
52
+ componentDidUpdate(prevProps) {
53
+ if (this.props.show !== prevProps.show) {
54
+ this.toggle();
55
55
  }
56
- this.toggle();
57
- }
58
- componentDidUpdate() {
59
56
  if (this.state.initiateShow) {
60
57
  // React doesn't like us calling setState from componentDidUpdate as it can lead to an infinite re-renders.
61
58
  // I think it is ok here, however, as this will only happen conditionally (ie once)
@@ -1,4 +1,4 @@
1
- import type { SyntheticEvent, ReactNode } from "react";
1
+ import type { SyntheticEvent, ReactNode } from 'react';
2
2
  interface CommonProps {
3
3
  actionText?: string;
4
4
  children: ReactNode;
@@ -19,5 +19,5 @@ export type Props = CommonProps & ({
19
19
  } | {
20
20
  ariaLabel: string;
21
21
  });
22
- declare const BpkBottomSheet: ({ actionText, children, closeLabel, closeOnEscPressed, closeOnScrimClick, id, isOpen, onAction, onClose, title, wide, ...ariaProps }: Props) => import("react/jsx-runtime").JSX.Element;
23
- export default BpkBottomSheet;
22
+ declare const BpkBottomSheetWithBreakpoint: (props: Props) => import("react/jsx-runtime").JSX.Element;
23
+ export default BpkBottomSheetWithBreakpoint;
@@ -16,7 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { useState } from "react";
19
+ import { useCallback, useState } from 'react';
20
20
  import BpkBreakpoint, { BREAKPOINTS } from "../../bpk-component-breakpoint";
21
21
  // @ts-expect-error Untyped import. See `decisions/imports-ts-suppressions.md`.
22
22
  import BpkCloseButton from "../../bpk-component-close-button";
@@ -35,6 +35,7 @@ const BpkBottomSheet = ({
35
35
  closeOnEscPressed = false,
36
36
  closeOnScrimClick = false,
37
37
  id,
38
+ isAboveMobile,
38
39
  isOpen,
39
40
  onAction = () => null,
40
41
  onClose,
@@ -44,58 +45,63 @@ const BpkBottomSheet = ({
44
45
  }) => {
45
46
  const [exiting, setExiting] = useState(false);
46
47
  const animationTimeout = 240;
47
- const handleClose = (timeout, arg0, arg1) => {
48
+ const handleClose = useCallback((arg0, arg1) => {
49
+ const timeoutDuration = isAboveMobile ? 0 : animationTimeout;
48
50
  setExiting(true);
49
51
  setTimeout(() => {
50
52
  onClose(arg0, arg1);
51
53
  setExiting(false);
52
- }, timeout);
53
- };
54
+ }, timeoutDuration);
55
+ }, [isAboveMobile, onClose]);
54
56
  const headingId = `bpk-bottom-sheet-heading-${id}`;
55
57
  const dialogClassName = getClassName('bpk-bottom-sheet', wide && 'bpk-bottom-sheet--wide');
56
- return /*#__PURE__*/_jsx(BpkBreakpoint, {
57
- query: BREAKPOINTS.ABOVE_MOBILE,
58
- children: isAboveMobile => /*#__PURE__*/_jsx(BpkDialogWrapper, {
59
- ...ariaProps,
60
- dialogClassName: dialogClassName,
61
- id: id,
62
- isOpen: isOpen,
63
- onClose: (arg0, arg1) => handleClose(isAboveMobile ? 0 : animationTimeout, arg0, arg1),
64
- exiting: exiting,
65
- transitionClassNames: {
66
- appear: getClassName('bpk-bottom-sheet--appear'),
67
- appearActive: getClassName('bpk-bottom-sheet--appear-active'),
68
- exit: getClassName('bpk-bottom-sheet--exit')
69
- },
70
- closeOnEscPressed: closeOnEscPressed,
71
- closeOnScrimClick: closeOnScrimClick,
72
- timeout: {
73
- appear: animationTimeout,
74
- exit: isAboveMobile ? 0 : animationTimeout
75
- },
76
- children: /*#__PURE__*/_jsxs(_Fragment, {
77
- children: [/*#__PURE__*/_jsx("header", {
78
- className: getClassName('bpk-bottom-sheet--header'),
79
- children: /*#__PURE__*/_jsx(BpkNavigationBar, {
80
- id: headingId,
81
- title: title,
82
- titleTextStyle: TEXT_STYLES.label1,
83
- titleTagName: title ? "h2" : "span",
84
- leadingButton: /*#__PURE__*/_jsx(BpkCloseButton, {
85
- label: closeLabel,
86
- onClick: (arg0, arg1) => handleClose(isAboveMobile ? 0 : animationTimeout, arg0, arg1)
87
- }),
88
- trailingButton: actionText && onAction ? /*#__PURE__*/_jsx(BpkButtonLink, {
89
- onClick: onAction,
90
- children: actionText
91
- }) : null
92
- })
93
- }), /*#__PURE__*/_jsx("div", {
94
- className: getClassName('bpk-bottom-sheet--content'),
95
- children: children
96
- })]
97
- })
58
+ return /*#__PURE__*/_jsx(BpkDialogWrapper, {
59
+ ...ariaProps,
60
+ dialogClassName: dialogClassName,
61
+ id: id,
62
+ isOpen: isOpen,
63
+ onClose: handleClose,
64
+ exiting: exiting,
65
+ transitionClassNames: {
66
+ appear: getClassName('bpk-bottom-sheet--appear'),
67
+ appearActive: getClassName('bpk-bottom-sheet--appear-active'),
68
+ exit: getClassName('bpk-bottom-sheet--exit')
69
+ },
70
+ closeOnEscPressed: closeOnEscPressed,
71
+ closeOnScrimClick: closeOnScrimClick,
72
+ timeout: {
73
+ appear: animationTimeout,
74
+ exit: isAboveMobile ? 0 : animationTimeout
75
+ },
76
+ children: /*#__PURE__*/_jsxs(_Fragment, {
77
+ children: [/*#__PURE__*/_jsx("header", {
78
+ className: getClassName('bpk-bottom-sheet--header'),
79
+ children: /*#__PURE__*/_jsx(BpkNavigationBar, {
80
+ id: headingId,
81
+ title: title,
82
+ titleTextStyle: TEXT_STYLES.label1,
83
+ titleTagName: title ? 'h2' : 'span',
84
+ leadingButton: /*#__PURE__*/_jsx(BpkCloseButton, {
85
+ label: closeLabel,
86
+ onClick: handleClose
87
+ }),
88
+ trailingButton: actionText && onAction ? /*#__PURE__*/_jsx(BpkButtonLink, {
89
+ onClick: onAction,
90
+ children: actionText
91
+ }) : null
92
+ })
93
+ }), /*#__PURE__*/_jsx("div", {
94
+ className: getClassName('bpk-bottom-sheet--content'),
95
+ children: children
96
+ })]
98
97
  })
99
98
  });
100
99
  };
101
- export default BpkBottomSheet;
100
+ const BpkBottomSheetWithBreakpoint = props => /*#__PURE__*/_jsx(BpkBreakpoint, {
101
+ query: BREAKPOINTS.ABOVE_MOBILE,
102
+ children: isAboveMobile => /*#__PURE__*/_jsx(BpkBottomSheet, {
103
+ ...props,
104
+ isAboveMobile: isAboveMobile
105
+ })
106
+ });
107
+ export default BpkBottomSheetWithBreakpoint;
@@ -44,7 +44,7 @@ type State = {
44
44
  };
45
45
  declare const withCalendarState: <P extends object>(Calendar: ComponentType<P>) => {
46
46
  new (props: CalendarProps<P>): {
47
- UNSAFE_componentWillReceiveProps(nextProps: CalendarProps<P>): void;
47
+ componentDidUpdate(prevProps: CalendarProps<P>): void;
48
48
  handleDateFocus: (event: UIEvent, { date, source }: {
49
49
  date: Date;
50
50
  source: string;
@@ -69,10 +69,10 @@ declare const withCalendarState: <P extends object>(Calendar: ComponentType<P>)
69
69
  componentWillUnmount?(): void;
70
70
  componentDidCatch?(error: Error, errorInfo: import("react").ErrorInfo): void;
71
71
  getSnapshotBeforeUpdate?(prevProps: Readonly<CalendarProps<P>>, prevState: Readonly<State>): any;
72
- componentDidUpdate?(prevProps: Readonly<CalendarProps<P>>, prevState: Readonly<State>, snapshot?: any): void;
73
72
  componentWillMount?(): void;
74
73
  UNSAFE_componentWillMount?(): void;
75
74
  componentWillReceiveProps?(nextProps: Readonly<CalendarProps<P>>, nextContext: any): void;
75
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<CalendarProps<P>>, nextContext: any): void;
76
76
  componentWillUpdate?(nextProps: Readonly<CalendarProps<P>>, nextState: Readonly<State>, nextContext: any): void;
77
77
  UNSAFE_componentWillUpdate?(nextProps: Readonly<CalendarProps<P>>, nextState: Readonly<State>, nextContext: any): void;
78
78
  };
@@ -94,7 +94,7 @@ declare const withCalendarState: <P extends object>(Calendar: ComponentType<P>)
94
94
  };
95
95
  declare const _default: {
96
96
  new (props: CalendarProps<import("./composeCalendar").Props>): {
97
- UNSAFE_componentWillReceiveProps(nextProps: CalendarProps<import("./composeCalendar").Props>): void;
97
+ componentDidUpdate(prevProps: CalendarProps<import("./composeCalendar").Props>): void;
98
98
  handleDateFocus: (event: UIEvent, { date, source }: {
99
99
  date: Date;
100
100
  source: string;
@@ -119,10 +119,10 @@ declare const _default: {
119
119
  componentWillUnmount?(): void;
120
120
  componentDidCatch?(error: Error, errorInfo: import("react").ErrorInfo): void;
121
121
  getSnapshotBeforeUpdate?(prevProps: Readonly<CalendarProps<import("./composeCalendar").Props>>, prevState: Readonly<State>): any;
122
- componentDidUpdate?(prevProps: Readonly<CalendarProps<import("./composeCalendar").Props>>, prevState: Readonly<State>, snapshot?: any): void;
123
122
  componentWillMount?(): void;
124
123
  UNSAFE_componentWillMount?(): void;
125
124
  componentWillReceiveProps?(nextProps: Readonly<CalendarProps<import("./composeCalendar").Props>>, nextContext: any): void;
125
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<CalendarProps<import("./composeCalendar").Props>>, nextContext: any): void;
126
126
  componentWillUpdate?(nextProps: Readonly<CalendarProps<import("./composeCalendar").Props>>, nextState: Readonly<State>, nextContext: any): void;
127
127
  UNSAFE_componentWillUpdate?(nextProps: Readonly<CalendarProps<import("./composeCalendar").Props>>, nextState: Readonly<State>, nextContext: any): void;
128
128
  };
@@ -28,24 +28,24 @@ import { addDays, addMonths, dateToBoundaries, isAfter, isSameMonth, isSameDay,
28
28
  import { jsx as _jsx } from "react/jsx-runtime";
29
29
  /**
30
30
  * Updates the current focused date
31
- * @param {Object} currentProps current input properties
32
- * @param {Object} nextProps next input properties when component changes
31
+ * @param {Object} prevProps previous input properties
32
+ * @param {Object} currentProps current input properties when component changes
33
33
  * @returns {Boolean} if the selected date has changed
34
34
  */
35
- const focusedDateHasChanged = (currentProps, nextProps) => {
35
+ const focusedDateHasChanged = (prevProps, currentProps) => {
36
+ const prevSelectConfig = prevProps.selectionConfiguration;
36
37
  const currentSelectConfig = currentProps.selectionConfiguration;
37
- const nextSelectConfig = nextProps.selectionConfiguration;
38
- const rawNextSelectedDate = nextSelectConfig.type === CALENDAR_SELECTION_TYPE.single ? nextSelectConfig.date : nextSelectConfig.startDate;
39
- const rawSelectedDate = currentSelectConfig.type === CALENDAR_SELECTION_TYPE.single ? currentSelectConfig.date : currentSelectConfig.startDate;
40
- if (!rawSelectedDate && !rawNextSelectedDate) {
38
+ const rawCurrentSelectedDate = currentSelectConfig.type === CALENDAR_SELECTION_TYPE.single ? currentSelectConfig.date : currentSelectConfig.startDate;
39
+ const rawPrevSelectedDate = prevSelectConfig.type === CALENDAR_SELECTION_TYPE.single ? prevSelectConfig.date : prevSelectConfig.startDate;
40
+ if (!rawPrevSelectedDate && !rawCurrentSelectedDate) {
41
41
  return false;
42
42
  }
43
- if (rawSelectedDate && !rawNextSelectedDate || !rawSelectedDate && rawNextSelectedDate) {
43
+ if (rawPrevSelectedDate && !rawCurrentSelectedDate || !rawPrevSelectedDate && rawCurrentSelectedDate) {
44
44
  return true;
45
45
  }
46
46
 
47
47
  // @ts-expect-error TS reporting incorrectly as we are already checking above that the dates are not null
48
- return !isSameDay(rawNextSelectedDate, rawSelectedDate);
48
+ return !isSameDay(rawCurrentSelectedDate, rawPrevSelectedDate);
49
49
  };
50
50
 
51
51
  /**
@@ -115,11 +115,11 @@ const withCalendarState = Calendar => {
115
115
  focusedDate: determineFocusedDate(rawSelectedDate[0], initiallyFocusedDate, minDate, maxDate)
116
116
  };
117
117
  }
118
- UNSAFE_componentWillReceiveProps(nextProps) {
119
- const rawNextSelectedDate = getRawSelectedDate(nextProps.selectionConfiguration);
120
- const minDate = startOfDay(nextProps.minDate);
121
- const maxDate = startOfDay(nextProps.maxDate);
122
- if (focusedDateHasChanged(this.props, nextProps)) {
118
+ componentDidUpdate(prevProps) {
119
+ const rawNextSelectedDate = getRawSelectedDate(this.props.selectionConfiguration);
120
+ const minDate = startOfDay(this.props.minDate);
121
+ const maxDate = startOfDay(this.props.maxDate);
122
+ if (focusedDateHasChanged(prevProps, this.props)) {
123
123
  this.setState({
124
124
  focusedDate: dateToBoundaries(rawNextSelectedDate[0], minDate, maxDate)
125
125
  });
@@ -50,7 +50,7 @@ declare class BpkCalendarGrid extends Component<Props, State> {
50
50
  static defaultProps: DefaultProps;
51
51
  constructor(props: Props);
52
52
  componentDidMount(): void;
53
- UNSAFE_componentWillReceiveProps(nextProps: Props): void;
53
+ componentDidUpdate(prevProps: Props): void;
54
54
  render(): import("react/jsx-runtime").JSX.Element;
55
55
  }
56
56
  declare const BpkCalendarGridWithTransition: typeof BpkCalendarGrid | ((props: Omit<DefaultProps & {
@@ -69,11 +69,11 @@ class BpkCalendarGrid extends Component {
69
69
  calendarMonthWeeks: getCalendar(this.props.month, this.props.weekStartsOn, this.props.formatDateFull)
70
70
  });
71
71
  }
72
- UNSAFE_componentWillReceiveProps(nextProps) {
72
+ componentDidUpdate(prevProps) {
73
73
  // We cache expensive calculations (and identities) in state
74
- if (!isSameMonth(nextProps.month, this.props.month) || nextProps.weekStartsOn !== this.props.weekStartsOn) {
74
+ if (!isSameMonth(this.props.month, prevProps.month) || this.props.weekStartsOn !== prevProps.weekStartsOn) {
75
75
  this.setState({
76
- calendarMonthWeeks: getCalendar(nextProps.month, nextProps.weekStartsOn, nextProps.formatDateFull)
76
+ calendarMonthWeeks: getCalendar(this.props.month, this.props.weekStartsOn, this.props.formatDateFull)
77
77
  });
78
78
  }
79
79
  }
@@ -23,8 +23,7 @@ declare class BpkCalendarGridTransition extends Component<Props, State> {
23
23
  focusedDate: null;
24
24
  };
25
25
  constructor(props: Props);
26
- UNSAFE_componentWillReceiveProps({ month: nextMonth }: Props): void;
27
- componentDidUpdate(): void;
26
+ componentDidUpdate(prevProps: Props): void;
28
27
  onMonthTransitionEnd(): void;
29
28
  render(): import("react/jsx-runtime").JSX.Element;
30
29
  }
@@ -51,16 +51,18 @@ class BpkCalendarGridTransition extends Component {
51
51
  };
52
52
  this.isTransitionEndSupported = isTransitionEndSupported();
53
53
  }
54
- UNSAFE_componentWillReceiveProps({
55
- month: nextMonth = new Date()
56
- }) {
54
+ componentDidUpdate(prevProps) {
57
55
  const {
58
- month = new Date()
56
+ month: currentMonth = new Date()
59
57
  } = this.props;
60
- const hasMonthChanged = !isSameMonth(month, nextMonth);
58
+ const {
59
+ month: previousMonth = new Date()
60
+ } = prevProps;
61
+ const hasMonthChanged = !isSameMonth(previousMonth, currentMonth);
61
62
  if (hasMonthChanged) {
62
63
  const reverse = isRTL();
63
- if (differenceInCalendarMonths(nextMonth, month) === 1) {
64
+ const monthDifference = differenceInCalendarMonths(currentMonth, previousMonth);
65
+ if (monthDifference === 1) {
64
66
  // Transition to next month
65
67
  this.setState({
66
68
  transitionValue: reverse ? transitionValues.previous : transitionValues.next,
@@ -68,7 +70,7 @@ class BpkCalendarGridTransition extends Component {
68
70
  });
69
71
  return;
70
72
  }
71
- if (differenceInCalendarMonths(nextMonth, month) === -1) {
73
+ if (monthDifference === -1) {
72
74
  // Transition to previous month
73
75
  this.setState({
74
76
  transitionValue: reverse ? transitionValues.next : transitionValues.previous,
@@ -79,12 +81,11 @@ class BpkCalendarGridTransition extends Component {
79
81
  this.setState({
80
82
  // Used in a test so this is valid usage.
81
83
  // eslint-disable-next-line react/no-unused-state
82
- currentMonth: nextMonth,
83
- months: [addMonths(nextMonth, -1), nextMonth, addMonths(nextMonth, 1)]
84
+ currentMonth,
85
+ months: [addMonths(currentMonth, -1), currentMonth, addMonths(currentMonth, 1)]
84
86
  });
85
87
  }
86
- }
87
- componentDidUpdate() {
88
+
88
89
  // For IE9, immediately call onMonthTransitionEnd instead of
89
90
  // waiting for the animation to complete
90
91
  // Thx to Airbnb's react-dates <3
@@ -65,7 +65,7 @@ const BpkCardList = props => {
65
65
  children: /*#__PURE__*/_jsx(BpkBreakpoint, {
66
66
  query: BREAKPOINTS.MOBILE,
67
67
  children: isMobile => /*#__PURE__*/_jsxs(_Fragment, {
68
- children: [/*#__PURE__*/_jsx(BpkSectionHeader, {
68
+ children: [title !== undefined && /*#__PURE__*/_jsx(BpkSectionHeader, {
69
69
  title: title,
70
70
  description: description,
71
71
  button: shouldShowHeaderButton(isMobile) ? headerButton : null
@@ -29,8 +29,6 @@ type AccessibilityLabels = {
29
29
  slideLabel?: (index: number, childrenLength: number) => string;
30
30
  };
31
31
  type CardListBaseProps = {
32
- title: string;
33
- description?: string;
34
32
  cardList: ReactElement[];
35
33
  layoutMobile: LayoutMobile;
36
34
  layoutDesktop: LayoutDesktop;
@@ -45,6 +43,13 @@ type CardListBaseProps = {
45
43
  buttonHref?: string;
46
44
  expandText?: string;
47
45
  accessibilityLabels?: AccessibilityLabels;
46
+ } & TitleProps;
47
+ type TitleProps = {
48
+ title: string;
49
+ description?: string;
50
+ } | {
51
+ title?: never;
52
+ description?: never;
48
53
  };
49
54
  type CardListGridStackProps = {
50
55
  children: ReactElement[];
@@ -63,7 +63,7 @@ declare class BpkDatepicker extends Component<Props, State> {
63
63
  }> & {
64
64
  [rest: string]: any;
65
65
  }): {
66
- UNSAFE_componentWillReceiveProps(nextProps: Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
66
+ componentDidUpdate(prevProps: Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
67
67
  onDateClick: ((date: Date) => void) | null;
68
68
  onDateKeyDown: ((event: KeyboardEvent) => void) | null;
69
69
  month: Date;
@@ -155,7 +155,9 @@ declare class BpkDatepicker extends Component<Props, State> {
155
155
  preventKeyboardFocus: boolean;
156
156
  focusedDate: Date;
157
157
  }>): any;
158
- componentDidUpdate?(prevProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
158
+ componentWillMount?(): void;
159
+ UNSAFE_componentWillMount?(): void;
160
+ componentWillReceiveProps?(nextProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
159
161
  onDateClick: ((date: Date) => void) | null;
160
162
  onDateKeyDown: ((event: KeyboardEvent) => void) | null;
161
163
  month: Date;
@@ -163,13 +165,8 @@ declare class BpkDatepicker extends Component<Props, State> {
163
165
  maxDate: Date;
164
166
  }> & {
165
167
  [rest: string]: any;
166
- }>, prevState: Readonly<{
167
- preventKeyboardFocus: boolean;
168
- focusedDate: Date;
169
- }>, snapshot?: any): void;
170
- componentWillMount?(): void;
171
- UNSAFE_componentWillMount?(): void;
172
- componentWillReceiveProps?(nextProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
168
+ }>, nextContext: any): void;
169
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
173
170
  onDateClick: ((date: Date) => void) | null;
174
171
  onDateKeyDown: ((event: KeyboardEvent) => void) | null;
175
172
  month: Date;
@@ -22,8 +22,7 @@ declare class AnimateAndFade extends Component<Props, State> {
22
22
  };
23
23
  constructor(props: Props);
24
24
  componentDidMount(): void;
25
- UNSAFE_componentWillReceiveProps(nextProps: Props): void;
26
- componentDidUpdate(): void;
25
+ componentDidUpdate(prevProps: Props): void;
27
26
  onAnimateHeightComplete: () => void;
28
27
  onFadeComplete: () => void;
29
28
  toggle: () => void;
@@ -49,13 +49,10 @@ class AnimateAndFade extends Component {
49
49
  this.toggle();
50
50
  }
51
51
  }
52
- UNSAFE_componentWillReceiveProps(nextProps) {
53
- if (nextProps.show === this.props.show) {
54
- return;
52
+ componentDidUpdate(prevProps) {
53
+ if (this.props.show !== prevProps.show) {
54
+ this.toggle();
55
55
  }
56
- this.toggle();
57
- }
58
- componentDidUpdate() {
59
56
  if (this.state.initiateShow) {
60
57
  // React doesn't like us calling setState from componentDidUpdate as it can lead to an infinite re-renders.
61
58
  // I think it is ok here, however, as this will only happen conditionally (ie once)
@@ -3,6 +3,7 @@ import { DIRECTIONS } from './NavButton';
3
3
  export declare const VARIANT: {
4
4
  readonly default: "default";
5
5
  readonly overImage: "overImage";
6
+ readonly overImageSpaced: "overImageSpaced";
6
7
  };
7
8
  type Variant = (typeof VARIANT)[keyof typeof VARIANT];
8
9
  type Direction = (typeof DIRECTIONS)[keyof typeof DIRECTIONS];
@@ -17,5 +18,5 @@ export type Props = {
17
18
  className?: string;
18
19
  showNav?: boolean;
19
20
  };
20
- declare const BpkPageIndicator: ({ className, currentIndex, indicatorLabel, nextNavLabel, onClick, prevNavLabel, showNav, totalIndicators, variant, }: Props) => import("react/jsx-runtime").JSX.Element;
21
+ declare const BpkPageIndicator: ({ className, currentIndex, indicatorLabel, nextNavLabel, onClick, prevNavLabel, showNav, totalIndicators, variant }: Props) => import("react/jsx-runtime").JSX.Element;
21
22
  export default BpkPageIndicator;
@@ -16,6 +16,7 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
+ import { BUTTON_TYPES } from "../../bpk-component-button";
19
20
  import { cssModules } from "../../bpk-react-utils";
20
21
  import NavButton, { DIRECTIONS } from "./NavButton";
21
22
  import STYLES from "./BpkPageIndicator.module.css";
@@ -25,7 +26,8 @@ const DISPLAYED_TOTAL = 5;
25
26
  const START_SCROLL_INDEX = Math.floor(DISPLAYED_TOTAL / 2);
26
27
  export const VARIANT = {
27
28
  default: 'default',
28
- overImage: 'overImage'
29
+ overImage: 'overImage',
30
+ overImageSpaced: 'overImageSpaced'
29
31
  };
30
32
  const BpkPageIndicator = ({
31
33
  className = undefined,
@@ -48,7 +50,7 @@ const BpkPageIndicator = ({
48
50
  '--scroll-index': totalIndicators > DISPLAYED_TOTAL ? Math.min(currentIndex - START_SCROLL_INDEX, totalIndicators - DISPLAYED_TOTAL) : 0
49
51
  };
50
52
  return /*#__PURE__*/_jsx("div", {
51
- className: className,
53
+ className: variant === VARIANT.overImageSpaced ? getClassName('bpk-page-indicator-fullWidth__container') : className,
52
54
  "aria-hidden": isInteractive ? 'false' : 'true',
53
55
  "data-testid": "indicator-container",
54
56
  children: /*#__PURE__*/_jsxs("div", {
@@ -56,9 +58,10 @@ const BpkPageIndicator = ({
56
58
  children: [showNav && /*#__PURE__*/_jsx(NavButton, {
57
59
  currentIndex: currentIndex,
58
60
  onClick: onClick,
59
- disabled: currentIndex === 0,
61
+ disabled: variant === VARIANT.overImageSpaced ? totalIndicators <= 1 : currentIndex === 0 || totalIndicators <= 1,
60
62
  direction: DIRECTIONS.PREV,
61
- ariaLabel: prevNavLabel
63
+ ariaLabel: prevNavLabel,
64
+ type: variant === VARIANT.overImageSpaced ? BUTTON_TYPES.secondaryOnDark : BUTTON_TYPES.link
62
65
  }), /*#__PURE__*/_jsx("div", {
63
66
  className: getClassName('bpk-page-indicator__container'),
64
67
  children: /*#__PURE__*/_jsx("div", {
@@ -81,9 +84,10 @@ const BpkPageIndicator = ({
81
84
  }), showNav && /*#__PURE__*/_jsx(NavButton, {
82
85
  currentIndex: currentIndex,
83
86
  onClick: onClick,
84
- disabled: currentIndex === totalIndicators - 1,
87
+ disabled: variant === VARIANT.overImageSpaced ? totalIndicators <= 1 : currentIndex === totalIndicators - 1 || totalIndicators <= 1,
85
88
  ariaLabel: nextNavLabel,
86
- direction: DIRECTIONS.NEXT
89
+ direction: DIRECTIONS.NEXT,
90
+ type: variant === VARIANT.overImageSpaced ? BUTTON_TYPES.secondaryOnDark : BUTTON_TYPES.link
87
91
  })]
88
92
  })
89
93
  });
@@ -15,4 +15,4 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- .bpk-page-indicator{display:flex;width:100%;justify-content:center;align-items:center}.bpk-page-indicator__showNav{justify-content:space-between}.bpk-page-indicator__container{max-width:5rem;min-height:.5rem;overflow:hidden}.bpk-page-indicator__indicators-container{--direction: -1;transform:translateX(calc(var(--direction) * var(--scroll-index, 0) * 1rem));transition:transform 200ms ease-in-out;white-space:nowrap}html[dir=rtl] .bpk-page-indicator__indicators-container{--direction: 1}.bpk-page-indicator__indicator{display:inline-block;width:.5rem;height:.5rem;padding:0;border:none;border-radius:50%;margin-inline:.25rem}.bpk-page-indicator__indicator:hover{cursor:pointer}.bpk-page-indicator__indicator--default{background-color:#c1c7cf}.bpk-page-indicator__indicator--overImage{background-color:hsla(0,0%,100%,.5)}.bpk-page-indicator__indicator--active-default{background-color:#626971;pointer-events:none}.bpk-page-indicator__indicator--active-overImage{background-color:#fff;pointer-events:none}
18
+ .bpk-page-indicator-fullWidth__container{width:100%}.bpk-page-indicator{display:flex;width:100%;justify-content:center;align-items:center}.bpk-page-indicator__showNav{justify-content:space-between}.bpk-page-indicator__container{max-width:5rem;min-height:.5rem;overflow:hidden}.bpk-page-indicator__indicators-container{--direction: -1;transform:translateX(calc(var(--direction) * var(--scroll-index, 0) * 1rem));transition:transform 200ms ease-in-out;white-space:nowrap}html[dir=rtl] .bpk-page-indicator__indicators-container{--direction: 1}.bpk-page-indicator__indicator{display:inline-block;width:.5rem;height:.5rem;padding:0;border:none;border-radius:50%;margin-inline:.25rem}.bpk-page-indicator__indicator:hover{cursor:pointer}.bpk-page-indicator__indicator--default{background-color:#c1c7cf}.bpk-page-indicator__indicator--overImage,.bpk-page-indicator__indicator--overImageSpaced{background-color:hsla(0,0%,100%,.5)}.bpk-page-indicator__indicator--active-default{background-color:#626971;pointer-events:none}.bpk-page-indicator__indicator--active-overImage,.bpk-page-indicator__indicator--active-overImageSpaced{background-color:#fff;pointer-events:none}
@@ -1,15 +1,18 @@
1
+ import { BUTTON_TYPES } from '../../bpk-component-button';
1
2
  export declare const DIRECTIONS: {
2
3
  readonly PREV: "PREV";
3
4
  readonly INDICATORS: "INDICATORS";
4
5
  readonly NEXT: "NEXT";
5
6
  };
6
7
  type Direction = (typeof DIRECTIONS)[keyof typeof DIRECTIONS];
8
+ type ButtonType = (typeof BUTTON_TYPES)[keyof typeof BUTTON_TYPES];
7
9
  type Props = {
8
10
  ariaLabel: string | undefined;
9
11
  currentIndex: number;
10
12
  direction: Direction;
11
13
  disabled?: boolean;
12
14
  onClick?: (event: React.MouseEvent<HTMLButtonElement>, newIndex: number, direction: Direction) => void;
15
+ type?: ButtonType;
13
16
  };
14
- declare const NavButton: ({ ariaLabel, currentIndex, direction, disabled, onClick, }: Props) => import("react/jsx-runtime").JSX.Element;
17
+ declare const NavButton: ({ ariaLabel, currentIndex, direction, disabled, onClick, type, }: Props) => import("react/jsx-runtime").JSX.Element;
15
18
  export default NavButton;
@@ -33,10 +33,11 @@ const NavButton = ({
33
33
  currentIndex,
34
34
  direction,
35
35
  disabled = false,
36
- onClick = () => {}
36
+ onClick = () => {},
37
+ type = BUTTON_TYPES.link
37
38
  }) => /*#__PURE__*/_jsx(BpkButtonV2, {
38
39
  iconOnly: true,
39
- type: BUTTON_TYPES.link,
40
+ type: type,
40
41
  onClick: e => {
41
42
  if (direction === DIRECTIONS.PREV) {
42
43
  onClick(e, currentIndex - 1, direction);
@@ -15,4 +15,4 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- .bpk-price-marker{position:relative;display:flex;z-index:1;flex-direction:column;align-items:center;flex:none;border:none;border-radius:.25rem;background:none;box-shadow:0px 1px 3px 0px rgba(37,32,31,.3);margin-block-end:.375rem}.bpk-price-marker span{display:inline-flex;z-index:1;padding:.125rem .5rem;border-radius:.25rem;color:#fff}.bpk-price-marker__arrow{position:absolute;top:50%;z-index:0;width:1rem;height:1rem;transform:rotate(45deg);border-radius:25%;background-color:inherit}.bpk-price-marker--low{background-color:#0c838a}.bpk-price-marker--medium{background-color:#05203c}.bpk-price-marker--high{background-color:#e70866}
18
+ .bpk-price-marker{position:relative;display:flex;z-index:1;flex-direction:column;align-items:center;flex:none;border:none;border-radius:.25rem;background:none;white-space:nowrap;box-shadow:0px 1px 3px 0px rgba(37,32,31,.3);margin-block-end:.375rem}.bpk-price-marker span{display:inline-flex;z-index:1;padding:.125rem .5rem;border-radius:.25rem;color:#fff}.bpk-price-marker__arrow{position:absolute;top:50%;z-index:0;width:1rem;height:1rem;transform:rotate(45deg);border-radius:25%;background-color:inherit}.bpk-price-marker--low{background-color:#0c838a}.bpk-price-marker--medium{background-color:#05203c}.bpk-price-marker--high{background-color:#e70866}
@@ -15,4 +15,4 @@
15
15
  * See the License for the specific language governing permissions and
16
16
  * limitations under the License.
17
17
  */
18
- .bpk-price-range{display:flex;width:100%;flex-direction:column;padding-block:.25rem;row-gap:.25rem}.bpk-price-range--large{padding-block:0}.bpk-price-range__lines{position:relative;display:flex;height:.25rem;flex:none;gap:.125rem}.bpk-price-range__lines--large{height:.5rem}.bpk-price-range__line--low{width:calc(100%*var(--low));height:100%;background-color:#0c838a;border-end-start-radius:.5rem;border-start-start-radius:.5rem}.bpk-price-range__line--lowLarge{border-end-start-radius:.75rem;border-start-start-radius:.75rem}.bpk-price-range__line--medium{width:calc(100%*(var(--high) - var(--low)));height:100%;background-color:#05203c}.bpk-price-range__line--high{width:calc(100%*(1 - var(--high)));height:100%;background-color:#e70866;border-end-end-radius:.5rem;border-start-end-radius:.5rem}.bpk-price-range__line--highLarge{border-end-end-radius:.75rem;border-start-end-radius:.75rem}.bpk-price-range__line--dot{position:absolute;top:50%;display:flex;width:.75rem;height:.75rem;justify-content:center;align-items:center;transform:translate(0, -50%);border-radius:50%;margin-inline-start:var(--prefilled-width)}.bpk-price-range__line--dot::after{content:"";display:block;width:.25rem;height:.25rem;border-radius:50%;background-color:#fff}.bpk-price-range__marker{width:fit-content;margin-inline-start:var(--prefilled-width)}.bpk-price-range__ranges{position:relative;display:flex;width:100%;height:1.25rem}.bpk-price-range__ranges span{position:absolute;display:inline-block;transform:translate(-50%, 0)}html[dir=rtl] .bpk-price-range__ranges span{transform:translate(50%, 0)}.bpk-price-range__ranges span:first-child{inset-inline-start:calc(100%*var(--low))}.bpk-price-range__ranges span:last-child{inset-inline-start:calc(100%*var(--high))}
18
+ .bpk-price-range{display:flex;width:100%;flex-direction:column;padding-block:.25rem;row-gap:.25rem}.bpk-price-range--large{padding-block:0}.bpk-price-range__lines{position:relative;display:flex;height:.25rem;flex:none;gap:.125rem}.bpk-price-range__lines--large{height:.5rem}.bpk-price-range__line--low{width:calc(100%*var(--low));height:100%;background-color:#0c838a;border-end-start-radius:.5rem;border-start-start-radius:.5rem}.bpk-price-range__line--lowLarge{border-end-start-radius:.75rem;border-start-start-radius:.75rem}.bpk-price-range__line--medium{width:calc(100%*(var(--high) - var(--low)));height:100%;background-color:#05203c}.bpk-price-range__line--high{width:calc(100%*(1 - var(--high)));height:100%;background-color:#e70866;border-end-end-radius:.5rem;border-start-end-radius:.5rem}.bpk-price-range__line--highLarge{border-end-end-radius:.75rem;border-start-end-radius:.75rem}.bpk-price-range__line--dot{position:absolute;top:50%;display:flex;width:.75rem;height:.75rem;justify-content:center;align-items:center;transform:translate(0, -50%);border-radius:50%;margin-inline-start:var(--prefilled-width)}.bpk-price-range__line--dot::after{content:"";display:block;width:.25rem;height:.25rem;border-radius:50%;background-color:#fff}.bpk-price-range__marker{width:fit-content;margin-inline-start:var(--prefilled-width)}.bpk-price-range__ranges{position:relative;display:flex;width:100%;height:1.25rem;white-space:nowrap}.bpk-price-range__ranges span{position:absolute;display:inline-block;transform:translate(-50%, 0)}html[dir=rtl] .bpk-price-range__ranges span{transform:translate(50%, 0)}.bpk-price-range__ranges span:first-child{inset-inline-start:calc(100%*var(--low))}.bpk-price-range__ranges span:last-child{inset-inline-start:calc(100%*var(--high))}
@@ -8,7 +8,7 @@ declare const _default: {
8
8
  }> & {
9
9
  [rest: string]: any;
10
10
  }): {
11
- UNSAFE_componentWillReceiveProps(nextProps: Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
11
+ componentDidUpdate(prevProps: Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
12
12
  onDateClick: ((date: Date) => void) | null;
13
13
  onDateKeyDown: ((event: KeyboardEvent) => void) | null;
14
14
  month: Date;
@@ -100,7 +100,9 @@ declare const _default: {
100
100
  preventKeyboardFocus: boolean;
101
101
  focusedDate: Date;
102
102
  }>): any;
103
- componentDidUpdate?(prevProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
103
+ componentWillMount?(): void;
104
+ UNSAFE_componentWillMount?(): void;
105
+ componentWillReceiveProps?(nextProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
104
106
  onDateClick: ((date: Date) => void) | null;
105
107
  onDateKeyDown: ((event: KeyboardEvent) => void) | null;
106
108
  month: Date;
@@ -108,13 +110,8 @@ declare const _default: {
108
110
  maxDate: Date;
109
111
  }> & {
110
112
  [rest: string]: any;
111
- }>, prevState: Readonly<{
112
- preventKeyboardFocus: boolean;
113
- focusedDate: Date;
114
- }>, snapshot?: any): void;
115
- componentWillMount?(): void;
116
- UNSAFE_componentWillMount?(): void;
117
- componentWillReceiveProps?(nextProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
113
+ }>, nextContext: any): void;
114
+ UNSAFE_componentWillReceiveProps?(nextProps: Readonly<Omit<import("../../bpk-component-calendar/src/composeCalendar").Props & import("../../bpk-component-calendar/src/BpkCalendarContainer").Props, keyof {
118
115
  onDateClick: ((date: Date) => void) | null;
119
116
  onDateKeyDown: ((event: KeyboardEvent) => void) | null;
120
117
  month: Date;
@@ -1,4 +1,4 @@
1
- import type { SyntheticEvent, ReactNode } from "react";
1
+ import type { SyntheticEvent, ReactNode } from 'react';
2
2
  interface CommonProps {
3
3
  children: ReactNode;
4
4
  closeOnEscPressed?: boolean;
@@ -16,23 +16,20 @@
16
16
  * limitations under the License.
17
17
  */
18
18
 
19
- import { useEffect, useRef, useState } from "react";
19
+ import { useEffect, useRef, useState } from 'react';
20
20
  import CSSTransition from 'react-transition-group/CSSTransition';
21
21
  import cssModules from "../cssModules";
22
22
  import STYLES from "./BpkDialogWrapper.module.css";
23
23
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
24
24
  const getClassName = cssModules(STYLES);
25
- ;
26
25
  // TODO: this check if the browser support the HTML dialog element. We can remove it once we drop support as a business for Safari 14
27
26
  const dialogSupported = typeof HTMLDialogElement === 'function';
28
27
  const setPageProperties = ({
29
28
  isDialogOpen
30
29
  }) => {
31
30
  document.body.style.overflowY = isDialogOpen ? 'hidden' : 'visible';
32
- if (!dialogSupported) {
33
- document.body.style.position = isDialogOpen ? 'fixed' : 'relative';
34
- document.body.style.width = isDialogOpen ? '100%' : 'auto';
35
- }
31
+ document.body.style.position = isDialogOpen ? 'fixed' : 'relative';
32
+ document.body.style.width = isDialogOpen ? '100%' : 'auto';
36
33
  };
37
34
  export const BpkDialogWrapper = ({
38
35
  children,
@@ -52,6 +49,8 @@ export const BpkDialogWrapper = ({
52
49
  }) => {
53
50
  const ref = useRef(null);
54
51
  const [dialogTarget, setDialogTarget] = useState(null);
52
+
53
+ // Handle the opening and closing of the dialog
55
54
  useEffect(() => {
56
55
  const dialog = document.getElementById(`${id}`);
57
56
  const dialogWithPolyfill = document.getElementById(`${id}-polyfill`);
@@ -63,7 +62,7 @@ export const BpkDialogWrapper = ({
63
62
  } = event;
64
63
  if (target === modal) {
65
64
  onClose(event, {
66
- source: "DOCUMENT_CLICK"
65
+ source: 'DOCUMENT_CLICK'
67
66
  });
68
67
  event.stopPropagation();
69
68
  }
@@ -73,7 +72,7 @@ export const BpkDialogWrapper = ({
73
72
  const handleKeyDown = event => {
74
73
  if (closeOnEscPressed && event.key === 'Escape' && (!dialogWithPolyfill || event.target === dialogWithPolyfill)) {
75
74
  onClose(event, {
76
- source: "ESCAPE"
75
+ source: 'ESCAPE'
77
76
  });
78
77
  }
79
78
  event.stopPropagation();
@@ -94,6 +93,13 @@ export const BpkDialogWrapper = ({
94
93
  } else {
95
94
  ref.current?.close?.();
96
95
  }
96
+ return () => {
97
+ window.removeEventListener('keydown', handleKeyDown);
98
+ };
99
+ }, [id, isOpen, onClose, closeOnEscPressed, closeOnScrimClick]);
100
+
101
+ // Lock the scroll of the page when the dialog is open
102
+ useEffect(() => {
97
103
  setPageProperties({
98
104
  isDialogOpen: isOpen
99
105
  });
@@ -101,15 +107,14 @@ export const BpkDialogWrapper = ({
101
107
  setPageProperties({
102
108
  isDialogOpen: false
103
109
  });
104
- window.removeEventListener('keydown', handleKeyDown);
105
110
  };
106
- }, [id, isOpen, onClose, closeOnEscPressed, closeOnScrimClick]);
111
+ }, [isOpen]);
107
112
  const aria = {
108
- ...("ariaLabelledby" in ariaProps ? {
109
- "aria-labelledby": ariaProps.ariaLabelledby
113
+ ...('ariaLabelledby' in ariaProps ? {
114
+ 'aria-labelledby': ariaProps.ariaLabelledby
110
115
  } : undefined),
111
- ...("ariaLabel" in ariaProps ? {
112
- "aria-label": ariaProps.ariaLabel
116
+ ...('ariaLabel' in ariaProps ? {
117
+ 'aria-label': ariaProps.ariaLabel
113
118
  } : undefined)
114
119
  };
115
120
  return isOpen ? /*#__PURE__*/_jsxs("div", {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skyscanner/backpack-web",
3
- "version": "38.16.0",
3
+ "version": "38.18.0",
4
4
  "description": "Backpack Design System web library",
5
5
  "repository": {
6
6
  "type": "git",