From feb1953772037cb54bac660c092d20fc3900c5eb Mon Sep 17 00:00:00 2001 From: Dilshod Turobov Date: Sat, 26 Sep 2026 16:55:10 +0200 Subject: [PATCH] carousel: subscribe before calling setApi The lint fix in #211 left the listeners in an effect declared after the one that calls setApi. Effects run in order, so a consumer that scrolls as soon as it gets the api (e.g. `setApi={(api) => api?.scrollTo(2, true)}`) moved the carousel before anyone was listening. The triggers and indicators then stayed on slide 1. Subscribing first fixes it, with no setState in an effect. --- components/application/carousel/carousel-base.tsx | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/components/application/carousel/carousel-base.tsx b/components/application/carousel/carousel-base.tsx index 2073b6b..ffddd0e 100644 --- a/components/application/carousel/carousel-base.tsx +++ b/components/application/carousel/carousel-base.tsx @@ -109,12 +109,8 @@ const CarouselRoot = ({ orientation = "horizontal", opts, setApi, plugins, class [scrollPrev, scrollNext], ); - useEffect(() => { - if (!api || !setApi) return; - - setApi(api); - }, [api, setApi]); - + // Subscribe before handing the api to setApi: effects run in order, so a consumer that + // scrolls as soon as it gets the api must find these listeners already attached. useEffect(() => { if (!api) return; @@ -129,6 +125,12 @@ const CarouselRoot = ({ orientation = "horizontal", opts, setApi, plugins, class }; }, [api, onInit, onSelect]); + useEffect(() => { + if (!api || !setApi) return; + + setApi(api); + }, [api, setApi]); + return (