Skip to content

Commit 6c273a3

Browse files
authored
add react (#1)
* add react
1 parent 6468110 commit 6c273a3

26 files changed

+1070
-33
lines changed

.eslintrc.js

+15-3
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,25 @@ module.exports = {
66
"plugin:vue-libs/recommended"
77
],
88
"plugins": [
9-
"mocha"
9+
"mocha",
10+
"react"
1011
],
1112
"rules": {
1213
"no-labels": 0,
1314
"no-empty-label": 0,
15+
"no-redeclare": 0,
1416
"semi": [2, "always"],
1517
"space-before-function-paren": 0,
16-
"no-new": 0
18+
"no-new": 0,
19+
"react/jsx-no-undef": 2,
20+
"react/jsx-uses-react": 2,
21+
"react/jsx-uses-vars": 1,
22+
"react/no-did-mount-set-state": 1,
23+
"react/no-did-update-set-state": 2,
24+
"react/no-direct-mutation-state": 2,
25+
"react/no-unknown-property": 1,
26+
"react/prefer-es6-class": 1,
27+
"react/react-in-jsx-scope": 2
1728
},
1829
"env": {
1930
"es6": true,
@@ -24,7 +35,8 @@ module.exports = {
2435
"ecmaVersion": 6,
2536
"sourceType": "module",
2637
"ecmaFeatures": {
27-
"experimentalObjectRestSpread": true
38+
"experimentalObjectRestSpread": true,
39+
"jsx": true
2840
}
2941
}
3042
};

.npmignore

+1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ test/
44
.eslintrc.js
55
.eslintignore
66
.stylelintrc.js
7+
postcss.config.js
78
coverage/
89
screenshots/
910
node_modules/

assets/app.less

-7
Original file line numberDiff line numberDiff line change
@@ -39,10 +39,6 @@
3939
color: #b3b3b3;
4040
color: rgba(255, 255, 255, 0.3);
4141
text-shadow: -1px -1px rgba(0, 0, 0, 0.2);
42-
-webkit-text-rendering: optimizeLegibility;
43-
-moz-text-rendering: optimizeLegibility;
44-
-ms-text-rendering: optimizeLegibility;
45-
-o-text-rendering: optimizeLegibility;
4642
text-rendering: optimizeLegibility;
4743
}
4844

@@ -164,7 +160,6 @@ label[for='toggle-all'] {
164160
margin: auto 0;
165161
/* Mobile Safari */
166162
border: none;
167-
-webkit-appearance: none;
168163
appearance: none;
169164
}
170165

@@ -191,7 +186,6 @@ label[for='toggle-all'] {
191186
margin-left: 45px;
192187
display: block;
193188
line-height: 1.2;
194-
-webkit-transition: color 0.4s;
195189
transition: color 0.4s;
196190
}
197191

@@ -331,7 +325,6 @@ label[for='toggle-all'] {
331325
width: 65px;
332326
height: 41px;
333327
transform: rotate(90deg);
334-
-webkit-appearance: none;
335328
appearance: none;
336329
}
337330
}

flux/actions.js

+72
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
'use strict';
2+
3+
import dispatcher from './dispatcher';
4+
5+
export const add = text => {
6+
dispatcher.dispatch({
7+
type: 'ADD_TODO',
8+
content: text
9+
});
10+
};
11+
12+
export const remove = (id) => {
13+
dispatcher.dispatch({
14+
type: 'DELETE_TODO',
15+
id
16+
});
17+
};
18+
19+
export const compelete = (id) => {
20+
dispatcher.dispatch({
21+
type: 'COMPLETE_TODO',
22+
id
23+
});
24+
};
25+
26+
export const edit = (id) => {
27+
dispatcher.dispatch({
28+
type: 'EDIT_TODO',
29+
id
30+
});
31+
};
32+
33+
export const update = (data) => {
34+
dispatcher.dispatch({
35+
type: 'UPDATE_TODO',
36+
id: data.id,
37+
content: data.value
38+
});
39+
};
40+
41+
export const updateItem = (data) => {
42+
dispatcher.dispatch({
43+
type: 'UPDATE_ITEM_TODO',
44+
id: data.id,
45+
content: data.value
46+
});
47+
};
48+
49+
export const completedAll = () => {
50+
dispatcher.dispatch({
51+
type: 'COMPLETE_ALL'
52+
});
53+
};
54+
55+
export const uncompletedAll = () => {
56+
dispatcher.dispatch({
57+
type: 'UNCOMPLETE_ALL'
58+
});
59+
};
60+
61+
export const clearCompleted = () => {
62+
dispatcher.dispatch({
63+
type: 'CLEAR_COMPLETED'
64+
});
65+
};
66+
67+
export const setVisibilityFilter = (hash) => {
68+
dispatcher.dispatch({
69+
type: 'SET_VISIBILITY_FILTER',
70+
hash
71+
});
72+
};

