@smitch/fluid
Version:
A Next/React ui-component libray.
147 lines (146 loc) • 7.56 kB
JavaScript
'use client';
import { jsx as _jsx, Fragment as _Fragment, jsxs as _jsxs } from "react/jsx-runtime";
import { useState, useRef, useEffect, useMemo } from 'react';
import { twMerge } from 'tailwind-merge';
import { Button, Gallery } from '..';
import { HiChevronRight, HiChevronLeft, HiOutlineArrowRight, HiOutlineArrowLeft, } from 'react-icons/hi';
var aspects = {
landscape: 'aspect-[4/3]',
portrait: 'aspect-[3/4]',
square: 'aspect-square',
circle: 'aspect-square',
video: 'aspect-video',
};
var iconSizes = {
md: 18,
lg: 24,
xl: 32,
};
var outlineWidths = {
none: 'outline-0',
thin: 'outline-1',
medium: 'outline-2',
thick: 'outline-4',
};
var roundedWidths = {
none: 'rounded-0',
md: 'rounded-md',
lg: 'rounded-lg',
xl: 'rounded-xl',
};
var Carousel = function (_a) {
var data = _a.data, _b = _a.caption, caption = _b === void 0 ? false : _b, _c = _a.autoplay, autoplay = _c === void 0 ? false : _c, _d = _a.autoplayDuration, autoplayDuration = _d === void 0 ? 3000 : _d, _e = _a.outline, outline = _e === void 0 ? 'medium' : _e, _f = _a.gallery, gallery = _f === void 0 ? true : _f, _g = _a.className, className = _g === void 0 ? '' : _g, _h = _a.aspect, aspect = _h === void 0 ? 'landscape' : _h, _j = _a.rounded, rounded = _j === void 0 ? 'none' : _j, _k = _a.buttonsPosition, buttonsPosition = _k === void 0 ? 'middle' : _k, _l = _a.buttonLayout, buttonLayout = _l === void 0 ? 'circle' : _l, _m = _a.buttonIcon, buttonIcon = _m === void 0 ? 'chevron' : _m, _o = _a.buttonSize, buttonSize = _o === void 0 ? 'md' : _o, _p = _a.buttonBackground, buttonBackground = _p === void 0 ? 'dark' : _p, _q = _a.buttonColor, buttonColor = _q === void 0 ? 'light' : _q, _r = _a.buttonOutline, buttonOutline = _r === void 0 ? true : _r, children = _a.children;
var _s = useState(0), index = _s[0], setIndex = _s[1];
var _t = useState(0), position = _t[0], setPosition = _t[1];
var _u = useState(false), rtl = _u[0], setRtl = _u[1];
var _v = useState(null), touchPosition = _v[0], setTouchPosition = _v[1];
var _w = useState(286), innerWidth = _w[0], setInnerWidth = _w[1];
var inner = useRef(null);
var intervalRef = useRef(null);
var playDirection = useRef('forward');
var iconSize = useMemo(function () { return iconSizes[buttonSize]; }, [buttonSize]);
var outlineClasses = useMemo(function () { return outlineWidths[outline]; }, [outline]);
var roundedClasses = useMemo(function () { return roundedWidths[rounded]; }, [rounded]);
var buttonsPositionClasses = useMemo(function () {
var buttonsPositions = {
top: 'top-2',
middle: 'top-[38%]',
bottom: caption ? 'bottom-12' : 'bottom-2',
};
return buttonsPositions[buttonsPosition];
}, [buttonsPosition, caption]);
var aspectClasses = useMemo(function () { return aspects[aspect]; }, [aspect]);
useEffect(function () {
var checkInnerWidth = function () {
if (inner.current) {
setInnerWidth(inner.current.offsetWidth);
}
else {
setTimeout(checkInnerWidth, 100);
}
};
checkInnerWidth();
}, [inner]);
useEffect(function () {
var isRTL = document.documentElement.getAttribute('dir') === 'rtl';
isRTL ? setRtl(true) : setRtl(false);
}, []);
var style = useMemo(function () {
return rtl ? { right: "".concat(position, "px") } : { left: "".concat(position, "px") };
}, [position, rtl]);
var heightStyle = useMemo(function () {
var _a;
var aspectRatios = {
landscape: 4 / 3,
portrait: 3 / 4,
video: 16 / 9,
phone: 9 / 16,
};
var aspectRatio = (_a = aspectRatios[aspect]) !== null && _a !== void 0 ? _a : 1;
var height = innerWidth / aspectRatio;
return { height: height };
}, [aspect, innerWidth]);
useEffect(function () {
var startAutoplay = function () {
intervalRef.current = window.setTimeout(function () {
if (index === 0)
playDirection.current = 'forward';
else if (index === data.length - 1)
playDirection.current = 'backward';
if (playDirection.current === 'forward')
setNext();
else
setPrevious();
}, autoplayDuration);
};
if (autoplay)
startAutoplay();
return function () {
clearInterval(intervalRef.current);
};
});
var clickNext = function (e) {
e.stopPropagation();
setNext();
};
var setNext = function () {
if (index === data.length - 1)
return;
setPosition(position - innerWidth);
setIndex(index + 1);
};
var clickPrevious = function (e) {
e.stopPropagation();
e.preventDefault();
setPrevious();
};
var setPrevious = function () {
if (index === 0)
return;
setPosition(position + innerWidth);
setIndex(index - 1);
};
var handleTouchStart = function (e) {
setTouchPosition(e.touches[0].clientX);
};
var handleTouchMove = function (e) {
if (touchPosition === null || autoplay)
return;
var diff = touchPosition - e.touches[0].clientX;
if (diff > 5) {
if (rtl)
setPrevious();
else
setNext();
}
else if (diff < -5) {
if (rtl)
setNext();
else
setPrevious();
}
setTouchPosition(null);
};
return (_jsx(_Fragment, { children: _jsxs("div", { className: twMerge("carousel group relative flex justify-center overflow-hidden w-auto outline outline-neutral ".concat(outlineClasses, " ").concat(roundedClasses), className), onTouchStart: handleTouchStart, onTouchMove: handleTouchMove, children: [_jsx("div", { className: "inner max-w-lg relative overflow-hidden ".concat(aspectClasses), ref: inner, style: heightStyle, children: gallery ? (_jsx(Gallery, { className: "oveflow-hidden !flex !gap-0 relative transition-all duration-500", style: style, data: data, caption: caption, aspect: aspect })) : (_jsx("div", { className: "oveflow-hidden !flex h-full transition-all duration-500 relative", style: style, children: children })) }), !autoplay && (_jsxs(_Fragment, { children: [_jsx("div", { className: "absolute z-10 start-2 ".concat(buttonsPositionClasses), children: _jsx(Button, { onClick: function (e) { return clickPrevious(e); }, className: "m-auto opacity-30 hover:opacity-100 disabled:hidden", disabled: index === 0, layout: buttonLayout, btnBackground: buttonBackground, btnColor: buttonColor, outline: buttonOutline, children: buttonIcon === 'arrow' ? (_jsx(HiOutlineArrowLeft, { size: iconSize })) : (_jsx(HiChevronLeft, { size: iconSize })) }) }), _jsx("div", { className: "absolute z-10 end-2 ".concat(buttonsPositionClasses), children: _jsx(Button, { onClick: function (e) { return clickNext(e); }, className: "m-auto opacity-30 hover:opacity-100 disabled:hidden", disabled: index === data.length - 1, layout: buttonLayout, btnBackground: buttonBackground, btnColor: buttonColor, outline: buttonOutline, children: buttonIcon === 'arrow' ? (_jsx(HiOutlineArrowRight, { size: iconSize })) : (_jsx(HiChevronRight, { size: iconSize })) }) })] }))] }) }));
};
export default Carousel;