update webpack dev, test and build & update eslint rule

old
ustccjw 2015-10-23 16:11:40 +08:00
parent 8c4c795d69
commit 4fb976a00d
49 changed files with 360 additions and 452 deletions

View File

@ -1 +0,0 @@
!node_modules

264
.eslintrc
View File

@ -1,207 +1,63 @@
{
"parser": "babel-eslint",
"env": {
"browser": true,
"node": true,
"mocha": true,
"es6": true
},
---
"ecmaFeatures": {
"jsx": true,
"templateStrings": true,
"superInFunctions": false,
"classes": true,
"modules": [2]
},
env:
es6: true
"plugins": [
"react"
],
ecmaFeatures:
modules: true
jsx: true
"rules": {
"block-scoped-var": [0],
"brace-style": [2, "1tbs", {
"allowSingleLine": true
}],
"camelcase": [0],
"comma-dangle": [2, "never"],
"comma-spacing": [2],
"comma-style": [2, "last"],
"complexity": [0, 11],
"consistent-return": [2],
"consistent-this": [0, "that"],
"curly": [2, "multi-line"],
"default-case": [2],
"dot-notation": [2, {
"allowKeywords": true
}],
"eol-last": [2],
"eqeqeq": [2],
"func-names": [0],
"func-style": [0, "declaration"],
"generator-star-spacing": [2, "after"],
"strict": [2, "always"],
"guard-for-in": [0],
"handle-callback-err": [0],
"key-spacing": [2, {
"beforeColon": false,
"afterColon": true
}],
"quotes": [2, "single", "avoid-escape"],
"max-depth": [0, 4],
"max-len": [0, 80, 4],
"max-nested-callbacks": [0, 2],
"max-params": [0, 3],
"max-statements": [0, 10],
"new-parens": [2],
"new-cap": [2, {
"capIsNewExceptions": ["CSSModules", "ToInteger", "ToObject", "ToPrimitive", "ToUint32"]
}],
"newline-after-var": [0],
"no-alert": [2],
"no-array-constructor": [2],
"no-bitwise": [0],
"no-caller": [2],
"no-catch-shadow": [2],
"no-cond-assign": [2],
"no-console": [0],
"no-constant-condition": [1],
"no-continue": [2],
"no-control-regex": [2],
"no-debugger": [2],
"no-delete-var": [2],
"no-div-regex": [0],
"no-dupe-args": [2],
"no-dupe-keys": [2],
"no-duplicate-case": [2],
"no-else-return": [0],
"no-empty": [2],
"no-empty-character-class": [2],
"no-empty-label": [2],
"no-eq-null": [0],
"no-eval": [2],
"no-ex-assign": [2],
"no-extend-native": [1],
"no-extra-bind": [2],
"no-extra-boolean-cast": [2],
"no-extra-parens": [0],
"no-extra-semi": [1],
"no-fallthrough": [2],
"no-floating-decimal": [2],
"no-func-assign": [2],
"no-implied-eval": [2],
"no-inline-comments": [0],
"no-inner-declarations": [2, "functions"],
"no-invalid-regexp": [2],
"no-irregular-whitespace": [2],
"no-iterator": [2],
"no-label-var": [2],
"no-labels": [2],
"no-lone-blocks": [2],
"no-lonely-if": [2],
"no-loop-func": [2],
"no-mixed-requires": [0, false],
"no-mixed-spaces-and-tabs": [2, false],
"no-multi-spaces": [2],
"no-multi-str": [2],
"no-multiple-empty-lines": [2, {
"max": 2
}],
"no-native-reassign": [1],
"no-negated-in-lhs": [2],
"no-nested-ternary": [0],
"no-new": [2],
"no-new-func": [2],
"no-new-object": [2],
"no-new-require": [0],
"no-new-wrappers": [2],
"no-obj-calls": [2],
"no-octal": [2],
"no-octal-escape": [2],
"no-path-concat": [0],
"no-param-reassign": [2],
"no-plusplus": [0],
"no-process-env": [0],
"no-process-exit": [2],
"no-proto": [2],
"no-redeclare": [2],
"no-regex-spaces": [2],
"no-reserved-keys": [0],
"no-restricted-modules": [0],
"no-return-assign": [2],
"no-script-url": [2],
"no-self-compare": [0],
"no-sequences": [2],
"no-shadow": [2],
"no-shadow-restricted-names": [2],
"semi-spacing": [2],
"no-spaced-func": [2],
"no-sparse-arrays": [2],
"no-sync": [0],
"no-ternary": [0],
"no-throw-literal": [2],
"no-trailing-spaces": [2],
"no-undef": [2],
"no-undef-init": [2],
"no-undefined": [0],
"no-underscore-dangle": [0],
"no-unreachable": [2],
"no-unused-expressions": [2],
"no-unused-vars": [1, {
"vars": "all",
"args": "after-used"
}],
"no-use-before-define": [2],
"no-void": [0],
"no-warning-comments": [0, {
"terms": ["todo", "fixme", "xxx"],
"location": "start"
}],
"no-with": [2],
"one-var": [0],
"operator-assignment": [0, "always"],
"operator-linebreak": [2, "after"],
"padded-blocks": [0],
"quote-props": [0],
"radix": [0],
"semi": [2],
"semi-spacing": [2, {
"before": false,
"after": true
}],
"sort-vars": [0],
"space-after-keywords": [2, "always"],
"space-before-function-paren": [2, {
"anonymous": "always",
"named": "always"
}],
"space-before-blocks": [0, "always"],
"space-in-brackets": [0, "never", {
"singleValue": true,
"arraysInArrays": false,
"arraysInObjects": false,
"objectsInArrays": true,
"objectsInObjects": true,
"propertyName": false
}],
"space-in-parens": [2, "never"],
"space-infix-ops": [2],
"space-return-throw-case": [2],
"space-unary-ops": [2, {
"words": true,
"nonwords": false
}],
"spaced-line-comment": [0, "always"],
"strict": [1],
"use-isnan": [2],
"valid-jsdoc": [0],
"valid-typeof": [2],
"vars-on-top": [0],
"wrap-iife": [2],
"wrap-regex": [2],
"yoda": [2, "never", {
"exceptRange": true
}]
}
}
parser: babel-eslint
plugins: [react]
rules:
# Best Practices
semi: [2, always]
# semi: [2, never]
curly: [2, multi-line]
# comma-dangle: [2, always-multiline]
no-use-before-define: [2, nofunc]
no-loop-func: 1 # should allow arrow function
# Strict Mode
strict: [2, global]
global-strict: 0
# Consistence
quotes: [2, single, avoid-escape]
new-cap: [2, capIsNew: false]
no-underscore-dangle: 0
new-parens: 0
# ES6+
no-var: 2
prefer-const: 2
object-shorthand: 1 # buggy
constructor-super: 2
no-this-before-super: 2
generator-star-spacing: 2
# Extra
no-labels: 1
no-proto: 1
no-constant-condition: 1
# React

