@skyscanner/backpack-web 36.4.0 → 36.5.1
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.
- package/bpk-component-calendar/src/BpkCalendarDate.d.ts +1 -0
- package/bpk-component-calendar/src/BpkCalendarDate.js +1 -0
- package/bpk-component-calendar/src/BpkCalendarGrid.d.ts +7 -1
- package/bpk-component-calendar/src/BpkCalendarGrid.js +12 -9
- package/bpk-component-calendar/src/BpkCalendarWeek.d.ts +2 -2
- package/bpk-component-calendar/src/BpkCalendarWeek.js +21 -22
- package/bpk-component-calendar/src/composeCalendar.js +1 -1
- package/bpk-component-calendar/src/date-utils.d.ts +4 -2
- package/bpk-component-calendar/src/date-utils.js +14 -3
- package/bpk-component-popover/src/BpkPopover.d.ts +1 -1
- package/bpk-component-popover/src/BpkPopover.js +1 -1
- package/bpk-react-utils/index.d.ts +1 -1
- package/bpk-react-utils/src/__mocks__/deferCallback.d.ts +9 -0
- package/{bpk-component-carousel/src/utils.test.js → bpk-react-utils/src/__mocks__/deferCallback.js} +12 -13
- package/bpk-react-utils/src/deferCallback.d.ts +13 -0
- package/bpk-react-utils/src/deferCallback.js +39 -0
- package/package.json +1 -1
|
@@ -33,12 +33,18 @@ export type Props = DefaultProps & {
|
|
|
33
33
|
*/
|
|
34
34
|
weekStartsOn: 0 | 1 | 2 | 3 | 4 | 5 | 6;
|
|
35
35
|
};
|
|
36
|
+
export type DateProps = {
|
|
37
|
+
val: Date;
|
|
38
|
+
customLabel: string | Date;
|
|
39
|
+
isoLabel: string;
|
|
40
|
+
};
|
|
36
41
|
type State = {
|
|
37
|
-
calendarMonthWeeks:
|
|
42
|
+
calendarMonthWeeks: DateProps[][];
|
|
38
43
|
};
|
|
39
44
|
declare class BpkCalendarGrid extends Component<Props, State> {
|
|
40
45
|
static defaultProps: DefaultProps;
|
|
41
46
|
constructor(props: Props);
|
|
47
|
+
componentDidMount(): void;
|
|
42
48
|
UNSAFE_componentWillReceiveProps(nextProps: Props): void;
|
|
43
49
|
render(): import("react/jsx-runtime").JSX.Element;
|
|
44
50
|
}
|
|
@@ -18,11 +18,11 @@
|
|
|
18
18
|
|
|
19
19
|
import { Component } from 'react';
|
|
20
20
|
import { cssModules, isDeviceIos } from "../../bpk-react-utils";
|
|
21
|
+
import deferCallback from "../../bpk-react-utils/src/deferCallback";
|
|
21
22
|
import { addCalendarGridTransition } from "./BpkCalendarGridTransition";
|
|
22
23
|
import BpkCalendarWeek from "./BpkCalendarWeek";
|
|
23
24
|
import { CALENDAR_SELECTION_TYPE } from "./custom-proptypes";
|
|
24
|
-
import { addMonths,
|
|
25
|
-
import { memoize } from "./utils";
|
|
25
|
+
import { addMonths, getCalendar, getCalendarNoCustomLabel, isSameMonth } from "./date-utils";
|
|
26
26
|
import STYLES from "./BpkCalendarGrid.module.css";
|
|
27
27
|
|
|
28
28
|
// This should be imported after `./BpkCalendarGrid.module.css`.
|
|
@@ -59,17 +59,22 @@ class BpkCalendarGrid extends Component {
|
|
|
59
59
|
};
|
|
60
60
|
constructor(props) {
|
|
61
61
|
super(props);
|
|
62
|
-
|
|
63
|
-
// We cache expensive calculations (and identities) in state
|
|
64
62
|
this.state = {
|
|
65
|
-
|
|
63
|
+
// Do not run expensive date formatting in the constructor
|
|
64
|
+
calendarMonthWeeks: getCalendarNoCustomLabel(props.month, props.weekStartsOn)
|
|
66
65
|
};
|
|
67
66
|
}
|
|
67
|
+
componentDidMount() {
|
|
68
|
+
// Defer expensive date formatting until after render to improve INP.
|
|
69
|
+
deferCallback(() => this.setState({
|
|
70
|
+
calendarMonthWeeks: getCalendar(this.props.month, this.props.weekStartsOn, this.props.formatDateFull)
|
|
71
|
+
}));
|
|
72
|
+
}
|
|
68
73
|
UNSAFE_componentWillReceiveProps(nextProps) {
|
|
69
74
|
// We cache expensive calculations (and identities) in state
|
|
70
75
|
if (!isSameMonth(nextProps.month, this.props.month) || nextProps.weekStartsOn !== this.props.weekStartsOn) {
|
|
71
76
|
this.setState({
|
|
72
|
-
calendarMonthWeeks:
|
|
77
|
+
calendarMonthWeeks: getCalendar(nextProps.month, nextProps.weekStartsOn, nextProps.formatDateFull)
|
|
73
78
|
});
|
|
74
79
|
}
|
|
75
80
|
}
|
|
@@ -81,7 +86,6 @@ class BpkCalendarGrid extends Component {
|
|
|
81
86
|
dateModifiers,
|
|
82
87
|
dateProps,
|
|
83
88
|
focusedDate,
|
|
84
|
-
formatDateFull,
|
|
85
89
|
ignoreOutsideDate,
|
|
86
90
|
isKeyboardFocusable,
|
|
87
91
|
markOutsideDays,
|
|
@@ -108,7 +112,6 @@ class BpkCalendarGrid extends Component {
|
|
|
108
112
|
dates: dates,
|
|
109
113
|
onDateClick: onDateClick,
|
|
110
114
|
onDateKeyDown: onDateKeyDown,
|
|
111
|
-
formatDateFull: memoize(formatDateFull),
|
|
112
115
|
DateComponent: DateComponent,
|
|
113
116
|
dateModifiers: dateModifiers,
|
|
114
117
|
preventKeyboardFocus: preventKeyboardFocus,
|
|
@@ -123,7 +126,7 @@ class BpkCalendarGrid extends Component {
|
|
|
123
126
|
ignoreOutsideDate: ignoreOutsideDate,
|
|
124
127
|
dateProps: dateProps,
|
|
125
128
|
cellClassName: cellClassName
|
|
126
|
-
},
|
|
129
|
+
}, dates[0].isoLabel))
|
|
127
130
|
})
|
|
128
131
|
});
|
|
129
132
|
}
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import type { ElementType } from 'react';
|
|
2
2
|
import { Component } from 'react';
|
|
3
|
+
import type { DateProps } from './BpkCalendarGrid';
|
|
3
4
|
import type { DateModifiers, SelectionConfiguration } from './custom-proptypes';
|
|
4
5
|
export type Props = DefaultProps & {
|
|
5
6
|
DateComponent: ElementType;
|
|
6
7
|
dateModifiers: DateModifiers;
|
|
7
|
-
dates:
|
|
8
|
-
formatDateFull: (date: Date) => Date | string;
|
|
8
|
+
dates: DateProps[];
|
|
9
9
|
preventKeyboardFocus: boolean;
|
|
10
10
|
markToday: boolean;
|
|
11
11
|
markOutsideDays: boolean;
|
|
@@ -67,13 +67,12 @@ function getSelectedDate(date, selectionConfiguration) {
|
|
|
67
67
|
* Gets the correct selection type for the current date
|
|
68
68
|
* @param {Date} date the current date of the calendar
|
|
69
69
|
* @param {Object} selectionConfiguration the current selection configuration
|
|
70
|
-
* @param {Function} formatDateFull function to format dates
|
|
71
70
|
* @param {Date} month the current month of the calendar
|
|
72
71
|
* @param {Number} weekStartsOn index of the first day of the week
|
|
73
72
|
* @param {Boolean} ignoreOutsideDate ignore date outside current month
|
|
74
73
|
* @returns {String} selection type to be passed to the date
|
|
75
74
|
*/
|
|
76
|
-
function getSelectionType(date, selectionConfiguration,
|
|
75
|
+
function getSelectionType(date, selectionConfiguration, month, weekStartsOn, ignoreOutsideDate) {
|
|
77
76
|
const {
|
|
78
77
|
endDate,
|
|
79
78
|
startDate
|
|
@@ -85,7 +84,7 @@ function getSelectionType(date, selectionConfiguration, formatDateFull, month, w
|
|
|
85
84
|
const sameEndDay = endDate && isSameDay(date, endDate);
|
|
86
85
|
const rangeDates = startDate && endDate;
|
|
87
86
|
const isEmptyCell = !isSameMonth(date, month) && ignoreOutsideDate;
|
|
88
|
-
if (selectionConfiguration.type === CALENDAR_SELECTION_TYPE.single && selectionConfiguration.date && (
|
|
87
|
+
if (selectionConfiguration.type === CALENDAR_SELECTION_TYPE.single && selectionConfiguration.date && isSameDay(date, selectionConfiguration.date)) {
|
|
89
88
|
return SELECTION_TYPES.single;
|
|
90
89
|
}
|
|
91
90
|
if (selectionConfiguration.type === CALENDAR_SELECTION_TYPE.range) {
|
|
@@ -120,10 +119,10 @@ function getSelectionType(date, selectionConfiguration, formatDateFull, month, w
|
|
|
120
119
|
}) && !sameStartDay && !sameEndDay) {
|
|
121
120
|
return SELECTION_TYPES.middle;
|
|
122
121
|
}
|
|
123
|
-
if (
|
|
122
|
+
if (sameStartDay) {
|
|
124
123
|
return SELECTION_TYPES.start;
|
|
125
124
|
}
|
|
126
|
-
if (
|
|
125
|
+
if (sameEndDay) {
|
|
127
126
|
return SELECTION_TYPES.end;
|
|
128
127
|
}
|
|
129
128
|
}
|
|
@@ -139,9 +138,9 @@ function getSelectionType(date, selectionConfiguration, formatDateFull, month, w
|
|
|
139
138
|
const singleDateHandler = (props, nextProps) => {
|
|
140
139
|
const currentSelectConfig = props.selectionConfiguration;
|
|
141
140
|
const nextSelectConfig = nextProps.selectionConfiguration;
|
|
142
|
-
if ((nextSelectConfig.date && isSameWeek(nextSelectConfig.date, nextProps.dates[0], {
|
|
141
|
+
if ((nextSelectConfig.date && isSameWeek(nextSelectConfig.date, nextProps.dates[0].val, {
|
|
143
142
|
weekStartsOn: nextProps.weekStartsOn
|
|
144
|
-
}) || currentSelectConfig.date && isSameWeek(currentSelectConfig.date, props.dates[0], {
|
|
143
|
+
}) || currentSelectConfig.date && isSameWeek(currentSelectConfig.date, props.dates[0].val, {
|
|
145
144
|
weekStartsOn: props.weekStartsOn
|
|
146
145
|
})) && currentSelectConfig.date !== nextSelectConfig.date) {
|
|
147
146
|
return true;
|
|
@@ -190,7 +189,7 @@ class BpkCalendarWeek extends Component {
|
|
|
190
189
|
cellClassName: null
|
|
191
190
|
};
|
|
192
191
|
shouldComponentUpdate(nextProps) {
|
|
193
|
-
const shallowProps = ['DateComponent', 'dateModifiers', '
|
|
192
|
+
const shallowProps = ['DateComponent', 'dateModifiers', 'isKeyboardFocusable', 'markOutsideDays', 'markToday', 'onDateClick', 'onDateKeyDown', 'preventKeyboardFocus', 'weekStartsOn', 'dates', 'cellClassName'];
|
|
194
193
|
|
|
195
194
|
// If any of the props have changed, component should update.
|
|
196
195
|
if (!shallowEqualProps(this.props, nextProps, shallowProps)) {
|
|
@@ -200,9 +199,9 @@ class BpkCalendarWeek extends Component {
|
|
|
200
199
|
// If focusedDate is changing, and it'll be included as part
|
|
201
200
|
// of either the week we're rendering now or the next week
|
|
202
201
|
// we'll render, component should update.
|
|
203
|
-
if ((nextProps.focusedDate && isSameWeek(nextProps.focusedDate, nextProps.dates[0], {
|
|
202
|
+
if ((nextProps.focusedDate && isSameWeek(nextProps.focusedDate, nextProps.dates[0].val, {
|
|
204
203
|
weekStartsOn: nextProps.weekStartsOn
|
|
205
|
-
}) || this.props.focusedDate && isSameWeek(this.props.focusedDate, this.props.dates[0], {
|
|
204
|
+
}) || this.props.focusedDate && isSameWeek(this.props.focusedDate, this.props.dates[0].val, {
|
|
206
205
|
weekStartsOn: this.props.weekStartsOn
|
|
207
206
|
})) && this.props.focusedDate !== nextProps.focusedDate) {
|
|
208
207
|
return true;
|
|
@@ -246,7 +245,6 @@ class BpkCalendarWeek extends Component {
|
|
|
246
245
|
dateModifiers,
|
|
247
246
|
dateProps,
|
|
248
247
|
focusedDate,
|
|
249
|
-
formatDateFull,
|
|
250
248
|
ignoreOutsideDate,
|
|
251
249
|
isKeyboardFocusable,
|
|
252
250
|
markOutsideDays,
|
|
@@ -261,7 +259,7 @@ class BpkCalendarWeek extends Component {
|
|
|
261
259
|
weekStartsOn
|
|
262
260
|
} = this.props;
|
|
263
261
|
if (ignoreOutsideDate) {
|
|
264
|
-
const daysOutside = this.props.dates.map(date => isSameMonth(date, month));
|
|
262
|
+
const daysOutside = this.props.dates.map(date => isSameMonth(date.val, month));
|
|
265
263
|
const shouldRender = daysOutside.reduce(or);
|
|
266
264
|
if (!shouldRender) {
|
|
267
265
|
return null;
|
|
@@ -270,33 +268,34 @@ class BpkCalendarWeek extends Component {
|
|
|
270
268
|
return /*#__PURE__*/_jsx("div", {
|
|
271
269
|
className: getClassName('bpk-calendar-week'),
|
|
272
270
|
children: this.props.dates.map(date => {
|
|
273
|
-
const isBlocked = minDate && maxDate ? !isWithinRange(date, {
|
|
271
|
+
const isBlocked = minDate && maxDate ? !isWithinRange(date.val, {
|
|
274
272
|
start: minDate,
|
|
275
273
|
end: maxDate
|
|
276
274
|
}) : false;
|
|
277
|
-
const dateSelectionType = getSelectionType(date, selectionConfiguration,
|
|
275
|
+
const dateSelectionType = getSelectionType(date.val, selectionConfiguration, month, weekStartsOn, ignoreOutsideDate);
|
|
278
276
|
return /*#__PURE__*/_jsx(DateContainer, {
|
|
279
277
|
className: cellClassName,
|
|
280
|
-
isEmptyCell: !isSameMonth(date, month) && ignoreOutsideDate,
|
|
278
|
+
isEmptyCell: !isSameMonth(date.val, month) && ignoreOutsideDate,
|
|
281
279
|
isBlocked: isBlocked,
|
|
282
280
|
selectionType: dateSelectionType,
|
|
283
281
|
children: /*#__PURE__*/_jsx(DateComponent, {
|
|
284
|
-
date: date,
|
|
282
|
+
date: date.val,
|
|
285
283
|
modifiers: dateModifiers,
|
|
286
|
-
"aria-label":
|
|
284
|
+
"aria-label": date.customLabel,
|
|
287
285
|
onClick: onDateClick,
|
|
288
286
|
onDateKeyDown: onDateKeyDown,
|
|
289
287
|
preventKeyboardFocus: preventKeyboardFocus,
|
|
290
288
|
isKeyboardFocusable: isKeyboardFocusable,
|
|
291
|
-
isFocused: focusedDate && isSameDay(date, focusedDate),
|
|
292
|
-
isSelected: getSelectedDate(date, selectionConfiguration),
|
|
289
|
+
isFocused: focusedDate && isSameDay(date.val, focusedDate),
|
|
290
|
+
isSelected: getSelectedDate(date.val, selectionConfiguration),
|
|
293
291
|
isBlocked: isBlocked,
|
|
294
|
-
isOutside: markOutsideDays && !isSameMonth(date, month),
|
|
295
|
-
isToday: markToday && isToday(date),
|
|
292
|
+
isOutside: markOutsideDays && !isSameMonth(date.val, month),
|
|
293
|
+
isToday: markToday && isToday(date.val),
|
|
296
294
|
selectionType: dateSelectionType,
|
|
295
|
+
isoLabel: date.isoLabel,
|
|
297
296
|
...dateProps
|
|
298
297
|
})
|
|
299
|
-
}, date.getDate());
|
|
298
|
+
}, date.val.getDate());
|
|
300
299
|
})
|
|
301
300
|
});
|
|
302
301
|
}
|
|
@@ -105,7 +105,7 @@ const composeCalendar = (Nav, GridHeader, Grid, CalendarDate) => {
|
|
|
105
105
|
DateComponent: CalendarDate,
|
|
106
106
|
dateModifiers: dateModifiers,
|
|
107
107
|
daysOfWeek: daysOfWeek,
|
|
108
|
-
formatDateFull: formatDateFull,
|
|
108
|
+
formatDateFull: memoize(formatDateFull),
|
|
109
109
|
formatMonth: memoize(formatMonth),
|
|
110
110
|
month: month,
|
|
111
111
|
onDateClick: onDateClick,
|
|
@@ -17,9 +17,11 @@ import { lastDayOfMonth } from 'date-fns/lastDayOfMonth';
|
|
|
17
17
|
import { parseISO } from 'date-fns/parseISO';
|
|
18
18
|
import { startOfDay } from 'date-fns/startOfDay';
|
|
19
19
|
import { startOfMonth } from 'date-fns/startOfMonth';
|
|
20
|
+
import type { DateProps } from './BpkCalendarGrid';
|
|
20
21
|
import type { DaysOfWeek } from './custom-proptypes';
|
|
21
22
|
declare function daysInMonth(year: number, month: number): number;
|
|
22
|
-
declare function
|
|
23
|
+
declare function getCalendarNoCustomLabel(date: Date, weekStartsOn: number): DateProps[][];
|
|
24
|
+
declare function getCalendar(date: Date, weekStartsOn: number, formatDate: (d: Date) => Date | string): DateProps[][];
|
|
23
25
|
declare function getLastDayOfWeekend(daysOfWeek: DaysOfWeek): number;
|
|
24
26
|
declare function getFirstDayOfWeekend(daysOfWeek: DaysOfWeek): number;
|
|
25
27
|
declare const orderDaysOfWeek: (daysOfWeek: DaysOfWeek, weekStartsOn: number) => import("./custom-proptypes").WeekDay[];
|
|
@@ -33,4 +35,4 @@ declare const setMonthYear: (date: Date | null, newMonth: number, newYear: numbe
|
|
|
33
35
|
declare const parseIsoDate: typeof parseISO;
|
|
34
36
|
declare const formatIsoDate: (date: Date) => string;
|
|
35
37
|
declare const formatIsoMonth: (date: Date) => string;
|
|
36
|
-
export {
|
|
38
|
+
export { getCalendar, getCalendarNoCustomLabel, getFirstDayOfWeekend, getLastDayOfWeekend, getMonthsInRange, getMonthRange, getDay, dateToBoundaries, isWithinRange, isSaturday, isSunday, isToday, isSameDay, isSameWeek, isSameMonth, isBefore, isAfter, differenceInCalendarMonths, addMonths, addDays, orderDaysOfWeek, setMonthYear, startOfMonth, lastDayOfMonth, startOfDay, format, daysInMonth, formatIsoDate, formatIsoMonth, parseIsoDate, endOfMonth, };
|
|
@@ -84,13 +84,24 @@ function startOfWeek(year, month, day, weekStartsOn) {
|
|
|
84
84
|
date.setUTCDate(date.getUTCDate() - diff);
|
|
85
85
|
return [date.getUTCFullYear(), date.getUTCMonth(), date.getUTCDate()];
|
|
86
86
|
}
|
|
87
|
-
function
|
|
87
|
+
function getCalendarNoCustomLabel(date, weekStartsOn) {
|
|
88
|
+
return getCalendarMonthWeeks(date, weekStartsOn);
|
|
89
|
+
}
|
|
90
|
+
function getCalendar(date, weekStartsOn, formatDate) {
|
|
91
|
+
return getCalendarMonthWeeks(date, weekStartsOn, formatDate);
|
|
92
|
+
}
|
|
93
|
+
function getCalendarMonthWeeks(date, weekStartsOn, formatDate) {
|
|
88
94
|
let [year, month, day] = startOfWeek(date.getFullYear(), date.getMonth(), 1, weekStartsOn);
|
|
89
95
|
const weeksInMonth = [];
|
|
90
96
|
for (let i = 0; i < 6; i += 1) {
|
|
91
97
|
const currWeek = [];
|
|
92
98
|
for (let j = 0; j < 7; j += 1) {
|
|
93
|
-
|
|
99
|
+
const currDate = dateAtStartOfDay(year, month, day);
|
|
100
|
+
currWeek.push({
|
|
101
|
+
val: currDate,
|
|
102
|
+
isoLabel: formatIsoDate(currDate),
|
|
103
|
+
customLabel: formatDate ? formatDate(currDate) : ''
|
|
104
|
+
});
|
|
94
105
|
[year, month, day] = addDay(year, month, day);
|
|
95
106
|
}
|
|
96
107
|
weeksInMonth.push(currWeek);
|
|
@@ -170,4 +181,4 @@ const setMonthYear = (date, newMonth, newYear) => {
|
|
|
170
181
|
const parseIsoDate = parseISO;
|
|
171
182
|
const formatIsoDate = date => format(date, 'yyyy-MM-dd');
|
|
172
183
|
const formatIsoMonth = date => format(date, 'yyyy-MM');
|
|
173
|
-
export {
|
|
184
|
+
export { getCalendar, getCalendarNoCustomLabel, getFirstDayOfWeekend, getLastDayOfWeekend, getMonthsInRange, getMonthRange, getDay, dateToBoundaries, isWithinRange, isSaturday, isSunday, isToday, isSameDay, isSameWeek, isSameMonth, isBefore, isAfter, differenceInCalendarMonths, addMonths, addDays, orderDaysOfWeek, setMonthYear, startOfMonth, lastDayOfMonth, startOfDay, format, daysInMonth, formatIsoDate, formatIsoMonth, parseIsoDate, endOfMonth };
|
|
@@ -32,7 +32,7 @@ export type Props = CloseButtonProps & {
|
|
|
32
32
|
closeButtonLabel?: string;
|
|
33
33
|
actionText?: string;
|
|
34
34
|
onAction?: () => void;
|
|
35
|
-
renderTarget?: () => HTMLElement | HTMLElement |
|
|
35
|
+
renderTarget?: () => HTMLElement | HTMLElement | undefined;
|
|
36
36
|
};
|
|
37
37
|
declare const BpkPopover: ({ actionText, children, className, closeButtonIcon, closeButtonLabel, closeButtonProps, closeButtonText, hoverable, id, isOpen, label, labelAsTitle, onAction, onClose, padded, placement, renderTarget, showArrow, target, ...rest }: Props) => import("react/jsx-runtime").JSX.Element;
|
|
38
38
|
export default BpkPopover;
|
|
@@ -8,7 +8,7 @@ import isRTL from './src/isRTL';
|
|
|
8
8
|
import { setNativeValue } from './src/nativeEventHandler';
|
|
9
9
|
import withDefaultProps from './src/withDefaultProps';
|
|
10
10
|
import wrapDisplayName from './src/wrapDisplayName';
|
|
11
|
-
export { Portal, TransitionInitialMount, cssModules, deprecated, withDefaultProps, wrapDisplayName, isDeviceIphone, isDeviceIpad, isDeviceIos, isRTL, BpkDialogWrapper, setNativeValue };
|
|
11
|
+
export { Portal, TransitionInitialMount, cssModules, deprecated, withDefaultProps, wrapDisplayName, isDeviceIphone, isDeviceIpad, isDeviceIos, isRTL, BpkDialogWrapper, setNativeValue, };
|
|
12
12
|
declare const _default: {
|
|
13
13
|
Portal: typeof Portal;
|
|
14
14
|
TransitionInitialMount: ({ appearActiveClassName, appearClassName, children, transitionTimeout, }: {
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Mock deferCallback to immediately invoke the callback. This ensures that
|
|
3
|
+
* asynchronous state updates triggered by `deferCallback` run before asserting.
|
|
4
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
|
5
|
+
* @param {function} callback - callback to execute, value cannot be returned.
|
|
6
|
+
* You'll typically want to wrap the callback `setState` to update React state.
|
|
7
|
+
* @returns {void}
|
|
8
|
+
*/
|
|
9
|
+
export default function deferCallback(callback: () => void): void;
|
package/{bpk-component-carousel/src/utils.test.js → bpk-react-utils/src/__mocks__/deferCallback.js}
RENAMED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
/*
|
|
2
2
|
* Backpack - Skyscanner's Design System
|
|
3
3
|
*
|
|
4
|
-
* Copyright
|
|
4
|
+
* Copyright 2016 Skyscanner Ltd
|
|
5
5
|
*
|
|
6
6
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
7
7
|
* you may not use this file except in compliance with the License.
|
|
@@ -16,15 +16,14 @@
|
|
|
16
16
|
* limitations under the License.
|
|
17
17
|
*/
|
|
18
18
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
});
|
|
19
|
+
/**
|
|
20
|
+
* Mock deferCallback to immediately invoke the callback. This ensures that
|
|
21
|
+
* asynchronous state updates triggered by `deferCallback` run before asserting.
|
|
22
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
|
23
|
+
* @param {function} callback - callback to execute, value cannot be returned.
|
|
24
|
+
* You'll typically want to wrap the callback `setState` to update React state.
|
|
25
|
+
* @returns {void}
|
|
26
|
+
*/
|
|
27
|
+
export default function deferCallback(callback) {
|
|
28
|
+
callback();
|
|
29
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Defer a task until the browser is idle, or till the next "tick" if the
|
|
3
|
+
* browser does not support the idle callback API. This is useful for deferring
|
|
4
|
+
* computationally heavy, non-essential tasks to keep the UI responsive. If the
|
|
5
|
+
* task has not completed within the timeout, it will be executed regardless.
|
|
6
|
+
*
|
|
7
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
|
8
|
+
* @param {function} callback - callback to execute, value cannot be returned.
|
|
9
|
+
* You'll typically want to wrap the callback `setState` to update React state.
|
|
10
|
+
* @returns {void}
|
|
11
|
+
*/
|
|
12
|
+
declare const deferCallback: (callback: () => void) => void;
|
|
13
|
+
export default deferCallback;
|
|
@@ -0,0 +1,39 @@
|
|
|
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
|
+
* Defer a task until the browser is idle, or till the next "tick" if the
|
|
21
|
+
* browser does not support the idle callback API. This is useful for deferring
|
|
22
|
+
* computationally heavy, non-essential tasks to keep the UI responsive. If the
|
|
23
|
+
* task has not completed within the timeout, it will be executed regardless.
|
|
24
|
+
*
|
|
25
|
+
* https://developer.mozilla.org/en-US/docs/Web/API/Window/requestIdleCallback
|
|
26
|
+
* @param {function} callback - callback to execute, value cannot be returned.
|
|
27
|
+
* You'll typically want to wrap the callback `setState` to update React state.
|
|
28
|
+
* @returns {void}
|
|
29
|
+
*/
|
|
30
|
+
const deferCallback = callback => {
|
|
31
|
+
if (window.requestIdleCallback) {
|
|
32
|
+
window.requestIdleCallback(callback, {
|
|
33
|
+
timeout: 500
|
|
34
|
+
});
|
|
35
|
+
} else {
|
|
36
|
+
setTimeout(callback, 0);
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
export default deferCallback;
|