@salt-ds/embla-carousel 0.0.0-snapshot-20250627090641

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (102) hide show
  1. package/CHANGELOG.md +161 -0
  2. package/README.md +3 -0
  3. package/css/salt-embla-carousel.css +155 -0
  4. package/dist-cjs/Carousel.css.js +6 -0
  5. package/dist-cjs/Carousel.css.js.map +1 -0
  6. package/dist-cjs/Carousel.js +53 -0
  7. package/dist-cjs/Carousel.js.map +1 -0
  8. package/dist-cjs/CarouselAnnouncementPlugin.js +55 -0
  9. package/dist-cjs/CarouselAnnouncementPlugin.js.map +1 -0
  10. package/dist-cjs/CarouselAutoplayIndicator.css.js +6 -0
  11. package/dist-cjs/CarouselAutoplayIndicator.css.js.map +1 -0
  12. package/dist-cjs/CarouselAutoplayIndicator.js +82 -0
  13. package/dist-cjs/CarouselAutoplayIndicator.js.map +1 -0
  14. package/dist-cjs/CarouselAutoplayIndicatorSVG.js +54 -0
  15. package/dist-cjs/CarouselAutoplayIndicatorSVG.js.map +1 -0
  16. package/dist-cjs/CarouselCard.css.js +6 -0
  17. package/dist-cjs/CarouselCard.css.js.map +1 -0
  18. package/dist-cjs/CarouselCard.js +50 -0
  19. package/dist-cjs/CarouselCard.js.map +1 -0
  20. package/dist-cjs/CarouselContext.js +22 -0
  21. package/dist-cjs/CarouselContext.js.map +1 -0
  22. package/dist-cjs/CarouselNextButton.js +35 -0
  23. package/dist-cjs/CarouselNextButton.js.map +1 -0
  24. package/dist-cjs/CarouselPreviousButton.js +35 -0
  25. package/dist-cjs/CarouselPreviousButton.js.map +1 -0
  26. package/dist-cjs/CarouselProgressLabel.css.js +6 -0
  27. package/dist-cjs/CarouselProgressLabel.css.js.map +1 -0
  28. package/dist-cjs/CarouselProgressLabel.js +65 -0
  29. package/dist-cjs/CarouselProgressLabel.js.map +1 -0
  30. package/dist-cjs/CarouselSlides.css.js +6 -0
  31. package/dist-cjs/CarouselSlides.css.js.map +1 -0
  32. package/dist-cjs/CarouselSlides.js +55 -0
  33. package/dist-cjs/CarouselSlides.js.map +1 -0
  34. package/dist-cjs/CarouselTab.css.js +6 -0
  35. package/dist-cjs/CarouselTab.css.js.map +1 -0
  36. package/dist-cjs/CarouselTab.js +71 -0
  37. package/dist-cjs/CarouselTab.js.map +1 -0
  38. package/dist-cjs/CarouselTabList.css.js +6 -0
  39. package/dist-cjs/CarouselTabList.css.js.map +1 -0
  40. package/dist-cjs/CarouselTabList.js +94 -0
  41. package/dist-cjs/CarouselTabList.js.map +1 -0
  42. package/dist-cjs/index.js +31 -0
  43. package/dist-cjs/index.js.map +1 -0
  44. package/dist-cjs/usePrevNextButtons.js +41 -0
  45. package/dist-cjs/usePrevNextButtons.js.map +1 -0
  46. package/dist-es/Carousel.css.js +4 -0
  47. package/dist-es/Carousel.css.js.map +1 -0
  48. package/dist-es/Carousel.js +51 -0
  49. package/dist-es/Carousel.js.map +1 -0
  50. package/dist-es/CarouselAnnouncementPlugin.js +52 -0
  51. package/dist-es/CarouselAnnouncementPlugin.js.map +1 -0
  52. package/dist-es/CarouselAutoplayIndicator.css.js +4 -0
  53. package/dist-es/CarouselAutoplayIndicator.css.js.map +1 -0
  54. package/dist-es/CarouselAutoplayIndicator.js +80 -0
  55. package/dist-es/CarouselAutoplayIndicator.js.map +1 -0
  56. package/dist-es/CarouselAutoplayIndicatorSVG.js +52 -0
  57. package/dist-es/CarouselAutoplayIndicatorSVG.js.map +1 -0
  58. package/dist-es/CarouselCard.css.js +4 -0
  59. package/dist-es/CarouselCard.css.js.map +1 -0
  60. package/dist-es/CarouselCard.js +48 -0
  61. package/dist-es/CarouselCard.js.map +1 -0
  62. package/dist-es/CarouselContext.js +19 -0
  63. package/dist-es/CarouselContext.js.map +1 -0
  64. package/dist-es/CarouselNextButton.js +33 -0
  65. package/dist-es/CarouselNextButton.js.map +1 -0
  66. package/dist-es/CarouselPreviousButton.js +33 -0
  67. package/dist-es/CarouselPreviousButton.js.map +1 -0
  68. package/dist-es/CarouselProgressLabel.css.js +4 -0
  69. package/dist-es/CarouselProgressLabel.css.js.map +1 -0
  70. package/dist-es/CarouselProgressLabel.js +63 -0
  71. package/dist-es/CarouselProgressLabel.js.map +1 -0
  72. package/dist-es/CarouselSlides.css.js +4 -0
  73. package/dist-es/CarouselSlides.css.js.map +1 -0
  74. package/dist-es/CarouselSlides.js +53 -0
  75. package/dist-es/CarouselSlides.js.map +1 -0
  76. package/dist-es/CarouselTab.css.js +4 -0
  77. package/dist-es/CarouselTab.css.js.map +1 -0
  78. package/dist-es/CarouselTab.js +68 -0
  79. package/dist-es/CarouselTab.js.map +1 -0
  80. package/dist-es/CarouselTabList.css.js +4 -0
  81. package/dist-es/CarouselTabList.css.js.map +1 -0
  82. package/dist-es/CarouselTabList.js +92 -0
  83. package/dist-es/CarouselTabList.js.map +1 -0
  84. package/dist-es/index.js +12 -0
  85. package/dist-es/index.js.map +1 -0
  86. package/dist-es/usePrevNextButtons.js +39 -0
  87. package/dist-es/usePrevNextButtons.js.map +1 -0
  88. package/dist-types/Carousel.d.ts +27 -0
  89. package/dist-types/CarouselAnnouncementPlugin.d.ts +34 -0
  90. package/dist-types/CarouselAutoplayIndicator.d.ts +16 -0
  91. package/dist-types/CarouselAutoplayIndicatorSVG.d.ts +24 -0
  92. package/dist-types/CarouselCard.d.ts +33 -0
  93. package/dist-types/CarouselContext.d.ts +20 -0
  94. package/dist-types/CarouselNextButton.d.ts +7 -0
  95. package/dist-types/CarouselPreviousButton.d.ts +7 -0
  96. package/dist-types/CarouselProgressLabel.d.ts +7 -0
  97. package/dist-types/CarouselSlides.d.ts +7 -0
  98. package/dist-types/CarouselTab.d.ts +34 -0
  99. package/dist-types/CarouselTabList.d.ts +12 -0
  100. package/dist-types/index.d.ts +11 -0
  101. package/dist-types/usePrevNextButtons.d.ts +20 -0
  102. package/package.json +54 -0
