UNPKG

react-round-carousel

Version:

An infinitely scrollable 3D carousel component for React

81 lines (80 loc) 5.21 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.Carousel = void 0; var tslib_1 = require("tslib"); var jsx_runtime_1 = require("react/jsx-runtime"); var touchsweep_1 = require("touchsweep"); var uuid_1 = require("uuid"); var react_1 = require("react"); exports.Carousel = (0, react_1.forwardRef)(function (_a, CarouselRef) { var items = _a.items, _b = _a.itemWidth, itemWidth = _b === void 0 ? 210 : _b, _c = _a.showControls, showControls = _c === void 0 ? true : _c, _d = _a.slideOnClick, slideOnClick = _d === void 0 ? false : _d, _e = _a.classNamePrefix, classNamePrefix = _e === void 0 ? 'carousel' : _e, _f = _a.prevButtonContent, prevButtonContent = _f === void 0 ? 'Previous' : _f, _g = _a.nextButtonContent, nextButtonContent = _g === void 0 ? 'Next' : _g; var data = (0, react_1.useMemo)(function () { return items.map(function (item) { return (tslib_1.__assign(tslib_1.__assign({}, item), (item.id ? {} : { id: (0, uuid_1.v4)() }))); }); }, [items]); var len = (0, react_1.useMemo)(function () { return data.length; }, [data.length]); var theta = (0, react_1.useMemo)(function () { return 360 / len; }, [len]); var radius = (0, react_1.useMemo)(function () { return Math.round(itemWidth / 2 / Math.tan(Math.PI / len)); }, [itemWidth, len]); var ref = (0, react_1.useRef)(null); var _h = (0, react_1.useState)(0), selectedIndex = _h[0], setSelectedIndex = _h[1]; var getSlideStyle = (0, react_1.useCallback)(function (index) { var style = {}; if (index < len) { var cellAngle = theta * index; style.opacity = 1; style.transform = "rotateY(".concat(cellAngle, "deg) translateZ(").concat(radius, "px)"); } else { style.opacity = 0; style.transform = 'none'; } return style; }, [len, radius, theta]); var getItemStyle = (0, react_1.useCallback)(function () { var angle = theta * selectedIndex * -1; return { transform: "translateZ(".concat(-1 * radius, "px) rotateY(").concat(angle, "deg)") }; }, [radius, selectedIndex, theta]); var getClassName = (0, react_1.useCallback)(function (parts) { return Array.isArray(parts) ? parts .map(function (part) { return "".concat(classNamePrefix).concat(part); }) .join(' ') : "".concat(classNamePrefix).concat(parts); }, [classNamePrefix]); var prev = (0, react_1.useCallback)(function () { return setSelectedIndex(selectedIndex - 1); }, [selectedIndex]); var next = (0, react_1.useCallback)(function () { return setSelectedIndex(selectedIndex + 1); }, [selectedIndex]); (0, react_1.useEffect)(function () { var area = ref === null || ref === void 0 ? void 0 : ref.current; var touchsweep = new touchsweep_1.default(area !== null && area !== void 0 ? area : undefined); area === null || area === void 0 ? void 0 : area.addEventListener('swipeleft', next); area === null || area === void 0 ? void 0 : area.addEventListener('swiperight', prev); return function () { touchsweep.unbind(); area === null || area === void 0 ? void 0 : area.removeEventListener('swipeleft', next); area === null || area === void 0 ? void 0 : area.removeEventListener('swiperight', prev); }; }); (0, react_1.useImperativeHandle)(CarouselRef, function () { return ({ next: next, prev: prev, getItems: function () { return data; }, getSelectedIndex: function () { return selectedIndex; }, setSelectedIndex: function (index) { return setSelectedIndex(index); } }); }); return ((0, jsx_runtime_1.jsxs)(jsx_runtime_1.Fragment, { children: [(0, jsx_runtime_1.jsx)("div", { className: getClassName(''), ref: ref, children: (0, jsx_runtime_1.jsx)("div", { className: getClassName('__container'), style: getItemStyle(), children: data.map(function (item, index) { return ((0, jsx_runtime_1.jsxs)("div", { style: getSlideStyle(index), onClick: function () { if (item.onClick) item.onClick(); if (slideOnClick) setSelectedIndex(index); }, className: getClassName('__slide'), children: [(0, jsx_runtime_1.jsx)("img", { src: item.image, alt: item.alt }), (0, jsx_runtime_1.jsx)("div", { className: getClassName('__slide-overlay'), children: item.content })] }, item.id)); }) }) }), showControls && ((0, jsx_runtime_1.jsxs)("div", { className: getClassName('__controls'), children: [(0, jsx_runtime_1.jsx)("button", { className: getClassName([ '__control', '__control--prev' ]), onClick: prev, children: prevButtonContent }), (0, jsx_runtime_1.jsx)("button", { className: getClassName([ '__control', '__control--next' ]), onClick: next, children: nextButtonContent })] }))] })); }); exports.default = exports.Carousel;