{"version":3,"file":"carousel.mjs","sources":["../../src/strings/carouselString.ts","../../src/strings/carouselComponent.ts","../../src/components/carousel.ts"],"sourcesContent":["/** @type {string} */\nconst carouselString = \"carousel\";\nexport default carouselString;\n","/** @type {string} */\nconst carouselComponent = \"Carousel\";\nexport default carouselComponent;\n","/* Native JavaScript for Bootstrap 5 | Carousel\n----------------------------------------------- */\nimport {\n addClass,\n closest,\n createCustomEvent,\n dispatchEvent,\n DragEvent,\n dragstartEvent,\n emulateTransitionEnd,\n getAttribute,\n getDocument,\n getElementsByClassName,\n getElementTransitionDuration,\n getInstance,\n hasClass,\n isElementInScrollRange,\n isRTL,\n keyArrowLeft,\n keyArrowRight,\n keydownEvent,\n matches,\n mouseclickEvent,\n mouseenterEvent,\n mouseleaveEvent,\n ObjectAssign,\n passiveHandler,\n pointerdownEvent,\n PointerEvent,\n pointermoveEvent,\n pointerupEvent,\n querySelector,\n querySelectorAll,\n reflow,\n removeClass,\n Timer,\n TouchEvent,\n touchstartEvent,\n} from \"@thednp/shorty\";\n\nimport { addListener, removeListener } from \"@thednp/event-listener\";\n\nimport activeClass from \"~/strings/activeClass\";\nimport dataBsTarget from \"~/strings/dataBsTarget\";\nimport carouselString from \"~/strings/carouselString\";\nimport carouselComponent from \"~/strings/carouselComponent\";\nimport getTargetElement from \"~/util/getTargetElement\";\nimport isDisabled from \"~/util/isDisabled\";\nimport BaseComponent from \"./base-component\";\nimport type { CarouselEvent, CarouselOptions } from \"~/interface/carousel\";\n\ntype CarouselEventProperties = {\n relatedTarget: EventTarget & HTMLElement;\n from: number;\n to: number;\n direction: \"left\" | \"right\";\n};\n\n// CAROUSEL PRIVATE GC\n// ===================\nconst carouselSelector = `[data-bs-ride=\"${carouselString}\"]`;\nconst carouselItem = `${carouselString}-item`;\nconst dataBsSlideTo = \"data-bs-slide-to\";\nconst dataBsSlide = \"data-bs-slide\";\nconst pausedClass = \"paused\";\n\nconst carouselDefaults: CarouselOptions = {\n pause: \"hover\",\n keyboard: false,\n touch: true,\n interval: 5000,\n};\n\n/**\n * Static method which returns an existing `Carousel` instance associated\n * to a target `Element`.\n */\nconst getCarouselInstance = (element: Element) =>\n getInstance(element, carouselComponent);\n\n/**\n * A `Carousel` initialization callback.\n */\nconst carouselInitCallback = (element: Element) => new Carousel(element);\n\nlet startX = 0;\nlet currentX = 0;\nlet endX = 0;\n\n// CAROUSEL CUSTOM EVENTS\n// ======================\nconst carouselSlideEvent = createCustomEvent<\n CarouselEventProperties,\n CarouselEvent\n>(`slide.bs.${carouselString}`);\nconst carouselSlidEvent = createCustomEvent<\n CarouselEventProperties,\n CarouselEvent\n>(`slid.bs.${carouselString}`);\n\n// CAROUSEL EVENT HANDLERS\n// =======================\n/**\n * The `transitionend` event listener of the `Carousel`.\n *\n * @param self the `Carousel` instance\n */\nconst carouselTransitionEndHandler = (self: Carousel) => {\n const { index, direction, element, slides, options } = self;\n\n // istanbul ignore else @preserve\n if (self.isAnimating) {\n const activeItem = getActiveIndex(self);\n const orientation = direction === \"left\" ? \"next\" : \"prev\";\n const directionClass = direction === \"left\" ? \"start\" : \"end\";\n\n addClass(slides[index], activeClass);\n removeClass(slides[index], `${carouselItem}-${orientation}`);\n removeClass(slides[index], `${carouselItem}-${directionClass}`);\n\n removeClass(slides[activeItem], activeClass);\n removeClass(slides[activeItem], `${carouselItem}-${directionClass}`);\n\n dispatchEvent(element, carouselSlidEvent);\n Timer.clear(element, dataBsSlide);\n\n // must check if a previous instance is disposed\n if (\n self.cycle && !getDocument(element).hidden && options.interval &&\n !self.isPaused\n ) {\n self.cycle();\n }\n }\n};\n\n/**\n * Handles the `mouseenter` events when *options.pause*\n * is set to `hover`.\n */\nfunction carouselPauseHandler(this: HTMLElement) {\n const self = getCarouselInstance(this);\n // istanbul ignore else @preserve\n if (self && !self.isPaused && !Timer.get(this, pausedClass)) {\n addClass(this, pausedClass);\n }\n}\n\n/**\n * Handles the `mouseleave` events when *options.pause*\n * is set to `hover`.\n */\nfunction carouselResumeHandler(this: HTMLElement) {\n const self = getCarouselInstance(this);\n // istanbul ignore else @preserve\n if (self && self.isPaused && !Timer.get(this, pausedClass)) {\n self.cycle();\n }\n}\n\n/**\n * Handles the `click` event for the `Carousel` indicators.\n *\n * @param e the `Event` object\n */\nfunction carouselIndicatorHandler(this: HTMLElement, e: MouseEvent) {\n e.preventDefault();\n const element = closest(this, carouselSelector) || getTargetElement(this);\n const self = element && getCarouselInstance(element);\n\n // istanbul ignore if @preserve\n if (isDisabled(this)) return;\n // istanbul ignore if @preserve\n if (!self || self.isAnimating) return;\n\n const newIndex = +(\n getAttribute(this, dataBsSlideTo) ||\n // istanbul ignore next @preserve\n 0\n );\n\n // istanbul ignore else @preserve\n if (\n this &&\n !hasClass(this, activeClass) && // event target is not active\n !Number.isNaN(newIndex)\n ) {\n // AND has the specific attribute\n self.to(newIndex); // do the slide\n }\n}\n\n/**\n * Handles the `click` event for the `Carousel` arrows.\n *\n * @param e the `Event` object\n */\nfunction carouselControlsHandler(this: HTMLElement, e: MouseEvent) {\n e.preventDefault();\n const element = closest(this, carouselSelector) || getTargetElement(this);\n const self = element && getCarouselInstance(element);\n\n // istanbul ignore if @preserve\n if (isDisabled(this)) return;\n // istanbul ignore if @preserve\n if (!self || self.isAnimating) return;\n\n const orientation = getAttribute(this, dataBsSlide);\n\n // istanbul ignore else @preserve\n if (orientation === \"next\") {\n self.next();\n } else if (orientation === \"prev\") {\n self.prev();\n }\n}\n\n/**\n * Handles the keyboard `keydown` event for the visible `Carousel` elements.\n *\n * @param e the `Event` object\n */\nconst carouselKeyHandler = (\n { code, target }: KeyboardEvent & { target: Node },\n) => {\n const doc = getDocument(target);\n const [element] = [...querySelectorAll(carouselSelector, doc)]\n .filter((x) => isElementInScrollRange(x));\n const self = getCarouselInstance(element);\n\n // istanbul ignore next @preserve\n if (\n !self || self.isAnimating || /textarea|input|select/i.test(target.nodeName)\n ) return;\n\n const RTL = isRTL(element);\n const arrowKeyNext = !RTL ? keyArrowRight : keyArrowLeft;\n const arrowKeyPrev = !RTL ? keyArrowLeft : keyArrowRight;\n\n // istanbul ignore else @preserve\n if (code === arrowKeyPrev) self.prev();\n else if (code === arrowKeyNext) self.next();\n};\n\n// CAROUSEL TOUCH HANDLERS\n// =======================\n/**\n * Prevents the `touchstart` and `dragstart` events for the `Carousel` element.\n *\n * @param e the `Event` object\n */\nfunction carouselDragHandler(\n this: T,\n e: Event & (DragEvent | TouchEvent),\n) {\n const { target } = e;\n const self = getCarouselInstance(this);\n\n // istanbul ignore next @preserve\n if (\n self &&\n self.isTouch &&\n ((self.indicator && !self.indicator.contains(target)) ||\n !self.controls.includes(target))\n ) {\n e.stopImmediatePropagation();\n e.stopPropagation();\n e.preventDefault();\n }\n}\n\n// CAROUSEL POINTER HANDLERS\n// =========================\n/**\n * Handles the `pointerdown` event for the `Carousel` element.\n *\n * @param e the `Event` object\n */\nfunction carouselPointerDownHandler(\n this: HTMLElement,\n e: PointerEvent,\n) {\n const { target } = e;\n const self = getCarouselInstance(this);\n\n // istanbul ignore else @preserve\n if (!self || self.isAnimating || self.isTouch) return;\n\n // filter pointer event on controls & indicators\n const { controls, indicators } = self;\n // istanbul ignore else @preserve\n if (\n ![...controls, ...indicators].every((el) =>\n el === target || el.contains(target)\n )\n ) {\n startX = e.pageX;\n\n // istanbul ignore else @preserve\n if (this.contains(target)) {\n self.isTouch = true;\n toggleCarouselTouchHandlers(self, true);\n }\n }\n}\n\n/**\n * Handles the `pointermove` event for the `Carousel` element.\n *\n * @param e\n */\nconst carouselPointerMoveHandler = (e: PointerEvent) => {\n currentX = e.pageX;\n};\n\n/**\n * Handles the `pointerup` event for the `Carousel` element.\n *\n * @param e\n */\nconst carouselPointerUpHandler = (e: PointerEvent) => {\n const { target } = e;\n const doc = getDocument(target);\n const self = [...querySelectorAll(carouselSelector, doc)]\n .map((c) => getCarouselInstance(c) as Carousel)\n .find((i) => i.isTouch) as Carousel;\n\n // istanbul ignore if @preserve\n if (!self) return;\n\n const { element, index } = self;\n const RTL = isRTL(element);\n endX = e.pageX;\n\n self.isTouch = false;\n toggleCarouselTouchHandlers(self);\n\n if (\n !doc.getSelection()?.toString().length &&\n element.contains(target) &&\n Math.abs(startX - endX) > 120\n ) {\n // determine next index to slide to\n // istanbul ignore else @preserve\n if (currentX < startX) {\n self.to(index + (RTL ? -1 : 1));\n } else if (currentX > startX) {\n self.to(index + (RTL ? 1 : -1));\n }\n }\n\n // reset pointer position\n startX = 0;\n currentX = 0;\n endX = 0;\n};\n\n// CAROUSEL PRIVATE METHODS\n// ========================\n/**\n * Sets active indicator for the `Carousel` instance.\n *\n * @param self the `Carousel` instance\n * @param index the index of the new active indicator\n */\nconst activateCarouselIndicator = (self: Carousel, index: number) => {\n const { indicators } = self;\n [...indicators].forEach((x) => removeClass(x, activeClass));\n\n // istanbul ignore else @preserve\n if (self.indicators[index]) addClass(indicators[index], activeClass);\n};\n\n/**\n * Toggles the pointer event listeners for a given `Carousel` instance.\n *\n * @param self the `Carousel` instance\n * @param add when `TRUE` event listeners are added\n */\nconst toggleCarouselTouchHandlers = (self: Carousel, add?: boolean) => {\n const { element } = self;\n const action = add ? addListener : removeListener;\n action(\n getDocument(element),\n pointermoveEvent,\n carouselPointerMoveHandler,\n passiveHandler,\n );\n action(\n getDocument(element),\n pointerupEvent,\n carouselPointerUpHandler,\n passiveHandler,\n );\n};\n\n/**\n * Returns the index of the current active item.\n *\n * @param self the `Carousel` instance\n * @returns the query result\n */\nconst getActiveIndex = (self: Carousel) => {\n const { slides, element } = self;\n const activeItem = querySelector(\n `.${carouselItem}.${activeClass}`,\n element,\n );\n return activeItem ? [...slides].indexOf(activeItem) : -1;\n};\n\n// CAROUSEL DEFINITION\n// ===================\n/** Creates a new `Carousel` instance. */\nexport default class Carousel extends BaseComponent {\n static selector = carouselSelector;\n static init = carouselInitCallback;\n static getInstance = getCarouselInstance;\n declare element: HTMLElement;\n declare options: CarouselOptions;\n declare direction: \"right\" | \"left\";\n declare index: number;\n declare isTouch: boolean;\n declare slides: HTMLCollectionOf;\n declare controls: HTMLElement[];\n declare indicator: HTMLElement | null;\n declare indicators: HTMLElement[];\n\n /**\n * @param target mostly a `.carousel` element\n * @param config instance options\n */\n constructor(target: Element | string, config?: Partial) {\n super(target, config);\n\n // initialization element\n const { element } = this;\n\n // additional properties\n this.direction = isRTL(element) ? \"right\" : \"left\";\n this.isTouch = false;\n\n // carousel elements\n // a LIVE collection is prefferable\n this.slides = getElementsByClassName(carouselItem, element);\n const { slides } = this;\n\n // invalidate when not enough items\n // no need to go further\n if (slides.length < 2) return;\n\n const activeIndex = getActiveIndex(this);\n // recover item from disposed instance\n const transitionItem = [...slides].find((s) =>\n matches(s, `.${carouselItem}-next`)\n );\n this.index = activeIndex;\n\n // external controls must be within same document context\n const doc = getDocument(element);\n\n this.controls = [\n ...querySelectorAll(`[${dataBsSlide}]`, element),\n ...querySelectorAll(\n `[${dataBsSlide}][${dataBsTarget}=\"#${element.id}\"]`,\n doc,\n ),\n ].filter((c, i, ar) => i === ar.indexOf(c));\n\n this.indicator = querySelector(\n `.${carouselString}-indicators`,\n element,\n );\n\n // a LIVE collection is preffered\n this.indicators = [\n ...(this.indicator\n ? querySelectorAll(`[${dataBsSlideTo}]`, this.indicator)\n /* istanbul ignore next @preserve */ : []),\n ...querySelectorAll(\n `[${dataBsSlideTo}][${dataBsTarget}=\"#${element.id}\"]`,\n doc,\n ),\n ].filter((c, i, ar) => i === ar.indexOf(c));\n\n // set JavaScript and DATA API options\n const { options } = this;\n\n // don't use TRUE as interval, it's actually 0, use the default 5000ms better\n this.options.interval = options.interval === true\n ? carouselDefaults.interval\n : options.interval;\n\n // set first slide active if none\n // istanbul ignore next @preserve - impossible to test\n if (transitionItem) {\n this.index = [...slides].indexOf(transitionItem);\n } else if (activeIndex < 0) {\n this.index = 0;\n addClass(slides[0], activeClass);\n if (this.indicators.length) activateCarouselIndicator(this, 0);\n }\n\n // istanbul ignore else @preserve\n if (this.indicators.length) activateCarouselIndicator(this, this.index);\n\n // attach event handlers\n this._toggleEventListeners(true);\n\n // start to cycle if interval is set\n if (options.interval) this.cycle();\n }\n\n /**\n * Returns component name string.\n */\n get name() {\n return carouselComponent;\n }\n /**\n * Returns component default options.\n */\n get defaults() {\n return carouselDefaults;\n }\n\n /**\n * Check if instance is paused.\n */\n get isPaused() {\n return hasClass(this.element, pausedClass);\n }\n\n /**\n * Check if instance is animating.\n */\n get isAnimating() {\n return querySelector(\n `.${carouselItem}-next,.${carouselItem}-prev`,\n this.element,\n ) !== null;\n }\n\n // CAROUSEL PUBLIC METHODS\n // =======================\n /** Slide automatically through items. */\n cycle() {\n const { element, options, isPaused, index } = this;\n\n Timer.clear(element, carouselString);\n if (isPaused) {\n Timer.clear(element, pausedClass);\n removeClass(element, pausedClass);\n }\n\n Timer.set(\n element,\n () => {\n // it's very important to check self.element\n // where instance might have been disposed\n // istanbul ignore else @preserve\n if (\n this.element && !this.isPaused && !this.isTouch &&\n isElementInScrollRange(element)\n ) {\n this.to(index + 1);\n }\n },\n options.interval as number,\n carouselString,\n );\n }\n\n /** Pause the automatic cycle. */\n pause() {\n const { element, options } = this;\n // istanbul ignore else @preserve\n if (this.isPaused || !options.interval) return;\n\n addClass(element, pausedClass);\n Timer.set(\n element,\n () => {\n /* ESLint is now happy */\n },\n 1,\n pausedClass,\n );\n }\n\n /** Slide to the next item. */\n next() {\n // istanbul ignore else @preserve\n if (!this.isAnimating) {\n this.to(this.index + 1);\n }\n }\n\n /** Slide to the previous item. */\n prev() {\n // istanbul ignore else @preserve\n if (!this.isAnimating) {\n this.to(this.index - 1);\n }\n }\n\n /**\n * Jump to the item with the `idx` index.\n *\n * @param idx the index of the item to jump to\n */\n to(idx: number) {\n const { element, slides, options } = this;\n const activeItem = getActiveIndex(this);\n const RTL = isRTL(element);\n let next = idx;\n\n // when controled via methods, make sure to check again\n // first return if we're on the same item #227\n // `to()` must be SPAM protected by Timer\n if (\n this.isAnimating || activeItem === next ||\n Timer.get(element, dataBsSlide)\n ) return;\n\n // determine transition direction\n // istanbul ignore else @preserve\n if (\n activeItem < next || (activeItem === 0 && next === slides.length - 1)\n ) {\n this.direction = RTL ? \"right\" : \"left\"; // next\n } else if (\n activeItem > next || (activeItem === slides.length - 1 && next === 0)\n ) {\n this.direction = RTL ? \"left\" : \"right\"; // prev\n }\n const { direction } = this;\n\n // find the right next index\n if (next < 0) {\n next = slides.length - 1;\n } else if (next >= slides.length) {\n next = 0;\n }\n\n // orientation, class name, eventProperties\n const orientation = direction === \"left\" ? \"next\" : \"prev\";\n const directionClass = direction === \"left\" ? \"start\" : \"end\";\n\n const eventProperties = {\n relatedTarget: slides[next],\n from: activeItem,\n to: next,\n direction,\n };\n\n // update event properties\n ObjectAssign(carouselSlideEvent, eventProperties);\n ObjectAssign(carouselSlidEvent, eventProperties);\n\n // discontinue when prevented\n dispatchEvent(element, carouselSlideEvent);\n if (carouselSlideEvent.defaultPrevented) return;\n\n // update index\n this.index = next;\n activateCarouselIndicator(this, next);\n\n if (\n getElementTransitionDuration(slides[next]) &&\n hasClass(element, \"slide\")\n ) {\n Timer.set(\n element,\n () => {\n addClass(slides[next], `${carouselItem}-${orientation}`);\n reflow(slides[next]);\n addClass(slides[next], `${carouselItem}-${directionClass}`);\n addClass(slides[activeItem], `${carouselItem}-${directionClass}`);\n\n // the instance might get diposed mid-animation\n emulateTransitionEnd(\n slides[next],\n () =>\n this.slides && this.slides.length &&\n carouselTransitionEndHandler(this),\n );\n },\n 0,\n dataBsSlide,\n );\n } else {\n addClass(slides[next], activeClass);\n removeClass(slides[activeItem], activeClass);\n\n Timer.set(\n element,\n () => {\n Timer.clear(element, dataBsSlide);\n // check for element, might have been disposed\n // istanbul ignore else @preserve\n if (element && options.interval && !this.isPaused) {\n this.cycle();\n }\n\n dispatchEvent(element, carouselSlidEvent);\n },\n 0,\n dataBsSlide,\n );\n }\n }\n\n /**\n * Toggles all event listeners for the `Carousel` instance.\n *\n * @param add when `TRUE` event listeners are added\n */\n _toggleEventListeners = (add?: boolean) => {\n const { element, options, slides, controls, indicators } = this;\n const { touch, pause, interval, keyboard } = options;\n const action = add ? addListener : removeListener;\n\n if (pause && interval) {\n action(element, mouseenterEvent, carouselPauseHandler);\n action(element, mouseleaveEvent, carouselResumeHandler);\n }\n\n if (touch && slides.length > 2) {\n action(\n element,\n pointerdownEvent,\n carouselPointerDownHandler,\n passiveHandler,\n );\n action(element, touchstartEvent, carouselDragHandler, { passive: false });\n action(element, dragstartEvent, carouselDragHandler, { passive: false });\n }\n\n // istanbul ignore else @preserve\n if (controls.length) {\n controls.forEach((arrow) => {\n action(arrow, mouseclickEvent, carouselControlsHandler);\n });\n }\n\n // istanbul ignore else @preserve\n if (indicators.length) {\n indicators.forEach((indicator) => {\n action(indicator, mouseclickEvent, carouselIndicatorHandler);\n });\n }\n\n if (keyboard) {\n action(getDocument(element), keydownEvent, carouselKeyHandler);\n }\n };\n\n /** Remove `Carousel` component from target. */\n dispose() {\n const { isAnimating } = this;\n\n const clone = {\n ...this,\n isAnimating,\n };\n this._toggleEventListeners();\n super.dispose();\n\n // istanbul ignore next @preserve - impossible to test in playwright\n if (clone.isAnimating) {\n emulateTransitionEnd(clone.slides[clone.index], () => {\n carouselTransitionEndHandler(clone);\n });\n }\n }\n}\n"],"names":["carouselString","carouselComponent","carouselSelector","carouselItem","dataBsSlideTo","dataBsSlide","pausedClass","carouselDefaults","getCarouselInstance","element","getInstance","carouselInitCallback","Carousel","startX","currentX","endX","carouselSlideEvent","createCustomEvent","carouselSlidEvent","carouselTransitionEndHandler","self","index","direction","slides","options","activeItem","getActiveIndex","orientation","directionClass","addClass","activeClass","removeClass","dispatchEvent","Timer","getDocument","carouselPauseHandler","carouselResumeHandler","carouselIndicatorHandler","e","closest","getTargetElement","isDisabled","newIndex","getAttribute","hasClass","carouselControlsHandler","carouselKeyHandler","code","target","doc","querySelectorAll","x","isElementInScrollRange","RTL","isRTL","keyArrowRight","keyArrowLeft","carouselDragHandler","carouselPointerDownHandler","controls","indicators","el","toggleCarouselTouchHandlers","carouselPointerMoveHandler","carouselPointerUpHandler","c","i","activateCarouselIndicator","add","action","addListener","removeListener","pointermoveEvent","passiveHandler","pointerupEvent","querySelector","BaseComponent","config","getElementsByClassName","activeIndex","transitionItem","s","matches","dataBsTarget","ar","isPaused","idx","next","eventProperties","ObjectAssign","getElementTransitionDuration","reflow","emulateTransitionEnd","touch","pause","interval","keyboard","mouseenterEvent","mouseleaveEvent","pointerdownEvent","touchstartEvent","dragstartEvent","arrow","mouseclickEvent","indicator","keydownEvent","isAnimating","clone"],"mappings":"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"}