@present-day/carousel 0.0.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/dist/index.js ADDED
@@ -0,0 +1,485 @@
1
+ 'use client';
2
+ "use strict";
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+ var __copyProps = (to, from, except, desc) => {
12
+ if (from && typeof from === "object" || typeof from === "function") {
13
+ for (let key of __getOwnPropNames(from))
14
+ if (!__hasOwnProp.call(to, key) && key !== except)
15
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
16
+ }
17
+ return to;
18
+ };
19
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
20
+
21
+ // src/index.ts
22
+ var index_exports = {};
23
+ __export(index_exports, {
24
+ CAROUSEL_ALIGN: () => CAROUSEL_ALIGN,
25
+ CAROUSEL_ORIENTATION: () => CAROUSEL_ORIENTATION,
26
+ Carousel: () => Carousel2
27
+ });
28
+ module.exports = __toCommonJS(index_exports);
29
+
30
+ // src/context.ts
31
+ var import_react = require("react");
32
+ var CarouselContext = (0, import_react.createContext)(null);
33
+ function useCarouselContext(component) {
34
+ const context = (0, import_react.useContext)(CarouselContext);
35
+ if (!context) {
36
+ throw new Error(`<${component}> must be used within <Carousel>`);
37
+ }
38
+ return context;
39
+ }
40
+ var SlideIndexContext = (0, import_react.createContext)(-1);
41
+
42
+ // src/Buttons.tsx
43
+ var import_jsx_runtime = require("react/jsx-runtime");
44
+ function Prev({
45
+ className,
46
+ style,
47
+ children,
48
+ "aria-label": ariaLabel = "Previous slide"
49
+ }) {
50
+ const { activeIndex, scrollToIndex } = useCarouselContext("Carousel.Prev");
51
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
52
+ "button",
53
+ {
54
+ type: "button",
55
+ "aria-label": ariaLabel,
56
+ disabled: activeIndex <= 0,
57
+ onClick: () => scrollToIndex(activeIndex - 1),
58
+ className,
59
+ style,
60
+ children
61
+ }
62
+ );
63
+ }
64
+ function Next({
65
+ className,
66
+ style,
67
+ children,
68
+ "aria-label": ariaLabel = "Next slide"
69
+ }) {
70
+ const { activeIndex, slideCount, scrollToIndex } = useCarouselContext("Carousel.Next");
71
+ return /* @__PURE__ */ (0, import_jsx_runtime.jsx)(
72
+ "button",
73
+ {
74
+ type: "button",
75
+ "aria-label": ariaLabel,
76
+ disabled: activeIndex >= slideCount - 1,
77
+ onClick: () => scrollToIndex(activeIndex + 1),
78
+ className,
79
+ style,
80
+ children
81
+ }
82
+ );
83
+ }
84
+
85
+ // src/Carousel.tsx
86
+ var import_react4 = require("react");
87
+
88
+ // src/join.ts
89
+ function join(...parts) {
90
+ const joined = parts.filter(Boolean).join(" ");
91
+ return joined === "" ? void 0 : joined;
92
+ }
93
+
94
+ // src/Slide.tsx
95
+ var import_react2 = require("react");
96
+ var import_jsx_runtime2 = (
97
+ // biome-ignore lint/a11y/useSemanticElements: explicit role required by ARIA slide pattern
98
+ require("react/jsx-runtime")
99
+ );
100
+ function Slide({ children, className, style }) {
101
+ const context = useCarouselContext("Carousel.Slide");
102
+ const index = (0, import_react2.useContext)(SlideIndexContext);
103
+ const { registerSlide } = context;
104
+ const ref = (0, import_react2.useCallback)(
105
+ (el) => {
106
+ registerSlide(index, el);
107
+ },
108
+ [registerSlide, index]
109
+ );
110
+ return /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
111
+ "div",
112
+ {
113
+ ref,
114
+ id: context.getSlideId(index),
115
+ role: "group",
116
+ "aria-roledescription": "slide",
117
+ "aria-label": `${index + 1} of ${context.slideCount}`,
118
+ className: join(context.slideClassName, className),
119
+ style: { scrollSnapAlign: context.align, flexShrink: 0, ...style },
120
+ children
121
+ }
122
+ );
123
+ }
124
+
125
+ // src/types.ts
126
+ var CAROUSEL_ORIENTATION = {
127
+ horizontal: "horizontal",
128
+ vertical: "vertical"
129
+ };
130
+ var CAROUSEL_ALIGN = {
131
+ start: "start",
132
+ center: "center"
133
+ };
134
+
135
+ // src/snapMath.ts
136
+ function getActiveFromScroll(scrollPos, snapPositions) {
137
+ let best = 0;
138
+ let bestDist = Number.POSITIVE_INFINITY;
139
+ for (let i = 0; i < snapPositions.length; i++) {
140
+ const position = snapPositions[i];
141
+ if (position === void 0) continue;
142
+ const dist = Math.abs(position - scrollPos);
143
+ if (dist < bestDist) {
144
+ bestDist = dist;
145
+ best = i;
146
+ }
147
+ }
148
+ return best;
149
+ }
150
+ function getSnapPositions(track, slides, align, orientation) {
151
+ const horizontal = orientation === CAROUSEL_ORIENTATION.horizontal;
152
+ const viewport = horizontal ? track.clientWidth : track.clientHeight;
153
+ const content = horizontal ? track.scrollWidth : track.scrollHeight;
154
+ const maxScroll = Math.max(0, content - viewport);
155
+ return slides.map((slide) => {
156
+ const offset = horizontal ? slide.offsetLeft : slide.offsetTop;
157
+ const size = horizontal ? slide.offsetWidth : slide.offsetHeight;
158
+ const raw = align === CAROUSEL_ALIGN.center ? offset - (viewport - size) / 2 : offset;
159
+ return Math.min(Math.max(raw, 0), maxScroll);
160
+ });
161
+ }
162
+
163
+ // src/support.ts
164
+ function supportsSnapEvents() {
165
+ return typeof window !== "undefined" && "onscrollsnapchange" in window;
166
+ }
167
+ function supportsScrollEnd() {
168
+ return typeof window !== "undefined" && "onscrollend" in window;
169
+ }
170
+ function prefersReducedMotion() {
171
+ return typeof window !== "undefined" && window.matchMedia?.("(prefers-reduced-motion: reduce)").matches === true;
172
+ }
173
+
174
+ // src/useIsomorphicLayoutEffect.ts
175
+ var import_react3 = require("react");
176
+ var useIsomorphicLayoutEffect = typeof window !== "undefined" ? import_react3.useLayoutEffect : import_react3.useEffect;
177
+
178
+ // src/Carousel.tsx
179
+ var import_jsx_runtime3 = require("react/jsx-runtime");
180
+ var SETTLE_DEBOUNCE_MS = 150;
181
+ function Carousel({
182
+ children,
183
+ defaultSlide = 0,
184
+ slide,
185
+ onSlideChange,
186
+ orientation = CAROUSEL_ORIENTATION.horizontal,
187
+ align = CAROUSEL_ALIGN.start,
188
+ classNames,
189
+ className,
190
+ style,
191
+ "aria-label": ariaLabel
192
+ }) {
193
+ const horizontal = orientation === CAROUSEL_ORIENTATION.horizontal;
194
+ const items = import_react4.Children.toArray(children);
195
+ const slideItems = items.filter(
196
+ (item) => (0, import_react4.isValidElement)(item) && item.type === Slide
197
+ );
198
+ const otherItems = items.filter(
199
+ (item) => !((0, import_react4.isValidElement)(item) && item.type === Slide)
200
+ );
201
+ const slideCount = slideItems.length;
202
+ const trackRef = (0, import_react4.useRef)(null);
203
+ const slideElsRef = (0, import_react4.useRef)([]);
204
+ const [internalActive, setInternalActive] = (0, import_react4.useState)(defaultSlide);
205
+ const isControlled = slide !== void 0;
206
+ const rawActiveIndex = isControlled ? slide : internalActive;
207
+ const activeIndex = slideCount > 0 ? Math.min(Math.max(rawActiveIndex, 0), slideCount - 1) : rawActiveIndex;
208
+ const baseId = (0, import_react4.useId)();
209
+ const getSlideId = (0, import_react4.useCallback)(
210
+ (index) => `${baseId}-slide-${index}`,
211
+ [baseId]
212
+ );
213
+ const registerSlide = (0, import_react4.useCallback)((index, el) => {
214
+ slideElsRef.current[index] = el;
215
+ }, []);
216
+ const lastSettledRef = (0, import_react4.useRef)(isControlled ? slide : defaultSlide);
217
+ const setActive = (0, import_react4.useCallback)(
218
+ (index, settled) => {
219
+ if (!isControlled) setInternalActive(index);
220
+ if (settled && index !== lastSettledRef.current) {
221
+ lastSettledRef.current = index;
222
+ onSlideChange?.(index);
223
+ }
224
+ },
225
+ [isControlled, onSlideChange]
226
+ );
227
+ const measure = (0, import_react4.useCallback)(() => {
228
+ const track = trackRef.current;
229
+ if (!track) return [];
230
+ const slides = slideElsRef.current.filter(
231
+ (el) => el !== null
232
+ );
233
+ return getSnapPositions(track, slides, align, orientation);
234
+ }, [align, orientation]);
235
+ const scrollToIndex = (0, import_react4.useCallback)(
236
+ (index) => {
237
+ const track = trackRef.current;
238
+ if (!track || slideCount === 0) return;
239
+ const clamped = Math.min(Math.max(index, 0), slideCount - 1);
240
+ const target = measure()[clamped];
241
+ if (target === void 0) return;
242
+ const behavior = prefersReducedMotion() ? "auto" : "smooth";
243
+ track.scrollTo(
244
+ horizontal ? { left: target, behavior } : { top: target, behavior }
245
+ );
246
+ },
247
+ [horizontal, measure, slideCount]
248
+ );
249
+ useIsomorphicLayoutEffect(() => {
250
+ const track = trackRef.current;
251
+ if (!track || activeIndex <= 0) return;
252
+ const target = measure()[activeIndex];
253
+ if (target === void 0) return;
254
+ if (horizontal) track.scrollLeft = target;
255
+ else track.scrollTop = target;
256
+ }, []);
257
+ (0, import_react4.useEffect)(() => {
258
+ if (isControlled && slide !== lastSettledRef.current) {
259
+ scrollToIndex(slide);
260
+ }
261
+ }, [isControlled, slide, scrollToIndex]);
262
+ (0, import_react4.useEffect)(() => {
263
+ const track = trackRef.current;
264
+ if (!track || supportsSnapEvents()) return;
265
+ let frame = 0;
266
+ let settleTimer;
267
+ const readActive = () => getActiveFromScroll(
268
+ horizontal ? track.scrollLeft : track.scrollTop,
269
+ measure()
270
+ );
271
+ const onScroll = () => {
272
+ if (!frame) {
273
+ frame = requestAnimationFrame(() => {
274
+ frame = 0;
275
+ setActive(readActive(), false);
276
+ });
277
+ }
278
+ if (!supportsScrollEnd()) {
279
+ if (settleTimer) clearTimeout(settleTimer);
280
+ settleTimer = setTimeout(
281
+ () => setActive(readActive(), true),
282
+ SETTLE_DEBOUNCE_MS
283
+ );
284
+ }
285
+ };
286
+ const onScrollEnd = () => setActive(readActive(), true);
287
+ track.addEventListener("scroll", onScroll, { passive: true });
288
+ if (supportsScrollEnd()) track.addEventListener("scrollend", onScrollEnd);
289
+ return () => {
290
+ if (frame) cancelAnimationFrame(frame);
291
+ if (settleTimer) clearTimeout(settleTimer);
292
+ track.removeEventListener("scroll", onScroll);
293
+ track.removeEventListener("scrollend", onScrollEnd);
294
+ };
295
+ }, [horizontal, measure, setActive]);
296
+ (0, import_react4.useEffect)(() => {
297
+ const track = trackRef.current;
298
+ if (!track || !supportsSnapEvents()) return;
299
+ const indexOfTarget = (event) => {
300
+ const snapEvent = event;
301
+ const target = horizontal ? snapEvent.snapTargetInline : snapEvent.snapTargetBlock;
302
+ if (!target) return -1;
303
+ return slideElsRef.current.indexOf(target);
304
+ };
305
+ const onChanging = (event) => {
306
+ const index = indexOfTarget(event);
307
+ if (index >= 0) setActive(index, false);
308
+ };
309
+ const onChange = (event) => {
310
+ const index = indexOfTarget(event);
311
+ if (index >= 0) setActive(index, true);
312
+ };
313
+ track.addEventListener("scrollsnapchanging", onChanging);
314
+ track.addEventListener("scrollsnapchange", onChange);
315
+ return () => {
316
+ track.removeEventListener("scrollsnapchanging", onChanging);
317
+ track.removeEventListener("scrollsnapchange", onChange);
318
+ };
319
+ }, [horizontal, setActive]);
320
+ const firstDeliveryRef = (0, import_react4.useRef)(true);
321
+ (0, import_react4.useEffect)(() => {
322
+ const track = trackRef.current;
323
+ if (!track || typeof ResizeObserver === "undefined") return;
324
+ firstDeliveryRef.current = true;
325
+ const observer = new ResizeObserver(() => {
326
+ if (firstDeliveryRef.current) {
327
+ firstDeliveryRef.current = false;
328
+ return;
329
+ }
330
+ const position = horizontal ? track.scrollLeft : track.scrollTop;
331
+ setActive(getActiveFromScroll(position, measure()), false);
332
+ });
333
+ observer.observe(track);
334
+ return () => observer.disconnect();
335
+ }, [horizontal, measure, setActive]);
336
+ (0, import_react4.useEffect)(() => {
337
+ slideElsRef.current.length = slideCount;
338
+ }, [slideCount]);
339
+ const trackStyle = {
340
+ position: "relative",
341
+ display: "flex",
342
+ flexDirection: horizontal ? "row" : "column",
343
+ overflowX: horizontal ? "auto" : "hidden",
344
+ overflowY: horizontal ? "hidden" : "auto",
345
+ scrollSnapType: horizontal ? "x mandatory" : "y mandatory",
346
+ overscrollBehaviorX: horizontal ? "contain" : void 0,
347
+ overscrollBehaviorY: horizontal ? void 0 : "contain",
348
+ scrollbarWidth: "none",
349
+ WebkitOverflowScrolling: "touch"
350
+ };
351
+ const contextValue = (0, import_react4.useMemo)(
352
+ () => ({
353
+ activeIndex,
354
+ slideCount,
355
+ orientation,
356
+ align,
357
+ getSlideId,
358
+ registerSlide,
359
+ scrollToIndex,
360
+ slideClassName: classNames?.slide
361
+ }),
362
+ [
363
+ activeIndex,
364
+ slideCount,
365
+ orientation,
366
+ align,
367
+ getSlideId,
368
+ registerSlide,
369
+ scrollToIndex,
370
+ classNames?.slide
371
+ ]
372
+ );
373
+ return /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(CarouselContext.Provider, { value: contextValue, children: /* @__PURE__ */ (0, import_jsx_runtime3.jsxs)(
374
+ "div",
375
+ {
376
+ role: "group",
377
+ "aria-roledescription": "carousel",
378
+ "aria-label": ariaLabel,
379
+ "data-active-slide": activeIndex,
380
+ className: join(classNames?.root, className),
381
+ style,
382
+ children: [
383
+ /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
384
+ "div",
385
+ {
386
+ ref: trackRef,
387
+ "data-orientation": orientation,
388
+ className: classNames?.track,
389
+ style: trackStyle,
390
+ children: slideItems.map((item, index) => /* @__PURE__ */ (0, import_jsx_runtime3.jsx)(
391
+ SlideIndexContext.Provider,
392
+ {
393
+ value: index,
394
+ children: item
395
+ },
396
+ (0, import_react4.isValidElement)(item) && item.key != null ? item.key : index
397
+ ))
398
+ }
399
+ ),
400
+ otherItems
401
+ ]
402
+ }
403
+ ) });
404
+ }
405
+
406
+ // src/Markers.tsx
407
+ var import_react5 = require("react");
408
+ var import_jsx_runtime4 = require("react/jsx-runtime");
409
+ function Markers({
410
+ classNames,
411
+ renderMarker,
412
+ "aria-label": ariaLabel = "Slides"
413
+ }) {
414
+ const { activeIndex, slideCount, orientation, getSlideId, scrollToIndex } = useCarouselContext("Carousel.Markers");
415
+ const tabRefs = (0, import_react5.useRef)([]);
416
+ tabRefs.current.length = slideCount;
417
+ if (slideCount <= 1) return null;
418
+ const horizontal = orientation === CAROUSEL_ORIENTATION.horizontal;
419
+ const select = (index) => {
420
+ scrollToIndex(index);
421
+ tabRefs.current[index]?.focus();
422
+ };
423
+ const onKeyDown = (event) => {
424
+ const prevKey = horizontal ? "ArrowLeft" : "ArrowUp";
425
+ const nextKey = horizontal ? "ArrowRight" : "ArrowDown";
426
+ let target = -1;
427
+ if (event.key === prevKey) target = Math.max(0, activeIndex - 1);
428
+ else if (event.key === nextKey)
429
+ target = Math.min(slideCount - 1, activeIndex + 1);
430
+ else if (event.key === "Home") target = 0;
431
+ else if (event.key === "End") target = slideCount - 1;
432
+ if (target < 0 || target === activeIndex) return;
433
+ event.preventDefault();
434
+ select(target);
435
+ };
436
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
437
+ "div",
438
+ {
439
+ role: "tablist",
440
+ "aria-label": ariaLabel,
441
+ "aria-orientation": orientation,
442
+ className: classNames?.list,
443
+ onKeyDown,
444
+ children: Array.from({ length: slideCount }, (_, index) => {
445
+ const active = index === activeIndex;
446
+ return /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
447
+ "button",
448
+ {
449
+ ref: (el) => {
450
+ tabRefs.current[index] = el;
451
+ },
452
+ type: "button",
453
+ role: "tab",
454
+ "aria-selected": active,
455
+ "aria-controls": getSlideId(index),
456
+ "aria-label": `Go to slide ${index + 1}`,
457
+ tabIndex: active ? 0 : -1,
458
+ className: join(
459
+ classNames?.marker,
460
+ active ? classNames?.markerActive : void 0
461
+ ),
462
+ onClick: () => scrollToIndex(index),
463
+ children: renderMarker?.(index, active)
464
+ },
465
+ index
466
+ );
467
+ })
468
+ }
469
+ );
470
+ }
471
+
472
+ // src/index.ts
473
+ var Carousel2 = Object.assign(Carousel, {
474
+ Slide,
475
+ Markers,
476
+ Prev,
477
+ Next
478
+ });
479
+ // Annotate the CommonJS export names for ESM import in node:
480
+ 0 && (module.exports = {
481
+ CAROUSEL_ALIGN,
482
+ CAROUSEL_ORIENTATION,
483
+ Carousel
484
+ });
485
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/index.ts","../src/context.ts","../src/Buttons.tsx","../src/Carousel.tsx","../src/join.ts","../src/Slide.tsx","../src/types.ts","../src/snapMath.ts","../src/support.ts","../src/useIsomorphicLayoutEffect.ts","../src/Markers.tsx"],"sourcesContent":["import { Next, Prev } from './Buttons'\nimport { Carousel as CarouselRoot } from './Carousel'\nimport { Markers } from './Markers'\nimport { Slide } from './Slide'\n\nexport const Carousel = Object.assign(CarouselRoot, {\n Slide,\n Markers,\n Prev,\n Next,\n})\n\nexport type { CarouselButtonProps } from './Buttons'\nexport type { CarouselMarkersProps } from './Markers'\nexport type { CarouselSlideProps } from './Slide'\nexport * from './types'\n","import { createContext, useContext } from 'react'\nimport type { CarouselAlign, CarouselOrientation } from './types'\n\nexport type CarouselContextValue = {\n activeIndex: number\n slideCount: number\n orientation: CarouselOrientation\n align: CarouselAlign\n getSlideId: (index: number) => string\n registerSlide: (index: number, el: HTMLElement | null) => void\n scrollToIndex: (index: number) => void\n slideClassName?: string\n}\n\nexport const CarouselContext = createContext<CarouselContextValue | null>(null)\n\nexport function useCarouselContext(component: string): CarouselContextValue {\n const context = useContext(CarouselContext)\n if (!context) {\n throw new Error(`<${component}> must be used within <Carousel>`)\n }\n return context\n}\n\n/** Index of the current slide, provided per-slide by the Carousel root. */\nexport const SlideIndexContext = createContext<number>(-1)\n","import type { CSSProperties, ReactNode } from 'react'\nimport { useCarouselContext } from './context'\n\nexport type CarouselButtonProps = {\n className?: string\n style?: CSSProperties\n children?: ReactNode\n 'aria-label'?: string\n}\n\nexport function Prev({\n className,\n style,\n children,\n 'aria-label': ariaLabel = 'Previous slide',\n}: CarouselButtonProps) {\n const { activeIndex, scrollToIndex } = useCarouselContext('Carousel.Prev')\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n disabled={activeIndex <= 0}\n onClick={() => scrollToIndex(activeIndex - 1)}\n className={className}\n style={style}\n >\n {children}\n </button>\n )\n}\n\nexport function Next({\n className,\n style,\n children,\n 'aria-label': ariaLabel = 'Next slide',\n}: CarouselButtonProps) {\n const { activeIndex, slideCount, scrollToIndex } =\n useCarouselContext('Carousel.Next')\n return (\n <button\n type=\"button\"\n aria-label={ariaLabel}\n disabled={activeIndex >= slideCount - 1}\n onClick={() => scrollToIndex(activeIndex + 1)}\n className={className}\n style={style}\n >\n {children}\n </button>\n )\n}\n","import {\n Children,\n type CSSProperties,\n isValidElement,\n useCallback,\n useEffect,\n useId,\n useMemo,\n useRef,\n useState,\n} from 'react'\nimport {\n CarouselContext,\n type CarouselContextValue,\n SlideIndexContext,\n} from './context'\nimport { join } from './join'\nimport { Slide } from './Slide'\nimport { getActiveFromScroll, getSnapPositions } from './snapMath'\nimport {\n prefersReducedMotion,\n supportsScrollEnd,\n supportsSnapEvents,\n} from './support'\nimport {\n CAROUSEL_ALIGN,\n CAROUSEL_ORIENTATION,\n type CarouselProps,\n} from './types'\nimport { useIsomorphicLayoutEffect } from './useIsomorphicLayoutEffect'\n\nconst SETTLE_DEBOUNCE_MS = 150\n\nexport function Carousel({\n children,\n defaultSlide = 0,\n slide,\n onSlideChange,\n orientation = CAROUSEL_ORIENTATION.horizontal,\n align = CAROUSEL_ALIGN.start,\n classNames,\n className,\n style,\n 'aria-label': ariaLabel,\n}: CarouselProps) {\n const horizontal = orientation === CAROUSEL_ORIENTATION.horizontal\n\n const items = Children.toArray(children)\n const slideItems = items.filter(\n (item) => isValidElement(item) && item.type === Slide,\n )\n const otherItems = items.filter(\n (item) => !(isValidElement(item) && item.type === Slide),\n )\n const slideCount = slideItems.length\n\n const trackRef = useRef<HTMLDivElement | null>(null)\n const slideElsRef = useRef<Array<HTMLElement | null>>([])\n const [internalActive, setInternalActive] = useState(defaultSlide)\n const isControlled = slide !== undefined\n const rawActiveIndex = isControlled ? slide : internalActive\n // Clamp so an out-of-bounds defaultSlide/slide (e.g. stale after slides\n // shrink) can't leak into the data attribute, Markers, or Prev/Next.\n const activeIndex =\n slideCount > 0\n ? Math.min(Math.max(rawActiveIndex, 0), slideCount - 1)\n : rawActiveIndex\n\n const baseId = useId()\n const getSlideId = useCallback(\n (index: number) => `${baseId}-slide-${index}`,\n [baseId],\n )\n const registerSlide = useCallback((index: number, el: HTMLElement | null) => {\n slideElsRef.current[index] = el\n }, [])\n\n const lastSettledRef = useRef(isControlled ? slide : defaultSlide)\n\n const setActive = useCallback(\n (index: number, settled: boolean) => {\n if (!isControlled) setInternalActive(index)\n if (settled && index !== lastSettledRef.current) {\n lastSettledRef.current = index\n onSlideChange?.(index)\n }\n },\n [isControlled, onSlideChange],\n )\n\n const measure = useCallback((): number[] => {\n const track = trackRef.current\n if (!track) return []\n const slides = slideElsRef.current.filter(\n (el): el is HTMLElement => el !== null,\n )\n return getSnapPositions(track, slides, align, orientation)\n }, [align, orientation])\n\n const scrollToIndex = useCallback(\n (index: number) => {\n const track = trackRef.current\n if (!track || slideCount === 0) return\n const clamped = Math.min(Math.max(index, 0), slideCount - 1)\n const target = measure()[clamped]\n if (target === undefined) return\n const behavior: ScrollBehavior = prefersReducedMotion()\n ? 'auto'\n : 'smooth'\n track.scrollTo(\n horizontal ? { left: target, behavior } : { top: target, behavior },\n )\n },\n [horizontal, measure, slideCount],\n )\n\n // Mount-only: instantly position the track at the initial active slide\n // (nonzero defaultSlide, or an initial controlled `slide`). Runs as a\n // layout effect so it lands before paint and before the ResizeObserver\n // below attaches — otherwise consumers see a flash of slide 0, or the\n // observer's own initial delivery (see below) can clobber it first.\n useIsomorphicLayoutEffect(() => {\n const track = trackRef.current\n if (!track || activeIndex <= 0) return\n const target = measure()[activeIndex]\n if (target === undefined) return\n if (horizontal) track.scrollLeft = target\n else track.scrollTop = target\n // Mount-only by design: re-positioning after this belongs to\n // scrollToIndex (controlled-prop effect, Markers, Prev/Next), not here.\n }, [])\n\n // Controlled mode: follow the slide prop.\n useEffect(() => {\n if (isControlled && slide !== lastSettledRef.current) {\n scrollToIndex(slide)\n }\n }, [isControlled, slide, scrollToIndex])\n\n // Fallback active-state tracking for browsers without scroll-snap events\n // (Firefox, Safari < 18.2): rAF-throttled scroll + scrollend/debounce settle.\n useEffect(() => {\n const track = trackRef.current\n if (!track || supportsSnapEvents()) return\n\n let frame = 0\n let settleTimer: ReturnType<typeof setTimeout> | undefined\n const readActive = () =>\n getActiveFromScroll(\n horizontal ? track.scrollLeft : track.scrollTop,\n measure(),\n )\n\n const onScroll = () => {\n if (!frame) {\n frame = requestAnimationFrame(() => {\n frame = 0\n setActive(readActive(), false)\n })\n }\n if (!supportsScrollEnd()) {\n if (settleTimer) clearTimeout(settleTimer)\n settleTimer = setTimeout(\n () => setActive(readActive(), true),\n SETTLE_DEBOUNCE_MS,\n )\n }\n }\n const onScrollEnd = () => setActive(readActive(), true)\n\n track.addEventListener('scroll', onScroll, { passive: true })\n if (supportsScrollEnd()) track.addEventListener('scrollend', onScrollEnd)\n return () => {\n if (frame) cancelAnimationFrame(frame)\n if (settleTimer) clearTimeout(settleTimer)\n track.removeEventListener('scroll', onScroll)\n track.removeEventListener('scrollend', onScrollEnd)\n }\n }, [horizontal, measure, setActive])\n\n // Native path: the browser reports its chosen snap target directly.\n // scrollsnapchanging fires mid-gesture (eager UI update); scrollsnapchange\n // fires once the scroll settles on a new target.\n useEffect(() => {\n const track = trackRef.current\n if (!track || !supportsSnapEvents()) return\n\n type SnapEvent = Event & {\n snapTargetInline: Element | null\n snapTargetBlock: Element | null\n }\n const indexOfTarget = (event: Event): number => {\n const snapEvent = event as SnapEvent\n const target = horizontal\n ? snapEvent.snapTargetInline\n : snapEvent.snapTargetBlock\n if (!target) return -1\n return slideElsRef.current.indexOf(target as HTMLElement)\n }\n const onChanging = (event: Event) => {\n const index = indexOfTarget(event)\n if (index >= 0) setActive(index, false)\n }\n const onChange = (event: Event) => {\n const index = indexOfTarget(event)\n if (index >= 0) setActive(index, true)\n }\n\n track.addEventListener('scrollsnapchanging', onChanging)\n track.addEventListener('scrollsnapchange', onChange)\n return () => {\n track.removeEventListener('scrollsnapchanging', onChanging)\n track.removeEventListener('scrollsnapchange', onChange)\n }\n }, [horizontal, setActive])\n\n // Layout changes (container resize, slide size changes) can silently move\n // the snapped slide; re-derive active from the current scroll position.\n // Real browsers deliver an initial callback right after `observe()` is\n // called, reporting the already-known size — that delivery carries no new\n // information and must not clobber the position the mount effect above\n // just set. `firstDeliveryRef` swallows exactly that one delivery per\n // `observe()` call; every delivery after it re-derives as normal.\n const firstDeliveryRef = useRef(true)\n useEffect(() => {\n const track = trackRef.current\n if (!track || typeof ResizeObserver === 'undefined') return\n firstDeliveryRef.current = true\n const observer = new ResizeObserver(() => {\n if (firstDeliveryRef.current) {\n firstDeliveryRef.current = false\n return\n }\n const position = horizontal ? track.scrollLeft : track.scrollTop\n setActive(getActiveFromScroll(position, measure()), false)\n })\n observer.observe(track)\n return () => observer.disconnect()\n }, [horizontal, measure, setActive])\n\n // Keep the registry aligned when slides are removed.\n useEffect(() => {\n slideElsRef.current.length = slideCount\n }, [slideCount])\n\n const trackStyle: CSSProperties = {\n position: 'relative',\n display: 'flex',\n flexDirection: horizontal ? 'row' : 'column',\n overflowX: horizontal ? 'auto' : 'hidden',\n overflowY: horizontal ? 'hidden' : 'auto',\n scrollSnapType: horizontal ? 'x mandatory' : 'y mandatory',\n overscrollBehaviorX: horizontal ? 'contain' : undefined,\n overscrollBehaviorY: horizontal ? undefined : 'contain',\n scrollbarWidth: 'none',\n WebkitOverflowScrolling: 'touch',\n }\n\n const contextValue = useMemo<CarouselContextValue>(\n () => ({\n activeIndex,\n slideCount,\n orientation,\n align,\n getSlideId,\n registerSlide,\n scrollToIndex,\n slideClassName: classNames?.slide,\n }),\n [\n activeIndex,\n slideCount,\n orientation,\n align,\n getSlideId,\n registerSlide,\n scrollToIndex,\n classNames?.slide,\n ],\n )\n\n return (\n <CarouselContext.Provider value={contextValue}>\n {/* biome-ignore lint/a11y/useSemanticElements: explicit role required by ARIA carousel pattern */}\n <div\n role=\"group\"\n aria-roledescription=\"carousel\"\n aria-label={ariaLabel}\n data-active-slide={activeIndex}\n className={join(classNames?.root, className)}\n style={style}\n >\n <div\n ref={trackRef}\n data-orientation={orientation}\n className={classNames?.track}\n style={trackStyle}\n >\n {slideItems.map((item, index) => (\n <SlideIndexContext.Provider\n key={isValidElement(item) && item.key != null ? item.key : index}\n value={index}\n >\n {item}\n </SlideIndexContext.Provider>\n ))}\n </div>\n {otherItems}\n </div>\n </CarouselContext.Provider>\n )\n}\n","export function join(...parts: Array<string | undefined>): string | undefined {\n const joined = parts.filter(Boolean).join(' ')\n return joined === '' ? undefined : joined\n}\n","import {\n type CSSProperties,\n type ReactNode,\n useCallback,\n useContext,\n} from 'react'\nimport { SlideIndexContext, useCarouselContext } from './context'\nimport { join } from './join'\n\nexport type CarouselSlideProps = {\n children: ReactNode\n className?: string\n style?: CSSProperties\n}\n\nexport function Slide({ children, className, style }: CarouselSlideProps) {\n const context = useCarouselContext('Carousel.Slide')\n const index = useContext(SlideIndexContext)\n const { registerSlide } = context\n\n const ref = useCallback(\n (el: HTMLDivElement | null) => {\n registerSlide(index, el)\n },\n [registerSlide, index],\n )\n\n return (\n // biome-ignore lint/a11y/useSemanticElements: explicit role required by ARIA slide pattern\n <div\n ref={ref}\n id={context.getSlideId(index)}\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-label={`${index + 1} of ${context.slideCount}`}\n className={join(context.slideClassName, className)}\n style={{ scrollSnapAlign: context.align, flexShrink: 0, ...style }}\n >\n {children}\n </div>\n )\n}\n","import type { CSSProperties, ReactNode } from 'react'\n\nexport const CAROUSEL_ORIENTATION = {\n horizontal: 'horizontal',\n vertical: 'vertical',\n} as const\n\nexport type CarouselOrientation =\n (typeof CAROUSEL_ORIENTATION)[keyof typeof CAROUSEL_ORIENTATION]\n\nexport const CAROUSEL_ALIGN = {\n start: 'start',\n center: 'center',\n} as const\n\nexport type CarouselAlign = (typeof CAROUSEL_ALIGN)[keyof typeof CAROUSEL_ALIGN]\n\nexport type CarouselClassNames = {\n root?: string\n track?: string\n slide?: string\n}\n\nexport type CarouselMarkersClassNames = {\n list?: string\n marker?: string\n markerActive?: string\n}\n\nexport type CarouselProps = {\n /** `Carousel.Slide` children plus any controls (`Carousel.Markers`, etc.). */\n children: ReactNode\n /** Initial slide when uncontrolled. @default 0 */\n defaultSlide?: number\n /** Controlled active slide index. */\n slide?: number\n /** Fires when the settled slide changes (after snap completes). */\n onSlideChange?: (index: number) => void\n /** Scroll axis. @default 'horizontal' */\n orientation?: CarouselOrientation\n /** scroll-snap-align of slides. @default 'start' */\n align?: CarouselAlign\n classNames?: CarouselClassNames\n /** Accessible name for the carousel region. */\n 'aria-label'?: string\n className?: string\n style?: CSSProperties\n}\n","import {\n CAROUSEL_ALIGN,\n CAROUSEL_ORIENTATION,\n type CarouselAlign,\n type CarouselOrientation,\n} from './types'\n\n/**\n * Index of the snap position nearest to `scrollPos`. Positions must be in\n * ascending order (they are: slides are measured in DOM order).\n */\nexport function getActiveFromScroll(\n scrollPos: number,\n snapPositions: number[],\n): number {\n let best = 0\n let bestDist = Number.POSITIVE_INFINITY\n for (let i = 0; i < snapPositions.length; i++) {\n const position = snapPositions[i]\n if (position === undefined) continue\n const dist = Math.abs(position - scrollPos)\n if (dist < bestDist) {\n bestDist = dist\n best = i\n }\n }\n return best\n}\n\n/**\n * Target scroll offset for each slide, clamped to the scrollable range.\n * Assumes `track` is the slides' offsetParent (track is position: relative).\n */\nexport function getSnapPositions(\n track: HTMLElement,\n slides: HTMLElement[],\n align: CarouselAlign,\n orientation: CarouselOrientation,\n): number[] {\n const horizontal = orientation === CAROUSEL_ORIENTATION.horizontal\n const viewport = horizontal ? track.clientWidth : track.clientHeight\n const content = horizontal ? track.scrollWidth : track.scrollHeight\n const maxScroll = Math.max(0, content - viewport)\n return slides.map((slide) => {\n const offset = horizontal ? slide.offsetLeft : slide.offsetTop\n const size = horizontal ? slide.offsetWidth : slide.offsetHeight\n const raw =\n align === CAROUSEL_ALIGN.center ? offset - (viewport - size) / 2 : offset\n return Math.min(Math.max(raw, 0), maxScroll)\n })\n}\n","/** Scroll-snap events: Chrome/Edge 129+, Safari 18.2+. Firefox: not yet. */\nexport function supportsSnapEvents(): boolean {\n return typeof window !== 'undefined' && 'onscrollsnapchange' in window\n}\n\nexport function supportsScrollEnd(): boolean {\n return typeof window !== 'undefined' && 'onscrollend' in window\n}\n\nexport function prefersReducedMotion(): boolean {\n return (\n typeof window !== 'undefined' &&\n window.matchMedia?.('(prefers-reduced-motion: reduce)').matches === true\n )\n}\n","import { useEffect, useLayoutEffect } from 'react'\n\n/**\n * `useLayoutEffect` in the browser, `useEffect` on the server. This package\n * renders on the server (SSR), where `useLayoutEffect` triggers a React\n * warning because there is no DOM to measure/mutate synchronously against.\n * `window` is only ever read here for the environment check, never accessed\n * eagerly at module scope beyond `typeof`.\n */\nexport const useIsomorphicLayoutEffect =\n typeof window !== 'undefined' ? useLayoutEffect : useEffect\n","import { type KeyboardEvent, type ReactNode, useRef } from 'react'\nimport { useCarouselContext } from './context'\nimport { join } from './join'\nimport { CAROUSEL_ORIENTATION, type CarouselMarkersClassNames } from './types'\n\nexport type CarouselMarkersProps = {\n classNames?: CarouselMarkersClassNames\n renderMarker?: (index: number, active: boolean) => ReactNode\n /** Accessible name for the marker list. @default 'Slides' */\n 'aria-label'?: string\n}\n\nexport function Markers({\n classNames,\n renderMarker,\n 'aria-label': ariaLabel = 'Slides',\n}: CarouselMarkersProps) {\n const { activeIndex, slideCount, orientation, getSlideId, scrollToIndex } =\n useCarouselContext('Carousel.Markers')\n const tabRefs = useRef<Array<HTMLButtonElement | null>>([])\n // Trim stale refs when slideCount shrinks, including down to <= 1 (the\n // early return below stops rendering buttons entirely).\n tabRefs.current.length = slideCount\n\n if (slideCount <= 1) return null\n\n const horizontal = orientation === CAROUSEL_ORIENTATION.horizontal\n\n const select = (index: number) => {\n scrollToIndex(index)\n tabRefs.current[index]?.focus()\n }\n\n const onKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n const prevKey = horizontal ? 'ArrowLeft' : 'ArrowUp'\n const nextKey = horizontal ? 'ArrowRight' : 'ArrowDown'\n let target = -1\n if (event.key === prevKey) target = Math.max(0, activeIndex - 1)\n else if (event.key === nextKey)\n target = Math.min(slideCount - 1, activeIndex + 1)\n else if (event.key === 'Home') target = 0\n else if (event.key === 'End') target = slideCount - 1\n if (target < 0 || target === activeIndex) return\n event.preventDefault()\n select(target)\n }\n\n return (\n <div\n role=\"tablist\"\n aria-label={ariaLabel}\n aria-orientation={orientation}\n className={classNames?.list}\n onKeyDown={onKeyDown}\n >\n {Array.from({ length: slideCount }, (_, index) => {\n const active = index === activeIndex\n return (\n <button\n // biome-ignore lint/suspicious/noArrayIndexKey: markers are positional by nature\n key={index}\n ref={(el) => {\n tabRefs.current[index] = el\n }}\n type=\"button\"\n role=\"tab\"\n aria-selected={active}\n aria-controls={getSlideId(index)}\n aria-label={`Go to slide ${index + 1}`}\n tabIndex={active ? 0 : -1}\n className={join(\n classNames?.marker,\n active ? classNames?.markerActive : undefined,\n )}\n onClick={() => scrollToIndex(index)}\n >\n {renderMarker?.(index, active)}\n </button>\n )\n })}\n </div>\n )\n}\n"],"mappings":"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","names":["Carousel","import_react","import_react","import_jsx_runtime","import_react","import_jsx_runtime","import_react","import_jsx_runtime","Carousel"]}