Skip to content

Commit c33ca91

Browse files
authored
Merge pull request #4 from amrlabib/feature/separate-exports
Feature/separate exports
2 parents a64add8 + c145d97 commit c33ca91

File tree

4 files changed

+203
-60
lines changed

4 files changed

+203
-60
lines changed

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "react-timer-hook",
3-
"version": "1.0.8",
3+
"version": "1.1.0",
44
"description": "React timer hook is a custom react hook built to handle timers and count down logic in your react component.",
55
"main": "dist/index.js",
66
"scripts": {

readme.md

Lines changed: 105 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
## react-timer-hook
22

3-
React timer hook is a custom [react hook](https://reactjs.org/docs/hooks-intro.html), built to handle timers and countdown logic in your react component.
3+
React timer hook is a custom [react hook](https://reactjs.org/docs/hooks-intro.html), built to handle time related logic in your react component:
4+
5+
1. Timers (countdown timer) `useTimer`
6+
2. Stopwatch (count up timer) `useStopwatch`
7+
48

59
#### Note:
610

@@ -18,58 +22,137 @@ OR
1822

1923
---
2024

21-
## Example
25+
## `useTimer`
26+
27+
### Example
2228

2329
```javascript
2430
import React from 'react';
25-
import useTimer from 'react-timer-hook';
31+
import { useTimer } from 'react-timer-hook';
2632

27-
export default function App() {
33+
function MyTimer({ expiryTimestamp }) {
2834
const {
2935
seconds,
3036
minutes,
3137
hours,
3238
days,
33-
startTimer,
34-
stopTimer,
35-
resetTimer,
36-
} = useTimer({ autoStart: true });
39+
start,
40+
pause,
41+
resume
42+
} = useTimer({ expiryTimestamp, onExpire: () => console.warn('onExpire called') });
3743

3844

3945
return (
4046
<div style={{textAlign: 'center'}}>
41-
<h1>react-timer-hook Demo</h1>
47+
<h1>react-timer-hook </h1>
48+
<p>Timer Demo</p>
4249
<div style={{fontSize: '100px'}}>
4350
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>
4451
</div>
45-
<button onClick={startTimer}>Start</button>
46-
<button onClick={stopTimer}>Stop</button>
47-
<button onClick={resetTimer}>Reset</button>
52+
<button onClick={start}>Start</button>
53+
<button onClick={pause}>Pause</button>
54+
<button onClick={resume}>Resume</button>
4855
</div>
4956
);
5057
}
51-
```
5258

53-
---
59+
export default function App() {
60+
var t = new Date();
61+
t.setSeconds(t.getSeconds() + 600); // 10 minutes timer
62+
return (
63+
<div>
64+
<MyTimer expiryTimestamp={t} />
65+
</div>
66+
);
67+
}
68+
```
5469

55-
## Settings
70+
### Settings
5671

5772
| key | Type | Required | Description |
5873
| --- | --- | --- | ---- |
59-
| autoStart | boolean | No | if set to `true` timer will auto start |
60-
| expiryTimestamp | number(timestamp) | No | if set a countdown timer will start, instead of normal timer |
61-
| onExpire | Function | No | callback function to be executed once countdown timer is expired, works only for countdown |
74+
| expiryTimestamp | number(timestamp) | YES | this will define for how long the timer will be running |
75+
| onExpire | Function | No | callback function to be executed once countdown timer is expired |
76+
77+
### Values
78+
79+
| key | Type | Description |
80+
| --- | --- | ---- |
81+
| seconds | number | seconds value |
82+
| minutes | number | minutes value |
83+
| hours | number | hours value |
84+
| days | number | days value |
85+
| pause | function | function to be called to pause timer |
86+
| start | function | function if called after pause the timer will continue based on original expiryTimestamp |
87+
| resume | function | function if called after pause the timer will continue countdown from last paused state |
88+
6289

6390
---
6491

65-
## Values
92+
## `useStopwatch`
93+
94+
### Example
95+
96+
```javascript
97+
import React from 'react';
98+
import { useStopwatch } from 'react-timer-hook';
99+
100+
function MyStopwatch() {
101+
const {
102+
seconds,
103+
minutes,
104+
hours,
105+
days,
106+
start,
107+
pause,
108+
reset,
109+
} = useStopwatch({ autoStart: true });
110+
111+
112+
return (
113+
<div style={{textAlign: 'center'}}>
114+
<h1>react-timer-hook</h1>
115+
<p>Stopwatch Demo</p>
116+
<div style={{fontSize: '100px'}}>
117+
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>
118+
</div>
119+
<button onClick={start}>Start</button>
120+
<button onClick={pause}>Pause</button>
121+
<button onClick={reset}>Reset</button>
122+
</div>
123+
);
124+
}
125+
126+
export default function App() {
127+
return (
128+
<div>
129+
<MyStopwatch />
130+
</div>
131+
);
132+
}
133+
```
134+
135+
### Settings
136+
137+
| key | Type | Required | Description |
138+
| --- | --- | --- | ---- |
139+
| autoStart | boolean | No | if set to `true` stopwatch will auto start |
140+
141+
### Values
66142

67143
| key | Type | Description |
68144
| --- | --- | ---- |
69145
| seconds | number | seconds value |
70146
| minutes | number | minutes value |
71147
| hours | number | hours value |
72148
| days | number | days value |
73-
| startTimer | function | function to be called to start timer |
74-
| stopTimer | function | function to be called to stop timer |
75-
| resetTimer | function | function to be called to reset timer to 0:0:0:0 |
149+
| start | function | function to be called to start stopwatch |
150+
| pause | function | function to be called to pause stopwatch |
151+
| reset | function | function to be called to reset stopwatch to 0:0:0:0 |
152+
153+
154+
---
155+
156+
### Deprecation Warning:
157+
158+
Starting from `v1.1.0` and above default export `useTimer` is deprecated, your old code will still work but it is better to start using named exports `{ useTimer, useStopwatch }`

src/App.js

Lines changed: 21 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,27 +1,38 @@
11
import React from 'react';
2-
import useTimer from './useTimer';
2+
import { useTimer } from './useTimer';
33

4-
export default function App() {
4+
function MyTimer({ expiryTimestamp }) {
55
const {
66
seconds,
77
minutes,
88
hours,
99
days,
10-
startTimer,
11-
stopTimer,
12-
resetTimer,
13-
} = useTimer({ autoStart: true });
10+
start,
11+
pause,
12+
resume
13+
} = useTimer({ expiryTimestamp, onExpire: () => console.warn('onExpire called') });
1414

1515

1616
return (
1717
<div style={{textAlign: 'center'}}>
18-
<h1>react-timer-hook Demo</h1>
18+
<h1>react-timer-hook </h1>
19+
<p>Timer Demo</p>
1920
<div style={{fontSize: '100px'}}>
2021
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>
2122
</div>
22-
<button onClick={startTimer}>Start</button>
23-
<button onClick={stopTimer}>Stop</button>
24-
<button onClick={resetTimer}>Reset</button>
23+
<button onClick={start}>Start</button>
24+
<button onClick={pause}>Pause</button>
25+
<button onClick={resume}>Resume</button>
26+
</div>
27+
);
28+
}
29+
30+
export default function App() {
31+
var t = new Date();
32+
t.setSeconds(t.getSeconds() + 600); // 10 minutes timer
33+
return (
34+
<div>
35+
<MyTimer expiryTimestamp={t} />
2536
</div>
2637
);
2738
}

src/useTimer.js

Lines changed: 76 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,22 @@
11
import { useState, useEffect, useRef } from 'react';
22

3-
export default function useTimer(settings) {
4-
const { autoStart, expiryTimestamp, onExpire } = settings || {};
3+
export default function deprecatedUseTimer(settings) {
4+
// didMount effect
5+
useEffect(() => {
6+
console.warn('react-timer-hook: default export useTimer is deprecated, use named exports { useTimer, useStopwatch } instead');
7+
},[]);
8+
9+
if(settings.expiryTimestamp) {
10+
return useTimer(settings);
11+
} else {
12+
return useStopwatch(settings);
13+
}
14+
}
15+
16+
/* --------------------- useStopwatch ----------------------- */
17+
18+
export function useStopwatch(settings) {
19+
const { autoStart } = settings || {};
520

621
// Seconds
722
const [seconds, setSeconds] = useState(0);
@@ -49,39 +64,69 @@ export default function useTimer(settings) {
4964

5065
// Control functions
5166
const intervalRef = useRef();
52-
function start(isFunctionTrigger) {
53-
if (expiryTimestamp) {
54-
isValidExpiryTimestamp(expiryTimestamp) && runCountdownTimer();
55-
} else if(autoStart) {
56-
runTimer();
57-
}
58-
}
5967

60-
function runCountdownTimer() {
68+
function start() {
6169
if(!intervalRef.current) {
62-
calculateExpiryDate();
63-
intervalRef.current = setInterval(() => calculateExpiryDate(), 1000);
70+
intervalRef.current = setInterval(() => addSecond(), 1000);
6471
}
6572
}
6673

67-
function startTimer() {
68-
runTimer();
74+
function pause() {
75+
if(intervalRef.current) {
76+
clearInterval(intervalRef.current);
77+
intervalRef.current = undefined;
78+
}
6979
}
7080

71-
function stopTimer() {
72-
if(intervalRef.current) {
81+
function reset() {
82+
if (intervalRef.current) {
7383
clearInterval(intervalRef.current);
7484
intervalRef.current = undefined;
7585
}
86+
setSeconds(0);
87+
setMinutes(0);
88+
setHours(0);
89+
setDays(0);
7690
}
7791

78-
function runTimer() {
79-
if(!intervalRef.current) {
80-
intervalRef.current = setInterval(() => addSecond(), 1000);
92+
// didMount effect
93+
useEffect(() => {
94+
if(autoStart) {
95+
start();
96+
}
97+
return reset;
98+
},[]);
99+
100+
return { seconds, minutes, hours, days, start, pause, reset };
101+
}
102+
103+
/* ---------------------- useTimer --------------------- */
104+
105+
export function useTimer(settings) {
106+
const { expiryTimestamp, onExpire } = settings || {};
107+
108+
const [seconds, setSeconds] = useState(0);
109+
const [minutes, setMinutes] = useState(0);
110+
const [hours, setHours] = useState(0);
111+
const [days, setDays] = useState(0);
112+
113+
const intervalRef = useRef();
114+
115+
function start() {
116+
if(isValidExpiryTimestamp(expiryTimestamp) && !intervalRef.current) {
117+
calculateExpiryDate();
118+
intervalRef.current = setInterval(() => calculateExpiryDate(), 1000);
119+
}
120+
}
121+
122+
function pause() {
123+
if(intervalRef.current) {
124+
clearInterval(intervalRef.current);
125+
intervalRef.current = undefined;
81126
}
82127
}
83128

84-
function resetTimer() {
129+
function reset() {
85130
if (intervalRef.current) {
86131
clearInterval(intervalRef.current);
87132
intervalRef.current = undefined;
@@ -92,6 +137,10 @@ export default function useTimer(settings) {
92137
setDays(0);
93138
}
94139

140+
function resume() {
141+
// TODO implement countdown timer resume after pause
142+
}
143+
95144
// Timer expiry date calculation
96145
function calculateExpiryDate() {
97146
var now = new Date().getTime();
@@ -101,7 +150,7 @@ export default function useTimer(settings) {
101150
var minutes = Math.floor((distance % (1000 * 60 * 60)) / (1000 * 60));
102151
var seconds = Math.floor((distance % (1000 * 60)) / 1000);
103152
if(seconds < 0) {
104-
resetTimer();
153+
reset();
105154
isValidOnExpire(onExpire) && onExpire();
106155
} else {
107156
setSeconds(seconds);
@@ -114,15 +163,15 @@ export default function useTimer(settings) {
114163
// didMount effect
115164
useEffect(() => {
116165
start();
117-
return stopTimer;
166+
return reset;
118167
},[]);
119168

120169

121170
// Validate expiryTimestamp
122171
function isValidExpiryTimestamp(expiryTimestamp) {
123-
const isValid = expiryTimestamp && (new Date(expiryTimestamp)).getTime() > 0;
124-
if(expiryTimestamp && !isValid) {
125-
console.warn('react-timer-hook: Invalid expiryTimestamp settings passed', expiryTimestamp);
172+
const isValid = (new Date(expiryTimestamp)).getTime() > 0;
173+
if(!isValid) {
174+
console.warn('react-timer-hook: { useTimer } Invalid expiryTimestamp settings', expiryTimestamp);
126175
}
127176
return isValid;
128177
}
@@ -131,10 +180,10 @@ export default function useTimer(settings) {
131180
function isValidOnExpire(onExpire) {
132181
const isValid = onExpire && typeof onExpire === 'function';
133182
if(onExpire && !isValid) {
134-
console.warn('react-timer-hook: Invalid onExpire settings function passed', onExpire);
183+
console.warn('react-timer-hook: { useTimer } Invalid onExpire settings function', onExpire);
135184
}
136185
return isValid;
137186
}
138187

139-
return { seconds, minutes, hours, days, startTimer, stopTimer, resetTimer };
188+
return { seconds, minutes, hours, days, start, pause, resume };
140189
}

0 commit comments

Comments
 (0)