Skip to content

Commit 3d2eb77

Browse files
committed
Initial commit
1 parent 733db87 commit 3d2eb77

File tree

11 files changed

+3367
-0
lines changed

11 files changed

+3367
-0
lines changed

.gitignore

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
.DS_Store
2+
es
3+
node_modules
4+
umd
5+
/*.js
6+
npm-debug.log
7+
yarn-error.log
8+
*.sublime-project
9+
*.sublime-workspace
10+
!rollup.config.js

.npmignore

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
tools
2+
*.sublime-project
3+
*.sublime-workspace

LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 Ryan Hefner <hi@ryanhefner.com> (https://www.ryanhefner.com)
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

README.md

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
# ⏳ react-timecode
2+
3+
Simple React component for displaying a timecode, with various formatting options.
4+
5+
## Install
6+
7+
Via [npm](https://npmjs.com/package/react-timecode)
8+
```
9+
npm install --save react-timecode
10+
```
11+
12+
Via [Yarn](https://yarn.fyi/react-timecode)
13+
```
14+
yarn add react-timecode
15+
```
16+
17+
## How to use
18+
19+
The `Timecode` component is setup to be configurable as it needs to be, and hopefully
20+
nothing more. Below are the `props` you can set on the component, along with a
21+
simple example.
22+
23+
### Properties
24+
25+
* `element:String` - Element to render the timecode within. (Default: `span`)
26+
* `format:String` - Specifies the format to display the timecode. (Default: `H:?m:ss`)
27+
* `HH:mm:ss.sss` - (Example: 00:01:23.876)
28+
* `H:mm:ss.sss` - (Example: 0:01:23.876)
29+
* `H:?mm:ss.sss` - (Example: 01:23.876)
30+
* `H:?m:ss.sss` - (Example: 1:23.876)
31+
* `HH:mm:ss` - (Example: 00:01:23)
32+
* `H:mm:ss` - (Example: 0:01:23)
33+
* `H:?mm:ss` - (Example: 01:23)
34+
* `H:mm` - (Example: 0:01)
35+
* `H:?m:ss` - (Example: 1:23 - _Default_)
36+
* `time:Number` - Time in milliseconds to display the timecode for. (Default: `0`)
37+
38+
### Example
39+
40+
```
41+
import Timecode from 'react-timecode';
42+
43+
...
44+
45+
render() {
46+
const {
47+
time,
48+
} = this.state;
49+
50+
return (
51+
<Timecode time={time} />
52+
);
53+
}
54+
55+
...
56+
57+
```
58+
59+
## Pairs well with...
60+
61+
* [react-timer-wrapper](https://github.com/ryanhefner/react-timer-wrapper)
62+
63+
## License
64+
65+
[MIT](LICENSE})

package.json

Lines changed: 65 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
{
2+
"name": "react-timecode",
3+
"version": "0.1.0",
4+
"license": "MIT",
5+
"description": "Simple React component for displaying a timecode, with various format options.",
6+
"repository": "ryanhefner/react-timecode",
7+
"author": "Ryan Hefner <hi@ryanhefner.com> (https://www.ryanhefner.com)",
8+
"files": [
9+
"index.js",
10+
"es",
11+
"umd"
12+
],
13+
"directories": {
14+
"lib": "/src"
15+
},
16+
"main": "index.js",
17+
"module": "es/index.js",
18+
"jsnext:main": "src/index.js",
19+
"scripts": {
20+
"clean": "rm -f index.js && rm -rf es && rm -rf umd",
21+
"prebuild": "npm run clean",
22+
"build": "node ./tools/build.js",
23+
"watch": "babel ./src -d . --ignore __tests__ --watch",
24+
"prepare": "npm run build",
25+
"prepublishOnly": "node ./tools/build.js",
26+
"push-release": "git push origin master && git push --tags",
27+
"test": "echo \"Error: no test specified\" && exit 1"
28+
},
29+
"peerDependencies": {
30+
"react": ">=15"
31+
},
32+
"dependencies": {
33+
"clean-react-props": "^0.1.0",
34+
"prop-types": "^15.5.10"
35+
},
36+
"devDependencies": {
37+
"babel-cli": "^6.24.1",
38+
"babel-plugin-dev-expression": "^0.2.1",
39+
"babel-plugin-external-helpers": "^6.22.0",
40+
"babel-plugin-transform-react-remove-prop-types": "^0.4.6",
41+
"babel-preset-latest": "^6.24.1",
42+
"babel-preset-react": "^6.24.1",
43+
"gzip-size": "^3.0.0",
44+
"jest": "^20.0.4",
45+
"pretty-bytes": "^4.0.2",
46+
"react": "^15.6.1",
47+
"rollup": "^0.45.2",
48+
"rollup-plugin-babel": "^2.7.1",
49+
"rollup-plugin-commonjs": "^8.0.2",
50+
"rollup-plugin-json": "^2.3.0",
51+
"rollup-plugin-node-resolve": "^3.0.0",
52+
"rollup-plugin-uglify": "^2.0.1",
53+
"rollup-watch": "^4.3.1"
54+
},
55+
"browserify": {
56+
"transform": [
57+
"loose-envify"
58+
]
59+
},
60+
"keywords": [
61+
"react",
62+
"react-component",
63+
"timecode"
64+
]
65+
}

rollup.config.js

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
import babel from 'rollup-plugin-babel';
2+
import commonjs from 'rollup-plugin-commonjs';
3+
import json from 'rollup-plugin-json';
4+
import resolve from 'rollup-plugin-node-resolve';
5+
import uglify from 'rollup-plugin-uglify';
6+
import pkg from './package.json';
7+
8+
const config = {
9+
entry: 'src/index.js',
10+
format: 'umd',
11+
moduleName: 'react-timecode',
12+
plugins: [
13+
babel({
14+
exclude: 'node_modules/**',
15+
}),
16+
resolve(),
17+
commonjs({
18+
include: /node_modules/,
19+
}),
20+
json(),
21+
],
22+
external: [
23+
'react',
24+
],
25+
globals: {
26+
'react': 'React',
27+
},
28+
dest: './index.js',
29+
banner: `/*! ${pkg.name} v${pkg.version} | (c) ${new Date().getFullYear()} Ryan Hefner | ${pkg.license} License | https://github.com/${pkg.repository} !*/`,
30+
footer: '/* follow me on Twitter! @ryanhefner */',
31+
};
32+
33+
if (process.env.NODE_ENV === 'production') {
34+
config.plugins.push(uglify());
35+
}
36+
37+
export default config;

src/.babelrc

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
{
2+
"presets": [ "../tools/babel-preset" ]
3+
}

src/index.js

Lines changed: 116 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,116 @@
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+
formatTimecode({hours, minutes, seconds, milliseconds}) {
11+
const {
12+
format,
13+
} = this.props;
14+
15+
switch (format) {
16+
case 'HH:mm:ss.sss':
17+
return `${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}.${(milliseconds / 1000).toFixed(3) * 1000}`;
18+
19+
case 'H:mm:ss.sss':
20+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}.${(milliseconds / 1000).toFixed(3) * 1000}`;
21+
22+
case 'H:?mm:ss.sss':
23+
if (hours) {
24+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}.${(milliseconds / 1000).toFixed(3) * 1000}`;
25+
}
26+
27+
return `${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}.${(milliseconds / 1000).toFixed(3) * 1000}`;
28+
29+
case 'H:?m:ss.sss':
30+
if (hours) {
31+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}.${(milliseconds / 1000).toFixed(3) * 1000}`;
32+
}
33+
34+
return `${minutes}:${seconds < 10 ? '0' + seconds : seconds}.${(milliseconds / 1000).toFixed(3) * 1000}`;
35+
36+
case 'HH:mm:ss':
37+
return `${hours < 10 ? '0' + hours : hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
38+
39+
case 'H:mm:ss':
40+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
41+
42+
case 'H:?mm:ss':
43+
if (hours) {
44+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
45+
}
46+
47+
return `${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
48+
49+
case 'H:mm':
50+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}`;
51+
52+
case 'H:?m:ss':
53+
default:
54+
if (hours) {
55+
return `${hours}:${minutes < 10 ? '0' + minutes : minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
56+
}
57+
58+
return `${minutes}:${seconds < 10 ? '0' + seconds : seconds}`;
59+
}
60+
}
61+
62+
render() {
63+
const {
64+
element,
65+
time,
66+
} = this.props;
67+
68+
let milliseconds = time;
69+
70+
const hours = milliseconds > HOUR
71+
? Math.floor(milliseconds / HOUR)
72+
: 0;
73+
74+
if (hours) {
75+
milliseconds -= hours * HOUR;
76+
}
77+
78+
const minutes = milliseconds > MINUTE
79+
? Math.floor(milliseconds / MINUTE)
80+
: 0;
81+
82+
if (minutes) {
83+
milliseconds -= minutes * MINUTE;
84+
}
85+
86+
const seconds = milliseconds > SECOND
87+
? Math.floor(milliseconds / SECOND)
88+
: 0;
89+
90+
if (seconds) {
91+
milliseconds -= seconds * SECOND;
92+
}
93+
94+
const ElementTag = `${element}`;
95+
96+
return (
97+
<ElementTag {...cleanProps(this.props)}>
98+
{this.formatTimecode({hours, minutes, seconds, milliseconds})}
99+
</ElementTag>
100+
);
101+
}
102+
}
103+
104+
Timecode.propTypes = {
105+
element: PropTypes.string,
106+
format: PropTypes.string,
107+
time: PropTypes.number,
108+
};
109+
110+
Timecode.defaultProps = {
111+
element: 'span',
112+
format: 'H:?m:ss',
113+
time: 0,
114+
};
115+
116+
export default Timecode;

tools/babel-preset.js

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
const BABEL_ENV = process.env.BABEL_ENV;
2+
const building = BABEL_ENV != undefined && BABEL_ENV !== 'cjs';
3+
4+
const plugins = [];
5+
6+
if (BABEL_ENV === 'umd') {
7+
plugins.push('external-helpers');
8+
}
9+
10+
if (process.env.NODE_ENV === 'production') {
11+
plugins.push(
12+
'dev-expression',
13+
'transform-react-remove-prop-types'
14+
);
15+
}
16+
17+
module.exports = {
18+
presets: [
19+
['latest', {
20+
'es2015': {
21+
'loose': true,
22+
'modules': building ? false : 'commonjs'
23+
}
24+
}],
25+
'react'
26+
],
27+
plugins: plugins
28+
};

0 commit comments

Comments
 (0)