flux/app.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
import {
4+
Container
5+
} from 'flux/utils';
6+
7+
import todoStore from './store/todo';
8+
import typeStore from './store/type';
9+
import View from './view.jsx';
10+
import * as actions from './actions';
11+
12+
function getStores() {
13+
return [
14+
todoStore,
15+
typeStore
16+
];
17+
}
18+
19+
function getState() {
20+
return {
21+
todos: todoStore.getState(),
22+
hash: typeStore.getState(),
23+
actions: {
24+
...actions
25+
}
26+
};
27+
}
28+
29+
export default Container.createFunctional(View, getStores, getState);

flux/dispatcher.js

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
'use strict';
2+
3+
import {
4+
Dispatcher
5+
} from 'flux';
6+
7+
export default new Dispatcher();

flux/index.html

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
<!DOCTYPE html>
2+
<html>
3+
<head>
4+
<meta charset="UTF-8">
5+
<meta content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=0" name="viewport">
6+
<link rel="shortcut icon" href="../assets/images/logo.png" type="image/x-icon" />
7+
<title>Flux &bull; TodoMVC</title>
8+
</head>
9+
<body>
10+
<div id="app">
11+
<script>
12+
var isOnline = !!~location.host.indexOf('github');
13+
var script = document.createElement('script');
14+
script.type = 'text/javascript';
15+
script.src = (isOnline ? '//unpkg.com/dataflow-sample@latest' : '..') + '/dist/flux.js';
16+
var head = document.getElementsByTagName('head')[0];
17+
head.appendChild(script);
18+
</script>
19+
</div>
20+
</body>
21+
</html>

flux/index.js

+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
'use strict';
2+
3+
import React from 'react';
4+
import ReactDOM from 'react-dom';
5+
6+
import App from './app';
7+
8+
ReactDOM.render(<App />, document.querySelector('#app'));

flux/store/todo.js

+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
'use strict';
2+
3+
import {
4+
ReduceStore
5+
} from 'flux/utils';
6+
7+
import dispatcher from '../dispatcher';
8+
9+
const localStore = {
10+
get() {
11+
return JSON.parse(localStorage['enough-todo'] || '[]');
12+
},
13+
set(data) {
14+
localStorage['enough-todo'] = JSON.stringify(data);
15+
}
16+
};
17+
18+
class TodoStore extends ReduceStore {
19+
constructor() {
20+
super(dispatcher);
21+
}
22+
23+
getInitialState() {
24+
return localStore.get();
25+
}
26+
27+
reduce(state, action) {
28+
switch (action.type) {
29+
case 'ADD_TODO':
30+
var res = [
31+
...state,
32+
{
33+
id: String(+new Date()),
34+
completed: false,
35+
content: action.content,
36+
editing: false
37+
}
38+
];
39+
localStore.set(res);
40+
return res;
41+
case 'DELETE_TODO':
42+
var res = state.filter(item => item.id !== action.id);
43+
localStore.set(res);
44+
return res;
45+
case 'COMPLETE_TODO':
46+
var res = state.map(item =>
47+
item.id === action.id
48+
? {
49+
...item,
50+
completed: !item.completed
51+
}
52+
: item
53+
);
54+
localStore.set(res);
55+
return res;
56+
case 'EDIT_TODO':
57+
var res = state.map(item =>
58+
item.id === action.id
59+
? {
60+
...item,
61+
editing: true
62+
}
63+
: item
64+
);
65+
return res;
66+
case 'UPDATE_TODO':
67+
var res = state.map(item =>
68+
item.id === action.id
69+
? {
70+
...item,
71+
content: action.content,
72+
editing: false
73+
}
74+
: item
75+
);
76+
localStore.set(res);
77+
return res;
78+
case 'UPDATE_ITEM_TODO':
79+
var res = state.map(item =>
80+
item.id === action.id
81+
? {
82+
...item,
83+
content: action.content
84+
}
85+
: item
86+
);
87+
return res;
88+
case 'COMPLETE_ALL':
89+
var res = state.map(item => {
90+
return {
91+
...item,
92+
completed: true
93+
};
94+
});
95+
localStore.set(res);
96+
return res;
97+
case 'UNCOMPLETE_ALL':
98+
var res = state.map(item => {
99+
return {
100+
...item,
101+
completed: false
102+
};
103+
});
104+
localStore.set(res);
105+
return res;
106+
case 'CLEAR_COMPLETED':
107+
var res = state.filter(item => !item.completed);
108+
localStore.set(res);
109+
return res;
110+
}
111+
return state;
112+
}
113+
}
114+
115+
export default new TodoStore(dispatcher);

flux/store/type.js

+29
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
'use strict';
2+
3+
import {
4+
ReduceStore
5+
} from 'flux/utils';
6+
7+
import dispatcher from '../dispatcher';
8+
9+
class TypeStore extends ReduceStore {
10+
constructor() {
11+
super(dispatcher);
12+
}
13+
14+
getInitialState() {
15+
return location.hash.replace('#/', '') || 'all';
16+
}
17+
18+
reduce(state, action) {
19+
switch (action.type) {
20+
case 'SET_VISIBILITY_FILTER':
21+
state = action.hash;
22+
return state;
23+
}
24+
return state;
25+
}
26+
}
27+
28+
export default new TypeStore(dispatcher);
29+

0 commit comments

Comments
 (0)