diff --git a/examples/simple/src/App.tsx b/examples/simple/src/App.tsx index d9715949..a55b4f1f 100644 --- a/examples/simple/src/App.tsx +++ b/examples/simple/src/App.tsx @@ -39,7 +39,12 @@ const Clock = () => { const Timer = () => { return ( - + console.log('start', e)} + onStop={(e) => console.log('stop', e)} + onComplete={(e) => console.log('complete', e)} + onReset={(e) => console.log('reset', e)} + > {(timer: TimerProps) => } @@ -49,7 +54,11 @@ const Timer = () => { const Stopwatch = () => { return ( - + console.log('start', e)} + onStop={(e) => console.log('stop', e)} + onReset={(e) => console.log('reset', e)} + > {(props: StopwatchProps) => } diff --git a/packages/stopwatch/src/container.tsx b/packages/stopwatch/src/container.tsx index 2f008ac7..14064fb7 100644 --- a/packages/stopwatch/src/container.tsx +++ b/packages/stopwatch/src/container.tsx @@ -35,6 +35,12 @@ export const StopwatchContainer: React.FunctionComponent< StopwatchContainerProps > = (props): JSX.Element => { const { children } = props + const emptyFn = (_event: CustomEvent) => { + /* do nothing */ + } + const onStart = props.onStart ?? emptyFn + const onStop = props.onStop ?? emptyFn + const onReset = props.onReset ?? emptyFn const [running, setRunning] = useState(false) const [elapsedTimeInLap, setElapsedTimeInLap] = useState(0) const [elapsedTimeTotal, setElapsedTimeTotal] = useState(0) @@ -61,6 +67,7 @@ export const StopwatchContainer: React.FunctionComponent< if (running) { return } + onStart(new CustomEvent('start', {})) setStartTime(new Date()) setRunning(true) } @@ -69,6 +76,7 @@ export const StopwatchContainer: React.FunctionComponent< if (!running) { return } + onStop(new CustomEvent('stop', {})) updateElapsedTime() setRunning(false) moveLapToTotal() @@ -86,6 +94,7 @@ export const StopwatchContainer: React.FunctionComponent< if (running) { stop() } + onReset(new CustomEvent('reset', {})) setElapsedTimeInLap(0) setElapsedTimeTotal(0) } diff --git a/packages/stopwatch/src/types.ts b/packages/stopwatch/src/types.ts index 68910ce2..76e30127 100644 --- a/packages/stopwatch/src/types.ts +++ b/packages/stopwatch/src/types.ts @@ -15,4 +15,7 @@ export type StopwatchProps = StopwatchValue & StopwatchActions export interface StopwatchContainerProps { refreshInterval?: number children: React.ReactElement | React.ReactElement[] + onStart?(event: CustomEvent): void + onStop?(event: CustomEvent): void + onReset?(event: CustomEvent): void } diff --git a/packages/timer/src/container.tsx b/packages/timer/src/container.tsx index f8c63539..9e4b8b4b 100644 --- a/packages/timer/src/container.tsx +++ b/packages/timer/src/container.tsx @@ -37,6 +37,13 @@ export const TimerContainer: React.FunctionComponent = ( props ): JSX.Element => { const { children } = props + const emptyFn = (_event: CustomEvent) => { + /* do nothing */ + } + const onStart = props.onStart ?? emptyFn + const onStop = props.onStop ?? emptyFn + const onComplete = props.onComplete ?? emptyFn + const onReset = props.onReset ?? emptyFn const [running, setRunning] = useState(false) const [targetDate, setTargetDate] = useState(new Date()) const [remaining, setRemaining] = useState(0) @@ -44,15 +51,21 @@ export const TimerContainer: React.FunctionComponent = ( const refreshInterval = props.refreshInterval || 10 // default 10ms useInterval(() => { + tick() + }, refreshInterval) + + function tick() { + // It can't be ticked if it is not running. if (running) { const remaining = calcRemaining(targetDate) setRemaining(remaining) if (remaining <= 0) { setRemaining(0) setRunning(false) + onComplete(new CustomEvent('complete', {})) } } - }, refreshInterval) + } function toggle() { if (running) { @@ -63,19 +76,35 @@ export const TimerContainer: React.FunctionComponent = ( } function reset() { + // First, stop the timer if it is running. if (running) { stop() } setRemaining(0) + onReset(new CustomEvent('reset', {})) } function start() { + // It can't be started if the remaining time is 0. + if (remaining <= 0) { + return + } + // It can't be started if it is already running. + if (running) { + return + } setTargetDate(new Date(Date.now() + remaining * 1000)) setRunning(true) + onStart(new CustomEvent('start', {})) } function stop() { + // It can't be stopped if it is not running. + if (!running) { + return + } setRunning(false) + onStop(new CustomEvent('stop', {})) } return ( diff --git a/packages/timer/src/types.ts b/packages/timer/src/types.ts index 8c990bca..88185c2d 100644 --- a/packages/timer/src/types.ts +++ b/packages/timer/src/types.ts @@ -17,4 +17,8 @@ export type TimerProps = TimerValue & TimerActions export interface TimerContainerProps { refreshInterval?: number children: React.ReactElement | React.ReactElement[] + onStart?(event: CustomEvent): void + onStop?(event: CustomEvent): void + onComplete?(event: CustomEvent): void + onReset?(event: CustomEvent): void }