@salt-ds/embla-carousel 0.1.5 → 1.0.0

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 (94) hide show
  1. package/CHANGELOG.md +51 -0
  2. package/css/salt-embla-carousel.css +54 -27
  3. package/dist-cjs/Carousel.js +30 -9
  4. package/dist-cjs/Carousel.js.map +1 -1
  5. package/dist-cjs/CarouselAutoplayIndicator.css.js +1 -1
  6. package/dist-cjs/CarouselAutoplayIndicator.js.map +1 -1
  7. package/dist-cjs/CarouselAutoplayIndicatorSVG.js +12 -24
  8. package/dist-cjs/CarouselAutoplayIndicatorSVG.js.map +1 -1
  9. package/dist-cjs/CarouselCard.css.js +1 -1
  10. package/dist-cjs/CarouselCard.js +23 -9
  11. package/dist-cjs/CarouselCard.js.map +1 -1
  12. package/dist-cjs/CarouselContext.js.map +1 -1
  13. package/dist-cjs/CarouselNextButton.js +4 -1
  14. package/dist-cjs/CarouselNextButton.js.map +1 -1
  15. package/dist-cjs/CarouselPreviousButton.js +4 -1
  16. package/dist-cjs/CarouselPreviousButton.js.map +1 -1
  17. package/dist-cjs/CarouselProgressLabel.js +11 -33
  18. package/dist-cjs/CarouselProgressLabel.js.map +1 -1
  19. package/dist-cjs/CarouselSlides.css.js +1 -1
  20. package/dist-cjs/CarouselSlides.js +148 -25
  21. package/dist-cjs/CarouselSlides.js.map +1 -1
  22. package/dist-cjs/CarouselTab.css.js +1 -1
  23. package/dist-cjs/CarouselTab.js +1 -5
  24. package/dist-cjs/CarouselTab.js.map +1 -1
  25. package/dist-cjs/CarouselTabList.css.js +1 -1
  26. package/dist-cjs/CarouselTabList.js +47 -27
  27. package/dist-cjs/CarouselTabList.js.map +1 -1
  28. package/dist-cjs/createCustomSettle.js +1 -1
  29. package/dist-cjs/createCustomSettle.js.map +1 -1
  30. package/dist-cjs/getSlideDescription.js +32 -0
  31. package/dist-cjs/getSlideDescription.js.map +1 -0
  32. package/dist-cjs/getVisibleSlideDescription.js +26 -0
  33. package/dist-cjs/getVisibleSlideDescription.js.map +1 -0
  34. package/dist-cjs/getVisibleSlideIndexes.js +33 -0
  35. package/dist-cjs/getVisibleSlideIndexes.js.map +1 -0
  36. package/dist-cjs/index.js +0 -3
  37. package/dist-cjs/index.js.map +1 -1
  38. package/dist-cjs/usePrevNextButtons.js +3 -1
  39. package/dist-cjs/usePrevNextButtons.js.map +1 -1
  40. package/dist-es/Carousel.js +32 -11
  41. package/dist-es/Carousel.js.map +1 -1
  42. package/dist-es/CarouselAutoplayIndicator.css.js +1 -1
  43. package/dist-es/CarouselAutoplayIndicator.js.map +1 -1
  44. package/dist-es/CarouselAutoplayIndicatorSVG.js +13 -25
  45. package/dist-es/CarouselAutoplayIndicatorSVG.js.map +1 -1
  46. package/dist-es/CarouselCard.css.js +1 -1
  47. package/dist-es/CarouselCard.js +23 -9
  48. package/dist-es/CarouselCard.js.map +1 -1
  49. package/dist-es/CarouselContext.js.map +1 -1
  50. package/dist-es/CarouselNextButton.js +4 -1
  51. package/dist-es/CarouselNextButton.js.map +1 -1
  52. package/dist-es/CarouselPreviousButton.js +4 -1
  53. package/dist-es/CarouselPreviousButton.js.map +1 -1
  54. package/dist-es/CarouselProgressLabel.js +12 -34
  55. package/dist-es/CarouselProgressLabel.js.map +1 -1
  56. package/dist-es/CarouselSlides.css.js +1 -1
  57. package/dist-es/CarouselSlides.js +150 -27
  58. package/dist-es/CarouselSlides.js.map +1 -1
  59. package/dist-es/CarouselTab.css.js +1 -1
  60. package/dist-es/CarouselTab.js +1 -5
  61. package/dist-es/CarouselTab.js.map +1 -1
  62. package/dist-es/CarouselTabList.css.js +1 -1
  63. package/dist-es/CarouselTabList.js +48 -28
  64. package/dist-es/CarouselTabList.js.map +1 -1
  65. package/dist-es/createCustomSettle.js +1 -1
  66. package/dist-es/createCustomSettle.js.map +1 -1
  67. package/dist-es/getSlideDescription.js +30 -0
  68. package/dist-es/getSlideDescription.js.map +1 -0
  69. package/dist-es/getVisibleSlideDescription.js +24 -0
  70. package/dist-es/getVisibleSlideDescription.js.map +1 -0
  71. package/dist-es/getVisibleSlideIndexes.js +30 -0
  72. package/dist-es/getVisibleSlideIndexes.js.map +1 -0
  73. package/dist-es/index.js +0 -1
  74. package/dist-es/index.js.map +1 -1
  75. package/dist-es/usePrevNextButtons.js +3 -1
  76. package/dist-es/usePrevNextButtons.js.map +1 -1
  77. package/dist-types/Carousel.d.ts +7 -1
  78. package/dist-types/CarouselContext.d.ts +31 -0
  79. package/dist-types/CarouselTab.d.ts +0 -6
  80. package/dist-types/CarouselTabList.d.ts +4 -0
  81. package/dist-types/getSlideDescription.d.ts +7 -0
  82. package/dist-types/getVisibleSlideDescription.d.ts +7 -0
  83. package/dist-types/getVisibleSlideIndexes.d.ts +8 -0
  84. package/dist-types/index.d.ts +0 -1
  85. package/package.json +2 -2
  86. package/dist-cjs/CarouselAnnouncementPlugin.js +0 -52
  87. package/dist-cjs/CarouselAnnouncementPlugin.js.map +0 -1
  88. package/dist-cjs/CarouselProgressLabel.css.js +0 -6
  89. package/dist-cjs/CarouselProgressLabel.css.js.map +0 -1
  90. package/dist-es/CarouselAnnouncementPlugin.js +0 -49
  91. package/dist-es/CarouselAnnouncementPlugin.js.map +0 -1
  92. package/dist-es/CarouselProgressLabel.css.js +0 -4
  93. package/dist-es/CarouselProgressLabel.css.js.map +0 -1
  94. package/dist-types/CarouselAnnouncementPlugin.d.ts +0 -24
@@ -1,11 +1,13 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useIcon, Button } from '@salt-ds/core';
3
3
  import { forwardRef } from 'react';
4
+ import { useCarouselContext } from './CarouselContext.js';
4
5
  import { usePrevNextButtons } from './usePrevNextButtons.js';
5
6
 
