Files

1 line
34 KiB
Plaintext

{"version":3,"file":"carousel.mjs","names":["pkg.version"],"sources":["../../../src/strings/activeClass.ts","../../../src/strings/dataBsTarget.ts","../../../src/strings/carouselString.ts","../../../src/strings/carouselComponent.ts","../../../src/strings/dataBsParent.ts","../../../src/strings/dataBsContainer.ts","../../../src/util/getTargetElement.ts","../../../src/util/isDisabled.ts","../../../package.json","../../../src/version.ts","../../../src/components/base-component.ts","../../../src/components/carousel.ts"],"sourcesContent":["/**\n * Global namespace for most components active class.\n */\nconst activeClass = \"active\";\nexport default activeClass;\n","/**\n * Global namespace for most components `target` option.\n */\nconst dataBsTarget = \"data-bs-target\";\nexport default dataBsTarget;\n","/** @type {string} */\nconst carouselString = \"carousel\";\nexport default carouselString;\n","/** @type {string} */\nconst carouselComponent = \"Carousel\";\nexport default carouselComponent;\n","/**\n * Global namespace for most components `parent` option.\n */\nconst dataBsParent = \"data-bs-parent\";\nexport default dataBsParent;\n","/**\n * Global namespace for most components `container` option.\n */\nconst dataBsContainer = \"data-bs-container\";\nexport default dataBsContainer;\n","import {\n closest,\n getAttribute,\n getDocument,\n querySelector,\n} from \"@thednp/shorty\";\n\nimport dataBsTarget from \"../strings/dataBsTarget\";\nimport dataBsParent from \"../strings/dataBsParent\";\nimport dataBsContainer from \"../strings/dataBsContainer\";\n\n/**\n * Returns the `Element` that THIS one targets\n * via `data-bs-target`, `href`, `data-bs-parent` or `data-bs-container`.\n *\n * @param element the target element\n * @returns the query result\n */\nconst getTargetElement = <T extends Element = HTMLElement>(element: T) => {\n const targetAttr = [dataBsTarget, dataBsParent, dataBsContainer, \"href\"];\n const doc = getDocument(element);\n\n return targetAttr\n .map((att) => {\n const attValue = getAttribute(element, att);\n if (attValue) {\n // istanbul ignore next @preserve\n return att === dataBsParent\n ? closest<T>(element, attValue)\n : querySelector<T>(attValue, doc);\n }\n return null;\n })\n .filter((x) => x)[0];\n};\n\nexport default getTargetElement;\n","import { getAttribute, hasClass } from \"@thednp/shorty\";\n\n/**\n * Check if interactive element is disabled.\n * @param target either a `<button>` or an `<a>`\n * @returns whether the target is disabled\n */\nconst isDisabled = (target: Element) => {\n return hasClass(target, \"disabled\") ||\n getAttribute(target, \"disabled\") === \"true\";\n};\n\nexport default isDisabled;\n","","import pkg from \"../package.json\" with { type: \"json\" };\n\nconst Version = pkg.version;\n\nexport default Version;\n","/* Native JavaScript for Bootstrap 5 | Base Component\n----------------------------------------------------- */\nimport {\n Data,\n isElement,\n isString,\n normalizeOptions,\n ObjectKeys,\n querySelector,\n} from \"@thednp/shorty\";\n\nimport type { BaseOptions } from \"~/interface/baseComponent\";\nimport Version from \"~/version\";\n\n/** Returns a new `BaseComponent` instance. */\nexport default class BaseComponent {\n declare element: Element;\n declare options?: BaseOptions;\n\n /**\n * @param target `Element` or selector string\n * @param config component instance options\n */\n constructor(target: Element | string, config?: BaseOptions) {\n let element: Element | null;\n\n try {\n if (isElement(target)) {\n element = target as Element;\n } else if (isString(target)) {\n element = querySelector(target);\n // istanbul ignore else @preserve\n if (!element) throw Error(`\"${target}\" is not a valid selector.`);\n } else {\n throw Error(`your target is not an instance of HTMLElement.`);\n }\n } catch (e) {\n throw Error(`${this.name} Error: ${(e as Error).message}`);\n }\n\n const prevInstance = Data.get<typeof this>(element, this.name);\n /* istanbul ignore else @preserve */\n if (prevInstance) {\n // remove previously attached event listeners\n // to avoid memory leaks\n prevInstance._toggleEventListeners();\n }\n\n this.element = element;\n this.options = this.defaults && ObjectKeys(this.defaults).length\n ? normalizeOptions(element, this.defaults, config || {}, \"bs\")\n : /* istanbul ignore next @preserve */ {};\n\n Data.set(element, this.name, this);\n }\n\n // istanbul ignore next @preserve\n get version() {\n return Version;\n }\n\n // istanbul ignore next @preserve\n get name() {\n return \"BaseComponent\";\n }\n\n // istanbul ignore next @preserve\n get defaults() {\n return {};\n }\n\n /** just to have something to extend from */\n // istanbul ignore next @preserve coverage wise this isn't important\n _toggleEventListeners = () => {\n // do something to please linters\n };\n\n /** Removes component from target element. */\n dispose() {\n Data.remove<typeof this>(this.element, this.name);\n ObjectKeys(this).forEach((prop) => {\n delete this[prop];\n });\n }\n}\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 // isMobile,\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// const touchEvent = isMobile() ? touchstartEvent : pointerdownEvent;\n// console.log({ isMobile: isMobile(), touchEvent });\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<Carousel>(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 = Number(\n // istanbul ignore next @preserve\n getAttribute(this, dataBsSlideTo) ||\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<HTMLElement>(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<T extends HTMLElement>(\n this: T,\n e: Event & (DragEvent<T> | TouchEvent<T>),\n) {\n const { target } = e;\n const self = getCarouselInstance(this);\n\n // Only prevent default if we're touching the carousel content\n // but not the controls or indicators\n // istanbul ignore next @preserve\n if (\n self &&\n self.isTouch &&\n !self.controls.includes(target as HTMLElement) &&\n !self.controls.includes(target?.parentElement as HTMLElement) &&\n (!self.indicator || !self.indicator.contains(target))\n ) {\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<HTMLElement>,\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, indicator } = self;\n // istanbul ignore else @preserve\n if (\n ![...controls, indicator].every((el) =>\n el && (el === target || el.contains(target))\n ) && this.contains(target)\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 } else {\n // e.stopImmediatePropagation();\n\n // e.stopPropagation();\n // e.preventDefault();\n }\n}\n\n/**\n * Handles the `pointermove` event for the `Carousel` element.\n *\n * @param e\n */\nconst carouselPointerMoveHandler = (e: PointerEvent<HTMLElement>) => {\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<HTMLElement>) => {\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<HTMLElement>(\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<HTMLElement>;\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<CarouselOptions>) {\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<HTMLElement>(`[${dataBsSlide}]`, element),\n ...querySelectorAll<HTMLElement>(\n `[${dataBsSlide}][${dataBsTarget}=\"#${element.id}\"]`,\n doc,\n ),\n ].filter((c, i, ar) => i === ar.indexOf(c));\n\n this.indicator = querySelector<HTMLElement>(\n `.${carouselString}-indicators`,\n element,\n );\n\n // a LIVE collection is preffered\n this.indicators = [\n ...(this.indicator\n ? querySelectorAll<HTMLElement>(`[${dataBsSlideTo}]`, this.indicator)\n /* istanbul ignore next @preserve */ : []),\n ...querySelectorAll<HTMLElement>(\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"],"mappings":"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"}