@salt-ds/lab 1.0.0-alpha.65 → 1.0.0-alpha.66
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 +53 -0
- package/css/salt-lab.css +111 -16
- package/dist-cjs/carousel/Carousel.css.js +1 -1
- package/dist-cjs/carousel/Carousel.js +30 -87
- package/dist-cjs/carousel/Carousel.js.map +1 -1
- package/dist-cjs/carousel/CarouselContext.js +62 -0
- package/dist-cjs/carousel/CarouselContext.js.map +1 -0
- package/dist-cjs/carousel/CarouselControls.css.js +6 -0
- package/dist-cjs/carousel/CarouselControls.css.js.map +1 -0
- package/dist-cjs/carousel/CarouselControls.js +122 -0
- package/dist-cjs/carousel/CarouselControls.js.map +1 -0
- package/dist-cjs/carousel/CarouselReducer.js +77 -0
- package/dist-cjs/carousel/CarouselReducer.js.map +1 -0
- package/dist-cjs/carousel/CarouselSlide.css.js +6 -0
- package/dist-cjs/carousel/CarouselSlide.css.js.map +1 -0
- package/dist-cjs/carousel/CarouselSlide.js +95 -45
- package/dist-cjs/carousel/CarouselSlide.js.map +1 -1
- package/dist-cjs/carousel/CarouselSlider.css.js +6 -0
- package/dist-cjs/carousel/CarouselSlider.css.js.map +1 -0
- package/dist-cjs/carousel/CarouselSlider.js +93 -0
- package/dist-cjs/carousel/CarouselSlider.js.map +1 -0
- package/dist-cjs/index.js +6 -2
- package/dist-cjs/index.js.map +1 -1
- package/dist-es/carousel/Carousel.css.js +1 -1
- package/dist-es/carousel/Carousel.js +32 -89
- package/dist-es/carousel/Carousel.js.map +1 -1
- package/dist-es/carousel/CarouselContext.js +58 -0
- package/dist-es/carousel/CarouselContext.js.map +1 -0
- package/dist-es/carousel/CarouselControls.css.js +4 -0
- package/dist-es/carousel/CarouselControls.css.js.map +1 -0
- package/dist-es/carousel/CarouselControls.js +120 -0
- package/dist-es/carousel/CarouselControls.js.map +1 -0
- package/dist-es/carousel/CarouselReducer.js +75 -0
- package/dist-es/carousel/CarouselReducer.js.map +1 -0
- package/dist-es/carousel/CarouselSlide.css.js +4 -0
- package/dist-es/carousel/CarouselSlide.css.js.map +1 -0
- package/dist-es/carousel/CarouselSlide.js +96 -46
- package/dist-es/carousel/CarouselSlide.js.map +1 -1
- package/dist-es/carousel/CarouselSlider.css.js +4 -0
- package/dist-es/carousel/CarouselSlider.css.js.map +1 -0
- package/dist-es/carousel/CarouselSlider.js +91 -0
- package/dist-es/carousel/CarouselSlider.js.map +1 -0
- package/dist-es/index.js +3 -1
- package/dist-es/index.js.map +1 -1
- package/dist-types/carousel/Carousel.d.ts +10 -23
- package/dist-types/carousel/CarouselContext.d.ts +11 -0
- package/dist-types/carousel/CarouselControls.d.ts +26 -0
- package/dist-types/carousel/CarouselReducer.d.ts +30 -0
- package/dist-types/carousel/CarouselSlide.d.ts +31 -8
- package/dist-types/carousel/CarouselSlider.d.ts +13 -0
- package/dist-types/carousel/index.d.ts +2 -0
- package/dist-types/utils/index.d.ts +1 -1
- package/package.json +2 -2
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
function carouselReducer(state, action) {
|
|
4
|
+
switch (action.type) {
|
|
5
|
+
case "register": {
|
|
6
|
+
const { slides } = state;
|
|
7
|
+
const [id, { element, slideDescription }] = action.payload;
|
|
8
|
+
const newSlides = new Map(slides);
|
|
9
|
+
newSlides.set(id, { element, slideDescription });
|
|
10
|
+
return {
|
|
11
|
+
...state,
|
|
12
|
+
slides: newSlides
|
|
13
|
+
};
|
|
14
|
+
}
|
|
15
|
+
case "unregister": {
|
|
16
|
+
const { slides } = state;
|
|
17
|
+
const id = action.payload;
|
|
18
|
+
if (!slides.has(id)) {
|
|
19
|
+
return state;
|
|
20
|
+
}
|
|
21
|
+
const newSlides = new Map(slides);
|
|
22
|
+
newSlides.delete(id);
|
|
23
|
+
return {
|
|
24
|
+
...state,
|
|
25
|
+
slides: newSlides
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
// moves the first visible item
|
|
29
|
+
case "move": {
|
|
30
|
+
const { slides } = state;
|
|
31
|
+
const id = action.payload;
|
|
32
|
+
if (!slides.has(id)) {
|
|
33
|
+
return state;
|
|
34
|
+
}
|
|
35
|
+
const slideIds = [...slides.keys()];
|
|
36
|
+
const index = slideIds.indexOf(id || slideIds[0]);
|
|
37
|
+
return {
|
|
38
|
+
...state,
|
|
39
|
+
activeSlideIndex: index
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
case "moveToIndex": {
|
|
43
|
+
const { slides } = state;
|
|
44
|
+
const index = action.payload;
|
|
45
|
+
if (index === -1 || index > slides.size) {
|
|
46
|
+
return state;
|
|
47
|
+
}
|
|
48
|
+
return {
|
|
49
|
+
...state,
|
|
50
|
+
focusedSlideIndex: index
|
|
51
|
+
};
|
|
52
|
+
}
|
|
53
|
+
case "updateSlideCount": {
|
|
54
|
+
const visibleSlides = action.payload;
|
|
55
|
+
return { ...state, visibleSlides };
|
|
56
|
+
}
|
|
57
|
+
case "scroll": {
|
|
58
|
+
const id = action.payload;
|
|
59
|
+
const { slides } = state;
|
|
60
|
+
const focusedSlideIndex = [...slides.keys()].indexOf(id);
|
|
61
|
+
if (focusedSlideIndex === -1) {
|
|
62
|
+
return state;
|
|
63
|
+
}
|
|
64
|
+
return {
|
|
65
|
+
...state,
|
|
66
|
+
focusedSlideIndex
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
default: {
|
|
70
|
+
const exhaustiveCheck = action;
|
|
71
|
+
throw new Error(`Action of type ${exhaustiveCheck} does not exist`);
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
exports.carouselReducer = carouselReducer;
|
|
77
|
+
//# sourceMappingURL=CarouselReducer.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CarouselReducer.js","sources":["../src/carousel/CarouselReducer.ts"],"sourcesContent":["import type { Dispatch } from \"react\";\n\nimport type { CarouselSlideId, CarouselSlideMeta } from \"./CarouselSlide\";\n\nexport interface CarouselReducerState {\n slides: Map<CarouselSlideId, CarouselSlideMeta>;\n activeSlideIndex: number;\n visibleSlides: number;\n focusedSlideIndex: number;\n carouselId?: string;\n}\nexport type CarouselReducerAction =\n | { type: \"register\"; payload: [CarouselSlideId, CarouselSlideMeta] }\n | { type: \"unregister\"; payload: CarouselSlideId }\n | { type: \"updateSlideCount\"; payload: number }\n | { type: \"move\"; payload: CarouselSlideId }\n | { type: \"moveToIndex\"; payload: number }\n | { type: \"scroll\"; payload: CarouselSlideId };\n\nexport type CarouselReducerDispatch = Dispatch<CarouselReducerAction>;\n\nexport function carouselReducer(\n state: CarouselReducerState,\n action: CarouselReducerAction,\n) {\n switch (action.type) {\n case \"register\": {\n const { slides } = state;\n const [id, { element, slideDescription }] = action.payload;\n const newSlides = new Map(slides);\n newSlides.set(id, { element, slideDescription });\n return {\n ...state,\n slides: newSlides,\n };\n }\n case \"unregister\": {\n const { slides } = state;\n const id = action.payload;\n if (!slides.has(id)) {\n return state;\n }\n const newSlides = new Map(slides);\n newSlides.delete(id);\n return {\n ...state,\n slides: newSlides,\n };\n }\n // moves the first visible item\n case \"move\": {\n const { slides } = state;\n const id = action.payload;\n if (!slides.has(id)) {\n return state;\n }\n const slideIds = [...slides.keys()];\n const index = slideIds.indexOf(id || slideIds[0]);\n return {\n ...state,\n activeSlideIndex: index,\n };\n }\n case \"moveToIndex\": {\n const { slides } = state;\n\n const index = action.payload;\n\n if (index === -1 || index > slides.size) {\n return state;\n }\n\n return {\n ...state,\n focusedSlideIndex: index,\n };\n }\n case \"updateSlideCount\": {\n const visibleSlides = action.payload;\n\n return { ...state, visibleSlides: visibleSlides };\n }\n\n case \"scroll\": {\n const id = action.payload;\n const { slides } = state;\n\n const focusedSlideIndex = [...slides.keys()].indexOf(id);\n\n if (focusedSlideIndex === -1) {\n return state;\n }\n\n return {\n ...state,\n focusedSlideIndex,\n };\n }\n default: {\n const exhaustiveCheck: never = action;\n throw new Error(`Action of type ${exhaustiveCheck} does not exist`);\n }\n }\n}\n"],"names":[],"mappings":";;AAqBgB,SAAA,eAAA,CACd,OACA,MACA,EAAA;AACA,EAAA,QAAQ,OAAO,IAAM;AAAA,IACnB,KAAK,UAAY,EAAA;AACf,MAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AACnB,MAAA,MAAM,CAAC,EAAI,EAAA,EAAE,SAAS,gBAAiB,EAAC,IAAI,MAAO,CAAA,OAAA;AACnD,MAAM,MAAA,SAAA,GAAY,IAAI,GAAA,CAAI,MAAM,CAAA;AAChC,MAAA,SAAA,CAAU,GAAI,CAAA,EAAA,EAAI,EAAE,OAAA,EAAS,kBAAkB,CAAA;AAC/C,MAAO,OAAA;AAAA,QACL,GAAG,KAAA;AAAA,QACH,MAAQ,EAAA;AAAA,OACV;AAAA;AACF,IACA,KAAK,YAAc,EAAA;AACjB,MAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AACnB,MAAA,MAAM,KAAK,MAAO,CAAA,OAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,GAAI,CAAA,EAAE,CAAG,EAAA;AACnB,QAAO,OAAA,KAAA;AAAA;AAET,MAAM,MAAA,SAAA,GAAY,IAAI,GAAA,CAAI,MAAM,CAAA;AAChC,MAAA,SAAA,CAAU,OAAO,EAAE,CAAA;AACnB,MAAO,OAAA;AAAA,QACL,GAAG,KAAA;AAAA,QACH,MAAQ,EAAA;AAAA,OACV;AAAA;AACF;AAAA,IAEA,KAAK,MAAQ,EAAA;AACX,MAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AACnB,MAAA,MAAM,KAAK,MAAO,CAAA,OAAA;AAClB,MAAA,IAAI,CAAC,MAAA,CAAO,GAAI,CAAA,EAAE,CAAG,EAAA;AACnB,QAAO,OAAA,KAAA;AAAA;AAET,MAAA,MAAM,QAAW,GAAA,CAAC,GAAG,MAAA,CAAO,MAAM,CAAA;AAClC,MAAA,MAAM,QAAQ,QAAS,CAAA,OAAA,CAAQ,EAAM,IAAA,QAAA,CAAS,CAAC,CAAC,CAAA;AAChD,MAAO,OAAA;AAAA,QACL,GAAG,KAAA;AAAA,QACH,gBAAkB,EAAA;AAAA,OACpB;AAAA;AACF,IACA,KAAK,aAAe,EAAA;AAClB,MAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AAEnB,MAAA,MAAM,QAAQ,MAAO,CAAA,OAAA;AAErB,MAAA,IAAI,KAAU,KAAA,CAAA,CAAA,IAAM,KAAQ,GAAA,MAAA,CAAO,IAAM,EAAA;AACvC,QAAO,OAAA,KAAA;AAAA;AAGT,MAAO,OAAA;AAAA,QACL,GAAG,KAAA;AAAA,QACH,iBAAmB,EAAA;AAAA,OACrB;AAAA;AACF,IACA,KAAK,kBAAoB,EAAA;AACvB,MAAA,MAAM,gBAAgB,MAAO,CAAA,OAAA;AAE7B,MAAO,OAAA,EAAE,GAAG,KAAA,EAAO,aAA6B,EAAA;AAAA;AAClD,IAEA,KAAK,QAAU,EAAA;AACb,MAAA,MAAM,KAAK,MAAO,CAAA,OAAA;AAClB,MAAM,MAAA,EAAE,QAAW,GAAA,KAAA;AAEnB,MAAM,MAAA,iBAAA,GAAoB,CAAC,GAAG,MAAA,CAAO,MAAM,CAAA,CAAE,QAAQ,EAAE,CAAA;AAEvD,MAAA,IAAI,sBAAsB,CAAI,CAAA,EAAA;AAC5B,QAAO,OAAA,KAAA;AAAA;AAGT,MAAO,OAAA;AAAA,QACL,GAAG,KAAA;AAAA,QACH;AAAA,OACF;AAAA;AACF,IACA,SAAS;AACP,MAAA,MAAM,eAAyB,GAAA,MAAA;AAC/B,MAAA,MAAM,IAAI,KAAA,CAAM,CAAkB,eAAA,EAAA,eAAe,CAAiB,eAAA,CAAA,CAAA;AAAA;AACpE;AAEJ;;;;"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".saltCarouselSlide {\n scroll-snap-align: start;\n display: flex;\n flex-direction: column;\n flex: 0 0 auto;\n box-sizing: border-box;\n width: var(--carousel-slide-width, 100%);\n gap: var(--salt-spacing-200);\n}\n.saltCarouselSlide:focus-visible {\n outline: var(--salt-focused-outline);\n outline-offset: calc(0px - var(--salt-focused-outlineWidth));\n}\n\n.saltCarouselSlide-actions {\n display: none;\n}\n\n.saltCarouselSlide-sr-only {\n position: fixed;\n top: 0;\n left: 0;\n transform: translate(-100%, -100%);\n}\n\n.saltCarouselSlide-actions.saltCarouselSlide-visible {\n display: flex;\n}\n.saltCarouselSlide-container {\n display: flex;\n flex-direction: column;\n box-sizing: border-box;\n gap: var(--salt-spacing-200);\n padding-left: var(--salt-spacing-25);\n padding-bottom: var(--salt-spacing-25);\n flex-grow: 1;\n}\n.saltCarouselSlide-content {\n display: flex;\n flex-direction: column;\n flex-grow: 1;\n gap: var(--salt-spacing-100);\n}\n.saltCarouselSlide-card {\n padding: var(--salt-spacing-200);\n padding-top: 0;\n}\n.saltCarouselSlide-content h2,\n.saltCarouselSlide-content h3 {\n margin: 0;\n}\n.saltCarouselSlide-bordered {\n border: var(--salt-size-border) var(--salt-container-borderStyle) var(--salt-container-primary-borderColor);\n border-radius: var(--salt-palette-corner, 0);\n overflow: hidden;\n}\n";
|
|
4
|
+
|
|
5
|
+
module.exports = css_248z;
|
|
6
|
+
//# sourceMappingURL=CarouselSlide.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CarouselSlide.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -2,57 +2,107 @@
|
|
|
2
2
|
|
|
3
3
|
var jsxRuntime = require('react/jsx-runtime');
|
|
4
4
|
var core = require('@salt-ds/core');
|
|
5
|
-
var
|
|
5
|
+
var styles = require('@salt-ds/styles');
|
|
6
|
+
var window = require('@salt-ds/window');
|
|
6
7
|
var clsx = require('clsx');
|
|
8
|
+
var react = require('react');
|
|
9
|
+
var CarouselContext = require('./CarouselContext.js');
|
|
10
|
+
var CarouselSlide$1 = require('./CarouselSlide.css.js');
|
|
7
11
|
|
|
8
12
|
const withBaseName = core.makePrefixer("saltCarouselSlide");
|
|
9
13
|
const CarouselSlide = react.forwardRef(
|
|
10
|
-
function CarouselSlide2({
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
14
|
+
function CarouselSlide2({
|
|
15
|
+
actions,
|
|
16
|
+
appearance,
|
|
17
|
+
media,
|
|
18
|
+
header,
|
|
19
|
+
children,
|
|
20
|
+
"aria-labelledby": ariaLabelledBy,
|
|
21
|
+
style,
|
|
22
|
+
id: idProp,
|
|
23
|
+
...rest
|
|
24
|
+
}, refProp) {
|
|
25
|
+
const targetWindow = window.useWindow();
|
|
26
|
+
styles.useComponentCssInjection({
|
|
27
|
+
testId: "salt-carousel-slide",
|
|
28
|
+
css: CarouselSlide$1,
|
|
29
|
+
window: targetWindow
|
|
30
|
+
});
|
|
31
|
+
const dispatch = react.useContext(CarouselContext.CarouselDispatchContext);
|
|
32
|
+
const { slides, visibleSlides, activeSlideIndex } = react.useContext(CarouselContext.CarouselStateContext);
|
|
33
|
+
const slideRef = react.useRef(null);
|
|
34
|
+
const headerRef = react.useRef(null);
|
|
35
|
+
const id = core.useIdMemo(idProp);
|
|
36
|
+
const announcerId = core.useId();
|
|
37
|
+
const slideCount = slides.size;
|
|
38
|
+
react.useEffect(() => {
|
|
39
|
+
var _a;
|
|
40
|
+
if (!slideRef.current) return;
|
|
41
|
+
dispatch({
|
|
42
|
+
type: "register",
|
|
43
|
+
payload: [
|
|
44
|
+
id,
|
|
38
45
|
{
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
[withBaseName("buttonBarOverrideLeft")]: contentAlignment === "left"
|
|
42
|
-
}),
|
|
43
|
-
children: /* @__PURE__ */ jsxRuntime.jsx(
|
|
44
|
-
ButtonBar,
|
|
45
|
-
{
|
|
46
|
-
className: clsx.clsx({
|
|
47
|
-
[withBaseName("buttonBarContainer")]: contentAlignment === "center",
|
|
48
|
-
[withBaseName("buttonBarContainerLeft")]: contentAlignment === "left"
|
|
49
|
-
})
|
|
50
|
-
}
|
|
51
|
-
)
|
|
46
|
+
element: slideRef.current,
|
|
47
|
+
slideDescription: (_a = headerRef == null ? void 0 : headerRef.current) == null ? void 0 : _a.innerText
|
|
52
48
|
}
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
49
|
+
]
|
|
50
|
+
});
|
|
51
|
+
return () => dispatch({ type: "unregister", payload: id });
|
|
52
|
+
}, [dispatch, id]);
|
|
53
|
+
const SlideStyles = {
|
|
54
|
+
"--carousel-slide-width": visibleSlides > 1 ? `calc((100% / ${visibleSlides}) - var(--salt-spacing-200)/${visibleSlides})` : void 0,
|
|
55
|
+
...style
|
|
56
|
+
};
|
|
57
|
+
const ref = core.useForkRef(refProp, slideRef);
|
|
58
|
+
const slideIds = [...slides.keys()];
|
|
59
|
+
const index = slideIds.indexOf(id || slideIds[0]);
|
|
60
|
+
const helperText = `${index + 1} of ${slideCount}`;
|
|
61
|
+
const isVisible = index >= activeSlideIndex && index < activeSlideIndex + visibleSlides;
|
|
62
|
+
return /* @__PURE__ */ jsxRuntime.jsxs(
|
|
63
|
+
"div",
|
|
64
|
+
{
|
|
65
|
+
role: "group",
|
|
66
|
+
"aria-roledescription": "slide",
|
|
67
|
+
"aria-labelledby": clsx.clsx(ariaLabelledBy, announcerId),
|
|
68
|
+
id,
|
|
69
|
+
className: clsx.clsx(withBaseName(), {
|
|
70
|
+
[withBaseName("bordered")]: appearance === "bordered"
|
|
71
|
+
}),
|
|
72
|
+
style: SlideStyles,
|
|
73
|
+
tabIndex: isVisible ? 0 : -1,
|
|
74
|
+
hidden: !isVisible,
|
|
75
|
+
...rest,
|
|
76
|
+
ref,
|
|
77
|
+
children: [
|
|
78
|
+
media,
|
|
79
|
+
children && /* @__PURE__ */ jsxRuntime.jsxs(
|
|
80
|
+
"div",
|
|
81
|
+
{
|
|
82
|
+
className: clsx.clsx(withBaseName("container"), {
|
|
83
|
+
[withBaseName("card")]: appearance === "bordered"
|
|
84
|
+
}),
|
|
85
|
+
children: [
|
|
86
|
+
/* @__PURE__ */ jsxRuntime.jsxs("div", { className: withBaseName("content"), children: [
|
|
87
|
+
isVisible && /* @__PURE__ */ jsxRuntime.jsx(
|
|
88
|
+
"span",
|
|
89
|
+
{
|
|
90
|
+
id: announcerId,
|
|
91
|
+
className: withBaseName("sr-only"),
|
|
92
|
+
"aria-hidden": "true",
|
|
93
|
+
children: helperText
|
|
94
|
+
}
|
|
95
|
+
),
|
|
96
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { ref: headerRef, children: header }),
|
|
97
|
+
/* @__PURE__ */ jsxRuntime.jsx("div", { children })
|
|
98
|
+
] }),
|
|
99
|
+
isVisible && actions
|
|
100
|
+
]
|
|
101
|
+
}
|
|
102
|
+
)
|
|
103
|
+
]
|
|
104
|
+
}
|
|
105
|
+
);
|
|
56
106
|
}
|
|
57
107
|
);
|
|
58
108
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"CarouselSlide.js","sources":["../src/carousel/CarouselSlide.tsx"],"sourcesContent":["import { makePrefixer } from \"@salt-ds/core\";\nimport {\n type
|
|
1
|
+
{"version":3,"file":"CarouselSlide.js","sources":["../src/carousel/CarouselSlide.tsx"],"sourcesContent":["import { makePrefixer, useForkRef, useId, useIdMemo } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport { clsx } from \"clsx\";\nimport {\n type ComponentProps,\n type ReactNode,\n forwardRef,\n useContext,\n useEffect,\n useRef,\n} from \"react\";\nimport {\n CarouselDispatchContext,\n CarouselStateContext,\n} from \"./CarouselContext\";\nimport carouselSlideCss from \"./CarouselSlide.css\";\n\nexport type CarouselSlideId = string;\nexport type CarouselSlideElement = HTMLDivElement;\nexport type CarouselSlideMeta = {\n element: CarouselSlideElement;\n slideDescription?: string;\n};\nexport interface CarouselSlideProps extends ComponentProps<\"div\"> {\n /**\n * Actions to be displayed in the content footer.\n **/\n actions?: ReactNode;\n /**\n * Media content to be displayed inside the slide. This could include images, videos, etc., that are visually prominent.\n * It differs from children in that media is intended to be the main visual element of the slide.\n **/\n media?: ReactNode;\n /**\n * The appearance of the slide. Options are 'bordered', and 'transparent'.\n * 'transparent' is the default value.\n **/\n appearance?: \"bordered\" | \"transparent\";\n /**\n * Header content to be displayed at the top of the slide. This can be text or any other React node.\n **/\n header?: ReactNode;\n /**\n * Carousel slide id.\n */\n id?: string;\n}\n\nconst withBaseName = makePrefixer(\"saltCarouselSlide\");\n\nexport const CarouselSlide = forwardRef<HTMLDivElement, CarouselSlideProps>(\n function CarouselSlide(\n {\n actions,\n appearance,\n media,\n header,\n children,\n \"aria-labelledby\": ariaLabelledBy,\n style,\n id: idProp,\n ...rest\n },\n refProp,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-slide\",\n css: carouselSlideCss,\n window: targetWindow,\n });\n const dispatch = useContext(CarouselDispatchContext);\n const { slides, visibleSlides, activeSlideIndex } =\n useContext(CarouselStateContext);\n\n const slideRef = useRef<HTMLDivElement>(null);\n const headerRef = useRef<HTMLDivElement>(null);\n const id = useIdMemo(idProp);\n const announcerId = useId();\n const slideCount = slides.size;\n\n useEffect(() => {\n if (!slideRef.current) return;\n\n dispatch({\n type: \"register\",\n payload: [\n id,\n {\n element: slideRef.current,\n slideDescription: headerRef?.current?.innerText,\n },\n ],\n });\n return () => dispatch({ type: \"unregister\", payload: id });\n }, [dispatch, id]);\n\n const SlideStyles = {\n \"--carousel-slide-width\":\n visibleSlides > 1\n ? `calc((100% / ${visibleSlides}) - var(--salt-spacing-200)/${visibleSlides})`\n : undefined,\n ...style,\n };\n\n const ref = useForkRef(refProp, slideRef);\n const slideIds = [...slides.keys()];\n const index = slideIds.indexOf(id || slideIds[0]);\n const helperText = `${index + 1} of ${slideCount}`;\n const isVisible =\n index >= activeSlideIndex && index < activeSlideIndex + visibleSlides;\n\n return (\n <div\n role=\"group\"\n aria-roledescription=\"slide\"\n aria-labelledby={clsx(ariaLabelledBy, announcerId)}\n id={id}\n className={clsx(withBaseName(), {\n [withBaseName(\"bordered\")]: appearance === \"bordered\",\n })}\n style={SlideStyles}\n tabIndex={isVisible ? 0 : -1}\n hidden={!isVisible}\n {...rest}\n ref={ref}\n >\n {media}\n {children && (\n <div\n className={clsx(withBaseName(\"container\"), {\n [withBaseName(\"card\")]: appearance === \"bordered\",\n })}\n >\n <div className={withBaseName(\"content\")}>\n {isVisible && (\n <span\n id={announcerId}\n className={withBaseName(\"sr-only\")}\n aria-hidden=\"true\"\n >\n {helperText}\n </span>\n )}\n <div ref={headerRef}>{header}</div>\n <div>{children}</div>\n </div>\n {isVisible && actions}\n </div>\n )}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","CarouselSlide","useWindow","useComponentCssInjection","carouselSlideCss","useContext","CarouselDispatchContext","CarouselStateContext","useRef","useIdMemo","useId","useEffect","useForkRef","jsxs","clsx","jsx"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var css_248z = ".saltCarouselSlider {\n display: flex;\n scroll-snap-type: x mandatory;\n overflow-x: auto;\n scroll-behavior: smooth;\n width: 100%;\n gap: var(--salt-spacing-100);\n grid-area: slider;\n}\n@supports (scrollbar-width: none) {\n .saltCarouselSlider {\n scrollbar-width: none;\n }\n}\n@supports not (scrollbar-width: none) {\n .saltCarouselSlider::-webkit-scrollbar {\n display: none;\n }\n}\n";
|
|
4
|
+
|
|
5
|
+
module.exports = css_248z;
|
|
6
|
+
//# sourceMappingURL=CarouselSlider.css.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CarouselSlider.css.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;;;;;"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
var jsxRuntime = require('react/jsx-runtime');
|
|
4
|
+
var core = require('@salt-ds/core');
|
|
5
|
+
var styles = require('@salt-ds/styles');
|
|
6
|
+
var window = require('@salt-ds/window');
|
|
7
|
+
var react = require('react');
|
|
8
|
+
var CarouselContext = require('./CarouselContext.js');
|
|
9
|
+
var CarouselSlider$1 = require('./CarouselSlider.css.js');
|
|
10
|
+
|
|
11
|
+
const withBaseName = core.makePrefixer("saltCarouselSlider");
|
|
12
|
+
const CarouselSlider = react.forwardRef(
|
|
13
|
+
function CarouselSlider2({ children, onKeyDown, onScroll, onSelectionChange, ...rest }, propRef) {
|
|
14
|
+
const targetWindow = window.useWindow();
|
|
15
|
+
styles.useComponentCssInjection({
|
|
16
|
+
testId: "salt-carousel-slider",
|
|
17
|
+
css: CarouselSlider$1,
|
|
18
|
+
window: targetWindow
|
|
19
|
+
});
|
|
20
|
+
const containerRef = react.useRef(null);
|
|
21
|
+
const hasRun = react.useRef(false);
|
|
22
|
+
const { slides, activeSlideIndex, focusedSlideIndex, visibleSlides } = react.useContext(CarouselContext.CarouselStateContext);
|
|
23
|
+
const dispatch = react.useContext(CarouselContext.CarouselDispatchContext);
|
|
24
|
+
const slideIds = [...slides.keys()];
|
|
25
|
+
const handleKeyDown = (event) => {
|
|
26
|
+
var _a, _b;
|
|
27
|
+
if (event.repeat) return;
|
|
28
|
+
switch (event.key) {
|
|
29
|
+
case "ArrowLeft": {
|
|
30
|
+
const prevIndex = focusedSlideIndex && focusedSlideIndex > activeSlideIndex ? focusedSlideIndex - 1 : activeSlideIndex - 1;
|
|
31
|
+
const prevId = slideIds[prevIndex] || null;
|
|
32
|
+
if (!prevId) break;
|
|
33
|
+
dispatch({ type: "scroll", payload: prevId });
|
|
34
|
+
onSelectionChange == null ? void 0 : onSelectionChange(event, prevIndex);
|
|
35
|
+
(_a = slides.get(prevId)) == null ? void 0 : _a.element.focus();
|
|
36
|
+
break;
|
|
37
|
+
}
|
|
38
|
+
case "ArrowRight": {
|
|
39
|
+
const nextIndex = activeSlideIndex + 1;
|
|
40
|
+
const nextId = slideIds[nextIndex] || null;
|
|
41
|
+
if (!nextId) break;
|
|
42
|
+
dispatch({ type: "scroll", payload: nextId });
|
|
43
|
+
onSelectionChange == null ? void 0 : onSelectionChange(event, nextIndex);
|
|
44
|
+
(_b = slides.get(nextId)) == null ? void 0 : _b.element.focus();
|
|
45
|
+
break;
|
|
46
|
+
}
|
|
47
|
+
}
|
|
48
|
+
onKeyDown == null ? void 0 : onKeyDown(event);
|
|
49
|
+
};
|
|
50
|
+
const handleScroll = (event) => {
|
|
51
|
+
const container = containerRef == null ? void 0 : containerRef.current;
|
|
52
|
+
if (!container) return;
|
|
53
|
+
const scrollLeft = container.scrollLeft;
|
|
54
|
+
const slideWidth = container.offsetWidth / visibleSlides;
|
|
55
|
+
const newIndex = Math.round(scrollLeft / slideWidth) || 0;
|
|
56
|
+
if (newIndex !== activeSlideIndex) {
|
|
57
|
+
dispatch({ type: "move", payload: slideIds[newIndex] });
|
|
58
|
+
onSelectionChange == null ? void 0 : onSelectionChange(event, newIndex);
|
|
59
|
+
}
|
|
60
|
+
onScroll == null ? void 0 : onScroll(event);
|
|
61
|
+
};
|
|
62
|
+
react.useLayoutEffect(() => {
|
|
63
|
+
const container = containerRef.current;
|
|
64
|
+
if (!container) return;
|
|
65
|
+
const scrollBehavior = hasRun.current ? "smooth" : "instant";
|
|
66
|
+
const slideWidth = container.offsetWidth / visibleSlides;
|
|
67
|
+
requestAnimationFrame(() => {
|
|
68
|
+
container.scrollTo({
|
|
69
|
+
left: focusedSlideIndex * slideWidth,
|
|
70
|
+
// @ts-ignore ScrollBehavior typescript definition missing instant
|
|
71
|
+
behavior: scrollBehavior
|
|
72
|
+
});
|
|
73
|
+
});
|
|
74
|
+
hasRun.current = true;
|
|
75
|
+
}, [focusedSlideIndex, visibleSlides]);
|
|
76
|
+
const ref = core.useForkRef(propRef, containerRef);
|
|
77
|
+
return /* @__PURE__ */ jsxRuntime.jsx(
|
|
78
|
+
"div",
|
|
79
|
+
{
|
|
80
|
+
ref,
|
|
81
|
+
className: withBaseName(),
|
|
82
|
+
tabIndex: -1,
|
|
83
|
+
onKeyDown: handleKeyDown,
|
|
84
|
+
onScroll: handleScroll,
|
|
85
|
+
...rest,
|
|
86
|
+
children
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
}
|
|
90
|
+
);
|
|
91
|
+
|
|
92
|
+
exports.CarouselSlider = CarouselSlider;
|
|
93
|
+
//# sourceMappingURL=CarouselSlider.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CarouselSlider.js","sources":["../src/carousel/CarouselSlider.tsx"],"sourcesContent":["import { makePrefixer, useForkRef } from \"@salt-ds/core\";\nimport { useComponentCssInjection } from \"@salt-ds/styles\";\nimport { useWindow } from \"@salt-ds/window\";\nimport {\n type HTMLAttributes,\n type KeyboardEvent,\n type ReactElement,\n type SyntheticEvent,\n type UIEvent,\n forwardRef,\n useContext,\n useLayoutEffect,\n useRef,\n} from \"react\";\nimport {\n CarouselDispatchContext,\n CarouselStateContext,\n} from \"./CarouselContext\";\nimport type { CarouselSlideProps } from \"./CarouselSlide\";\nimport carouselSliderCss from \"./CarouselSlider.css\";\n\nexport interface CarouselSliderProps extends HTMLAttributes<HTMLDivElement> {\n /**\n * Collection of slides to render\n */\n children: Array<ReactElement<CarouselSlideProps>>;\n /**\n * Callback fired when the selected slide change.\n **/\n onSelectionChange?: (\n event: SyntheticEvent<HTMLDivElement>,\n index: number,\n ) => void;\n}\n\nconst withBaseName = makePrefixer(\"saltCarouselSlider\");\n\nexport const CarouselSlider = forwardRef<HTMLDivElement, CarouselSliderProps>(\n function CarouselSlider(\n { children, onKeyDown, onScroll, onSelectionChange, ...rest },\n propRef,\n ) {\n const targetWindow = useWindow();\n useComponentCssInjection({\n testId: \"salt-carousel-slider\",\n css: carouselSliderCss,\n window: targetWindow,\n });\n const containerRef = useRef<HTMLDivElement>(null);\n const hasRun = useRef(false);\n const { slides, activeSlideIndex, focusedSlideIndex, visibleSlides } =\n useContext(CarouselStateContext);\n const dispatch = useContext(CarouselDispatchContext);\n const slideIds = [...slides.keys()];\n\n const handleKeyDown = (event: KeyboardEvent<HTMLDivElement>) => {\n if (event.repeat) return;\n switch (event.key) {\n case \"ArrowLeft\": {\n const prevIndex =\n focusedSlideIndex && focusedSlideIndex > activeSlideIndex\n ? focusedSlideIndex - 1\n : activeSlideIndex - 1;\n const prevId = slideIds[prevIndex] || null;\n\n if (!prevId) break;\n dispatch({ type: \"scroll\", payload: prevId });\n onSelectionChange?.(event, prevIndex);\n slides.get(prevId)?.element.focus();\n\n break;\n }\n case \"ArrowRight\": {\n const nextIndex = activeSlideIndex + 1;\n const nextId = slideIds[nextIndex] || null;\n\n if (!nextId) break;\n\n dispatch({ type: \"scroll\", payload: nextId });\n onSelectionChange?.(event, nextIndex);\n\n slides.get(nextId)?.element.focus();\n\n break;\n }\n }\n onKeyDown?.(event);\n };\n\n const handleScroll = (event: UIEvent<HTMLDivElement>) => {\n const container = containerRef?.current;\n if (!container) return;\n const scrollLeft = container.scrollLeft;\n const slideWidth = container.offsetWidth / visibleSlides;\n const newIndex = Math.round(scrollLeft / slideWidth) || 0;\n\n if (newIndex !== activeSlideIndex) {\n dispatch({ type: \"move\", payload: slideIds[newIndex] });\n onSelectionChange?.(event, newIndex);\n }\n onScroll?.(event);\n };\n\n useLayoutEffect(() => {\n const container = containerRef.current;\n if (!container) return;\n\n const scrollBehavior = hasRun.current ? \"smooth\" : \"instant\";\n const slideWidth = container.offsetWidth / visibleSlides;\n\n requestAnimationFrame(() => {\n container.scrollTo({\n left: focusedSlideIndex * slideWidth,\n // @ts-ignore ScrollBehavior typescript definition missing instant\n behavior: scrollBehavior,\n });\n });\n\n hasRun.current = true;\n }, [focusedSlideIndex, visibleSlides]);\n\n const ref = useForkRef(propRef, containerRef);\n return (\n <div\n ref={ref}\n className={withBaseName()}\n tabIndex={-1}\n onKeyDown={handleKeyDown}\n onScroll={handleScroll}\n {...rest}\n >\n {children}\n </div>\n );\n },\n);\n"],"names":["makePrefixer","forwardRef","CarouselSlider","useWindow","useComponentCssInjection","carouselSliderCss","useRef","useContext","CarouselStateContext","CarouselDispatchContext","useLayoutEffect","useForkRef","jsx"],"mappings":";;;;;;;;;;AAmCA,MAAM,YAAA,GAAeA,kBAAa,oBAAoB,CAAA;AAE/C,MAAM,cAAiB,GAAAC,gBAAA;AAAA,EAC5B,SAASC,eACP,CAAA,EAAE,QAAU,EAAA,SAAA,EAAW,UAAU,iBAAmB,EAAA,GAAG,IAAK,EAAA,EAC5D,OACA,EAAA;AACA,IAAA,MAAM,eAAeC,gBAAU,EAAA;AAC/B,IAAyBC,+BAAA,CAAA;AAAA,MACvB,MAAQ,EAAA,sBAAA;AAAA,MACR,GAAK,EAAAC,gBAAA;AAAA,MACL,MAAQ,EAAA;AAAA,KACT,CAAA;AACD,IAAM,MAAA,YAAA,GAAeC,aAAuB,IAAI,CAAA;AAChD,IAAM,MAAA,MAAA,GAASA,aAAO,KAAK,CAAA;AAC3B,IAAA,MAAM,EAAE,MAAQ,EAAA,gBAAA,EAAkB,mBAAmB,aAAc,EAAA,GACjEC,iBAAWC,oCAAoB,CAAA;AACjC,IAAM,MAAA,QAAA,GAAWD,iBAAWE,uCAAuB,CAAA;AACnD,IAAA,MAAM,QAAW,GAAA,CAAC,GAAG,MAAA,CAAO,MAAM,CAAA;AAElC,IAAM,MAAA,aAAA,GAAgB,CAAC,KAAyC,KAAA;AAvDpE,MAAA,IAAA,EAAA,EAAA,EAAA;AAwDM,MAAA,IAAI,MAAM,MAAQ,EAAA;AAClB,MAAA,QAAQ,MAAM,GAAK;AAAA,QACjB,KAAK,WAAa,EAAA;AAChB,UAAA,MAAM,YACJ,iBAAqB,IAAA,iBAAA,GAAoB,gBACrC,GAAA,iBAAA,GAAoB,IACpB,gBAAmB,GAAA,CAAA;AACzB,UAAM,MAAA,MAAA,GAAS,QAAS,CAAA,SAAS,CAAK,IAAA,IAAA;AAEtC,UAAA,IAAI,CAAC,MAAQ,EAAA;AACb,UAAA,QAAA,CAAS,EAAE,IAAA,EAAM,QAAU,EAAA,OAAA,EAAS,QAAQ,CAAA;AAC5C,UAAA,iBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,iBAAA,CAAoB,KAAO,EAAA,SAAA,CAAA;AAC3B,UAAA,CAAA,EAAA,GAAA,MAAA,CAAO,GAAI,CAAA,MAAM,CAAjB,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAoB,OAAQ,CAAA,KAAA,EAAA;AAE5B,UAAA;AAAA;AACF,QACA,KAAK,YAAc,EAAA;AACjB,UAAA,MAAM,YAAY,gBAAmB,GAAA,CAAA;AACrC,UAAM,MAAA,MAAA,GAAS,QAAS,CAAA,SAAS,CAAK,IAAA,IAAA;AAEtC,UAAA,IAAI,CAAC,MAAQ,EAAA;AAEb,UAAA,QAAA,CAAS,EAAE,IAAA,EAAM,QAAU,EAAA,OAAA,EAAS,QAAQ,CAAA;AAC5C,UAAA,iBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,iBAAA,CAAoB,KAAO,EAAA,SAAA,CAAA;AAE3B,UAAA,CAAA,EAAA,GAAA,MAAA,CAAO,GAAI,CAAA,MAAM,CAAjB,KAAA,IAAA,GAAA,KAAA,CAAA,GAAA,EAAA,CAAoB,OAAQ,CAAA,KAAA,EAAA;AAE5B,UAAA;AAAA;AACF;AAEF,MAAY,SAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,SAAA,CAAA,KAAA,CAAA;AAAA,KACd;AAEA,IAAM,MAAA,YAAA,GAAe,CAAC,KAAmC,KAAA;AACvD,MAAA,MAAM,YAAY,YAAc,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,YAAA,CAAA,OAAA;AAChC,MAAA,IAAI,CAAC,SAAW,EAAA;AAChB,MAAA,MAAM,aAAa,SAAU,CAAA,UAAA;AAC7B,MAAM,MAAA,UAAA,GAAa,UAAU,WAAc,GAAA,aAAA;AAC3C,MAAA,MAAM,QAAW,GAAA,IAAA,CAAK,KAAM,CAAA,UAAA,GAAa,UAAU,CAAK,IAAA,CAAA;AAExD,MAAA,IAAI,aAAa,gBAAkB,EAAA;AACjC,QAAA,QAAA,CAAS,EAAE,IAAM,EAAA,MAAA,EAAQ,SAAS,QAAS,CAAA,QAAQ,GAAG,CAAA;AACtD,QAAA,iBAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,iBAAA,CAAoB,KAAO,EAAA,QAAA,CAAA;AAAA;AAE7B,MAAW,QAAA,IAAA,IAAA,GAAA,KAAA,CAAA,GAAA,QAAA,CAAA,KAAA,CAAA;AAAA,KACb;AAEA,IAAAC,qBAAA,CAAgB,MAAM;AACpB,MAAA,MAAM,YAAY,YAAa,CAAA,OAAA;AAC/B,MAAA,IAAI,CAAC,SAAW,EAAA;AAEhB,MAAM,MAAA,cAAA,GAAiB,MAAO,CAAA,OAAA,GAAU,QAAW,GAAA,SAAA;AACnD,MAAM,MAAA,UAAA,GAAa,UAAU,WAAc,GAAA,aAAA;AAE3C,MAAA,qBAAA,CAAsB,MAAM;AAC1B,QAAA,SAAA,CAAU,QAAS,CAAA;AAAA,UACjB,MAAM,iBAAoB,GAAA,UAAA;AAAA;AAAA,UAE1B,QAAU,EAAA;AAAA,SACX,CAAA;AAAA,OACF,CAAA;AAED,MAAA,MAAA,CAAO,OAAU,GAAA,IAAA;AAAA,KAChB,EAAA,CAAC,iBAAmB,EAAA,aAAa,CAAC,CAAA;AAErC,IAAM,MAAA,GAAA,GAAMC,eAAW,CAAA,OAAA,EAAS,YAAY,CAAA;AAC5C,IACE,uBAAAC,cAAA;AAAA,MAAC,KAAA;AAAA,MAAA;AAAA,QACC,GAAA;AAAA,QACA,WAAW,YAAa,EAAA;AAAA,QACxB,QAAU,EAAA,CAAA,CAAA;AAAA,QACV,SAAW,EAAA,aAAA;AAAA,QACX,QAAU,EAAA,YAAA;AAAA,QACT,GAAG,IAAA;AAAA,QAEH;AAAA;AAAA,KACH;AAAA;AAGN;;;;"}
|
package/dist-cjs/index.js
CHANGED
|
@@ -16,9 +16,9 @@ var isPlainObject = require('./utils/isPlainObject.js');
|
|
|
16
16
|
var partition = require('./utils/partition.js');
|
|
17
17
|
var useClickOutside = require('./utils/useClickOutside.js');
|
|
18
18
|
var useEventCallback = require('./utils/useEventCallback.js');
|
|
19
|
+
var useIsViewportLargerThanBreakpoint = require('./utils/useIsViewportLargerThanBreakpoint.js');
|
|
19
20
|
var useLayoutEffectOnce = require('./utils/useLayoutEffectOnce.js');
|
|
20
21
|
var useLayoutEffectSkipFirst = require('./utils/useLayoutEffectSkipFirst.js');
|
|
21
|
-
var useIsViewportLargerThanBreakpoint = require('./utils/useIsViewportLargerThanBreakpoint.js');
|
|
22
22
|
var useOverflowDetection = require('./utils/useOverflowDetection.js');
|
|
23
23
|
var useSlideSelection = require('./utils/useSlideSelection.js');
|
|
24
24
|
var AppHeader = require('./app-header/AppHeader.js');
|
|
@@ -35,6 +35,8 @@ var useCalendar = require('./calendar/useCalendar.js');
|
|
|
35
35
|
var useCalendarSelection = require('./calendar/useCalendarSelection.js');
|
|
36
36
|
var Carousel = require('./carousel/Carousel.js');
|
|
37
37
|
var CarouselSlide = require('./carousel/CarouselSlide.js');
|
|
38
|
+
var CarouselSlider = require('./carousel/CarouselSlider.js');
|
|
39
|
+
var CarouselControls = require('./carousel/CarouselControls.js');
|
|
38
40
|
var CascadingMenu = require('./cascading-menu/CascadingMenu.js');
|
|
39
41
|
var ColorChooser = require('./color-chooser/ColorChooser.js');
|
|
40
42
|
var Color = require('./color-chooser/Color.js');
|
|
@@ -169,9 +171,9 @@ exports.isPlainObject = isPlainObject.isPlainObject;
|
|
|
169
171
|
exports.partition = partition.partition;
|
|
170
172
|
exports.useClickOutside = useClickOutside.useClickOutside;
|
|
171
173
|
exports.useEventCallback = useEventCallback.useEventCallback;
|
|
174
|
+
exports.useIsViewportLargerThanBreakpoint = useIsViewportLargerThanBreakpoint.useIsViewportLargerThanBreakpoint;
|
|
172
175
|
exports.useLayoutEffectOnce = useLayoutEffectOnce.useLayoutEffectOnce;
|
|
173
176
|
exports.useLayoutEffectSkipFirst = useLayoutEffectSkipFirst.useLayoutEffectSkipFirst;
|
|
174
|
-
exports.useIsViewportLargerThanBreakpoint = useIsViewportLargerThanBreakpoint.useIsViewportLargerThanBreakpoint;
|
|
175
177
|
exports.useOverflowDetection = useOverflowDetection.useOverflowDetection;
|
|
176
178
|
exports.useSlideSelection = useSlideSelection.useSlideSelection;
|
|
177
179
|
exports.AppHeader = AppHeader.AppHeader;
|
|
@@ -193,6 +195,8 @@ exports.useCalendarSelection = useCalendarSelection.useCalendarSelection;
|
|
|
193
195
|
exports.useCalendarSelectionDay = useCalendarSelection.useCalendarSelectionDay;
|
|
194
196
|
exports.Carousel = Carousel.Carousel;
|
|
195
197
|
exports.CarouselSlide = CarouselSlide.CarouselSlide;
|
|
198
|
+
exports.CarouselSlider = CarouselSlider.CarouselSlider;
|
|
199
|
+
exports.CarouselControls = CarouselControls.CarouselControls;
|
|
196
200
|
exports.CascadingMenu = CascadingMenu.CascadingMenu;
|
|
197
201
|
exports.ColorChooser = ColorChooser.ColorChooser;
|
|
198
202
|
exports.Color = Color.Color;
|
package/dist-cjs/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":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;"}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
var css_248z = ".
|
|
1
|
+
var css_248z = ".saltCarousel {\n display: grid;\n grid-row-gap: var(--salt-spacing-100);\n grid-template-areas: \"controls\" \"slider\";\n grid-template-rows: auto 1fr;\n}\n\n.saltCarousel.saltCarousel-bottom {\n grid-template-areas: \"slider\" \"controls\";\n grid-template-rows: 1fr auto;\n}\n";
|
|
2
2
|
|
|
3
3
|
export { css_248z as default };
|
|
4
4
|
//# sourceMappingURL=Carousel.css.js.map
|
|
@@ -1,22 +1,20 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { makePrefixer, useIcon, useId, GridLayout, Button, RadioButtonGroup, RadioButton } from '@salt-ds/core';
|
|
1
|
+
import { jsx } from 'react/jsx-runtime';
|
|
2
|
+
import { makePrefixer, useBreakpoint, resolveResponsiveValue, useId } from '@salt-ds/core';
|
|
4
3
|
import { useComponentCssInjection } from '@salt-ds/styles';
|
|
5
4
|
import { useWindow } from '@salt-ds/window';
|
|
6
5
|
import { clsx } from 'clsx';
|
|
7
|
-
import {
|
|
8
|
-
import { useSlideSelection } from '../utils/useSlideSelection.js';
|
|
6
|
+
import { forwardRef } from 'react';
|
|
9
7
|
import css_248z from './Carousel.css.js';
|
|
8
|
+
import { CarouselProvider } from './CarouselContext.js';
|
|
10
9
|
|
|
11
10
|
const withBaseName = makePrefixer("saltCarousel");
|
|
12
11
|
const Carousel = forwardRef(
|
|
13
12
|
function Carousel2({
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
13
|
+
defaultActiveSlideIndex = 0,
|
|
14
|
+
activeSlideIndex,
|
|
15
|
+
visibleSlides: visibleSlidesProp = 1,
|
|
17
16
|
children,
|
|
18
|
-
|
|
19
|
-
compact,
|
|
17
|
+
controlsPlacement = "top",
|
|
20
18
|
id: idProp,
|
|
21
19
|
...rest
|
|
22
20
|
}, ref) {
|
|
@@ -26,88 +24,33 @@ const Carousel = forwardRef(
|
|
|
26
24
|
css: css_248z,
|
|
27
25
|
window: targetWindow
|
|
28
26
|
});
|
|
29
|
-
const {
|
|
27
|
+
const { matchedBreakpoints } = useBreakpoint();
|
|
28
|
+
const visibleSlides = resolveResponsiveValue(
|
|
29
|
+
visibleSlidesProp,
|
|
30
|
+
matchedBreakpoints
|
|
31
|
+
);
|
|
30
32
|
const id = useId(idProp);
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
const moveSlide = (direction) => {
|
|
34
|
-
const moveLeft = selectedSlide === 0 ? slidesCount - 1 : selectedSlide - 1;
|
|
35
|
-
const moveRight = selectedSlide === slidesCount - 1 ? 0 : selectedSlide + 1;
|
|
36
|
-
const newSelection = direction === "left" ? moveLeft : moveRight;
|
|
37
|
-
const newTransition = direction === "left" ? "decrease" : "increase";
|
|
38
|
-
handleSlideSelection(newSelection, newTransition);
|
|
39
|
-
};
|
|
40
|
-
const handleRadioChange = ({
|
|
41
|
-
target: { value }
|
|
42
|
-
}) => {
|
|
43
|
-
handleSlideSelection(Number(value));
|
|
44
|
-
};
|
|
45
|
-
useEffect(() => {
|
|
46
|
-
if (process.env.NODE_ENV !== "production") {
|
|
47
|
-
if (slidesCount < 1) {
|
|
48
|
-
console.warn(
|
|
49
|
-
"Carousel component requires more than one children to render. At least two elements should be provided."
|
|
50
|
-
);
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
}, [slidesCount]);
|
|
54
|
-
return /* @__PURE__ */ jsxs(
|
|
55
|
-
GridLayout,
|
|
33
|
+
return /* @__PURE__ */ jsx(
|
|
34
|
+
CarouselProvider,
|
|
56
35
|
{
|
|
57
|
-
|
|
58
|
-
|
|
36
|
+
defaultActiveSlideIndex,
|
|
37
|
+
activeSlideIndex,
|
|
38
|
+
visibleSlides,
|
|
59
39
|
id,
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
variant: "secondary",
|
|
75
|
-
className: withBaseName("prev-button"),
|
|
76
|
-
onClick: () => moveSlide("left"),
|
|
77
|
-
children: /* @__PURE__ */ jsx(PreviousIcon, { size: 2 })
|
|
78
|
-
}
|
|
79
|
-
),
|
|
80
|
-
/* @__PURE__ */ jsx(
|
|
81
|
-
DeckLayout,
|
|
82
|
-
{
|
|
83
|
-
activeIndex: selectedSlide,
|
|
84
|
-
animation,
|
|
85
|
-
className: withBaseName("slider"),
|
|
86
|
-
children
|
|
87
|
-
}
|
|
88
|
-
),
|
|
89
|
-
/* @__PURE__ */ jsx(
|
|
90
|
-
Button,
|
|
91
|
-
{
|
|
92
|
-
variant: "secondary",
|
|
93
|
-
className: withBaseName("next-button"),
|
|
94
|
-
onClick: () => moveSlide("right"),
|
|
95
|
-
children: /* @__PURE__ */ jsx(NextIcon, { size: 2 })
|
|
96
|
-
}
|
|
97
|
-
),
|
|
98
|
-
/* @__PURE__ */ jsx("div", { className: withBaseName("dots"), children: /* @__PURE__ */ jsx(
|
|
99
|
-
RadioButtonGroup,
|
|
100
|
-
{
|
|
101
|
-
"aria-label": "Carousel buttons",
|
|
102
|
-
onChange: handleRadioChange,
|
|
103
|
-
value: `${selectedSlide}`,
|
|
104
|
-
direction: "horizontal",
|
|
105
|
-
children: Array.from({ length: slidesCount }, (_2, index) => ({
|
|
106
|
-
value: `${index}`
|
|
107
|
-
})).map((radio) => /* @__PURE__ */ createElement(RadioButton, { ...radio, key: radio.value }))
|
|
108
|
-
}
|
|
109
|
-
) })
|
|
110
|
-
]
|
|
40
|
+
children: /* @__PURE__ */ jsx(
|
|
41
|
+
"section",
|
|
42
|
+
{
|
|
43
|
+
role: "region",
|
|
44
|
+
className: clsx(withBaseName(), {
|
|
45
|
+
[withBaseName(controlsPlacement)]: controlsPlacement === "bottom"
|
|
46
|
+
}),
|
|
47
|
+
"aria-roledescription": "carousel",
|
|
48
|
+
id,
|
|
49
|
+
ref,
|
|
50
|
+
...rest,
|
|
51
|
+
children
|
|
52
|
+
}
|
|
53
|
+
)
|
|
111
54
|
}
|
|
112
55
|
);
|
|
113
56
|
}
|