Skip to content

Commit 8ed2f62

Browse files
committed
Update structure to break out code into Component and utils
1 parent 1b370a7 commit 8ed2f62

4 files changed

Lines changed: 150 additions & 397 deletions

File tree

src/Timecode.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
import React, { forwardRef, useMemo } from 'react'
2+
import cleanReactProps from 'clean-react-props'
3+
import { formatTimecode } from './utils'
4+
5+
/**
6+
* Timecode - React Component
7+
*
8+
* @param {Object} props
9+
* @param {String} [props.as='span'] - HTML element to render
10+
* @param {String} [props.format='H:?m:ss'] - Timecode format
11+
* @param {String} [props.postfix=''] - Postfix to append to timecode
12+
* @param {String} [props.prefix=''] - Prefix to prepend to timecode
13+
* @param {Number} [props.time=0] - Time in milliseconds
14+
* @param {Object} [rest] - Additional props to pass to HTML element
15+
* @param {React.Ref} [ref] - React ref
16+
* @returns {React.ReactElement}
17+
*/
18+
export const Timecode = forwardRef(({ as: asProp = 'span', format = 'H:?m:ss', postfix = '', prefix = '', time = 0, ...rest }, ref) => {
19+
const timecode = useMemo(() => formatTimecode({ format, time }), [format, time])
20+
21+
const Component = asProp
22+
23+
return (
24+
<Component {...cleanReactProps(rest)} ref={ref}>
25+
{`${prefix}${timecode}${postfix}`}
26+
</Component>
27+
)
28+
})

src/index.js

Lines changed: 2 additions & 158 deletions
Original file line numberDiff line numberDiff line change
@@ -1,158 +1,2 @@
1-
import React, { Component } from 'react';
2-
import PropTypes from 'prop-types';
3-
import cleanProps from 'clean-react-props';
4-
5-
const SECOND = 1000;
6-
const MINUTE = 60 * 1000;
7-
const HOUR = 60 * 60 * 1000;
8-
9-
class Timecode extends Component {
10-
pad(number, length = 2) {
11-
const numberLength = number.toString().length;
12-
if (numberLength < length) {
13-
const diff = length - numberLength;
14-
let padding = '';
15-
16-
while (padding.length < diff) {
17-
padding += '0';
18-
}
19-
20-
return `${padding}${number}`;
21-
}
22-
23-
return number;
24-
}
25-
26-
formatMilliseconds(milliseconds, length = 3) {
27-
return this.pad((milliseconds / 1000).toFixed(length) * 1000, length);
28-
}
29-
30-
formatTimecode({hours, minutes, seconds, milliseconds}) {
31-
const {
32-
format,
33-
} = this.props;
34-
35-
switch (format) {
36-
case 'HH:mm:ss.SSS':
37-
return `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(seconds)}.${this.formatMilliseconds(milliseconds)}`;
38-
39-
case 'H:mm:ss.SSS':
40-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}.${this.formatMilliseconds(milliseconds)}`;
41-
42-
case 'H:?mm:ss.SSS':
43-
if (hours) {
44-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}.${this.formatMilliseconds(milliseconds)}`;
45-
}
46-
47-
return `${this.pad(minutes)}:${this.pad(seconds)}.${this.formatMilliseconds(milliseconds)}`;
48-
49-
case 'H:?m:ss.SSS':
50-
if (hours) {
51-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}.${this.formatMilliseconds(milliseconds)}`;
52-
}
53-
54-
return `${minutes}:${this.pad(seconds)}.${this.formatMilliseconds(milliseconds)}`;
55-
56-
case 'HH:mm:ss':
57-
return `${this.pad(hours)}:${this.pad(minutes)}:${this.pad(seconds)}`;
58-
59-
case 'H:mm:ss':
60-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}`;
61-
62-
case 'H:?mm:ss':
63-
if (hours) {
64-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}`;
65-
}
66-
67-
return `${this.pad(minutes)}:${this.pad(seconds)}`;
68-
69-
case 'H:mm':
70-
return `${hours}:${this.pad(minutes)}`;
71-
72-
case 's.SSS':
73-
return `${seconds}.${this.formatMilliseconds(milliseconds)}`;
74-
75-
case 's.SS':
76-
return `${seconds}.${this.formatMilliseconds(milliseconds, 2)}`;
77-
78-
case 'H:?mm:ss':
79-
if (hours) {
80-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}`;
81-
}
82-
83-
return `${this.pad(minutes)}:${this.pad(seconds)}`;
84-
85-
case 'H:?m:ss':
86-
default:
87-
if (hours) {
88-
return `${hours}:${this.pad(minutes)}:${this.pad(seconds)}`;
89-
}
90-
91-
return `${minutes}:${this.pad(seconds)}`;
92-
}
93-
}
94-
95-
render() {
96-
const {
97-
component,
98-
prefix,
99-
postfix,
100-
time,
101-
} = this.props;
102-
103-
let milliseconds = time;
104-
105-
const hours = milliseconds >= HOUR
106-
? Math.floor(milliseconds / HOUR)
107-
: 0;
108-
109-
if (hours) {
110-
milliseconds -= hours * HOUR;
111-
}
112-
113-
const minutes = milliseconds >= MINUTE
114-
? Math.floor(milliseconds / MINUTE)
115-
: 0;
116-
117-
if (minutes) {
118-
milliseconds -= minutes * MINUTE;
119-
}
120-
121-
const seconds = milliseconds >= SECOND
122-
? Math.floor(milliseconds / SECOND)
123-
: 0;
124-
125-
if (seconds) {
126-
milliseconds -= seconds * SECOND;
127-
}
128-
129-
return React.createElement(
130-
component,
131-
{...cleanProps(this.props, ['prefix', 'postfix'])},
132-
[
133-
`${prefix}${this.formatTimecode({hours, minutes, seconds, milliseconds})}${postfix}`,
134-
],
135-
);
136-
}
137-
}
138-
139-
Timecode.propTypes = {
140-
component: PropTypes.oneOfType([
141-
PropTypes.func,
142-
PropTypes.string,
143-
]),
144-
format: PropTypes.string,
145-
prefix: PropTypes.string,
146-
postfix: PropTypes.string,
147-
time: PropTypes.number,
148-
};
149-
150-
Timecode.defaultProps = {
151-
component: 'span',
152-
format: 'H:?m:ss',
153-
prefix: '',
154-
postfix: '',
155-
time: 0,
156-
};
157-
158-
export default Timecode;
1+
export { Timecode as default } from './Timecode'
2+
export * from './utils'

0 commit comments

Comments
 (0)