@zag-js/carousel
Advanced tools
| import * as _zag_js_anatomy from '@zag-js/anatomy'; | ||
| declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "itemGroup" | "item" | "control" | "nextTrigger" | "prevTrigger" | "indicatorGroup" | "indicator" | "autoplayTrigger" | "progressText">; | ||
| declare const parts: Record<"root" | "itemGroup" | "item" | "control" | "nextTrigger" | "prevTrigger" | "indicatorGroup" | "indicator" | "autoplayTrigger" | "progressText", _zag_js_anatomy.AnatomyPart>; | ||
| export { anatomy, parts }; |
| import * as _zag_js_anatomy from '@zag-js/anatomy'; | ||
| declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "itemGroup" | "item" | "control" | "nextTrigger" | "prevTrigger" | "indicatorGroup" | "indicator" | "autoplayTrigger" | "progressText">; | ||
| declare const parts: Record<"root" | "itemGroup" | "item" | "control" | "nextTrigger" | "prevTrigger" | "indicatorGroup" | "indicator" | "autoplayTrigger" | "progressText", _zag_js_anatomy.AnatomyPart>; | ||
| export { anatomy, parts }; |
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.anatomy.ts | ||
| var carousel_anatomy_exports = {}; | ||
| __export(carousel_anatomy_exports, { | ||
| anatomy: () => anatomy, | ||
| parts: () => parts | ||
| }); | ||
| module.exports = __toCommonJS(carousel_anatomy_exports); | ||
| var import_anatomy = require("@zag-js/anatomy"); | ||
| var anatomy = (0, import_anatomy.createAnatomy)("carousel").parts( | ||
| "root", | ||
| "itemGroup", | ||
| "item", | ||
| "control", | ||
| "nextTrigger", | ||
| "prevTrigger", | ||
| "indicatorGroup", | ||
| "indicator", | ||
| "autoplayTrigger", | ||
| "progressText" | ||
| ); | ||
| var parts = anatomy.build(); | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| anatomy, | ||
| parts | ||
| }); |
| // src/carousel.anatomy.ts | ||
| import { createAnatomy } from "@zag-js/anatomy"; | ||
| var anatomy = createAnatomy("carousel").parts( | ||
| "root", | ||
| "itemGroup", | ||
| "item", | ||
| "control", | ||
| "nextTrigger", | ||
| "prevTrigger", | ||
| "indicatorGroup", | ||
| "indicator", | ||
| "autoplayTrigger", | ||
| "progressText" | ||
| ); | ||
| var parts = anatomy.build(); | ||
| export { | ||
| anatomy, | ||
| parts | ||
| }; |
| import { PropTypes, NormalizeProps } from '@zag-js/types'; | ||
| import { CarouselService, CarouselApi } from './carousel.types.mjs'; | ||
| import '@zag-js/core'; | ||
| declare function connect<T extends PropTypes>(service: CarouselService, normalize: NormalizeProps<T>): CarouselApi<T>; | ||
| export { connect }; |
| import { PropTypes, NormalizeProps } from '@zag-js/types'; | ||
| import { CarouselService, CarouselApi } from './carousel.types.js'; | ||
| import '@zag-js/core'; | ||
| declare function connect<T extends PropTypes>(service: CarouselService, normalize: NormalizeProps<T>): CarouselApi<T>; | ||
| export { connect }; |
| "use strict"; | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
| // If the importer is in node compatibility mode or this is not an ESM | ||
| // file that has been converted to a CommonJS file using a Babel- | ||
| // compatible transform (i.e. "__esModule" has not been set), then set | ||
| // "default" to the CommonJS "module.exports" for node compatibility. | ||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
| mod | ||
| )); | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.connect.ts | ||
| var carousel_connect_exports = {}; | ||
| __export(carousel_connect_exports, { | ||
| connect: () => connect | ||
| }); | ||
| module.exports = __toCommonJS(carousel_connect_exports); | ||
| var import_dom_query = require("@zag-js/dom-query"); | ||
| var import_utils = require("@zag-js/utils"); | ||
| var import_carousel = require("./carousel.anatomy.cjs"); | ||
| var dom = __toESM(require("./carousel.dom.cjs")); | ||
| function connect(service, normalize) { | ||
| const { state, context, computed, send, scope, prop } = service; | ||
| const isPlaying = state.matches("autoplay"); | ||
| const isDragging = state.matches("dragging"); | ||
| const canScrollNext = computed("canScrollNext"); | ||
| const canScrollPrev = computed("canScrollPrev"); | ||
| const horizontal = computed("isHorizontal"); | ||
| const autoSize = prop("autoSize"); | ||
| const pageSnapPoints = Array.from(context.get("pageSnapPoints")); | ||
| const page = context.get("page"); | ||
| const slidesPerPage = prop("slidesPerPage"); | ||
| const padding = prop("padding"); | ||
| const translations = prop("translations"); | ||
| return { | ||
| isPlaying, | ||
| isDragging, | ||
| page, | ||
| pageSnapPoints, | ||
| canScrollNext, | ||
| canScrollPrev, | ||
| getProgress() { | ||
| return page / pageSnapPoints.length; | ||
| }, | ||
| getProgressText() { | ||
| const details = { page: page + 1, totalPages: pageSnapPoints.length }; | ||
| return translations.progressText?.(details) ?? ""; | ||
| }, | ||
| scrollToIndex(index, instant) { | ||
| send({ type: "INDEX.SET", index, instant }); | ||
| }, | ||
| scrollTo(index, instant) { | ||
| send({ type: "PAGE.SET", index, instant }); | ||
| }, | ||
| scrollNext(instant) { | ||
| send({ type: "PAGE.NEXT", instant }); | ||
| }, | ||
| scrollPrev(instant) { | ||
| send({ type: "PAGE.PREV", instant }); | ||
| }, | ||
| play() { | ||
| send({ type: "AUTOPLAY.START" }); | ||
| }, | ||
| pause() { | ||
| send({ type: "AUTOPLAY.PAUSE" }); | ||
| }, | ||
| isInView(index) { | ||
| return Array.from(context.get("slidesInView")).includes(index); | ||
| }, | ||
| refresh() { | ||
| send({ type: "SNAP.REFRESH" }); | ||
| }, | ||
| getRootProps() { | ||
| return normalize.element({ | ||
| ...import_carousel.parts.root.attrs, | ||
| id: dom.getRootId(scope), | ||
| role: "region", | ||
| "aria-roledescription": "carousel", | ||
| "data-orientation": prop("orientation"), | ||
| dir: prop("dir"), | ||
| style: { | ||
| "--slides-per-page": slidesPerPage, | ||
| "--slide-spacing": prop("spacing"), | ||
| "--slide-item-size": autoSize ? "auto" : "calc(100% / var(--slides-per-page) - var(--slide-spacing) * (var(--slides-per-page) - 1) / var(--slides-per-page))" | ||
| } | ||
| }); | ||
| }, | ||
| getItemGroupProps() { | ||
| return normalize.element({ | ||
| ...import_carousel.parts.itemGroup.attrs, | ||
| id: dom.getItemGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| "data-dragging": (0, import_dom_query.dataAttr)(isDragging), | ||
| dir: prop("dir"), | ||
| "aria-live": isPlaying ? "off" : "polite", | ||
| onFocus(event) { | ||
| if (!(0, import_dom_query.contains)(event.currentTarget, (0, import_dom_query.getEventTarget)(event))) return; | ||
| send({ type: "VIEWPORT.FOCUS" }); | ||
| }, | ||
| onBlur(event) { | ||
| if ((0, import_dom_query.contains)(event.currentTarget, event.relatedTarget)) return; | ||
| send({ type: "VIEWPORT.BLUR" }); | ||
| }, | ||
| onMouseDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (!prop("allowMouseDrag")) return; | ||
| if (!(0, import_dom_query.isLeftClick)(event)) return; | ||
| const target = (0, import_dom_query.getEventTarget)(event); | ||
| if ((0, import_dom_query.isFocusable)(target) && target !== event.currentTarget) return; | ||
| event.preventDefault(); | ||
| send({ type: "DRAGGING.START" }); | ||
| }, | ||
| onWheel: (0, import_utils.throttle)((event) => { | ||
| const axis = prop("orientation") === "horizontal" ? "deltaX" : "deltaY"; | ||
| const isScrollingLeft = event[axis] < 0; | ||
| if (isScrollingLeft && !computed("canScrollPrev")) return; | ||
| const isScrollingRight = event[axis] > 0; | ||
| if (isScrollingRight && !computed("canScrollNext")) return; | ||
| send({ type: "USER.SCROLL" }); | ||
| }, 150), | ||
| onTouchStart() { | ||
| send({ type: "USER.SCROLL" }); | ||
| }, | ||
| style: { | ||
| display: autoSize ? "flex" : "grid", | ||
| gap: "var(--slide-spacing)", | ||
| scrollSnapType: [horizontal ? "x" : "y", prop("snapType")].join(" "), | ||
| gridAutoFlow: horizontal ? "column" : "row", | ||
| scrollbarWidth: "none", | ||
| overscrollBehaviorX: "contain", | ||
| [horizontal ? "gridAutoColumns" : "gridAutoRows"]: autoSize ? void 0 : "var(--slide-item-size)", | ||
| [horizontal ? "scrollPaddingInline" : "scrollPaddingBlock"]: padding, | ||
| [horizontal ? "paddingInline" : "paddingBlock"]: padding, | ||
| [horizontal ? "overflowX" : "overflowY"]: "auto" | ||
| } | ||
| }); | ||
| }, | ||
| getItemProps(props) { | ||
| const isInView = context.get("slidesInView").includes(props.index); | ||
| return normalize.element({ | ||
| ...import_carousel.parts.item.attrs, | ||
| id: dom.getItemId(scope, props.index), | ||
| dir: prop("dir"), | ||
| role: "group", | ||
| "data-index": props.index, | ||
| "data-inview": (0, import_dom_query.dataAttr)(isInView), | ||
| "aria-roledescription": "slide", | ||
| "data-orientation": prop("orientation"), | ||
| "aria-label": translations.item(props.index, prop("slideCount")), | ||
| "aria-hidden": (0, import_dom_query.ariaAttr)(!isInView), | ||
| style: { | ||
| flex: "0 0 auto", | ||
| [horizontal ? "maxWidth" : "maxHeight"]: "100%", | ||
| scrollSnapAlign: (() => { | ||
| const snapAlign = props.snapAlign ?? "start"; | ||
| const slidesPerMove = prop("slidesPerMove"); | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(prop("slidesPerPage")) : slidesPerMove; | ||
| const shouldSnap = (props.index + perMove) % perMove === 0; | ||
| return shouldSnap ? snapAlign : void 0; | ||
| })() | ||
| } | ||
| }); | ||
| }, | ||
| getControlProps() { | ||
| return normalize.element({ | ||
| ...import_carousel.parts.control.attrs, | ||
| "data-orientation": prop("orientation") | ||
| }); | ||
| }, | ||
| getPrevTriggerProps() { | ||
| return normalize.button({ | ||
| ...import_carousel.parts.prevTrigger.attrs, | ||
| id: dom.getPrevTriggerId(scope), | ||
| type: "button", | ||
| disabled: !canScrollPrev, | ||
| dir: prop("dir"), | ||
| "aria-label": translations.prevTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": dom.getItemGroupId(scope), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.PREV", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getNextTriggerProps() { | ||
| return normalize.button({ | ||
| ...import_carousel.parts.nextTrigger.attrs, | ||
| dir: prop("dir"), | ||
| id: dom.getNextTriggerId(scope), | ||
| type: "button", | ||
| "aria-label": translations.nextTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": dom.getItemGroupId(scope), | ||
| disabled: !canScrollNext, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.NEXT", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorGroupProps() { | ||
| return normalize.element({ | ||
| ...import_carousel.parts.indicatorGroup.attrs, | ||
| dir: prop("dir"), | ||
| id: dom.getIndicatorGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| onKeyDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| const src = "indicator"; | ||
| const keyMap = { | ||
| ArrowDown(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowUp(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowRight(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowLeft(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| Home(event2) { | ||
| send({ type: "PAGE.SET", index: 0, src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| End(event2) { | ||
| send({ type: "PAGE.SET", index: pageSnapPoints.length - 1, src }); | ||
| event2.preventDefault(); | ||
| } | ||
| }; | ||
| const key = (0, import_dom_query.getEventKey)(event, { | ||
| dir: prop("dir"), | ||
| orientation: prop("orientation") | ||
| }); | ||
| const exec = keyMap[key]; | ||
| exec?.(event); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorProps(props) { | ||
| return normalize.button({ | ||
| ...import_carousel.parts.indicator.attrs, | ||
| dir: prop("dir"), | ||
| id: dom.getIndicatorId(scope, props.index), | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-index": props.index, | ||
| "data-readonly": (0, import_dom_query.dataAttr)(props.readOnly), | ||
| "data-current": (0, import_dom_query.dataAttr)(props.index === page), | ||
| "aria-label": translations.indicator(props.index), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (props.readOnly) return; | ||
| send({ type: "PAGE.SET", index: props.index, src: "indicator" }); | ||
| } | ||
| }); | ||
| }, | ||
| getAutoplayTriggerProps() { | ||
| return normalize.button({ | ||
| ...import_carousel.parts.autoplayTrigger.attrs, | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-pressed": (0, import_dom_query.dataAttr)(isPlaying), | ||
| "aria-label": isPlaying ? translations.autoplayStop : translations.autoplayStart, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: isPlaying ? "AUTOPLAY.PAUSE" : "AUTOPLAY.START" }); | ||
| } | ||
| }); | ||
| }, | ||
| getProgressTextProps() { | ||
| return normalize.element({ | ||
| ...import_carousel.parts.progressText.attrs | ||
| }); | ||
| } | ||
| }; | ||
| } | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| connect | ||
| }); |
| // src/carousel.connect.ts | ||
| import { ariaAttr, contains, dataAttr, getEventKey, getEventTarget, isFocusable, isLeftClick } from "@zag-js/dom-query"; | ||
| import { throttle } from "@zag-js/utils"; | ||
| import { parts } from "./carousel.anatomy.mjs"; | ||
| import * as dom from "./carousel.dom.mjs"; | ||
| function connect(service, normalize) { | ||
| const { state, context, computed, send, scope, prop } = service; | ||
| const isPlaying = state.matches("autoplay"); | ||
| const isDragging = state.matches("dragging"); | ||
| const canScrollNext = computed("canScrollNext"); | ||
| const canScrollPrev = computed("canScrollPrev"); | ||
| const horizontal = computed("isHorizontal"); | ||
| const autoSize = prop("autoSize"); | ||
| const pageSnapPoints = Array.from(context.get("pageSnapPoints")); | ||
| const page = context.get("page"); | ||
| const slidesPerPage = prop("slidesPerPage"); | ||
| const padding = prop("padding"); | ||
| const translations = prop("translations"); | ||
| return { | ||
| isPlaying, | ||
| isDragging, | ||
| page, | ||
| pageSnapPoints, | ||
| canScrollNext, | ||
| canScrollPrev, | ||
| getProgress() { | ||
| return page / pageSnapPoints.length; | ||
| }, | ||
| getProgressText() { | ||
| const details = { page: page + 1, totalPages: pageSnapPoints.length }; | ||
| return translations.progressText?.(details) ?? ""; | ||
| }, | ||
| scrollToIndex(index, instant) { | ||
| send({ type: "INDEX.SET", index, instant }); | ||
| }, | ||
| scrollTo(index, instant) { | ||
| send({ type: "PAGE.SET", index, instant }); | ||
| }, | ||
| scrollNext(instant) { | ||
| send({ type: "PAGE.NEXT", instant }); | ||
| }, | ||
| scrollPrev(instant) { | ||
| send({ type: "PAGE.PREV", instant }); | ||
| }, | ||
| play() { | ||
| send({ type: "AUTOPLAY.START" }); | ||
| }, | ||
| pause() { | ||
| send({ type: "AUTOPLAY.PAUSE" }); | ||
| }, | ||
| isInView(index) { | ||
| return Array.from(context.get("slidesInView")).includes(index); | ||
| }, | ||
| refresh() { | ||
| send({ type: "SNAP.REFRESH" }); | ||
| }, | ||
| getRootProps() { | ||
| return normalize.element({ | ||
| ...parts.root.attrs, | ||
| id: dom.getRootId(scope), | ||
| role: "region", | ||
| "aria-roledescription": "carousel", | ||
| "data-orientation": prop("orientation"), | ||
| dir: prop("dir"), | ||
| style: { | ||
| "--slides-per-page": slidesPerPage, | ||
| "--slide-spacing": prop("spacing"), | ||
| "--slide-item-size": autoSize ? "auto" : "calc(100% / var(--slides-per-page) - var(--slide-spacing) * (var(--slides-per-page) - 1) / var(--slides-per-page))" | ||
| } | ||
| }); | ||
| }, | ||
| getItemGroupProps() { | ||
| return normalize.element({ | ||
| ...parts.itemGroup.attrs, | ||
| id: dom.getItemGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| "data-dragging": dataAttr(isDragging), | ||
| dir: prop("dir"), | ||
| "aria-live": isPlaying ? "off" : "polite", | ||
| onFocus(event) { | ||
| if (!contains(event.currentTarget, getEventTarget(event))) return; | ||
| send({ type: "VIEWPORT.FOCUS" }); | ||
| }, | ||
| onBlur(event) { | ||
| if (contains(event.currentTarget, event.relatedTarget)) return; | ||
| send({ type: "VIEWPORT.BLUR" }); | ||
| }, | ||
| onMouseDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (!prop("allowMouseDrag")) return; | ||
| if (!isLeftClick(event)) return; | ||
| const target = getEventTarget(event); | ||
| if (isFocusable(target) && target !== event.currentTarget) return; | ||
| event.preventDefault(); | ||
| send({ type: "DRAGGING.START" }); | ||
| }, | ||
| onWheel: throttle((event) => { | ||
| const axis = prop("orientation") === "horizontal" ? "deltaX" : "deltaY"; | ||
| const isScrollingLeft = event[axis] < 0; | ||
| if (isScrollingLeft && !computed("canScrollPrev")) return; | ||
| const isScrollingRight = event[axis] > 0; | ||
| if (isScrollingRight && !computed("canScrollNext")) return; | ||
| send({ type: "USER.SCROLL" }); | ||
| }, 150), | ||
| onTouchStart() { | ||
| send({ type: "USER.SCROLL" }); | ||
| }, | ||
| style: { | ||
| display: autoSize ? "flex" : "grid", | ||
| gap: "var(--slide-spacing)", | ||
| scrollSnapType: [horizontal ? "x" : "y", prop("snapType")].join(" "), | ||
| gridAutoFlow: horizontal ? "column" : "row", | ||
| scrollbarWidth: "none", | ||
| overscrollBehaviorX: "contain", | ||
| [horizontal ? "gridAutoColumns" : "gridAutoRows"]: autoSize ? void 0 : "var(--slide-item-size)", | ||
| [horizontal ? "scrollPaddingInline" : "scrollPaddingBlock"]: padding, | ||
| [horizontal ? "paddingInline" : "paddingBlock"]: padding, | ||
| [horizontal ? "overflowX" : "overflowY"]: "auto" | ||
| } | ||
| }); | ||
| }, | ||
| getItemProps(props) { | ||
| const isInView = context.get("slidesInView").includes(props.index); | ||
| return normalize.element({ | ||
| ...parts.item.attrs, | ||
| id: dom.getItemId(scope, props.index), | ||
| dir: prop("dir"), | ||
| role: "group", | ||
| "data-index": props.index, | ||
| "data-inview": dataAttr(isInView), | ||
| "aria-roledescription": "slide", | ||
| "data-orientation": prop("orientation"), | ||
| "aria-label": translations.item(props.index, prop("slideCount")), | ||
| "aria-hidden": ariaAttr(!isInView), | ||
| style: { | ||
| flex: "0 0 auto", | ||
| [horizontal ? "maxWidth" : "maxHeight"]: "100%", | ||
| scrollSnapAlign: (() => { | ||
| const snapAlign = props.snapAlign ?? "start"; | ||
| const slidesPerMove = prop("slidesPerMove"); | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(prop("slidesPerPage")) : slidesPerMove; | ||
| const shouldSnap = (props.index + perMove) % perMove === 0; | ||
| return shouldSnap ? snapAlign : void 0; | ||
| })() | ||
| } | ||
| }); | ||
| }, | ||
| getControlProps() { | ||
| return normalize.element({ | ||
| ...parts.control.attrs, | ||
| "data-orientation": prop("orientation") | ||
| }); | ||
| }, | ||
| getPrevTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.prevTrigger.attrs, | ||
| id: dom.getPrevTriggerId(scope), | ||
| type: "button", | ||
| disabled: !canScrollPrev, | ||
| dir: prop("dir"), | ||
| "aria-label": translations.prevTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": dom.getItemGroupId(scope), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.PREV", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getNextTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.nextTrigger.attrs, | ||
| dir: prop("dir"), | ||
| id: dom.getNextTriggerId(scope), | ||
| type: "button", | ||
| "aria-label": translations.nextTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": dom.getItemGroupId(scope), | ||
| disabled: !canScrollNext, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.NEXT", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorGroupProps() { | ||
| return normalize.element({ | ||
| ...parts.indicatorGroup.attrs, | ||
| dir: prop("dir"), | ||
| id: dom.getIndicatorGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| onKeyDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| const src = "indicator"; | ||
| const keyMap = { | ||
| ArrowDown(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowUp(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowRight(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowLeft(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| Home(event2) { | ||
| send({ type: "PAGE.SET", index: 0, src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| End(event2) { | ||
| send({ type: "PAGE.SET", index: pageSnapPoints.length - 1, src }); | ||
| event2.preventDefault(); | ||
| } | ||
| }; | ||
| const key = getEventKey(event, { | ||
| dir: prop("dir"), | ||
| orientation: prop("orientation") | ||
| }); | ||
| const exec = keyMap[key]; | ||
| exec?.(event); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorProps(props) { | ||
| return normalize.button({ | ||
| ...parts.indicator.attrs, | ||
| dir: prop("dir"), | ||
| id: dom.getIndicatorId(scope, props.index), | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-index": props.index, | ||
| "data-readonly": dataAttr(props.readOnly), | ||
| "data-current": dataAttr(props.index === page), | ||
| "aria-label": translations.indicator(props.index), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (props.readOnly) return; | ||
| send({ type: "PAGE.SET", index: props.index, src: "indicator" }); | ||
| } | ||
| }); | ||
| }, | ||
| getAutoplayTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.autoplayTrigger.attrs, | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-pressed": dataAttr(isPlaying), | ||
| "aria-label": isPlaying ? translations.autoplayStop : translations.autoplayStart, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: isPlaying ? "AUTOPLAY.PAUSE" : "AUTOPLAY.START" }); | ||
| } | ||
| }); | ||
| }, | ||
| getProgressTextProps() { | ||
| return normalize.element({ | ||
| ...parts.progressText.attrs | ||
| }); | ||
| } | ||
| }; | ||
| } | ||
| export { | ||
| connect | ||
| }; |
| import { Scope } from '@zag-js/core'; | ||
| declare const getRootId: (ctx: Scope) => any; | ||
| declare const getItemId: (ctx: Scope, index: number) => any; | ||
| declare const getItemGroupId: (ctx: Scope) => any; | ||
| declare const getNextTriggerId: (ctx: Scope) => any; | ||
| declare const getPrevTriggerId: (ctx: Scope) => any; | ||
| declare const getIndicatorGroupId: (ctx: Scope) => any; | ||
| declare const getIndicatorId: (ctx: Scope, index: number) => any; | ||
| declare const getRootEl: (ctx: Scope) => HTMLElement | null; | ||
| declare const getItemGroupEl: (ctx: Scope) => HTMLElement | null; | ||
| declare const getItemEl: (ctx: Scope, index: number) => HTMLElement | null; | ||
| declare const getItemEls: (ctx: Scope) => HTMLElement[]; | ||
| declare const getIndicatorEl: (ctx: Scope, page: number) => HTMLElement | null; | ||
| declare const syncTabIndex: (ctx: Scope) => void; | ||
| export { getIndicatorEl, getIndicatorGroupId, getIndicatorId, getItemEl, getItemEls, getItemGroupEl, getItemGroupId, getItemId, getNextTriggerId, getPrevTriggerId, getRootEl, getRootId, syncTabIndex }; |
| import { Scope } from '@zag-js/core'; | ||
| declare const getRootId: (ctx: Scope) => any; | ||
| declare const getItemId: (ctx: Scope, index: number) => any; | ||
| declare const getItemGroupId: (ctx: Scope) => any; | ||
| declare const getNextTriggerId: (ctx: Scope) => any; | ||
| declare const getPrevTriggerId: (ctx: Scope) => any; | ||
| declare const getIndicatorGroupId: (ctx: Scope) => any; | ||
| declare const getIndicatorId: (ctx: Scope, index: number) => any; | ||
| declare const getRootEl: (ctx: Scope) => HTMLElement | null; | ||
| declare const getItemGroupEl: (ctx: Scope) => HTMLElement | null; | ||
| declare const getItemEl: (ctx: Scope, index: number) => HTMLElement | null; | ||
| declare const getItemEls: (ctx: Scope) => HTMLElement[]; | ||
| declare const getIndicatorEl: (ctx: Scope, page: number) => HTMLElement | null; | ||
| declare const syncTabIndex: (ctx: Scope) => void; | ||
| export { getIndicatorEl, getIndicatorGroupId, getIndicatorId, getItemEl, getItemEls, getItemGroupEl, getItemGroupId, getItemId, getNextTriggerId, getPrevTriggerId, getRootEl, getRootId, syncTabIndex }; |
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.dom.ts | ||
| var carousel_dom_exports = {}; | ||
| __export(carousel_dom_exports, { | ||
| getIndicatorEl: () => getIndicatorEl, | ||
| getIndicatorGroupId: () => getIndicatorGroupId, | ||
| getIndicatorId: () => getIndicatorId, | ||
| getItemEl: () => getItemEl, | ||
| getItemEls: () => getItemEls, | ||
| getItemGroupEl: () => getItemGroupEl, | ||
| getItemGroupId: () => getItemGroupId, | ||
| getItemId: () => getItemId, | ||
| getNextTriggerId: () => getNextTriggerId, | ||
| getPrevTriggerId: () => getPrevTriggerId, | ||
| getRootEl: () => getRootEl, | ||
| getRootId: () => getRootId, | ||
| syncTabIndex: () => syncTabIndex | ||
| }); | ||
| module.exports = __toCommonJS(carousel_dom_exports); | ||
| var import_dom_query = require("@zag-js/dom-query"); | ||
| var getRootId = (ctx) => ctx.ids?.root ?? `carousel:${ctx.id}`; | ||
| var getItemId = (ctx, index) => ctx.ids?.item?.(index) ?? `carousel:${ctx.id}:item:${index}`; | ||
| var getItemGroupId = (ctx) => ctx.ids?.itemGroup ?? `carousel:${ctx.id}:item-group`; | ||
| var getNextTriggerId = (ctx) => ctx.ids?.nextTrigger ?? `carousel:${ctx.id}:next-trigger`; | ||
| var getPrevTriggerId = (ctx) => ctx.ids?.prevTrigger ?? `carousel:${ctx.id}:prev-trigger`; | ||
| var getIndicatorGroupId = (ctx) => ctx.ids?.indicatorGroup ?? `carousel:${ctx.id}:indicator-group`; | ||
| var getIndicatorId = (ctx, index) => ctx.ids?.indicator?.(index) ?? `carousel:${ctx.id}:indicator:${index}`; | ||
| var getRootEl = (ctx) => ctx.getById(getRootId(ctx)); | ||
| var getItemGroupEl = (ctx) => ctx.getById(getItemGroupId(ctx)); | ||
| var getItemEl = (ctx, index) => ctx.getById(getItemId(ctx, index)); | ||
| var getItemEls = (ctx) => (0, import_dom_query.queryAll)(getItemGroupEl(ctx), `[data-part=item]`); | ||
| var getIndicatorEl = (ctx, page) => ctx.getById(getIndicatorId(ctx, page)); | ||
| var syncTabIndex = (ctx) => { | ||
| const el = getItemGroupEl(ctx); | ||
| if (!el) return; | ||
| const tabbables = (0, import_dom_query.getTabbables)(el); | ||
| el.setAttribute("tabindex", tabbables.length > 0 ? "-1" : "0"); | ||
| }; | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| getIndicatorEl, | ||
| getIndicatorGroupId, | ||
| getIndicatorId, | ||
| getItemEl, | ||
| getItemEls, | ||
| getItemGroupEl, | ||
| getItemGroupId, | ||
| getItemId, | ||
| getNextTriggerId, | ||
| getPrevTriggerId, | ||
| getRootEl, | ||
| getRootId, | ||
| syncTabIndex | ||
| }); |
| // src/carousel.dom.ts | ||
| import { getTabbables, queryAll } from "@zag-js/dom-query"; | ||
| var getRootId = (ctx) => ctx.ids?.root ?? `carousel:${ctx.id}`; | ||
| var getItemId = (ctx, index) => ctx.ids?.item?.(index) ?? `carousel:${ctx.id}:item:${index}`; | ||
| var getItemGroupId = (ctx) => ctx.ids?.itemGroup ?? `carousel:${ctx.id}:item-group`; | ||
| var getNextTriggerId = (ctx) => ctx.ids?.nextTrigger ?? `carousel:${ctx.id}:next-trigger`; | ||
| var getPrevTriggerId = (ctx) => ctx.ids?.prevTrigger ?? `carousel:${ctx.id}:prev-trigger`; | ||
| var getIndicatorGroupId = (ctx) => ctx.ids?.indicatorGroup ?? `carousel:${ctx.id}:indicator-group`; | ||
| var getIndicatorId = (ctx, index) => ctx.ids?.indicator?.(index) ?? `carousel:${ctx.id}:indicator:${index}`; | ||
| var getRootEl = (ctx) => ctx.getById(getRootId(ctx)); | ||
| var getItemGroupEl = (ctx) => ctx.getById(getItemGroupId(ctx)); | ||
| var getItemEl = (ctx, index) => ctx.getById(getItemId(ctx, index)); | ||
| var getItemEls = (ctx) => queryAll(getItemGroupEl(ctx), `[data-part=item]`); | ||
| var getIndicatorEl = (ctx, page) => ctx.getById(getIndicatorId(ctx, page)); | ||
| var syncTabIndex = (ctx) => { | ||
| const el = getItemGroupEl(ctx); | ||
| if (!el) return; | ||
| const tabbables = getTabbables(el); | ||
| el.setAttribute("tabindex", tabbables.length > 0 ? "-1" : "0"); | ||
| }; | ||
| export { | ||
| getIndicatorEl, | ||
| getIndicatorGroupId, | ||
| getIndicatorId, | ||
| getItemEl, | ||
| getItemEls, | ||
| getItemGroupEl, | ||
| getItemGroupId, | ||
| getItemId, | ||
| getNextTriggerId, | ||
| getPrevTriggerId, | ||
| getRootEl, | ||
| getRootId, | ||
| syncTabIndex | ||
| }; |
| import * as _zag_js_core from '@zag-js/core'; | ||
| import { CarouselSchema } from './carousel.types.mjs'; | ||
| import '@zag-js/types'; | ||
| declare const machine: _zag_js_core.Machine<CarouselSchema>; | ||
| export { machine }; |
| import * as _zag_js_core from '@zag-js/core'; | ||
| import { CarouselSchema } from './carousel.types.js'; | ||
| import '@zag-js/types'; | ||
| declare const machine: _zag_js_core.Machine<CarouselSchema>; | ||
| export { machine }; |
| "use strict"; | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps( | ||
| // If the importer is in node compatibility mode or this is not an ESM | ||
| // file that has been converted to a CommonJS file using a Babel- | ||
| // compatible transform (i.e. "__esModule" has not been set), then set | ||
| // "default" to the CommonJS "module.exports" for node compatibility. | ||
| isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target, | ||
| mod | ||
| )); | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.machine.ts | ||
| var carousel_machine_exports = {}; | ||
| __export(carousel_machine_exports, { | ||
| machine: () => machine | ||
| }); | ||
| module.exports = __toCommonJS(carousel_machine_exports); | ||
| var import_core = require("@zag-js/core"); | ||
| var import_dom_query = require("@zag-js/dom-query"); | ||
| var import_scroll_snap = require("@zag-js/scroll-snap"); | ||
| var import_utils = require("@zag-js/utils"); | ||
| var dom = __toESM(require("./carousel.dom.cjs")); | ||
| var machine = (0, import_core.createMachine)({ | ||
| props({ props }) { | ||
| (0, import_utils.ensureProps)(props, ["slideCount"], "carousel"); | ||
| return { | ||
| dir: "ltr", | ||
| defaultPage: 0, | ||
| orientation: "horizontal", | ||
| snapType: "mandatory", | ||
| loop: !!props.autoplay, | ||
| slidesPerPage: 1, | ||
| slidesPerMove: "auto", | ||
| spacing: "0px", | ||
| autoplay: false, | ||
| allowMouseDrag: false, | ||
| inViewThreshold: 0.6, | ||
| autoSize: false, | ||
| ...props, | ||
| translations: { | ||
| nextTrigger: "Next slide", | ||
| prevTrigger: "Previous slide", | ||
| indicator: (index) => `Go to slide ${index + 1}`, | ||
| item: (index, count) => `${index + 1} of ${count}`, | ||
| autoplayStart: "Start slide rotation", | ||
| autoplayStop: "Stop slide rotation", | ||
| progressText: ({ page, totalPages }) => `${page} / ${totalPages}`, | ||
| ...props.translations | ||
| } | ||
| }; | ||
| }, | ||
| refs() { | ||
| return { | ||
| timeoutRef: void 0 | ||
| }; | ||
| }, | ||
| initialState({ prop }) { | ||
| return prop("autoplay") ? "autoplay" : "idle"; | ||
| }, | ||
| context({ prop, bindable, getContext }) { | ||
| return { | ||
| page: bindable(() => ({ | ||
| defaultValue: prop("defaultPage"), | ||
| value: prop("page"), | ||
| onChange(page) { | ||
| const ctx = getContext(); | ||
| const pageSnapPoints = ctx.get("pageSnapPoints"); | ||
| prop("onPageChange")?.({ page, pageSnapPoint: pageSnapPoints[page] }); | ||
| } | ||
| })), | ||
| pageSnapPoints: bindable(() => { | ||
| return { | ||
| defaultValue: prop("autoSize") ? Array.from({ length: prop("slideCount") }, (_, i) => i) : getPageSnapPoints(prop("slideCount"), prop("slidesPerMove"), prop("slidesPerPage")) | ||
| }; | ||
| }), | ||
| slidesInView: bindable(() => ({ | ||
| defaultValue: [] | ||
| })) | ||
| }; | ||
| }, | ||
| computed: { | ||
| isRtl: ({ prop }) => prop("dir") === "rtl", | ||
| isHorizontal: ({ prop }) => prop("orientation") === "horizontal", | ||
| canScrollNext: ({ prop, context }) => prop("loop") || context.get("page") < context.get("pageSnapPoints").length - 1, | ||
| canScrollPrev: ({ prop, context }) => prop("loop") || context.get("page") > 0, | ||
| autoplayInterval: ({ prop }) => { | ||
| const autoplay = prop("autoplay"); | ||
| return (0, import_utils.isObject)(autoplay) ? autoplay.delay : 4e3; | ||
| } | ||
| }, | ||
| watch({ track, action, context, prop, send }) { | ||
| track([() => prop("slidesPerPage"), () => prop("slidesPerMove")], () => { | ||
| action(["setSnapPoints"]); | ||
| }); | ||
| track([() => context.get("page")], () => { | ||
| action(["scrollToPage", "focusIndicatorEl"]); | ||
| }); | ||
| track([() => prop("orientation"), () => prop("autoSize"), () => prop("dir")], () => { | ||
| action(["setSnapPoints", "scrollToPage"]); | ||
| }); | ||
| track([() => prop("slideCount")], () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.count" }); | ||
| }); | ||
| track([() => !!prop("autoplay")], () => { | ||
| send({ type: prop("autoplay") ? "AUTOPLAY.START" : "AUTOPLAY.PAUSE", src: "autoplay.prop.change" }); | ||
| }); | ||
| }, | ||
| on: { | ||
| "PAGE.NEXT": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "SNAP.REFRESH": { | ||
| actions: ["setSnapPoints", "clampPage"] | ||
| }, | ||
| "PAGE.SCROLL": { | ||
| actions: ["scrollToPage"] | ||
| } | ||
| }, | ||
| effects: ["trackSlideMutation", "trackSlideIntersections", "trackSlideResize"], | ||
| entry: ["setSnapPoints", "setPage"], | ||
| exit: ["clearScrollEndTimer"], | ||
| states: { | ||
| idle: { | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.START": { | ||
| target: "autoplay", | ||
| actions: ["invokeAutoplayStart"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| }, | ||
| "VIEWPORT.FOCUS": { | ||
| target: "focus" | ||
| } | ||
| } | ||
| }, | ||
| focus: { | ||
| effects: ["trackKeyboardScroll"], | ||
| on: { | ||
| "VIEWPORT.BLUR": { | ||
| target: "idle" | ||
| }, | ||
| "PAGE.NEXT": { | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| } | ||
| } | ||
| }, | ||
| dragging: { | ||
| effects: ["trackPointerMove"], | ||
| entry: ["disableScrollSnap"], | ||
| on: { | ||
| DRAGGING: { | ||
| actions: ["scrollSlides", "invokeDragging"] | ||
| }, | ||
| "DRAGGING.END": { | ||
| target: "idle", | ||
| actions: ["endDragging", "invokeDraggingEnd"] | ||
| } | ||
| } | ||
| }, | ||
| userScroll: { | ||
| effects: ["trackScroll"], | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "SCROLL.END": [ | ||
| { | ||
| guard: "isFocused", | ||
| target: "focus", | ||
| actions: ["setClosestPage"] | ||
| }, | ||
| { | ||
| target: "idle", | ||
| actions: ["setClosestPage"] | ||
| } | ||
| ] | ||
| } | ||
| }, | ||
| autoplay: { | ||
| effects: ["trackDocumentVisibility", "trackScroll", "autoUpdateSlide"], | ||
| exit: ["invokeAutoplayEnd"], | ||
| on: { | ||
| "AUTOPLAY.TICK": { | ||
| actions: ["setNextPage", "invokeAutoplay"] | ||
| }, | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.PAUSE": { | ||
| target: "idle" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| implementations: { | ||
| guards: { | ||
| isFocused: ({ scope }) => scope.isActiveElement(dom.getItemGroupEl(scope)) | ||
| }, | ||
| effects: { | ||
| autoUpdateSlide({ computed, send }) { | ||
| const id = setInterval(() => { | ||
| send({ | ||
| type: computed("canScrollNext") ? "AUTOPLAY.TICK" : "AUTOPLAY.PAUSE", | ||
| src: "autoplay.interval" | ||
| }); | ||
| }, computed("autoplayInterval")); | ||
| return () => clearInterval(id); | ||
| }, | ||
| trackSlideMutation({ scope, send }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const win = scope.getWin(); | ||
| const observer = new win.MutationObserver(() => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.mutation" }); | ||
| dom.syncTabIndex(scope); | ||
| }); | ||
| dom.syncTabIndex(scope); | ||
| observer.observe(el, { childList: true, subtree: true }); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackSlideResize({ scope, send }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const exec = () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.resize" }); | ||
| }; | ||
| (0, import_dom_query.raf)(() => { | ||
| exec(); | ||
| (0, import_dom_query.raf)(() => { | ||
| send({ type: "PAGE.SCROLL", instant: true }); | ||
| }); | ||
| }); | ||
| const itemEls = dom.getItemEls(scope); | ||
| itemEls.forEach(exec); | ||
| const cleanups = itemEls.map((el2) => import_dom_query.resizeObserverBorderBox.observe(el2, exec)); | ||
| return (0, import_utils.callAll)(...cleanups); | ||
| }, | ||
| trackSlideIntersections({ scope, prop, context }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| const win = scope.getWin(); | ||
| const observer = new win.IntersectionObserver( | ||
| (entries) => { | ||
| const slidesInView = entries.reduce((acc, entry) => { | ||
| const target = entry.target; | ||
| const index = Number(target.dataset.index ?? "-1"); | ||
| if (index == null || Number.isNaN(index) || index === -1) return acc; | ||
| return entry.isIntersecting ? (0, import_utils.add)(acc, index) : (0, import_utils.remove)(acc, index); | ||
| }, context.get("slidesInView")); | ||
| context.set("slidesInView", (0, import_utils.uniq)(slidesInView)); | ||
| }, | ||
| { | ||
| root: el, | ||
| threshold: prop("inViewThreshold") | ||
| } | ||
| ); | ||
| dom.getItemEls(scope).forEach((slide) => observer.observe(slide)); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackScroll({ send, refs, scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const onScroll = () => { | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| refs.set( | ||
| "timeoutRef", | ||
| setTimeout(() => { | ||
| send({ type: "SCROLL.END" }); | ||
| }, 150) | ||
| ); | ||
| }; | ||
| return (0, import_dom_query.addDomEvent)(el, "scroll", onScroll, { passive: true }); | ||
| }, | ||
| trackDocumentVisibility({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| const onVisibilityChange = () => { | ||
| if (doc.visibilityState === "visible") return; | ||
| send({ type: "AUTOPLAY.PAUSE", src: "doc.hidden" }); | ||
| }; | ||
| return (0, import_dom_query.addDomEvent)(doc, "visibilitychange", onVisibilityChange); | ||
| }, | ||
| trackPointerMove({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| return (0, import_dom_query.trackPointerMove)(doc, { | ||
| onPointerMove({ event }) { | ||
| send({ type: "DRAGGING", left: -event.movementX, top: -event.movementY }); | ||
| }, | ||
| onPointerUp() { | ||
| send({ type: "DRAGGING.END" }); | ||
| } | ||
| }); | ||
| }, | ||
| trackKeyboardScroll({ scope, send, context }) { | ||
| const win = scope.getWin(); | ||
| const onKeyDown = (event) => { | ||
| switch (event.key) { | ||
| case "ArrowRight": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.NEXT" }); | ||
| break; | ||
| case "ArrowLeft": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.PREV" }); | ||
| break; | ||
| case "Home": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: 0 }); | ||
| break; | ||
| case "End": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: context.get("pageSnapPoints").length - 1 }); | ||
| } | ||
| }; | ||
| return (0, import_dom_query.addDomEvent)(win, "keydown", onKeyDown, { capture: true }); | ||
| } | ||
| }, | ||
| actions: { | ||
| clearScrollEndTimer({ refs }) { | ||
| if (refs.get("timeoutRef") == null) return; | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| }, | ||
| scrollToPage({ context, event, scope, computed, flush }) { | ||
| const behavior = event.instant ? "instant" : "smooth"; | ||
| const index = (0, import_utils.clampValue)(event.index ?? context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const axis = computed("isHorizontal") ? "left" : "top"; | ||
| flush(() => { | ||
| el.scrollTo({ [axis]: context.get("pageSnapPoints")[index], behavior }); | ||
| }); | ||
| }, | ||
| setClosestPage({ context, scope, computed }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollPosition = computed("isHorizontal") ? el.scrollLeft : el.scrollTop; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - scrollPosition) < 1); | ||
| if (page === -1) return; | ||
| context.set("page", page); | ||
| }, | ||
| setNextPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = (0, import_utils.nextIndex)(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setPrevPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = (0, import_utils.prevIndex)(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setMatchingPage({ context, event, computed, scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const snapPoint = (0, import_scroll_snap.findSnapPoint)( | ||
| el, | ||
| computed("isHorizontal") ? "x" : "y", | ||
| (node) => node.dataset.index === event.index.toString() | ||
| ); | ||
| if (snapPoint == null) return; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - snapPoint) < 1); | ||
| context.set("page", page); | ||
| }, | ||
| setPage({ context, event }) { | ||
| const page = event.index ?? context.get("page"); | ||
| context.set("page", page); | ||
| }, | ||
| clampPage({ context }) { | ||
| const index = (0, import_utils.clampValue)(context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| context.set("page", index); | ||
| }, | ||
| setSnapPoints({ context, computed, scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollSnapPoints = (0, import_scroll_snap.getScrollSnapPositions)(el); | ||
| context.set("pageSnapPoints", computed("isHorizontal") ? scrollSnapPoints.x : scrollSnapPoints.y); | ||
| }, | ||
| disableScrollSnap({ scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const styles = getComputedStyle(el); | ||
| el.dataset.scrollSnapType = styles.getPropertyValue("scroll-snap-type"); | ||
| el.style.setProperty("scroll-snap-type", "none"); | ||
| }, | ||
| scrollSlides({ scope, event }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| el?.scrollBy({ left: event.left, top: event.top, behavior: "instant" }); | ||
| }, | ||
| endDragging({ scope, context, computed }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const isHorizontal = computed("isHorizontal"); | ||
| const scrollPos = isHorizontal ? el.scrollLeft : el.scrollTop; | ||
| const snapPoints = context.get("pageSnapPoints"); | ||
| const closest = snapPoints.reduce((closest2, curr) => { | ||
| return Math.abs(curr - scrollPos) < Math.abs(closest2 - scrollPos) ? curr : closest2; | ||
| }, snapPoints[0]); | ||
| (0, import_dom_query.raf)(() => { | ||
| el.scrollTo({ | ||
| left: isHorizontal ? closest : el.scrollLeft, | ||
| top: isHorizontal ? el.scrollTop : closest, | ||
| behavior: "smooth" | ||
| }); | ||
| context.set("page", snapPoints.indexOf(closest)); | ||
| const scrollSnapType = el.dataset.scrollSnapType; | ||
| if (scrollSnapType) { | ||
| el.style.setProperty("scroll-snap-type", scrollSnapType); | ||
| delete el.dataset.scrollSnapType; | ||
| } | ||
| }); | ||
| }, | ||
| focusIndicatorEl({ context, event, scope }) { | ||
| if (event.src !== "indicator") return; | ||
| const el = dom.getIndicatorEl(scope, context.get("page")); | ||
| if (!el) return; | ||
| (0, import_dom_query.raf)(() => el.focus({ preventScroll: true })); | ||
| }, | ||
| invokeDragStart({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.start", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDragging({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDraggingEnd({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.end", isDragging: false, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplay({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayStart({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.start", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayEnd({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.stop", isPlaying: false, page: context.get("page") }); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| function getPageSnapPoints(totalSlides, slidesPerMove, slidesPerPage) { | ||
| if (totalSlides == null || slidesPerPage <= 0) { | ||
| return []; | ||
| } | ||
| const snapPoints = []; | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(slidesPerPage) : slidesPerMove; | ||
| if (perMove <= 0) { | ||
| return []; | ||
| } | ||
| for (let i = 0; i < totalSlides; i += perMove) { | ||
| if (i + slidesPerPage > totalSlides) break; | ||
| snapPoints.push(i); | ||
| } | ||
| return snapPoints; | ||
| } | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| machine | ||
| }); |
| // src/carousel.machine.ts | ||
| import { createMachine } from "@zag-js/core"; | ||
| import { addDomEvent, raf, resizeObserverBorderBox, trackPointerMove } from "@zag-js/dom-query"; | ||
| import { findSnapPoint, getScrollSnapPositions } from "@zag-js/scroll-snap"; | ||
| import { add, callAll, clampValue, ensureProps, isObject, nextIndex, prevIndex, remove, uniq } from "@zag-js/utils"; | ||
| import * as dom from "./carousel.dom.mjs"; | ||
| var machine = createMachine({ | ||
| props({ props }) { | ||
| ensureProps(props, ["slideCount"], "carousel"); | ||
| return { | ||
| dir: "ltr", | ||
| defaultPage: 0, | ||
| orientation: "horizontal", | ||
| snapType: "mandatory", | ||
| loop: !!props.autoplay, | ||
| slidesPerPage: 1, | ||
| slidesPerMove: "auto", | ||
| spacing: "0px", | ||
| autoplay: false, | ||
| allowMouseDrag: false, | ||
| inViewThreshold: 0.6, | ||
| autoSize: false, | ||
| ...props, | ||
| translations: { | ||
| nextTrigger: "Next slide", | ||
| prevTrigger: "Previous slide", | ||
| indicator: (index) => `Go to slide ${index + 1}`, | ||
| item: (index, count) => `${index + 1} of ${count}`, | ||
| autoplayStart: "Start slide rotation", | ||
| autoplayStop: "Stop slide rotation", | ||
| progressText: ({ page, totalPages }) => `${page} / ${totalPages}`, | ||
| ...props.translations | ||
| } | ||
| }; | ||
| }, | ||
| refs() { | ||
| return { | ||
| timeoutRef: void 0 | ||
| }; | ||
| }, | ||
| initialState({ prop }) { | ||
| return prop("autoplay") ? "autoplay" : "idle"; | ||
| }, | ||
| context({ prop, bindable, getContext }) { | ||
| return { | ||
| page: bindable(() => ({ | ||
| defaultValue: prop("defaultPage"), | ||
| value: prop("page"), | ||
| onChange(page) { | ||
| const ctx = getContext(); | ||
| const pageSnapPoints = ctx.get("pageSnapPoints"); | ||
| prop("onPageChange")?.({ page, pageSnapPoint: pageSnapPoints[page] }); | ||
| } | ||
| })), | ||
| pageSnapPoints: bindable(() => { | ||
| return { | ||
| defaultValue: prop("autoSize") ? Array.from({ length: prop("slideCount") }, (_, i) => i) : getPageSnapPoints(prop("slideCount"), prop("slidesPerMove"), prop("slidesPerPage")) | ||
| }; | ||
| }), | ||
| slidesInView: bindable(() => ({ | ||
| defaultValue: [] | ||
| })) | ||
| }; | ||
| }, | ||
| computed: { | ||
| isRtl: ({ prop }) => prop("dir") === "rtl", | ||
| isHorizontal: ({ prop }) => prop("orientation") === "horizontal", | ||
| canScrollNext: ({ prop, context }) => prop("loop") || context.get("page") < context.get("pageSnapPoints").length - 1, | ||
| canScrollPrev: ({ prop, context }) => prop("loop") || context.get("page") > 0, | ||
| autoplayInterval: ({ prop }) => { | ||
| const autoplay = prop("autoplay"); | ||
| return isObject(autoplay) ? autoplay.delay : 4e3; | ||
| } | ||
| }, | ||
| watch({ track, action, context, prop, send }) { | ||
| track([() => prop("slidesPerPage"), () => prop("slidesPerMove")], () => { | ||
| action(["setSnapPoints"]); | ||
| }); | ||
| track([() => context.get("page")], () => { | ||
| action(["scrollToPage", "focusIndicatorEl"]); | ||
| }); | ||
| track([() => prop("orientation"), () => prop("autoSize"), () => prop("dir")], () => { | ||
| action(["setSnapPoints", "scrollToPage"]); | ||
| }); | ||
| track([() => prop("slideCount")], () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.count" }); | ||
| }); | ||
| track([() => !!prop("autoplay")], () => { | ||
| send({ type: prop("autoplay") ? "AUTOPLAY.START" : "AUTOPLAY.PAUSE", src: "autoplay.prop.change" }); | ||
| }); | ||
| }, | ||
| on: { | ||
| "PAGE.NEXT": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "SNAP.REFRESH": { | ||
| actions: ["setSnapPoints", "clampPage"] | ||
| }, | ||
| "PAGE.SCROLL": { | ||
| actions: ["scrollToPage"] | ||
| } | ||
| }, | ||
| effects: ["trackSlideMutation", "trackSlideIntersections", "trackSlideResize"], | ||
| entry: ["setSnapPoints", "setPage"], | ||
| exit: ["clearScrollEndTimer"], | ||
| states: { | ||
| idle: { | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.START": { | ||
| target: "autoplay", | ||
| actions: ["invokeAutoplayStart"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| }, | ||
| "VIEWPORT.FOCUS": { | ||
| target: "focus" | ||
| } | ||
| } | ||
| }, | ||
| focus: { | ||
| effects: ["trackKeyboardScroll"], | ||
| on: { | ||
| "VIEWPORT.BLUR": { | ||
| target: "idle" | ||
| }, | ||
| "PAGE.NEXT": { | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| } | ||
| } | ||
| }, | ||
| dragging: { | ||
| effects: ["trackPointerMove"], | ||
| entry: ["disableScrollSnap"], | ||
| on: { | ||
| DRAGGING: { | ||
| actions: ["scrollSlides", "invokeDragging"] | ||
| }, | ||
| "DRAGGING.END": { | ||
| target: "idle", | ||
| actions: ["endDragging", "invokeDraggingEnd"] | ||
| } | ||
| } | ||
| }, | ||
| userScroll: { | ||
| effects: ["trackScroll"], | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "SCROLL.END": [ | ||
| { | ||
| guard: "isFocused", | ||
| target: "focus", | ||
| actions: ["setClosestPage"] | ||
| }, | ||
| { | ||
| target: "idle", | ||
| actions: ["setClosestPage"] | ||
| } | ||
| ] | ||
| } | ||
| }, | ||
| autoplay: { | ||
| effects: ["trackDocumentVisibility", "trackScroll", "autoUpdateSlide"], | ||
| exit: ["invokeAutoplayEnd"], | ||
| on: { | ||
| "AUTOPLAY.TICK": { | ||
| actions: ["setNextPage", "invokeAutoplay"] | ||
| }, | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.PAUSE": { | ||
| target: "idle" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| implementations: { | ||
| guards: { | ||
| isFocused: ({ scope }) => scope.isActiveElement(dom.getItemGroupEl(scope)) | ||
| }, | ||
| effects: { | ||
| autoUpdateSlide({ computed, send }) { | ||
| const id = setInterval(() => { | ||
| send({ | ||
| type: computed("canScrollNext") ? "AUTOPLAY.TICK" : "AUTOPLAY.PAUSE", | ||
| src: "autoplay.interval" | ||
| }); | ||
| }, computed("autoplayInterval")); | ||
| return () => clearInterval(id); | ||
| }, | ||
| trackSlideMutation({ scope, send }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const win = scope.getWin(); | ||
| const observer = new win.MutationObserver(() => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.mutation" }); | ||
| dom.syncTabIndex(scope); | ||
| }); | ||
| dom.syncTabIndex(scope); | ||
| observer.observe(el, { childList: true, subtree: true }); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackSlideResize({ scope, send }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const exec = () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.resize" }); | ||
| }; | ||
| raf(() => { | ||
| exec(); | ||
| raf(() => { | ||
| send({ type: "PAGE.SCROLL", instant: true }); | ||
| }); | ||
| }); | ||
| const itemEls = dom.getItemEls(scope); | ||
| itemEls.forEach(exec); | ||
| const cleanups = itemEls.map((el2) => resizeObserverBorderBox.observe(el2, exec)); | ||
| return callAll(...cleanups); | ||
| }, | ||
| trackSlideIntersections({ scope, prop, context }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| const win = scope.getWin(); | ||
| const observer = new win.IntersectionObserver( | ||
| (entries) => { | ||
| const slidesInView = entries.reduce((acc, entry) => { | ||
| const target = entry.target; | ||
| const index = Number(target.dataset.index ?? "-1"); | ||
| if (index == null || Number.isNaN(index) || index === -1) return acc; | ||
| return entry.isIntersecting ? add(acc, index) : remove(acc, index); | ||
| }, context.get("slidesInView")); | ||
| context.set("slidesInView", uniq(slidesInView)); | ||
| }, | ||
| { | ||
| root: el, | ||
| threshold: prop("inViewThreshold") | ||
| } | ||
| ); | ||
| dom.getItemEls(scope).forEach((slide) => observer.observe(slide)); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackScroll({ send, refs, scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const onScroll = () => { | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| refs.set( | ||
| "timeoutRef", | ||
| setTimeout(() => { | ||
| send({ type: "SCROLL.END" }); | ||
| }, 150) | ||
| ); | ||
| }; | ||
| return addDomEvent(el, "scroll", onScroll, { passive: true }); | ||
| }, | ||
| trackDocumentVisibility({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| const onVisibilityChange = () => { | ||
| if (doc.visibilityState === "visible") return; | ||
| send({ type: "AUTOPLAY.PAUSE", src: "doc.hidden" }); | ||
| }; | ||
| return addDomEvent(doc, "visibilitychange", onVisibilityChange); | ||
| }, | ||
| trackPointerMove({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| return trackPointerMove(doc, { | ||
| onPointerMove({ event }) { | ||
| send({ type: "DRAGGING", left: -event.movementX, top: -event.movementY }); | ||
| }, | ||
| onPointerUp() { | ||
| send({ type: "DRAGGING.END" }); | ||
| } | ||
| }); | ||
| }, | ||
| trackKeyboardScroll({ scope, send, context }) { | ||
| const win = scope.getWin(); | ||
| const onKeyDown = (event) => { | ||
| switch (event.key) { | ||
| case "ArrowRight": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.NEXT" }); | ||
| break; | ||
| case "ArrowLeft": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.PREV" }); | ||
| break; | ||
| case "Home": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: 0 }); | ||
| break; | ||
| case "End": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: context.get("pageSnapPoints").length - 1 }); | ||
| } | ||
| }; | ||
| return addDomEvent(win, "keydown", onKeyDown, { capture: true }); | ||
| } | ||
| }, | ||
| actions: { | ||
| clearScrollEndTimer({ refs }) { | ||
| if (refs.get("timeoutRef") == null) return; | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| }, | ||
| scrollToPage({ context, event, scope, computed, flush }) { | ||
| const behavior = event.instant ? "instant" : "smooth"; | ||
| const index = clampValue(event.index ?? context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const axis = computed("isHorizontal") ? "left" : "top"; | ||
| flush(() => { | ||
| el.scrollTo({ [axis]: context.get("pageSnapPoints")[index], behavior }); | ||
| }); | ||
| }, | ||
| setClosestPage({ context, scope, computed }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollPosition = computed("isHorizontal") ? el.scrollLeft : el.scrollTop; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - scrollPosition) < 1); | ||
| if (page === -1) return; | ||
| context.set("page", page); | ||
| }, | ||
| setNextPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = nextIndex(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setPrevPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = prevIndex(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setMatchingPage({ context, event, computed, scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const snapPoint = findSnapPoint( | ||
| el, | ||
| computed("isHorizontal") ? "x" : "y", | ||
| (node) => node.dataset.index === event.index.toString() | ||
| ); | ||
| if (snapPoint == null) return; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - snapPoint) < 1); | ||
| context.set("page", page); | ||
| }, | ||
| setPage({ context, event }) { | ||
| const page = event.index ?? context.get("page"); | ||
| context.set("page", page); | ||
| }, | ||
| clampPage({ context }) { | ||
| const index = clampValue(context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| context.set("page", index); | ||
| }, | ||
| setSnapPoints({ context, computed, scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollSnapPoints = getScrollSnapPositions(el); | ||
| context.set("pageSnapPoints", computed("isHorizontal") ? scrollSnapPoints.x : scrollSnapPoints.y); | ||
| }, | ||
| disableScrollSnap({ scope }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const styles = getComputedStyle(el); | ||
| el.dataset.scrollSnapType = styles.getPropertyValue("scroll-snap-type"); | ||
| el.style.setProperty("scroll-snap-type", "none"); | ||
| }, | ||
| scrollSlides({ scope, event }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| el?.scrollBy({ left: event.left, top: event.top, behavior: "instant" }); | ||
| }, | ||
| endDragging({ scope, context, computed }) { | ||
| const el = dom.getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const isHorizontal = computed("isHorizontal"); | ||
| const scrollPos = isHorizontal ? el.scrollLeft : el.scrollTop; | ||
| const snapPoints = context.get("pageSnapPoints"); | ||
| const closest = snapPoints.reduce((closest2, curr) => { | ||
| return Math.abs(curr - scrollPos) < Math.abs(closest2 - scrollPos) ? curr : closest2; | ||
| }, snapPoints[0]); | ||
| raf(() => { | ||
| el.scrollTo({ | ||
| left: isHorizontal ? closest : el.scrollLeft, | ||
| top: isHorizontal ? el.scrollTop : closest, | ||
| behavior: "smooth" | ||
| }); | ||
| context.set("page", snapPoints.indexOf(closest)); | ||
| const scrollSnapType = el.dataset.scrollSnapType; | ||
| if (scrollSnapType) { | ||
| el.style.setProperty("scroll-snap-type", scrollSnapType); | ||
| delete el.dataset.scrollSnapType; | ||
| } | ||
| }); | ||
| }, | ||
| focusIndicatorEl({ context, event, scope }) { | ||
| if (event.src !== "indicator") return; | ||
| const el = dom.getIndicatorEl(scope, context.get("page")); | ||
| if (!el) return; | ||
| raf(() => el.focus({ preventScroll: true })); | ||
| }, | ||
| invokeDragStart({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.start", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDragging({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDraggingEnd({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.end", isDragging: false, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplay({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayStart({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.start", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayEnd({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.stop", isPlaying: false, page: context.get("page") }); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| function getPageSnapPoints(totalSlides, slidesPerMove, slidesPerPage) { | ||
| if (totalSlides == null || slidesPerPage <= 0) { | ||
| return []; | ||
| } | ||
| const snapPoints = []; | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(slidesPerPage) : slidesPerMove; | ||
| if (perMove <= 0) { | ||
| return []; | ||
| } | ||
| for (let i = 0; i < totalSlides; i += perMove) { | ||
| if (i + slidesPerPage > totalSlides) break; | ||
| snapPoints.push(i); | ||
| } | ||
| return snapPoints; | ||
| } | ||
| export { | ||
| machine | ||
| }; |
| import { IndicatorProps, ItemProps, CarouselProps } from './carousel.types.mjs'; | ||
| import '@zag-js/core'; | ||
| import '@zag-js/types'; | ||
| declare const props: (keyof CarouselProps)[]; | ||
| declare const splitProps: <Props extends Partial<CarouselProps>>(props: Props) => [Partial<CarouselProps>, Omit<Props, keyof CarouselProps>]; | ||
| declare const indicatorProps: (keyof IndicatorProps)[]; | ||
| declare const splitIndicatorProps: <Props extends IndicatorProps>(props: Props) => [IndicatorProps, Omit<Props, keyof IndicatorProps>]; | ||
| declare const itemProps: (keyof ItemProps)[]; | ||
| declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>]; | ||
| export { indicatorProps, itemProps, props, splitIndicatorProps, splitItemProps, splitProps }; |
| import { IndicatorProps, ItemProps, CarouselProps } from './carousel.types.js'; | ||
| import '@zag-js/core'; | ||
| import '@zag-js/types'; | ||
| declare const props: (keyof CarouselProps)[]; | ||
| declare const splitProps: <Props extends Partial<CarouselProps>>(props: Props) => [Partial<CarouselProps>, Omit<Props, keyof CarouselProps>]; | ||
| declare const indicatorProps: (keyof IndicatorProps)[]; | ||
| declare const splitIndicatorProps: <Props extends IndicatorProps>(props: Props) => [IndicatorProps, Omit<Props, keyof IndicatorProps>]; | ||
| declare const itemProps: (keyof ItemProps)[]; | ||
| declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>]; | ||
| export { indicatorProps, itemProps, props, splitIndicatorProps, splitItemProps, splitProps }; |
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.props.ts | ||
| var carousel_props_exports = {}; | ||
| __export(carousel_props_exports, { | ||
| indicatorProps: () => indicatorProps, | ||
| itemProps: () => itemProps, | ||
| props: () => props, | ||
| splitIndicatorProps: () => splitIndicatorProps, | ||
| splitItemProps: () => splitItemProps, | ||
| splitProps: () => splitProps | ||
| }); | ||
| module.exports = __toCommonJS(carousel_props_exports); | ||
| var import_types = require("@zag-js/types"); | ||
| var import_utils = require("@zag-js/utils"); | ||
| var props = (0, import_types.createProps)()([ | ||
| "dir", | ||
| "getRootNode", | ||
| "id", | ||
| "ids", | ||
| "loop", | ||
| "page", | ||
| "defaultPage", | ||
| "onPageChange", | ||
| "orientation", | ||
| "slideCount", | ||
| "slidesPerPage", | ||
| "slidesPerMove", | ||
| "spacing", | ||
| "padding", | ||
| "autoplay", | ||
| "allowMouseDrag", | ||
| "inViewThreshold", | ||
| "translations", | ||
| "snapType", | ||
| "autoSize", | ||
| "onDragStatusChange", | ||
| "onAutoplayStatusChange" | ||
| ]); | ||
| var splitProps = (0, import_utils.createSplitProps)(props); | ||
| var indicatorProps = (0, import_types.createProps)()(["index", "readOnly"]); | ||
| var splitIndicatorProps = (0, import_utils.createSplitProps)(indicatorProps); | ||
| var itemProps = (0, import_types.createProps)()(["index", "snapAlign"]); | ||
| var splitItemProps = (0, import_utils.createSplitProps)(itemProps); | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| indicatorProps, | ||
| itemProps, | ||
| props, | ||
| splitIndicatorProps, | ||
| splitItemProps, | ||
| splitProps | ||
| }); |
| // src/carousel.props.ts | ||
| import { createProps } from "@zag-js/types"; | ||
| import { createSplitProps } from "@zag-js/utils"; | ||
| var props = createProps()([ | ||
| "dir", | ||
| "getRootNode", | ||
| "id", | ||
| "ids", | ||
| "loop", | ||
| "page", | ||
| "defaultPage", | ||
| "onPageChange", | ||
| "orientation", | ||
| "slideCount", | ||
| "slidesPerPage", | ||
| "slidesPerMove", | ||
| "spacing", | ||
| "padding", | ||
| "autoplay", | ||
| "allowMouseDrag", | ||
| "inViewThreshold", | ||
| "translations", | ||
| "snapType", | ||
| "autoSize", | ||
| "onDragStatusChange", | ||
| "onAutoplayStatusChange" | ||
| ]); | ||
| var splitProps = createSplitProps(props); | ||
| var indicatorProps = createProps()(["index", "readOnly"]); | ||
| var splitIndicatorProps = createSplitProps(indicatorProps); | ||
| var itemProps = createProps()(["index", "snapAlign"]); | ||
| var splitItemProps = createSplitProps(itemProps); | ||
| export { | ||
| indicatorProps, | ||
| itemProps, | ||
| props, | ||
| splitIndicatorProps, | ||
| splitItemProps, | ||
| splitProps | ||
| }; |
| import { Service, EventObject, Machine } from '@zag-js/core'; | ||
| import { RequiredBy, DirectionProperty, CommonProperties, OrientationProperty, PropTypes } from '@zag-js/types'; | ||
| export { Orientation } from '@zag-js/types'; | ||
| interface PageChangeDetails { | ||
| page: number; | ||
| pageSnapPoint: number; | ||
| } | ||
| interface DragStatusDetails { | ||
| type: "dragging.start" | "dragging" | "dragging.end"; | ||
| page: number; | ||
| isDragging: boolean; | ||
| } | ||
| interface AutoplayStatusDetails { | ||
| type: "autoplay.start" | "autoplay" | "autoplay.stop"; | ||
| page: number; | ||
| isPlaying: boolean; | ||
| } | ||
| interface ProgressTextDetails { | ||
| page: number; | ||
| totalPages: number; | ||
| } | ||
| interface IntlTranslations { | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicator: (index: number) => string; | ||
| item: (index: number, count: number) => string; | ||
| autoplayStart: string; | ||
| autoplayStop: string; | ||
| progressText?: ((details: ProgressTextDetails) => string) | undefined; | ||
| } | ||
| type ElementIds = Partial<{ | ||
| root: string; | ||
| item: (index: number) => string; | ||
| itemGroup: string; | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicatorGroup: string; | ||
| indicator: (index: number) => string; | ||
| }>; | ||
| interface CarouselProps extends DirectionProperty, CommonProperties, OrientationProperty { | ||
| /** | ||
| * The ids of the elements in the carousel. Useful for composition. | ||
| */ | ||
| ids?: ElementIds | undefined; | ||
| /** | ||
| * The localized messages to use. | ||
| */ | ||
| translations?: IntlTranslations | undefined; | ||
| /** | ||
| * The number of slides to show at a time. | ||
| * @default 1 | ||
| */ | ||
| slidesPerPage?: number | undefined; | ||
| /** | ||
| * Whether to enable variable width slides. | ||
| * @default false | ||
| */ | ||
| autoSize?: boolean | undefined; | ||
| /** | ||
| * The number of slides to scroll at a time. | ||
| * | ||
| * When set to `auto`, the number of slides to scroll is determined by the | ||
| * `slidesPerPage` property. | ||
| * | ||
| * @default "auto" | ||
| */ | ||
| slidesPerMove?: number | "auto" | undefined; | ||
| /** | ||
| * Whether to scroll automatically. The default delay is 4000ms. | ||
| * @default false | ||
| */ | ||
| autoplay?: boolean | { | ||
| delay: number; | ||
| } | undefined; | ||
| /** | ||
| * Whether to allow scrolling via dragging with mouse | ||
| * @default false | ||
| */ | ||
| allowMouseDrag?: boolean | undefined; | ||
| /** | ||
| * Whether the carousel should loop around. | ||
| * @default false | ||
| */ | ||
| loop?: boolean | undefined; | ||
| /** | ||
| * The controlled page of the carousel. | ||
| */ | ||
| page?: number | undefined; | ||
| /** | ||
| * The initial page to scroll to when rendered. | ||
| * Use when you don't need to control the page of the carousel. | ||
| * @default 0 | ||
| */ | ||
| defaultPage?: number | undefined; | ||
| /** | ||
| * The amount of space between items. | ||
| * @default "0px" | ||
| */ | ||
| spacing?: string | undefined; | ||
| /** | ||
| * Defines the extra space added around the scrollable area, | ||
| * enabling nearby items to remain partially in view. | ||
| */ | ||
| padding?: string | undefined; | ||
| /** | ||
| * Function called when the page changes. | ||
| */ | ||
| onPageChange?: ((details: PageChangeDetails) => void) | undefined; | ||
| /** | ||
| * The threshold for determining if an item is in view. | ||
| * @default 0.6 | ||
| */ | ||
| inViewThreshold?: number | number[] | undefined; | ||
| /** | ||
| * The snap type of the item. | ||
| * @default "mandatory" | ||
| */ | ||
| snapType?: "proximity" | "mandatory" | undefined; | ||
| /** | ||
| * The total number of slides. | ||
| * Useful for SSR to render the initial ating the snap points. | ||
| */ | ||
| slideCount: number; | ||
| /** | ||
| * Function called when the drag status changes. | ||
| */ | ||
| onDragStatusChange?: ((details: DragStatusDetails) => void) | undefined; | ||
| /** | ||
| * Function called when the autoplay status changes. | ||
| */ | ||
| onAutoplayStatusChange?: ((details: AutoplayStatusDetails) => void) | undefined; | ||
| } | ||
| type PropsWithDefault = "dir" | "defaultPage" | "orientation" | "snapType" | "loop" | "slidesPerPage" | "slidesPerMove" | "spacing" | "autoplay" | "allowMouseDrag" | "inViewThreshold" | "translations" | "slideCount" | "autoSize"; | ||
| interface PrivateContext { | ||
| pageSnapPoints: number[]; | ||
| slidesInView: number[]; | ||
| page: number; | ||
| } | ||
| interface ComputedContext { | ||
| isRtl: boolean; | ||
| isHorizontal: boolean; | ||
| canScrollNext: boolean; | ||
| canScrollPrev: boolean; | ||
| autoplayInterval: number; | ||
| } | ||
| type CarouselService = Service<CarouselSchema>; | ||
| type CarouselMachine = Machine<CarouselSchema>; | ||
| interface CarouselSchema { | ||
| props: RequiredBy<CarouselProps, PropsWithDefault>; | ||
| context: PrivateContext; | ||
| computed: ComputedContext; | ||
| refs: { | ||
| timeoutRef: any; | ||
| }; | ||
| state: "idle" | "dragging" | "autoplay" | "userScroll" | "focus"; | ||
| effect: string; | ||
| action: string; | ||
| guard: string; | ||
| event: EventObject; | ||
| } | ||
| interface ItemProps { | ||
| /** | ||
| * The index of the item. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * The snap alignment of the item. | ||
| * @default "start" | ||
| */ | ||
| snapAlign?: "start" | "end" | "center" | undefined; | ||
| } | ||
| interface IndicatorProps { | ||
| /** | ||
| * The index of the indicator. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * Whether the indicator is read only. | ||
| * @default false | ||
| */ | ||
| readOnly?: boolean | undefined; | ||
| } | ||
| interface CarouselApi<T extends PropTypes = PropTypes> { | ||
| /** | ||
| * The current index of the carousel | ||
| */ | ||
| page: number; | ||
| /** | ||
| * The current snap points of the carousel | ||
| */ | ||
| pageSnapPoints: number[]; | ||
| /** | ||
| * Whether the carousel is auto playing | ||
| */ | ||
| isPlaying: boolean; | ||
| /** | ||
| * Whether the carousel is being dragged. This only works when `draggable` is true. | ||
| */ | ||
| isDragging: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the next view | ||
| */ | ||
| canScrollNext: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the previous view | ||
| */ | ||
| canScrollPrev: boolean; | ||
| /** | ||
| * Function to scroll to a specific item index | ||
| */ | ||
| scrollToIndex: (index: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to a specific page | ||
| */ | ||
| scrollTo: (page: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the next page | ||
| */ | ||
| scrollNext: (instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the previous page | ||
| */ | ||
| scrollPrev: (instant?: boolean) => void; | ||
| /** | ||
| * Returns the current scroll progress as a percentage | ||
| */ | ||
| getProgress: () => number; | ||
| /** | ||
| * Returns the progress text | ||
| */ | ||
| getProgressText: () => string; | ||
| /** | ||
| * Function to start/resume autoplay | ||
| */ | ||
| play: VoidFunction; | ||
| /** | ||
| * Function to pause autoplay | ||
| */ | ||
| pause: VoidFunction; | ||
| /** | ||
| * Whether the item is in view | ||
| */ | ||
| isInView: (index: number) => boolean; | ||
| /** | ||
| * Function to re-compute the snap points | ||
| * and clamp the page | ||
| */ | ||
| refresh: VoidFunction; | ||
| getRootProps: () => T["element"]; | ||
| getControlProps: () => T["element"]; | ||
| getItemGroupProps: () => T["element"]; | ||
| getItemProps: (props: ItemProps) => T["element"]; | ||
| getPrevTriggerProps: () => T["button"]; | ||
| getNextTriggerProps: () => T["button"]; | ||
| getAutoplayTriggerProps: () => T["button"]; | ||
| getIndicatorGroupProps: () => T["element"]; | ||
| getIndicatorProps: (props: IndicatorProps) => T["button"]; | ||
| getProgressTextProps: () => T["element"]; | ||
| } | ||
| export type { AutoplayStatusDetails, CarouselApi, CarouselMachine, CarouselProps, CarouselSchema, CarouselService, DragStatusDetails, ElementIds, IndicatorProps, IntlTranslations, ItemProps, PageChangeDetails, ProgressTextDetails }; |
| import { Service, EventObject, Machine } from '@zag-js/core'; | ||
| import { RequiredBy, DirectionProperty, CommonProperties, OrientationProperty, PropTypes } from '@zag-js/types'; | ||
| export { Orientation } from '@zag-js/types'; | ||
| interface PageChangeDetails { | ||
| page: number; | ||
| pageSnapPoint: number; | ||
| } | ||
| interface DragStatusDetails { | ||
| type: "dragging.start" | "dragging" | "dragging.end"; | ||
| page: number; | ||
| isDragging: boolean; | ||
| } | ||
| interface AutoplayStatusDetails { | ||
| type: "autoplay.start" | "autoplay" | "autoplay.stop"; | ||
| page: number; | ||
| isPlaying: boolean; | ||
| } | ||
| interface ProgressTextDetails { | ||
| page: number; | ||
| totalPages: number; | ||
| } | ||
| interface IntlTranslations { | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicator: (index: number) => string; | ||
| item: (index: number, count: number) => string; | ||
| autoplayStart: string; | ||
| autoplayStop: string; | ||
| progressText?: ((details: ProgressTextDetails) => string) | undefined; | ||
| } | ||
| type ElementIds = Partial<{ | ||
| root: string; | ||
| item: (index: number) => string; | ||
| itemGroup: string; | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicatorGroup: string; | ||
| indicator: (index: number) => string; | ||
| }>; | ||
| interface CarouselProps extends DirectionProperty, CommonProperties, OrientationProperty { | ||
| /** | ||
| * The ids of the elements in the carousel. Useful for composition. | ||
| */ | ||
| ids?: ElementIds | undefined; | ||
| /** | ||
| * The localized messages to use. | ||
| */ | ||
| translations?: IntlTranslations | undefined; | ||
| /** | ||
| * The number of slides to show at a time. | ||
| * @default 1 | ||
| */ | ||
| slidesPerPage?: number | undefined; | ||
| /** | ||
| * Whether to enable variable width slides. | ||
| * @default false | ||
| */ | ||
| autoSize?: boolean | undefined; | ||
| /** | ||
| * The number of slides to scroll at a time. | ||
| * | ||
| * When set to `auto`, the number of slides to scroll is determined by the | ||
| * `slidesPerPage` property. | ||
| * | ||
| * @default "auto" | ||
| */ | ||
| slidesPerMove?: number | "auto" | undefined; | ||
| /** | ||
| * Whether to scroll automatically. The default delay is 4000ms. | ||
| * @default false | ||
| */ | ||
| autoplay?: boolean | { | ||
| delay: number; | ||
| } | undefined; | ||
| /** | ||
| * Whether to allow scrolling via dragging with mouse | ||
| * @default false | ||
| */ | ||
| allowMouseDrag?: boolean | undefined; | ||
| /** | ||
| * Whether the carousel should loop around. | ||
| * @default false | ||
| */ | ||
| loop?: boolean | undefined; | ||
| /** | ||
| * The controlled page of the carousel. | ||
| */ | ||
| page?: number | undefined; | ||
| /** | ||
| * The initial page to scroll to when rendered. | ||
| * Use when you don't need to control the page of the carousel. | ||
| * @default 0 | ||
| */ | ||
| defaultPage?: number | undefined; | ||
| /** | ||
| * The amount of space between items. | ||
| * @default "0px" | ||
| */ | ||
| spacing?: string | undefined; | ||
| /** | ||
| * Defines the extra space added around the scrollable area, | ||
| * enabling nearby items to remain partially in view. | ||
| */ | ||
| padding?: string | undefined; | ||
| /** | ||
| * Function called when the page changes. | ||
| */ | ||
| onPageChange?: ((details: PageChangeDetails) => void) | undefined; | ||
| /** | ||
| * The threshold for determining if an item is in view. | ||
| * @default 0.6 | ||
| */ | ||
| inViewThreshold?: number | number[] | undefined; | ||
| /** | ||
| * The snap type of the item. | ||
| * @default "mandatory" | ||
| */ | ||
| snapType?: "proximity" | "mandatory" | undefined; | ||
| /** | ||
| * The total number of slides. | ||
| * Useful for SSR to render the initial ating the snap points. | ||
| */ | ||
| slideCount: number; | ||
| /** | ||
| * Function called when the drag status changes. | ||
| */ | ||
| onDragStatusChange?: ((details: DragStatusDetails) => void) | undefined; | ||
| /** | ||
| * Function called when the autoplay status changes. | ||
| */ | ||
| onAutoplayStatusChange?: ((details: AutoplayStatusDetails) => void) | undefined; | ||
| } | ||
| type PropsWithDefault = "dir" | "defaultPage" | "orientation" | "snapType" | "loop" | "slidesPerPage" | "slidesPerMove" | "spacing" | "autoplay" | "allowMouseDrag" | "inViewThreshold" | "translations" | "slideCount" | "autoSize"; | ||
| interface PrivateContext { | ||
| pageSnapPoints: number[]; | ||
| slidesInView: number[]; | ||
| page: number; | ||
| } | ||
| interface ComputedContext { | ||
| isRtl: boolean; | ||
| isHorizontal: boolean; | ||
| canScrollNext: boolean; | ||
| canScrollPrev: boolean; | ||
| autoplayInterval: number; | ||
| } | ||
| type CarouselService = Service<CarouselSchema>; | ||
| type CarouselMachine = Machine<CarouselSchema>; | ||
| interface CarouselSchema { | ||
| props: RequiredBy<CarouselProps, PropsWithDefault>; | ||
| context: PrivateContext; | ||
| computed: ComputedContext; | ||
| refs: { | ||
| timeoutRef: any; | ||
| }; | ||
| state: "idle" | "dragging" | "autoplay" | "userScroll" | "focus"; | ||
| effect: string; | ||
| action: string; | ||
| guard: string; | ||
| event: EventObject; | ||
| } | ||
| interface ItemProps { | ||
| /** | ||
| * The index of the item. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * The snap alignment of the item. | ||
| * @default "start" | ||
| */ | ||
| snapAlign?: "start" | "end" | "center" | undefined; | ||
| } | ||
| interface IndicatorProps { | ||
| /** | ||
| * The index of the indicator. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * Whether the indicator is read only. | ||
| * @default false | ||
| */ | ||
| readOnly?: boolean | undefined; | ||
| } | ||
| interface CarouselApi<T extends PropTypes = PropTypes> { | ||
| /** | ||
| * The current index of the carousel | ||
| */ | ||
| page: number; | ||
| /** | ||
| * The current snap points of the carousel | ||
| */ | ||
| pageSnapPoints: number[]; | ||
| /** | ||
| * Whether the carousel is auto playing | ||
| */ | ||
| isPlaying: boolean; | ||
| /** | ||
| * Whether the carousel is being dragged. This only works when `draggable` is true. | ||
| */ | ||
| isDragging: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the next view | ||
| */ | ||
| canScrollNext: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the previous view | ||
| */ | ||
| canScrollPrev: boolean; | ||
| /** | ||
| * Function to scroll to a specific item index | ||
| */ | ||
| scrollToIndex: (index: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to a specific page | ||
| */ | ||
| scrollTo: (page: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the next page | ||
| */ | ||
| scrollNext: (instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the previous page | ||
| */ | ||
| scrollPrev: (instant?: boolean) => void; | ||
| /** | ||
| * Returns the current scroll progress as a percentage | ||
| */ | ||
| getProgress: () => number; | ||
| /** | ||
| * Returns the progress text | ||
| */ | ||
| getProgressText: () => string; | ||
| /** | ||
| * Function to start/resume autoplay | ||
| */ | ||
| play: VoidFunction; | ||
| /** | ||
| * Function to pause autoplay | ||
| */ | ||
| pause: VoidFunction; | ||
| /** | ||
| * Whether the item is in view | ||
| */ | ||
| isInView: (index: number) => boolean; | ||
| /** | ||
| * Function to re-compute the snap points | ||
| * and clamp the page | ||
| */ | ||
| refresh: VoidFunction; | ||
| getRootProps: () => T["element"]; | ||
| getControlProps: () => T["element"]; | ||
| getItemGroupProps: () => T["element"]; | ||
| getItemProps: (props: ItemProps) => T["element"]; | ||
| getPrevTriggerProps: () => T["button"]; | ||
| getNextTriggerProps: () => T["button"]; | ||
| getAutoplayTriggerProps: () => T["button"]; | ||
| getIndicatorGroupProps: () => T["element"]; | ||
| getIndicatorProps: (props: IndicatorProps) => T["button"]; | ||
| getProgressTextProps: () => T["element"]; | ||
| } | ||
| export type { AutoplayStatusDetails, CarouselApi, CarouselMachine, CarouselProps, CarouselSchema, CarouselService, DragStatusDetails, ElementIds, IndicatorProps, IntlTranslations, ItemProps, PageChangeDetails, ProgressTextDetails }; |
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.types.ts | ||
| var carousel_types_exports = {}; | ||
| module.exports = __toCommonJS(carousel_types_exports); |
+7
-276
@@ -1,277 +0,8 @@ | ||
| import * as _zag_js_anatomy from '@zag-js/anatomy'; | ||
| import { PropTypes, RequiredBy, DirectionProperty, CommonProperties, OrientationProperty, NormalizeProps } from '@zag-js/types'; | ||
| export { anatomy } from './carousel.anatomy.mjs'; | ||
| export { connect } from './carousel.connect.mjs'; | ||
| export { machine } from './carousel.machine.mjs'; | ||
| export { indicatorProps, itemProps, props, splitIndicatorProps, splitItemProps, splitProps } from './carousel.props.mjs'; | ||
| export { CarouselApi as Api, AutoplayStatusDetails, DragStatusDetails, ElementIds, IndicatorProps, IntlTranslations, ItemProps, CarouselMachine as Machine, PageChangeDetails, ProgressTextDetails, CarouselProps as Props, CarouselService as Service } from './carousel.types.mjs'; | ||
| export { Orientation } from '@zag-js/types'; | ||
| import * as _zag_js_core from '@zag-js/core'; | ||
| import { Machine, EventObject, Service } from '@zag-js/core'; | ||
| declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "itemGroup" | "item" | "control" | "nextTrigger" | "prevTrigger" | "indicatorGroup" | "indicator" | "autoplayTrigger" | "progressText">; | ||
| interface PageChangeDetails { | ||
| page: number; | ||
| pageSnapPoint: number; | ||
| } | ||
| interface DragStatusDetails { | ||
| type: "dragging.start" | "dragging" | "dragging.end"; | ||
| page: number; | ||
| isDragging: boolean; | ||
| } | ||
| interface AutoplayStatusDetails { | ||
| type: "autoplay.start" | "autoplay" | "autoplay.stop"; | ||
| page: number; | ||
| isPlaying: boolean; | ||
| } | ||
| interface ProgressTextDetails { | ||
| page: number; | ||
| totalPages: number; | ||
| } | ||
| interface IntlTranslations { | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicator: (index: number) => string; | ||
| item: (index: number, count: number) => string; | ||
| autoplayStart: string; | ||
| autoplayStop: string; | ||
| progressText?: ((details: ProgressTextDetails) => string) | undefined; | ||
| } | ||
| type ElementIds = Partial<{ | ||
| root: string; | ||
| item: (index: number) => string; | ||
| itemGroup: string; | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicatorGroup: string; | ||
| indicator: (index: number) => string; | ||
| }>; | ||
| interface CarouselProps extends DirectionProperty, CommonProperties, OrientationProperty { | ||
| /** | ||
| * The ids of the elements in the carousel. Useful for composition. | ||
| */ | ||
| ids?: ElementIds | undefined; | ||
| /** | ||
| * The localized messages to use. | ||
| */ | ||
| translations?: IntlTranslations | undefined; | ||
| /** | ||
| * The number of slides to show at a time. | ||
| * @default 1 | ||
| */ | ||
| slidesPerPage?: number | undefined; | ||
| /** | ||
| * Whether to enable variable width slides. | ||
| * @default false | ||
| */ | ||
| autoSize?: boolean | undefined; | ||
| /** | ||
| * The number of slides to scroll at a time. | ||
| * | ||
| * When set to `auto`, the number of slides to scroll is determined by the | ||
| * `slidesPerPage` property. | ||
| * | ||
| * @default "auto" | ||
| */ | ||
| slidesPerMove?: number | "auto" | undefined; | ||
| /** | ||
| * Whether to scroll automatically. The default delay is 4000ms. | ||
| * @default false | ||
| */ | ||
| autoplay?: boolean | { | ||
| delay: number; | ||
| } | undefined; | ||
| /** | ||
| * Whether to allow scrolling via dragging with mouse | ||
| * @default false | ||
| */ | ||
| allowMouseDrag?: boolean | undefined; | ||
| /** | ||
| * Whether the carousel should loop around. | ||
| * @default false | ||
| */ | ||
| loop?: boolean | undefined; | ||
| /** | ||
| * The controlled page of the carousel. | ||
| */ | ||
| page?: number | undefined; | ||
| /** | ||
| * The initial page to scroll to when rendered. | ||
| * Use when you don't need to control the page of the carousel. | ||
| * @default 0 | ||
| */ | ||
| defaultPage?: number | undefined; | ||
| /** | ||
| * The amount of space between items. | ||
| * @default "0px" | ||
| */ | ||
| spacing?: string | undefined; | ||
| /** | ||
| * Defines the extra space added around the scrollable area, | ||
| * enabling nearby items to remain partially in view. | ||
| */ | ||
| padding?: string | undefined; | ||
| /** | ||
| * Function called when the page changes. | ||
| */ | ||
| onPageChange?: ((details: PageChangeDetails) => void) | undefined; | ||
| /** | ||
| * The threshold for determining if an item is in view. | ||
| * @default 0.6 | ||
| */ | ||
| inViewThreshold?: number | number[] | undefined; | ||
| /** | ||
| * The snap type of the item. | ||
| * @default "mandatory" | ||
| */ | ||
| snapType?: "proximity" | "mandatory" | undefined; | ||
| /** | ||
| * The total number of slides. | ||
| * Useful for SSR to render the initial ating the snap points. | ||
| */ | ||
| slideCount: number; | ||
| /** | ||
| * Function called when the drag status changes. | ||
| */ | ||
| onDragStatusChange?: ((details: DragStatusDetails) => void) | undefined; | ||
| /** | ||
| * Function called when the autoplay status changes. | ||
| */ | ||
| onAutoplayStatusChange?: ((details: AutoplayStatusDetails) => void) | undefined; | ||
| } | ||
| type PropsWithDefault = "dir" | "defaultPage" | "orientation" | "snapType" | "loop" | "slidesPerPage" | "slidesPerMove" | "spacing" | "autoplay" | "allowMouseDrag" | "inViewThreshold" | "translations" | "slideCount" | "autoSize"; | ||
| interface PrivateContext { | ||
| pageSnapPoints: number[]; | ||
| slidesInView: number[]; | ||
| page: number; | ||
| } | ||
| interface ComputedContext { | ||
| isRtl: boolean; | ||
| isHorizontal: boolean; | ||
| canScrollNext: boolean; | ||
| canScrollPrev: boolean; | ||
| autoplayInterval: number; | ||
| } | ||
| type CarouselService = Service<CarouselSchema>; | ||
| type CarouselMachine = Machine<CarouselSchema>; | ||
| interface CarouselSchema { | ||
| props: RequiredBy<CarouselProps, PropsWithDefault>; | ||
| context: PrivateContext; | ||
| computed: ComputedContext; | ||
| refs: { | ||
| timeoutRef: any; | ||
| }; | ||
| state: "idle" | "dragging" | "autoplay" | "userScroll" | "focus"; | ||
| effect: string; | ||
| action: string; | ||
| guard: string; | ||
| event: EventObject; | ||
| } | ||
| interface ItemProps { | ||
| /** | ||
| * The index of the item. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * The snap alignment of the item. | ||
| * @default "start" | ||
| */ | ||
| snapAlign?: "start" | "end" | "center" | undefined; | ||
| } | ||
| interface IndicatorProps { | ||
| /** | ||
| * The index of the indicator. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * Whether the indicator is read only. | ||
| * @default false | ||
| */ | ||
| readOnly?: boolean | undefined; | ||
| } | ||
| interface CarouselApi<T extends PropTypes = PropTypes> { | ||
| /** | ||
| * The current index of the carousel | ||
| */ | ||
| page: number; | ||
| /** | ||
| * The current snap points of the carousel | ||
| */ | ||
| pageSnapPoints: number[]; | ||
| /** | ||
| * Whether the carousel is auto playing | ||
| */ | ||
| isPlaying: boolean; | ||
| /** | ||
| * Whether the carousel is being dragged. This only works when `draggable` is true. | ||
| */ | ||
| isDragging: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the next view | ||
| */ | ||
| canScrollNext: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the previous view | ||
| */ | ||
| canScrollPrev: boolean; | ||
| /** | ||
| * Function to scroll to a specific item index | ||
| */ | ||
| scrollToIndex: (index: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to a specific page | ||
| */ | ||
| scrollTo: (page: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the next page | ||
| */ | ||
| scrollNext: (instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the previous page | ||
| */ | ||
| scrollPrev: (instant?: boolean) => void; | ||
| /** | ||
| * Returns the current scroll progress as a percentage | ||
| */ | ||
| getProgress: () => number; | ||
| /** | ||
| * Returns the progress text | ||
| */ | ||
| getProgressText: () => string; | ||
| /** | ||
| * Function to start/resume autoplay | ||
| */ | ||
| play: VoidFunction; | ||
| /** | ||
| * Function to pause autoplay | ||
| */ | ||
| pause: VoidFunction; | ||
| /** | ||
| * Whether the item is in view | ||
| */ | ||
| isInView: (index: number) => boolean; | ||
| /** | ||
| * Function to re-compute the snap points | ||
| * and clamp the page | ||
| */ | ||
| refresh: VoidFunction; | ||
| getRootProps: () => T["element"]; | ||
| getControlProps: () => T["element"]; | ||
| getItemGroupProps: () => T["element"]; | ||
| getItemProps: (props: ItemProps) => T["element"]; | ||
| getPrevTriggerProps: () => T["button"]; | ||
| getNextTriggerProps: () => T["button"]; | ||
| getAutoplayTriggerProps: () => T["button"]; | ||
| getIndicatorGroupProps: () => T["element"]; | ||
| getIndicatorProps: (props: IndicatorProps) => T["button"]; | ||
| getProgressTextProps: () => T["element"]; | ||
| } | ||
| declare function connect<T extends PropTypes>(service: CarouselService, normalize: NormalizeProps<T>): CarouselApi<T>; | ||
| declare const machine: _zag_js_core.Machine<CarouselSchema>; | ||
| declare const props: (keyof CarouselProps)[]; | ||
| declare const splitProps: <Props extends Partial<CarouselProps>>(props: Props) => [Partial<CarouselProps>, Omit<Props, keyof CarouselProps>]; | ||
| declare const indicatorProps: (keyof IndicatorProps)[]; | ||
| declare const splitIndicatorProps: <Props extends IndicatorProps>(props: Props) => [IndicatorProps, Omit<Props, keyof IndicatorProps>]; | ||
| declare const itemProps: (keyof ItemProps)[]; | ||
| declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>]; | ||
| export { type CarouselApi as Api, type AutoplayStatusDetails, type DragStatusDetails, type ElementIds, type IndicatorProps, type IntlTranslations, type ItemProps, type CarouselMachine as Machine, type PageChangeDetails, type ProgressTextDetails, type CarouselProps as Props, type CarouselService as Service, anatomy, connect, indicatorProps, itemProps, machine, props, splitIndicatorProps, splitItemProps, splitProps }; | ||
| import '@zag-js/anatomy'; | ||
| import '@zag-js/core'; |
+7
-276
@@ -1,277 +0,8 @@ | ||
| import * as _zag_js_anatomy from '@zag-js/anatomy'; | ||
| import { PropTypes, RequiredBy, DirectionProperty, CommonProperties, OrientationProperty, NormalizeProps } from '@zag-js/types'; | ||
| export { anatomy } from './carousel.anatomy.js'; | ||
| export { connect } from './carousel.connect.js'; | ||
| export { machine } from './carousel.machine.js'; | ||
| export { indicatorProps, itemProps, props, splitIndicatorProps, splitItemProps, splitProps } from './carousel.props.js'; | ||
| export { CarouselApi as Api, AutoplayStatusDetails, DragStatusDetails, ElementIds, IndicatorProps, IntlTranslations, ItemProps, CarouselMachine as Machine, PageChangeDetails, ProgressTextDetails, CarouselProps as Props, CarouselService as Service } from './carousel.types.js'; | ||
| export { Orientation } from '@zag-js/types'; | ||
| import * as _zag_js_core from '@zag-js/core'; | ||
| import { Machine, EventObject, Service } from '@zag-js/core'; | ||
| declare const anatomy: _zag_js_anatomy.AnatomyInstance<"root" | "itemGroup" | "item" | "control" | "nextTrigger" | "prevTrigger" | "indicatorGroup" | "indicator" | "autoplayTrigger" | "progressText">; | ||
| interface PageChangeDetails { | ||
| page: number; | ||
| pageSnapPoint: number; | ||
| } | ||
| interface DragStatusDetails { | ||
| type: "dragging.start" | "dragging" | "dragging.end"; | ||
| page: number; | ||
| isDragging: boolean; | ||
| } | ||
| interface AutoplayStatusDetails { | ||
| type: "autoplay.start" | "autoplay" | "autoplay.stop"; | ||
| page: number; | ||
| isPlaying: boolean; | ||
| } | ||
| interface ProgressTextDetails { | ||
| page: number; | ||
| totalPages: number; | ||
| } | ||
| interface IntlTranslations { | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicator: (index: number) => string; | ||
| item: (index: number, count: number) => string; | ||
| autoplayStart: string; | ||
| autoplayStop: string; | ||
| progressText?: ((details: ProgressTextDetails) => string) | undefined; | ||
| } | ||
| type ElementIds = Partial<{ | ||
| root: string; | ||
| item: (index: number) => string; | ||
| itemGroup: string; | ||
| nextTrigger: string; | ||
| prevTrigger: string; | ||
| indicatorGroup: string; | ||
| indicator: (index: number) => string; | ||
| }>; | ||
| interface CarouselProps extends DirectionProperty, CommonProperties, OrientationProperty { | ||
| /** | ||
| * The ids of the elements in the carousel. Useful for composition. | ||
| */ | ||
| ids?: ElementIds | undefined; | ||
| /** | ||
| * The localized messages to use. | ||
| */ | ||
| translations?: IntlTranslations | undefined; | ||
| /** | ||
| * The number of slides to show at a time. | ||
| * @default 1 | ||
| */ | ||
| slidesPerPage?: number | undefined; | ||
| /** | ||
| * Whether to enable variable width slides. | ||
| * @default false | ||
| */ | ||
| autoSize?: boolean | undefined; | ||
| /** | ||
| * The number of slides to scroll at a time. | ||
| * | ||
| * When set to `auto`, the number of slides to scroll is determined by the | ||
| * `slidesPerPage` property. | ||
| * | ||
| * @default "auto" | ||
| */ | ||
| slidesPerMove?: number | "auto" | undefined; | ||
| /** | ||
| * Whether to scroll automatically. The default delay is 4000ms. | ||
| * @default false | ||
| */ | ||
| autoplay?: boolean | { | ||
| delay: number; | ||
| } | undefined; | ||
| /** | ||
| * Whether to allow scrolling via dragging with mouse | ||
| * @default false | ||
| */ | ||
| allowMouseDrag?: boolean | undefined; | ||
| /** | ||
| * Whether the carousel should loop around. | ||
| * @default false | ||
| */ | ||
| loop?: boolean | undefined; | ||
| /** | ||
| * The controlled page of the carousel. | ||
| */ | ||
| page?: number | undefined; | ||
| /** | ||
| * The initial page to scroll to when rendered. | ||
| * Use when you don't need to control the page of the carousel. | ||
| * @default 0 | ||
| */ | ||
| defaultPage?: number | undefined; | ||
| /** | ||
| * The amount of space between items. | ||
| * @default "0px" | ||
| */ | ||
| spacing?: string | undefined; | ||
| /** | ||
| * Defines the extra space added around the scrollable area, | ||
| * enabling nearby items to remain partially in view. | ||
| */ | ||
| padding?: string | undefined; | ||
| /** | ||
| * Function called when the page changes. | ||
| */ | ||
| onPageChange?: ((details: PageChangeDetails) => void) | undefined; | ||
| /** | ||
| * The threshold for determining if an item is in view. | ||
| * @default 0.6 | ||
| */ | ||
| inViewThreshold?: number | number[] | undefined; | ||
| /** | ||
| * The snap type of the item. | ||
| * @default "mandatory" | ||
| */ | ||
| snapType?: "proximity" | "mandatory" | undefined; | ||
| /** | ||
| * The total number of slides. | ||
| * Useful for SSR to render the initial ating the snap points. | ||
| */ | ||
| slideCount: number; | ||
| /** | ||
| * Function called when the drag status changes. | ||
| */ | ||
| onDragStatusChange?: ((details: DragStatusDetails) => void) | undefined; | ||
| /** | ||
| * Function called when the autoplay status changes. | ||
| */ | ||
| onAutoplayStatusChange?: ((details: AutoplayStatusDetails) => void) | undefined; | ||
| } | ||
| type PropsWithDefault = "dir" | "defaultPage" | "orientation" | "snapType" | "loop" | "slidesPerPage" | "slidesPerMove" | "spacing" | "autoplay" | "allowMouseDrag" | "inViewThreshold" | "translations" | "slideCount" | "autoSize"; | ||
| interface PrivateContext { | ||
| pageSnapPoints: number[]; | ||
| slidesInView: number[]; | ||
| page: number; | ||
| } | ||
| interface ComputedContext { | ||
| isRtl: boolean; | ||
| isHorizontal: boolean; | ||
| canScrollNext: boolean; | ||
| canScrollPrev: boolean; | ||
| autoplayInterval: number; | ||
| } | ||
| type CarouselService = Service<CarouselSchema>; | ||
| type CarouselMachine = Machine<CarouselSchema>; | ||
| interface CarouselSchema { | ||
| props: RequiredBy<CarouselProps, PropsWithDefault>; | ||
| context: PrivateContext; | ||
| computed: ComputedContext; | ||
| refs: { | ||
| timeoutRef: any; | ||
| }; | ||
| state: "idle" | "dragging" | "autoplay" | "userScroll" | "focus"; | ||
| effect: string; | ||
| action: string; | ||
| guard: string; | ||
| event: EventObject; | ||
| } | ||
| interface ItemProps { | ||
| /** | ||
| * The index of the item. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * The snap alignment of the item. | ||
| * @default "start" | ||
| */ | ||
| snapAlign?: "start" | "end" | "center" | undefined; | ||
| } | ||
| interface IndicatorProps { | ||
| /** | ||
| * The index of the indicator. | ||
| */ | ||
| index: number; | ||
| /** | ||
| * Whether the indicator is read only. | ||
| * @default false | ||
| */ | ||
| readOnly?: boolean | undefined; | ||
| } | ||
| interface CarouselApi<T extends PropTypes = PropTypes> { | ||
| /** | ||
| * The current index of the carousel | ||
| */ | ||
| page: number; | ||
| /** | ||
| * The current snap points of the carousel | ||
| */ | ||
| pageSnapPoints: number[]; | ||
| /** | ||
| * Whether the carousel is auto playing | ||
| */ | ||
| isPlaying: boolean; | ||
| /** | ||
| * Whether the carousel is being dragged. This only works when `draggable` is true. | ||
| */ | ||
| isDragging: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the next view | ||
| */ | ||
| canScrollNext: boolean; | ||
| /** | ||
| * Whether the carousel is can scroll to the previous view | ||
| */ | ||
| canScrollPrev: boolean; | ||
| /** | ||
| * Function to scroll to a specific item index | ||
| */ | ||
| scrollToIndex: (index: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to a specific page | ||
| */ | ||
| scrollTo: (page: number, instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the next page | ||
| */ | ||
| scrollNext: (instant?: boolean) => void; | ||
| /** | ||
| * Function to scroll to the previous page | ||
| */ | ||
| scrollPrev: (instant?: boolean) => void; | ||
| /** | ||
| * Returns the current scroll progress as a percentage | ||
| */ | ||
| getProgress: () => number; | ||
| /** | ||
| * Returns the progress text | ||
| */ | ||
| getProgressText: () => string; | ||
| /** | ||
| * Function to start/resume autoplay | ||
| */ | ||
| play: VoidFunction; | ||
| /** | ||
| * Function to pause autoplay | ||
| */ | ||
| pause: VoidFunction; | ||
| /** | ||
| * Whether the item is in view | ||
| */ | ||
| isInView: (index: number) => boolean; | ||
| /** | ||
| * Function to re-compute the snap points | ||
| * and clamp the page | ||
| */ | ||
| refresh: VoidFunction; | ||
| getRootProps: () => T["element"]; | ||
| getControlProps: () => T["element"]; | ||
| getItemGroupProps: () => T["element"]; | ||
| getItemProps: (props: ItemProps) => T["element"]; | ||
| getPrevTriggerProps: () => T["button"]; | ||
| getNextTriggerProps: () => T["button"]; | ||
| getAutoplayTriggerProps: () => T["button"]; | ||
| getIndicatorGroupProps: () => T["element"]; | ||
| getIndicatorProps: (props: IndicatorProps) => T["button"]; | ||
| getProgressTextProps: () => T["element"]; | ||
| } | ||
| declare function connect<T extends PropTypes>(service: CarouselService, normalize: NormalizeProps<T>): CarouselApi<T>; | ||
| declare const machine: _zag_js_core.Machine<CarouselSchema>; | ||
| declare const props: (keyof CarouselProps)[]; | ||
| declare const splitProps: <Props extends Partial<CarouselProps>>(props: Props) => [Partial<CarouselProps>, Omit<Props, keyof CarouselProps>]; | ||
| declare const indicatorProps: (keyof IndicatorProps)[]; | ||
| declare const splitIndicatorProps: <Props extends IndicatorProps>(props: Props) => [IndicatorProps, Omit<Props, keyof IndicatorProps>]; | ||
| declare const itemProps: (keyof ItemProps)[]; | ||
| declare const splitItemProps: <Props extends ItemProps>(props: Props) => [ItemProps, Omit<Props, keyof ItemProps>]; | ||
| export { type CarouselApi as Api, type AutoplayStatusDetails, type DragStatusDetails, type ElementIds, type IndicatorProps, type IntlTranslations, type ItemProps, type CarouselMachine as Machine, type PageChangeDetails, type ProgressTextDetails, type CarouselProps as Props, type CarouselService as Service, anatomy, connect, indicatorProps, itemProps, machine, props, splitIndicatorProps, splitItemProps, splitProps }; | ||
| import '@zag-js/anatomy'; | ||
| import '@zag-js/core'; |
+36
-805
@@ -1,808 +0,39 @@ | ||
| 'use strict'; | ||
| var anatomy$1 = require('@zag-js/anatomy'); | ||
| var domQuery = require('@zag-js/dom-query'); | ||
| var utils = require('@zag-js/utils'); | ||
| var core = require('@zag-js/core'); | ||
| var scrollSnap = require('@zag-js/scroll-snap'); | ||
| var types = require('@zag-js/types'); | ||
| // src/carousel.anatomy.ts | ||
| var anatomy = anatomy$1.createAnatomy("carousel").parts( | ||
| "root", | ||
| "itemGroup", | ||
| "item", | ||
| "control", | ||
| "nextTrigger", | ||
| "prevTrigger", | ||
| "indicatorGroup", | ||
| "indicator", | ||
| "autoplayTrigger", | ||
| "progressText" | ||
| ); | ||
| var parts = anatomy.build(); | ||
| var getRootId = (ctx) => ctx.ids?.root ?? `carousel:${ctx.id}`; | ||
| var getItemId = (ctx, index) => ctx.ids?.item?.(index) ?? `carousel:${ctx.id}:item:${index}`; | ||
| var getItemGroupId = (ctx) => ctx.ids?.itemGroup ?? `carousel:${ctx.id}:item-group`; | ||
| var getNextTriggerId = (ctx) => ctx.ids?.nextTrigger ?? `carousel:${ctx.id}:next-trigger`; | ||
| var getPrevTriggerId = (ctx) => ctx.ids?.prevTrigger ?? `carousel:${ctx.id}:prev-trigger`; | ||
| var getIndicatorGroupId = (ctx) => ctx.ids?.indicatorGroup ?? `carousel:${ctx.id}:indicator-group`; | ||
| var getIndicatorId = (ctx, index) => ctx.ids?.indicator?.(index) ?? `carousel:${ctx.id}:indicator:${index}`; | ||
| var getItemGroupEl = (ctx) => ctx.getById(getItemGroupId(ctx)); | ||
| var getItemEls = (ctx) => domQuery.queryAll(getItemGroupEl(ctx), `[data-part=item]`); | ||
| var getIndicatorEl = (ctx, page) => ctx.getById(getIndicatorId(ctx, page)); | ||
| var syncTabIndex = (ctx) => { | ||
| const el = getItemGroupEl(ctx); | ||
| if (!el) return; | ||
| const tabbables = domQuery.getTabbables(el); | ||
| el.setAttribute("tabindex", tabbables.length > 0 ? "-1" : "0"); | ||
| "use strict"; | ||
| var __defProp = Object.defineProperty; | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __export = (target, all) => { | ||
| for (var name in all) | ||
| __defProp(target, name, { get: all[name], enumerable: true }); | ||
| }; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") { | ||
| for (let key of __getOwnPropNames(from)) | ||
| if (!__hasOwnProp.call(to, key) && key !== except) | ||
| __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable }); | ||
| } | ||
| return to; | ||
| }; | ||
| var __reExport = (target, mod, secondTarget) => (__copyProps(target, mod, "default"), secondTarget && __copyProps(secondTarget, mod, "default")); | ||
| var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod); | ||
| // src/carousel.connect.ts | ||
| function connect(service, normalize) { | ||
| const { state, context, computed, send, scope, prop } = service; | ||
| const isPlaying = state.matches("autoplay"); | ||
| const isDragging = state.matches("dragging"); | ||
| const canScrollNext = computed("canScrollNext"); | ||
| const canScrollPrev = computed("canScrollPrev"); | ||
| const horizontal = computed("isHorizontal"); | ||
| const autoSize = prop("autoSize"); | ||
| const pageSnapPoints = Array.from(context.get("pageSnapPoints")); | ||
| const page = context.get("page"); | ||
| const slidesPerPage = prop("slidesPerPage"); | ||
| const padding = prop("padding"); | ||
| const translations = prop("translations"); | ||
| return { | ||
| isPlaying, | ||
| isDragging, | ||
| page, | ||
| pageSnapPoints, | ||
| canScrollNext, | ||
| canScrollPrev, | ||
| getProgress() { | ||
| return page / pageSnapPoints.length; | ||
| }, | ||
| getProgressText() { | ||
| const details = { page: page + 1, totalPages: pageSnapPoints.length }; | ||
| return translations.progressText?.(details) ?? ""; | ||
| }, | ||
| scrollToIndex(index, instant) { | ||
| send({ type: "INDEX.SET", index, instant }); | ||
| }, | ||
| scrollTo(index, instant) { | ||
| send({ type: "PAGE.SET", index, instant }); | ||
| }, | ||
| scrollNext(instant) { | ||
| send({ type: "PAGE.NEXT", instant }); | ||
| }, | ||
| scrollPrev(instant) { | ||
| send({ type: "PAGE.PREV", instant }); | ||
| }, | ||
| play() { | ||
| send({ type: "AUTOPLAY.START" }); | ||
| }, | ||
| pause() { | ||
| send({ type: "AUTOPLAY.PAUSE" }); | ||
| }, | ||
| isInView(index) { | ||
| return Array.from(context.get("slidesInView")).includes(index); | ||
| }, | ||
| refresh() { | ||
| send({ type: "SNAP.REFRESH" }); | ||
| }, | ||
| getRootProps() { | ||
| return normalize.element({ | ||
| ...parts.root.attrs, | ||
| id: getRootId(scope), | ||
| role: "region", | ||
| "aria-roledescription": "carousel", | ||
| "data-orientation": prop("orientation"), | ||
| dir: prop("dir"), | ||
| style: { | ||
| "--slides-per-page": slidesPerPage, | ||
| "--slide-spacing": prop("spacing"), | ||
| "--slide-item-size": autoSize ? "auto" : "calc(100% / var(--slides-per-page) - var(--slide-spacing) * (var(--slides-per-page) - 1) / var(--slides-per-page))" | ||
| } | ||
| }); | ||
| }, | ||
| getItemGroupProps() { | ||
| return normalize.element({ | ||
| ...parts.itemGroup.attrs, | ||
| id: getItemGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| "data-dragging": domQuery.dataAttr(isDragging), | ||
| dir: prop("dir"), | ||
| "aria-live": isPlaying ? "off" : "polite", | ||
| onFocus(event) { | ||
| if (!domQuery.contains(event.currentTarget, domQuery.getEventTarget(event))) return; | ||
| send({ type: "VIEWPORT.FOCUS" }); | ||
| }, | ||
| onBlur(event) { | ||
| if (domQuery.contains(event.currentTarget, event.relatedTarget)) return; | ||
| send({ type: "VIEWPORT.BLUR" }); | ||
| }, | ||
| onMouseDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (!prop("allowMouseDrag")) return; | ||
| if (!domQuery.isLeftClick(event)) return; | ||
| const target = domQuery.getEventTarget(event); | ||
| if (domQuery.isFocusable(target) && target !== event.currentTarget) return; | ||
| event.preventDefault(); | ||
| send({ type: "DRAGGING.START" }); | ||
| }, | ||
| onWheel: utils.throttle((event) => { | ||
| const axis = prop("orientation") === "horizontal" ? "deltaX" : "deltaY"; | ||
| const isScrollingLeft = event[axis] < 0; | ||
| if (isScrollingLeft && !computed("canScrollPrev")) return; | ||
| const isScrollingRight = event[axis] > 0; | ||
| if (isScrollingRight && !computed("canScrollNext")) return; | ||
| send({ type: "USER.SCROLL" }); | ||
| }, 150), | ||
| onTouchStart() { | ||
| send({ type: "USER.SCROLL" }); | ||
| }, | ||
| style: { | ||
| display: autoSize ? "flex" : "grid", | ||
| gap: "var(--slide-spacing)", | ||
| scrollSnapType: [horizontal ? "x" : "y", prop("snapType")].join(" "), | ||
| gridAutoFlow: horizontal ? "column" : "row", | ||
| scrollbarWidth: "none", | ||
| overscrollBehaviorX: "contain", | ||
| [horizontal ? "gridAutoColumns" : "gridAutoRows"]: autoSize ? void 0 : "var(--slide-item-size)", | ||
| [horizontal ? "scrollPaddingInline" : "scrollPaddingBlock"]: padding, | ||
| [horizontal ? "paddingInline" : "paddingBlock"]: padding, | ||
| [horizontal ? "overflowX" : "overflowY"]: "auto" | ||
| } | ||
| }); | ||
| }, | ||
| getItemProps(props2) { | ||
| const isInView = context.get("slidesInView").includes(props2.index); | ||
| return normalize.element({ | ||
| ...parts.item.attrs, | ||
| id: getItemId(scope, props2.index), | ||
| dir: prop("dir"), | ||
| role: "group", | ||
| "data-index": props2.index, | ||
| "data-inview": domQuery.dataAttr(isInView), | ||
| "aria-roledescription": "slide", | ||
| "data-orientation": prop("orientation"), | ||
| "aria-label": translations.item(props2.index, prop("slideCount")), | ||
| "aria-hidden": domQuery.ariaAttr(!isInView), | ||
| style: { | ||
| flex: "0 0 auto", | ||
| [horizontal ? "maxWidth" : "maxHeight"]: "100%", | ||
| scrollSnapAlign: (() => { | ||
| const snapAlign = props2.snapAlign ?? "start"; | ||
| const slidesPerMove = prop("slidesPerMove"); | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(prop("slidesPerPage")) : slidesPerMove; | ||
| const shouldSnap = (props2.index + perMove) % perMove === 0; | ||
| return shouldSnap ? snapAlign : void 0; | ||
| })() | ||
| } | ||
| }); | ||
| }, | ||
| getControlProps() { | ||
| return normalize.element({ | ||
| ...parts.control.attrs, | ||
| "data-orientation": prop("orientation") | ||
| }); | ||
| }, | ||
| getPrevTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.prevTrigger.attrs, | ||
| id: getPrevTriggerId(scope), | ||
| type: "button", | ||
| disabled: !canScrollPrev, | ||
| dir: prop("dir"), | ||
| "aria-label": translations.prevTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": getItemGroupId(scope), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.PREV", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getNextTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.nextTrigger.attrs, | ||
| dir: prop("dir"), | ||
| id: getNextTriggerId(scope), | ||
| type: "button", | ||
| "aria-label": translations.nextTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": getItemGroupId(scope), | ||
| disabled: !canScrollNext, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.NEXT", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorGroupProps() { | ||
| return normalize.element({ | ||
| ...parts.indicatorGroup.attrs, | ||
| dir: prop("dir"), | ||
| id: getIndicatorGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| onKeyDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| const src = "indicator"; | ||
| const keyMap = { | ||
| ArrowDown(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowUp(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowRight(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowLeft(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| Home(event2) { | ||
| send({ type: "PAGE.SET", index: 0, src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| End(event2) { | ||
| send({ type: "PAGE.SET", index: pageSnapPoints.length - 1, src }); | ||
| event2.preventDefault(); | ||
| } | ||
| }; | ||
| const key = domQuery.getEventKey(event, { | ||
| dir: prop("dir"), | ||
| orientation: prop("orientation") | ||
| }); | ||
| const exec = keyMap[key]; | ||
| exec?.(event); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorProps(props2) { | ||
| return normalize.button({ | ||
| ...parts.indicator.attrs, | ||
| dir: prop("dir"), | ||
| id: getIndicatorId(scope, props2.index), | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-index": props2.index, | ||
| "data-readonly": domQuery.dataAttr(props2.readOnly), | ||
| "data-current": domQuery.dataAttr(props2.index === page), | ||
| "aria-label": translations.indicator(props2.index), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (props2.readOnly) return; | ||
| send({ type: "PAGE.SET", index: props2.index, src: "indicator" }); | ||
| } | ||
| }); | ||
| }, | ||
| getAutoplayTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.autoplayTrigger.attrs, | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-pressed": domQuery.dataAttr(isPlaying), | ||
| "aria-label": isPlaying ? translations.autoplayStop : translations.autoplayStart, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: isPlaying ? "AUTOPLAY.PAUSE" : "AUTOPLAY.START" }); | ||
| } | ||
| }); | ||
| }, | ||
| getProgressTextProps() { | ||
| return normalize.element({ | ||
| ...parts.progressText.attrs | ||
| }); | ||
| } | ||
| }; | ||
| } | ||
| var machine = core.createMachine({ | ||
| props({ props: props2 }) { | ||
| utils.ensureProps(props2, ["slideCount"], "carousel"); | ||
| return { | ||
| dir: "ltr", | ||
| defaultPage: 0, | ||
| orientation: "horizontal", | ||
| snapType: "mandatory", | ||
| loop: !!props2.autoplay, | ||
| slidesPerPage: 1, | ||
| slidesPerMove: "auto", | ||
| spacing: "0px", | ||
| autoplay: false, | ||
| allowMouseDrag: false, | ||
| inViewThreshold: 0.6, | ||
| autoSize: false, | ||
| ...props2, | ||
| translations: { | ||
| nextTrigger: "Next slide", | ||
| prevTrigger: "Previous slide", | ||
| indicator: (index) => `Go to slide ${index + 1}`, | ||
| item: (index, count) => `${index + 1} of ${count}`, | ||
| autoplayStart: "Start slide rotation", | ||
| autoplayStop: "Stop slide rotation", | ||
| progressText: ({ page, totalPages }) => `${page} / ${totalPages}`, | ||
| ...props2.translations | ||
| } | ||
| }; | ||
| }, | ||
| refs() { | ||
| return { | ||
| timeoutRef: void 0 | ||
| }; | ||
| }, | ||
| initialState({ prop }) { | ||
| return prop("autoplay") ? "autoplay" : "idle"; | ||
| }, | ||
| context({ prop, bindable, getContext }) { | ||
| return { | ||
| page: bindable(() => ({ | ||
| defaultValue: prop("defaultPage"), | ||
| value: prop("page"), | ||
| onChange(page) { | ||
| const ctx = getContext(); | ||
| const pageSnapPoints = ctx.get("pageSnapPoints"); | ||
| prop("onPageChange")?.({ page, pageSnapPoint: pageSnapPoints[page] }); | ||
| } | ||
| })), | ||
| pageSnapPoints: bindable(() => { | ||
| return { | ||
| defaultValue: prop("autoSize") ? Array.from({ length: prop("slideCount") }, (_, i) => i) : getPageSnapPoints(prop("slideCount"), prop("slidesPerMove"), prop("slidesPerPage")) | ||
| }; | ||
| }), | ||
| slidesInView: bindable(() => ({ | ||
| defaultValue: [] | ||
| })) | ||
| }; | ||
| }, | ||
| computed: { | ||
| isRtl: ({ prop }) => prop("dir") === "rtl", | ||
| isHorizontal: ({ prop }) => prop("orientation") === "horizontal", | ||
| canScrollNext: ({ prop, context }) => prop("loop") || context.get("page") < context.get("pageSnapPoints").length - 1, | ||
| canScrollPrev: ({ prop, context }) => prop("loop") || context.get("page") > 0, | ||
| autoplayInterval: ({ prop }) => { | ||
| const autoplay = prop("autoplay"); | ||
| return utils.isObject(autoplay) ? autoplay.delay : 4e3; | ||
| } | ||
| }, | ||
| watch({ track, action, context, prop, send }) { | ||
| track([() => prop("slidesPerPage"), () => prop("slidesPerMove")], () => { | ||
| action(["setSnapPoints"]); | ||
| }); | ||
| track([() => context.get("page")], () => { | ||
| action(["scrollToPage", "focusIndicatorEl"]); | ||
| }); | ||
| track([() => prop("orientation"), () => prop("autoSize"), () => prop("dir")], () => { | ||
| action(["setSnapPoints", "scrollToPage"]); | ||
| }); | ||
| track([() => prop("slideCount")], () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.count" }); | ||
| }); | ||
| track([() => !!prop("autoplay")], () => { | ||
| send({ type: prop("autoplay") ? "AUTOPLAY.START" : "AUTOPLAY.PAUSE", src: "autoplay.prop.change" }); | ||
| }); | ||
| }, | ||
| on: { | ||
| "PAGE.NEXT": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "SNAP.REFRESH": { | ||
| actions: ["setSnapPoints", "clampPage"] | ||
| }, | ||
| "PAGE.SCROLL": { | ||
| actions: ["scrollToPage"] | ||
| } | ||
| }, | ||
| effects: ["trackSlideMutation", "trackSlideIntersections", "trackSlideResize"], | ||
| entry: ["setSnapPoints", "setPage"], | ||
| exit: ["clearScrollEndTimer"], | ||
| states: { | ||
| idle: { | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.START": { | ||
| target: "autoplay", | ||
| actions: ["invokeAutoplayStart"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| }, | ||
| "VIEWPORT.FOCUS": { | ||
| target: "focus" | ||
| } | ||
| } | ||
| }, | ||
| focus: { | ||
| effects: ["trackKeyboardScroll"], | ||
| on: { | ||
| "VIEWPORT.BLUR": { | ||
| target: "idle" | ||
| }, | ||
| "PAGE.NEXT": { | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| } | ||
| } | ||
| }, | ||
| dragging: { | ||
| effects: ["trackPointerMove"], | ||
| entry: ["disableScrollSnap"], | ||
| on: { | ||
| DRAGGING: { | ||
| actions: ["scrollSlides", "invokeDragging"] | ||
| }, | ||
| "DRAGGING.END": { | ||
| target: "idle", | ||
| actions: ["endDragging", "invokeDraggingEnd"] | ||
| } | ||
| } | ||
| }, | ||
| userScroll: { | ||
| effects: ["trackScroll"], | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "SCROLL.END": [ | ||
| { | ||
| guard: "isFocused", | ||
| target: "focus", | ||
| actions: ["setClosestPage"] | ||
| }, | ||
| { | ||
| target: "idle", | ||
| actions: ["setClosestPage"] | ||
| } | ||
| ] | ||
| } | ||
| }, | ||
| autoplay: { | ||
| effects: ["trackDocumentVisibility", "trackScroll", "autoUpdateSlide"], | ||
| exit: ["invokeAutoplayEnd"], | ||
| on: { | ||
| "AUTOPLAY.TICK": { | ||
| actions: ["setNextPage", "invokeAutoplay"] | ||
| }, | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.PAUSE": { | ||
| target: "idle" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| implementations: { | ||
| guards: { | ||
| isFocused: ({ scope }) => scope.isActiveElement(getItemGroupEl(scope)) | ||
| }, | ||
| effects: { | ||
| autoUpdateSlide({ computed, send }) { | ||
| const id = setInterval(() => { | ||
| send({ | ||
| type: computed("canScrollNext") ? "AUTOPLAY.TICK" : "AUTOPLAY.PAUSE", | ||
| src: "autoplay.interval" | ||
| }); | ||
| }, computed("autoplayInterval")); | ||
| return () => clearInterval(id); | ||
| }, | ||
| trackSlideMutation({ scope, send }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const win = scope.getWin(); | ||
| const observer = new win.MutationObserver(() => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.mutation" }); | ||
| syncTabIndex(scope); | ||
| }); | ||
| syncTabIndex(scope); | ||
| observer.observe(el, { childList: true, subtree: true }); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackSlideResize({ scope, send }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const exec = () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.resize" }); | ||
| }; | ||
| domQuery.raf(() => { | ||
| exec(); | ||
| domQuery.raf(() => { | ||
| send({ type: "PAGE.SCROLL", instant: true }); | ||
| }); | ||
| }); | ||
| const itemEls = getItemEls(scope); | ||
| itemEls.forEach(exec); | ||
| const cleanups = itemEls.map((el2) => domQuery.resizeObserverBorderBox.observe(el2, exec)); | ||
| return utils.callAll(...cleanups); | ||
| }, | ||
| trackSlideIntersections({ scope, prop, context }) { | ||
| const el = getItemGroupEl(scope); | ||
| const win = scope.getWin(); | ||
| const observer = new win.IntersectionObserver( | ||
| (entries) => { | ||
| const slidesInView = entries.reduce((acc, entry) => { | ||
| const target = entry.target; | ||
| const index = Number(target.dataset.index ?? "-1"); | ||
| if (index == null || Number.isNaN(index) || index === -1) return acc; | ||
| return entry.isIntersecting ? utils.add(acc, index) : utils.remove(acc, index); | ||
| }, context.get("slidesInView")); | ||
| context.set("slidesInView", utils.uniq(slidesInView)); | ||
| }, | ||
| { | ||
| root: el, | ||
| threshold: prop("inViewThreshold") | ||
| } | ||
| ); | ||
| getItemEls(scope).forEach((slide) => observer.observe(slide)); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackScroll({ send, refs, scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const onScroll = () => { | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| refs.set( | ||
| "timeoutRef", | ||
| setTimeout(() => { | ||
| send({ type: "SCROLL.END" }); | ||
| }, 150) | ||
| ); | ||
| }; | ||
| return domQuery.addDomEvent(el, "scroll", onScroll, { passive: true }); | ||
| }, | ||
| trackDocumentVisibility({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| const onVisibilityChange = () => { | ||
| if (doc.visibilityState === "visible") return; | ||
| send({ type: "AUTOPLAY.PAUSE", src: "doc.hidden" }); | ||
| }; | ||
| return domQuery.addDomEvent(doc, "visibilitychange", onVisibilityChange); | ||
| }, | ||
| trackPointerMove({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| return domQuery.trackPointerMove(doc, { | ||
| onPointerMove({ event }) { | ||
| send({ type: "DRAGGING", left: -event.movementX, top: -event.movementY }); | ||
| }, | ||
| onPointerUp() { | ||
| send({ type: "DRAGGING.END" }); | ||
| } | ||
| }); | ||
| }, | ||
| trackKeyboardScroll({ scope, send, context }) { | ||
| const win = scope.getWin(); | ||
| const onKeyDown = (event) => { | ||
| switch (event.key) { | ||
| case "ArrowRight": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.NEXT" }); | ||
| break; | ||
| case "ArrowLeft": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.PREV" }); | ||
| break; | ||
| case "Home": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: 0 }); | ||
| break; | ||
| case "End": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: context.get("pageSnapPoints").length - 1 }); | ||
| } | ||
| }; | ||
| return domQuery.addDomEvent(win, "keydown", onKeyDown, { capture: true }); | ||
| } | ||
| }, | ||
| actions: { | ||
| clearScrollEndTimer({ refs }) { | ||
| if (refs.get("timeoutRef") == null) return; | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| }, | ||
| scrollToPage({ context, event, scope, computed, flush }) { | ||
| const behavior = event.instant ? "instant" : "smooth"; | ||
| const index = utils.clampValue(event.index ?? context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const axis = computed("isHorizontal") ? "left" : "top"; | ||
| flush(() => { | ||
| el.scrollTo({ [axis]: context.get("pageSnapPoints")[index], behavior }); | ||
| }); | ||
| }, | ||
| setClosestPage({ context, scope, computed }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollPosition = computed("isHorizontal") ? el.scrollLeft : el.scrollTop; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - scrollPosition) < 1); | ||
| if (page === -1) return; | ||
| context.set("page", page); | ||
| }, | ||
| setNextPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = utils.nextIndex(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setPrevPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = utils.prevIndex(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setMatchingPage({ context, event, computed, scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const snapPoint = scrollSnap.findSnapPoint( | ||
| el, | ||
| computed("isHorizontal") ? "x" : "y", | ||
| (node) => node.dataset.index === event.index.toString() | ||
| ); | ||
| if (snapPoint == null) return; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - snapPoint) < 1); | ||
| context.set("page", page); | ||
| }, | ||
| setPage({ context, event }) { | ||
| const page = event.index ?? context.get("page"); | ||
| context.set("page", page); | ||
| }, | ||
| clampPage({ context }) { | ||
| const index = utils.clampValue(context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| context.set("page", index); | ||
| }, | ||
| setSnapPoints({ context, computed, scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollSnapPoints = scrollSnap.getScrollSnapPositions(el); | ||
| context.set("pageSnapPoints", computed("isHorizontal") ? scrollSnapPoints.x : scrollSnapPoints.y); | ||
| }, | ||
| disableScrollSnap({ scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const styles = getComputedStyle(el); | ||
| el.dataset.scrollSnapType = styles.getPropertyValue("scroll-snap-type"); | ||
| el.style.setProperty("scroll-snap-type", "none"); | ||
| }, | ||
| scrollSlides({ scope, event }) { | ||
| const el = getItemGroupEl(scope); | ||
| el?.scrollBy({ left: event.left, top: event.top, behavior: "instant" }); | ||
| }, | ||
| endDragging({ scope, context, computed }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const isHorizontal = computed("isHorizontal"); | ||
| const scrollPos = isHorizontal ? el.scrollLeft : el.scrollTop; | ||
| const snapPoints = context.get("pageSnapPoints"); | ||
| const closest = snapPoints.reduce((closest2, curr) => { | ||
| return Math.abs(curr - scrollPos) < Math.abs(closest2 - scrollPos) ? curr : closest2; | ||
| }, snapPoints[0]); | ||
| domQuery.raf(() => { | ||
| el.scrollTo({ | ||
| left: isHorizontal ? closest : el.scrollLeft, | ||
| top: isHorizontal ? el.scrollTop : closest, | ||
| behavior: "smooth" | ||
| }); | ||
| context.set("page", snapPoints.indexOf(closest)); | ||
| const scrollSnapType = el.dataset.scrollSnapType; | ||
| if (scrollSnapType) { | ||
| el.style.setProperty("scroll-snap-type", scrollSnapType); | ||
| delete el.dataset.scrollSnapType; | ||
| } | ||
| }); | ||
| }, | ||
| focusIndicatorEl({ context, event, scope }) { | ||
| if (event.src !== "indicator") return; | ||
| const el = getIndicatorEl(scope, context.get("page")); | ||
| if (!el) return; | ||
| domQuery.raf(() => el.focus({ preventScroll: true })); | ||
| }, | ||
| invokeDragStart({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.start", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDragging({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDraggingEnd({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.end", isDragging: false, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplay({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayStart({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.start", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayEnd({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.stop", isPlaying: false, page: context.get("page") }); | ||
| } | ||
| } | ||
| } | ||
| // src/index.ts | ||
| var index_exports = {}; | ||
| __export(index_exports, { | ||
| anatomy: () => import_carousel.anatomy, | ||
| connect: () => import_carousel2.connect, | ||
| machine: () => import_carousel3.machine | ||
| }); | ||
| function getPageSnapPoints(totalSlides, slidesPerMove, slidesPerPage) { | ||
| if (totalSlides == null || slidesPerPage <= 0) { | ||
| return []; | ||
| } | ||
| const snapPoints = []; | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(slidesPerPage) : slidesPerMove; | ||
| if (perMove <= 0) { | ||
| return []; | ||
| } | ||
| for (let i = 0; i < totalSlides; i += perMove) { | ||
| if (i + slidesPerPage > totalSlides) break; | ||
| snapPoints.push(i); | ||
| } | ||
| return snapPoints; | ||
| } | ||
| var props = types.createProps()([ | ||
| "dir", | ||
| "getRootNode", | ||
| "id", | ||
| "ids", | ||
| "loop", | ||
| "page", | ||
| "defaultPage", | ||
| "onPageChange", | ||
| "orientation", | ||
| "slideCount", | ||
| "slidesPerPage", | ||
| "slidesPerMove", | ||
| "spacing", | ||
| "padding", | ||
| "autoplay", | ||
| "allowMouseDrag", | ||
| "inViewThreshold", | ||
| "translations", | ||
| "snapType", | ||
| "autoSize", | ||
| "onDragStatusChange", | ||
| "onAutoplayStatusChange" | ||
| ]); | ||
| var splitProps = utils.createSplitProps(props); | ||
| var indicatorProps = types.createProps()(["index", "readOnly"]); | ||
| var splitIndicatorProps = utils.createSplitProps(indicatorProps); | ||
| var itemProps = types.createProps()(["index", "snapAlign"]); | ||
| var splitItemProps = utils.createSplitProps(itemProps); | ||
| exports.anatomy = anatomy; | ||
| exports.connect = connect; | ||
| exports.indicatorProps = indicatorProps; | ||
| exports.itemProps = itemProps; | ||
| exports.machine = machine; | ||
| exports.props = props; | ||
| exports.splitIndicatorProps = splitIndicatorProps; | ||
| exports.splitItemProps = splitItemProps; | ||
| exports.splitProps = splitProps; | ||
| module.exports = __toCommonJS(index_exports); | ||
| var import_carousel = require("./carousel.anatomy.cjs"); | ||
| var import_carousel2 = require("./carousel.connect.cjs"); | ||
| var import_carousel3 = require("./carousel.machine.cjs"); | ||
| __reExport(index_exports, require("./carousel.props.cjs"), module.exports); | ||
| // Annotate the CommonJS export names for ESM import in node: | ||
| 0 && (module.exports = { | ||
| anatomy, | ||
| connect, | ||
| machine, | ||
| ...require("./carousel.props.cjs") | ||
| }); |
+9
-797
@@ -1,798 +0,10 @@ | ||
| import { createAnatomy } from '@zag-js/anatomy'; | ||
| import { raf, addDomEvent, trackPointerMove, resizeObserverBorderBox, queryAll, getTabbables, dataAttr, getEventKey, ariaAttr, isLeftClick, getEventTarget, isFocusable, contains } from '@zag-js/dom-query'; | ||
| import { clampValue, prevIndex, nextIndex, add, remove, uniq, callAll, isObject, ensureProps, createSplitProps, throttle } from '@zag-js/utils'; | ||
| import { createMachine } from '@zag-js/core'; | ||
| import { getScrollSnapPositions, findSnapPoint } from '@zag-js/scroll-snap'; | ||
| import { createProps } from '@zag-js/types'; | ||
| // src/carousel.anatomy.ts | ||
| var anatomy = createAnatomy("carousel").parts( | ||
| "root", | ||
| "itemGroup", | ||
| "item", | ||
| "control", | ||
| "nextTrigger", | ||
| "prevTrigger", | ||
| "indicatorGroup", | ||
| "indicator", | ||
| "autoplayTrigger", | ||
| "progressText" | ||
| ); | ||
| var parts = anatomy.build(); | ||
| var getRootId = (ctx) => ctx.ids?.root ?? `carousel:${ctx.id}`; | ||
| var getItemId = (ctx, index) => ctx.ids?.item?.(index) ?? `carousel:${ctx.id}:item:${index}`; | ||
| var getItemGroupId = (ctx) => ctx.ids?.itemGroup ?? `carousel:${ctx.id}:item-group`; | ||
| var getNextTriggerId = (ctx) => ctx.ids?.nextTrigger ?? `carousel:${ctx.id}:next-trigger`; | ||
| var getPrevTriggerId = (ctx) => ctx.ids?.prevTrigger ?? `carousel:${ctx.id}:prev-trigger`; | ||
| var getIndicatorGroupId = (ctx) => ctx.ids?.indicatorGroup ?? `carousel:${ctx.id}:indicator-group`; | ||
| var getIndicatorId = (ctx, index) => ctx.ids?.indicator?.(index) ?? `carousel:${ctx.id}:indicator:${index}`; | ||
| var getItemGroupEl = (ctx) => ctx.getById(getItemGroupId(ctx)); | ||
| var getItemEls = (ctx) => queryAll(getItemGroupEl(ctx), `[data-part=item]`); | ||
| var getIndicatorEl = (ctx, page) => ctx.getById(getIndicatorId(ctx, page)); | ||
| var syncTabIndex = (ctx) => { | ||
| const el = getItemGroupEl(ctx); | ||
| if (!el) return; | ||
| const tabbables = getTabbables(el); | ||
| el.setAttribute("tabindex", tabbables.length > 0 ? "-1" : "0"); | ||
| // src/index.ts | ||
| import { anatomy } from "./carousel.anatomy.mjs"; | ||
| import { connect } from "./carousel.connect.mjs"; | ||
| import { machine } from "./carousel.machine.mjs"; | ||
| export * from "./carousel.props.mjs"; | ||
| export { | ||
| anatomy, | ||
| connect, | ||
| machine | ||
| }; | ||
| // src/carousel.connect.ts | ||
| function connect(service, normalize) { | ||
| const { state, context, computed, send, scope, prop } = service; | ||
| const isPlaying = state.matches("autoplay"); | ||
| const isDragging = state.matches("dragging"); | ||
| const canScrollNext = computed("canScrollNext"); | ||
| const canScrollPrev = computed("canScrollPrev"); | ||
| const horizontal = computed("isHorizontal"); | ||
| const autoSize = prop("autoSize"); | ||
| const pageSnapPoints = Array.from(context.get("pageSnapPoints")); | ||
| const page = context.get("page"); | ||
| const slidesPerPage = prop("slidesPerPage"); | ||
| const padding = prop("padding"); | ||
| const translations = prop("translations"); | ||
| return { | ||
| isPlaying, | ||
| isDragging, | ||
| page, | ||
| pageSnapPoints, | ||
| canScrollNext, | ||
| canScrollPrev, | ||
| getProgress() { | ||
| return page / pageSnapPoints.length; | ||
| }, | ||
| getProgressText() { | ||
| const details = { page: page + 1, totalPages: pageSnapPoints.length }; | ||
| return translations.progressText?.(details) ?? ""; | ||
| }, | ||
| scrollToIndex(index, instant) { | ||
| send({ type: "INDEX.SET", index, instant }); | ||
| }, | ||
| scrollTo(index, instant) { | ||
| send({ type: "PAGE.SET", index, instant }); | ||
| }, | ||
| scrollNext(instant) { | ||
| send({ type: "PAGE.NEXT", instant }); | ||
| }, | ||
| scrollPrev(instant) { | ||
| send({ type: "PAGE.PREV", instant }); | ||
| }, | ||
| play() { | ||
| send({ type: "AUTOPLAY.START" }); | ||
| }, | ||
| pause() { | ||
| send({ type: "AUTOPLAY.PAUSE" }); | ||
| }, | ||
| isInView(index) { | ||
| return Array.from(context.get("slidesInView")).includes(index); | ||
| }, | ||
| refresh() { | ||
| send({ type: "SNAP.REFRESH" }); | ||
| }, | ||
| getRootProps() { | ||
| return normalize.element({ | ||
| ...parts.root.attrs, | ||
| id: getRootId(scope), | ||
| role: "region", | ||
| "aria-roledescription": "carousel", | ||
| "data-orientation": prop("orientation"), | ||
| dir: prop("dir"), | ||
| style: { | ||
| "--slides-per-page": slidesPerPage, | ||
| "--slide-spacing": prop("spacing"), | ||
| "--slide-item-size": autoSize ? "auto" : "calc(100% / var(--slides-per-page) - var(--slide-spacing) * (var(--slides-per-page) - 1) / var(--slides-per-page))" | ||
| } | ||
| }); | ||
| }, | ||
| getItemGroupProps() { | ||
| return normalize.element({ | ||
| ...parts.itemGroup.attrs, | ||
| id: getItemGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| "data-dragging": dataAttr(isDragging), | ||
| dir: prop("dir"), | ||
| "aria-live": isPlaying ? "off" : "polite", | ||
| onFocus(event) { | ||
| if (!contains(event.currentTarget, getEventTarget(event))) return; | ||
| send({ type: "VIEWPORT.FOCUS" }); | ||
| }, | ||
| onBlur(event) { | ||
| if (contains(event.currentTarget, event.relatedTarget)) return; | ||
| send({ type: "VIEWPORT.BLUR" }); | ||
| }, | ||
| onMouseDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (!prop("allowMouseDrag")) return; | ||
| if (!isLeftClick(event)) return; | ||
| const target = getEventTarget(event); | ||
| if (isFocusable(target) && target !== event.currentTarget) return; | ||
| event.preventDefault(); | ||
| send({ type: "DRAGGING.START" }); | ||
| }, | ||
| onWheel: throttle((event) => { | ||
| const axis = prop("orientation") === "horizontal" ? "deltaX" : "deltaY"; | ||
| const isScrollingLeft = event[axis] < 0; | ||
| if (isScrollingLeft && !computed("canScrollPrev")) return; | ||
| const isScrollingRight = event[axis] > 0; | ||
| if (isScrollingRight && !computed("canScrollNext")) return; | ||
| send({ type: "USER.SCROLL" }); | ||
| }, 150), | ||
| onTouchStart() { | ||
| send({ type: "USER.SCROLL" }); | ||
| }, | ||
| style: { | ||
| display: autoSize ? "flex" : "grid", | ||
| gap: "var(--slide-spacing)", | ||
| scrollSnapType: [horizontal ? "x" : "y", prop("snapType")].join(" "), | ||
| gridAutoFlow: horizontal ? "column" : "row", | ||
| scrollbarWidth: "none", | ||
| overscrollBehaviorX: "contain", | ||
| [horizontal ? "gridAutoColumns" : "gridAutoRows"]: autoSize ? void 0 : "var(--slide-item-size)", | ||
| [horizontal ? "scrollPaddingInline" : "scrollPaddingBlock"]: padding, | ||
| [horizontal ? "paddingInline" : "paddingBlock"]: padding, | ||
| [horizontal ? "overflowX" : "overflowY"]: "auto" | ||
| } | ||
| }); | ||
| }, | ||
| getItemProps(props2) { | ||
| const isInView = context.get("slidesInView").includes(props2.index); | ||
| return normalize.element({ | ||
| ...parts.item.attrs, | ||
| id: getItemId(scope, props2.index), | ||
| dir: prop("dir"), | ||
| role: "group", | ||
| "data-index": props2.index, | ||
| "data-inview": dataAttr(isInView), | ||
| "aria-roledescription": "slide", | ||
| "data-orientation": prop("orientation"), | ||
| "aria-label": translations.item(props2.index, prop("slideCount")), | ||
| "aria-hidden": ariaAttr(!isInView), | ||
| style: { | ||
| flex: "0 0 auto", | ||
| [horizontal ? "maxWidth" : "maxHeight"]: "100%", | ||
| scrollSnapAlign: (() => { | ||
| const snapAlign = props2.snapAlign ?? "start"; | ||
| const slidesPerMove = prop("slidesPerMove"); | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(prop("slidesPerPage")) : slidesPerMove; | ||
| const shouldSnap = (props2.index + perMove) % perMove === 0; | ||
| return shouldSnap ? snapAlign : void 0; | ||
| })() | ||
| } | ||
| }); | ||
| }, | ||
| getControlProps() { | ||
| return normalize.element({ | ||
| ...parts.control.attrs, | ||
| "data-orientation": prop("orientation") | ||
| }); | ||
| }, | ||
| getPrevTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.prevTrigger.attrs, | ||
| id: getPrevTriggerId(scope), | ||
| type: "button", | ||
| disabled: !canScrollPrev, | ||
| dir: prop("dir"), | ||
| "aria-label": translations.prevTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": getItemGroupId(scope), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.PREV", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getNextTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.nextTrigger.attrs, | ||
| dir: prop("dir"), | ||
| id: getNextTriggerId(scope), | ||
| type: "button", | ||
| "aria-label": translations.nextTrigger, | ||
| "data-orientation": prop("orientation"), | ||
| "aria-controls": getItemGroupId(scope), | ||
| disabled: !canScrollNext, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: "PAGE.NEXT", src: "trigger" }); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorGroupProps() { | ||
| return normalize.element({ | ||
| ...parts.indicatorGroup.attrs, | ||
| dir: prop("dir"), | ||
| id: getIndicatorGroupId(scope), | ||
| "data-orientation": prop("orientation"), | ||
| onKeyDown(event) { | ||
| if (event.defaultPrevented) return; | ||
| const src = "indicator"; | ||
| const keyMap = { | ||
| ArrowDown(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowUp(event2) { | ||
| if (horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowRight(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.NEXT", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| ArrowLeft(event2) { | ||
| if (!horizontal) return; | ||
| send({ type: "PAGE.PREV", src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| Home(event2) { | ||
| send({ type: "PAGE.SET", index: 0, src }); | ||
| event2.preventDefault(); | ||
| }, | ||
| End(event2) { | ||
| send({ type: "PAGE.SET", index: pageSnapPoints.length - 1, src }); | ||
| event2.preventDefault(); | ||
| } | ||
| }; | ||
| const key = getEventKey(event, { | ||
| dir: prop("dir"), | ||
| orientation: prop("orientation") | ||
| }); | ||
| const exec = keyMap[key]; | ||
| exec?.(event); | ||
| } | ||
| }); | ||
| }, | ||
| getIndicatorProps(props2) { | ||
| return normalize.button({ | ||
| ...parts.indicator.attrs, | ||
| dir: prop("dir"), | ||
| id: getIndicatorId(scope, props2.index), | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-index": props2.index, | ||
| "data-readonly": dataAttr(props2.readOnly), | ||
| "data-current": dataAttr(props2.index === page), | ||
| "aria-label": translations.indicator(props2.index), | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| if (props2.readOnly) return; | ||
| send({ type: "PAGE.SET", index: props2.index, src: "indicator" }); | ||
| } | ||
| }); | ||
| }, | ||
| getAutoplayTriggerProps() { | ||
| return normalize.button({ | ||
| ...parts.autoplayTrigger.attrs, | ||
| type: "button", | ||
| "data-orientation": prop("orientation"), | ||
| "data-pressed": dataAttr(isPlaying), | ||
| "aria-label": isPlaying ? translations.autoplayStop : translations.autoplayStart, | ||
| onClick(event) { | ||
| if (event.defaultPrevented) return; | ||
| send({ type: isPlaying ? "AUTOPLAY.PAUSE" : "AUTOPLAY.START" }); | ||
| } | ||
| }); | ||
| }, | ||
| getProgressTextProps() { | ||
| return normalize.element({ | ||
| ...parts.progressText.attrs | ||
| }); | ||
| } | ||
| }; | ||
| } | ||
| var machine = createMachine({ | ||
| props({ props: props2 }) { | ||
| ensureProps(props2, ["slideCount"], "carousel"); | ||
| return { | ||
| dir: "ltr", | ||
| defaultPage: 0, | ||
| orientation: "horizontal", | ||
| snapType: "mandatory", | ||
| loop: !!props2.autoplay, | ||
| slidesPerPage: 1, | ||
| slidesPerMove: "auto", | ||
| spacing: "0px", | ||
| autoplay: false, | ||
| allowMouseDrag: false, | ||
| inViewThreshold: 0.6, | ||
| autoSize: false, | ||
| ...props2, | ||
| translations: { | ||
| nextTrigger: "Next slide", | ||
| prevTrigger: "Previous slide", | ||
| indicator: (index) => `Go to slide ${index + 1}`, | ||
| item: (index, count) => `${index + 1} of ${count}`, | ||
| autoplayStart: "Start slide rotation", | ||
| autoplayStop: "Stop slide rotation", | ||
| progressText: ({ page, totalPages }) => `${page} / ${totalPages}`, | ||
| ...props2.translations | ||
| } | ||
| }; | ||
| }, | ||
| refs() { | ||
| return { | ||
| timeoutRef: void 0 | ||
| }; | ||
| }, | ||
| initialState({ prop }) { | ||
| return prop("autoplay") ? "autoplay" : "idle"; | ||
| }, | ||
| context({ prop, bindable, getContext }) { | ||
| return { | ||
| page: bindable(() => ({ | ||
| defaultValue: prop("defaultPage"), | ||
| value: prop("page"), | ||
| onChange(page) { | ||
| const ctx = getContext(); | ||
| const pageSnapPoints = ctx.get("pageSnapPoints"); | ||
| prop("onPageChange")?.({ page, pageSnapPoint: pageSnapPoints[page] }); | ||
| } | ||
| })), | ||
| pageSnapPoints: bindable(() => { | ||
| return { | ||
| defaultValue: prop("autoSize") ? Array.from({ length: prop("slideCount") }, (_, i) => i) : getPageSnapPoints(prop("slideCount"), prop("slidesPerMove"), prop("slidesPerPage")) | ||
| }; | ||
| }), | ||
| slidesInView: bindable(() => ({ | ||
| defaultValue: [] | ||
| })) | ||
| }; | ||
| }, | ||
| computed: { | ||
| isRtl: ({ prop }) => prop("dir") === "rtl", | ||
| isHorizontal: ({ prop }) => prop("orientation") === "horizontal", | ||
| canScrollNext: ({ prop, context }) => prop("loop") || context.get("page") < context.get("pageSnapPoints").length - 1, | ||
| canScrollPrev: ({ prop, context }) => prop("loop") || context.get("page") > 0, | ||
| autoplayInterval: ({ prop }) => { | ||
| const autoplay = prop("autoplay"); | ||
| return isObject(autoplay) ? autoplay.delay : 4e3; | ||
| } | ||
| }, | ||
| watch({ track, action, context, prop, send }) { | ||
| track([() => prop("slidesPerPage"), () => prop("slidesPerMove")], () => { | ||
| action(["setSnapPoints"]); | ||
| }); | ||
| track([() => context.get("page")], () => { | ||
| action(["scrollToPage", "focusIndicatorEl"]); | ||
| }); | ||
| track([() => prop("orientation"), () => prop("autoSize"), () => prop("dir")], () => { | ||
| action(["setSnapPoints", "scrollToPage"]); | ||
| }); | ||
| track([() => prop("slideCount")], () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.count" }); | ||
| }); | ||
| track([() => !!prop("autoplay")], () => { | ||
| send({ type: prop("autoplay") ? "AUTOPLAY.START" : "AUTOPLAY.PAUSE", src: "autoplay.prop.change" }); | ||
| }); | ||
| }, | ||
| on: { | ||
| "PAGE.NEXT": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| target: "idle", | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "SNAP.REFRESH": { | ||
| actions: ["setSnapPoints", "clampPage"] | ||
| }, | ||
| "PAGE.SCROLL": { | ||
| actions: ["scrollToPage"] | ||
| } | ||
| }, | ||
| effects: ["trackSlideMutation", "trackSlideIntersections", "trackSlideResize"], | ||
| entry: ["setSnapPoints", "setPage"], | ||
| exit: ["clearScrollEndTimer"], | ||
| states: { | ||
| idle: { | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.START": { | ||
| target: "autoplay", | ||
| actions: ["invokeAutoplayStart"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| }, | ||
| "VIEWPORT.FOCUS": { | ||
| target: "focus" | ||
| } | ||
| } | ||
| }, | ||
| focus: { | ||
| effects: ["trackKeyboardScroll"], | ||
| on: { | ||
| "VIEWPORT.BLUR": { | ||
| target: "idle" | ||
| }, | ||
| "PAGE.NEXT": { | ||
| actions: ["clearScrollEndTimer", "setNextPage"] | ||
| }, | ||
| "PAGE.PREV": { | ||
| actions: ["clearScrollEndTimer", "setPrevPage"] | ||
| }, | ||
| "PAGE.SET": { | ||
| actions: ["clearScrollEndTimer", "setPage"] | ||
| }, | ||
| "INDEX.SET": { | ||
| actions: ["clearScrollEndTimer", "setMatchingPage"] | ||
| }, | ||
| "USER.SCROLL": { | ||
| target: "userScroll" | ||
| } | ||
| } | ||
| }, | ||
| dragging: { | ||
| effects: ["trackPointerMove"], | ||
| entry: ["disableScrollSnap"], | ||
| on: { | ||
| DRAGGING: { | ||
| actions: ["scrollSlides", "invokeDragging"] | ||
| }, | ||
| "DRAGGING.END": { | ||
| target: "idle", | ||
| actions: ["endDragging", "invokeDraggingEnd"] | ||
| } | ||
| } | ||
| }, | ||
| userScroll: { | ||
| effects: ["trackScroll"], | ||
| on: { | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "SCROLL.END": [ | ||
| { | ||
| guard: "isFocused", | ||
| target: "focus", | ||
| actions: ["setClosestPage"] | ||
| }, | ||
| { | ||
| target: "idle", | ||
| actions: ["setClosestPage"] | ||
| } | ||
| ] | ||
| } | ||
| }, | ||
| autoplay: { | ||
| effects: ["trackDocumentVisibility", "trackScroll", "autoUpdateSlide"], | ||
| exit: ["invokeAutoplayEnd"], | ||
| on: { | ||
| "AUTOPLAY.TICK": { | ||
| actions: ["setNextPage", "invokeAutoplay"] | ||
| }, | ||
| "DRAGGING.START": { | ||
| target: "dragging", | ||
| actions: ["invokeDragStart"] | ||
| }, | ||
| "AUTOPLAY.PAUSE": { | ||
| target: "idle" | ||
| } | ||
| } | ||
| } | ||
| }, | ||
| implementations: { | ||
| guards: { | ||
| isFocused: ({ scope }) => scope.isActiveElement(getItemGroupEl(scope)) | ||
| }, | ||
| effects: { | ||
| autoUpdateSlide({ computed, send }) { | ||
| const id = setInterval(() => { | ||
| send({ | ||
| type: computed("canScrollNext") ? "AUTOPLAY.TICK" : "AUTOPLAY.PAUSE", | ||
| src: "autoplay.interval" | ||
| }); | ||
| }, computed("autoplayInterval")); | ||
| return () => clearInterval(id); | ||
| }, | ||
| trackSlideMutation({ scope, send }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const win = scope.getWin(); | ||
| const observer = new win.MutationObserver(() => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.mutation" }); | ||
| syncTabIndex(scope); | ||
| }); | ||
| syncTabIndex(scope); | ||
| observer.observe(el, { childList: true, subtree: true }); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackSlideResize({ scope, send }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const exec = () => { | ||
| send({ type: "SNAP.REFRESH", src: "slide.resize" }); | ||
| }; | ||
| raf(() => { | ||
| exec(); | ||
| raf(() => { | ||
| send({ type: "PAGE.SCROLL", instant: true }); | ||
| }); | ||
| }); | ||
| const itemEls = getItemEls(scope); | ||
| itemEls.forEach(exec); | ||
| const cleanups = itemEls.map((el2) => resizeObserverBorderBox.observe(el2, exec)); | ||
| return callAll(...cleanups); | ||
| }, | ||
| trackSlideIntersections({ scope, prop, context }) { | ||
| const el = getItemGroupEl(scope); | ||
| const win = scope.getWin(); | ||
| const observer = new win.IntersectionObserver( | ||
| (entries) => { | ||
| const slidesInView = entries.reduce((acc, entry) => { | ||
| const target = entry.target; | ||
| const index = Number(target.dataset.index ?? "-1"); | ||
| if (index == null || Number.isNaN(index) || index === -1) return acc; | ||
| return entry.isIntersecting ? add(acc, index) : remove(acc, index); | ||
| }, context.get("slidesInView")); | ||
| context.set("slidesInView", uniq(slidesInView)); | ||
| }, | ||
| { | ||
| root: el, | ||
| threshold: prop("inViewThreshold") | ||
| } | ||
| ); | ||
| getItemEls(scope).forEach((slide) => observer.observe(slide)); | ||
| return () => observer.disconnect(); | ||
| }, | ||
| trackScroll({ send, refs, scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const onScroll = () => { | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| refs.set( | ||
| "timeoutRef", | ||
| setTimeout(() => { | ||
| send({ type: "SCROLL.END" }); | ||
| }, 150) | ||
| ); | ||
| }; | ||
| return addDomEvent(el, "scroll", onScroll, { passive: true }); | ||
| }, | ||
| trackDocumentVisibility({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| const onVisibilityChange = () => { | ||
| if (doc.visibilityState === "visible") return; | ||
| send({ type: "AUTOPLAY.PAUSE", src: "doc.hidden" }); | ||
| }; | ||
| return addDomEvent(doc, "visibilitychange", onVisibilityChange); | ||
| }, | ||
| trackPointerMove({ scope, send }) { | ||
| const doc = scope.getDoc(); | ||
| return trackPointerMove(doc, { | ||
| onPointerMove({ event }) { | ||
| send({ type: "DRAGGING", left: -event.movementX, top: -event.movementY }); | ||
| }, | ||
| onPointerUp() { | ||
| send({ type: "DRAGGING.END" }); | ||
| } | ||
| }); | ||
| }, | ||
| trackKeyboardScroll({ scope, send, context }) { | ||
| const win = scope.getWin(); | ||
| const onKeyDown = (event) => { | ||
| switch (event.key) { | ||
| case "ArrowRight": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.NEXT" }); | ||
| break; | ||
| case "ArrowLeft": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.PREV" }); | ||
| break; | ||
| case "Home": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: 0 }); | ||
| break; | ||
| case "End": | ||
| event.preventDefault(); | ||
| send({ type: "PAGE.SET", index: context.get("pageSnapPoints").length - 1 }); | ||
| } | ||
| }; | ||
| return addDomEvent(win, "keydown", onKeyDown, { capture: true }); | ||
| } | ||
| }, | ||
| actions: { | ||
| clearScrollEndTimer({ refs }) { | ||
| if (refs.get("timeoutRef") == null) return; | ||
| clearTimeout(refs.get("timeoutRef")); | ||
| refs.set("timeoutRef", void 0); | ||
| }, | ||
| scrollToPage({ context, event, scope, computed, flush }) { | ||
| const behavior = event.instant ? "instant" : "smooth"; | ||
| const index = clampValue(event.index ?? context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const axis = computed("isHorizontal") ? "left" : "top"; | ||
| flush(() => { | ||
| el.scrollTo({ [axis]: context.get("pageSnapPoints")[index], behavior }); | ||
| }); | ||
| }, | ||
| setClosestPage({ context, scope, computed }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollPosition = computed("isHorizontal") ? el.scrollLeft : el.scrollTop; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - scrollPosition) < 1); | ||
| if (page === -1) return; | ||
| context.set("page", page); | ||
| }, | ||
| setNextPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = nextIndex(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setPrevPage({ context, prop, state }) { | ||
| const loop = state.matches("autoplay") || prop("loop"); | ||
| const page = prevIndex(context.get("pageSnapPoints"), context.get("page"), { loop }); | ||
| context.set("page", page); | ||
| }, | ||
| setMatchingPage({ context, event, computed, scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const snapPoint = findSnapPoint( | ||
| el, | ||
| computed("isHorizontal") ? "x" : "y", | ||
| (node) => node.dataset.index === event.index.toString() | ||
| ); | ||
| if (snapPoint == null) return; | ||
| const page = context.get("pageSnapPoints").findIndex((point) => Math.abs(point - snapPoint) < 1); | ||
| context.set("page", page); | ||
| }, | ||
| setPage({ context, event }) { | ||
| const page = event.index ?? context.get("page"); | ||
| context.set("page", page); | ||
| }, | ||
| clampPage({ context }) { | ||
| const index = clampValue(context.get("page"), 0, context.get("pageSnapPoints").length - 1); | ||
| context.set("page", index); | ||
| }, | ||
| setSnapPoints({ context, computed, scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const scrollSnapPoints = getScrollSnapPositions(el); | ||
| context.set("pageSnapPoints", computed("isHorizontal") ? scrollSnapPoints.x : scrollSnapPoints.y); | ||
| }, | ||
| disableScrollSnap({ scope }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const styles = getComputedStyle(el); | ||
| el.dataset.scrollSnapType = styles.getPropertyValue("scroll-snap-type"); | ||
| el.style.setProperty("scroll-snap-type", "none"); | ||
| }, | ||
| scrollSlides({ scope, event }) { | ||
| const el = getItemGroupEl(scope); | ||
| el?.scrollBy({ left: event.left, top: event.top, behavior: "instant" }); | ||
| }, | ||
| endDragging({ scope, context, computed }) { | ||
| const el = getItemGroupEl(scope); | ||
| if (!el) return; | ||
| const isHorizontal = computed("isHorizontal"); | ||
| const scrollPos = isHorizontal ? el.scrollLeft : el.scrollTop; | ||
| const snapPoints = context.get("pageSnapPoints"); | ||
| const closest = snapPoints.reduce((closest2, curr) => { | ||
| return Math.abs(curr - scrollPos) < Math.abs(closest2 - scrollPos) ? curr : closest2; | ||
| }, snapPoints[0]); | ||
| raf(() => { | ||
| el.scrollTo({ | ||
| left: isHorizontal ? closest : el.scrollLeft, | ||
| top: isHorizontal ? el.scrollTop : closest, | ||
| behavior: "smooth" | ||
| }); | ||
| context.set("page", snapPoints.indexOf(closest)); | ||
| const scrollSnapType = el.dataset.scrollSnapType; | ||
| if (scrollSnapType) { | ||
| el.style.setProperty("scroll-snap-type", scrollSnapType); | ||
| delete el.dataset.scrollSnapType; | ||
| } | ||
| }); | ||
| }, | ||
| focusIndicatorEl({ context, event, scope }) { | ||
| if (event.src !== "indicator") return; | ||
| const el = getIndicatorEl(scope, context.get("page")); | ||
| if (!el) return; | ||
| raf(() => el.focus({ preventScroll: true })); | ||
| }, | ||
| invokeDragStart({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.start", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDragging({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging", isDragging: true, page: context.get("page") }); | ||
| }, | ||
| invokeDraggingEnd({ context, prop }) { | ||
| prop("onDragStatusChange")?.({ type: "dragging.end", isDragging: false, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplay({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayStart({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.start", isPlaying: true, page: context.get("page") }); | ||
| }, | ||
| invokeAutoplayEnd({ context, prop }) { | ||
| prop("onAutoplayStatusChange")?.({ type: "autoplay.stop", isPlaying: false, page: context.get("page") }); | ||
| } | ||
| } | ||
| } | ||
| }); | ||
| function getPageSnapPoints(totalSlides, slidesPerMove, slidesPerPage) { | ||
| if (totalSlides == null || slidesPerPage <= 0) { | ||
| return []; | ||
| } | ||
| const snapPoints = []; | ||
| const perMove = slidesPerMove === "auto" ? Math.floor(slidesPerPage) : slidesPerMove; | ||
| if (perMove <= 0) { | ||
| return []; | ||
| } | ||
| for (let i = 0; i < totalSlides; i += perMove) { | ||
| if (i + slidesPerPage > totalSlides) break; | ||
| snapPoints.push(i); | ||
| } | ||
| return snapPoints; | ||
| } | ||
| var props = createProps()([ | ||
| "dir", | ||
| "getRootNode", | ||
| "id", | ||
| "ids", | ||
| "loop", | ||
| "page", | ||
| "defaultPage", | ||
| "onPageChange", | ||
| "orientation", | ||
| "slideCount", | ||
| "slidesPerPage", | ||
| "slidesPerMove", | ||
| "spacing", | ||
| "padding", | ||
| "autoplay", | ||
| "allowMouseDrag", | ||
| "inViewThreshold", | ||
| "translations", | ||
| "snapType", | ||
| "autoSize", | ||
| "onDragStatusChange", | ||
| "onAutoplayStatusChange" | ||
| ]); | ||
| var splitProps = createSplitProps(props); | ||
| var indicatorProps = createProps()(["index", "readOnly"]); | ||
| var splitIndicatorProps = createSplitProps(indicatorProps); | ||
| var itemProps = createProps()(["index", "snapAlign"]); | ||
| var splitItemProps = createSplitProps(itemProps); | ||
| export { anatomy, connect, indicatorProps, itemProps, machine, props, splitIndicatorProps, splitItemProps, splitProps }; |
+18
-8
| { | ||
| "name": "@zag-js/carousel", | ||
| "version": "1.34.1", | ||
| "version": "1.35.0", | ||
| "description": "Core logic for the carousel widget implemented as a state machine", | ||
@@ -30,8 +30,8 @@ "keywords": [ | ||
| "dependencies": { | ||
| "@zag-js/anatomy": "1.34.1", | ||
| "@zag-js/core": "1.34.1", | ||
| "@zag-js/types": "1.34.1", | ||
| "@zag-js/dom-query": "1.34.1", | ||
| "@zag-js/scroll-snap": "1.34.1", | ||
| "@zag-js/utils": "1.34.1" | ||
| "@zag-js/anatomy": "1.35.0", | ||
| "@zag-js/core": "1.35.0", | ||
| "@zag-js/types": "1.35.0", | ||
| "@zag-js/dom-query": "1.35.0", | ||
| "@zag-js/scroll-snap": "1.35.0", | ||
| "@zag-js/utils": "1.35.0" | ||
| }, | ||
@@ -41,3 +41,3 @@ "devDependencies": { | ||
| }, | ||
| "clean-package": "../../../clean-package.config.json", | ||
| "clean-package": "./clean-package.config.json", | ||
| "module": "dist/index.mjs", | ||
@@ -56,2 +56,12 @@ "types": "dist/index.d.ts", | ||
| }, | ||
| "./anatomy": { | ||
| "import": { | ||
| "types": "./dist/carousel.anatomy.d.mts", | ||
| "default": "./dist/carousel.anatomy.mjs" | ||
| }, | ||
| "require": { | ||
| "types": "./dist/carousel.anatomy.d.ts", | ||
| "default": "./dist/carousel.anatomy.js" | ||
| } | ||
| }, | ||
| "./package.json": "./package.json" | ||
@@ -58,0 +68,0 @@ }, |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
93646
21.55%31
342.86%2208
18.01%1
Infinity%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated
Updated