@skyscanner/backpack-web 42.23.0-dev-v26810456218.1 → 42.24.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.
- package/bpk-component-card-list/src/BpkCardList.js +3 -0
- package/bpk-component-card-list/src/BpkCardListRowRail/BpkCardListCarousel.js +3 -1
- package/bpk-component-card-list/src/BpkCardListRowRail/BpkCardListRowRailContainer.js +14 -1
- package/bpk-component-card-list/src/BpkCardListRowRail/utils.d.ts +2 -1
- package/bpk-component-card-list/src/BpkCardListRowRail/utils.js +21 -0
- package/bpk-component-card-list/src/common-types.d.ts +3 -0
- package/bpk-component-page-indicator/src/BpkPageIndicator.module.css +1 -1
- package/package.json +1 -1
|
@@ -38,6 +38,7 @@ const BpkCardList = props => {
|
|
|
38
38
|
chipGroup,
|
|
39
39
|
description,
|
|
40
40
|
expandText,
|
|
41
|
+
initiallyInViewCardIndex = 0,
|
|
41
42
|
initiallyShownCardsDesktop = DEFAULT_ITEMS_DESKTOP,
|
|
42
43
|
initiallyShownCardsMobile = DEFAULT_ITEMS_MOBILE,
|
|
43
44
|
layoutDesktop,
|
|
@@ -78,6 +79,7 @@ const BpkCardList = props => {
|
|
|
78
79
|
initiallyShownCards: initiallyShownCardsMobile,
|
|
79
80
|
layout: layoutMobile,
|
|
80
81
|
accessibilityLabels: accessibilityLabels,
|
|
82
|
+
initiallyInViewCardIndex: initiallyInViewCardIndex,
|
|
81
83
|
isMobile: true,
|
|
82
84
|
children: cardList
|
|
83
85
|
}), layoutMobile === LAYOUTS.stack && /*#__PURE__*/_jsx(BpkCardListGridStack, {
|
|
@@ -97,6 +99,7 @@ const BpkCardList = props => {
|
|
|
97
99
|
initiallyShownCards: initiallyShownCardsDesktop,
|
|
98
100
|
layout: layoutDesktop,
|
|
99
101
|
accessibilityLabels: accessibilityLabels,
|
|
102
|
+
initiallyInViewCardIndex: initiallyInViewCardIndex,
|
|
100
103
|
children: cardList
|
|
101
104
|
}), layoutDesktop === LAYOUTS.grid && accessoryDesktop !== ACCESSORY_DESKTOP_TYPES.pagination && /*#__PURE__*/_jsx(BpkCardListGridStack, {
|
|
102
105
|
accessory: accessoryDesktop,
|
|
@@ -30,6 +30,7 @@ const BpkCardListCarousel = props => {
|
|
|
30
30
|
carouselLabel = (initiallyShownCards, childrenLength) => `Entering Carousel with ${initiallyShownCards} slides shown at a time, ${childrenLength} slides in total. Please use Pagination below with the Previous and Next buttons to navigate, or the slide dot buttons at the end to jump to slides.`,
|
|
31
31
|
children,
|
|
32
32
|
currentIndex,
|
|
33
|
+
initialPageIndex,
|
|
33
34
|
initiallyShownCards,
|
|
34
35
|
isMobile = false,
|
|
35
36
|
layout,
|
|
@@ -58,7 +59,8 @@ const BpkCardListCarousel = props => {
|
|
|
58
59
|
cardRefs,
|
|
59
60
|
visibilityList,
|
|
60
61
|
container: root,
|
|
61
|
-
enabled: !isMobile
|
|
62
|
+
enabled: !isMobile,
|
|
63
|
+
initialPageIndex
|
|
62
64
|
});
|
|
63
65
|
|
|
64
66
|
// Similar to Virtual Scrolling to improve performance
|
|
@@ -28,6 +28,7 @@ const BpkCardListRowRailContainer = props => {
|
|
|
28
28
|
accessibilityLabels,
|
|
29
29
|
accessory,
|
|
30
30
|
children,
|
|
31
|
+
initiallyInViewCardIndex,
|
|
31
32
|
initiallyShownCards,
|
|
32
33
|
isMobile = false,
|
|
33
34
|
layout
|
|
@@ -35,7 +36,18 @@ const BpkCardListRowRailContainer = props => {
|
|
|
35
36
|
const childrenCount = Children.count(children);
|
|
36
37
|
const totalIndicators = Math.ceil(childrenCount / initiallyShownCards);
|
|
37
38
|
const showAccessory = childrenCount > initiallyShownCards;
|
|
38
|
-
|
|
39
|
+
|
|
40
|
+
// Calculate initial page from card index
|
|
41
|
+
const [initialPageIndex] = useState(() => {
|
|
42
|
+
if (initiallyInViewCardIndex < 0) {
|
|
43
|
+
return 0;
|
|
44
|
+
}
|
|
45
|
+
if (initiallyInViewCardIndex >= childrenCount) {
|
|
46
|
+
return Math.max(0, totalIndicators - 1);
|
|
47
|
+
}
|
|
48
|
+
return Math.floor(initiallyInViewCardIndex / initiallyShownCards);
|
|
49
|
+
});
|
|
50
|
+
const [currentIndex, setCurrentIndex] = useState(initialPageIndex);
|
|
39
51
|
const accessoryContent = layout === LAYOUTS.row && accessory === ACCESSORY_DESKTOP_TYPES.pagination ? /*#__PURE__*/_jsx(BpkPageIndicator, {
|
|
40
52
|
currentIndex: currentIndex,
|
|
41
53
|
totalIndicators: totalIndicators,
|
|
@@ -57,6 +69,7 @@ const BpkCardListRowRailContainer = props => {
|
|
|
57
69
|
isMobile: isMobile,
|
|
58
70
|
carouselLabel: accessibilityLabels?.carouselLabel,
|
|
59
71
|
slideLabel: accessibilityLabels?.slideLabel,
|
|
72
|
+
initialPageIndex: initialPageIndex,
|
|
60
73
|
children: children
|
|
61
74
|
}), accessoryContent && showAccessory && /*#__PURE__*/_jsx("div", {
|
|
62
75
|
role: "region",
|
|
@@ -15,6 +15,7 @@ type UsePageScrollSyncOptions = {
|
|
|
15
15
|
visibilityList: number[];
|
|
16
16
|
container: HTMLElement | null;
|
|
17
17
|
enabled: boolean;
|
|
18
|
+
initialPageIndex: number;
|
|
18
19
|
};
|
|
19
20
|
/**
|
|
20
21
|
* Provides bidirectional synchronisation between page index state and scroll position.
|
|
@@ -27,5 +28,5 @@ type UsePageScrollSyncOptions = {
|
|
|
27
28
|
* The hook uses a lock mechanism to prevent conflicts between programmatic and
|
|
28
29
|
* user-initiated scrolling.
|
|
29
30
|
*/
|
|
30
|
-
export declare const usePageScrollSync: ({ cardRefs, container, currentIndex, enabled, initiallyShownCards, setCurrentIndex, visibilityList, }: UsePageScrollSyncOptions) => void;
|
|
31
|
+
export declare const usePageScrollSync: ({ cardRefs, container, currentIndex, enabled, initialPageIndex, initiallyShownCards, setCurrentIndex, visibilityList, }: UsePageScrollSyncOptions) => void;
|
|
31
32
|
export {};
|
|
@@ -98,6 +98,7 @@ export const usePageScrollSync = ({
|
|
|
98
98
|
container,
|
|
99
99
|
currentIndex,
|
|
100
100
|
enabled,
|
|
101
|
+
initialPageIndex,
|
|
101
102
|
initiallyShownCards,
|
|
102
103
|
setCurrentIndex,
|
|
103
104
|
visibilityList
|
|
@@ -105,6 +106,26 @@ export const usePageScrollSync = ({
|
|
|
105
106
|
const isUserScrollingRef = useRef(false);
|
|
106
107
|
const scrollEndTimeoutRef = useRef(null);
|
|
107
108
|
const lastCurrentIndexRef = useRef(currentIndex);
|
|
109
|
+
const hasInitialScrolled = useRef(false);
|
|
110
|
+
|
|
111
|
+
// Effect 0: Initial scroll (instant, runs once on mount)
|
|
112
|
+
useEffect(() => {
|
|
113
|
+
if (hasInitialScrolled.current) {
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
116
|
+
hasInitialScrolled.current = true;
|
|
117
|
+
if (!enabled || initialPageIndex === 0) {
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
const targetCard = cardRefs.current?.[initialPageIndex * initiallyShownCards];
|
|
121
|
+
if (targetCard) {
|
|
122
|
+
targetCard.scrollIntoView({
|
|
123
|
+
behavior: 'instant',
|
|
124
|
+
block: 'nearest',
|
|
125
|
+
inline: 'start'
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
}, [cardRefs, enabled, initialPageIndex, initiallyShownCards]); // Run once on mount only
|
|
108
129
|
|
|
109
130
|
// Effect 1: Programmatic scroll when currentIndex changes
|
|
110
131
|
useEffect(() => {
|
|
@@ -36,6 +36,7 @@ type CardListBaseProps = {
|
|
|
36
36
|
accessoryMobile?: (typeof ACCESSORY_MOBILE_TYPES)[keyof typeof ACCESSORY_MOBILE_TYPES];
|
|
37
37
|
initiallyShownCardsDesktop?: number;
|
|
38
38
|
initiallyShownCardsMobile?: number;
|
|
39
|
+
initiallyInViewCardIndex?: number;
|
|
39
40
|
chipGroup?: ReactElement;
|
|
40
41
|
buttonContent?: React.ReactNode;
|
|
41
42
|
onButtonClick?: () => void;
|
|
@@ -69,6 +70,7 @@ type CardListRowRailProps = {
|
|
|
69
70
|
accessory?: typeof ACCESSORY_DESKTOP_TYPES.pagination;
|
|
70
71
|
isMobile?: boolean;
|
|
71
72
|
accessibilityLabels?: AccessibilityLabels;
|
|
73
|
+
initiallyInViewCardIndex: number;
|
|
72
74
|
};
|
|
73
75
|
type CardListCarouselProps = {
|
|
74
76
|
children: Array<ReactElement<HTMLDivElement | HTMLAnchorElement>>;
|
|
@@ -79,6 +81,7 @@ type CardListCarouselProps = {
|
|
|
79
81
|
isMobile?: boolean;
|
|
80
82
|
carouselLabel?: (initiallyShownCards: number, childrenLength: number) => string;
|
|
81
83
|
slideLabel?: (index: number, childrenLength: number) => string;
|
|
84
|
+
initialPageIndex: number;
|
|
82
85
|
};
|
|
83
86
|
type CardListProps = CardListBaseProps;
|
|
84
87
|
export default CardListProps;
|
|
@@ -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-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,.bpk-page-indicator__indicator--carousel{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,.bpk-page-indicator__indicator--active-carousel{background-color:#fff;pointer-events:none}.bpk-page-indicator__nav-carousel{--bpk-button-border-radius: 50%;--bpk-button-secondary-on-dark-background-color: rgba(255, 255, 255, 0.5);--bpk-button-secondary-on-dark-hover-background-color: rgba(255, 255, 255, 0.8);--bpk-button-secondary-on-dark-active-background-color: rgba(255, 255, 255, 0.8);--bpk-button-secondary-on-dark-text-color: rgb(22, 22, 22);--bpk-button-secondary-on-dark-hover-text-color: rgb(22, 22, 22);--bpk-button-secondary-on-dark-active-text-color: rgb(22, 22, 22)}.bpk-page-indicator__nav-carousel-button{display:inline-flex;width:2rem;height:2rem;min-height:2rem;padding:0;justify-content:center;align-items:center}
|
|
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,.bpk-page-indicator__indicator--carousel{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,.bpk-page-indicator__indicator--active-carousel{background-color:#fff;pointer-events:none}.bpk-page-indicator__nav-carousel{--bpk-button-border-radius: 50%;--bpk-button-secondary-on-dark-background-color: rgba(255, 255, 255, 0.5);--bpk-button-secondary-on-dark-hover-background-color: rgba(255, 255, 255, 0.8);--bpk-button-secondary-on-dark-active-background-color: rgba(255, 255, 255, 0.8);--bpk-button-secondary-on-dark-text-color: rgb(22, 22, 22);--bpk-button-secondary-on-dark-hover-text-color: rgb(22, 22, 22);--bpk-button-secondary-on-dark-active-text-color: rgb(22, 22, 22)}.bpk-page-indicator__nav-carousel .bpk-page-indicator__nav-carousel-button{display:inline-flex;width:2rem;height:2rem;min-height:2rem;padding:0;justify-content:center;align-items:center}
|