123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384 |
- import React, { useEffect, useRef, useState } from "react";
- const useCountdown = (seconds, onEnd) => {
- const [finished, setFinished] = useState(false);
- const [remaining, setRemaining] = useState(seconds);
- const [paused, setPaused] = useState(false);
- const remainingMut = useRef(seconds);
- useEffect(() => {
- const timer = setInterval(() => {
- if (!paused) {
- setRemaining((remainingMut.current -= 1));
- }
- }, 1000);
- return () => clearInterval(timer);
- }, [paused]);
- useEffect(() => {
- if (!finished && remaining <= 0) {
- onEnd();
- setFinished(true);
- }
- }, [finished, remaining, onEnd]);
- return [remaining, () => setPaused(!paused)];
- };
- const CountdownButton = ({
- onCancelled,
- onEnd,
- formatter,
- seconds,
- autoFocus,
- buttonClass,
- }) => {
- const [remaining, pause] = useCountdown(seconds, onEnd);
- return (
- <button
- type="button"
- className={buttonClass}
- autoFocus={autoFocus}
- onClick={() => {
- pause();
- onCancelled();
- }}
- >
- {formatter(remaining)}
- </button>
- );
- };
- const DelayedButton = ({
- children,
- onEnd,
- countDownFormatter,
- seconds,
- autoFocus,
- buttonClass,
- }) => {
- const [delayed, setDelayed] = useState(false);
- return delayed ? (
- <CountdownButton
- onCancelled={() => setDelayed(false)}
- onEnd={onEnd}
- formatter={countDownFormatter ?? JSON.stringify}
- seconds={seconds ?? 3}
- autoFocus={autoFocus}
- buttonClass={buttonClass}
- />
- ) : (
- <button
- type="button"
- className={buttonClass}
- autoFocus={autoFocus}
- onClick={() => setDelayed(true)}
- >
- {children}
- </button>
- );
- };
- export default DelayedButton;
|