@destyler/carousel 0.0.7-beta.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.mjs ADDED
@@ -0,0 +1,674 @@
1
+ import { createAnatomy } from '@zag-js/anatomy';
2
+ import { getEventKey, addDomEvent, trackPointerMove } from '@zag-js/dom-event';
3
+ import { createScope, queryAll, getTabbables, dataAttr, getEventTarget, isFocusable, ariaAttr, raf } from '@zag-js/dom-query';
4
+ import { createMachine, ref } from '@zag-js/core';
5
+ import { findSnapPoint, getScrollSnapPositions } from '@zag-js/scroll-snap';
6
+ import { compact, isObject, add, remove, uniq, nextIndex, prevIndex, isEqual, createSplitProps } from '@zag-js/utils';
7
+ import { createProps } from '@zag-js/types';
8
+
9
+ const anatomy = createAnatomy("carousel").parts(
10
+ "root",
11
+ "itemGroup",
12
+ "item",
13
+ "control",
14
+ "nextTrigger",
15
+ "prevTrigger",
16
+ "indicatorGroup",
17
+ "indicator",
18
+ "autoplayTrigger"
19
+ );
20
+ const parts = anatomy.build();
21
+
22
+ const dom = createScope({
23
+ getRootId: (ctx) => ctx.ids?.root ?? `carousel:${ctx.id}`,
24
+ getItemId: (ctx, index) => ctx.ids?.item?.(index) ?? `carousel:${ctx.id}:item:${index}`,
25
+ getItemGroupId: (ctx) => ctx.ids?.itemGroup ?? `carousel:${ctx.id}:item-group`,
26
+ getNextTriggerId: (ctx) => ctx.ids?.nextTrigger ?? `carousel:${ctx.id}:next-trigger`,
27
+ getPrevTriggerId: (ctx) => ctx.ids?.prevTrigger ?? `carousel:${ctx.id}:prev-trigger`,
28
+ getIndicatorGroupId: (ctx) => ctx.ids?.indicatorGroup ?? `carousel:${ctx.id}:indicator-group`,
29
+ getIndicatorId: (ctx, index) => ctx.ids?.indicator?.(index) ?? `carousel:${ctx.id}:indicator:${index}`,
30
+ getRootEl: (ctx) => dom.getById(ctx, dom.getRootId(ctx)),
31
+ getItemGroupEl: (ctx) => dom.getById(ctx, dom.getItemGroupId(ctx)),
32
+ getItemEl: (ctx, index) => dom.getById(ctx, dom.getItemId(ctx, index)),
33
+ getItemEls: (ctx) => queryAll(dom.getItemGroupEl(ctx), `[data-part=item]`),
34
+ getActiveIndicatorEl: (ctx) => dom.getById(ctx, dom.getIndicatorId(ctx, ctx.page)),
35
+ syncTabIndex(ctx) {
36
+ const el = dom.getItemGroupEl(ctx);
37
+ if (!el)
38
+ return;
39
+ const tabbables = getTabbables(el);
40
+ if (tabbables.length > 0) {
41
+ el.removeAttribute("tabindex");
42
+ } else {
43
+ el.setAttribute("tabindex", "0");
44
+ }
45
+ }
46
+ });
47
+
48
+ function connect(state, send, normalize) {
49
+ const isPlaying = state.matches("autoplay");
50
+ const isDragging = state.matches("dragging");
51
+ const canScrollNext = state.context.canScrollNext;
52
+ const canScrollPrev = state.context.canScrollPrev;
53
+ const horizontal = state.context.isHorizontal;
54
+ const pageSnapPoints = Array.from(state.context.pageSnapPoints);
55
+ const page = state.context.page;
56
+ const slidesPerPage = state.context.slidesPerPage;
57
+ const padding = state.context.padding;
58
+ const translations = state.context.translations;
59
+ return {
60
+ isPlaying,
61
+ isDragging,
62
+ page,
63
+ pageSnapPoints,
64
+ canScrollNext,
65
+ canScrollPrev,
66
+ getProgress() {
67
+ return page / pageSnapPoints.length;
68
+ },
69
+ scrollToIndex(index, instant) {
70
+ send({ type: "INDEX.SET", index, instant });
71
+ },
72
+ scrollTo(index, instant) {
73
+ send({ type: "PAGE.SET", index, instant });
74
+ },
75
+ scrollNext(instant) {
76
+ send({ type: "PAGE.NEXT", instant });
77
+ },
78
+ scrollPrev(instant) {
79
+ send({ type: "PAGE.PREV", instant });
80
+ },
81
+ play() {
82
+ send("AUTOPLAY.START");
83
+ },
84
+ pause() {
85
+ send("AUTOPLAY.PAUSE");
86
+ },
87
+ isInView(index) {
88
+ return Array.from(state.context.slidesInView).includes(index);
89
+ },
90
+ refresh() {
91
+ send({ type: "SNAP.REFRESH" });
92
+ },
93
+ getRootProps() {
94
+ return normalize.element({
95
+ ...parts.root.attrs,
96
+ "id": dom.getRootId(state.context),
97
+ "role": "region",
98
+ "aria-roledescription": "carousel",
99
+ "data-orientation": state.context.orientation,
100
+ "dir": state.context.dir,
101
+ "style": {
102
+ "--slides-per-page": slidesPerPage,
103
+ "--slide-spacing": state.context.spacing,
104
+ "--slide-item-size": "calc(100% / var(--slides-per-page) - var(--slide-spacing) * (var(--slides-per-page) - 1) / var(--slides-per-page))"
105
+ }
106
+ });
107
+ },
108
+ getItemGroupProps() {
109
+ return normalize.element({
110
+ ...parts.itemGroup.attrs,
111
+ "id": dom.getItemGroupId(state.context),
112
+ "data-orientation": state.context.orientation,
113
+ "data-dragging": dataAttr(isDragging),
114
+ "dir": state.context.dir,
115
+ "aria-live": isPlaying ? "off" : "polite",
116
+ onMouseDown(event) {
117
+ if (!state.context.allowMouseDrag)
118
+ return;
119
+ if (event.button !== 0)
120
+ return;
121
+ if (event.defaultPrevented)
122
+ return;
123
+ const target = getEventTarget(event);
124
+ if (isFocusable(target) && target !== event.currentTarget)
125
+ return;
126
+ event.preventDefault();
127
+ send({ type: "DRAGGING.START" });
128
+ },
129
+ "style": {
130
+ display: "grid",
131
+ gap: "var(--slide-spacing)",
132
+ scrollSnapType: [horizontal ? "x" : "y", state.context.snapType].join(" "),
133
+ gridAutoFlow: horizontal ? "column" : "row",
134
+ scrollbarWidth: "none",
135
+ overscrollBehavior: "contain",
136
+ [horizontal ? "gridAutoColumns" : "gridAutoRows"]: "var(--slide-item-size)",
137
+ [horizontal ? "scrollPaddingInline" : "scrollPaddingBlock"]: padding,
138
+ [horizontal ? "paddingInline" : "paddingBlock"]: padding,
139
+ [horizontal ? "overflowX" : "overflowY"]: "auto"
140
+ }
141
+ });
142
+ },
143
+ getItemProps(props) {
144
+ const isInView = state.context.slidesInView.includes(props.index);
145
+ return normalize.element({
146
+ ...parts.item.attrs,
147
+ "id": dom.getItemId(state.context, props.index),
148
+ "dir": state.context.dir,
149
+ "role": "group",
150
+ "data-index": props.index,
151
+ "data-inview": dataAttr(isInView),
152
+ "aria-roledescription": "slide",
153
+ "data-orientation": state.context.orientation,
154
+ "aria-label": state.context.slideCount ? translations.item(props.index, state.context.slideCount) : void 0,
155
+ "aria-hidden": ariaAttr(!isInView),
156
+ "style": {
157
+ scrollSnapAlign: getSnapAlign(state.context, props)
158
+ }
159
+ });
160
+ },
161
+ getControlProps() {
162
+ return normalize.element({
163
+ ...parts.control.attrs,
164
+ "data-orientation": state.context.orientation
165
+ });
166
+ },
167
+ getPrevTriggerProps() {
168
+ return normalize.button({
169
+ ...parts.prevTrigger.attrs,
170
+ "id": dom.getPrevTriggerId(state.context),
171
+ "type": "button",
172
+ "disabled": !canScrollPrev,
173
+ "dir": state.context.dir,
174
+ "aria-label": translations.prevTrigger,
175
+ "data-orientation": state.context.orientation,
176
+ "aria-controls": dom.getItemGroupId(state.context),
177
+ onClick(event) {
178
+ if (event.defaultPrevented)
179
+ return;
180
+ send({ type: "PAGE.PREV", src: "trigger" });
181
+ }
182
+ });
183
+ },
184
+ getNextTriggerProps() {
185
+ return normalize.button({
186
+ ...parts.nextTrigger.attrs,
187
+ "dir": state.context.dir,
188
+ "id": dom.getNextTriggerId(state.context),
189
+ "type": "button",
190
+ "aria-label": translations.nextTrigger,
191
+ "data-orientation": state.context.orientation,
192
+ "aria-controls": dom.getItemGroupId(state.context),
193
+ "disabled": !canScrollNext,
194
+ onClick(event) {
195
+ if (event.defaultPrevented)
196
+ return;
197
+ send({ type: "PAGE.NEXT", src: "trigger" });
198
+ }
199
+ });
200
+ },
201
+ getIndicatorGroupProps() {
202
+ return normalize.element({
203
+ ...parts.indicatorGroup.attrs,
204
+ "dir": state.context.dir,
205
+ "id": dom.getIndicatorGroupId(state.context),
206
+ "data-orientation": state.context.orientation,
207
+ onKeyDown(event) {
208
+ if (event.defaultPrevented)
209
+ return;
210
+ const src = "indicator";
211
+ const keyMap = {
212
+ ArrowDown(event2) {
213
+ if (horizontal)
214
+ return;
215
+ send({ type: "PAGE.NEXT", src });
216
+ event2.preventDefault();
217
+ },
218
+ ArrowUp(event2) {
219
+ if (horizontal)
220
+ return;
221
+ send({ type: "PAGE.PREV", src });
222
+ event2.preventDefault();
223
+ },
224
+ ArrowRight(event2) {
225
+ if (!horizontal)
226
+ return;
227
+ send({ type: "PAGE.NEXT", src });
228
+ event2.preventDefault();
229
+ },
230
+ ArrowLeft(event2) {
231
+ if (!horizontal)
232
+ return;
233
+ send({ type: "PAGE.PREV", src });
234
+ event2.preventDefault();
235
+ },
236
+ Home(event2) {
237
+ send({ type: "PAGE.SET", index: 0, src });
238
+ event2.preventDefault();
239
+ },
240
+ End(event2) {
241
+ send({ type: "PAGE.SET", index: pageSnapPoints.length - 1, src });
242
+ event2.preventDefault();
243
+ }
244
+ };
245
+ const key = getEventKey(event, {
246
+ dir: state.context.dir,
247
+ orientation: state.context.orientation
248
+ });
249
+ const exec = keyMap[key];
250
+ exec?.(event);
251
+ }
252
+ });
253
+ },
254
+ getIndicatorProps(props) {
255
+ return normalize.button({
256
+ ...parts.indicator.attrs,
257
+ "dir": state.context.dir,
258
+ "id": dom.getIndicatorId(state.context, props.index),
259
+ "type": "button",
260
+ "data-orientation": state.context.orientation,
261
+ "data-index": props.index,
262
+ "data-readonly": dataAttr(props.readOnly),
263
+ "data-current": dataAttr(props.index === state.context.page),
264
+ "aria-label": translations.indicator(props.index),
265
+ onClick(event) {
266
+ if (event.defaultPrevented)
267
+ return;
268
+ if (props.readOnly)
269
+ return;
270
+ send({ type: "PAGE.SET", index: props.index, src: "indicator" });
271
+ }
272
+ });
273
+ },
274
+ getAutoplayTriggerProps() {
275
+ return normalize.button({
276
+ ...parts.autoplayTrigger.attrs,
277
+ "type": "button",
278
+ "data-orientation": state.context.orientation,
279
+ "data-pressed": dataAttr(isPlaying),
280
+ "aria-label": isPlaying ? translations.autoplayStop : translations.autoplayStart,
281
+ onClick(event) {
282
+ if (event.defaultPrevented)
283
+ return;
284
+ send({ type: isPlaying ? "AUTOPLAY.PAUSE" : "AUTOPLAY.START" });
285
+ }
286
+ });
287
+ }
288
+ };
289
+ }
290
+ function getSnapAlign(ctx, props) {
291
+ const { snapAlign = "start", index } = props;
292
+ const perMove = ctx.slidesPerMove === "auto" ? Math.floor(ctx.slidesPerPage) : ctx.slidesPerMove;
293
+ const shouldSnap = (index + perMove) % perMove === 0;
294
+ return shouldSnap ? snapAlign : void 0;
295
+ }
296
+
297
+ const DEFAULT_SLIDES_PER_PAGE = 1;
298
+ const DEFAULT_SLIDES_PER_MOVE = "auto";
299
+ const invoke = {
300
+ pageChange: (ctx) => {
301
+ ctx.onPageChange?.({
302
+ page: ctx.page,
303
+ pageSnapPoint: ctx.pageSnapPoints[ctx.page]
304
+ });
305
+ }
306
+ };
307
+ const set = {
308
+ page: (ctx, value) => {
309
+ const page = clamp(value, 0, ctx.pageSnapPoints.length - 1);
310
+ if (isEqual(ctx.page, page))
311
+ return;
312
+ ctx.page = page;
313
+ invoke.pageChange(ctx);
314
+ }
315
+ };
316
+ function clamp(value, min, max) {
317
+ return Math.min(Math.max(value, min), max);
318
+ }
319
+ function getPageSnapPoints(totalSlides, slidesPerMove, slidesPerPage) {
320
+ if (totalSlides == null)
321
+ return [];
322
+ const snapPoints = [];
323
+ const perMove = slidesPerMove === "auto" ? Math.floor(slidesPerPage) : slidesPerMove;
324
+ for (let i = 0; i < totalSlides - 1; i += perMove) snapPoints.push(i);
325
+ return snapPoints;
326
+ }
327
+ function machine(userContext) {
328
+ const ctx = compact(userContext);
329
+ return createMachine(
330
+ {
331
+ id: "carousel",
332
+ initial: ctx.autoplay ? "autoplay" : "idle",
333
+ context: {
334
+ dir: "ltr",
335
+ page: 0,
336
+ orientation: "horizontal",
337
+ snapType: "mandatory",
338
+ loop: false,
339
+ slidesPerPage: DEFAULT_SLIDES_PER_PAGE,
340
+ slidesPerMove: DEFAULT_SLIDES_PER_MOVE,
341
+ spacing: "0px",
342
+ autoplay: false,
343
+ allowMouseDrag: false,
344
+ inViewThreshold: 0.6,
345
+ ...ctx,
346
+ timeoutRef: ref({ current: void 0 }),
347
+ translations: {
348
+ nextTrigger: "Next slide",
349
+ prevTrigger: "Previous slide",
350
+ indicator: (index) => `Go to slide ${index + 1}`,
351
+ item: (index, count) => `${index + 1} of ${count}`,
352
+ autoplayStart: "Start slide rotation",
353
+ autoplayStop: "Stop slide rotation",
354
+ ...ctx.translations
355
+ },
356
+ pageSnapPoints: getPageSnapPoints(
357
+ ctx.slideCount,
358
+ ctx.slidesPerMove ?? DEFAULT_SLIDES_PER_MOVE,
359
+ ctx.slidesPerPage ?? DEFAULT_SLIDES_PER_PAGE
360
+ ),
361
+ slidesInView: []
362
+ },
363
+ computed: {
364
+ isRtl: (ctx2) => ctx2.dir === "rtl",
365
+ isHorizontal: (ctx2) => ctx2.orientation === "horizontal",
366
+ canScrollNext: (ctx2) => ctx2.loop || ctx2.page < ctx2.pageSnapPoints.length - 1,
367
+ canScrollPrev: (ctx2) => ctx2.loop || ctx2.page > 0,
368
+ autoplayInterval: (ctx2) => isObject(ctx2.autoplay) ? ctx2.autoplay.delay : 4e3
369
+ },
370
+ watch: {
371
+ slidesPerPage: ["setSnapPoints"],
372
+ slidesPerMove: ["setSnapPoints"],
373
+ page: ["scrollToPage", "focusIndicatorEl"],
374
+ orientation: ["setSnapPoints", "scrollToPage"]
375
+ },
376
+ on: {
377
+ "PAGE.NEXT": {
378
+ target: "idle",
379
+ actions: ["clearScrollEndTimer", "setNextPage"]
380
+ },
381
+ "PAGE.PREV": {
382
+ target: "idle",
383
+ actions: ["clearScrollEndTimer", "setPrevPage"]
384
+ },
385
+ "PAGE.SET": {
386
+ target: "idle",
387
+ actions: ["clearScrollEndTimer", "setPage"]
388
+ },
389
+ "INDEX.SET": {
390
+ target: "idle",
391
+ actions: ["clearScrollEndTimer", "setMatchingPage"]
392
+ },
393
+ "SNAP.REFRESH": {
394
+ actions: ["setSnapPoints", "clampPage"]
395
+ }
396
+ },
397
+ activities: ["trackSlideMutation", "trackSlideIntersections", "trackSlideResize"],
398
+ entry: ["resetScrollPosition", "setSnapPoints", "setPage"],
399
+ exit: ["clearScrollEndTimer"],
400
+ states: {
401
+ idle: {
402
+ activities: ["trackScroll"],
403
+ on: {
404
+ "DRAGGING.START": {
405
+ target: "dragging",
406
+ actions: ["invokeDragStart"]
407
+ },
408
+ "AUTOPLAY.START": {
409
+ target: "autoplay",
410
+ actions: ["invokeAutoplayStart"]
411
+ }
412
+ }
413
+ },
414
+ dragging: {
415
+ activities: ["trackPointerMove"],
416
+ entry: ["disableScrollSnap"],
417
+ on: {
418
+ "DRAGGING": {
419
+ actions: ["scrollSlides", "invokeDragging"]
420
+ },
421
+ "DRAGGING.END": {
422
+ target: "idle",
423
+ actions: ["endDragging", "invokeDraggingEnd"]
424
+ }
425
+ }
426
+ },
427
+ autoplay: {
428
+ activities: ["trackDocumentVisibility", "trackScroll"],
429
+ exit: ["invokeAutoplayEnd"],
430
+ every: {
431
+ AUTOPLAY_INTERVAL: ["setNextPage", "invokeAutoplay"]
432
+ },
433
+ on: {
434
+ "DRAGGING.START": {
435
+ target: "dragging",
436
+ actions: ["invokeDragStart"]
437
+ },
438
+ "AUTOPLAY.PAUSE": "idle"
439
+ }
440
+ }
441
+ }
442
+ },
443
+ {
444
+ activities: {
445
+ trackSlideMutation(ctx2, _evt, { send }) {
446
+ const el = dom.getItemGroupEl(ctx2);
447
+ if (!el)
448
+ return;
449
+ const win = dom.getWin(ctx2);
450
+ const observer = new win.MutationObserver(() => {
451
+ send({ type: "SNAP.REFRESH", src: "slide.mutation" });
452
+ dom.syncTabIndex(ctx2);
453
+ });
454
+ dom.syncTabIndex(ctx2);
455
+ observer.observe(el, { childList: true, subtree: true });
456
+ return () => observer.disconnect();
457
+ },
458
+ trackSlideResize(ctx2, _evt, { send }) {
459
+ const el = dom.getItemGroupEl(ctx2);
460
+ if (!el)
461
+ return;
462
+ const win = dom.getWin(ctx2);
463
+ const observer = new win.ResizeObserver(() => {
464
+ send({ type: "SNAP.REFRESH", src: "slide.resize" });
465
+ });
466
+ dom.getItemEls(ctx2).forEach((slide) => observer.observe(slide));
467
+ return () => observer.disconnect();
468
+ },
469
+ trackSlideIntersections(ctx2) {
470
+ const el = dom.getItemGroupEl(ctx2);
471
+ const win = dom.getWin(ctx2);
472
+ const observer = new win.IntersectionObserver(
473
+ (entries) => {
474
+ const slidesInView = entries.reduce((acc, entry) => {
475
+ const target = entry.target;
476
+ const index = Number(target.dataset.index ?? "-1");
477
+ if (index == null || Number.isNaN(index) || index === -1)
478
+ return acc;
479
+ return entry.isIntersecting ? add(acc, index) : remove(acc, index);
480
+ }, ctx2.slidesInView);
481
+ ctx2.slidesInView = uniq(slidesInView);
482
+ },
483
+ {
484
+ root: el,
485
+ threshold: ctx2.inViewThreshold
486
+ }
487
+ );
488
+ dom.getItemEls(ctx2).forEach((slide) => observer.observe(slide));
489
+ return () => observer.disconnect();
490
+ },
491
+ trackScroll(ctx2) {
492
+ const el = dom.getItemGroupEl(ctx2);
493
+ if (!el)
494
+ return;
495
+ const onScrollEnd = () => {
496
+ if (ctx2.slidesInView.length === 0)
497
+ return;
498
+ const scrollPosition = ctx2.isHorizontal ? el.scrollLeft : el.scrollTop;
499
+ const page = ctx2.pageSnapPoints.findIndex((point) => Math.abs(point - scrollPosition) < 1);
500
+ if (page === -1)
501
+ return;
502
+ set.page(ctx2, page);
503
+ };
504
+ const onScroll = () => {
505
+ clearTimeout(ctx2.timeoutRef.current);
506
+ ctx2.timeoutRef.current = setTimeout(() => {
507
+ onScrollEnd?.();
508
+ }, 150);
509
+ };
510
+ return addDomEvent(el, "scroll", onScroll, { passive: true });
511
+ },
512
+ trackDocumentVisibility(ctx2, _evt, { send }) {
513
+ const doc = dom.getDoc(ctx2);
514
+ const onVisibilityChange = () => {
515
+ if (doc.visibilityState === "visible")
516
+ return;
517
+ send({ type: "AUTOPLAY.PAUSE", src: "doc.hidden" });
518
+ };
519
+ return addDomEvent(doc, "visibilitychange", onVisibilityChange);
520
+ },
521
+ trackPointerMove(ctx2, _evt, { send }) {
522
+ const doc = dom.getDoc(ctx2);
523
+ return trackPointerMove(doc, {
524
+ onPointerMove({ event }) {
525
+ send({ type: "DRAGGING", left: -event.movementX, top: -event.movementY });
526
+ },
527
+ onPointerUp() {
528
+ send({ type: "DRAGGING.END" });
529
+ }
530
+ });
531
+ }
532
+ },
533
+ actions: {
534
+ resetScrollPosition(ctx2) {
535
+ const el = dom.getItemGroupEl(ctx2);
536
+ el.scrollTo(0, 0);
537
+ },
538
+ clearScrollEndTimer(ctx2) {
539
+ if (ctx2.timeoutRef.current == null)
540
+ return;
541
+ clearTimeout(ctx2.timeoutRef.current);
542
+ ctx2.timeoutRef.current = void 0;
543
+ },
544
+ scrollToPage(ctx2, evt) {
545
+ const behavior = evt.instant ? "instant" : "smooth";
546
+ const index = clamp(evt.index ?? ctx2.page, 0, ctx2.pageSnapPoints.length - 1);
547
+ const el = dom.getItemGroupEl(ctx2);
548
+ const axis = ctx2.isHorizontal ? "left" : "top";
549
+ el.scrollTo({ [axis]: ctx2.pageSnapPoints[index], behavior });
550
+ },
551
+ setNextPage(ctx2) {
552
+ const page = nextIndex(ctx2.pageSnapPoints, ctx2.page, { loop: ctx2.loop });
553
+ set.page(ctx2, page);
554
+ },
555
+ setPrevPage(ctx2) {
556
+ const page = prevIndex(ctx2.pageSnapPoints, ctx2.page, { loop: ctx2.loop });
557
+ set.page(ctx2, page);
558
+ },
559
+ setMatchingPage(ctx2, evt) {
560
+ const snapPoint = findSnapPoint(
561
+ dom.getItemGroupEl(ctx2),
562
+ ctx2.isHorizontal ? "x" : "y",
563
+ (node) => node.dataset.index === evt.index.toString()
564
+ );
565
+ if (snapPoint == null)
566
+ return;
567
+ const page = ctx2.pageSnapPoints.indexOf(snapPoint);
568
+ set.page(ctx2, page);
569
+ },
570
+ setPage(ctx2, evt) {
571
+ set.page(ctx2, evt.index ?? ctx2.page);
572
+ },
573
+ clampPage(ctx2) {
574
+ const index = clamp(ctx2.page, 0, ctx2.pageSnapPoints.length - 1);
575
+ set.page(ctx2, index);
576
+ },
577
+ setSnapPoints(ctx2) {
578
+ queueMicrotask(() => {
579
+ const el = dom.getItemGroupEl(ctx2);
580
+ const scrollSnapPoints = getScrollSnapPositions(el);
581
+ ctx2.pageSnapPoints = ctx2.isHorizontal ? scrollSnapPoints.x : scrollSnapPoints.y;
582
+ });
583
+ },
584
+ disableScrollSnap(ctx2) {
585
+ const el = dom.getItemGroupEl(ctx2);
586
+ const styles = getComputedStyle(el);
587
+ el.dataset.scrollSnapType = styles.getPropertyValue("scroll-snap-type");
588
+ el.style.setProperty("scroll-snap-type", "none");
589
+ },
590
+ scrollSlides(ctx2, evt) {
591
+ const el = dom.getItemGroupEl(ctx2);
592
+ el.scrollBy({ left: evt.left, top: evt.top, behavior: "instant" });
593
+ },
594
+ endDragging(ctx2) {
595
+ const el = dom.getItemGroupEl(ctx2);
596
+ const startX = el.scrollLeft;
597
+ const startY = el.scrollTop;
598
+ const snapPositions = getScrollSnapPositions(el);
599
+ const closestX = snapPositions.x.reduce((closest, curr) => {
600
+ return Math.abs(curr - startX) < Math.abs(closest - startX) ? curr : closest;
601
+ }, snapPositions.x[0]);
602
+ const closestY = snapPositions.y.reduce((closest, curr) => {
603
+ return Math.abs(curr - startY) < Math.abs(closest - startY) ? curr : closest;
604
+ }, snapPositions.y[0]);
605
+ raf(() => {
606
+ el.scrollTo({ left: closestX, top: closestY, behavior: "smooth" });
607
+ const scrollSnapType = el.dataset.scrollSnapType;
608
+ if (scrollSnapType) {
609
+ el.style.removeProperty("scroll-snap-type");
610
+ delete el.dataset.scrollSnapType;
611
+ }
612
+ });
613
+ },
614
+ focusIndicatorEl(ctx2, evt) {
615
+ if (evt.src !== "indicator")
616
+ return;
617
+ const el = dom.getActiveIndicatorEl(ctx2);
618
+ raf(() => el.focus({ preventScroll: true }));
619
+ },
620
+ invokeDragStart(ctx2) {
621
+ ctx2.onDragStatusChange?.({ type: "dragging.start", isDragging: true, page: ctx2.page });
622
+ },
623
+ invokeDragging(ctx2) {
624
+ ctx2.onDragStatusChange?.({ type: "dragging", isDragging: true, page: ctx2.page });
625
+ },
626
+ invokeDraggingEnd(ctx2) {
627
+ ctx2.onDragStatusChange?.({ type: "dragging.end", isDragging: false, page: ctx2.page });
628
+ },
629
+ invokeAutoplay(ctx2) {
630
+ ctx2.onAutoplayStatusChange?.({ type: "autoplay", isPlaying: true, page: ctx2.page });
631
+ },
632
+ invokeAutoplayStart(ctx2) {
633
+ ctx2.onAutoplayStatusChange?.({ type: "autoplay.start", isPlaying: true, page: ctx2.page });
634
+ },
635
+ invokeAutoplayEnd(ctx2) {
636
+ ctx2.onAutoplayStatusChange?.({ type: "autoplay.stop", isPlaying: false, page: ctx2.page });
637
+ }
638
+ },
639
+ delays: {
640
+ AUTOPLAY_INTERVAL: (ctx2) => ctx2.autoplayInterval
641
+ }
642
+ }
643
+ );
644
+ }
645
+
646
+ const props = createProps()([
647
+ "dir",
648
+ "getRootNode",
649
+ "id",
650
+ "ids",
651
+ "loop",
652
+ "page",
653
+ "onPageChange",
654
+ "orientation",
655
+ "slideCount",
656
+ "slidesPerPage",
657
+ "slidesPerMove",
658
+ "spacing",
659
+ "padding",
660
+ "autoplay",
661
+ "allowMouseDrag",
662
+ "inViewThreshold",
663
+ "translations",
664
+ "snapType",
665
+ "onDragStatusChange",
666
+ "onAutoplayStatusChange"
667
+ ]);
668
+ const splitProps = createSplitProps(props);
669
+ const indicatorProps = createProps()(["index", "readOnly"]);
670
+ const splitIndicatorProps = createSplitProps(indicatorProps);
671
+ const itemProps = createProps()(["index", "snapAlign"]);
672
+ const splitItemProps = createSplitProps(itemProps);
673
+
674
+ export { anatomy, connect, indicatorProps, itemProps, machine, props, splitIndicatorProps, splitItemProps, splitProps };