@octopusdeploy/design-system-components
Version:
The design systems component library.
90 lines (89 loc) • 5.14 kB
JavaScript
;
Object.defineProperty(exports, "__esModule", { value: true });
exports.Carousel = Carousel;
const jsx_runtime_1 = require("react/jsx-runtime");
const css_1 = require("@emotion/css");
const design_system_icons_1 = require("@octopusdeploy/design-system-icons");
const design_system_tokens_1 = require("@octopusdeploy/design-system-tokens");
const react_1 = require("react");
const Button_1 = require("../Button");
const carouselStyles = {
carousel: (0, css_1.css)({
display: "flex",
flexDirection: "column",
alignItems: "center",
justifyContent: "flex-start",
height: "100%",
gap: design_system_tokens_1.space[24],
}),
carouselContentContainer: (0, css_1.css)({ overflowX: "hidden", width: "100%" }),
carouselAnimationContainer: (0, css_1.css)({
display: "flex",
flexDirection: "row",
direction: "ltr",
transition: "transform 0.35s cubic-bezier(0.15, 0.3, 0.25, 1) 0s;",
}),
slideContent: (0, css_1.css)({
display: "flex",
width: "100%",
overflow: "auto",
flexShrink: 0,
}),
};
function Carousel({ slides, initialSlide, accessibleName, onInteraction }) {
const [activeSlide, setActiveSlide] = (0, react_1.useState)(initialSlide && slides[initialSlide] ? initialSlide : 0);
const accessibleContainerName = accessibleName ?? "carousel";
const nextSlide = () => {
if (activeSlide < slides.length - 1) {
jumpToSlide(activeSlide + 1);
}
};
const previousSlide = () => {
if (activeSlide > 0) {
jumpToSlide(activeSlide - 1);
}
};
const jumpToSlide = (slideNumber) => {
setActiveSlide(slideNumber);
if (onInteraction) {
const slideKey = slides[slideNumber].key?.toString() ?? slideNumber.toString();
onInteraction(slideKey);
}
};
const transitionAnimation = {
transform: `translate(-${activeSlide > 0 ? activeSlide * 100 : 0}%, 0px)`,
};
return ((0, jsx_runtime_1.jsxs)("section", { className: carouselStyles.carousel, "aria-label": accessibleContainerName, "aria-roledescription": "carousel", children: [(0, jsx_runtime_1.jsx)("div", { className: carouselStyles.carouselContentContainer, children: (0, jsx_runtime_1.jsx)("div", { className: carouselStyles.carouselAnimationContainer, style: transitionAnimation, children: slides.map((slide, index) => ((0, jsx_runtime_1.jsx)("div", { role: "tabpanel", "aria-roledescription": "slide", "aria-label": `slide ${index}`, className: carouselStyles.slideContent, "aria-hidden": index !== activeSlide, children: slide }, slide.key ?? index))) }) }), (0, jsx_runtime_1.jsx)(Controller, { backButton: (0, jsx_runtime_1.jsx)(Button_1.Button, { importance: "quiet", onClick: previousSlide, icon: (0, jsx_runtime_1.jsx)(design_system_icons_1.ChevronLeftIcon, { size: 20 }), accessibleName: "Previous", disabled: activeSlide === 0 }), nextButton: (0, jsx_runtime_1.jsx)(Button_1.Button, { importance: "quiet", onClick: nextSlide, icon: (0, jsx_runtime_1.jsx)(design_system_icons_1.ChevronRightIcon, { size: 20 }), accessibleName: "Next", disabled: activeSlide === slides.length - 1 }), totalSlides: slides.length, activeSlide: activeSlide, onSlideDotClick: jumpToSlide, accessibleName: accessibleContainerName })] }));
}
const controllerStyles = {
controller: (0, css_1.css)({
display: "flex",
flexDirection: "row",
alignItems: "center",
justifyContent: "space-around",
height: 28,
gap: design_system_tokens_1.space[24],
}),
controllerDotContainer: (0, css_1.css)({
display: "inline-flex",
gap: design_system_tokens_1.space[12],
}),
controllerDot: (0, css_1.css)({
borderRadius: design_system_tokens_1.borderRadius.circle,
width: 12,
height: 12,
backgroundColor: design_system_tokens_1.themeTokens.color.carousel.icon.default,
cursor: "pointer",
"&:hover": {
backgroundColor: design_system_tokens_1.themeTokens.color.carousel.icon.hover,
},
}),
};
const controllerActiveDotStyles = (0, css_1.cx)(controllerStyles.controllerDot, (0, css_1.css)({
backgroundColor: design_system_tokens_1.themeTokens.color.carousel.icon.selected,
}));
function Controller({ backButton, nextButton, totalSlides, activeSlide, onSlideDotClick, accessibleName }) {
const slides = [...Array(totalSlides).keys()];
const accessibleContainerName = accessibleName ? `${accessibleName} slides` : "slides";
return ((0, jsx_runtime_1.jsxs)("div", { className: controllerStyles.controller, role: "tablist", "aria-label": accessibleContainerName, children: [backButton, (0, jsx_runtime_1.jsx)("div", { className: controllerStyles.controllerDotContainer, children: slides.map((val) => ((0, jsx_runtime_1.jsx)("span", { role: "tab", "aria-label": `slide ${val}`, "aria-selected": val === activeSlide, onClick: () => onSlideDotClick(val), className: val === activeSlide ? controllerActiveDotStyles : controllerStyles.controllerDot }, val))) }), nextButton] }));
}