From 2e875fa3d52d80ddba210ebd16b68ce972fda21a Mon Sep 17 00:00:00 2001 From: Aleksander Grygier Date: Fri, 21 Aug 2026 08:46:22 +0200 Subject: [PATCH] ui : fix carousel scrollability detection Observe the content wrapper as well as the container, since adding overflowing items does not change the container's own box size. Also expose an onScrollableChange callback. Assisted-by: pi --- .../lib/hooks/use-scroll-carousel.svelte.ts | 28 ++++++++++++++++--- 1 file changed, 24 insertions(+), 4 deletions(-) diff --git a/tools/ui/src/lib/hooks/use-scroll-carousel.svelte.ts b/tools/ui/src/lib/hooks/use-scroll-carousel.svelte.ts index d23b8536b8..9d1043d8bf 100644 --- a/tools/ui/src/lib/hooks/use-scroll-carousel.svelte.ts +++ b/tools/ui/src/lib/hooks/use-scroll-carousel.svelte.ts @@ -1,7 +1,8 @@ -export function useScrollCarousel() { +export function useScrollCarousel(onScrollableChange?: (isScrollable: boolean) => void) { let canScrollLeft = $state(false); let canScrollRight = $state(false); let scrollContainer = $state(); + let contentContainer = $state(); function scrollToCenter(element: HTMLElement) { if (!scrollContainer) return; @@ -34,12 +35,25 @@ export function useScrollCarousel() { canScrollLeft = sl > 0; canScrollRight = sl < scrollWidth - clientWidth - 1; + + onScrollableChange?.(scrollWidth > clientWidth); } + // Re-evaluate arrow visibility whenever the container or its content resizes, + // otherwise the arrows may not appear when overflowing items are added (e.g. new + // tabs/attachments) and the user has not scrolled yet. $effect(() => { - if (scrollContainer) { - updateScrollButtons(); - } + if (!scrollContainer) return; + + updateScrollButtons(); + + const observer = new ResizeObserver(() => updateScrollButtons()); + + observer.observe(scrollContainer); + + if (contentContainer) observer.observe(contentContainer); + + return () => observer.disconnect(); }); return { @@ -49,6 +63,12 @@ export function useScrollCarousel() { get canScrollRight() { return canScrollRight; }, + get contentContainer() { + return contentContainer; + }, + set contentContainer(el: HTMLDivElement | undefined) { + contentContainer = el; + }, get scrollContainer() { return scrollContainer; },