@salt-ds/embla-carousel 0.1.4 → 0.1.6
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.
- package/CHANGELOG.md +40 -0
- package/css/salt-embla-carousel.css +42 -22
- package/dist-cjs/Carousel.js +30 -9
- package/dist-cjs/Carousel.js.map +1 -1
- package/dist-cjs/CarouselAutoplayIndicator.js.map +1 -1
- package/dist-cjs/CarouselAutoplayIndicatorSVG.js.map +1 -1
- package/dist-cjs/CarouselCard.css.js +1 -1
- package/dist-cjs/CarouselCard.js +18 -8
- package/dist-cjs/CarouselCard.js.map +1 -1
- package/dist-cjs/CarouselContext.js.map +1 -1
- package/dist-cjs/CarouselNextButton.js +4 -1
- package/dist-cjs/CarouselNextButton.js.map +1 -1
- package/dist-cjs/CarouselPreviousButton.js +4 -1
- package/dist-cjs/CarouselPreviousButton.js.map +1 -1
- package/dist-cjs/CarouselProgressLabel.js +11 -33
- package/dist-cjs/CarouselProgressLabel.js.map +1 -1
- package/dist-cjs/CarouselSlides.css.js +1 -1
- package/dist-cjs/CarouselSlides.js +119 -23
- package/dist-cjs/CarouselSlides.js.map +1 -1
- package/dist-cjs/CarouselTab.css.js +1 -1
- package/dist-cjs/CarouselTab.js +1 -5
- package/dist-cjs/CarouselTab.js.map +1 -1
- package/dist-cjs/CarouselTabList.css.js +1 -1
- package/dist-cjs/CarouselTabList.js +41 -27
- package/dist-cjs/CarouselTabList.js.map +1 -1
- package/dist-cjs/createCustomSettle.js.map +1 -1
- package/dist-cjs/getSlideDescription.js +32 -0
- package/dist-cjs/getSlideDescription.js.map +1 -0
- package/dist-cjs/getVisibleSlideDescription.js +26 -0
- package/dist-cjs/getVisibleSlideDescription.js.map +1 -0
- package/dist-cjs/getVisibleSlideIndexes.js +33 -0
- package/dist-cjs/getVisibleSlideIndexes.js.map +1 -0
- package/dist-cjs/index.js +0 -3
- package/dist-cjs/index.js.map +1 -1
- package/dist-cjs/usePrevNextButtons.js +3 -1
- package/dist-cjs/usePrevNextButtons.js.map +1 -1
- package/dist-es/Carousel.js +32 -11
- package/dist-es/Carousel.js.map +1 -1
- package/dist-es/CarouselAutoplayIndicator.js.map +1 -1
- package/dist-es/CarouselAutoplayIndicatorSVG.js.map +1 -1
- package/dist-es/CarouselCard.css.js +1 -1
- package/dist-es/CarouselCard.js +18 -8
- package/dist-es/CarouselCard.js.map +1 -1
- package/dist-es/CarouselContext.js.map +1 -1
- package/dist-es/CarouselNextButton.js +4 -1
- package/dist-es/CarouselNextButton.js.map +1 -1
- package/dist-es/CarouselPreviousButton.js +4 -1
- package/dist-es/CarouselPreviousButton.js.map +1 -1
- package/dist-es/CarouselProgressLabel.js +12 -34
- package/dist-es/CarouselProgressLabel.js.map +1 -1
- package/dist-es/CarouselSlides.css.js +1 -1
- package/dist-es/CarouselSlides.js +121 -25
- package/dist-es/CarouselSlides.js.map +1 -1
- package/dist-es/CarouselTab.css.js +1 -1
- package/dist-es/CarouselTab.js +1 -5
- package/dist-es/CarouselTab.js.map +1 -1
- package/dist-es/CarouselTabList.css.js +1 -1
- package/dist-es/CarouselTabList.js +42 -28
- package/dist-es/CarouselTabList.js.map +1 -1
- package/dist-es/createCustomSettle.js.map +1 -1
- package/dist-es/getSlideDescription.js +30 -0
- package/dist-es/getSlideDescription.js.map +1 -0
- package/dist-es/getVisibleSlideDescription.js +24 -0
- package/dist-es/getVisibleSlideDescription.js.map +1 -0
- package/dist-es/getVisibleSlideIndexes.js +30 -0
- package/dist-es/getVisibleSlideIndexes.js.map +1 -0
- package/dist-es/index.js +0 -1
- package/dist-es/index.js.map +1 -1
- package/dist-es/usePrevNextButtons.js +3 -1
- package/dist-es/usePrevNextButtons.js.map +1 -1
- package/dist-types/Carousel.d.ts +7 -1
- package/dist-types/CarouselContext.d.ts +31 -0
- package/dist-types/CarouselTab.d.ts +0 -6
- package/dist-types/CarouselTabList.d.ts +4 -0
- package/dist-types/getSlideDescription.d.ts +7 -0
- package/dist-types/getVisibleSlideDescription.d.ts +7 -0
- package/dist-types/getVisibleSlideIndexes.d.ts +8 -0
- package/dist-types/index.d.ts +0 -1
- package/package.json +2 -2
- package/dist-cjs/CarouselAnnouncementPlugin.js +0 -52
- package/dist-cjs/CarouselAnnouncementPlugin.js.map +0 -1
- package/dist-cjs/CarouselProgressLabel.css.js +0 -6
- package/dist-cjs/CarouselProgressLabel.css.js.map +0 -1
- package/dist-es/CarouselAnnouncementPlugin.js +0 -49
- package/dist-es/CarouselAnnouncementPlugin.js.map +0 -1
- package/dist-es/CarouselProgressLabel.css.js +0 -4
- package/dist-es/CarouselProgressLabel.css.js.map +0 -1
- package/dist-types/CarouselAnnouncementPlugin.d.ts +0 -24
|
@@ -1,51 +1,104 @@
|
|
|
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, useLayoutEffect, 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
|
+
"navigation"
|
|
18
|
+
];
|
|
12
19
|
const CarouselSlides = forwardRef(
|
|
13
|
-
function CarouselSlides2({ children, className, onKeyDown, ...rest }, ref) {
|
|
20
|
+
function CarouselSlides2({ children, className, id, onKeyDown, ...rest }, ref) {
|
|
14
21
|
const targetWindow = useWindow();
|
|
15
22
|
useComponentCssInjection({
|
|
16
23
|
testId: "salt-carousel-slides",
|
|
17
24
|
css: css_248z,
|
|
18
25
|
window: targetWindow
|
|
19
26
|
});
|
|
20
|
-
const {
|
|
27
|
+
const {
|
|
28
|
+
disableSlideAnnouncements,
|
|
29
|
+
announcementState,
|
|
30
|
+
setAnnouncementState,
|
|
31
|
+
emblaApi,
|
|
32
|
+
emblaRef,
|
|
33
|
+
carouselId
|
|
34
|
+
} = useCarouselContext();
|
|
21
35
|
const carouselRef = useForkRef(ref, emblaRef);
|
|
22
|
-
const
|
|
36
|
+
const slideRefs = useRef([]);
|
|
37
|
+
const [focusSlideIndex, setFocusedSlideIndex] = useState(-1);
|
|
38
|
+
const [dragging, setDragging] = useState(false);
|
|
39
|
+
const [stableScrollSnap, setStableScrollSnap] = useState(void 0);
|
|
40
|
+
const visibleSlideIndexes = getVisibleSlideIndexes(
|
|
41
|
+
emblaApi,
|
|
42
|
+
stableScrollSnap ?? 0
|
|
43
|
+
);
|
|
44
|
+
const { announce } = useAriaAnnouncer();
|
|
23
45
|
useEffect(() => {
|
|
24
46
|
const handleSettle = (emblaApi2) => {
|
|
25
|
-
|
|
26
|
-
|
|
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;
|
|
47
|
+
const selectedScrollSnap = (emblaApi2 == null ? void 0 : emblaApi2.selectedScrollSnap()) ?? 0;
|
|
48
|
+
setStableScrollSnap(selectedScrollSnap);
|
|
39
49
|
};
|
|
40
50
|
if (!emblaApi) {
|
|
41
51
|
return;
|
|
42
52
|
}
|
|
43
53
|
const scrollCallback = createCustomSettle(handleSettle);
|
|
54
|
+
const pointerDownCallback = () => {
|
|
55
|
+
setAnnouncementState("drag");
|
|
56
|
+
};
|
|
44
57
|
emblaApi.on("scroll", scrollCallback);
|
|
58
|
+
emblaApi.on("pointerDown", pointerDownCallback);
|
|
45
59
|
return () => {
|
|
46
60
|
emblaApi.off("scroll", scrollCallback);
|
|
61
|
+
emblaApi.off("pointerDown", pointerDownCallback);
|
|
47
62
|
};
|
|
48
63
|
}, [emblaApi]);
|
|
64
|
+
useLayoutEffect(() => {
|
|
65
|
+
if (focusSlideIndex >= 0) {
|
|
66
|
+
const numberOfSnaps = (emblaApi == null ? void 0 : emblaApi.scrollSnapList().length) ?? 1;
|
|
67
|
+
const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;
|
|
68
|
+
const nearestScrollSnap = Math.floor(
|
|
69
|
+
focusSlideIndex / numberOfSlidesPerSnap
|
|
70
|
+
);
|
|
71
|
+
if ((emblaApi == null ? void 0 : emblaApi.selectedScrollSnap()) !== nearestScrollSnap) {
|
|
72
|
+
setAnnouncementState("focus");
|
|
73
|
+
emblaApi == null ? void 0 : emblaApi.scrollTo(nearestScrollSnap);
|
|
74
|
+
}
|
|
75
|
+
setTimeout(() => {
|
|
76
|
+
var _a;
|
|
77
|
+
(_a = slideRefs.current[focusSlideIndex]) == null ? void 0 : _a.focus();
|
|
78
|
+
}, 0);
|
|
79
|
+
}
|
|
80
|
+
}, [focusSlideIndex, emblaApi, setAnnouncementState]);
|
|
81
|
+
useEffect(() => {
|
|
82
|
+
if (disableSlideAnnouncements === false) {
|
|
83
|
+
setAnnouncementState(void 0);
|
|
84
|
+
}
|
|
85
|
+
}, [disableSlideAnnouncements]);
|
|
86
|
+
useEffect(() => {
|
|
87
|
+
if (stableScrollSnap === void 0 || disableSlideAnnouncements || !announcementState || announceSlideChangesFrom.indexOf(announcementState) === -1) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
const announcement = getVisibleSlideDescription(
|
|
91
|
+
emblaApi,
|
|
92
|
+
stableScrollSnap
|
|
93
|
+
);
|
|
94
|
+
announce(announcement, ANNOUNCEMENT_DURATION);
|
|
95
|
+
}, [
|
|
96
|
+
announce,
|
|
97
|
+
announcementState,
|
|
98
|
+
disableSlideAnnouncements,
|
|
99
|
+
stableScrollSnap,
|
|
100
|
+
emblaApi
|
|
101
|
+
]);
|
|
49
102
|
const handleKeyDown = (event) => {
|
|
50
103
|
if (event.repeat) {
|
|
51
104
|
return;
|
|
@@ -53,27 +106,70 @@ const CarouselSlides = forwardRef(
|
|
|
53
106
|
switch (event.key) {
|
|
54
107
|
case "ArrowLeft": {
|
|
55
108
|
event.preventDefault();
|
|
56
|
-
|
|
57
|
-
usingArrowNavigation.current = true;
|
|
109
|
+
setFocusedSlideIndex((prevState) => Math.max(prevState - 1, 0));
|
|
58
110
|
break;
|
|
59
111
|
}
|
|
60
112
|
case "ArrowRight": {
|
|
61
113
|
event.preventDefault();
|
|
62
|
-
|
|
63
|
-
|
|
114
|
+
setFocusedSlideIndex(
|
|
115
|
+
(prevState) => Math.min(prevState + 1, slideRefs.current.length - 1)
|
|
116
|
+
);
|
|
64
117
|
break;
|
|
65
118
|
}
|
|
66
119
|
}
|
|
67
120
|
onKeyDown == null ? void 0 : onKeyDown(event);
|
|
68
121
|
};
|
|
122
|
+
const handleMouseDown = (event) => {
|
|
123
|
+
var _a;
|
|
124
|
+
setDragging(true);
|
|
125
|
+
(_a = rest.onMouseDown) == null ? void 0 : _a.call(rest, event);
|
|
126
|
+
};
|
|
127
|
+
const handleMouseUp = (event) => {
|
|
128
|
+
var _a;
|
|
129
|
+
setDragging(false);
|
|
130
|
+
(_a = rest.onMouseUp) == null ? void 0 : _a.call(rest, event);
|
|
131
|
+
};
|
|
69
132
|
return /* @__PURE__ */ jsx(
|
|
70
133
|
"div",
|
|
71
134
|
{
|
|
72
135
|
onKeyDown: handleKeyDown,
|
|
136
|
+
onMouseDown: handleMouseDown,
|
|
137
|
+
onMouseUp: handleMouseUp,
|
|
73
138
|
ref: carouselRef,
|
|
74
|
-
className: clsx(
|
|
139
|
+
className: clsx(
|
|
140
|
+
withBaseName(),
|
|
141
|
+
{ [withBaseName("dragging")]: dragging },
|
|
142
|
+
className
|
|
143
|
+
),
|
|
75
144
|
...rest,
|
|
76
|
-
children: /* @__PURE__ */ jsx(
|
|
145
|
+
children: /* @__PURE__ */ jsx(
|
|
146
|
+
"div",
|
|
147
|
+
{
|
|
148
|
+
className: withBaseName("container"),
|
|
149
|
+
id: id ?? `${carouselId}-slides`,
|
|
150
|
+
children: Children.map(children, (child, index) => {
|
|
151
|
+
const childElement = child;
|
|
152
|
+
const existingId = childElement.props.id;
|
|
153
|
+
const isHidden = !visibleSlideIndexes.includes(index + 1);
|
|
154
|
+
const element = child;
|
|
155
|
+
return cloneElement(element, {
|
|
156
|
+
"aria-hidden": isHidden,
|
|
157
|
+
id: existingId ?? `${carouselId}-slide${index + 1}`,
|
|
158
|
+
onMouseDown: (event) => event.preventDefault(),
|
|
159
|
+
onFocus: (event) => {
|
|
160
|
+
var _a, _b;
|
|
161
|
+
event.preventDefault();
|
|
162
|
+
setFocusedSlideIndex(index);
|
|
163
|
+
(_b = (_a = element.props) == null ? void 0 : _a.onFocus) == null ? void 0 : _b.call(_a, event);
|
|
164
|
+
},
|
|
165
|
+
tabIndex: !isHidden ? 0 : -1,
|
|
166
|
+
ref: (el) => {
|
|
167
|
+
slideRefs.current[index] = el;
|
|
168
|
+
}
|
|
169
|
+
});
|
|
170
|
+
})
|
|
171
|
+
}
|
|
172
|
+
)
|
|
77
173
|
}
|
|
78
174
|
);
|
|
79
175
|
}
|
|
@@ -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 forwardRef,\n type KeyboardEvent,\n type MouseEventHandler,\n type SyntheticEvent,\n useEffect,\n useLayoutEffect,\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 \"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 carouselRef = useForkRef<HTMLDivElement>(ref, emblaRef);\n\n const slideRefs = useRef<(HTMLDivElement | null)[]>([]);\n const [focusSlideIndex, setFocusedSlideIndex] = useState<number>(-1);\n const [dragging, setDragging] = useState(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 };\n\n if (!emblaApi) {\n return;\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]);\n\n useLayoutEffect(() => {\n if (focusSlideIndex >= 0) {\n const numberOfSnaps = emblaApi?.scrollSnapList().length ?? 1;\n const numberOfSlidesPerSnap = slideRefs.current.length / numberOfSnaps;\n const nearestScrollSnap = Math.floor(\n focusSlideIndex / numberOfSlidesPerSnap,\n );\n if (emblaApi?.selectedScrollSnap() !== nearestScrollSnap) {\n setAnnouncementState(\"focus\");\n emblaApi?.scrollTo(nearestScrollSnap);\n }\n setTimeout(() => {\n slideRefs.current[focusSlideIndex]?.focus();\n }, 0);\n }\n }, [focusSlideIndex, emblaApi, setAnnouncementState]);\n\n useEffect(() => {\n if (disableSlideAnnouncements === false) {\n setAnnouncementState(undefined);\n }\n }, [disableSlideAnnouncements]);\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 switch (event.key) {\n case \"ArrowLeft\": {\n event.preventDefault();\n setFocusedSlideIndex((prevState) => Math.max(prevState - 1, 0));\n break;\n }\n case \"ArrowRight\": {\n event.preventDefault();\n setFocusedSlideIndex((prevState) =>\n Math.min(prevState + 1, slideRefs.current.length - 1),\n );\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 React.ReactElement;\n const existingId = childElement.props.id;\n const isHidden = !visibleSlideIndexes.includes(index + 1);\n const element = child as React.ReactElement;\n return cloneElement(element, {\n \"aria-hidden\": isHidden,\n id: existingId ?? `${carouselId}-slide${index + 1}`,\n onMouseDown: (event: SyntheticEvent) => event.preventDefault(),\n onFocus: (event: FocusEvent) => {\n event.preventDefault();\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
|
|
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
|
package/dist-es/CarouselTab.js
CHANGED
|
@@ -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
|
|
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
|
|
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
|
|
@@ -3,10 +3,12 @@ import { makePrefixer, renderProps } 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 } from 'react';
|
|
6
|
+
import { forwardRef, useRef, useState, useEffect } from 'react';
|
|
7
7
|
import { useCarouselContext } from './CarouselContext.js';
|
|
8
8
|
import { CarouselTab, useCarouselTab } from './CarouselTab.js';
|
|
9
9
|
import css_248z from './CarouselTabList.css.js';
|
|
10
|
+
import { getSlideDescription } from './getSlideDescription.js';
|
|
11
|
+
import { getVisibleSlideIndexes } from './getVisibleSlideIndexes.js';
|
|
10
12
|
|
|
11
13
|
const withBaseName = makePrefixer("saltCarouselTabList");
|
|
12
14
|
const CarouselTabRenderer = forwardRef((props, ref) => {
|
|
@@ -20,67 +22,79 @@ const CarouselTabList = forwardRef(
|
|
|
20
22
|
css: css_248z,
|
|
21
23
|
window: targetWindow
|
|
22
24
|
});
|
|
23
|
-
const { emblaApi } = useCarouselContext();
|
|
24
|
-
const { selectedIndex, scrollSnaps
|
|
25
|
-
const slideNodes = emblaApi == null ? void 0 : emblaApi.slideNodes();
|
|
26
|
-
const numberOfSlides = (slideNodes == null ? void 0 : slideNodes.length) ?? 0;
|
|
27
|
-
const slidesPerTransition = numberOfSlides ? Math.ceil(numberOfSlides / scrollSnaps.length) : 0;
|
|
25
|
+
const { emblaApi, setAriaVariant, setAnnouncementState } = useCarouselContext();
|
|
26
|
+
const { selectedIndex, scrollSnaps } = useCarouselTab(emblaApi);
|
|
28
27
|
const buttonRefs = useRef([]);
|
|
28
|
+
const [focusedTabIndex, setFocusedTabIndex] = useState(null);
|
|
29
29
|
const handleKeyDown = (event) => {
|
|
30
30
|
var _a;
|
|
31
|
-
let newIndex = selectedIndex;
|
|
31
|
+
let newIndex = focusedTabIndex ?? selectedIndex;
|
|
32
32
|
if (event.key === "ArrowLeft" || event.key === "ArrowRight") {
|
|
33
33
|
const direction = event.key === "ArrowLeft" ? -1 : 1;
|
|
34
|
-
newIndex = (
|
|
34
|
+
newIndex = (newIndex + direction + scrollSnaps.length) % scrollSnaps.length;
|
|
35
35
|
} else if (event.key === "Home") {
|
|
36
36
|
newIndex = 0;
|
|
37
37
|
} else if (event.key === "End") {
|
|
38
38
|
newIndex = scrollSnaps.length - 1;
|
|
39
39
|
}
|
|
40
|
-
if (newIndex !==
|
|
41
|
-
onClick(newIndex);
|
|
40
|
+
if (newIndex !== focusedTabIndex) {
|
|
42
41
|
(_a = buttonRefs.current[newIndex]) == null ? void 0 : _a.focus();
|
|
43
|
-
|
|
44
|
-
event.stopPropagation();
|
|
42
|
+
setFocusedTabIndex(newIndex);
|
|
45
43
|
}
|
|
46
44
|
onKeyDown == null ? void 0 : onKeyDown(event);
|
|
47
45
|
};
|
|
46
|
+
useEffect(() => {
|
|
47
|
+
setAriaVariant("tabpanel");
|
|
48
|
+
}, [setAriaVariant]);
|
|
48
49
|
return /* @__PURE__ */ jsx(
|
|
49
50
|
"div",
|
|
50
51
|
{
|
|
51
52
|
role: "tablist",
|
|
52
|
-
"aria-label": "Choose slide",
|
|
53
|
-
tabIndex: 0,
|
|
54
53
|
className: clsx(withBaseName(), className),
|
|
55
54
|
onKeyDown: handleKeyDown,
|
|
56
55
|
ref,
|
|
57
56
|
...rest,
|
|
58
|
-
children: scrollSnaps.map((_,
|
|
59
|
-
const
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
numberOfSlides
|
|
57
|
+
children: scrollSnaps.map((_, scrollSnapIndex) => {
|
|
58
|
+
const visibleSlides = getVisibleSlideIndexes(
|
|
59
|
+
emblaApi,
|
|
60
|
+
scrollSnapIndex
|
|
63
61
|
);
|
|
64
|
-
const
|
|
65
|
-
const
|
|
62
|
+
const startSlideNumber = visibleSlides.length >= 1 ? visibleSlides[0] : 0;
|
|
63
|
+
const endSlideNumber = visibleSlides.length > 1 ? visibleSlides[visibleSlides.length - 1] : 0;
|
|
64
|
+
const slideNodes = emblaApi == null ? void 0 : emblaApi.slideNodes();
|
|
65
|
+
const numberOfSlides = slideNodes == null ? void 0 : slideNodes.length;
|
|
66
|
+
let ariaLabel;
|
|
67
|
+
if (endSlideNumber >= 1) {
|
|
68
|
+
ariaLabel = `Slide ${startSlideNumber} to ${endSlideNumber} of ${numberOfSlides}`;
|
|
69
|
+
} else {
|
|
70
|
+
const description = getSlideDescription(emblaApi, startSlideNumber);
|
|
71
|
+
ariaLabel = `${description}`;
|
|
72
|
+
}
|
|
73
|
+
const selected = selectedIndex === scrollSnapIndex;
|
|
66
74
|
const ariaControls = (slideNodes == null ? void 0 : slideNodes.length) ? slideNodes[startSlideNumber - 1].id : void 0;
|
|
67
75
|
return /* @__PURE__ */ jsx(
|
|
68
76
|
CarouselTabRenderer,
|
|
69
77
|
{
|
|
70
78
|
ref: (element) => {
|
|
71
|
-
buttonRefs.current[
|
|
79
|
+
buttonRefs.current[scrollSnapIndex] = element;
|
|
72
80
|
},
|
|
73
81
|
render,
|
|
74
82
|
role: "tab",
|
|
75
|
-
onClick: () => onClick(tabIndex),
|
|
76
|
-
"aria-selected": selected,
|
|
77
83
|
selected,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
84
|
+
onBlur: () => {
|
|
85
|
+
setFocusedTabIndex(null);
|
|
86
|
+
},
|
|
87
|
+
onFocus: () => {
|
|
88
|
+
setFocusedTabIndex(scrollSnapIndex);
|
|
89
|
+
setAnnouncementState("tab");
|
|
90
|
+
emblaApi == null ? void 0 : emblaApi.scrollTo(scrollSnapIndex);
|
|
91
|
+
},
|
|
92
|
+
"aria-label": ariaLabel,
|
|
93
|
+
"aria-selected": selected,
|
|
94
|
+
tabIndex: selected && focusedTabIndex === null ? 0 : -1,
|
|
81
95
|
"aria-controls": ariaControls
|
|
82
96
|
},
|
|
83
|
-
`carouselTab-${
|
|
97
|
+
`carouselTab-${scrollSnapIndex}}`
|
|
84
98
|
);
|
|
85
99
|
})
|
|
86
100
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CarouselTabList.js","sources":["../src/CarouselTabList.tsx"],"sourcesContent":["import { makePrefixer, type RenderPropsType, renderProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n forwardRef,\n type HTMLAttributes,\n type KeyboardEventHandler,\n useRef,\n} from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport {\n CarouselTab,\n type CarouselTabProps,\n useCarouselTab,\n} from \"./CarouselTab\";\nimport carouselControlsCss from \"./CarouselTabList.css\";\n\nconst withBaseName = makePrefixer(\"saltCarouselTabList\");\n\n/**\n * Props for the CarouselTabList component.\n */\nexport interface CarouselTabListProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Render prop to enable customisation of tab button.\n */\n render?: RenderPropsType[\"render\"];\n}\n\
|
|
1
|
+
{"version":3,"file":"CarouselTabList.js","sources":["../src/CarouselTabList.tsx"],"sourcesContent":["import { makePrefixer, type RenderPropsType, renderProps } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n forwardRef,\n type HTMLAttributes,\n type KeyboardEventHandler,\n useEffect,\n useRef,\n useState,\n} from \"react\";\nimport { useCarouselContext } from \"./CarouselContext\";\nimport {\n CarouselTab,\n type CarouselTabProps,\n useCarouselTab,\n} from \"./CarouselTab\";\nimport carouselControlsCss from \"./CarouselTabList.css\";\nimport { getSlideDescription } from \"./getSlideDescription\";\nimport { getVisibleSlideIndexes } from \"./getVisibleSlideIndexes\";\n\nconst withBaseName = makePrefixer(\"saltCarouselTabList\");\n\n/**\n * Props for the CarouselTabList component.\n */\nexport interface CarouselTabListProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Render prop to enable customisation of tab button.\n */\n render?: RenderPropsType[\"render\"];\n}\n\nexport interface CarouselTabRendererProps extends CarouselTabProps {\n render?: CarouselTabListProps[\"render\"];\n}\n\nconst CarouselTabRenderer = forwardRef<\n HTMLButtonElement,\n CarouselTabRendererProps\n>((props, ref) => {\n return renderProps(CarouselTab, { ...props, ref });\n});\n\nexport const CarouselTabList = forwardRef<HTMLDivElement, CarouselTabListProps>(\n function CarouselTabList({ className, render, onKeyDown, ...rest }, ref) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-controls\",\n css: carouselControlsCss,\n window: targetWindow,\n });\n\n const { emblaApi, setAriaVariant, setAnnouncementState } =\n useCarouselContext();\n const { selectedIndex, scrollSnaps } = useCarouselTab(emblaApi);\n\n const buttonRefs = useRef<(HTMLButtonElement | null)[]>([]);\n\n const [focusedTabIndex, setFocusedTabIndex] = useState<number | null>(null);\n\n const handleKeyDown: KeyboardEventHandler<HTMLDivElement> = (event) => {\n let newIndex = focusedTabIndex ?? selectedIndex;\n\n if (event.key === \"ArrowLeft\" || event.key === \"ArrowRight\") {\n const direction = event.key === \"ArrowLeft\" ? -1 : 1;\n newIndex =\n (newIndex + direction + scrollSnaps.length) % scrollSnaps.length;\n } else if (event.key === \"Home\") {\n newIndex = 0;\n } else if (event.key === \"End\") {\n newIndex = scrollSnaps.length - 1;\n }\n\n if (newIndex !== focusedTabIndex) {\n buttonRefs.current[newIndex]?.focus();\n setFocusedTabIndex(newIndex);\n }\n onKeyDown?.(event);\n };\n\n useEffect(() => {\n setAriaVariant(\"tabpanel\");\n }, [setAriaVariant]);\n\n return (\n <div\n role=\"tablist\"\n className={clsx(withBaseName(), className)}\n onKeyDown={handleKeyDown}\n ref={ref}\n {...rest}\n >\n {scrollSnaps.map((_, scrollSnapIndex) => {\n const visibleSlides = getVisibleSlideIndexes(\n emblaApi,\n scrollSnapIndex,\n );\n const startSlideNumber =\n visibleSlides.length >= 1 ? visibleSlides[0] : 0;\n const endSlideNumber =\n visibleSlides.length > 1\n ? visibleSlides[visibleSlides.length - 1]\n : 0;\n const slideNodes = emblaApi?.slideNodes();\n const numberOfSlides = slideNodes?.length;\n\n let ariaLabel: string;\n if (endSlideNumber >= 1) {\n ariaLabel = `Slide ${startSlideNumber} to ${endSlideNumber} of ${numberOfSlides}`;\n } else {\n const description = getSlideDescription(emblaApi, startSlideNumber);\n ariaLabel = `${description}`;\n }\n\n const selected = selectedIndex === scrollSnapIndex;\n const ariaControls = slideNodes?.length\n ? slideNodes[startSlideNumber - 1].id\n : undefined;\n\n return (\n <CarouselTabRenderer\n key={`carouselTab-${scrollSnapIndex}}`}\n ref={(element: HTMLButtonElement) => {\n buttonRefs.current[scrollSnapIndex] = element;\n }}\n render={render}\n role={\"tab\"}\n selected={selected}\n onBlur={() => {\n setFocusedTabIndex(null);\n }}\n onFocus={() => {\n setFocusedTabIndex(scrollSnapIndex);\n setAnnouncementState(\"tab\");\n emblaApi?.scrollTo(scrollSnapIndex);\n }}\n aria-label={ariaLabel}\n aria-selected={selected}\n tabIndex={selected && focusedTabIndex === null ? 0 : -1}\n aria-controls={ariaControls}\n />\n );\n })}\n </div>\n );\n },\n);\n"],"names":["CarouselTabList","carouselControlsCss"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"createCustomSettle.js","sources":["../src/createCustomSettle.ts"],"sourcesContent":["import type { EmblaCarouselType } from \"embla-carousel\";\n\nconst settlePixelThreshold = 10;\n\nexport type SettleCallback = (emblaApi: EmblaCarouselType) => void;\nexport type CreateCustomSettle = (callback: SettleCallback) => SettleCallback;\n\nexport const createCustomSettle: CreateCustomSettle = (callback) =>\n function fireCustomSettle(emblaApi: EmblaCarouselType) {\n const { dragHandler, location, target } = emblaApi.internalEngine();\n if (dragHandler.pointerDown()) return;\n const displacement = target.get() - location.get();\n if (Math.abs(displacement) < settlePixelThreshold) {\n callback(emblaApi);\n }\n };\n"],"names":[],"mappings":"AAEA,MAAM,
|
|
1
|
+
{"version":3,"file":"createCustomSettle.js","sources":["../src/createCustomSettle.ts"],"sourcesContent":["import type { EmblaCarouselType } from \"embla-carousel\";\n\nconst settlePixelThreshold = 10;\n\nexport type SettleCallback = (emblaApi: EmblaCarouselType) => void;\nexport type CreateCustomSettle = (callback: SettleCallback) => SettleCallback;\n\nexport const createCustomSettle: CreateCustomSettle = (callback) =>\n function fireCustomSettle(emblaApi: EmblaCarouselType) {\n const { dragHandler, location, target } = emblaApi.internalEngine();\n if (dragHandler.pointerDown()) return;\n const displacement = target.get() - location.get();\n if (Math.abs(displacement) < settlePixelThreshold) {\n callback(emblaApi);\n }\n };\n"],"names":[],"mappings":"AAEA,MAAM,oBAAA,GAAuB,EAAA;AAKtB,MAAM,kBAAA,GAAyC,CAAC,QAAA,KACrD,SAAS,iBAAiB,QAAA,EAA6B;AACrD,EAAA,MAAM,EAAE,WAAA,EAAa,QAAA,EAAU,MAAA,EAAO,GAAI,SAAS,cAAA,EAAe;AAClE,EAAA,IAAI,WAAA,CAAY,aAAY,EAAG;AAC/B,EAAA,MAAM,YAAA,GAAe,MAAA,CAAO,GAAA,EAAI,GAAI,SAAS,GAAA,EAAI;AACjD,EAAA,IAAI,IAAA,CAAK,GAAA,CAAI,YAAY,CAAA,GAAI,oBAAA,EAAsB;AACjD,IAAA,QAAA,CAAS,QAAQ,CAAA;AAAA,EACnB;AACF;;;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const getSlideDescription = (emblaApi, slideNumber) => {
|
|
2
|
+
if (!emblaApi || slideNumber < 1) {
|
|
3
|
+
return "";
|
|
4
|
+
}
|
|
5
|
+
const slideElement = emblaApi.slideNodes()[slideNumber - 1];
|
|
6
|
+
const { ownerDocument } = emblaApi.internalEngine();
|
|
7
|
+
const resolveAriaLabelledBy = (element) => {
|
|
8
|
+
if (!element) return null;
|
|
9
|
+
const labelledById = element.getAttribute("aria-labelledby");
|
|
10
|
+
let description2 = null;
|
|
11
|
+
if (labelledById) {
|
|
12
|
+
const labelledByElement = ownerDocument.getElementById(labelledById);
|
|
13
|
+
if (labelledByElement) {
|
|
14
|
+
description2 = resolveAriaLabelledBy(labelledByElement);
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (!description2) {
|
|
18
|
+
description2 = element.getAttribute("aria-label") || element.textContent || null;
|
|
19
|
+
}
|
|
20
|
+
return description2;
|
|
21
|
+
};
|
|
22
|
+
let description = resolveAriaLabelledBy(slideElement);
|
|
23
|
+
if (!description) {
|
|
24
|
+
description = (slideElement == null ? void 0 : slideElement.getAttribute("aria-label")) ?? null;
|
|
25
|
+
}
|
|
26
|
+
return description || "";
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { getSlideDescription };
|
|
30
|
+
//# sourceMappingURL=getSlideDescription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getSlideDescription.js","sources":["../src/getSlideDescription.ts"],"sourcesContent":["import type { EmblaCarouselType } from \"embla-carousel\";\n\n/** Get a description of the slide.\n * @param emblaApi\n * @param slideIndex\n * @returns A slide description if defined or an empty string\n */\nexport const getSlideDescription = (\n emblaApi: EmblaCarouselType | undefined,\n slideNumber: number,\n): string => {\n if (!emblaApi || slideNumber < 1) {\n return \"\";\n }\n\n const slideElement = emblaApi.slideNodes()[slideNumber - 1];\n const { ownerDocument } = emblaApi.internalEngine();\n\n const resolveAriaLabelledBy = (element: Element | null): string | null => {\n if (!element) return null;\n\n const labelledById = element.getAttribute(\"aria-labelledby\");\n let description = null;\n\n if (labelledById) {\n const labelledByElement = ownerDocument.getElementById(labelledById);\n if (labelledByElement) {\n // Recursively resolve aria-labelledby\n description = resolveAriaLabelledBy(labelledByElement);\n }\n }\n\n // If no description found, use aria-label or text content\n if (!description) {\n description =\n element.getAttribute(\"aria-label\") || element.textContent || null;\n }\n\n return description;\n };\n\n let description = resolveAriaLabelledBy(slideElement);\n\n if (!description) {\n description = slideElement?.getAttribute(\"aria-label\") ?? null;\n }\n\n return description || \"\";\n};\n"],"names":["description"],"mappings":"AAOO,MAAM,mBAAA,GAAsB,CACjC,QAAA,EACA,WAAA,KACW;AACX,EAAA,IAAI,CAAC,QAAA,IAAY,WAAA,GAAc,CAAA,EAAG;AAChC,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,YAAA,GAAe,QAAA,CAAS,UAAA,EAAW,CAAE,cAAc,CAAC,CAAA;AAC1D,EAAA,MAAM,EAAE,aAAA,EAAc,GAAI,QAAA,CAAS,cAAA,EAAe;AAElD,EAAA,MAAM,qBAAA,GAAwB,CAAC,OAAA,KAA2C;AACxE,IAAA,IAAI,CAAC,SAAS,OAAO,IAAA;AAErB,IAAA,MAAM,YAAA,GAAe,OAAA,CAAQ,YAAA,CAAa,iBAAiB,CAAA;AAC3D,IAAA,IAAIA,YAAAA,GAAc,IAAA;AAElB,IAAA,IAAI,YAAA,EAAc;AAChB,MAAA,MAAM,iBAAA,GAAoB,aAAA,CAAc,cAAA,CAAe,YAAY,CAAA;AACnE,MAAA,IAAI,iBAAA,EAAmB;AAErB,QAAAA,YAAAA,GAAc,sBAAsB,iBAAiB,CAAA;AAAA,MACvD;AAAA,IACF;AAGA,IAAA,IAAI,CAACA,YAAAA,EAAa;AAChB,MAAAA,eACE,OAAA,CAAQ,YAAA,CAAa,YAAY,CAAA,IAAK,QAAQ,WAAA,IAAe,IAAA;AAAA,IACjE;AAEA,IAAA,OAAOA,YAAAA;AAAA,EACT,CAAA;AAEA,EAAA,IAAI,WAAA,GAAc,sBAAsB,YAAY,CAAA;AAEpD,EAAA,IAAI,CAAC,WAAA,EAAa;AAChB,IAAA,WAAA,GAAA,CAAc,YAAA,IAAA,IAAA,GAAA,MAAA,GAAA,YAAA,CAAc,aAAa,YAAA,CAAA,KAAiB,IAAA;AAAA,EAC5D;AAEA,EAAA,OAAO,WAAA,IAAe,EAAA;AACxB;;;;"}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { getSlideDescription } from './getSlideDescription.js';
|
|
2
|
+
import { getVisibleSlideIndexes } from './getVisibleSlideIndexes.js';
|
|
3
|
+
|
|
4
|
+
const getVisibleSlideDescription = (emblaApi, scrollSnapIndex) => {
|
|
5
|
+
if (!emblaApi) {
|
|
6
|
+
return "";
|
|
7
|
+
}
|
|
8
|
+
const visibleSlideIndexes = getVisibleSlideIndexes(emblaApi, scrollSnapIndex);
|
|
9
|
+
const numberOfSlides = (emblaApi == null ? void 0 : emblaApi.slideNodes().length) ?? 0;
|
|
10
|
+
if (numberOfSlides < 1) {
|
|
11
|
+
return "";
|
|
12
|
+
}
|
|
13
|
+
if (visibleSlideIndexes.length > 1) {
|
|
14
|
+
return `Slide ${visibleSlideIndexes[0]} to ${visibleSlideIndexes[visibleSlideIndexes.length - 1]} of ${numberOfSlides}`;
|
|
15
|
+
}
|
|
16
|
+
const visibleSlideIndex = visibleSlideIndexes[0];
|
|
17
|
+
const description = getSlideDescription(emblaApi, visibleSlideIndex);
|
|
18
|
+
const slide = emblaApi == null ? void 0 : emblaApi.slideNodes()[visibleSlideIndex - 1];
|
|
19
|
+
const slideRoleDescription = (slide == null ? void 0 : slide.ariaRoleDescription) ?? "slide";
|
|
20
|
+
return `${description}, ${slideRoleDescription}, ${visibleSlideIndex} of ${numberOfSlides}`;
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
export { getVisibleSlideDescription };
|
|
24
|
+
//# sourceMappingURL=getVisibleSlideDescription.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getVisibleSlideDescription.js","sources":["../src/getVisibleSlideDescription.ts"],"sourcesContent":["import type { EmblaCarouselType } from \"embla-carousel\";\nimport { getSlideDescription } from \"./getSlideDescription\";\nimport { getVisibleSlideIndexes } from \"./getVisibleSlideIndexes\";\n\n/** Get a description of the visible slide(s).\n * @param emblaApi\n * @param slideIndex\n * @returns An array of descriptions for the visible slides\n */\nexport const getVisibleSlideDescription = (\n emblaApi: EmblaCarouselType | undefined,\n scrollSnapIndex: number,\n): string => {\n if (!emblaApi) {\n return \"\";\n }\n\n const visibleSlideIndexes = getVisibleSlideIndexes(emblaApi, scrollSnapIndex);\n const numberOfSlides = emblaApi?.slideNodes().length ?? 0;\n\n if (numberOfSlides < 1) {\n return \"\";\n }\n\n if (visibleSlideIndexes.length > 1) {\n return `Slide ${visibleSlideIndexes[0]} to ${visibleSlideIndexes[visibleSlideIndexes.length - 1]} of ${numberOfSlides}`;\n }\n const visibleSlideIndex = visibleSlideIndexes[0];\n const description = getSlideDescription(emblaApi, visibleSlideIndex);\n const slide = emblaApi?.slideNodes()[visibleSlideIndex - 1];\n const slideRoleDescription = slide?.ariaRoleDescription ?? \"slide\";\n return `${description}, ${slideRoleDescription}, ${visibleSlideIndex} of ${numberOfSlides}`;\n};\n"],"names":[],"mappings":";;;AASO,MAAM,0BAAA,GAA6B,CACxC,QAAA,EACA,eAAA,KACW;AACX,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,MAAM,mBAAA,GAAsB,sBAAA,CAAuB,QAAA,EAAU,eAAe,CAAA;AAC5E,EAAA,MAAM,cAAA,GAAA,CAAiB,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAA,EAAA,CAAa,MAAA,KAAU,CAAA;AAExD,EAAA,IAAI,iBAAiB,CAAA,EAAG;AACtB,IAAA,OAAO,EAAA;AAAA,EACT;AAEA,EAAA,IAAI,mBAAA,CAAoB,SAAS,CAAA,EAAG;AAClC,IAAA,OAAO,CAAA,MAAA,EAAS,mBAAA,CAAoB,CAAC,CAAC,CAAA,IAAA,EAAO,mBAAA,CAAoB,mBAAA,CAAoB,MAAA,GAAS,CAAC,CAAC,CAAA,IAAA,EAAO,cAAc,CAAA,CAAA;AAAA,EACvH;AACA,EAAA,MAAM,iBAAA,GAAoB,oBAAoB,CAAC,CAAA;AAC/C,EAAA,MAAM,WAAA,GAAc,mBAAA,CAAoB,QAAA,EAAU,iBAAiB,CAAA;AACnE,EAAA,MAAM,KAAA,GAAQ,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAA,EAAA,CAAa,iBAAA,GAAoB,CAAA,CAAA;AACzD,EAAA,MAAM,oBAAA,GAAA,CAAuB,+BAAO,mBAAA,KAAuB,OAAA;AAC3D,EAAA,OAAO,GAAG,WAAW,CAAA,EAAA,EAAK,oBAAoB,CAAA,EAAA,EAAK,iBAAiB,OAAO,cAAc,CAAA,CAAA;AAC3F;;;;"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
const getSlideNumberRange = (startSlideNumber, endSlideNumber) => {
|
|
2
|
+
const slideNumbers = [];
|
|
3
|
+
for (let i = startSlideNumber; i <= endSlideNumber; i++) {
|
|
4
|
+
slideNumbers.push(i);
|
|
5
|
+
}
|
|
6
|
+
return slideNumbers;
|
|
7
|
+
};
|
|
8
|
+
const getVisibleSlideIndexes = (emblaApi, scrollSnapIndex) => {
|
|
9
|
+
if (!emblaApi) {
|
|
10
|
+
return [];
|
|
11
|
+
}
|
|
12
|
+
const numberOfSlides = (emblaApi == null ? void 0 : emblaApi.slideNodes().length) ?? 0;
|
|
13
|
+
const scrollSnaps = (emblaApi == null ? void 0 : emblaApi.scrollSnapList()) ?? [];
|
|
14
|
+
const slidesPerTransition = numberOfSlides ? Math.ceil(numberOfSlides / scrollSnaps.length) : 0;
|
|
15
|
+
const startSlideNumber = Math.min(
|
|
16
|
+
scrollSnapIndex * slidesPerTransition + 1,
|
|
17
|
+
numberOfSlides - (slidesPerTransition - 1)
|
|
18
|
+
);
|
|
19
|
+
const endSlideNumber = Math.min(
|
|
20
|
+
startSlideNumber + slidesPerTransition - 1,
|
|
21
|
+
numberOfSlides
|
|
22
|
+
);
|
|
23
|
+
if (startSlideNumber === endSlideNumber) {
|
|
24
|
+
return [startSlideNumber];
|
|
25
|
+
}
|
|
26
|
+
return getSlideNumberRange(startSlideNumber, endSlideNumber);
|
|
27
|
+
};
|
|
28
|
+
|
|
29
|
+
export { getSlideNumberRange, getVisibleSlideIndexes };
|
|
30
|
+
//# sourceMappingURL=getVisibleSlideIndexes.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"getVisibleSlideIndexes.js","sources":["../src/getVisibleSlideIndexes.ts"],"sourcesContent":["import type { EmblaCarouselType } from \"embla-carousel\";\n\nexport const getSlideNumberRange = (\n startSlideNumber: number,\n endSlideNumber: number,\n): number[] => {\n const slideNumbers: number[] = [];\n for (let i = startSlideNumber; i <= endSlideNumber; i++) {\n slideNumbers.push(i);\n }\n return slideNumbers;\n};\n\n/** Get the visible slide indexes\n * @param emblaApi\n * @param scrollSnap\n * @returns An array of visible slide indexes\n */\nexport const getVisibleSlideIndexes = (\n emblaApi: EmblaCarouselType | undefined,\n scrollSnapIndex: number,\n): number[] => {\n if (!emblaApi) {\n return [];\n }\n\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 scrollSnapIndex * 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 return [startSlideNumber];\n }\n return getSlideNumberRange(startSlideNumber, endSlideNumber);\n};\n"],"names":[],"mappings":"AAEO,MAAM,mBAAA,GAAsB,CACjC,gBAAA,EACA,cAAA,KACa;AACb,EAAA,MAAM,eAAyB,EAAC;AAChC,EAAA,KAAA,IAAS,CAAA,GAAI,gBAAA,EAAkB,CAAA,IAAK,cAAA,EAAgB,CAAA,EAAA,EAAK;AACvD,IAAA,YAAA,CAAa,KAAK,CAAC,CAAA;AAAA,EACrB;AACA,EAAA,OAAO,YAAA;AACT;AAOO,MAAM,sBAAA,GAAyB,CACpC,QAAA,EACA,eAAA,KACa;AACb,EAAA,IAAI,CAAC,QAAA,EAAU;AACb,IAAA,OAAO,EAAC;AAAA,EACV;AAEA,EAAA,MAAM,cAAA,GAAA,CAAiB,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,UAAA,EAAA,CAAa,MAAA,KAAU,CAAA;AACxD,EAAA,MAAM,WAAA,GAAA,CAAc,QAAA,IAAA,IAAA,GAAA,MAAA,GAAA,QAAA,CAAU,cAAA,EAAA,KAAoB,EAAC;AACnD,EAAA,MAAM,sBAAsB,cAAA,GACxB,IAAA,CAAK,KAAK,cAAA,GAAiB,WAAA,CAAY,MAAM,CAAA,GAC7C,CAAA;AACJ,EAAA,MAAM,mBAAmB,IAAA,CAAK,GAAA;AAAA,IAC5B,kBAAkB,mBAAA,GAAsB,CAAA;AAAA,IACxC,kBAAkB,mBAAA,GAAsB,CAAA;AAAA,GAC1C;AACA,EAAA,MAAM,iBAAiB,IAAA,CAAK,GAAA;AAAA,IAC1B,mBAAmB,mBAAA,GAAsB,CAAA;AAAA,IACzC;AAAA,GACF;AAEA,EAAA,IAAI,qBAAqB,cAAA,EAAgB;AACvC,IAAA,OAAO,CAAC,gBAAgB,CAAA;AAAA,EAC1B;AACA,EAAA,OAAO,mBAAA,CAAoB,kBAAkB,cAAc,CAAA;AAC7D;;;;"}
|
package/dist-es/index.js
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
1
|
export { Carousel } from './Carousel.js';
|
|
2
|
-
export { CarouselAnnouncement, getSlideLabel } from './CarouselAnnouncementPlugin.js';
|
|
3
2
|
export { CarouselAutoplayIndicator } from './CarouselAutoplayIndicator.js';
|
|
4
3
|
export { CarouselCard } from './CarouselCard.js';
|
|
5
4
|
export { CarouselContext, useCarouselContext } from './CarouselContext.js';
|
package/dist-es/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;;;;"}
|