UNPKG

react-status-stories

Version:

A lightweight and customizable React component to display WhatsApp-style status stories with circular previews. Perfect for building Instagram, WhatsApp, or Snapchat-like story UIs in your React apps.

79 lines (78 loc) 5 kB
import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime"; import { useState, useEffect, useRef } from "react"; var ReactStatus = function (_a) { var items = _a.items, _b = _a.timeout, timeout = _b === void 0 ? 3000 : _b, _c = _a.customClass, customClass = _c === void 0 ? "" : _c; var _d = useState(0), activeIndex = _d[0], setActiveIndex = _d[1]; var _e = useState(timeout), newTime = _e[0], setNewTime = _e[1]; var _f = useState(false), isPaused = _f[0], setIsPaused = _f[1]; var timerRef = useRef(null); var mouseLeaveRef = useRef(null); var timeCheck = Date.now(); // Setting active index var handleTimeout = function () { clearInterval(mouseLeaveRef.current); clearInterval(timerRef.current); }; var handleImage = function (e) { handleTimeout(); setIsPaused(false); setNewTime(timeout); setActiveIndex(function (prevIndex) { return e === "previous" ? (prevIndex + items.length - 1) % items.length : (prevIndex + 1) % items.length; }); }; // Incrementing index after timeout var handleIncrementIndex = function () { handleTimeout(); setActiveIndex(function (prevIndex) { return (prevIndex + 1) % items.length; }); setNewTime(timeout); }; // Clearing timeout and calling increment index function useEffect(function () { if (!isPaused) { timerRef.current = setInterval(handleIncrementIndex, timeout); } return function () { return clearInterval(timerRef.current); }; }, [activeIndex]); // Pause Time var handlePause = function () { var currentTime = Date.now() - timeCheck; setNewTime(newTime - currentTime); setIsPaused(true); handleTimeout(); }; // Play var handlePlay = function () { setIsPaused(false); mouseLeaveRef.current = setInterval(handleIncrementIndex, newTime); }; // Handling pause and play of time var handleTimeElapsed = function (e) { if (e.type === "touchstart") { handlePause(); } else if (e.type === "touchend") { handlePlay(); } }; return (_jsxs("div", { className: "jul-stories ".concat(customClass).replace(/\s\s+/g, " ").trim(), onTouchStart: function (e) { return handleTimeElapsed(e); }, onTouchEnd: function (e) { return handleTimeElapsed(e); }, children: [_jsx("div", { className: "jul-stories__container", children: _jsxs("figure", { children: [_jsx("img", { src: items[activeIndex].imageUrl, alt: "story" }), _jsx("figcaption", { children: items[activeIndex].imageCaption })] }) }), items.length !== 1 && (_jsxs(_Fragment, { children: [_jsxs("div", { className: "jul-stories__control", children: [_jsx("button", { onClick: function () { return handleImage("previous"); }, children: "Previous" }), _jsx("button", { onClick: function () { return handleImage("next"); }, children: "Next" })] }), _jsx("div", { className: "jul-stories__progressContainer", children: items.map(function (i, index) { return (_jsx("div", { className: "jul-stories__progressItems", children: _jsx("span", { className: "".concat(index === activeIndex ? "jul-stories__progressItems--active" : ""), style: { animationDuration: "".concat(timeout, "ms"), animationPlayState: isPaused ? "paused" : "running", } }) }, index)); }) }), _jsx("div", { className: "jul-stories__pause-play ".concat(isPaused ? "jul-stories__pause-play--paused" : "jul-stories__pause-play--play"), role: "button", onClick: function (e) { if (!isPaused) { handlePause(); } else { handlePlay(); } }, "aria-label": isPaused ? "play" : "pause", children: !isPaused ? (_jsxs("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "white", xmlns: "http://www.w3.org/2000/svg", children: [_jsx("path", { d: "M10 4.93652H6V20.9365H10V4.93652Z", stroke: "#1c2433", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }), _jsx("path", { d: "M14 20.9365V4.93652H18V20.9365H14Z", stroke: "#1c2433", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" })] })) : (_jsx("svg", { width: "20", height: "20", viewBox: "0 0 24 24", fill: "white", xmlns: "http://www.w3.org/2000/svg", children: _jsx("path", { d: "M5 3.93652L19 12.9365L5 21.9365V3.93652Z", stroke: "#1c2433", strokeWidth: "2", strokeLinecap: "round", strokeLinejoin: "round" }) })) })] }))] })); }; export default ReactStatus;