fix: handle edge cases in continue watching carousel

This commit is contained in:
2026-06-06 17:26:41 +02:00
committed by Milas Holsting
parent 5c10bd1a5a
commit 24d77cfe98

View File

@@ -13,17 +13,11 @@ type ContinueWatchingCarousel = {
nextFade: HTMLElement; nextFade: HTMLElement;
}; };
const getContinueWatchingCarousel = ( const getContinueWatchingCarousel = (root: HTMLElement): ContinueWatchingCarousel | null => {
root: HTMLElement,
): ContinueWatchingCarousel | null => {
const track = root.querySelector<HTMLElement>("[data-continue-watching-track]"); const track = root.querySelector<HTMLElement>("[data-continue-watching-track]");
const previous = root.querySelector<HTMLButtonElement>( const previous = root.querySelector<HTMLButtonElement>("[data-continue-watching-prev]");
"[data-continue-watching-prev]",
);
const next = root.querySelector<HTMLButtonElement>("[data-continue-watching-next]"); const next = root.querySelector<HTMLButtonElement>("[data-continue-watching-next]");
const previousFade = root.querySelector<HTMLElement>( const previousFade = root.querySelector<HTMLElement>("[data-continue-watching-prev-fade]");
"[data-continue-watching-prev-fade]",
);
const nextFade = root.querySelector<HTMLElement>("[data-continue-watching-next-fade]"); const nextFade = root.querySelector<HTMLElement>("[data-continue-watching-next-fade]");
if (!track || !previous || !next || !previousFade || !nextFade) { if (!track || !previous || !next || !previousFade || !nextFade) {
@@ -39,11 +33,7 @@ const continueWatchingCarousels = (root: ParentNode = document): HTMLElement[] =
const maxScrollLeft = (track: HTMLElement): number => const maxScrollLeft = (track: HTMLElement): number =>
Math.max(0, track.scrollWidth - track.clientWidth); Math.max(0, track.scrollWidth - track.clientWidth);
const setControlState = ( const setControlState = (button: HTMLButtonElement, fade: HTMLElement, visible: boolean): void => {
button: HTMLButtonElement,
fade: HTMLElement,
visible: boolean,
): void => {
button.classList.toggle("hidden", !visible); button.classList.toggle("hidden", !visible);
button.classList.toggle("inline-flex", visible); button.classList.toggle("inline-flex", visible);
button.setAttribute("aria-hidden", String(!visible)); button.setAttribute("aria-hidden", String(!visible));
@@ -61,10 +51,8 @@ const updateContinueWatchingCarousel = (root: HTMLElement): void => {
const maxScroll = maxScrollLeft(carousel.track); const maxScroll = maxScrollLeft(carousel.track);
const canScroll = maxScroll > carouselScrollEpsilon; const canScroll = maxScroll > carouselScrollEpsilon;
const allowArrows = canScroll && items.length >= minimumArrowItems; const allowArrows = canScroll && items.length >= minimumArrowItems;
const hasPrevious = const hasPrevious = allowArrows && carousel.track.scrollLeft > carouselScrollEpsilon;
allowArrows && carousel.track.scrollLeft > carouselScrollEpsilon; const hasNext = allowArrows && carousel.track.scrollLeft < maxScroll - carouselScrollEpsilon;
const hasNext =
allowArrows && carousel.track.scrollLeft < maxScroll - carouselScrollEpsilon;
setControlState(carousel.previous, carousel.previousFade, hasPrevious); setControlState(carousel.previous, carousel.previousFade, hasPrevious);
setControlState(carousel.next, carousel.nextFade, hasNext); setControlState(carousel.next, carousel.nextFade, hasNext);
@@ -86,10 +74,7 @@ const carouselScrollAmount = (track: HTMLElement): number => {
return Math.max(itemWidth, track.clientWidth - Math.min(itemWidth, overlap)); return Math.max(itemWidth, track.clientWidth - Math.min(itemWidth, overlap));
}; };
const scrollContinueWatchingCarousel = ( const scrollContinueWatchingCarousel = (root: HTMLElement, direction: -1 | 1): void => {
root: HTMLElement,
direction: -1 | 1,
): void => {
const carousel = getContinueWatchingCarousel(root); const carousel = getContinueWatchingCarousel(root);
if (!carousel) { if (!carousel) {
return; return;
@@ -150,10 +135,7 @@ document.addEventListener(
"scroll", "scroll",
(event: Event): void => { (event: Event): void => {
const target = event.target; const target = event.target;
if ( if (!(target instanceof HTMLElement) || !target.matches("[data-continue-watching-track]")) {
!(target instanceof HTMLElement) ||
!target.matches("[data-continue-watching-track]")
) {
return; return;
} }