Skip to content

Commit 6f4bbe6

Browse files
authored
Feature/support milliseconds (#116)
* support milliseconds in useTimer * update readme of useTimer settings and returned values * support milliseconds in useStopwatch * support milliseconds in useTime * handle milliseconds precision in useTimer after pause and resume * handle milliseconds precision in useStopwatch after pause and start * move intervals to constants * update types * update readme file * conditionally increment precision counter * update readme file * update milliseconds interval to 20ms * replace enableMilliseconds with custom interval * validate * useStopwatch accurate pause and resume * remove passed seconds state from useStopwatch * update readme
1 parent a0aa036 commit 6f4bbe6

File tree

15 files changed

+268
-268
lines changed

15 files changed

+268
-268
lines changed

demo/App.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -66,11 +66,11 @@ export default function App() {
6666
<p>
6767
React timer hook is a custom <a href="https://reactjs.org/docs/hooks-intro.html" target="_blank">react hook</a> built to handle timer, stopwatch, and time logic/state in your react component.
6868
</p>
69-
<UseTimerDemo expiryTimestamp={time} />
69+
<UseTimerDemo expiryTimestamp={time} interval={20} />
7070
<Separator />
71-
<UseStopwatchDemo />
71+
<UseStopwatchDemo interval={20} />
7272
<Separator />
73-
<UseTimeDemo />
73+
<UseTimeDemo interval={20} />
7474
</Container>
7575
</div>
7676
);

demo/components/Digit.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,9 @@ const SingleDigit = styled.span`
3131
border-radius: 5px;
3232
padding: 10px 12px;
3333
color: white;
34-
&:first-child {
35-
margin-right: 2px;
34+
margin-right: 2px;
35+
&:last-child {
36+
margin-right: ;
3637
}
3738
&:after {
3839
position: absolute;
@@ -48,18 +49,29 @@ const SingleDigit = styled.span`
4849
}
4950
`;
5051

51-
export default function Digit({ value, title }) {
52-
const leftDigit = value >= 10 ? value.toString()[0] : '0';
53-
const rightDigit = value >= 10 ? value.toString()[1] : value.toString();
52+
export default function Digit({ value, title, isMIlliseconds }) {
53+
const digits = value.toString().padStart(4, '0');
5454
return (
5555
<Container>
5656
<Title>{title}</Title>
5757
<DigitContainer>
58+
{isMIlliseconds ?
59+
<>
60+
<SingleDigit>
61+
{digits[0]}
62+
</SingleDigit>
63+
<SingleDigit>
64+
{digits[1]}
65+
</SingleDigit>
66+
</>
67+
:
68+
null
69+
}
5870
<SingleDigit>
59-
{leftDigit}
71+
{digits[2]}
6072
</SingleDigit>
6173
<SingleDigit>
62-
{rightDigit}
74+
{digits[3]}
6375
</SingleDigit>
6476
</DigitContainer>
6577
</Container>

demo/components/TimerStyled.js

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ const Separtor = styled.span`
2626
margin: 5px 0px;
2727
`;
2828

29-
export default function TimerStyled({ seconds, minutes, hours, days }) {
29+
export default function TimerStyled({ milliseconds, seconds, minutes, hours, days, enableMilliseconds }) {
3030
return (
3131
<TimerContainer>
3232
{days !== undefined ? <Digit value={days} title="DAYS" addSeparator /> : null}
@@ -36,6 +36,12 @@ export default function TimerStyled({ seconds, minutes, hours, days }) {
3636
<Digit value={minutes} title="MINUTES" addSeparator />
3737
<SepartorContainer><Separtor /><Separtor /></SepartorContainer>
3838
<Digit value={seconds} title="SECONDS" />
39+
{enableMilliseconds ?
40+
<>
41+
<SepartorContainer><Separtor /><Separtor /></SepartorContainer>
42+
<Digit value={milliseconds} title="MILLISECONDS" isMIlliseconds />
43+
</>
44+
: null }
3945
</TimerContainer>
4046
);
4147
}

demo/components/UseStopwatchDemo.js

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,22 +3,25 @@ import { useStopwatch } from '../../src/index';
33
import Button from './Button';
44
import TimerStyled from './TimerStyled';
55

6-
export default function UseStopwatchDemo() {
6+
export default function UseStopwatchDemo({ interval }) {
7+
const time = new Date();
8+
time.setMilliseconds(time.getMilliseconds() + 10000);
79
const {
10+
milliseconds,
811
seconds,
912
minutes,
1013
hours,
1114
days,
1215
start,
1316
pause,
1417
reset,
15-
} = useStopwatch({ autoStart: true });
18+
} = useStopwatch({ autoStart: true, interval, offsetTimestamp: 0 });
1619

1720

1821
return (
1922
<div>
2023
<h2>UseStopwatch Demo</h2>
21-
<TimerStyled seconds={seconds} minutes={minutes} hours={hours} days={days} />
24+
<TimerStyled milliseconds={milliseconds} seconds={seconds} minutes={minutes} hours={hours} days={days} enableMilliseconds={interval < 1000} />
2225
<Button onClick={start}>Start</Button>
2326
<Button onClick={pause}>Pause</Button>
2427
<Button onClick={reset}>Reset</Button>

demo/components/UseTimeDemo.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,19 @@ import React from 'react';
22
import { useTime } from '../../src/index';
33
import TimerStyled from './TimerStyled';
44

5-
export default function UseTimeDemo() {
5+
export default function UseTimeDemo({ interval }) {
66
const {
7+
milliseconds,
78
seconds,
89
minutes,
910
hours,
10-
} = useTime({ });
11+
} = useTime({ interval });
1112

1213
return (
1314
<div>
1415
<h2>UseTime Demo</h2>
1516
<div>
16-
<TimerStyled seconds={seconds} minutes={minutes} hours={hours} />
17+
<TimerStyled milliseconds={milliseconds} seconds={seconds} minutes={minutes} hours={hours} enableMilliseconds={interval < 1000} />
1718
</div>
1819
</div>
1920
);

demo/components/UseTimerDemo.js

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ import { useTimer } from '../../src/index';
33
import TimerStyled from './TimerStyled';
44
import Button from './Button';
55

6-
export default function UseTimerDemo({ expiryTimestamp }) {
6+
export default function UseTimerDemo({ expiryTimestamp, interval }) {
77
const {
8+
milliseconds,
89
seconds,
910
minutes,
1011
hours,
@@ -13,12 +14,12 @@ export default function UseTimerDemo({ expiryTimestamp }) {
1314
pause,
1415
resume,
1516
restart,
16-
} = useTimer({ expiryTimestamp, onExpire: () => console.warn('onExpire called') });
17+
} = useTimer({ expiryTimestamp, onExpire: () => console.warn('onExpire called'), interval });
1718

1819
return (
1920
<div>
2021
<h2>UseTimer Demo</h2>
21-
<TimerStyled seconds={seconds} minutes={minutes} hours={hours} days={days} />
22+
<TimerStyled milliseconds={milliseconds} seconds={seconds} minutes={minutes} hours={hours} days={days} enableMilliseconds={interval < 1000} />
2223
<Button type="button" onClick={start}>Start</Button>
2324
<Button type="button" onClick={pause}>Pause</Button>
2425
<Button type="button" onClick={resume}>Resume</Button>

docs/index.js

Lines changed: 25 additions & 14 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

readme.md

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ import { useTimer } from 'react-timer-hook';
2525
function MyTimer({ expiryTimestamp }) {
2626
const {
2727
totalSeconds,
28+
milliseconds,
2829
seconds,
2930
minutes,
3031
hours,
@@ -34,15 +35,15 @@ function MyTimer({ expiryTimestamp }) {
3435
pause,
3536
resume,
3637
restart,
37-
} = useTimer({ expiryTimestamp, onExpire: () => console.warn('onExpire called') });
38+
} = useTimer({ expiryTimestamp, onExpire: () => console.warn('onExpire called'), interval: 20 });
3839

3940

4041
return (
4142
<div style={{textAlign: 'center'}}>
4243
<h1>react-timer-hook </h1>
4344
<p>Timer Demo</p>
4445
<div style={{fontSize: '100px'}}>
45-
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>
46+
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>:<span>{milliseconds}</span>
4647
</div>
4748
<p>{isRunning ? 'Running' : 'Not running'}</p>
4849
<button onClick={start}>Start</button>
@@ -75,18 +76,21 @@ export default function App() {
7576
| --- | --- | --- | ---- |
7677
| expiryTimestamp | Date object | YES | this will define for how long the timer will be running |
7778
| autoStart | boolean | No | flag to decide if timer should start automatically, by default it is set to `true` |
79+
| interval | number | No | value to change the interval of the timer, by default it is set to 1000ms. Note: this value will not affect the timer, it will just define the frequency used to calculate the current timer values. For example, if you have a use case where milliseconds are used, you need to use a smaller value for the interval, for example, 20ms or 100ms based on your needs. |
7880
| onExpire | Function | No | callback function to be executed once countdown timer is expired |
7981

8082

8183
### Values
8284

8385
| key | Type | Description |
8486
| --- | --- | ---- |
87+
| milliseconds | number | milliseconds value, to get accurate ms values you need to set interval to a smaller value example: 20ms |
8588
| seconds | number | seconds value |
8689
| minutes | number | minutes value |
8790
| hours | number | hours value |
8891
| days | number | days value |
8992
| totalSeconds | number | total number of seconds left in timer NOT converted to minutes, hours or days |
93+
| totalMilliseconds | number | total number of milliseconds left in timer NOT converted to minutes, hours or days |
9094
| isRunning | boolean | flag to indicate if timer is running or not |
9195
| pause | function | function to be called to pause timer |
9296
| start | function | function if called after pause the timer will continue based on original expiryTimestamp |
@@ -107,6 +111,7 @@ import { useStopwatch } from 'react-timer-hook';
107111
function MyStopwatch() {
108112
const {
109113
totalSeconds,
114+
milliseconds,
110115
seconds,
111116
minutes,
112117
hours,
@@ -115,15 +120,15 @@ function MyStopwatch() {
115120
start,
116121
pause,
117122
reset,
118-
} = useStopwatch({ autoStart: true });
123+
} = useStopwatch({ autoStart: true, interval: 20 });
119124

120125

121126
return (
122127
<div style={{textAlign: 'center'}}>
123128
<h1>react-timer-hook</h1>
124129
<p>Stopwatch Demo</p>
125130
<div style={{fontSize: '100px'}}>
126-
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>
131+
<span>{days}</span>:<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span>:<span>{milliseconds}</span>
127132
</div>
128133
<p>{isRunning ? 'Running' : 'Not running'}</p>
129134
<button onClick={start}>Start</button>
@@ -148,11 +153,13 @@ export default function App() {
148153
| --- | --- | --- | ---- |
149154
| autoStart | boolean | No | if set to `true` stopwatch will auto start, by default it is set to `false` |
150155
| offsetTimestamp | Date object | No | this will define the initial stopwatch offset example: `const stopwatchOffset = new Date(); stopwatchOffset.setSeconds(stopwatchOffset.getSeconds() + 300);` this will result in a 5 minutes offset and stopwatch will start from 0:0:5:0 instead of 0:0:0:0 |
156+
| interval | number | No | value to change the interval of the stopwatch, by default it is set to 1000ms. Note: this value will not affect the stopwatch, it will just define the frequency used to calculate the current timer values. For example, if you have a use case where milliseconds are used, you need to use a smaller value for the interval, for example, 20ms or 100ms based on your needs. |
151157

152158
### Values
153159

154160
| key | Type | Description |
155161
| --- | --- | ---- |
162+
| milliseconds | number | milliseconds value, to get accurate ms values you need to set interval to a smaller value example: 20ms |
156163
| seconds | number | seconds value |
157164
| minutes | number | minutes value |
158165
| hours | number | hours value |
@@ -177,18 +184,19 @@ import { useTime } from 'react-timer-hook';
177184

178185
function MyTime() {
179186
const {
187+
milliseconds,
180188
seconds,
181189
minutes,
182190
hours,
183191
ampm,
184-
} = useTime({ format: '12-hour'});
192+
} = useTime({ format: '12-hour', interval: 20 });
185193

186194
return (
187195
<div style={{textAlign: 'center'}}>
188196
<h1>react-timer-hook </h1>
189197
<p>Current Time Demo</p>
190198
<div style={{fontSize: '100px'}}>
191-
<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span><span>{ampm}</span>
199+
<span>{hours}</span>:<span>{minutes}</span>:<span>{seconds}</span><span>{milliseconds}</span><span>{ampm}</span>
192200
</div>
193201
</div>
194202
);
@@ -208,11 +216,13 @@ export default function App() {
208216
| key | Type | Required | Description |
209217
| --- | --- | --- | ---- |
210218
| format | string | No | if set to `12-hour` time will be formatted with am/pm |
219+
| interval | number | No | value to change the interval of the time, by default it is set to 1000ms. Note: this value will not affect the thime, it will just define the frequency used to calculate the current time values. For example, if you have a use case where milliseconds are used, you need to use a smaller value for the interval, for example, 20ms or 100ms based on your needs. |
211220

212221
### Values
213222

214223
| key | Type | Description |
215224
| --- | --- | ---- |
225+
| milliseconds | number | milliseconds value |
216226
| seconds | number | seconds value |
217227
| minutes | number | minutes value |
218228
| hours | number | hours value |

src/constants/index.js

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
const SECOND_INTERVAL = 1000;
2+
const PRECISION_COUNTER_LIMIT = 5;
3+
4+
export {
5+
SECOND_INTERVAL,
6+
PRECISION_COUNTER_LIMIT,
7+
};

src/index.d.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,13 @@ interface TimerSettings {
22
autoStart?: boolean;
33
expiryTimestamp: Date;
44
onExpire?: () => void;
5+
enableMilliseconds?: boolean;
56
}
67

78
interface TimerResult {
9+
totalMilliseconds: number;
810
totalSeconds: number;
11+
milliseconds: number;
912
seconds: number;
1013
minutes: number;
1114
hours: number;
@@ -22,10 +25,13 @@ export function useTimer(settings: TimerSettings): TimerResult
2225
interface StopwatchSettings {
2326
autoStart?: boolean;
2427
offsetTimestamp?: Date;
28+
enableMilliseconds?: boolean;
2529
}
2630

2731
interface StopwatchResult {
32+
totalMilliseconds: number;
2833
totalSeconds: number;
34+
milliseconds: number;
2935
seconds: number;
3036
minutes: number;
3137
hours: number;
@@ -43,6 +49,7 @@ interface TimeSettings {
4349
}
4450

4551
interface TimeResult {
52+
milliseconds: number;
4653
seconds: number;
4754
minutes: number;
4855
hours: number;

0 commit comments

Comments
 (0)