@@ -0,0 +1,41 @@
1
+ 'use strict';
2
+
3
+ var react = require('react');
4
+ var CarouselContext = require('./CarouselContext.js');
5
+
6
+ const usePrevNextButtons = () => {
7
+ const [prevBtnDisabled, setPrevBtnDisabled] = react.useState(true);
8
+ const [nextBtnDisabled, setNextBtnDisabled] = react.useState(true);
9
+ const { emblaApi } = CarouselContext.useCarouselContext();
10
+ const handlePrevButtonClick = react.useCallback(() => {
11
+ if (!emblaApi) return;
12
+ emblaApi.scrollPrev();
13
+ }, [emblaApi]);
14
+ const handleNextButtonClick = react.useCallback(() => {
15
+ if (!emblaApi) return;
16
+ emblaApi.scrollNext();
17
+ }, [emblaApi]);
18
+ const handleSelect = react.useCallback((emblaApi2) => {
19
+ setPrevBtnDisabled(!emblaApi2.canScrollPrev());
20
+ setNextBtnDisabled(!emblaApi2.canScrollNext());
21
+ }, []);
22
+ react.useEffect(() => {
23
+ if (!emblaApi) {
24
+ return;
25
+ }
26
+ handleSelect(emblaApi);
27
+ emblaApi.on("init", handleSelect).on("reInit", handleSelect).on("select", handleSelect);
28
+ return () => {
29
+ emblaApi.off("init", handleSelect).off("reInit", handleSelect).off("select", handleSelect);
30
+ };
31
+ }, [emblaApi, handleSelect]);
32
+ return {
33
+ prevBtnDisabled,
34
+ nextBtnDisabled,
35
+ onPrevButtonClick: handlePrevButtonClick,
36
+ onNextButtonClick: handleNextButtonClick
37
+ };
38
+ };
39
+
40
+ exports.usePrevNextButtons = usePrevNextButtons;
41
+ //# sourceMappingURL=usePrevNextButtons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usePrevNextButtons.js","sources":["../src/usePrevNextButtons.tsx"],"sourcesContent":["import type { EmblaCarouselType } from \"embla-carousel\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\n\ntype UsePrevNextButtonsType = {\n /**\n * Indicates whether the previous button is disabled.\n */\n prevBtnDisabled: boolean;\n /**\n * Indicates whether the next button is disabled.\n */\n nextBtnDisabled: boolean;\n /**\n * Handles the click event for the previous button.\n */\n onPrevButtonClick: () => void;\n /**\n * Handles the click event for the next button.\n */\n onNextButtonClick: () => void;\n};\n\nexport const usePrevNextButtons = (): UsePrevNextButtonsType => {\n const [prevBtnDisabled, setPrevBtnDisabled] = useState(true);\n const [nextBtnDisabled, setNextBtnDisabled] = useState(true);\n\n const { emblaApi } = useCarouselContext();\n\n const handlePrevButtonClick = useCallback(() => {\n if (!emblaApi) return;\n emblaApi.scrollPrev();\n }, [emblaApi]);\n\n const handleNextButtonClick = useCallback(() => {\n if (!emblaApi) return;\n emblaApi.scrollNext();\n }, [emblaApi]);\n\n const handleSelect = useCallback((emblaApi: EmblaCarouselType) => {\n setPrevBtnDisabled(!emblaApi.canScrollPrev());\n setNextBtnDisabled(!emblaApi.canScrollNext());\n }, []);\n\n useEffect(() => {\n if (!emblaApi) {\n return;\n }\n handleSelect(emblaApi);\n emblaApi\n .on(\"init\", handleSelect)\n .on(\"reInit\", handleSelect)\n .on(\"select\", handleSelect);\n // Cleanup listener on component unmount\n return () => {\n emblaApi\n .off(\"init\", handleSelect)\n .off(\"reInit\", handleSelect)\n .off(\"select\", handleSelect);\n };\n }, [emblaApi, handleSelect]);\n\n return {\n prevBtnDisabled,\n nextBtnDisabled,\n onPrevButtonClick: handlePrevButtonClick,\n onNextButtonClick: handleNextButtonClick,\n };\n};\n"],"names":["useState","useCarouselContext","useCallback","emblaApi","useEffect"],"mappings":";;;;;AAuBO,MAAM,qBAAqB,MAA8B;AAC9D,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAIA,eAAS,IAAI,CAAA;AAC3D,EAAA,MAAM,CAAC,eAAA,EAAiB,kBAAkB,CAAA,GAAIA,eAAS,IAAI,CAAA;AAE3D,EAAM,MAAA,EAAE,QAAS,EAAA,GAAIC,kCAAmB,EAAA;AAExC,EAAM,MAAA,qBAAA,GAAwBC,kBAAY,MAAM;AAC9C,IAAA,IAAI,CAAC,QAAU,EAAA;AACf,IAAA,QAAA,CAAS,UAAW,EAAA;AAAA,GACtB,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAM,MAAA,qBAAA,GAAwBA,kBAAY,MAAM;AAC9C,IAAA,IAAI,CAAC,QAAU,EAAA;AACf,IAAA,QAAA,CAAS,UAAW,EAAA;AAAA,GACtB,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAM,MAAA,YAAA,GAAeA,iBAAY,CAAA,CAACC,SAAgC,KAAA;AAChE,IAAmB,kBAAA,CAAA,CAACA,SAAS,CAAA,aAAA,EAAe,CAAA;AAC5C,IAAmB,kBAAA,CAAA,CAACA,SAAS,CAAA,aAAA,EAAe,CAAA;AAAA,GAC9C,EAAG,EAAE,CAAA;AAEL,EAAAC,eAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,QAAU,EAAA;AACb,MAAA;AAAA;AAEF,IAAA,YAAA,CAAa,QAAQ,CAAA;AACrB,IACG,QAAA,CAAA,EAAA,CAAG,MAAQ,EAAA,YAAY,CACvB,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA,CACzB,EAAG,CAAA,QAAA,EAAU,YAAY,CAAA;AAE5B,IAAA,OAAO,MAAM;AACX,MACG,QAAA,CAAA,GAAA,CAAI,MAAQ,EAAA,YAAY,CACxB,CAAA,GAAA,CAAI,UAAU,YAAY,CAAA,CAC1B,GAAI,CAAA,QAAA,EAAU,YAAY,CAAA;AAAA,KAC/B;AAAA,GACC,EAAA,CAAC,QAAU,EAAA,YAAY,CAAC,CAAA;AAE3B,EAAO,OAAA;AAAA,IACL,eAAA;AAAA,IACA,eAAA;AAAA,IACA,iBAAmB,EAAA,qBAAA;AAAA,IACnB,iBAAmB,EAAA;AAAA,GACrB;AACF;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltCarousel {\n --saltCarousel-slide-height: 310px;\n --saltCarousel-slide-spacing: var(--salt-spacing-100);\n --saltCarousel-slide-size: 100%;\n display: flex;\n flex-direction: column;\n gap: var(--salt-spacing-100);\n margin: auto;\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=Carousel.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Carousel.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,51 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { makePrefixer } from '@salt-ds/core';
3
+ import { useComponentCssInjection } from '@salt-ds/styles';
4
+ import { useWindow } from '@salt-ds/window';
5
+ import { clsx } from 'clsx';
6
+ import useEmblaCarousel from 'embla-carousel-react';
7
+ import { forwardRef, useEffect } from 'react';
8
+ import css_248z from './Carousel.css.js';
9
+ import { CarouselContext } from './CarouselContext.js';
10
+
11
+ const withBaseName = makePrefixer("saltCarousel");
12
+ const Carousel = forwardRef(
13
+ function Carousel2({
14
+ children,
15
+ className,
16
+ emblaOptions = {},
17
+ emblaPlugins = [],
18
+ getEmblaApi,
19
+ ...rest
20
+ }, ref) {
21
+ const targetWindow = useWindow();
22
+ useComponentCssInjection({
23
+ testId: "salt-carousel",
24
+ css: css_248z,
25
+ window: targetWindow
26
+ });
27
+ const [emblaRef, emblaApi] = useEmblaCarousel(emblaOptions, [
28
+ ...emblaPlugins
29
+ ]);
30
+ useEffect(() => {
31
+ if (emblaApi) {
32
+ getEmblaApi == null ? void 0 : getEmblaApi(emblaApi);
33
+ }
34
+ return void 0;
35
+ }, [emblaApi]);
36
+ return /* @__PURE__ */ jsx(CarouselContext.Provider, { value: { emblaApi, emblaRef }, children: /* @__PURE__ */ jsx(
37
+ "section",
38
+ {
39
+ "aria-roledescription": "carousel",
40
+ role: "region",
41
+ className: clsx(withBaseName(), className),
42
+ ref,
43
+ ...rest,
44
+ children
45
+ }
46
+ ) });
47
+ }
48
+ );
49
+
50
+ export { Carousel };
51
+ //# sourceMappingURL=Carousel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Carousel.js","sources":["../src/Carousel.tsx"],"sourcesContent":["import { makePrefixer } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport useEmblaCarousel, {\n type UseEmblaCarouselType,\n} from \"embla-carousel-react\";\nimport { type ComponentPropsWithoutRef, forwardRef, useEffect } from \"react\";\nimport carouselCss from \"./Carousel.css\";\nimport { CarouselContext } from \"./CarouselContext\";\n\nconst withBaseName = makePrefixer(\"saltCarousel\");\n\nexport type CarouselEmblaRefType = UseEmblaCarouselType[0];\nexport type CarouselEmblaApiType = UseEmblaCarouselType[1];\n\ntype UseCarouselParameters = Parameters<typeof useEmblaCarousel>;\nexport type CarouselOptions = UseCarouselParameters[0];\nexport type CarouselPlugin = UseCarouselParameters[1];\n\n/**\n * Props for the Carousel component.\n * Pass a ref to the carousel to get it to return a reference to the embla API\n */\nexport interface CarouselProps extends ComponentPropsWithoutRef<\"section\"> {\n /**\n * Options to configure the Embla Carousel.\n * These options are passed directly to the Embla Carousel instance.\n */\n emblaOptions?: CarouselOptions;\n\n /**\n * Plugins to enhance the functionality of the Embla Carousel.\n * These options are passed directly to the Embla Carousel instance.\n */\n emblaPlugins?: CarouselPlugin;\n /** Get embla API as ref, use this to manage the state of the Carousel */\n getEmblaApi?: (embla: CarouselEmblaApiType) => void;\n}\n\nexport const Carousel = forwardRef<HTMLElement, CarouselProps>(\n function Carousel(\n {\n children,\n className,\n emblaOptions = {},\n emblaPlugins = [],\n getEmblaApi,\n ...rest\n },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel\",\n css: carouselCss,\n window: targetWindow,\n });\n\n const [emblaRef, emblaApi] = useEmblaCarousel(emblaOptions, [\n ...emblaPlugins,\n ]);\n\n useEffect(() => {\n if (emblaApi) {\n getEmblaApi?.(emblaApi);\n }\n return undefined;\n }, [emblaApi]);\n\n return (\n <CarouselContext.Provider value={{ emblaApi, emblaRef }}>\n <section\n aria-roledescription=\"carousel\"\n role=\"region\"\n className={clsx(withBaseName(), className)}\n ref={ref}\n {...rest}\n >\n {children}\n </section>\n </CarouselContext.Provider>\n );\n },\n);\n"],"names":["Carousel","carouselCss"],"mappings":";;;;;;;;;;AAWA,MAAM,YAAA,GAAe,aAAa,cAAc,CAAA;AA6BzC,MAAM,QAAW,GAAA,UAAA;AAAA,EACtB,SAASA,SACP,CAAA;AAAA,IACE,QAAA;AAAA,IACA,SAAA;AAAA,IACA,eAAe,EAAC;AAAA,IAChB,eAAe,EAAC;AAAA,IAChB,WAAA;AAAA,IACA,GAAG;AAAA,KAEL,GACA,EAAA;AACA,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,eAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IAAA,MAAM,CAAC,QAAA,EAAU,QAAQ,CAAA,GAAI,iBAAiB,YAAc,EAAA;AAAA,MAC1D,GAAG;AAAA,KACJ,CAAA;AAED,IAAA,SAAA,CAAU,MAAM;AACd,MAAA,IAAI,QAAU,EAAA;AACZ,QAAc,WAAA,IAAA,IAAA,GAAA,MAAA,GAAA,WAAA,CAAA,QAAA,CAAA;AAAA;AAEhB,MAAO,OAAA,MAAA;AAAA,KACT,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,IACE,uBAAA,GAAA,CAAC,gBAAgB,QAAhB,EAAA,EAAyB,OAAO,EAAE,QAAA,EAAU,UAC3C,EAAA,QAAA,kBAAA,GAAA;AAAA,MAAC,SAAA;AAAA,MAAA;AAAA,QACC,sBAAqB,EAAA,UAAA;AAAA,QACrB,IAAK,EAAA,QAAA;AAAA,QACL,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,QACzC,GAAA;AAAA,QACC,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KAEL,EAAA,CAAA;AAAA;AAGN;;;;"}
@@ -0,0 +1,52 @@
1
+ import { useAriaAnnouncer } from '@salt-ds/core';
2
+ import { useCallback } from 'react';
3
+
4
+ const getSlideLabel = (slideElement, slideIndex, slideCount) => {
5
+ let description = slideElement == null ? void 0 : slideElement.getAttribute("aria-label");
6
+ if (!description) {
7
+ const labelledById = slideElement == null ? void 0 : slideElement.getAttribute("aria-labelledby");
8
+ if (labelledById) {
9
+ const labelledByElement = document.getElementById(labelledById);
10
+ description = (labelledByElement == null ? void 0 : labelledByElement.textContent) || "No description available";
11
+ } else {
12
+ description = "No description available";
13
+ }
14
+ }
15
+ return `slide ${slideIndex + 1} of ${slideCount}. ${description}`;
16
+ };
17
+ function CarouselAnnouncement(userOptions = {}) {
18
+ let emblaApi;
19
+ const { announce } = useAriaAnnouncer();
20
+ const handleSettle = useCallback(
21
+ (emblaApi2) => {
22
+ var _a;
23
+ const slideCount = (emblaApi2 == null ? void 0 : emblaApi2.slideNodes().length) ?? 0;
24
+ const slideIndexInView = ((_a = emblaApi2 == null ? void 0 : emblaApi2.slidesInView()) == null ? void 0 : _a[0]) ?? 0;
25
+ const slideElement = emblaApi2 == null ? void 0 : emblaApi2.slideNodes()[slideIndexInView];
26
+ const slideLabel = getSlideLabel(
27
+ slideElement,
28
+ slideIndexInView,
29
+ slideCount
30
+ );
31
+ announce(slideLabel);
32
+ },
33
+ [announce]
34
+ );
35
+ function init(emblaApiInstance) {
36
+ emblaApi = emblaApiInstance;
37
+ emblaApi.on("settle", handleSettle);
38
+ }
39
+ function destroy() {
40
+ emblaApi.off("settle", handleSettle);
41
+ }
42
+ const self = {
43
+ name: "announcement",
44
+ options: userOptions,
45
+ init,
46
+ destroy
47
+ };
48
+ return self;
49
+ }
50
+
51
+ export { CarouselAnnouncement, getSlideLabel };
52
+ //# sourceMappingURL=CarouselAnnouncementPlugin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselAnnouncementPlugin.js","sources":["../src/CarouselAnnouncementPlugin.ts"],"sourcesContent":["import { useAriaAnnouncer } from \"@salt-ds/core\";\nimport type {\n CreateOptionsType,\n CreatePluginType,\n EmblaCarouselType,\n} from \"embla-carousel\";\nimport { useCallback } from \"react\";\n\ndeclare module \"embla-carousel\" {\n interface EmblaPluginsType {\n announcement: CarouselAnnouncementType;\n }\n}\n\n/**\n * Type definition for the parameters of the getSlideLabel function.\n */\nexport type GetSlideLabelProps = (\n /**\n * The HTML element representing the slide.\n */\n slideElement: HTMLElement,\n\n /**\n * The index of the slide within the carousel.\n */\n slideIndex: number,\n\n /**\n * The total number of slides in the carousel.\n */\n slideCount: number,\n) => string;\n\n/**\n * Generates a label for a carousel slide based on ARIA attributes.\n *\n * @param props - The properties required to generate the slide description.\n * @returns A string description of the slide, including its position and ARIA label or text content.\n */\nexport const getSlideLabel: GetSlideLabelProps = (\n slideElement,\n slideIndex,\n slideCount,\n): string => {\n let description = slideElement?.getAttribute(\"aria-label\");\n if (!description) {\n const labelledById = slideElement?.getAttribute(\"aria-labelledby\");\n if (labelledById) {\n const labelledByElement = document.getElementById(labelledById);\n description =\n labelledByElement?.textContent || \"No description available\";\n } else {\n description = \"No description available\";\n }\n }\n return `slide ${slideIndex + 1} of ${slideCount}. ${description}`;\n};\n\n// biome-ignore lint/complexity/noBannedTypes: Replicated from embla docs/code\ntype OptionsType = CreateOptionsType<{}>;\n// biome-ignore lint/complexity/noBannedTypes: Replicated from embla docs/code\nexport type CarouselAnnouncementType = CreatePluginType<{}, OptionsType>;\n\nexport type CarouselAnnouncementOptionsType =\n CarouselAnnouncementType[\"options\"];\n\nexport function CarouselAnnouncement(\n userOptions: CarouselAnnouncementOptionsType = {},\n): CarouselAnnouncementType {\n let emblaApi: EmblaCarouselType;\n\n const { announce } = useAriaAnnouncer();\n\n const handleSettle = useCallback(\n (emblaApi: EmblaCarouselType) => {\n const slideCount = emblaApi?.slideNodes().length ?? 0;\n const slideIndexInView = emblaApi?.slidesInView()?.[0] ?? 0;\n const slideElement = emblaApi?.slideNodes()[slideIndexInView];\n\n const slideLabel = getSlideLabel(\n slideElement,\n slideIndexInView,\n slideCount,\n );\n announce(slideLabel);\n },\n [announce],\n );\n\n function init(emblaApiInstance: EmblaCarouselType): void {\n emblaApi = emblaApiInstance;\n emblaApi.on(\"settle\", handleSettle);\n }\n\n function destroy(): void {\n emblaApi.off(\"settle\", handleSettle);\n }\n\n const self: CarouselAnnouncementType = {\n name: \"announcement\",\n options: userOptions,\n init,\n destroy,\n };\n return self;\n}\n"],"names":["emblaApi"],"mappings":";;;AAwCO,MAAM,aAAoC,GAAA,CAC/C,YACA,EAAA,UAAA,EACA,UACW,KAAA;AACX,EAAI,IAAA,WAAA,GAAc,6CAAc,YAAa,CAAA,YAAA,CAAA;AAC7C,EAAA,IAAI,CAAC,WAAa,EAAA;AAChB,IAAM,MAAA,YAAA,GAAe,6CAAc,YAAa,CAAA,iBAAA,CAAA;AAChD,IAAA,IAAI,YAAc,EAAA;AAChB,MAAM,MAAA,iBAAA,GAAoB,QAAS,CAAA,cAAA,CAAe,YAAY,CAAA;AAC9D,MAAA,WAAA,GAAA,CACE,uDAAmB,WAAe,KAAA,0BAAA;AAAA,KAC/B,MAAA;AACL,MAAc,WAAA,GAAA,0BAAA;AAAA;AAChB;AAEF,EAAA,OAAO,SAAS,UAAa,GAAA,CAAC,CAAO,IAAA,EAAA,UAAU,KAAK,WAAW,CAAA,CAAA;AACjE;AAUgB,SAAA,oBAAA,CACd,WAA+C,GAAA,EACrB,EAAA;AAC1B,EAAI,IAAA,QAAA;AAEJ,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,gBAAiB,EAAA;AAEtC,EAAA,MAAM,YAAe,GAAA,WAAA;AAAA,IACnB,CAACA,SAAgC,KAAA;AA3ErC,MAAA,IAAA,EAAA;AA4EM,MAAA,MAAM,UAAaA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,aAAa,MAAU,KAAA,CAAA;AACpD,MAAA,MAAM,qBAAmB,EAAAA,GAAAA,SAAAA,IAAA,gBAAAA,SAAU,CAAA,YAAA,EAAA,KAAV,mBAA2B,CAAM,CAAA,KAAA,CAAA;AAC1D,MAAA,MAAM,YAAeA,GAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,UAAa,EAAA,CAAA,gBAAA,CAAA;AAE5C,MAAA,MAAM,UAAa,GAAA,aAAA;AAAA,QACjB,YAAA;AAAA,QACA,gBAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,QAAA,CAAS,UAAU,CAAA;AAAA,KACrB;AAAA,IACA,CAAC,QAAQ;AAAA,GACX;AAEA,EAAA,SAAS,KAAK,gBAA2C,EAAA;AACvD,IAAW,QAAA,GAAA,gBAAA;AACX,IAAS,QAAA,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA;AAAA;AAGpC,EAAA,SAAS,OAAgB,GAAA;AACvB,IAAS,QAAA,CAAA,GAAA,CAAI,UAAU,YAAY,CAAA;AAAA;AAGrC,EAAA,MAAM,IAAiC,GAAA;AAAA,IACrC,IAAM,EAAA,cAAA;AAAA,IACN,OAAS,EAAA,WAAA;AAAA,IACT,IAAA;AAAA,IACA;AAAA,GACF;AACA,EAAO,OAAA,IAAA;AACT;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltCarouselAutoplayIndicator {\n --salt-carousel-svg-circumference: 0;\n display: flex;\n align-self: center;\n}\n\n.saltCarouselAutoplayIndicatorSVG {\n transform: rotate(-90deg);\n}\n\n.saltCarouselAutoplayIndicatorSVG-track {\n fill: none;\n stroke: var(--salt-accent-foreground);\n}\n\n.saltCarouselAutoplayIndicatorSVG-bar {\n fill: none;\n stroke: var(--salt-accent-background);\n stroke-dasharray: var(--salt-carousel-svg-circumference);\n stroke-dashoffset: var(--salt-carousel-svg-circumference);\n animation: indicatorAnimation 0.5s linear;\n animation-play-state: paused;\n}\n\n@keyframes indicatorAnimation {\n from {\n stroke-dashoffset: var(--salt-carousel-svg-circumference);\n }\n to {\n stroke-dashoffset: 0;\n }\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=CarouselAutoplayIndicator.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselAutoplayIndicator.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,80 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { makePrefixer, useDensity } from '@salt-ds/core';
3
+ import { useComponentCssInjection } from '@salt-ds/styles';
4
+ import { useWindow } from '@salt-ds/window';
5
+ import clsx from 'classnames';
6
+ import { forwardRef, useRef, useEffect } from 'react';
7
+ import css_248z from './CarouselAutoplayIndicator.css.js';
8
+ import { CarouselAutoplayIndicatorSVG } from './CarouselAutoplayIndicatorSVG.js';
9
+
10
+ const withBaseName = makePrefixer("saltCarouselAutoplayIndicator");
11
+ const sizeAndStrokeWidthMapping = {
12
+ high: { size: 10, strokeWidth: 2 },
13
+ medium: { size: 12, strokeWidth: 2 },
14
+ low: { size: 14, strokeWidth: 2 },
15
+ touch: { size: 16, strokeWidth: 2 }
16
+ };
17
+ const CarouselAutoplayIndicator = forwardRef(({ className, duration, slideIndex, isPlaying, children, ...props }, ref) => {
18
+ const targetWindow = useWindow();
19
+ useComponentCssInjection({
20
+ testId: "salt-carousel-autoplay-indicator",
21
+ css: css_248z,
22
+ window: targetWindow
23
+ });
24
+ const barRef = useRef(null);
25
+ const animationFrameId = useRef(null);
26
+ const density = useDensity();
27
+ const { size, strokeWidth } = sizeAndStrokeWidthMapping[density];
28
+ const radius = (size - strokeWidth) / 2;
29
+ const circumference = 2 * Math.PI * radius;
30
+ useEffect(() => {
31
+ if (barRef.current) {
32
+ animationFrameId.current = requestAnimationFrame(() => {
33
+ if (!barRef.current) {
34
+ return;
35
+ }
36
+ barRef.current.style.animation = "none";
37
+ barRef.current.style.strokeDashoffset = `${circumference}`;
38
+ animationFrameId.current = requestAnimationFrame(() => {
39
+ if (!barRef.current) {
40
+ return;
41
+ }
42
+ barRef.current.style.animation = `indicatorAnimation ${duration}ms linear`;
43
+ barRef.current.style.animationPlayState = isPlaying ? "running" : "paused";
44
+ });
45
+ });
46
+ }
47
+ return () => {
48
+ if (animationFrameId.current !== null) {
49
+ cancelAnimationFrame(animationFrameId.current);
50
+ animationFrameId.current = null;
51
+ }
52
+ };
53
+ }, [circumference, duration, slideIndex, isPlaying]);
54
+ return /* @__PURE__ */ jsx(
55
+ "div",
56
+ {
57
+ ref,
58
+ style: {
59
+ width: size,
60
+ height: size,
61
+ // @ts-ignore
62
+ "--salt-carousel-svg-circumference": circumference
63
+ },
64
+ className: clsx(withBaseName(), className),
65
+ ...props,
66
+ children: /* @__PURE__ */ jsx(
67
+ CarouselAutoplayIndicatorSVG,
68
+ {
69
+ size,
70
+ strokeWidth,
71
+ barRef,
72
+ radius
73
+ }
74
+ )
75
+ }
76
+ );
77
+ });
78
+
79
+ export { CarouselAutoplayIndicator };
80
+ //# sourceMappingURL=CarouselAutoplayIndicator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselAutoplayIndicator.js","sources":["../src/CarouselAutoplayIndicator.tsx"],"sourcesContent":["import { makePrefixer, useDensity } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport clsx from \"classnames\";\nimport {\n type ComponentPropsWithoutRef,\n forwardRef,\n useEffect,\n useRef,\n} from \"react\";\nimport carouselAutoplayIndicator from \"./CarouselAutoplayIndicator.css\";\nimport { CarouselAutoplayIndicatorSVG } from \"./CarouselAutoplayIndicatorSVG\";\n\nexport interface CarouselAutoplayIndicatorProps\n extends ComponentPropsWithoutRef<\"div\"> {\n /**\n * Duration of each slide in milliseconds.\n */\n duration: number;\n /**\n * Index of slide currently displayed.\n */\n slideIndex: number;\n /**\n * If `true`, the indicator is animated to visualize the time until the next slide.\n */\n isPlaying: boolean;\n}\n\nconst withBaseName = makePrefixer(\"saltCarouselAutoplayIndicator\");\n\nconst sizeAndStrokeWidthMapping = {\n high: { size: 10, strokeWidth: 2 },\n medium: { size: 12, strokeWidth: 2 },\n low: { size: 14, strokeWidth: 2 },\n touch: { size: 16, strokeWidth: 2 },\n};\n\nexport const CarouselAutoplayIndicator = forwardRef<\n HTMLDivElement,\n CarouselAutoplayIndicatorProps\n>(({ className, duration, slideIndex, isPlaying, children, ...props }, ref) => {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-autoplay-indicator\",\n css: carouselAutoplayIndicator,\n window: targetWindow,\n });\n\n const barRef = useRef<SVGCircleElement | null>(null);\n const animationFrameId = useRef<number | null>(null);\n\n const density = useDensity();\n const { size, strokeWidth } = sizeAndStrokeWidthMapping[density];\n const radius = (size - strokeWidth) / 2;\n const circumference = 2 * Math.PI * radius;\n\n useEffect(() => {\n if (barRef.current) {\n animationFrameId.current = requestAnimationFrame(() => {\n if (!barRef.current) {\n return;\n }\n barRef.current.style.animation = \"none\"; // Reset animation\n barRef.current.style.strokeDashoffset = `${circumference}`;\n animationFrameId.current = requestAnimationFrame(() => {\n if (!barRef.current) {\n return;\n }\n barRef.current.style.animation = `indicatorAnimation ${duration}ms linear`;\n barRef.current.style.animationPlayState = isPlaying\n ? \"running\"\n : \"paused\";\n });\n });\n }\n\n return () => {\n if (animationFrameId.current !== null) {\n cancelAnimationFrame(animationFrameId.current);\n animationFrameId.current = null;\n }\n };\n }, [circumference, duration, slideIndex, isPlaying]);\n\n return (\n <div\n ref={ref}\n style={{\n width: size,\n height: size,\n // @ts-ignore\n \"--salt-carousel-svg-circumference\": circumference,\n }}\n className={clsx(withBaseName(), className)}\n {...props}\n >\n <CarouselAutoplayIndicatorSVG\n size={size}\n strokeWidth={strokeWidth}\n barRef={barRef}\n radius={radius}\n />\n </div>\n );\n});\n"],"names":["carouselAutoplayIndicator"],"mappings":";;;;;;;;;AA6BA,MAAM,YAAA,GAAe,aAAa,+BAA+B,CAAA;AAEjE,MAAM,yBAA4B,GAAA;AAAA,EAChC,IAAM,EAAA,EAAE,IAAM,EAAA,EAAA,EAAI,aAAa,CAAE,EAAA;AAAA,EACjC,MAAQ,EAAA,EAAE,IAAM,EAAA,EAAA,EAAI,aAAa,CAAE,EAAA;AAAA,EACnC,GAAK,EAAA,EAAE,IAAM,EAAA,EAAA,EAAI,aAAa,CAAE,EAAA;AAAA,EAChC,KAAO,EAAA,EAAE,IAAM,EAAA,EAAA,EAAI,aAAa,CAAE;AACpC,CAAA;AAEO,MAAM,yBAA4B,GAAA,UAAA,CAGvC,CAAC,EAAE,SAAW,EAAA,QAAA,EAAU,UAAY,EAAA,SAAA,EAAW,QAAU,EAAA,GAAG,KAAM,EAAA,EAAG,GAAQ,KAAA;AAC7E,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,kCAAA;AAAA,IACR,GAAK,EAAAA,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,MAAA,GAAS,OAAgC,IAAI,CAAA;AACnD,EAAM,MAAA,gBAAA,GAAmB,OAAsB,IAAI,CAAA;AAEnD,EAAA,MAAM,UAAU,UAAW,EAAA;AAC3B,EAAA,MAAM,EAAE,IAAA,EAAM,WAAY,EAAA,GAAI,0BAA0B,OAAO,CAAA;AAC/D,EAAM,MAAA,MAAA,GAAA,CAAU,OAAO,WAAe,IAAA,CAAA;AACtC,EAAM,MAAA,aAAA,GAAgB,CAAI,GAAA,IAAA,CAAK,EAAK,GAAA,MAAA;AAEpC,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,OAAO,OAAS,EAAA;AAClB,MAAiB,gBAAA,CAAA,OAAA,GAAU,sBAAsB,MAAM;AACrD,QAAI,IAAA,CAAC,OAAO,OAAS,EAAA;AACnB,UAAA;AAAA;AAEF,QAAO,MAAA,CAAA,OAAA,CAAQ,MAAM,SAAY,GAAA,MAAA;AACjC,QAAA,MAAA,CAAO,OAAQ,CAAA,KAAA,CAAM,gBAAmB,GAAA,CAAA,EAAG,aAAa,CAAA,CAAA;AACxD,QAAiB,gBAAA,CAAA,OAAA,GAAU,sBAAsB,MAAM;AACrD,UAAI,IAAA,CAAC,OAAO,OAAS,EAAA;AACnB,YAAA;AAAA;AAEF,UAAA,MAAA,CAAO,OAAQ,CAAA,KAAA,CAAM,SAAY,GAAA,CAAA,mBAAA,EAAsB,QAAQ,CAAA,SAAA,CAAA;AAC/D,UAAA,MAAA,CAAO,OAAQ,CAAA,KAAA,CAAM,kBAAqB,GAAA,SAAA,GACtC,SACA,GAAA,QAAA;AAAA,SACL,CAAA;AAAA,OACF,CAAA;AAAA;AAGH,IAAA,OAAO,MAAM;AACX,MAAI,IAAA,gBAAA,CAAiB,YAAY,IAAM,EAAA;AACrC,QAAA,oBAAA,CAAqB,iBAAiB,OAAO,CAAA;AAC7C,QAAA,gBAAA,CAAiB,OAAU,GAAA,IAAA;AAAA;AAC7B,KACF;AAAA,KACC,CAAC,aAAA,EAAe,QAAU,EAAA,UAAA,EAAY,SAAS,CAAC,CAAA;AAEnD,EACE,uBAAA,GAAA;AAAA,IAAC,KAAA;AAAA,IAAA;AAAA,MACC,GAAA;AAAA,MACA,KAAO,EAAA;AAAA,QACL,KAAO,EAAA,IAAA;AAAA,QACP,MAAQ,EAAA,IAAA;AAAA;AAAA,QAER,mCAAqC,EAAA;AAAA,OACvC;AAAA,MACA,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,MACxC,GAAG,KAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA;AAAA,QAAC,4BAAA;AAAA,QAAA;AAAA,UACC,IAAA;AAAA,UACA,WAAA;AAAA,UACA,MAAA;AAAA,UACA;AAAA;AAAA;AACF;AAAA,GACF;AAEJ,CAAC;;;;"}
@@ -0,0 +1,52 @@
1
+ import { jsxs, jsx } from 'react/jsx-runtime';
2
+ import { makePrefixer } from '@salt-ds/core';
3
+ import clsx from 'classnames';
4
+ import { forwardRef } from 'react';
5
+
6
+ const withBaseName = makePrefixer("saltCarouselAutoplayIndicatorSVG");
7
+ const CarouselAutoplayIndicatorSVG = forwardRef(
8
+ ({
9
+ barRef,
10
+ className,
11
+ radius,
12
+ size,
13
+ strokeWidth
14
+ }, ref) => {
15
+ return /* @__PURE__ */ jsxs(
16
+ "svg",
17
+ {
18
+ className: clsx(withBaseName(), className),
19
+ width: size,
20
+ height: size,
21
+ "aria-hidden": true,
22
+ ref,
23
+ children: [
24
+ /* @__PURE__ */ jsx(
25
+ "circle",
26
+ {
27
+ className: withBaseName("track"),
28
+ cx: size / 2,
29
+ cy: size / 2,
30
+ r: radius,
31
+ strokeWidth
32
+ }
33
+ ),
34
+ /* @__PURE__ */ jsx(
35
+ "circle",
36
+ {
37
+ ref: barRef,
38
+ className: withBaseName("bar"),
39
+ cx: size / 2,
40
+ cy: size / 2,
41
+ r: radius,
42
+ strokeWidth
43
+ }
44
+ )
45
+ ]
46
+ }
47
+ );
48
+ }
49
+ );
50
+
51
+ export { CarouselAutoplayIndicatorSVG };
52
+ //# sourceMappingURL=CarouselAutoplayIndicatorSVG.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselAutoplayIndicatorSVG.js","sources":["../src/CarouselAutoplayIndicatorSVG.tsx"],"sourcesContent":["import { makePrefixer } from \"@salt-ds/core\";\nimport clsx from \"classnames\";\nimport { type SVGAttributes, forwardRef } from \"react\";\nconst withBaseName = makePrefixer(\"saltCarouselAutoplayIndicatorSVG\");\n\nexport interface CarouselAutoplayIndicatorSVGProps\n extends SVGAttributes<SVGSVGElement> {\n /**\n * Class name to apply to the SVG element.\n */\n className?: string;\n /**\n * Ref to attach to progress indicator element\n */\n barRef: React.Ref<SVGCircleElement>;\n /**\n * Size of the SVG in pixels.\n */\n size: number;\n /**\n * Stroke width of the progress indicator in pixels.\n */\n strokeWidth: number;\n /**\n * Radius of the progress indicator circle.\n */\n radius: number;\n}\n\nexport const CarouselAutoplayIndicatorSVG = forwardRef<\n SVGSVGElement,\n CarouselAutoplayIndicatorSVGProps\n>(\n (\n {\n barRef,\n className,\n radius,\n size,\n strokeWidth,\n }: CarouselAutoplayIndicatorSVGProps,\n ref,\n ) => {\n return (\n <svg\n className={clsx(withBaseName(), className)}\n width={size}\n height={size}\n aria-hidden\n ref={ref}\n >\n <circle\n className={withBaseName(\"track\")}\n cx={size / 2}\n cy={size / 2}\n r={radius}\n strokeWidth={strokeWidth}\n />\n <circle\n ref={barRef}\n className={withBaseName(\"bar\")}\n cx={size / 2}\n cy={size / 2}\n r={radius}\n strokeWidth={strokeWidth}\n />\n </svg>\n );\n },\n);\n"],"names":[],"mappings":";;;;;AAGA,MAAM,YAAA,GAAe,aAAa,kCAAkC,CAAA;AA0B7D,MAAM,4BAA+B,GAAA,UAAA;AAAA,EAI1C,CACE;AAAA,IACE,MAAA;AAAA,IACA,SAAA;AAAA,IACA,MAAA;AAAA,IACA,IAAA;AAAA,IACA;AAAA,KAEF,GACG,KAAA;AACH,IACE,uBAAA,IAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,QACzC,KAAO,EAAA,IAAA;AAAA,QACP,MAAQ,EAAA,IAAA;AAAA,QACR,aAAW,EAAA,IAAA;AAAA,QACX,GAAA;AAAA,QAEA,QAAA,EAAA;AAAA,0BAAA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,SAAA,EAAW,aAAa,OAAO,CAAA;AAAA,cAC/B,IAAI,IAAO,GAAA,CAAA;AAAA,cACX,IAAI,IAAO,GAAA,CAAA;AAAA,cACX,CAAG,EAAA,MAAA;AAAA,cACH;AAAA;AAAA,WACF;AAAA,0BACA,GAAA;AAAA,YAAC,QAAA;AAAA,YAAA;AAAA,cACC,GAAK,EAAA,MAAA;AAAA,cACL,SAAA,EAAW,aAAa,KAAK,CAAA;AAAA,cAC7B,IAAI,IAAO,GAAA,CAAA;AAAA,cACX,IAAI,IAAO,GAAA,CAAA;AAAA,cACX,CAAG,EAAA,MAAA;AAAA,cACH;AAAA;AAAA;AACF;AAAA;AAAA,KACF;AAAA;AAGN;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltCarouselCard {\n display: flex;\n transform: translate3d(0, 0, 0);\n flex: 0 0 var(--saltCarousel-slide-size);\n min-width: 0;\n padding-left: var(--saltCarousel-slide-spacing);\n box-sizing: border-box;\n}\n\n.saltCarouselCard-content {\n display: flex;\n user-select: none;\n overflow: hidden;\n flex-direction: column;\n gap: var(--salt-spacing-200);\n flex-grow: 1;\n}\n\n.saltCarouselCard-body {\n display: flex;\n overflow: hidden;\n flex-direction: column;\n gap: var(--salt-spacing-200);\n flex-grow: 1;\n padding: 0 var(--salt-spacing-200) var(--salt-spacing-200) var(--salt-spacing-200);\n}\n\n.saltCarouselCard-content h2,\n.saltCarouselCard-content h3 {\n margin: 0;\n}\n\n.saltCarouselCard[data-visibility=\"off-screen\"] a {\n visibility: hidden;\n}\n\n.saltCarouselCard-bordered {\n background: var(--salt-container-primary-background);\n border: var(--salt-size-border) var(--salt-container-borderStyle) var(--salt-container-primary-borderColor);\n border-radius: var(--salt-palette-corner, 0);\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=CarouselCard.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselCard.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,48 @@
1
+ import { jsx, jsxs } from 'react/jsx-runtime';
2
+ import { makePrefixer } from '@salt-ds/core';
3
+ import { useComponentCssInjection } from '@salt-ds/styles';
4
+ import { useWindow } from '@salt-ds/window';
5
+ import { clsx } from 'clsx';
6
+ import { forwardRef } from 'react';
7
+ import css_248z from './CarouselCard.css.js';
8
+
9
+ const withBaseName = makePrefixer("saltCarouselCard");
10
+ const CarouselCard = forwardRef(
11
+ function CarouselCard2({ actions, appearance, children, className, header, media, ...rest }, ref) {
12
+ const targetWindow = useWindow();
13
+ useComponentCssInjection({
14
+ testId: "salt-carousel-slide",
15
+ css: css_248z,
16
+ window: targetWindow
17
+ });
18
+ return /* @__PURE__ */ jsx(
19
+ "div",
20
+ {
21
+ role: "tabpanel",
22
+ "aria-roledescription": "slide",
23
+ className: clsx(withBaseName(), className),
24
+ ...rest,
25
+ ref,
26
+ children: /* @__PURE__ */ jsxs(
27
+ "div",
28
+ {
29
+ className: clsx(withBaseName("content"), {
30
+ [withBaseName("bordered")]: appearance === "bordered"
31
+ }),
32
+ children: [
33
+ media,
34
+ children && /* @__PURE__ */ jsxs("div", { className: withBaseName("body"), children: [
35
+ /* @__PURE__ */ jsx("div", { children: header }),
36
+ /* @__PURE__ */ jsx("div", { children }),
37
+ actions
38
+ ] })
39
+ ]
40
+ }
41
+ )
42
+ }
43
+ );
44
+ }
45
+ );
46
+
47
+ export { CarouselCard };
48
+ //# sourceMappingURL=CarouselCard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselCard.js","sources":["../src/CarouselCard.tsx"],"sourcesContent":["import { makePrefixer } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport { type ComponentProps, type ReactNode, forwardRef } from \"react\";\nimport saltCarouselCardCss from \"./CarouselCard.css\";\n\nconst withBaseName = makePrefixer(\"saltCarouselCard\");\n\n/**\n * Props for the CarouselCard component.\n */\nexport interface CarouselCardProps extends ComponentProps<\"div\"> {\n /**\n * Actions to be displayed in the content footer.\n * This can include buttons or any other interactive elements.\n */\n actions?: ReactNode;\n\n /**\n * Media content to be displayed inside the slide.\n * This could include images, videos, etc., that are visually prominent.\n * It differs from children in that media is intended to be the main visual element of the slide.\n */\n media?: ReactNode;\n\n /**\n * The appearance of the slide. Options are 'bordered', and 'transparent'.\n * 'transparent' is the default value.\n **/\n appearance?: \"bordered\" | \"transparent\";\n\n /**\n * Header content to be displayed at the top of the slide.\n * This can be text or any other React node.\n */\n header?: ReactNode;\n\n /**\n * Carousel slide id.\n * This can be used to uniquely identify the slide.\n */\n id?: string;\n}\n\nexport const CarouselCard = forwardRef<HTMLDivElement, CarouselCardProps>(\n function CarouselCard(\n { actions, appearance, children, className, header, media, ...rest },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-slide\",\n css: saltCarouselCardCss,\n window: targetWindow,\n });\n\n return (\n <div\n role=\"tabpanel\"\n aria-roledescription=\"slide\"\n className={clsx(withBaseName(), className)}\n {...rest}\n ref={ref}\n >\n <div\n className={clsx(withBaseName(\"content\"), {\n [withBaseName(\"bordered\")]: appearance === \"bordered\",\n })}\n >\n {media}\n {children && (\n <div className={withBaseName(\"body\")}>\n <div>{header}</div>\n <div>{children}</div>\n {actions}\n </div>\n )}\n </div>\n </div>\n );\n },\n);\n"],"names":["CarouselCard","saltCarouselCardCss"],"mappings":";;;;;;;;AAOA,MAAM,YAAA,GAAe,aAAa,kBAAkB,CAAA;AAsC7C,MAAM,YAAe,GAAA,UAAA;AAAA,EAC1B,SAASA,aAAAA,CACP,EAAE,OAAA,EAAS,UAAY,EAAA,QAAA,EAAU,SAAW,EAAA,MAAA,EAAQ,KAAO,EAAA,GAAG,IAAK,EAAA,EACnE,GACA,EAAA;AACA,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,qBAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IACE,uBAAA,GAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,IAAK,EAAA,UAAA;AAAA,QACL,sBAAqB,EAAA,OAAA;AAAA,QACrB,SAAW,EAAA,IAAA,CAAK,YAAa,EAAA,EAAG,SAAS,CAAA;AAAA,QACxC,GAAG,IAAA;AAAA,QACJ,GAAA;AAAA,QAEA,QAAA,kBAAA,IAAA;AAAA,UAAC,KAAA;AAAA,UAAA;AAAA,YACC,SAAW,EAAA,IAAA,CAAK,YAAa,CAAA,SAAS,CAAG,EAAA;AAAA,cACvC,CAAC,YAAA,CAAa,UAAU,CAAC,GAAG,UAAe,KAAA;AAAA,aAC5C,CAAA;AAAA,YAEA,QAAA,EAAA;AAAA,cAAA,KAAA;AAAA,cACA,4BACE,IAAA,CAAA,KAAA,EAAA,EAAI,SAAW,EAAA,YAAA,CAAa,MAAM,CACjC,EAAA,QAAA,EAAA;AAAA,gCAAA,GAAA,CAAC,SAAK,QAAO,EAAA,MAAA,EAAA,CAAA;AAAA,gCACb,GAAA,CAAC,SAAK,QAAS,EAAA,CAAA;AAAA,gBACd;AAAA,eACH,EAAA;AAAA;AAAA;AAAA;AAEJ;AAAA,KACF;AAAA;AAGN;;;;"}
@@ -0,0 +1,19 @@
1
+ import { createContext } from '@salt-ds/core';
2
+ import { useContext } from 'react';
3
+
4
+ const CarouselContext = createContext(
5
+ "CarouselContext",
6
+ void 0
7
+ );
8
+ const useCarouselContext = () => {
9
+ const context = useContext(CarouselContext);
10
+ if (!context) {
11
+ throw new Error(
12
+ "useCarouselContext must be used within a CarouselProvider"
13
+ );
14
+ }
15
+ return context;
16
+ };
17
+
18
+ export { CarouselContext, useCarouselContext };
19
+ //# sourceMappingURL=CarouselContext.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselContext.js","sources":["../src/CarouselContext.tsx"],"sourcesContent":["import { createContext } from \"@salt-ds/core\";\nimport { useContext } from \"react\";\nimport type { CarouselEmblaApiType, CarouselEmblaRefType } from \"./Carousel\";\n\n/**\n * Type definition for the Carousel context.\n * Provides access to the Embla Carousel API and reference.\n */\ninterface CarouselContextType {\n /**\n * The API instance of the Embla Carousel.\n * Provides methods to control the carousel programmatically.\n */\n emblaApi?: CarouselEmblaApiType;\n\n /**\n * The reference to the Embla Carousel viewport.\n * Used to directly interact with the carousel DOM element.\n */\n emblaRef?: CarouselEmblaRefType;\n}\n\nexport const CarouselContext = createContext<CarouselContextType | undefined>(\n \"CarouselContext\",\n undefined,\n);\n\nexport const useCarouselContext = (): CarouselContextType => {\n const context = useContext(CarouselContext);\n if (!context) {\n throw new Error(\n \"useCarouselContext must be used within a CarouselProvider\",\n );\n }\n return context;\n};\n"],"names":[],"mappings":";;;AAsBO,MAAM,eAAkB,GAAA,aAAA;AAAA,EAC7B,iBAAA;AAAA,EACA;AACF;AAEO,MAAM,qBAAqB,MAA2B;AAC3D,EAAM,MAAA,OAAA,GAAU,WAAW,eAAe,CAAA;AAC1C,EAAA,IAAI,CAAC,OAAS,EAAA;AACZ,IAAA,MAAM,IAAI,KAAA;AAAA,MACR;AAAA,KACF;AAAA;AAEF,EAAO,OAAA,OAAA;AACT;;;;"}
@@ -0,0 +1,33 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useIcon, Button } from '@salt-ds/core';
3
+ import { forwardRef, useCallback } from 'react';
4
+ import { usePrevNextButtons } from './usePrevNextButtons.js';
5
+
6
+ const CarouselNextButton = forwardRef(function CarouselNextButton2({ className, onClick, ...rest }, ref) {
7
+ const { NextIcon } = useIcon();
8
+ const { nextBtnDisabled, onNextButtonClick } = usePrevNextButtons();
9
+ const handleClick = useCallback(
10
+ (event) => {
11
+ onNextButtonClick();
12
+ onClick == null ? void 0 : onClick(event);
13
+ },
14
+ [onNextButtonClick, onClick]
15
+ );
16
+ return /* @__PURE__ */ jsx(
17
+ Button,
18
+ {
19
+ onClick: handleClick,
20
+ disabled: nextBtnDisabled,
21
+ focusableWhenDisabled: true,
22
+ appearance: "bordered",
23
+ sentiment: "neutral",
24
+ "aria-label": "Next slide",
25
+ ref,
26
+ ...rest,
27
+ children: /* @__PURE__ */ jsx(NextIcon, { "aria-hidden": true })
28
+ }
29
+ );
30
+ });
31
+
32
+ export { CarouselNextButton };
33
+ //# sourceMappingURL=CarouselNextButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselNextButton.js","sources":["../src/CarouselNextButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, useIcon } from \"@salt-ds/core\";\nimport { type MouseEventHandler, forwardRef, useCallback } from \"react\";\nimport { usePrevNextButtons } from \"./usePrevNextButtons\";\n\n/**\n * Props for the CarouselNextButton component.\n */\nexport interface CarouselNextButtonProps extends ButtonProps {}\n\nexport const CarouselNextButton = forwardRef<\n HTMLButtonElement,\n CarouselNextButtonProps\n>(function CarouselNextButton({ className, onClick, ...rest }, ref) {\n const { NextIcon } = useIcon();\n const { nextBtnDisabled, onNextButtonClick } = usePrevNextButtons();\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (event) => {\n onNextButtonClick();\n onClick?.(event);\n },\n [onNextButtonClick, onClick],\n );\n\n return (\n <Button\n onClick={handleClick}\n disabled={nextBtnDisabled}\n focusableWhenDisabled\n appearance=\"bordered\"\n sentiment=\"neutral\"\n aria-label=\"Next slide\"\n ref={ref}\n {...rest}\n >\n <NextIcon aria-hidden />\n </Button>\n );\n});\n"],"names":["CarouselNextButton"],"mappings":";;;;;AASa,MAAA,kBAAA,GAAqB,UAGhC,CAAA,SAASA,mBAAmB,CAAA,EAAE,WAAW,OAAS,EAAA,GAAG,IAAK,EAAA,EAAG,GAAK,EAAA;AAClE,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,OAAQ,EAAA;AAC7B,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAkB,EAAA,GAAI,kBAAmB,EAAA;AAElE,EAAA,MAAM,WAAoD,GAAA,WAAA;AAAA,IACxD,CAAC,KAAU,KAAA;AACT,MAAkB,iBAAA,EAAA;AAClB,MAAU,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,KAAA,CAAA;AAAA,KACZ;AAAA,IACA,CAAC,mBAAmB,OAAO;AAAA,GAC7B;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,WAAA;AAAA,MACT,QAAU,EAAA,eAAA;AAAA,MACV,qBAAqB,EAAA,IAAA;AAAA,MACrB,UAAW,EAAA,UAAA;AAAA,MACX,SAAU,EAAA,SAAA;AAAA,MACV,YAAW,EAAA,YAAA;AAAA,MACX,GAAA;AAAA,MACC,GAAG,IAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA,CAAC,QAAS,EAAA,EAAA,aAAA,EAAW,IAAC,EAAA;AAAA;AAAA,GACxB;AAEJ,CAAC;;;;"}
@@ -0,0 +1,33 @@
1
+ import { jsx } from 'react/jsx-runtime';
2
+ import { useIcon, Button } from '@salt-ds/core';
3
+ import { forwardRef, useCallback } from 'react';
4
+ import { usePrevNextButtons } from './usePrevNextButtons.js';
5
+
6
+ const CarouselPreviousButton = forwardRef(function CarouselPreviousButton2({ className, onClick, ...rest }, ref) {
7
+ const { PreviousIcon } = useIcon();
8
+ const { prevBtnDisabled, onPrevButtonClick } = usePrevNextButtons();
9
+ const handleClick = useCallback(
10
+ (event) => {
11
+ onPrevButtonClick();
12
+ onClick == null ? void 0 : onClick(event);
13
+ },
14
+ [onPrevButtonClick, onClick]
15
+ );
16
+ return /* @__PURE__ */ jsx(
17
+ Button,
18
+ {
19
+ onClick: handleClick,
20
+ disabled: prevBtnDisabled,
21
+ focusableWhenDisabled: true,
22
+ appearance: "bordered",
23
+ sentiment: "neutral",
24
+ "aria-label": "Previous slide",
25
+ ref,
26
+ ...rest,
27
+ children: /* @__PURE__ */ jsx(PreviousIcon, { "aria-hidden": true })
28
+ }
29
+ );
30
+ });
31
+
32
+ export { CarouselPreviousButton };
33
+ //# sourceMappingURL=CarouselPreviousButton.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselPreviousButton.js","sources":["../src/CarouselPreviousButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, useIcon } from \"@salt-ds/core\";\nimport { type MouseEventHandler, forwardRef, useCallback } from \"react\";\nimport { usePrevNextButtons } from \"./usePrevNextButtons\";\n\n/**\n * Props for the CarouselPreviousButton component.\n */\nexport interface CarouselPreviousButtonProps extends ButtonProps {}\n\nexport const CarouselPreviousButton = forwardRef<\n HTMLButtonElement,\n CarouselPreviousButtonProps\n>(function CarouselPreviousButton({ className, onClick, ...rest }, ref) {\n const { PreviousIcon } = useIcon();\n const { prevBtnDisabled, onPrevButtonClick } = usePrevNextButtons();\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = useCallback(\n (event) => {\n onPrevButtonClick();\n onClick?.(event);\n },\n [onPrevButtonClick, onClick],\n );\n\n return (\n <Button\n onClick={handleClick}\n disabled={prevBtnDisabled}\n focusableWhenDisabled\n appearance=\"bordered\"\n sentiment=\"neutral\"\n aria-label=\"Previous slide\"\n ref={ref}\n {...rest}\n >\n <PreviousIcon aria-hidden />\n </Button>\n );\n});\n"],"names":["CarouselPreviousButton"],"mappings":";;;;;AASa,MAAA,sBAAA,GAAyB,UAGpC,CAAA,SAASA,uBAAuB,CAAA,EAAE,WAAW,OAAS,EAAA,GAAG,IAAK,EAAA,EAAG,GAAK,EAAA;AACtE,EAAM,MAAA,EAAE,YAAa,EAAA,GAAI,OAAQ,EAAA;AACjC,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAkB,EAAA,GAAI,kBAAmB,EAAA;AAElE,EAAA,MAAM,WAAoD,GAAA,WAAA;AAAA,IACxD,CAAC,KAAU,KAAA;AACT,MAAkB,iBAAA,EAAA;AAClB,MAAU,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,KAAA,CAAA;AAAA,KACZ;AAAA,IACA,CAAC,mBAAmB,OAAO;AAAA,GAC7B;AAEA,EACE,uBAAA,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAS,EAAA,WAAA;AAAA,MACT,QAAU,EAAA,eAAA;AAAA,MACV,qBAAqB,EAAA,IAAA;AAAA,MACrB,UAAW,EAAA,UAAA;AAAA,MACX,SAAU,EAAA,SAAA;AAAA,MACV,YAAW,EAAA,gBAAA;AAAA,MACX,GAAA;AAAA,MACC,GAAG,IAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA,CAAC,YAAa,EAAA,EAAA,aAAA,EAAW,IAAC,EAAA;AAAA;AAAA,GAC5B;AAEJ,CAAC;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltCarouselTabList.saltText {\n font-weight: var(--salt-palette-text-body-fontWeight-strong);\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=CarouselProgressLabel.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselProgressLabel.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}
@@ -0,0 +1,63 @@
1
+ import { jsxs } from 'react/jsx-runtime';
2
+ import { makePrefixer, Text } from '@salt-ds/core';
3
+ import { useComponentCssInjection } from '@salt-ds/styles';
4
+ import { useWindow } from '@salt-ds/window';
5
+ import { clsx } from 'clsx';
6
+ import { useState, useCallback, useEffect } from 'react';
7
+ import { useCarouselContext } from './CarouselContext.js';
8
+ import css_248z from './CarouselProgressLabel.css.js';
9
+
10
+ const withBaseName = makePrefixer("saltCarouselTabList");
11
+ function CarouselProgressLabel({
12
+ className,
13
+ styleAs = "label",
14
+ children,
15
+ ...props
16
+ }) {
17
+ const targetWindow = useWindow();
18
+ useComponentCssInjection({
19
+ testId: "salt-carousel-progress-label",
20
+ css: css_248z,
21
+ window: targetWindow
22
+ });
23
+ const { emblaApi } = useCarouselContext();
24
+ const [currentSlide, setCurrentSlide] = useState("");
25
+ const [totalSlides, setTotalSlides] = useState(0);
26
+ const handleSettle = useCallback((emblaApi2) => {
27
+ const slideIndexInView = (emblaApi2 == null ? void 0 : emblaApi2.selectedScrollSnap()) ?? 0;
28
+ const numberOfSlides = (emblaApi2 == null ? void 0 : emblaApi2.slideNodes().length) ?? 0;
29
+ const scrollSnaps = (emblaApi2 == null ? void 0 : emblaApi2.scrollSnapList()) ?? [];
30
+ const slidesPerTransition = numberOfSlides ? Math.ceil(numberOfSlides / scrollSnaps.length) : 0;
31
+ const startSlideNumber = Math.min(
32
+ slideIndexInView * slidesPerTransition + 1,
33
+ numberOfSlides - (slidesPerTransition - 1)
34
+ );
35
+ const endSlideNumber = Math.min(
36
+ startSlideNumber + slidesPerTransition - 1,
37
+ numberOfSlides
38
+ );
39
+ if (startSlideNumber === endSlideNumber) {
40
+ setCurrentSlide(startSlideNumber.toString(10));
41
+ } else {
42
+ setCurrentSlide(`${startSlideNumber}-${endSlideNumber}`);
43
+ }
44
+ setTotalSlides(numberOfSlides);
45
+ }, []);
46
+ useEffect(() => {
47
+ if (!emblaApi) return;
48
+ emblaApi.on("init", handleSettle).on("reInit", handleSettle).on("settle", handleSettle);
49
+ handleSettle(emblaApi);
50
+ return () => {
51
+ emblaApi.off("init", handleSettle).off("reInit", handleSettle).off("settle", handleSettle);
52
+ };
53
+ }, [emblaApi, handleSettle]);
54
+ return /* @__PURE__ */ jsxs(Text, { className: clsx(withBaseName(), className), ...props, children: [
55
+ "Slide ",
56
+ currentSlide,
57
+ " of ",
58
+ totalSlides
59
+ ] });
60
+ }
61
+
62
+ export { CarouselProgressLabel };
63
+ //# sourceMappingURL=CarouselProgressLabel.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselProgressLabel.js","sources":["../src/CarouselProgressLabel.tsx"],"sourcesContent":["import { Text, type TextProps, makePrefixer } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport type { EmblaCarouselType } from \"embla-carousel\";\nimport { useCallback, useEffect, useState } from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport carouselProgressLabelCss from \"./CarouselProgressLabel.css\";\n\n/**\n * Props for the CarouselProgressLabel component.\n */\nexport interface CarouselProgressLabelProps extends TextProps<\"div\"> {}\n\nconst withBaseName = makePrefixer(\"saltCarouselTabList\");\n\nexport function CarouselProgressLabel({\n className,\n styleAs = \"label\",\n children,\n ...props\n}: CarouselProgressLabelProps) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-progress-label\",\n css: carouselProgressLabelCss,\n window: targetWindow,\n });\n\n const { emblaApi } = useCarouselContext();\n\n const [currentSlide, setCurrentSlide] = useState(\"\");\n const [totalSlides, setTotalSlides] = useState(0);\n\n const handleSettle = useCallback((emblaApi: EmblaCarouselType) => {\n const slideIndexInView = emblaApi?.selectedScrollSnap() ?? 0;\n const numberOfSlides = emblaApi?.slideNodes().length ?? 0;\n const scrollSnaps = emblaApi?.scrollSnapList() ?? [];\n const slidesPerTransition = numberOfSlides\n ? Math.ceil(numberOfSlides / scrollSnaps.length)\n : 0;\n const startSlideNumber = Math.min(\n slideIndexInView * slidesPerTransition + 1,\n numberOfSlides - (slidesPerTransition - 1),\n );\n const endSlideNumber = Math.min(\n startSlideNumber + slidesPerTransition - 1,\n numberOfSlides,\n );\n\n if (startSlideNumber === endSlideNumber) {\n setCurrentSlide(startSlideNumber.toString(10));\n } else {\n setCurrentSlide(`${startSlideNumber}-${endSlideNumber}`);\n }\n setTotalSlides(numberOfSlides);\n }, []);\n\n useEffect(() => {\n if (!emblaApi) return;\n emblaApi\n .on(\"init\", handleSettle)\n .on(\"reInit\", handleSettle)\n .on(\"settle\", handleSettle);\n handleSettle(emblaApi);\n // Cleanup listener on component unmount\n return () => {\n emblaApi\n .off(\"init\", handleSettle)\n .off(\"reInit\", handleSettle)\n .off(\"settle\", handleSettle);\n };\n }, [emblaApi, handleSettle]);\n\n return (\n <Text className={clsx(withBaseName(), className)} {...props}>\n Slide {currentSlide} of {totalSlides}\n </Text>\n );\n}\n"],"names":["carouselProgressLabelCss","emblaApi"],"mappings":";;;;;;;;;AAcA,MAAM,YAAA,GAAe,aAAa,qBAAqB,CAAA;AAEhD,SAAS,qBAAsB,CAAA;AAAA,EACpC,SAAA;AAAA,EACA,OAAU,GAAA,OAAA;AAAA,EACV,QAAA;AAAA,EACA,GAAG;AACL,CAA+B,EAAA;AAC7B,EAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,EAAyB,wBAAA,CAAA;AAAA,IACvB,MAAQ,EAAA,8BAAA;AAAA,IACR,GAAK,EAAAA,QAAA;AAAA,IACL,MAAQ,EAAA;AAAA,GACT,CAAA;AAED,EAAM,MAAA,EAAE,QAAS,EAAA,GAAI,kBAAmB,EAAA;AAExC,EAAA,MAAM,CAAC,YAAA,EAAc,eAAe,CAAA,GAAI,SAAS,EAAE,CAAA;AACnD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,SAAS,CAAC,CAAA;AAEhD,EAAM,MAAA,YAAA,GAAe,WAAY,CAAA,CAACC,SAAgC,KAAA;AAChE,IAAA,MAAM,gBAAmBA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,kBAAwB,EAAA,KAAA,CAAA;AAC3D,IAAA,MAAM,cAAiBA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,aAAa,MAAU,KAAA,CAAA;AACxD,IAAA,MAAM,WAAcA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,qBAAoB,EAAC;AACnD,IAAA,MAAM,sBAAsB,cACxB,GAAA,IAAA,CAAK,KAAK,cAAiB,GAAA,WAAA,CAAY,MAAM,CAC7C,GAAA,CAAA;AACJ,IAAA,MAAM,mBAAmB,IAAK,CAAA,GAAA;AAAA,MAC5B,mBAAmB,mBAAsB,GAAA,CAAA;AAAA,MACzC,kBAAkB,mBAAsB,GAAA,CAAA;AAAA,KAC1C;AACA,IAAA,MAAM,iBAAiB,IAAK,CAAA,GAAA;AAAA,MAC1B,mBAAmB,mBAAsB,GAAA,CAAA;AAAA,MACzC;AAAA,KACF;AAEA,IAAA,IAAI,qBAAqB,cAAgB,EAAA;AACvC,MAAgB,eAAA,CAAA,gBAAA,CAAiB,QAAS,CAAA,EAAE,CAAC,CAAA;AAAA,KACxC,MAAA;AACL,MAAA,eAAA,CAAgB,CAAG,EAAA,gBAAgB,CAAI,CAAA,EAAA,cAAc,CAAE,CAAA,CAAA;AAAA;AAEzD,IAAA,cAAA,CAAe,cAAc,CAAA;AAAA,GAC/B,EAAG,EAAE,CAAA;AAEL,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,IAAI,CAAC,QAAU,EAAA;AACf,IACG,QAAA,CAAA,EAAA,CAAG,MAAQ,EAAA,YAAY,CACvB,CAAA,EAAA,CAAG,UAAU,YAAY,CAAA,CACzB,EAAG,CAAA,QAAA,EAAU,YAAY,CAAA;AAC5B,IAAA,YAAA,CAAa,QAAQ,CAAA;AAErB,IAAA,OAAO,MAAM;AACX,MACG,QAAA,CAAA,GAAA,CAAI,MAAQ,EAAA,YAAY,CACxB,CAAA,GAAA,CAAI,UAAU,YAAY,CAAA,CAC1B,GAAI,CAAA,QAAA,EAAU,YAAY,CAAA;AAAA,KAC/B;AAAA,GACC,EAAA,CAAC,QAAU,EAAA,YAAY,CAAC,CAAA;AAE3B,EACE,uBAAA,IAAA,CAAC,QAAK,SAAW,EAAA,IAAA,CAAK,cAAgB,EAAA,SAAS,CAAI,EAAA,GAAG,KAAO,EAAA,QAAA,EAAA;AAAA,IAAA,QAAA;AAAA,IACpD,YAAA;AAAA,IAAa,MAAA;AAAA,IAAK;AAAA,GAC3B,EAAA,CAAA;AAEJ;;;;"}
@@ -0,0 +1,4 @@
1
+ var css_248z = ".saltCarouselSlides {\n overflow: hidden;\n}\n.saltCarouselSlides-container {\n display: flex;\n touch-action: pan-y pinch-zoom;\n margin-left: calc(var(--saltCarousel-slide-spacing) * -1);\n}\n";
2
+
3
+ export { css_248z as default };
4
+ //# sourceMappingURL=CarouselSlides.css.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"CarouselSlides.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;"}