6
7
  const CarouselNextButton = forwardRef(function CarouselNextButton2({ className, onClick, ...rest }, ref) {
7
8
  const { NextIcon } = useIcon();
8
9
  const { nextBtnDisabled, onNextButtonClick } = usePrevNextButtons();
10
+ const { carouselId } = useCarouselContext();
9
11
  const handleClick = (event) => {
10
12
  onNextButtonClick();
11
13
  onClick == null ? void 0 : onClick(event);
@@ -16,7 +18,8 @@ const CarouselNextButton = forwardRef(function CarouselNextButton2({ className,
16
18
  onClick: handleClick,
17
19
  disabled: nextBtnDisabled,
18
20
  focusableWhenDisabled: true,
19
- appearance: "bordered",
21
+ appearance: "transparent",
22
+ "aria-controls": `${carouselId}-slides`,
20
23
  sentiment: "neutral",
21
24
  "aria-label": "Next slide",
22
25
  ref,
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselNextButton.js","sources":["../src/CarouselNextButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, useIcon } from \"@salt-ds/core\";\nimport { forwardRef, type MouseEventHandler } from \"react\";\nimport { usePrevNextButtons } from \"./usePrevNextButtons\";\n\n/**\n * Props for the CarouselNextButton component.\n */\nexport interface CarouselNextButtonProps\n extends Omit<ButtonProps, \"variant\" | \"loading\" | \"loadingAnnouncement\"> {}\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> = (event) => {\n onNextButtonClick();\n onClick?.(event);\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":";;;;;AAUa,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,EAAM,MAAA,WAAA,GAAoD,CAAC,KAAU,KAAA;AACnE,IAAkB,iBAAA,EAAA;AAClB,IAAU,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,KAAA,CAAA;AAAA,GACZ;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;;;;"}
1
+ {"version":3,"file":"CarouselNextButton.js","sources":["../src/CarouselNextButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, useIcon } from \"@salt-ds/core\";\nimport { forwardRef, type MouseEventHandler } from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport { usePrevNextButtons } from \"./usePrevNextButtons\";\n\n/**\n * Props for the CarouselNextButton component.\n */\nexport interface CarouselNextButtonProps\n extends Omit<ButtonProps, \"variant\" | \"loading\" | \"loadingAnnouncement\"> {}\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 { carouselId } = useCarouselContext();\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n onNextButtonClick();\n onClick?.(event);\n };\n\n return (\n <Button\n onClick={handleClick}\n disabled={nextBtnDisabled}\n focusableWhenDisabled\n appearance=\"transparent\"\n aria-controls={`${carouselId}-slides`}\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":";;;;;;AAWO,MAAM,kBAAA,GAAqB,UAAA,CAGhC,SAASA,mBAAAA,CAAmB,EAAE,WAAW,OAAA,EAAS,GAAG,IAAA,EAAK,EAAG,GAAA,EAAK;AAClE,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,OAAA,EAAQ;AAC7B,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAA,EAAkB,GAAI,kBAAA,EAAmB;AAElE,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,kBAAA,EAAmB;AAE1C,EAAA,MAAM,WAAA,GAAoD,CAAC,KAAA,KAAU;AACnE,IAAA,iBAAA,EAAkB;AAClB,IAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAU,KAAA,CAAA;AAAA,EACZ,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAS,WAAA;AAAA,MACT,QAAA,EAAU,eAAA;AAAA,MACV,qBAAA,EAAqB,IAAA;AAAA,MACrB,UAAA,EAAW,aAAA;AAAA,MACX,eAAA,EAAe,GAAG,UAAU,CAAA,OAAA,CAAA;AAAA,MAC5B,SAAA,EAAU,SAAA;AAAA,MACV,YAAA,EAAW,YAAA;AAAA,MACX,GAAA;AAAA,MACC,GAAG,IAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA,CAAC,QAAA,EAAA,EAAS,aAAA,EAAW,IAAA,EAAC;AAAA;AAAA,GACxB;AAEJ,CAAC;;;;"}
@@ -1,11 +1,13 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
2
  import { useIcon, Button } from '@salt-ds/core';
3
3
  import { forwardRef } from 'react';
4
+ import { useCarouselContext } from './CarouselContext.js';
4
5
  import { usePrevNextButtons } from './usePrevNextButtons.js';
5
6
 
6
7
  const CarouselPreviousButton = forwardRef(function CarouselPreviousButton2({ className, onClick, ...rest }, ref) {
7
8
  const { PreviousIcon } = useIcon();
8
9
  const { prevBtnDisabled, onPrevButtonClick } = usePrevNextButtons();
10
+ const { carouselId } = useCarouselContext();
9
11
  const handleClick = (event) => {
10
12
  onPrevButtonClick();
11
13
  onClick == null ? void 0 : onClick(event);
@@ -16,7 +18,8 @@ const CarouselPreviousButton = forwardRef(function CarouselPreviousButton2({ cla
16
18
  onClick: handleClick,
17
19
  disabled: prevBtnDisabled,
18
20
  focusableWhenDisabled: true,
19
- appearance: "bordered",
21
+ appearance: "transparent",
22
+ "aria-controls": `${carouselId}-slides`,
20
23
  sentiment: "neutral",
21
24
  "aria-label": "Previous slide",
22
25
  ref,
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselPreviousButton.js","sources":["../src/CarouselPreviousButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, useIcon } from \"@salt-ds/core\";\nimport { forwardRef, type MouseEventHandler } from \"react\";\nimport { usePrevNextButtons } from \"./usePrevNextButtons\";\n\n/**\n * Props for the CarouselPreviousButton component.\n */\nexport interface CarouselPreviousButtonProps\n extends Omit<ButtonProps, \"variant\" | \"loading\" | \"loadingAnnouncement\"> {}\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> = (event) => {\n onPrevButtonClick();\n onClick?.(event);\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":";;;;;AAUa,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,EAAM,MAAA,WAAA,GAAoD,CAAC,KAAU,KAAA;AACnE,IAAkB,iBAAA,EAAA;AAClB,IAAU,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAA,KAAA,CAAA;AAAA,GACZ;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;;;;"}
1
+ {"version":3,"file":"CarouselPreviousButton.js","sources":["../src/CarouselPreviousButton.tsx"],"sourcesContent":["import { Button, type ButtonProps, useIcon } from \"@salt-ds/core\";\nimport { forwardRef, type MouseEventHandler } from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport { usePrevNextButtons } from \"./usePrevNextButtons\";\n\n/**\n * Props for the CarouselPreviousButton component.\n */\nexport interface CarouselPreviousButtonProps\n extends Omit<ButtonProps, \"variant\" | \"loading\" | \"loadingAnnouncement\"> {}\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 { carouselId } = useCarouselContext();\n\n const handleClick: MouseEventHandler<HTMLButtonElement> = (event) => {\n onPrevButtonClick();\n onClick?.(event);\n };\n\n return (\n <Button\n onClick={handleClick}\n disabled={prevBtnDisabled}\n focusableWhenDisabled\n appearance=\"transparent\"\n aria-controls={`${carouselId}-slides`}\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":";;;;;;AAWO,MAAM,sBAAA,GAAyB,UAAA,CAGpC,SAASA,uBAAAA,CAAuB,EAAE,WAAW,OAAA,EAAS,GAAG,IAAA,EAAK,EAAG,GAAA,EAAK;AACtE,EAAA,MAAM,EAAE,YAAA,EAAa,GAAI,OAAA,EAAQ;AACjC,EAAA,MAAM,EAAE,eAAA,EAAiB,iBAAA,EAAkB,GAAI,kBAAA,EAAmB;AAElE,EAAA,MAAM,EAAE,UAAA,EAAW,GAAI,kBAAA,EAAmB;AAE1C,EAAA,MAAM,WAAA,GAAoD,CAAC,KAAA,KAAU;AACnE,IAAA,iBAAA,EAAkB;AAClB,IAAA,OAAA,IAAA,IAAA,GAAA,MAAA,GAAA,OAAA,CAAU,KAAA,CAAA;AAAA,EACZ,CAAA;AAEA,EAAA,uBACE,GAAA;AAAA,IAAC,MAAA;AAAA,IAAA;AAAA,MACC,OAAA,EAAS,WAAA;AAAA,MACT,QAAA,EAAU,eAAA;AAAA,MACV,qBAAA,EAAqB,IAAA;AAAA,MACrB,UAAA,EAAW,aAAA;AAAA,MACX,eAAA,EAAe,GAAG,UAAU,CAAA,OAAA,CAAA;AAAA,MAC5B,SAAA,EAAU,SAAA;AAAA,MACV,YAAA,EAAW,gBAAA;AAAA,MACX,GAAA;AAAA,MACC,GAAG,IAAA;AAAA,MAEJ,QAAA,kBAAA,GAAA,CAAC,YAAA,EAAA,EAAa,aAAA,EAAW,IAAA,EAAC;AAAA;AAAA,GAC5B;AAEJ,CAAC;;;;"}
@@ -1,11 +1,9 @@
1
- import { jsxs } from 'react/jsx-runtime';
1
+ import { jsx } from 'react/jsx-runtime';
2
2
  import { makePrefixer, Text } from '@salt-ds/core';
3
- import { useComponentCssInjection } from '@salt-ds/styles';
4
- import { useWindow } from '@salt-ds/window';
5
3
  import { clsx } from 'clsx';
6
4
  import { useState, useEffect } from 'react';
7
5
  import { useCarouselContext } from './CarouselContext.js';
8
- import css_248z from './CarouselProgressLabel.css.js';
6
+ import { getVisibleSlideIndexes } from './getVisibleSlideIndexes.js';
9
7
 
10
8
  const withBaseName = makePrefixer("saltCarouselTabList");
11
9
  function CarouselProgressLabel({
@@ -14,35 +12,20 @@ function CarouselProgressLabel({
14
12
  children,
15
13
  ...props
16
14
  }) {
17
- const targetWindow = useWindow();
18
- useComponentCssInjection({
19
- testId: "salt-carousel-progress-label",
20
- css: css_248z,
21
- window: targetWindow
22
- });
23
15
  const { emblaApi } = useCarouselContext();
24
- const [currentSlide, setCurrentSlide] = useState("");
25
- const [totalSlides, setTotalSlides] = useState(0);
16
+ const [progress, setProgress] = useState("");
26
17
  useEffect(() => {
27
18
  const handleSelect = (emblaApi2) => {
28
- const slideIndexInView = (emblaApi2 == null ? void 0 : emblaApi2.selectedScrollSnap()) ?? 0;
19
+ const selectedScrollSnap = (emblaApi2 == null ? void 0 : emblaApi2.selectedScrollSnap()) ?? 0;
29
20
  const numberOfSlides = (emblaApi2 == null ? void 0 : emblaApi2.slideNodes().length) ?? 0;
30
- const scrollSnaps = (emblaApi2 == null ? void 0 : emblaApi2.scrollSnapList()) ?? [];
31
- const slidesPerTransition = numberOfSlides ? Math.ceil(numberOfSlides / scrollSnaps.length) : 0;
32
- const startSlideNumber = Math.min(
33
- slideIndexInView * slidesPerTransition + 1,
34
- numberOfSlides - (slidesPerTransition - 1)
21
+ const visibleSlides = getVisibleSlideIndexes(
22
+ emblaApi2,
23
+ selectedScrollSnap
35
24
  );
36
- const endSlideNumber = Math.min(
37
- startSlideNumber + slidesPerTransition - 1,
38
- numberOfSlides
39
- );
40
- if (startSlideNumber === endSlideNumber) {
41
- setCurrentSlide(startSlideNumber.toString(10));
42
- } else {
43
- setCurrentSlide(`${startSlideNumber}-${endSlideNumber}`);
44
- }
45
- setTotalSlides(numberOfSlides);
25
+ const startSlideNumber = visibleSlides.length >= 1 ? visibleSlides[0] : 0;
26
+ const endSlideNumber = visibleSlides.length > 1 ? visibleSlides[visibleSlides.length - 1] : 0;
27
+ const slidePosition = endSlideNumber ? `${startSlideNumber}-${endSlideNumber}` : startSlideNumber;
28
+ setProgress(`Slide ${slidePosition} of ${numberOfSlides}`);
46
29
  };
47
30
  if (!emblaApi) return;
48
31
  emblaApi.on("init", handleSelect).on("reInit", handleSelect).on("select", handleSelect);
@@ -51,12 +34,7 @@ function CarouselProgressLabel({
51
34
  emblaApi.off("init", handleSelect).off("reInit", handleSelect).off("select", handleSelect);
52
35
  };
53
36
  }, [emblaApi]);
54
- return /* @__PURE__ */ jsxs(Text, { className: clsx(withBaseName(), className), ...props, children: [
55
- "Slide ",
56
- currentSlide,
57
- " of ",
58
- totalSlides
59
- ] });
37
+ return /* @__PURE__ */ jsx(Text, { className: clsx(withBaseName(), className), ...props, children: progress });
60
38
  }
61
39
 
62
40
  export { CarouselProgressLabel };
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselProgressLabel.js","sources":["../src/CarouselProgressLabel.tsx"],"sourcesContent":["import { makePrefixer, Text, type TextProps } 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 { 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 useEffect(() => {\n const handleSelect = (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 if (!emblaApi) return;\n emblaApi\n .on(\"init\", handleSelect)\n .on(\"reInit\", handleSelect)\n .on(\"select\", handleSelect);\n handleSelect(emblaApi);\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]);\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,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,YAAA,GAAe,CAACC,SAAgC,KAAA;AACpD,MAAA,MAAM,gBAAmBA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,kBAAwB,EAAA,KAAA,CAAA;AAC3D,MAAA,MAAM,cAAiBA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,aAAa,MAAU,KAAA,CAAA;AACxD,MAAA,MAAM,WAAcA,GAAAA,CAAAA,SAAAA,IAAA,IAAAA,GAAAA,MAAAA,GAAAA,SAAAA,CAAU,qBAAoB,EAAC;AACnD,MAAA,MAAM,sBAAsB,cACxB,GAAA,IAAA,CAAK,KAAK,cAAiB,GAAA,WAAA,CAAY,MAAM,CAC7C,GAAA,CAAA;AACJ,MAAA,MAAM,mBAAmB,IAAK,CAAA,GAAA;AAAA,QAC5B,mBAAmB,mBAAsB,GAAA,CAAA;AAAA,QACzC,kBAAkB,mBAAsB,GAAA,CAAA;AAAA,OAC1C;AACA,MAAA,MAAM,iBAAiB,IAAK,CAAA,GAAA;AAAA,QAC1B,mBAAmB,mBAAsB,GAAA,CAAA;AAAA,QACzC;AAAA,OACF;AAEA,MAAA,IAAI,qBAAqB,cAAgB,EAAA;AACvC,QAAgB,eAAA,CAAA,gBAAA,CAAiB,QAAS,CAAA,EAAE,CAAC,CAAA;AAAA,OACxC,MAAA;AACL,QAAA,eAAA,CAAgB,CAAG,EAAA,gBAAgB,CAAI,CAAA,EAAA,cAAc,CAAE,CAAA,CAAA;AAAA;AAEzD,MAAA,cAAA,CAAe,cAAc,CAAA;AAAA,KAC/B;AAEA,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,GACF,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,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;;;;"}
1
+ {"version":3,"file":"CarouselProgressLabel.js","sources":["../src/CarouselProgressLabel.tsx"],"sourcesContent":["import { makePrefixer, Text, type TextProps } from \"@salt-ds/core\";\nimport { clsx } from \"clsx\";\nimport type { EmblaCarouselType } from \"embla-carousel\";\nimport { useEffect, useState } from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport { getVisibleSlideIndexes } from \"./getVisibleSlideIndexes\";\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 { emblaApi } = useCarouselContext();\n\n const [progress, setProgress] = useState(\"\");\n\n useEffect(() => {\n const handleSelect = (emblaApi: EmblaCarouselType) => {\n const selectedScrollSnap = emblaApi?.selectedScrollSnap() ?? 0;\n const numberOfSlides = emblaApi?.slideNodes().length ?? 0;\n const visibleSlides = getVisibleSlideIndexes(\n emblaApi,\n selectedScrollSnap,\n );\n const startSlideNumber = visibleSlides.length >= 1 ? visibleSlides[0] : 0;\n const endSlideNumber =\n visibleSlides.length > 1 ? visibleSlides[visibleSlides.length - 1] : 0;\n const slidePosition = endSlideNumber\n ? `${startSlideNumber}-${endSlideNumber}`\n : startSlideNumber;\n setProgress(`Slide ${slidePosition} of ${numberOfSlides}`);\n };\n\n if (!emblaApi) return;\n emblaApi\n .on(\"init\", handleSelect)\n .on(\"reInit\", handleSelect)\n .on(\"select\", handleSelect);\n handleSelect(emblaApi);\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]);\n\n return (\n <Text className={clsx(withBaseName(), className)} {...props}>\n {progress}\n </Text>\n );\n}\n"],"names":["emblaApi"],"mappings":";;;;;;;AAYA,MAAM,YAAA,GAAe,aAAa,qBAAqB,CAAA;AAEhD,SAAS,qBAAA,CAAsB;AAAA,EACpC,SAAA;AAAA,EACA,OAAA,GAAU,OAAA;AAAA,EACV,QAAA;AAAA,EACA,GAAG;AACL,CAAA,EAA+B;AAC7B,EAAA,MAAM,EAAE,QAAA,EAAS,GAAI,kBAAA,EAAmB;AAExC,EAAA,MAAM,CAAC,QAAA,EAAU,WAAW,CAAA,GAAI,SAAS,EAAE,CAAA;AAE3C,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,YAAA,GAAe,CAACA,SAAAA,KAAgC;AACpD,MAAA,MAAM,kBAAA,GAAA,CAAqBA,SAAAA,IAAA,IAAA,GAAA,MAAA,GAAAA,SAAAA,CAAU,kBAAA,EAAA,KAAwB,CAAA;AAC7D,MAAA,MAAM,cAAA,GAAA,CAAiBA,SAAAA,IAAA,IAAA,GAAA,MAAA,GAAAA,SAAAA,CAAU,aAAa,MAAA,KAAU,CAAA;AACxD,MAAA,MAAM,aAAA,GAAgB,sBAAA;AAAA,QACpBA,SAAAA;AAAA,QACA;AAAA,OACF;AACA,MAAA,MAAM,mBAAmB,aAAA,CAAc,MAAA,IAAU,CAAA,GAAI,aAAA,CAAc,CAAC,CAAA,GAAI,CAAA;AACxE,MAAA,MAAM,cAAA,GACJ,cAAc,MAAA,GAAS,CAAA,GAAI,cAAc,aAAA,CAAc,MAAA,GAAS,CAAC,CAAA,GAAI,CAAA;AACvE,MAAA,MAAM,gBAAgB,cAAA,GAClB,CAAA,EAAG,gBAAgB,CAAA,CAAA,EAAI,cAAc,CAAA,CAAA,GACrC,gBAAA;AACJ,MAAA,WAAA,CAAY,CAAA,MAAA,EAAS,aAAa,CAAA,IAAA,EAAO,cAAc,CAAA,CAAE,CAAA;AAAA,IAC3D,CAAA;AAEA,IAAA,IAAI,CAAC,QAAA,EAAU;AACf,IAAA,QAAA,CACG,EAAA,CAAG,MAAA,EAAQ,YAAY,CAAA,CACvB,EAAA,CAAG,UAAU,YAAY,CAAA,CACzB,EAAA,CAAG,QAAA,EAAU,YAAY,CAAA;AAC5B,IAAA,YAAA,CAAa,QAAQ,CAAA;AAErB,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CACG,GAAA,CAAI,MAAA,EAAQ,YAAY,CAAA,CACxB,GAAA,CAAI,UAAU,YAAY,CAAA,CAC1B,GAAA,CAAI,QAAA,EAAU,YAAY,CAAA;AAAA,IAC/B,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,uBACE,GAAA,CAAC,IAAA,EAAA,EAAK,SAAA,EAAW,IAAA,CAAK,YAAA,IAAgB,SAAS,CAAA,EAAI,GAAG,KAAA,EACnD,QAAA,EAAA,QAAA,EACH,CAAA;AAEJ;;;;"}
@@ -1,4 +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(--carousel-slide-spacing) * -1);\n}\n";
1
+ var css_248z = ".saltCarouselSlides {\n overflow: hidden;\n cursor: var(--salt-cursor-grab);\n}\n\n.saltCarouselSlides-container {\n display: flex;\n touch-action: pan-y pinch-zoom;\n margin-left: calc(var(--carousel-slide-spacing) * -1);\n}\n\n.saltCarouselSlides-sr-only {\n position: absolute;\n height: 1px;\n width: 1px;\n padding: 0;\n margin: -1px;\n overflow: hidden;\n clip: rect(0, 0, 0, 0);\n white-space: nowrap;\n border-width: 0;\n}\n\n.saltCarouselSlides-dragging {\n cursor: var(--salt-cursor-grab-active);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=CarouselSlides.css.js.map
@@ -1,79 +1,202 @@
1
1
  import { jsx } from 'react/jsx-runtime';
2
- import { makePrefixer, useForkRef } from '@salt-ds/core';
2
+ import { makePrefixer, useForkRef, useAriaAnnouncer } from '@salt-ds/core';
3
3
  import { useComponentCssInjection } from '@salt-ds/styles';
4
4
  import { useWindow } from '@salt-ds/window';
5
5
  import { clsx } from 'clsx';
6
- import { forwardRef, useRef, useEffect } from 'react';
6
+ import { forwardRef, useRef, useState, useEffect, Children, cloneElement } from 'react';
7
7
  import { useCarouselContext } from './CarouselContext.js';
8
8
  import css_248z from './CarouselSlides.css.js';
9
9
  import { createCustomSettle } from './createCustomSettle.js';
10
+ import { getVisibleSlideDescription } from './getVisibleSlideDescription.js';
11
+ import { getVisibleSlideIndexes } from './getVisibleSlideIndexes.js';
10
12
 
13
+ const ANNOUNCEMENT_DURATION = 1200;
11
14
  const withBaseName = makePrefixer("saltCarouselSlides");
15
+ const announceSlideChangesFrom = [
16
+ "drag",
17
+ "focus",
18
+ "navigation"
19
+ ];
12
20
  const CarouselSlides = forwardRef(
13
- function CarouselSlides2({ children, className, onKeyDown, ...rest }, ref) {
21
+ function CarouselSlides2({ children, className, id, onKeyDown, ...rest }, ref) {
14
22
  const targetWindow = useWindow();
15
23
  useComponentCssInjection({
16
24
  testId: "salt-carousel-slides",
17
25
  css: css_248z,
18
26
  window: targetWindow
19
27
  });
20
- const { emblaApi, emblaRef } = useCarouselContext();
21
- const carouselRef = useForkRef(ref, emblaRef);
22
- const usingArrowNavigation = useRef();
28
+ const {
29
+ disableSlideAnnouncements,
30
+ announcementState,
31
+ setAnnouncementState,
32
+ emblaApi,
33
+ emblaRef,
34
+ carouselId
35
+ } = useCarouselContext();
36
+ const containerRef = useRef(null);
37
+ const forkedEmblaRef = useForkRef(ref, emblaRef);
38
+ const carouselRef = useForkRef(
39
+ forkedEmblaRef,
40
+ containerRef
41
+ );
42
+ const slideRefs = useRef([]);
43
+ const [focusedSlideIndex, setFocusedSlideIndex] = useState(-1);
44
+ const [dragging, setDragging] = useState(false);
45
+ const focusOnSettle = useRef(false);
46
+ const [stableScrollSnap, setStableScrollSnap] = useState(void 0);
47
+ const visibleSlideIndexes = getVisibleSlideIndexes(
48
+ emblaApi,
49
+ stableScrollSnap ?? 0
50
+ );
51
+ const { announce } = useAriaAnnouncer();
23
52
  useEffect(() => {
24
53
  const handleSettle = (emblaApi2) => {
25
- if (!usingArrowNavigation.current) {
26
- return;
27
- }
28
- const slideIndexInView = (emblaApi2 == null ? void 0 : emblaApi2.selectedScrollSnap()) ?? 0;
29
- const snappedSlide = emblaApi2.slideNodes()[slideIndexInView];
30
- if (snappedSlide) {
31
- const focusableElements = snappedSlide.querySelectorAll(
32
- 'a, button, input, textarea, select, [tabindex]:not([tabindex="-1"])'
33
- );
34
- if (focusableElements.length > 0) {
35
- focusableElements[0].focus();
36
- }
37
- }
38
- usingArrowNavigation.current = false;
54
+ const selectedScrollSnap = (emblaApi2 == null ? void 0 : emblaApi2.selectedScrollSnap()) ?? 0;
55
+ setStableScrollSnap(selectedScrollSnap);
56
+ const numberOfSnaps = (emblaApi2 == null ? void 0 : emblaApi2.scrollSnapList().length) ?? 1;
57
+ const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;
58
+ const settledSlideIndex = Math.floor(
59
+ selectedScrollSnap * numberOfSlidesPerSnap
60
+ );
61
+ setFocusedSlideIndex(settledSlideIndex);
39
62
  };
40
63
  if (!emblaApi) {
41
64
  return;
42
65
  }
43
66
  const scrollCallback = createCustomSettle(handleSettle);
67
+ const pointerDownCallback = () => {
68
+ setAnnouncementState("drag");
69
+ };
44
70
  emblaApi.on("scroll", scrollCallback);
71
+ emblaApi.on("pointerDown", pointerDownCallback);
45
72
  return () => {
46
73
  emblaApi.off("scroll", scrollCallback);
74
+ emblaApi.off("pointerDown", pointerDownCallback);
47
75
  };
48
- }, [emblaApi]);
76
+ }, [emblaApi, setAnnouncementState]);
77
+ useEffect(() => {
78
+ var _a;
79
+ if (!focusOnSettle.current || stableScrollSnap === void 0) {
80
+ return;
81
+ }
82
+ (_a = slideRefs.current[focusedSlideIndex]) == null ? void 0 : _a.focus();
83
+ setAnnouncementState("focus");
84
+ focusOnSettle.current = false;
85
+ }, [stableScrollSnap, focusedSlideIndex, setAnnouncementState]);
86
+ useEffect(() => {
87
+ const numberOfSnaps = (emblaApi == null ? void 0 : emblaApi.scrollSnapList().length) ?? 1;
88
+ const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;
89
+ if (focusedSlideIndex >= 0) {
90
+ const nearestScrollSnap = Math.floor(
91
+ focusedSlideIndex / numberOfSlidesPerSnap
92
+ );
93
+ if ((emblaApi == null ? void 0 : emblaApi.selectedScrollSnap()) !== nearestScrollSnap) {
94
+ emblaApi == null ? void 0 : emblaApi.scrollTo(nearestScrollSnap);
95
+ focusOnSettle.current = true;
96
+ }
97
+ } else if (focusedSlideIndex === -1) {
98
+ const initialSnap = emblaApi == null ? void 0 : emblaApi.selectedScrollSnap();
99
+ const initialSlideIndex = initialSnap !== void 0 ? Math.floor(initialSnap * numberOfSlidesPerSnap) : 0;
100
+ setFocusedSlideIndex(initialSlideIndex);
101
+ setStableScrollSnap(initialSnap);
102
+ }
103
+ }, [focusedSlideIndex, emblaApi]);
104
+ useEffect(() => {
105
+ if (disableSlideAnnouncements === false) {
106
+ setAnnouncementState(void 0);
107
+ }
108
+ }, [disableSlideAnnouncements, setAnnouncementState]);
109
+ useEffect(() => {
110
+ if (stableScrollSnap === void 0 || disableSlideAnnouncements || !announcementState || announceSlideChangesFrom.indexOf(announcementState) === -1) {
111
+ return;
112
+ }
113
+ const announcement = getVisibleSlideDescription(
114
+ emblaApi,
115
+ stableScrollSnap
116
+ );
117
+ announce(announcement, ANNOUNCEMENT_DURATION);
118
+ }, [
119
+ announce,
120
+ announcementState,
121
+ disableSlideAnnouncements,
122
+ stableScrollSnap,
123
+ emblaApi
124
+ ]);
49
125
  const handleKeyDown = (event) => {
50
126
  if (event.repeat) {
51
127
  return;
52
128
  }
129
+ const numberOfSnaps = (emblaApi == null ? void 0 : emblaApi.scrollSnapList().length) ?? 1;
130
+ const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;
131
+ const currentSnap = Math.floor(focusedSlideIndex / numberOfSlidesPerSnap);
53
132
  switch (event.key) {
54
133
  case "ArrowLeft": {
55
134
  event.preventDefault();
56
- emblaApi == null ? void 0 : emblaApi.scrollPrev();
57
- usingArrowNavigation.current = true;
135
+ const prevSnap = Math.max(currentSnap - 1, 0);
136
+ const newIndex = prevSnap * numberOfSlidesPerSnap;
137
+ setFocusedSlideIndex(newIndex);
58
138
  break;
59
139
  }
60
140
  case "ArrowRight": {
61
141
  event.preventDefault();
62
- emblaApi == null ? void 0 : emblaApi.scrollNext();
63
- usingArrowNavigation.current = true;
142
+ const nextSnap = Math.min(currentSnap + 1, numberOfSnaps - 1);
143
+ const newIndex = nextSnap * numberOfSlidesPerSnap;
144
+ setFocusedSlideIndex(newIndex);
64
145
  break;
65
146
  }
66
147
  }
67
148
  onKeyDown == null ? void 0 : onKeyDown(event);
68
149
  };
150
+ const handleMouseDown = (event) => {
151
+ var _a;
152
+ setDragging(true);
153
+ (_a = rest.onMouseDown) == null ? void 0 : _a.call(rest, event);
154
+ };
155
+ const handleMouseUp = (event) => {
156
+ var _a;
157
+ setDragging(false);
158
+ (_a = rest.onMouseUp) == null ? void 0 : _a.call(rest, event);
159
+ };
69
160
  return /* @__PURE__ */ jsx(
70
161
  "div",
71
162
  {
72
163
  onKeyDown: handleKeyDown,
164
+ onMouseDown: handleMouseDown,
165
+ onMouseUp: handleMouseUp,
73
166
  ref: carouselRef,
74
- className: clsx(withBaseName(), className),
167
+ className: clsx(
168
+ withBaseName(),
169
+ { [withBaseName("dragging")]: dragging },
170
+ className
171
+ ),
75
172
  ...rest,
76
- children: /* @__PURE__ */ jsx("div", { className: withBaseName("container"), children })
173
+ children: /* @__PURE__ */ jsx(
174
+ "div",
175
+ {
176
+ className: withBaseName("container"),
177
+ id: id ?? `${carouselId}-slides`,
178
+ children: Children.map(children, (child, index) => {
179
+ const childElement = child;
180
+ const existingId = childElement.props.id;
181
+ const isFocused = focusedSlideIndex === index;
182
+ const isHidden = !visibleSlideIndexes.includes(index + 1) && !isFocused;
183
+ const element = child;
184
+ return cloneElement(element, {
185
+ "aria-hidden": isHidden,
186
+ id: existingId ?? `${carouselId}-slide${index + 1}`,
187
+ onFocus: (event) => {
188
+ var _a, _b;
189
+ setFocusedSlideIndex(index);
190
+ (_b = (_a = element.props) == null ? void 0 : _a.onFocus) == null ? void 0 : _b.call(_a, event);
191
+ },
192
+ tabIndex: !isHidden ? 0 : -1,
193
+ ref: (el) => {
194
+ slideRefs.current[index] = el;
195
+ }
196
+ });
197
+ })
198
+ }
199
+ )
77
200
  }
78
201
  );
79
202
  }
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselSlides.js","sources":["../src/CarouselSlides.tsx"],"sourcesContent":["import { makePrefixer, useForkRef } 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 {\n type ComponentPropsWithoutRef,\n forwardRef,\n type KeyboardEvent,\n useEffect,\n useRef,\n} from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport carouselSlidesCss from \"./CarouselSlides.css\";\nimport { createCustomSettle } from \"./createCustomSettle\";\n\n/**\n * Props for the CarouselSlides component.\n */\nexport interface CarouselSlidesProps extends ComponentPropsWithoutRef<\"div\"> {}\n\nconst withBaseName = makePrefixer(\"saltCarouselSlides\");\n\nexport const CarouselSlides = forwardRef<HTMLDivElement, CarouselSlidesProps>(\n function CarouselSlides({ children, className, onKeyDown, ...rest }, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-slides\",\n css: carouselSlidesCss,\n window: targetWindow,\n });\n const { emblaApi, emblaRef } = useCarouselContext();\n\n const carouselRef = useForkRef<HTMLDivElement>(ref, emblaRef);\n\n const usingArrowNavigation = useRef<boolean>();\n\n useEffect(() => {\n const handleSettle = (emblaApi: EmblaCarouselType) => {\n if (!usingArrowNavigation.current) {\n return;\n }\n const slideIndexInView = emblaApi?.selectedScrollSnap() ?? 0;\n const snappedSlide = emblaApi.slideNodes()[slideIndexInView];\n if (snappedSlide) {\n const focusableElements = snappedSlide.querySelectorAll<HTMLElement>(\n 'a, button, input, textarea, select, [tabindex]:not([tabindex=\"-1\"])',\n );\n if (focusableElements.length > 0) {\n focusableElements[0].focus();\n }\n }\n usingArrowNavigation.current = false;\n };\n\n if (!emblaApi) {\n return;\n }\n const scrollCallback = createCustomSettle(handleSettle);\n emblaApi.on(\"scroll\", scrollCallback);\n // Cleanup listener on component unmount\n return () => {\n emblaApi.off(\"scroll\", scrollCallback);\n };\n }, [emblaApi]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.repeat) {\n return;\n }\n switch (event.key) {\n case \"ArrowLeft\": {\n event.preventDefault();\n emblaApi?.scrollPrev();\n usingArrowNavigation.current = true;\n break;\n }\n case \"ArrowRight\": {\n event.preventDefault();\n emblaApi?.scrollNext();\n usingArrowNavigation.current = true;\n break;\n }\n }\n onKeyDown?.(event);\n };\n\n return (\n <div\n onKeyDown={handleKeyDown}\n ref={carouselRef}\n className={clsx(withBaseName(), className)}\n {...rest}\n >\n <div className={withBaseName(\"container\")}>{children}</div>\n </div>\n );\n },\n);\n"],"names":["CarouselSlides","carouselSlidesCss","emblaApi"],"mappings":"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"}
1
+ {"version":3,"file":"CarouselSlides.js","sources":["../src/CarouselSlides.tsx"],"sourcesContent":["import { makePrefixer, useAriaAnnouncer, useForkRef } 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 {\n Children,\n type ComponentPropsWithoutRef,\n cloneElement,\n type FocusEvent,\n forwardRef,\n type KeyboardEvent,\n type MouseEventHandler,\n type ReactElement,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport {\n type CarouselAnnouncementTrigger,\n useCarouselContext,\n} from \"./CarouselContext\";\nimport carouselSlidesCss from \"./CarouselSlides.css\";\nimport { createCustomSettle } from \"./createCustomSettle\";\nimport { getVisibleSlideDescription } from \"./getVisibleSlideDescription\";\nimport { getVisibleSlideIndexes } from \"./getVisibleSlideIndexes\";\n\nconst ANNOUNCEMENT_DURATION = 1200;\n\n/**\n * Props for the CarouselSlides component.\n */\nexport interface CarouselSlidesProps extends ComponentPropsWithoutRef<\"div\"> {}\n\nconst withBaseName = makePrefixer(\"saltCarouselSlides\");\n\nconst announceSlideChangesFrom: CarouselAnnouncementTrigger[] = [\n \"drag\",\n \"focus\",\n \"navigation\",\n];\n\nexport const CarouselSlides = forwardRef<HTMLDivElement, CarouselSlidesProps>(\n function CarouselSlides(\n { children, className, id, onKeyDown, ...rest },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-slides\",\n css: carouselSlidesCss,\n window: targetWindow,\n });\n const {\n disableSlideAnnouncements,\n announcementState,\n setAnnouncementState,\n emblaApi,\n emblaRef,\n carouselId,\n } = useCarouselContext();\n\n const containerRef = useRef<HTMLDivElement>(null);\n const forkedEmblaRef = useForkRef<HTMLDivElement>(ref, emblaRef);\n const carouselRef = useForkRef<HTMLDivElement>(\n forkedEmblaRef,\n containerRef,\n );\n\n const slideRefs = useRef<(HTMLDivElement | null)[]>([]);\n const [focusedSlideIndex, setFocusedSlideIndex] = useState<number>(-1);\n const [dragging, setDragging] = useState(false);\n const focusOnSettle = useRef<boolean>(false);\n\n const [stableScrollSnap, setStableScrollSnap] = useState<\n number | undefined\n >(undefined);\n\n const visibleSlideIndexes = getVisibleSlideIndexes(\n emblaApi,\n stableScrollSnap ?? 0,\n );\n const { announce } = useAriaAnnouncer();\n\n useEffect(() => {\n const handleSettle = (emblaApi: EmblaCarouselType) => {\n const selectedScrollSnap = emblaApi?.selectedScrollSnap() ?? 0;\n setStableScrollSnap(selectedScrollSnap);\n const numberOfSnaps = emblaApi?.scrollSnapList().length ?? 1;\n const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;\n const settledSlideIndex = Math.floor(\n selectedScrollSnap * numberOfSlidesPerSnap,\n );\n setFocusedSlideIndex(settledSlideIndex);\n };\n\n if (!emblaApi) {\n return;\n }\n\n const scrollCallback = createCustomSettle(handleSettle);\n const pointerDownCallback = () => {\n setAnnouncementState(\"drag\");\n };\n emblaApi.on(\"scroll\", scrollCallback);\n emblaApi.on(\"pointerDown\", pointerDownCallback);\n // Cleanup listener on component unmount\n return () => {\n emblaApi.off(\"scroll\", scrollCallback);\n emblaApi.off(\"pointerDown\", pointerDownCallback);\n };\n }, [emblaApi, setAnnouncementState]);\n\n useEffect(() => {\n if (!focusOnSettle.current || stableScrollSnap === undefined) {\n return;\n }\n slideRefs.current[focusedSlideIndex]?.focus();\n setAnnouncementState(\"focus\");\n focusOnSettle.current = false;\n }, [stableScrollSnap, focusedSlideIndex, setAnnouncementState]);\n\n useEffect(() => {\n const numberOfSnaps = emblaApi?.scrollSnapList().length ?? 1;\n const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;\n if (focusedSlideIndex >= 0) {\n const nearestScrollSnap = Math.floor(\n focusedSlideIndex / numberOfSlidesPerSnap,\n );\n if (emblaApi?.selectedScrollSnap() !== nearestScrollSnap) {\n emblaApi?.scrollTo(nearestScrollSnap);\n focusOnSettle.current = true;\n }\n } else if (focusedSlideIndex === -1) {\n const initialSnap = emblaApi?.selectedScrollSnap();\n const initialSlideIndex =\n initialSnap !== undefined\n ? Math.floor(initialSnap * numberOfSlidesPerSnap)\n : 0;\n setFocusedSlideIndex(initialSlideIndex);\n setStableScrollSnap(initialSnap);\n }\n }, [focusedSlideIndex, emblaApi]);\n\n useEffect(() => {\n if (disableSlideAnnouncements === false) {\n setAnnouncementState(undefined);\n }\n }, [disableSlideAnnouncements, setAnnouncementState]);\n\n useEffect(() => {\n if (\n stableScrollSnap === undefined ||\n disableSlideAnnouncements ||\n !announcementState ||\n announceSlideChangesFrom.indexOf(announcementState) === -1\n ) {\n return;\n }\n const announcement = getVisibleSlideDescription(\n emblaApi,\n stableScrollSnap,\n );\n announce(announcement, ANNOUNCEMENT_DURATION);\n }, [\n announce,\n announcementState,\n disableSlideAnnouncements,\n stableScrollSnap,\n emblaApi,\n ]);\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.repeat) {\n return;\n }\n const numberOfSnaps = emblaApi?.scrollSnapList().length ?? 1;\n const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;\n\n // Find the current snap\n const currentSnap = Math.floor(focusedSlideIndex / numberOfSlidesPerSnap);\n\n switch (event.key) {\n case \"ArrowLeft\": {\n event.preventDefault();\n const prevSnap = Math.max(currentSnap - 1, 0);\n const newIndex = prevSnap * numberOfSlidesPerSnap;\n setFocusedSlideIndex(newIndex);\n break;\n }\n case \"ArrowRight\": {\n event.preventDefault();\n const nextSnap = Math.min(currentSnap + 1, numberOfSnaps - 1);\n const newIndex = nextSnap * numberOfSlidesPerSnap;\n setFocusedSlideIndex(newIndex);\n break;\n }\n }\n onKeyDown?.(event);\n };\n\n const handleMouseDown: MouseEventHandler<HTMLDivElement> = (event) => {\n setDragging(true);\n rest.onMouseDown?.(event);\n };\n const handleMouseUp: MouseEventHandler<HTMLDivElement> = (event) => {\n setDragging(false);\n rest.onMouseUp?.(event);\n };\n\n return (\n <div\n onKeyDown={handleKeyDown}\n onMouseDown={handleMouseDown}\n onMouseUp={handleMouseUp}\n ref={carouselRef}\n className={clsx(\n withBaseName(),\n { [withBaseName(\"dragging\")]: dragging },\n className,\n )}\n {...rest}\n >\n <div\n className={withBaseName(\"container\")}\n id={id ?? `${carouselId}-slides`}\n >\n {Children.map(children, (child, index) => {\n const childElement = child as ReactElement;\n const existingId = childElement.props.id;\n const isFocused = focusedSlideIndex === index;\n const isHidden =\n !visibleSlideIndexes.includes(index + 1) && !isFocused;\n const element = child as ReactElement;\n return cloneElement(element, {\n \"aria-hidden\": isHidden,\n id: existingId ?? `${carouselId}-slide${index + 1}`,\n onFocus: (event: FocusEvent) => {\n setFocusedSlideIndex(index);\n element.props?.onFocus?.(event);\n },\n tabIndex: !isHidden ? 0 : -1,\n ref: (el: HTMLDivElement) => {\n slideRefs.current[index] = el;\n },\n });\n })}\n </div>\n </div>\n );\n },\n);\n"],"names":["CarouselSlides","carouselSlidesCss","emblaApi"],"mappings":"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"}
@@ -1,4 +1,4 @@
1
- var css_248z = ".saltCarouselTab {\n position: relative;\n width: var(--salt-size-selectable);\n height: var(--salt-size-selectable);\n border: none;\n box-shadow: inset 0 0 0 var(--salt-size-fixed-100) var(--salt-selectable-borderColor);\n -webkit-tap-highlight-color: var(--salt-selectable-borderColor-hover);\n -webkit-appearance: none;\n appearance: none;\n background-color: transparent;\n touch-action: manipulation;\n display: inline-flex;\n text-decoration: none;\n cursor: pointer;\n padding: 0;\n margin: 0;\n align-items: center;\n justify-content: center;\n border-radius: var(--salt-palette-corner-strongest);\n transition: box-shadow var(--salt-duration-perceptible) ease-in-out;\n}\n\n.saltCarouselTab:after {\n content: \"\";\n position: absolute;\n width: var(--salt-size-selectable);\n height: var(--salt-size-selectable);\n border-radius: 50%;\n background-color: transparent;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n.saltCarouselTab:focus-visible {\n outline-style: var(--salt-focused-outlineStyle);\n outline-width: var(--salt-focused-outlineWidth);\n outline-color: var(--salt-focused-outlineColor);\n outline-offset: var(--salt-focused-outlineOffset);\n background: var(--salt-selectable-background-hover);\n border-color: var(--salt-selectable-borderColor-hover);\n}\n\n.saltCarouselTab-selected {\n box-shadow: inset 0 0 0 var(--salt-size-selectable) var(--salt-selectable-borderColor-selected);\n}\n";
1
+ var css_248z = ".saltCarouselTab {\n position: relative;\n width: var(--salt-size-selectable);\n height: var(--salt-size-selectable);\n border: none;\n box-shadow: inset 0 0 0 var(--salt-size-fixed-100) var(--salt-selectable-borderColor);\n -webkit-tap-highlight-color: var(--salt-selectable-borderColor-hover);\n -webkit-appearance: none;\n appearance: none;\n background-color: transparent;\n touch-action: manipulation;\n display: inline-flex;\n text-decoration: none;\n cursor: pointer;\n padding: 0;\n margin: 0;\n align-items: center;\n justify-content: center;\n border-radius: var(--salt-palette-corner-strongest);\n transition: box-shadow var(--salt-duration-perceptible) ease-in-out;\n}\n\n.saltCarouselTab:after {\n content: \"\";\n position: absolute;\n width: var(--salt-size-selectable);\n height: var(--salt-size-selectable);\n border-radius: 50%;\n background-color: transparent;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n}\n\n.saltCarouselTab:focus-visible {\n outline: var(--saltRadioButton-outline, var(--salt-focused-outline));\n outline-offset: var(--salt-spacing-fixed-100);\n}\n\n.saltCarouselTab-selected {\n box-shadow: inset 0 0 0 var(--salt-size-selectable) var(--salt-selectable-borderColor-selected);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=CarouselTab.css.js.map
@@ -10,9 +10,6 @@ const withBaseName = makePrefixer("saltCarouselTab");
10
10
  const useCarouselTab = (emblaApi) => {
11
11
  const [selectedIndex, setSelectedIndex] = useState(0);
12
12
  const [scrollSnaps, setScrollSnaps] = useState([]);
13
- const handleClick = (index) => {
14
- emblaApi == null ? void 0 : emblaApi.scrollTo(index);
15
- };
16
13
  useEffect(() => {
17
14
  const handleInit = (emblaApi2) => {
18
15
  setScrollSnaps(emblaApi2.scrollSnapList());
@@ -32,8 +29,7 @@ const useCarouselTab = (emblaApi) => {
32
29
  }, [emblaApi]);
33
30
  return {
34
31
  selectedIndex,
35
- scrollSnaps,
36
- onClick: handleClick
32
+ scrollSnaps
37
33
  };
38
34
  };
39
35
  const CarouselTab = forwardRef(
@@ -1 +1 @@
1
- {"version":3,"file":"CarouselTab.js","sources":["../src/CarouselTab.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 { EmblaCarouselType } from \"embla-carousel\";\nimport {\n type ComponentPropsWithRef,\n forwardRef,\n useEffect,\n useState,\n} from \"react\";\nimport carouselTabCss from \"./CarouselTab.css\";\n\n/**\n * Type definition for the UseCarouselTab hook.\n * Provides state and handlers for tablist navigation in a carousel.\n */\ntype UseCarouselTabProps = {\n /**\n * The index of the currently selected slide.\n */\n selectedIndex: number;\n\n /**\n * An array of scroll snap positions for the carousel slides.\n */\n scrollSnaps: number[];\n\n /**\n * Handler function for clicking a tab button to navigate to a specific slide.\n *\n * @param index - The index of the slide to navigate to.\n */\n onClick: (index: number) => void;\n};\n\nconst withBaseName = makePrefixer(\"saltCarouselTab\");\n\nexport const useCarouselTab = (\n emblaApi: EmblaCarouselType | undefined,\n): UseCarouselTabProps => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [scrollSnaps, setScrollSnaps] = useState<number[]>([]);\n\n const handleClick = (index: number) => {\n emblaApi?.scrollTo(index);\n };\n\n useEffect(() => {\n const handleInit = (emblaApi: EmblaCarouselType) => {\n setScrollSnaps(emblaApi.scrollSnapList());\n };\n\n const handleSelect = (emblaApi: EmblaCarouselType) => {\n setSelectedIndex(emblaApi.selectedScrollSnap());\n };\n\n if (!emblaApi) return;\n\n handleInit(emblaApi);\n handleSelect(emblaApi);\n emblaApi\n .on(\"init\", handleInit)\n .on(\"reInit\", handleInit)\n .on(\"select\", handleSelect);\n // Cleanup listener on component unmount\n return () => {\n emblaApi.off(\"init\", handleInit);\n emblaApi.off(\"reInit\", handleInit);\n emblaApi.off(\"select\", handleSelect);\n };\n }, [emblaApi]);\n\n return {\n selectedIndex,\n scrollSnaps,\n onClick: handleClick,\n };\n};\n\n/**\n * Props for the CarouselTab component.\n */\nexport interface CarouselTabProps extends ComponentPropsWithRef<\"button\"> {\n /**\n * Is the selected slide\n */\n selected?: boolean;\n}\n\nexport const CarouselTab = forwardRef<HTMLButtonElement, CarouselTabProps>(\n function CarouselTab(\n { children, className, selected = false, ...rest },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-tab\",\n css: carouselTabCss,\n window: targetWindow,\n });\n\n return (\n <button\n className={clsx(\n withBaseName(),\n { [withBaseName(\"selected\")]: selected },\n className,\n )}\n ref={ref}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n"],"names":["emblaApi","CarouselTab","carouselTabCss"],"mappings":";;;;;;;;AAoCA,MAAM,YAAA,GAAe,aAAa,iBAAiB,CAAA;AAEtC,MAAA,cAAA,GAAiB,CAC5B,QACwB,KAAA;AACxB,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,CAAC,CAAA;AACpD,EAAA,MAAM,CAAC,WAAa,EAAA,cAAc,CAAI,GAAA,QAAA,CAAmB,EAAE,CAAA;AAE3D,EAAM,MAAA,WAAA,GAAc,CAAC,KAAkB,KAAA;AACrC,IAAA,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,QAAS,CAAA,KAAA,CAAA;AAAA,GACrB;AAEA,EAAA,SAAA,CAAU,MAAM;AACd,IAAM,MAAA,UAAA,GAAa,CAACA,SAAgC,KAAA;AAClD,MAAeA,cAAAA,CAAAA,SAAAA,CAAS,gBAAgB,CAAA;AAAA,KAC1C;AAEA,IAAM,MAAA,YAAA,GAAe,CAACA,SAAgC,KAAA;AACpD,MAAiBA,gBAAAA,CAAAA,SAAAA,CAAS,oBAAoB,CAAA;AAAA,KAChD;AAEA,IAAA,IAAI,CAAC,QAAU,EAAA;AAEf,IAAA,UAAA,CAAW,QAAQ,CAAA;AACnB,IAAA,YAAA,CAAa,QAAQ,CAAA;AACrB,IACG,QAAA,CAAA,EAAA,CAAG,MAAQ,EAAA,UAAU,CACrB,CAAA,EAAA,CAAG,UAAU,UAAU,CAAA,CACvB,EAAG,CAAA,QAAA,EAAU,YAAY,CAAA;AAE5B,IAAA,OAAO,MAAM;AACX,MAAS,QAAA,CAAA,GAAA,CAAI,QAAQ,UAAU,CAAA;AAC/B,MAAS,QAAA,CAAA,GAAA,CAAI,UAAU,UAAU,CAAA;AACjC,MAAS,QAAA,CAAA,GAAA,CAAI,UAAU,YAAY,CAAA;AAAA,KACrC;AAAA,GACF,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAO,OAAA;AAAA,IACL,aAAA;AAAA,IACA,WAAA;AAAA,IACA,OAAS,EAAA;AAAA,GACX;AACF;AAYO,MAAM,WAAc,GAAA,UAAA;AAAA,EACzB,SAASC,YACP,CAAA,EAAE,QAAU,EAAA,SAAA,EAAW,WAAW,KAAO,EAAA,GAAG,IAAK,EAAA,EACjD,GACA,EAAA;AACA,IAAA,MAAM,eAAe,SAAU,EAAA;AAC/B,IAAyB,wBAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,mBAAA;AAAA,MACR,GAAK,EAAAC,QAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AAED,IACE,uBAAA,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,SAAW,EAAA,IAAA;AAAA,UACT,YAAa,EAAA;AAAA,UACb,EAAE,CAAC,YAAA,CAAa,UAAU,CAAC,GAAG,QAAS,EAAA;AAAA,UACvC;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA;AAGN;;;;"}
1
+ {"version":3,"file":"CarouselTab.js","sources":["../src/CarouselTab.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 { EmblaCarouselType } from \"embla-carousel\";\nimport {\n type ComponentPropsWithRef,\n forwardRef,\n useEffect,\n useState,\n} from \"react\";\nimport carouselTabCss from \"./CarouselTab.css\";\n\n/**\n * Type definition for the UseCarouselTab hook.\n * Provides state and handlers for tablist navigation in a carousel.\n */\ntype UseCarouselTabProps = {\n /**\n * The index of the currently selected slide.\n */\n selectedIndex: number;\n\n /**\n * An array of scroll snap positions for the carousel slides.\n */\n scrollSnaps: number[];\n};\n\nconst withBaseName = makePrefixer(\"saltCarouselTab\");\n\nexport const useCarouselTab = (\n emblaApi: EmblaCarouselType | undefined,\n): UseCarouselTabProps => {\n const [selectedIndex, setSelectedIndex] = useState(0);\n const [scrollSnaps, setScrollSnaps] = useState<number[]>([]);\n\n useEffect(() => {\n const handleInit = (emblaApi: EmblaCarouselType) => {\n setScrollSnaps(emblaApi.scrollSnapList());\n };\n\n const handleSelect = (emblaApi: EmblaCarouselType) => {\n setSelectedIndex(emblaApi.selectedScrollSnap());\n };\n\n if (!emblaApi) return;\n\n handleInit(emblaApi);\n handleSelect(emblaApi);\n emblaApi\n .on(\"init\", handleInit)\n .on(\"reInit\", handleInit)\n .on(\"select\", handleSelect);\n // Cleanup listener on component unmount\n return () => {\n emblaApi.off(\"init\", handleInit);\n emblaApi.off(\"reInit\", handleInit);\n emblaApi.off(\"select\", handleSelect);\n };\n }, [emblaApi]);\n\n return {\n selectedIndex,\n scrollSnaps,\n };\n};\n\n/**\n * Props for the CarouselTab component.\n */\nexport interface CarouselTabProps extends ComponentPropsWithRef<\"button\"> {\n /**\n * Is the selected slide\n */\n selected?: boolean;\n}\n\nexport const CarouselTab = forwardRef<HTMLButtonElement, CarouselTabProps>(\n function CarouselTab(\n { children, className, selected = false, ...rest },\n ref,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-tab\",\n css: carouselTabCss,\n window: targetWindow,\n });\n\n return (\n <button\n className={clsx(\n withBaseName(),\n { [withBaseName(\"selected\")]: selected },\n className,\n )}\n ref={ref}\n {...rest}\n >\n {children}\n </button>\n );\n },\n);\n"],"names":["emblaApi","CarouselTab","carouselTabCss"],"mappings":";;;;;;;;AA6BA,MAAM,YAAA,GAAe,aAAa,iBAAiB,CAAA;AAE5C,MAAM,cAAA,GAAiB,CAC5B,QAAA,KACwB;AACxB,EAAA,MAAM,CAAC,aAAA,EAAe,gBAAgB,CAAA,GAAI,SAAS,CAAC,CAAA;AACpD,EAAA,MAAM,CAAC,WAAA,EAAa,cAAc,CAAA,GAAI,QAAA,CAAmB,EAAE,CAAA;AAE3D,EAAA,SAAA,CAAU,MAAM;AACd,IAAA,MAAM,UAAA,GAAa,CAACA,SAAAA,KAAgC;AAClD,MAAA,cAAA,CAAeA,SAAAA,CAAS,gBAAgB,CAAA;AAAA,IAC1C,CAAA;AAEA,IAAA,MAAM,YAAA,GAAe,CAACA,SAAAA,KAAgC;AACpD,MAAA,gBAAA,CAAiBA,SAAAA,CAAS,oBAAoB,CAAA;AAAA,IAChD,CAAA;AAEA,IAAA,IAAI,CAAC,QAAA,EAAU;AAEf,IAAA,UAAA,CAAW,QAAQ,CAAA;AACnB,IAAA,YAAA,CAAa,QAAQ,CAAA;AACrB,IAAA,QAAA,CACG,EAAA,CAAG,MAAA,EAAQ,UAAU,CAAA,CACrB,EAAA,CAAG,UAAU,UAAU,CAAA,CACvB,EAAA,CAAG,QAAA,EAAU,YAAY,CAAA;AAE5B,IAAA,OAAO,MAAM;AACX,MAAA,QAAA,CAAS,GAAA,CAAI,QAAQ,UAAU,CAAA;AAC/B,MAAA,QAAA,CAAS,GAAA,CAAI,UAAU,UAAU,CAAA;AACjC,MAAA,QAAA,CAAS,GAAA,CAAI,UAAU,YAAY,CAAA;AAAA,IACrC,CAAA;AAAA,EACF,CAAA,EAAG,CAAC,QAAQ,CAAC,CAAA;AAEb,EAAA,OAAO;AAAA,IACL,aAAA;AAAA,IACA;AAAA,GACF;AACF;AAYO,MAAM,WAAA,GAAc,UAAA;AAAA,EACzB,SAASC,YAAAA,CACP,EAAE,QAAA,EAAU,SAAA,EAAW,WAAW,KAAA,EAAO,GAAG,IAAA,EAAK,EACjD,GAAA,EACA;AACA,IAAA,MAAM,eAAe,SAAA,EAAU;AAC/B,IAAA,wBAAA,CAAyB;AAAA,MACvB,MAAA,EAAQ,mBAAA;AAAA,MACR,GAAA,EAAKC,QAAA;AAAA,MACL,MAAA,EAAQ;AAAA,KACT,CAAA;AAED,IAAA,uBACE,GAAA;AAAA,MAAC,QAAA;AAAA,MAAA;AAAA,QACC,SAAA,EAAW,IAAA;AAAA,UACT,YAAA,EAAa;AAAA,UACb,EAAE,CAAC,YAAA,CAAa,UAAU,CAAC,GAAG,QAAA,EAAS;AAAA,UACvC;AAAA,SACF;AAAA,QACA,GAAA;AAAA,QACC,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA,EAEJ;AACF;;;;"}
@@ -1,4 +1,4 @@
1
- var css_248z = ".saltCarouselTabList {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n align-items: center;\n gap: var(--salt-spacing-200);\n}\n\n.saltCarouselTabList:focus-visible {\n outline-style: var(--salt-focused-outlineStyle);\n outline-width: var(--salt-focused-outlineWidth);\n outline-offset: var(--salt-focused-outlineOffset);\n outline-color: var(--salt-focused-outlineColor);\n}\n";
1
+ var css_248z = ".saltCarouselTabList {\n display: flex;\n flex-wrap: wrap;\n justify-content: flex-end;\n align-items: center;\n gap: var(--salt-spacing-200);\n}\n";
2
2
 
3
3
  export { css_248z as default };
4
4
  //# sourceMappingURL=CarouselTabList.css.js.map