Skip to content

Commit 61d569f

Browse files
✨ [feature] Support server rendering (#4)
1 parent 53c4a97 commit 61d569f

11 files changed

+144
-809
lines changed

.eslintrc

+2
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
"camelcase": 0,
66
"indent": [2, 4, {"SwitchCase": 1}],
77
"no-use-before-define": 0,
8+
"no-restricted-syntax": ["error", "WithStatement"],
89
"space-before-function-paren": [2, {"anonymous": "always", "named": "never"}],
10+
"no-param-reassign": 0,
911
"func-names": 0,
1012
"new-cap": 0,
1113
"no-underscore-dangle": 0,

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@ node_modules/
22
examples/__build__/
33
.nyc_output/
44
coverage/
5+
dist

dist/react-mobile-datepicker.js

-764
This file was deleted.

dist/react-mobile-datepicker.js.map

-1
This file was deleted.

dist/react-mobile-datepicker.min.js

-2
This file was deleted.

dist/react-mobile-datepicker.min.js.map

-1
This file was deleted.

lib/DatePickerItem.js

+10-11
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,7 @@
55
import React, { Component, PropTypes } from 'react';
66
import * as TimeUtil from './time.js';
77
import { shallowEqual } from './pureRender.js';
8-
9-
import {
10-
TRANSITION,
11-
TRANSFORM,
12-
TRANSFORM_CSS,
13-
} from './transition';
8+
import { addPrefixCss, formatCss } from './prefix.js';
149

1510
const DATE_HEIGHT = 40; // 每个日期的高度
1611
const DATE_LENGTH = 10; // 日期的个数
@@ -116,7 +111,7 @@ class DatePickerItem extends Component {
116111
* @return {undefined}
117112
*/
118113
_clearTransition(obj) {
119-
obj.style[TRANSITION] = ''; // eslint-disable-line
114+
addPrefixCss(obj, { transition: '' });
120115
}
121116

122117
/**
@@ -144,10 +139,14 @@ class DatePickerItem extends Component {
144139
*/
145140
_moveTo(obj, currentIndex) {
146141
this.animating = true;
147-
obj.style[TRANSITION] = `${TRANSFORM_CSS} .2s ease-out`; // eslint-disable-line
142+
143+
addPrefixCss(obj, { transition: 'transform .2s ease-out' });
144+
148145
this.setState({
149146
translateY: -currentIndex * DATE_HEIGHT,
150147
});
148+
149+
// NOTE: There is no transitionend, setTimeout is used instead.
151150
setTimeout(() => {
152151
this.animating = false;
153152
this.props.onSelect(this.state.dates[MIDDLE_INDEX]);
@@ -251,10 +250,10 @@ class DatePickerItem extends Component {
251250
}
252251

253252
render() {
254-
const scrollStyle = {
255-
[TRANSFORM]: `translateY(${this.state.translateY}px)`,
253+
const scrollStyle = formatCss({
254+
transform: `translateY(${this.state.translateY}px)`,
256255
marginTop: this.state.marginTop,
257-
};
256+
});
258257

259258
return (
260259
<div className="datepicker-col-1">

lib/prefix.js

+54
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
/**
2+
* 驼峰写法
3+
* @param {String} str 要转化的字符串
4+
* @return {String} 转化后的字符串
5+
*/
6+
export function camelCase(str) {
7+
return str.replace(/-([a-z])/g, ($0, $1) => $1.toUpperCase()).replace('-', '');
8+
}
9+
10+
/**
11+
* 格式化css属性对象
12+
* @param {Object} props 属性对象
13+
* @return {Object} 添加前缀的格式化属性对象
14+
*/
15+
export function formatCss(props) {
16+
const prefixs = ['-webkit-', '-moz-', '-ms-'];
17+
18+
const result = {};
19+
20+
const regPrefix = /transform|transition/;
21+
22+
23+
for (const key in props) {
24+
if (props.hasOwnProperty(key)) {
25+
const styleValue = props[key];
26+
27+
// 如果检测是transform或transition属性
28+
if (regPrefix.test(key)) {
29+
for (let i = 0; i < prefixs.length; i++) {
30+
const styleName = camelCase(prefixs[i] + key);
31+
result[styleName] = styleValue.replace(regPrefix, `${prefixs[i]}$&`);
32+
}
33+
}
34+
35+
result[key] = styleValue;
36+
}
37+
}
38+
39+
return result;
40+
}
41+
42+
/**
43+
* 为元素添加css样式
44+
* @param {Object} element 目标元素
45+
* @param {Object} props css属性对象
46+
*/
47+
export function addPrefixCss(element, props) {
48+
const formatedProps = formatCss(props);
49+
for (const key in formatedProps) {
50+
if (formatedProps.hasOwnProperty(key)) {
51+
element.style[key] = formatedProps[key];
52+
}
53+
}
54+
}

lib/transition.js

-30
This file was deleted.

test/functional/DatePicker_spec.js

+11
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,17 @@ function delay(time) {
2424
}
2525

2626
describe('DatePicker.js', () => {
27+
28+
describe('Lifecycle', () => {
29+
it ('should update value of state when parent component value of props update', () => {
30+
const datePicker = mount(
31+
<DatePicker {...DEFAULT_PROPS} />
32+
);
33+
datePicker.setProps({ value: new Date(2016, 8, 15) });
34+
expect(datePicker.state('value').getTime()).to.equals(new Date(2016, 8, 15).getTime());
35+
});
36+
});
37+
2738
describe('logic', () => {
2839
var datePicker;
2940
var yearPicker;

test/functional/prefix.spec.js

+66
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,66 @@
1+
2+
import { expect } from 'chai';
3+
import { formatCss, addPrefixCss } from '../../lib/prefix.js';
4+
5+
6+
describe('prefix.js', () => {
7+
8+
describe('formatCss', () => {
9+
it('should return correct formated css property when contain "transform"', function () {
10+
const date = {
11+
transform: 'translate(100px, 100px, 100px)',
12+
margin: '10px',
13+
};
14+
15+
expect(formatCss(date)).to.eql({
16+
WebkitTransform: 'translate(100px, 100px, 100px)',
17+
MozTransform: 'translate(100px, 100px, 100px)',
18+
MsTransform: 'translate(100px, 100px, 100px)',
19+
transform: 'translate(100px, 100px, 100px)',
20+
margin: '10px',
21+
});
22+
});
23+
24+
it('should return correct formated css property when contain "transition"', function () {
25+
const date = {
26+
transition: 'transform 2s',
27+
padding: 0,
28+
margin: '10px',
29+
};
30+
31+
expect(formatCss(date)).to.eql({
32+
WebkitTransition: '-webkit-transform 2s',
33+
MozTransition: '-moz-transform 2s',
34+
MsTransition: '-ms-transform 2s',
35+
transition: 'transform 2s',
36+
padding: 0,
37+
margin: '10px',
38+
});
39+
});
40+
});
41+
42+
describe('addPrefixCss', () => {
43+
it('should set correct style', () => {
44+
const mock = {
45+
style: {}
46+
};
47+
48+
const props = {
49+
transition: 'transform 2s',
50+
padding: 0,
51+
margin: '10px',
52+
};
53+
54+
addPrefixCss(mock, props);
55+
56+
expect(mock.style).to.eql({
57+
WebkitTransition: '-webkit-transform 2s',
58+
MozTransition: '-moz-transform 2s',
59+
MsTransition: '-ms-transform 2s',
60+
transition: 'transform 2s',
61+
padding: 0,
62+
margin: '10px',
63+
});
64+
});
65+
});
66+
})

0 commit comments

Comments
 (0)