UNPKG

@etsoo/materialui

Version:

TypeScript Material-UI Implementation

93 lines (92 loc) 3.06 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.CountdownButton = void 0; const jsx_runtime_1 = require("react/jsx-runtime"); const Button_1 = __importDefault(require("@mui/material/Button")); const CircularProgress_1 = __importDefault(require("@mui/material/CircularProgress")); const react_1 = __importDefault(require("react")); /** * Countdown button * @param props Props * @returns Button */ exports.CountdownButton = react_1.default.forwardRef((props, ref) => { // Destructure const { initState = 0, onAction, onClick, ...rest } = props; // State // 0 - normal // 1 - loading // >= 2 - countdown seconds const [state, updateState] = react_1.default.useState(0); // Ignore seconds const ignoreSeconds = 2; // Refs const refs = react_1.default.useRef({ isMounted: false, maxLength: 0 }); // Set state const setState = react_1.default.useCallback((result) => { // Seconds to wait, 120 if (result > ignoreSeconds) { // Here 122 result += ignoreSeconds; updateState(result); // Update max length refs.current.maxLength = result.toString().length; const seed = setInterval(() => { // Mounted? if (!refs.current.isMounted) return; // Last 1 second and then complete if (result > ignoreSeconds + 1) { result--; updateState(result); } else { clearInterval(seed); updateState(0); } }, 1000); } else { updateState(0); } }, []); // endIcon let endIcon; if (state === 0) { endIcon = undefined; } else if (state === 1) { endIcon = (0, jsx_runtime_1.jsx)(CircularProgress_1.default, { size: 12 }); } else { const countdown = (state - ignoreSeconds) .toString() .padStart(refs.current.maxLength, "0"); endIcon = (0, jsx_runtime_1.jsx)("span", { style: { fontSize: "smaller" }, children: countdown }); } // Disabled? const disabled = state > 0; // Local click const localClick = (event) => { // Show loading updateState(1); // Callback if (onClick != null) onClick(event); // Return any countdown onAction().then(setState); }; react_1.default.useEffect(() => { refs.current.isMounted = true; return () => { refs.current.isMounted = false; }; }, []); react_1.default.useEffect(() => { setState(initState); }, [initState]); return ((0, jsx_runtime_1.jsx)(Button_1.default, { disabled: disabled, endIcon: endIcon, onClick: localClick, ref: ref, ...rest })); });