3
.gitignore vendored
View File

@ -1,5 +1,4 @@
build
dist
lib
node_modules
npm-debug.log
.sass-cache/

View File

@ -1,3 +1,6 @@
language: node_js
node_js:
- 0.10
- "stable"
script:
- npm run lint
- npm test

View File

@ -52,7 +52,7 @@ class Autocomplete extends React.Component {
handleQueryChange = () => {
const query = this.refs.input.getValue();
if (this.state.query !== query) {
this.setState({query: query});
this.setState({query});
}
};
@ -71,8 +71,8 @@ class Autocomplete extends React.Component {
};
handleFocus = () => {
let client = event.target.getBoundingClientRect();
let screen_height = window.innerHeight || document.documentElement.offsetHeight;
const client = event.target.getBoundingClientRect();
const screen_height = window.innerHeight || document.documentElement.offsetHeight;
this.refs.suggestions.scrollTop = 0;
this.setState({
@ -126,7 +126,7 @@ class Autocomplete extends React.Component {
let suggestionsClassName = style.suggestions;
if (this.state.up) suggestionsClassName += ` ${style.up}`;
let suggestionsStyle = {width: this.state.width};
const suggestionsStyle = {width: this.state.width};
return (
<div data-react-toolbox='autocomplete' className={className}>
@ -164,9 +164,9 @@ class Autocomplete extends React.Component {
}
_getSuggestions () {
let query = this.state.query.toLowerCase().trim() || '';
let suggestions = new Map();
for (let [key, value] of this.state.dataSource) {
const query = this.state.query.toLowerCase().trim() || '';
const suggestions = new Map();
for (const [key, value] of this.state.dataSource) {
if (!this.state.values.has(key) && value.toLowerCase().trim().startsWith(query)) {
suggestions.set(key, value);
}
@ -175,14 +175,15 @@ class Autocomplete extends React.Component {
}
_selectOption (key) {
let { values, dataSource } = this.state;
let query = !this.props.multiple ? dataSource.get(key) : '';
const { dataSource } = this.state;
let { values } = this.state;
const query = !this.props.multiple ? dataSource.get(key) : '';
values = new Map(values);
if (!this.props.multiple) values.clear();
values.set(key, dataSource.get(key));
this.setState({focus: false, query: query, values: values}, () => {
this.setState({focus: false, query, values}, () => {
this.refs.input.blur();
if (this.props.onChange) this.props.onChange(this);
});
@ -190,26 +191,26 @@ class Autocomplete extends React.Component {
_unselectOption (key) {
if (key) {
let values = new Map(this.state.values);
const values = new Map(this.state.values);
values.delete(key);
this.setState({focus: false, values: values}, () => {
this.setState({focus: false, values}, () => {
if (this.props.onChange) this.props.onChange(this);
});
}
}
getValue () {
let values = [...this.state.values.keys()];
const values = [...this.state.values.keys()];
return this.props.multiple ? values : (values.length > 0 ? values[0] : null);
}
setValue (dataParam = []) {
let values = new Map();
let data = (typeof dataParam === 'string') ? [dataParam] : dataParam;
for (let [key, value] of this.state.dataSource) {
const values = new Map();
const data = (typeof dataParam === 'string') ? [dataParam] : dataParam;
for (const [key, value] of this.state.dataSource) {
if (data.indexOf(key) !== -1) values.set(key, value);
}
this.setState({values: values, query: this.props.multiple ? '' : values.get(data[0])});
this.setState({values, query: this.props.multiple ? '' : values.get(data[0])});
}
setError (data) {

View File

@ -30,7 +30,8 @@ class Card extends React.Component {
};
renderTitle () {
let styleFigure = {}, styleOverflow = {};
const styleFigure = {};
const styleOverflow = {};
if (this.props.image) styleFigure.backgroundImage = `url(${this.props.image})`;
if (this.props.color) {
styleFigure.backgroundColor = this.props.color;

View File

@ -39,13 +39,13 @@ class Calendar extends React.Component {
}
handleDayClick = (day) => {
let newDate = utils.time.setDay(this.state.viewDate, day);
const newDate = utils.time.setDay(this.state.viewDate, day);
this.setState({selectedDate: newDate});
if (this.props.onChange) this.props.onChange(newDate);
};
handleYearClick = (year) => {
let newDate = utils.time.setYear(this.state.selectedDate, year);
const newDate = utils.time.setYear(this.state.selectedDate, year);
this.setState({selectedDate: newDate, viewDate: newDate});
if (this.props.onChange) this.props.onChange(newDate);
};
@ -67,7 +67,7 @@ class Calendar extends React.Component {
};
renderYear (year) {
let props = {
const props = {
className: year === this.state.viewDate.getFullYear() ? style.active : '',
key: year,
onClick: this.handleYearClick.bind(this, year)
@ -89,7 +89,7 @@ class Calendar extends React.Component {
}
renderMonths () {
let animation = this.state.direction === 'left' ? SlideLeft : SlideRight;
const animation = this.state.direction === 'left' ? SlideLeft : SlideRight;
return (
<div data-react-toolbox='calendar'>
<FontIcon className={style.prev} value='chevron-left' onMouseDown={this.decrementViewMonth}>

View File

@ -24,7 +24,7 @@ class CalendarDialog extends React.Component {
};
handleCalendarChange = (date) => {
this.setState({date: date, display: 'months'});
this.setState({date, display: 'months'});
};
displayMonths = () => {

View File

@ -26,7 +26,7 @@ class DatePicker extends React.Component {
handleDateSelected = (value) => {
this.refs.input.setValue(this.formatDate(value));
this.setState({value: value});
this.setState({value});
};
formatDate (date) {
@ -59,7 +59,7 @@ class DatePicker extends React.Component {
}
setValue (value) {
this.setState({value: value});
this.setState({value});
}
}

View File

@ -51,8 +51,8 @@ class Dropdown extends React.Component {
}
handleClick = (event) => {
let client = event.target.getBoundingClientRect();
let screen_height = window.innerHeight || document.documentElement.offsetHeight;
const client = event.target.getBoundingClientRect();
const screen_height = window.innerHeight || document.documentElement.offsetHeight;
this.setState({
active: true,
@ -62,8 +62,8 @@ class Dropdown extends React.Component {
handleClickValue = (id) => {
if (!this.props.disabled) {
let value = id.toString();
for (let item of this.props.dataSource) {
const value = id.toString();
for (const item of this.props.dataSource) {
if (item.value.toString() === value) {
this.setState({active: false, selected: item});
break;
@ -73,7 +73,7 @@ class Dropdown extends React.Component {
};
renderValues () {
let items = this.props.dataSource.map((item, index) => {
const items = this.props.dataSource.map((item, index) => {
let className;
if (item.value === this.state.selected.value) className = ` ${style.selected}`;
@ -92,7 +92,7 @@ class Dropdown extends React.Component {
let className = style.values;
if (this.state.up) className += ` ${style.up}`;
let valuesStyle = {width: this.state.width};
const valuesStyle = {width: this.state.width};
return <ul ref='values' className={className} style={valuesStyle}>{ items }</ul>;
}

View File

@ -33,8 +33,8 @@ class Form extends React.Component {
componentWillReceiveProps (next_props) {
if (next_props.attributes) {
let attributes = this.storage(next_props);
this.setState({attributes: attributes});
const attributes = this.storage(next_props);
this.setState({attributes});
this.setValue(attributes.map((item) => { return item; }));
}
}
@ -48,8 +48,8 @@ class Form extends React.Component {
onChange = (event) => {
let is_valid = true;
let value = this.getValue();
for (let attr of this.state.attributes) {
const value = this.getValue();
for (const attr of this.state.attributes) {
if (attr.required && value[attr.ref] !== undefined && value[attr.ref].trim() === '') {
is_valid = false;
console.log('NOT VALUD');
@ -71,7 +71,7 @@ class Form extends React.Component {
};
render () {
let className = `${style.root} ${this.props.className}`;
const className = `${style.root} ${this.props.className}`;
const attributes = this.state.attributes.map((attribute, index) => {
if (attribute.type === 'autocomplete') {
return <Autocomplete key={index} {...attribute} onChange={this.onChange}/>;
@ -110,16 +110,16 @@ class Form extends React.Component {
}
storage (props, value) {
let key = `react-toolbox-form-${props.storage}`;
const key = `react-toolbox-form-${props.storage}`;
if (value) {
let store = {};
for (let attr of props.attributes) {
const store = {};
for (const attr of props.attributes) {
if (attr.storage) store[attr.ref] = value[attr.ref];
}
window.localStorage.setItem(key, JSON.stringify(store));
} else if (props.storage) {
let store = JSON.parse(window.localStorage.getItem(key) || {});
for (let input of props.attributes) {
const store = JSON.parse(window.localStorage.getItem(key) || {});
for (const input of props.attributes) {
if (store && store[input.ref]) {
input.value = store[input.ref];
}
@ -130,15 +130,15 @@ class Form extends React.Component {
}
getValue () {
let value = {};
for (let ref of Object.keys(this.refs)) {
let el = this.refs[ref];
const value = {};
for (const ref of Object.keys(this.refs)) {
const el = this.refs[ref];
if (el.getValue) {
if (ref.indexOf('.') === -1) {
value[ref] = el.getValue();
} else {
let parent = value;
let hierarchy = ref.split('.');
const hierarchy = ref.split('.');
hierarchy.forEach((attr, index) => {
if (index === hierarchy.length - 1) {
parent[attr] = el.getValue();
@ -155,7 +155,7 @@ class Form extends React.Component {
}
setValue (data = {}) {
for (let field of data) {
for (const field of data) {
if (this.refs[field.ref].setValue) {
this.refs[field.ref].setValue(field.value);
}

View File

@ -1,4 +1,6 @@
module.exports = {
import './commons';
export default {
Autocomplete: require('./autocomplete'),
Button: require('./button'),
Card: require('./card'),

View File

@ -100,7 +100,7 @@ class Input extends React.Component {
}
setValue (value) {
this.setState({value: value});
this.setState({value});
}
}

View File

@ -44,13 +44,13 @@ class Menu extends React.Component {
componentDidMount () {
const { width, height } = this.refs.menu.getBoundingClientRect();
const position = this.props.position === POSITION.AUTO ? this.calculatePosition() : this.props.position;
this.setState({position: position, width: width, height: height});
this.setState({ position, width, height });
}
componentWillReceiveProps (nextProps) {
if (this.props.position !== nextProps.position) {
const position = nextProps.position === POSITION.AUTO ? this.calculatePosition() : nextProps.position;
this.setState({ position: position });
this.setState({ position });
}
}
@ -58,7 +58,7 @@ class Menu extends React.Component {
if (!this.state.active && nextState.active && this.props.position === POSITION.AUTO) {
const position = this.calculatePosition();
if (this.state.position !== position) {
this.setState({position: position, active: false}, () => {
this.setState({ position, active: false }, () => {
setTimeout(() => {this.setState({active: true}); }, 20);
});
return false;
@ -89,8 +89,8 @@ class Menu extends React.Component {
};
handleSelect = (item) => {
let { value, onClick } = item.props;
this.setState({value: value, active: false, rippled: this.props.ripple}, () => {
const { value, onClick } = item.props;
this.setState({ value, active: false, rippled: this.props.ripple }, () => {
if (onClick) onClick();
if (this.props.onSelect) this.props.onSelect(value, this);
});

View File

@ -43,7 +43,7 @@ class RadioButton extends React.Component {
render () {
let labelClassName = style[this.props.disabled ? 'disabled' : 'field'];
let radioClassName = style[this.props.checked ? 'radio-checked' : 'radio'];
const radioClassName = style[this.props.checked ? 'radio-checked' : 'radio'];
if (this.props.className) labelClassName += ` ${this.props.className}`;
return (

View File

@ -20,7 +20,7 @@ class RadioGroup extends React.Component {
};
handleChange = (value, event) => {
this.setState({value: value}, () => {
this.setState({ value }, () => {
if (this.props.onChange) this.props.onChange(event, this);
});
};
@ -54,7 +54,7 @@ class RadioGroup extends React.Component {
}
setValue (value) {
this.setState({value: value});
this.setState({ value });
}
}

View File

@ -29,8 +29,8 @@ class Ripple extends React.Component {
document.addEventListener('mouseup', this.handleEnd);
const {top, left, width} = this._getDescriptor(pageX, pageY);
this.setState({active: false, restarting: true, width: 0}, () => {
this.refs.ripple.offsetWidth; //eslint-disable-line no-unused-expressions
this.setState({active: true, restarting: false, top: top, left: left, width: width});
this.refs.ripple.offsetWidth;
this.setState({active: true, restarting: false, top, left, width});
});
};
@ -40,7 +40,7 @@ class Ripple extends React.Component {
};
_getDescriptor (pageX, pageY) {
let { left, top, height, width } = ReactDOM.findDOMNode(this).getBoundingClientRect();
const { left, top, height, width } = ReactDOM.findDOMNode(this).getBoundingClientRect();
return {
left: this.props.centered ? width / 2 : pageX - left,
top: this.props.centered ? height / 2 : pageY - top,
@ -49,8 +49,8 @@ class Ripple extends React.Component {
}
render () {
let { left, top, width } = this.state;
let rippleStyle = {left: left, top: top, width: width, height: width};
const { left, top, width } = this.state;
const rippleStyle = {left, top, width, height};
let className = style[this.props.loading ? 'loading' : 'normal'];
if (this.state.active) className += ` ${style.active}`;
if (this.state.restarting) className += ` ${style.restarting}`;

View File

@ -157,7 +157,7 @@ describe('Slider', function () {
});
it('calls onChange callback when the value is changed', function () {
let onChangeSpy = sinon.spy();
const onChangeSpy = sinon.spy();
slider = utils.renderComponent(Slider, {onChange: onChangeSpy}, {sliderStart: 0, sliderLength: 1000});
TestUtils.Simulate.mouseDown(slider.refs.slider, { pageX: 900 });
expect(onChangeSpy.called).toEqual(true);

View File

@ -138,8 +138,8 @@ class Slider extends React.Component {
}
positionToValue (position) {
let { sliderStart: start, sliderLength: length } = this.state;
let { max, min } = this.props;
const { sliderStart: start, sliderLength: length } = this.state;
const { max, min } = this.props;
return this.trimValue((position.x - start) / length * (max - min) + min);
}
@ -163,7 +163,7 @@ class Slider extends React.Component {
}
knobOffset () {
let { max, min } = this.props;
const { max, min } = this.props;
return this.state.sliderLength * (this.state.value - min) / (max - min);
}
@ -194,7 +194,7 @@ class Slider extends React.Component {
}
render () {
let knobStyles = utils.prefixer({transform: `translateX(${this.knobOffset()}px)`});
const knobStyles = utils.prefixer({transform: `translateX(${this.knobOffset()}px)`});
let className = this.props.className;
if (this.props.editable) className += ` ${style.editable}`;
if (this.props.pinned) className += ` ${style.pinned}`;
@ -246,7 +246,7 @@ class Slider extends React.Component {
}
setValue (value) {
this.setState({value: value});
this.setState({value});
}
}

View File

@ -46,7 +46,7 @@ class Switch extends React.Component {
render () {
let labelClassName = style[this.props.disabled ? 'disabled' : 'field'];
let switchClassName = style[this.state.checked ? 'switch-on' : 'switch-off'];
const switchClassName = style[this.state.checked ? 'switch-on' : 'switch-off'];
if (this.props.className) labelClassName += ` ${this.props.className}`;
return (

View File

@ -27,7 +27,7 @@ class Tabs extends React.Component {
componentWillReceiveProps (next_props) {
const index = next_props.index || this.state.index;
this.setState({
index: index,
index,
pointer: this._pointerPosition(index, this.refs.navigation)
});
}
@ -45,7 +45,7 @@ class Tabs extends React.Component {
handleClick = (index) => {
this.setState({
index: index,
index,
pointer: this._pointerPosition(index, this.refs.navigation)
});
if (this.props.onChange) this.props.onChange(this);
@ -58,10 +58,10 @@ class Tabs extends React.Component {
}
render () {
let labels = [];
const labels = [];
const tabs = this.props.children.map((tab, index) => {
let active = this.state.index === index;
const active = this.state.index === index;
let className = `${style.label} ${tab.props.className}`;
if (active) className += ` ${style.active}`;
@ -69,13 +69,13 @@ class Tabs extends React.Component {
if (tab.props.hidden) className += ` ${style.hidden}`;
labels.push({
className: className,
className,
label: tab.props.label,
key: index,
onClick: !tab.props.disabled ? this.handleClick.bind(this, index) : null
});
return React.cloneElement(tab, {active: active, key: index, tabIndex: index });
return React.cloneElement(tab, { active, key: index, tabIndex: index });
});
let className = style.root;

View File

@ -67,8 +67,8 @@ class Hand extends React.Component {
}
getPositionRadius (position) {
let x = this.props.origin.x - position.x;
let y = this.props.origin.y - position.y;
const x = this.props.origin.x - position.x;
const y = this.props.origin.y - position.y;
return Math.sqrt(x * x + y * y);
}
@ -86,14 +86,14 @@ class Hand extends React.Component {
}
move (position) {
let degrees = this.trimAngleToValue(this.positionToAngle(position));
let radius = this.getPositionRadius(position);
const degrees = this.trimAngleToValue(this.positionToAngle(position));
const radius = this.getPositionRadius(position);
if (this.props.onMove) this.props.onMove(degrees === 360 ? 0 : degrees, radius);
}
render () {
const className = `${style.hand} ${this.props.className}`;
let handStyle = utils.prefixer({
const handStyle = utils.prefixer({
height: this.props.length - this.state.knobWidth / 2,
transform: `rotate(${this.props.angle}deg)`
});

View File

@ -21,7 +21,7 @@ class Hours extends React.Component {
};
handleHandMove = (degrees, radius) => {
let currentInner = radius < this.props.radius - this.props.spacing * innerSpacing;
const currentInner = radius < this.props.radius - this.props.spacing * innerSpacing;
if (this.props.format === '24hr' && this.state.inner !== currentInner) {
this.setState({inner: currentInner}, () => {
this.props.onChange(this.valueFromDegrees(degrees));

View File

@ -52,7 +52,7 @@ class Clock extends React.Component {
};
handleCalculateShape = () => {
let { top, left, width } = this.refs.wrapper.getBoundingClientRect();
const { top, left, width } = this.refs.wrapper.getBoundingClientRect();
this.setState({
center: { x: left + width / 2, y: top + width / 2 },
radius: width / 2

View File

@ -62,7 +62,7 @@ class TimePicker extends React.Component {
}
setValue (value) {
this.setState({value: value});
this.setState({value});
}
}

View File

@ -22,13 +22,13 @@ module.exports = {
},
addEventsToDocument (eventMap) {
for (let key in eventMap) {
for (const key in eventMap) {
document.addEventListener(key, eventMap[key], false);
}
},
removeEventsFromDocument (eventMap) {
for (let key in eventMap) {
for (const key in eventMap) {
document.removeEventListener(key, eventMap[key], false);
}
},

View File

@ -1,19 +1,22 @@
module.exports = {
angleFromPositions (cx, cy, ex, ey) {
let theta = Math.atan2(ey - cy, ex - cx) + Math.PI / 2;
const theta = Math.atan2(ey - cy, ex - cx) + Math.PI / 2;
return theta * 180 / Math.PI;
},
angle360FromPositions (cx, cy, ex, ey) {
let angle = this.angleFromPositions(cx, cy, ex, ey);
const angle = this.angleFromPositions(cx, cy, ex, ey);
return angle < 0 ? 360 + angle : angle;
},
range (start = 0, stop = null, step = 1) {
let [_start, _stop] = (stop !== null) ? [start, stop] : [0, start];
let length = Math.max(Math.ceil((_stop - _start) / step), 0);
let range = Array(length);
let [_start, _stop] = [0, start];
if (stop !== null) {
[_start, _stop] = [start, stop];
}
const length = Math.max(Math.ceil((_stop - _start) / step), 0);
const range = Array(length);
for (let idx = 0; idx < length; idx++, _start += step) {
range[idx] = _start;
@ -24,7 +27,7 @@ module.exports = {
round (number, decimals) {
if (!isNaN(parseFloat(number)) && isFinite(number)) {
let decimalPower = Math.pow(10, decimals);
const decimalPower = Math.pow(10, decimals);
return Math.round(parseFloat(number) * decimalPower) / decimalPower;
}
return NaN;

View File

@ -19,7 +19,7 @@ function getPrefixes (property, value) {
function prefixer (style) {
let _style = style;
for (let property in properties) {
for (const property in properties) {
if (style[property]) {
_style = Object.assign(_style, getPrefixes(property, style[property]));
}

View File

@ -4,13 +4,13 @@ import TestUtils from 'react-addons-test-utils';
module.exports = {
renderComponent (Component, props = {}, state = {}) {
let component = TestUtils.renderIntoDocument(<Component {...props} />);
const component = TestUtils.renderIntoDocument(<Component {...props} />);
if (state !== {}) { component.setState(state); }
return component;
},
shallowRenderComponent (component, props, ...children) {
let shallowRenderer = TestUtils.createRenderer();
const shallowRenderer = TestUtils.createRenderer();
shallowRenderer.render(React.createElement(component, props, children.length > 1 ? children : children[0]));
return shallowRenderer.getRenderOutput();
}

View File

@ -1,7 +1,7 @@
module.exports = {
getDaysInMonth (d) {
let resultDate = this.getFirstDayOfMonth(d);
const resultDate = this.getFirstDayOfMonth(d);
resultDate.setMonth(resultDate.getMonth() + 1);
resultDate.setDate(resultDate.getDate() - 1);
return resultDate.getDate();
@ -20,7 +20,7 @@ module.exports = {
},
getFullMonth (d) {
let month = d.getMonth();
const month = d.getMonth();
switch (month) {
default: return 'Unknown';
case 0: return 'January';
@ -39,7 +39,7 @@ module.exports = {
},
getShortMonth (d) {
let month = d.getMonth();
const month = d.getMonth();
switch (month) {
default: return 'Unknown';
case 0: return 'Jan';
@ -88,7 +88,7 @@ module.exports = {
},
cloneAsDate (d) {
let clonedDate = this.clone(d);
const clonedDate = this.clone(d);
clonedDate.setHours(0, 0, 0, 0);
return clonedDate;
},
@ -98,56 +98,56 @@ module.exports = {
},
addDays (d, days) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setDate(d.getDate() + days);
return newDate;
},
addMonths (d, months) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setMonth(d.getMonth() + months);
return newDate;
},
addYears (d, years) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setFullYear(d.getFullYear() + years);
return newDate;
},
setDay (d, day) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setDate(day);
return newDate;
},
setMonth (d, month) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setMonth(month);
return newDate;
},
setYear (d, year) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setFullYear(year);
return newDate;
},
setHours (d, hours) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setHours(hours);
return newDate;
},
setMinutes (d, minutes) {
let newDate = this.clone(d);
const newDate = this.clone(d);
newDate.setMinutes(minutes);
return newDate;
},
toggleTimeMode (d) {
let newDate = this.clone(d);
let hours = newDate.getHours();
const newDate = this.clone(d);
const hours = newDate.getHours();
newDate.setHours(hours - (hours > 12 ? -12 : 12));
return newDate;
@ -158,8 +158,8 @@ module.exports = {
let mins = date.getMinutes().toString();
if (format === 'ampm') {
let isAM = hours < 12;
let additional = isAM ? ' am' : ' pm';
const isAM = hours < 12;
const additional = isAM ? ' am' : ' pm';
hours = hours % 12;
hours = (hours || 12).toString();

View File

@ -1,7 +1,7 @@
var pkg = require('./package.json');
var node_modules = __dirname + '/node_modules';
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var environment = process.env.NODE_ENV;
const pkg = require('./package.json');
const node_modules = __dirname + '/node_modules';
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const environment = process.env.NODE_ENV;
module.exports = {
cache: true,

View File

@ -1,7 +1,6 @@
require('webpack');
'use strict';
var pkg = require('./package.json');
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const webpackConfig = require('./webpack.config.test');
module.exports = function (config) {
config.set({
@ -15,17 +14,7 @@ module.exports = function (config) {
],
reporters: ['dots'],
preprocessors: {'tests.webpack.js': ['webpack']},
webpack: {
resolve: { extensions: ['', '.jsx', '.scss', '.js', '.json'] },
module: {
loaders: [
{ test: /(\.js|\.jsx)$/, exclude: /(node_modules)/, loader: 'babel' },
{ test: /(\.scss|\.css)$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader!sass') },
]
},
watch: true,
plugins: [new ExtractTextPlugin(pkg.name + '.[name].css', {allChunks: false})]
},
webpack: webpackConfig,
webpackServer: {
noInfo: true
}

View File

@ -15,21 +15,18 @@
"email": "javier.velasco86@gmail.com"
}
],
"style": "commons.scss",
"main": "./components",
"directories": {
"react-toolbox": "./react-toolbox/components"
},
"main": "./lib",
"scripts": {
"start": "webpack-dev-server --hot",
"eslint": "eslint ./components/**/*.jsx",
"clean": "rm -rf dist",
"babel": "babel --stage 2 --optional es7.classProperties ./components --out-dir ./lib",
"sass": "sass --update components:lib --sourcemap=none",
"dist": "npm run babel && npm run sass",
"deploy": "NODE_ENV=production webpack -p",
"test": "karma start",
"test:watch": "karma start --no-single-run"
"test:watch": "karma start --no-single-run",
"babel": "babel ./components --out-dir ./lib",
"sass": "node-sass ./components -o ./lib",
"clean": "rimraf ./lib",
"prebuild": "npm run clean",
"lint": "eslint ./components ./spec ./example --ext .js,.jsx",
"build": "npm run lint && npm run babel && npm run sass",
"prepublish": "npm run build",
"start": "node ./server"
},
"bugs": {
"url": "https://github.com/react-toolbox/react-toolbox/issues",
@ -45,19 +42,19 @@
"license": "MIT",
"peerDependencies": {
"react": "^0.14",
"react-dom": "^0.14.0"
"react-dom": "^0.14.0",
"react-addons-css-transition-group": "^0.14.0",
"normalize.css": "^3.0.3"
},
"devDependencies": {
"autoprefixer-core": "^5.1.11",
"autoprefixer": "^6.0.3",
"babel-core": "^5.8.23",
"babel-eslint": "^4.1.3",
"babel-loader": "^5.3.2",
"babel-runtime": "^5.8.20",
"css-loader": "^0.16.0",
"eslint": "^1.3.1",
"eslint": "^1.7.3",
"eslint-plugin-react": "^3.3.1",
"expect": "^1.8.0",
"extract-text-webpack-plugin": "^0.8.1",
"karma": "^0.13.3",
"karma-chrome-launcher": "^0.2.0",
"karma-cli": "^0.1.0",
@ -67,13 +64,12 @@
"mocha": "^2.3.3",
"node-libs-browser": "^0.5.2",
"node-sass": "^3.3.3",
"normalize.css": "^3.0.3",
"phantomjs-polyfill": "0.0.1",
"postcss-loader": "^0.4.3",
"postcss-loader": "^0.7.0",
"react": "^0.14",
"react-dom": "^0.14.0",
"react-addons-css-transition-group": "^0.14.0",
"react-addons-test-utils": "^0.14.0",
"react-dom": "^0.14.0",
"react-hot-loader": "^1.3.0",
"sass-loader": "^2.0.1",
"sinon": "git://github.com/cjohansen/Sinon.JS#sinon-2.0",

26
server.js Normal file
View File

@ -0,0 +1,26 @@
'use strict';
const webpack = require('webpack');
const WebpackDevServer = require('webpack-dev-server');
const config = require('./webpack.config.development');
const devServer = {
host: '0.0.0.0',
port: 8080,
inline: true
};
new WebpackDevServer(webpack(config), {
publicPath: config.output.publicPath,
hot: true,
historyApiFallback: false,
stats: {
colors: true
}
}).listen(devServer.port, devServer.host, function(err) {
if (err) {
console.error(err)
}
console.log(`Listening at ${devServer.host}:${devServer.port}`)
console.log(`open http://${devServer.host}:${devServer.port}/spec/`)
});

49
spec/app.jsx Normal file
View File

@ -0,0 +1,49 @@
import React from 'react';
import Autocomplete from './components/autocomplete';
import Button from './components/button';
import Card from './components/card';
import Checkbox from './components/checkbox';
import Dialog from './components/dialog';
import Drawer from './components/drawer';
import Dropdown from './components/dropdown';
import IconMenu from './components/icon_menu';
import Input from './components/input';
import List from './components/list';
import Menu from './components/menu';
import Pickers from './components/pickers';
import Progress from './components/progress';
import Radio from './components/radio';
import Snackbar from './components/snackbar';
import Slider from './components/slider';
import Switch from './components/switch';
import Tabs from './components/tabs';
const App = () => {
return(
<app data-react-toolbox-app>
<h1>React Toolbox</h1>
<h3>Component Spec v0.10.20</h3>
<Autocomplete />
<Button />
<Card />
<Checkbox />
<Dialog />
<Drawer />
<Dropdown />
<IconMenu />
<Input />
<List />
<Menu />
<Pickers />
<Progress />
<Radio />
<Slider />
<Snackbar />
<Switch />
<Tabs />
</app>
);
};
export default App;

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import Button from '../../components/button';

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import FontIcon from '../../components/font_icon';

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import Input from '../../components/input';

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import Link from '../../components/link';

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import { ListCheckbox, ListSubHeader, List, ListItem, ListDivider } from '../../components/list';

View File

@ -1,10 +1,9 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import DatePicker from '../../components/date_picker';
import TimePicker from '../../components/time_picker';
const PickersTest = () => {
let datetime = new Date(1995, 11, 17);
const datetime = new Date(1995, 11, 17);
datetime.setHours(17);
datetime.setMinutes(28);

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import Slider from '../../components/slider';

View File

@ -1,4 +1,3 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import { Tabs, Tab } from '../../components/tabs';

View File

@ -13,8 +13,6 @@
<meta name="format-detection" content="telephone=no">
<meta name="HandheldFriendly" content="True">
<meta http-equiv="cleartype" content="on">
<link href="../build/react-toolbox.commons.css" rel='stylesheet' type='text/css'>
<link href="../build/react-toolbox.test.css" rel='stylesheet' type='text/css'>
<style>
app { padding: 1.6rem; }
app > h1, app > h3 { line-height: 100%; }
@ -28,6 +26,6 @@
</head>
<body>
<div id="toolbox-test"></div>
<script src="../build/react-toolbox.test.js"></script>
<script src="/build/index.js"></script>
</body>
</html>

View File

@ -1,52 +1,5 @@
/*eslint-disable no-unused-vars*/
import React from 'react';
import ReactDOM from 'react-dom';
import Autocomplete from './components/autocomplete';
import Button from './components/button';
import Card from './components/card';
import Checkbox from './components/checkbox';
import Dialog from './components/dialog';
import Drawer from './components/drawer';
import Dropdown from './components/dropdown';
import IconMenu from './components/icon_menu';
import Input from './components/input';
import List from './components/list';
import Menu from './components/menu';
import Pickers from './components/pickers';
import Progress from './components/progress';
import Radio from './components/radio';
import Snackbar from './components/snackbar';
import Slider from './components/slider';
import Switch from './components/switch';
import Tabs from './components/tabs';
const App = () => {
return (
<app data-react-toolbox-app>
<h1>React Toolbox</h1>
<h3>Component Spec v0.10.20</h3>
<Autocomplete />
<Button />
<Card />
<Checkbox />
<Dialog />
<Drawer />
<Dropdown />
<IconMenu />
<Input />
<List />
<Menu />
<Pickers />
<Progress />
<Radio />
<Slider />
<Snackbar />
<Switch />
<Tabs />
</app>
);
};
import App from './app';
ReactDOM.render(<App/>, document.getElementById('toolbox-test'));

View File

@ -1,2 +1,4 @@
var context = require.context('./components', true, /(.spec\.cjsx?|.spec\.jsx?)$/);
'use strict';
const context = require.context('./components', true, /(.spec\.cjsx?|.spec\.jsx?)$/);
context.keys().forEach(context);

View File

@ -0,0 +1,45 @@
'use strict';
const path = require('path')
const webpack = require('webpack')
const autoprefixer = require('autoprefixer');
const devServer = 'http://0.0.0.0:8080';
module.exports = {
context: __dirname,
devtool: '#eval-source-map',
entry: [
'webpack-dev-server/client?' + devServer,
'webpack/hot/only-dev-server',
'./spec/index.jsx'
],
output: {
path: path.join(__dirname, 'build'),
filename: 'index.js',
publicPath: '/build/'
},
resolve: {
extensions: ['', '.jsx', '.scss', '.js', '.json']
},
module: {
loaders: [
{
test: /(\.js|\.jsx)$/,
exclude: /(node_modules)/,
loader: 'react-hot!babel'
}, {
test: /(\.scss|\.css)$/,
loader: 'style!css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass'
}
]
},
postcss: [autoprefixer],
plugins: [
new webpack.HotModuleReplacementPlugin(),
new webpack.optimize.OccurenceOrderPlugin(),
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('development')
})
]
};

View File

@ -1,35 +0,0 @@
var pkg = require('./package.json');
var node_modules = __dirname + '/node_modules';
var ExtractTextPlugin = require('extract-text-webpack-plugin');
var environment = process.env.NODE_ENV;
module.exports = {
cache: true,
resolve: {
extensions: ['', '.jsx', '.scss', '.js', '.json']
},
context: __dirname,
entry: {
commons: ['./components/commons'],
test: ['webpack/hot/dev-server', './spec/index.jsx']
},
output: {
path: environment === 'production' ? './dist' : './build',
filename: pkg.name + '.[name].js',
publicPath: '/build/'
},
devServer: {
host: '0.0.0.0',
port: 8080,
inline: true
},
module: {
noParse: [node_modules + '/react/dist/*.js'],
loaders: [
{ test: /(\.js|\.jsx)$/, exclude: /(node_modules)/, loaders: ['babel'] },
{ test: /(\.scss|\.css)$/, loader: ExtractTextPlugin.extract('style-loader', 'css-loader?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss-loader!sass') }
]
},
postcss: [require('autoprefixer-core')],
plugins: [new ExtractTextPlugin(pkg.name + '.[name].css', {allChunks: true})]
};

29
webpack.config.test.js Normal file
View File

@ -0,0 +1,29 @@
'use strict';
const webpack = require('webpack')
const autoprefixer = require('autoprefixer');
module.exports = {
module: {
loaders: [
{
test: /(\.js|\.jsx)$/,
exclude: /(node_modules)/,
loader: 'react-hot!babel'
}, {
test: /(\.scss|\.css)$/,
loader: 'style!css?modules&importLoaders=1&localIdentName=[name]__[local]___[hash:base64:5]!postcss!sass'
}
]
},
resolve: {
extensions: ['', '.jsx', '.scss', '.js', '.json']
},
watch: true,
postcss: [autoprefixer],
plugins: [
new webpack.DefinePlugin({
'process.env.NODE_ENV': JSON.stringify('test')
})
]
};