Skip to content

Commit 40a2b4f

Browse files
committed
Initial
0 parents  commit 40a2b4f

20 files changed

+620
-0
lines changed

Diff for: .gitignore

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.DS_Store
2+
npm-debug.log*
3+
node_modules
4+
.idea

Diff for: LICENSE

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2017 gsoec
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.

Diff for: README.md

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
## react-template
2+
3+
[Live Demo](https://gsoec.github.io/react-template/)
4+
5+
## How to use
6+
7+
First, install the dependencies.
8+
9+
```bash
10+
$ npm install
11+
```
12+
13+
Then, launch the app.
14+
15+
```bash
16+
$ npm start
17+
```
18+
19+
Now you should see a new browser window/tab opening in http://127.0.0.1:8080.
20+
21+
Use`npm run build` to build the static files on Linux or Mac.
22+
Use`npm run build-windows` to build the static files on windows.
23+
Use`npm run clean` to delete all the files generated by above commands.

Diff for: dist/bundle.js

+37
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Diff for: dist/index.html

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
<html>
2+
<title>Sample</title>
3+
<head>
4+
<link href="https://fonts.googleapis.com/icon?family=Material+Icons" rel="stylesheet">
5+
</head>
6+
<body>
7+
<script type="text/javascript" src="bundle.js"></script>
8+
</body>
9+
</html>

Diff for: package.json

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
{
2+
"name": "react-template",
3+
"version": "0.0.1",
4+
"description": "",
5+
"main": "src/index.js",
6+
"scripts": {
7+
"start": "webpack-dev-server --devtool eval --progress --hot --content-base src",
8+
"clean": "find . -name '.DS_Store' -print0 | xargs -0 rm -rf && rm -rf dist",
9+
"lint": "eslint --ignore-path .gitignore --ext .jsx,.js --format=node_modules/eslint-formatter-pretty .",
10+
"test": "npm run lint",
11+
"build": "NODE_ENV=production webpack --config webpack.production.config.js",
12+
"build-windows": "SET NODE_ENV=production & webpack --config webpack.production.config.js"
13+
},
14+
"dependencies": {
15+
"classnames": "^2.2.5",
16+
"react": "15.x",
17+
"react-dom": "15.x",
18+
"validator": "^7.0.0",
19+
"whatwg-fetch": "^2.0.3"
20+
},
21+
"devDependencies": {
22+
"babel-core": "6.x",
23+
"babel-eslint": "7.x",
24+
"babel-loader": "6.x",
25+
"babel-preset-es2015": "6.x",
26+
"babel-preset-react": "6.x",
27+
"babel-preset-stage-0": "^6.24.1",
28+
"copy-webpack-plugin": "latest",
29+
"css-loader": "^0.28.0",
30+
"open-browser-webpack-plugin": "0.0.5",
31+
"style-loader": "^0.16.1",
32+
"webpack": "1.x",
33+
"webpack-dev-server": "1.x"
34+
},
35+
"babel": {
36+
"presets": [
37+
"es2015",
38+
"stage-0",
39+
"react"
40+
]
41+
},
42+
"author": "",
43+
"license": "MIT"
44+
}

Diff for: src/App/index.js

+50
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import React, { Component } from 'react';
2+
import { TabBar, TabBarItem } from '../Tab';
3+
import Movie from '../Movie';
4+
import Photos from '../Photos';
5+
import Dashboard from '../Dashboard';
6+
7+
export default class App extends Component {
8+
constructor(props) {
9+
super(props);
10+
this.state = { tab: 0 };
11+
}
12+
13+
renderPanel(tab) {
14+
switch(tab) {
15+
case 1:
16+
return <Photos />;
17+
case 2:
18+
return <Dashboard />;
19+
default:
20+
return <Movie />;
21+
}
22+
}
23+
24+
render() {
25+
const { tab } = this.state;
26+
27+
return (
28+
<div>
29+
{this.renderPanel(tab)}
30+
<TabBar>
31+
<TabBarItem
32+
active={tab === 0}
33+
onClick={() => this.setState({ tab: 0 })}
34+
icon="movie"
35+
/>
36+
<TabBarItem
37+
active={tab === 1}
38+
onClick={() => this.setState({ tab: 1 })}
39+
icon="photo"
40+
/>
41+
<TabBarItem
42+
active={tab === 2}
43+
onClick={() => this.setState({ tab: 2 })}
44+
icon="dashboard"
45+
/>
46+
</TabBar>
47+
</div>
48+
);
49+
}
50+
}

Diff for: src/Dashboard/Input.js

+89
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
import React, { Component } from 'react';
2+
import validator from 'validator';
3+
4+
require('./input.css');
5+
6+
export default class InputValidator extends Component {
7+
8+
// Append more rules into this static variable if need.
9+
// Example:
10+
// Object.assign(InputValidator.rules, {
11+
// phone: {
12+
// test: value => validator.isNumeric(value),
13+
// hint: value => <span className='form-error'>phone number must contains only numbers</span>
14+
// }
15+
// })
16+
static rules = {
17+
required: {
18+
test: value => value.toString().trim(),
19+
hint: value => <span className='form-error'>Required</span>
20+
},
21+
email: {
22+
test: value => validator.isEmail(value),
23+
hint: value => <span className='form-error'>{value} isnt an Email.</span>
24+
},
25+
};
26+
27+
static defaultProps = {
28+
validators: []
29+
};
30+
31+
constructor(props) {
32+
super(props);
33+
this.state = {
34+
value: props.value || '',
35+
hint: false,
36+
validators: []
37+
};
38+
}
39+
40+
componentDidMount() {
41+
this._validate(this.state.value);
42+
}
43+
44+
_validate(value) {
45+
let hint;
46+
this.props.validators.find(validator => {
47+
if (validator in InputValidator.rules) {
48+
const rule = InputValidator.rules[validator];
49+
if (!rule.test(value)) {
50+
hint = rule.hint(value)
51+
return hint;
52+
}
53+
}
54+
});
55+
this.setState({ hint, value });
56+
}
57+
58+
handleChange(e) {
59+
const { onChange } = this.props;
60+
this._validate(e.target.value);
61+
if (onChange) {
62+
onChange(e);
63+
}
64+
}
65+
66+
handleBlur(e) {
67+
const { onBlur } = this.props;
68+
this._validate(e.target.value);
69+
if (onBlur) {
70+
onBlur(e);
71+
}
72+
}
73+
74+
render() {
75+
const { rootClass, validators, onChange, onBlur, value, ...others } = this.props;
76+
77+
return (
78+
<div className={rootClass}>
79+
<input
80+
onChange={this.handleChange.bind(this)}
81+
onBlur={this.handleBlur.bind(this)}
82+
value={this.state.value}
83+
{...others}
84+
/>
85+
{this.state.hint}
86+
</div>
87+
);
88+
}
89+
}

Diff for: src/Dashboard/index.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
import React, { Component } from 'react';
2+
import { TabPanel } from '../Tab';
3+
import Input from './Input';
4+
5+
export default class Dashboard extends Component {
6+
7+
render() {
8+
return (
9+
<TabPanel>
10+
<div>
11+
Email
12+
<span className="form-required">*</span>
13+
<Input
14+
className="input"
15+
type="text"
16+
17+
validators={['required', 'email']}
18+
/>
19+
</div>
20+
<div>
21+
Password
22+
<span className="form-required">*</span>
23+
<Input
24+
className="input"
25+
type="password"
26+
value=""
27+
validators={['required']}
28+
/>
29+
</div>
30+
</TabPanel>
31+
);
32+
}
33+
}

Diff for: src/Dashboard/input.css

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
.input {
2+
display: block;
3+
box-sizing: border-box;
4+
width: 100%;
5+
height: 2.4375rem;
6+
padding: 0.5rem;
7+
border: 1px solid #cacaca;
8+
font-size: 1rem;
9+
color: #0a0a0a;
10+
background-color: #fefefe;
11+
box-shadow: inset 0 1px 2px rgba(10, 10, 10, 0.1);
12+
border-radius: 0;
13+
transition: box-shadow 0.5s, border-color 0.25s ease-in-out;
14+
-webkit-appearance: none;
15+
-moz-appearance: none;
16+
}
17+
.form-required {
18+
color: red;
19+
padding: 0 5px;
20+
}
21+
.form-error {
22+
color: red;
23+
}

Diff for: src/Movie/index.css

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
.video-container {
2+
position:relative;
3+
padding-bottom:56.25%;
4+
padding-top:30px;
5+
height:0;
6+
overflow:hidden;
7+
}
8+
.video-container iframe,
9+
.video-container object,
10+
.video-container embed {
11+
position:absolute;
12+
top:0;
13+
left:0;
14+
width:100%;
15+
height:100%;
16+
}

Diff for: src/Movie/index.js

+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import React, { Component } from 'react';
2+
import { TabPanel } from '../Tab';
3+
4+
require('./index.css');
5+
6+
export default class Movie extends Component {
7+
constructor(props) {
8+
super(props);
9+
this.state = {
10+
url: 'https://www.youtube.com/embed/nQUibyxOx2c',
11+
title: '',
12+
body: '',
13+
};
14+
}
15+
16+
componentDidMount() {
17+
return fetch('https://jsonplaceholder.typicode.com/posts/1')
18+
.then(response => response.json())
19+
.then(movie => this.setState(movie));
20+
}
21+
22+
render() {
23+
const { title, body, url } = this.state;
24+
25+
return (
26+
<TabPanel>
27+
<h2>{title}</h2>
28+
<div>{body}</div>
29+
<div className="video-container">
30+
<iframe
31+
width="560"
32+
height="315"
33+
src={url}
34+
frameBorder="0"
35+
allowFullScreen
36+
/>
37+
</div>
38+
</TabPanel>
39+
);
40+
}
41+
}

0 commit comments

Comments
 (0)