diff --git a/.eslintignore b/.eslintignore index b04f9cd2..f574f775 100644 --- a/.eslintignore +++ b/.eslintignore @@ -1,3 +1,10 @@ **/node_modules/ **/build/ +docs/ +spec/ lib +karma.conf.js +gulpfile.js +tests.webpack* +server.js +webpack* diff --git a/.eslintrc b/.eslintrc index 136e551f..3c7ec891 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,227 +1,30 @@ { + "parser": "babel-eslint", + "extends": "airbnb", "env": { "browser": true, "node": true, - "mocha": true, + "jest": true, "es6": true }, - - "ecmaFeatures": { - "jsx": true, - "templateStrings": true, - "superInFunctions": false, - "classes": true, - "modules": true - }, - - "parser": "babel-eslint", - - "plugins": [ - "babel", - "react" - ], - "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], - "constructor-super": [2], - "consistent-return": [0], - "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"], - "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": [0], - "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-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-this-before-super": [2], - "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, { - "allowShortCircuit": true - }], - "no-unused-vars": [1, { - "vars": "all", - "args": "after-used" - }], - "no-use-before-define": [2, "nofunc"], - "no-var": [2], - "no-void": [0], - "no-warning-comments": [0, { - "terms": ["todo", "fixme", "xxx"], - "location": "start" - }], - "no-with": [2], - "object-shorthand": [2], - "one-var": [0], - "operator-assignment": [0, "always"], - "operator-linebreak": [2, "before"], - "padded-blocks": [0], - "prefer-const": [2], - "prefer-spread": [2], - "quote-props": [0], - "radix": [0], - "semi": [2], - "sort-vars": [0], - "keyword-spacing": [2, {"after": true}], - "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-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 - }], - "react/display-name": 0, - "react/jsx-boolean-value": 1, - "react/jsx-closing-bracket-location": 0, - "react/jsx-curly-spacing": 1, - "react/jsx-max-props-per-line": 0, - "react/jsx-indent-props": 0, - "react/jsx-no-duplicate-props": 1, - "react/jsx-no-undef": 1, - "react/jsx-pascal-case": 1, - "react/sort-prop-types": 1, - "react/jsx-sort-props": 0, - "react/jsx-uses-react": 1, - "react/jsx-uses-vars": 1, - "react/no-danger": 0, - "react/no-did-mount-set-state": 0, - "react/no-did-update-set-state": 1, - "react/no-multi-comp": 0, - "react/no-unknown-property": 1, - "react/prop-types": [2, {"ignore": ["onMouseDown", "onTouchStart"]}], - "react/react-in-jsx-scope": 1, - "react/self-closing-comp": 1, - "react/sort-comp": 1 + "func-names": "off", + "global-require": "off", + "no-use-before-define": 0, + "no-underscore-dangle": 0, + "react/sort-prop-types": 2, + "react/jsx-no-bind": 2, + "react/require-default-props": 0, + "react/no-find-dom-node": 0, + "react/jsx-filename-extension": 0, + "import/prefer-default-export": 0, + "jsx-a11y/no-static-element-interactions": 0, + "import/no-extraneous-dependencies": [ + "error", { + "devDependencies": true, + "optionalDependencies": false, + "peerDependencies": false + } + ] } } diff --git a/components/app_bar/AppBar.js b/components/app_bar/AppBar.js index f694f6cf..6e6aec44 100644 --- a/components/app_bar/AppBar.js +++ b/components/app_bar/AppBar.js @@ -1,8 +1,8 @@ import React, { PropTypes } from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; -import { APP_BAR } from '../identifiers.js'; -import InjectIconButton from '../button/IconButton.js'; +import { APP_BAR } from '../identifiers'; +import InjectIconButton from '../button/IconButton'; const factory = (IconButton) => { class AppBar extends React.Component { @@ -13,13 +13,13 @@ const factory = (IconButton) => { flat: PropTypes.bool, leftIcon: PropTypes.oneOfType([ PropTypes.string, - PropTypes.element + PropTypes.element, ]), onLeftIconClick: PropTypes.func, onRightIconClick: PropTypes.func, rightIcon: PropTypes.oneOfType([ PropTypes.string, - PropTypes.element + PropTypes.element, ]), scrollHide: PropTypes.bool, theme: PropTypes.shape({ @@ -30,27 +30,27 @@ const factory = (IconButton) => { leftIcon: PropTypes.string, rightIcon: PropTypes.string, scrollHide: PropTypes.string, - title: PropTypes.string + title: PropTypes.string, }), - title: PropTypes.node + title: PropTypes.node, }; static defaultProps = { className: '', fixed: false, flat: false, - scrollHide: false + scrollHide: false, }; - state = {hidden: false, height: 0}; + state = { hidden: false, height: 0 }; - componentDidMount () { + componentDidMount() { if (this.props.scrollHide) { this.initializeScroll(); } } - componentWillReceiveProps (nextProps) { + componentWillReceiveProps(nextProps) { if (!this.props.scrollHide && nextProps.scrollHide) { this.initializeScroll(); } @@ -60,7 +60,7 @@ const factory = (IconButton) => { } } - componentWillUnmount () { + componentWillUnmount() { if (this.props.scrollHide) { this.endScroll(); } @@ -70,7 +70,7 @@ const factory = (IconButton) => { window.addEventListener('scroll', this.handleScroll); const { height } = this.rootNode.getBoundingClientRect(); this.curScroll = window.scrollY; - this.setState({height}); + this.setState({ height }); }; endScroll = () => { @@ -79,31 +79,42 @@ const factory = (IconButton) => { handleScroll = () => { const scrollDiff = this.curScroll - window.scrollY; - const hidden = scrollDiff < 0 && window.scrollY !== undefined && window.scrollY > this.state.height; - this.setState({hidden}); + const hidden = scrollDiff < 0 + && window.scrollY !== undefined + && window.scrollY > this.state.height; + this.setState({ hidden }); this.curScroll = window.scrollY; }; - render () { - const { children, leftIcon, onLeftIconClick, onRightIconClick, rightIcon, theme, title } = this.props; + render() { + const { + children, + leftIcon, + onLeftIconClick, + onRightIconClick, + rightIcon, + theme, + title, + } = this.props; const className = classnames(theme.appBar, { [theme.fixed]: this.props.fixed, [theme.flat]: this.props.flat, - [theme.scrollHide]: this.state.hidden + [theme.scrollHide]: this.state.hidden, }, this.props.className); return (
{this.rootNode = node;}} + data-react-toolbox="app-bar" + ref={(node) => { this.rootNode = node; }} >
{leftIcon && + icon={leftIcon} + /> } {title &&

{title}

} {children} @@ -111,7 +122,8 @@ const factory = (IconButton) => { inverse className={classnames(theme.rightIcon)} onClick={onRightIconClick} - icon={rightIcon} /> + icon={rightIcon} + /> }
diff --git a/components/app_bar/index.js b/components/app_bar/index.js index 83d10d8e..ac09b55c 100644 --- a/components/app_bar/index.js +++ b/components/app_bar/index.js @@ -1,6 +1,6 @@ import { themr } from 'react-css-themr'; -import { APP_BAR } from '../identifiers.js'; -import { appBarFactory } from './AppBar.js'; +import { APP_BAR } from '../identifiers'; +import { appBarFactory } from './AppBar'; import { IconButton } from '../button'; import theme from './theme.css'; diff --git a/components/autocomplete/Autocomplete.js b/components/autocomplete/Autocomplete.js index 32c6d647..636943d0 100644 --- a/components/autocomplete/Autocomplete.js +++ b/components/autocomplete/Autocomplete.js @@ -1,3 +1,4 @@ +/* eslint-disable */ import React, { Component, PropTypes } from 'react'; import ReactDOM from 'react-dom'; import classnames from 'classnames'; @@ -10,192 +11,191 @@ import events from '../utils/events.js'; const POSITION = { AUTO: 'auto', DOWN: 'down', - UP: 'up' + UP: 'up', }; const factory = (Chip, Input) => { class Autocomplete extends Component { - static propTypes = { - allowCreate: PropTypes.bool, - className: PropTypes.string, - direction: PropTypes.oneOf(['auto', 'up', 'down']), - disabled: PropTypes.bool, - error: React.PropTypes.oneOfType([ - React.PropTypes.string, - React.PropTypes.node - ]), - keepFocusOnChange: PropTypes.bool, - label: React.PropTypes.oneOfType([ - React.PropTypes.string, - React.PropTypes.node - ]), - multiple: PropTypes.bool, - onBlur: PropTypes.func, - onChange: PropTypes.func, - onFocus: PropTypes.func, - onQueryChange: PropTypes.func, - query: PropTypes.string, - selectedPosition: PropTypes.oneOf(['above', 'below', 'none']), - showSelectedWhenNotInSource: PropTypes.bool, - showSuggestionsWhenValueIsSet: PropTypes.bool, - source: PropTypes.any, - suggestionMatch: PropTypes.oneOf(['disabled', 'start', 'anywhere', 'word']), - theme: PropTypes.shape({ - active: PropTypes.string, - autocomplete: PropTypes.string, - focus: PropTypes.string, - input: PropTypes.string, - suggestion: PropTypes.string, - suggestions: PropTypes.string, - up: PropTypes.string, - value: PropTypes.string, - values: PropTypes.string - }), - value: PropTypes.any - }; + static propTypes = { + allowCreate: PropTypes.bool, + className: PropTypes.string, + direction: PropTypes.oneOf(['auto', 'up', 'down']), + disabled: PropTypes.bool, + error: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.node, + ]), + keepFocusOnChange: PropTypes.bool, + label: React.PropTypes.oneOfType([ + React.PropTypes.string, + React.PropTypes.node, + ]), + multiple: PropTypes.bool, + onBlur: PropTypes.func, + onChange: PropTypes.func, + onFocus: PropTypes.func, + onQueryChange: PropTypes.func, + query: PropTypes.string, + selectedPosition: PropTypes.oneOf(['above', 'below', 'none']), + showSelectedWhenNotInSource: PropTypes.bool, + showSuggestionsWhenValueIsSet: PropTypes.bool, + source: PropTypes.any, + suggestionMatch: PropTypes.oneOf(['disabled', 'start', 'anywhere', 'word']), + theme: PropTypes.shape({ + active: PropTypes.string, + autocomplete: PropTypes.string, + focus: PropTypes.string, + input: PropTypes.string, + suggestion: PropTypes.string, + suggestions: PropTypes.string, + up: PropTypes.string, + value: PropTypes.string, + values: PropTypes.string, + }), + value: PropTypes.any, + }; - static defaultProps = { - allowCreate: false, - className: '', - direction: 'auto', - keepFocusOnChange: false, - multiple: true, - selectedPosition: 'above', - showSelectedWhenNotInSource: false, - showSuggestionsWhenValueIsSet: false, - source: {}, - suggestionMatch: 'start' - }; + static defaultProps = { + allowCreate: false, + className: '', + direction: 'auto', + keepFocusOnChange: false, + multiple: true, + selectedPosition: 'above', + showSelectedWhenNotInSource: false, + showSuggestionsWhenValueIsSet: false, + source: {}, + suggestionMatch: 'start', + }; - state = { - direction: this.props.direction, - focus: false, - showAllSuggestions: this.props.showSuggestionsWhenValueIsSet, - query: this.props.query ? this.props.query : this.query(this.props.value), - isValueAnObject: false - }; + state = { + direction: this.props.direction, + focus: false, + showAllSuggestions: this.props.showSuggestionsWhenValueIsSet, + query: this.props.query ? this.props.query : this.query(this.props.value), + isValueAnObject: false, + }; - componentWillReceiveProps (nextProps) { - if (!this.props.multiple) { - const query = nextProps.query ? nextProps.query : this.query(nextProps.value); - this.updateQuery(query, false); - } - } + componentWillReceiveProps(nextProps) { + if (!this.props.multiple) { + const query = nextProps.query ? nextProps.query : this.query(nextProps.value); + this.updateQuery(query, false); + } + } - shouldComponentUpdate (nextProps, nextState) { - if (!this.state.focus && nextState.focus && this.props.direction === POSITION.AUTO) { - const direction = this.calculateDirection(); - if (this.state.direction !== direction) { - this.setState({ direction }); - } - } - return true; - } + shouldComponentUpdate(nextProps, nextState) { + if (!this.state.focus && nextState.focus && this.props.direction === POSITION.AUTO) { + const direction = this.calculateDirection(); + if (this.state.direction !== direction) { + this.setState({ direction }); + } + } + return true; + } - handleChange = (values, event) => { - const value = this.props.multiple ? values : values[0]; - const { showSuggestionsWhenValueIsSet: showAllSuggestions } = this.props; - const query = this.query(value); - if (this.props.onChange) this.props.onChange(value, event); - if (this.props.keepFocusOnChange) { - this.setState({ query, showAllSuggestions }); - } else { - this.setState({ focus: false, query, showAllSuggestions }, () => { - ReactDOM.findDOMNode(this).querySelector('input').blur(); - }); - } - this.updateQuery(query, this.props.query); - }; + handleChange = (values, event) => { + const value = this.props.multiple ? values : values[0]; + const { showSuggestionsWhenValueIsSet: showAllSuggestions } = this.props; + const query = this.query(value); + if (this.props.onChange) this.props.onChange(value, event); + if (this.props.keepFocusOnChange) { + this.setState({ query, showAllSuggestions }); + } else { + this.setState({ focus: false, query, showAllSuggestions }, () => { + ReactDOM.findDOMNode(this).querySelector('input').blur(); + }); + } + this.updateQuery(query, this.props.query); + }; - handleMouseDown = (event) => { - this.selectOrCreateActiveItem(event); - } + handleMouseDown = (event) => { + this.selectOrCreateActiveItem(event); + } - handleQueryBlur = (event) => { - if (this.state.focus) this.setState({focus: false}); - if (this.props.onBlur) this.props.onBlur(event, this.state.active); - }; + handleQueryBlur = (event) => { + if (this.state.focus) this.setState({ focus: false }); + if (this.props.onBlur) this.props.onBlur(event, this.state.active); + }; - updateQuery = (query, notify) => { - if (notify && this.props.onQueryChange) this.props.onQueryChange(query); - this.setState({ query }); - } + updateQuery = (query, notify) => { + if (notify && this.props.onQueryChange) this.props.onQueryChange(query); + this.setState({ query }); + } - handleQueryChange = (value) => { - const query = this.clearQuery ? '' : value; - this.clearQuery = false; + handleQueryChange = (value) => { + const query = this.clearQuery ? '' : value; + this.clearQuery = false; - this.updateQuery(query, true); - this.setState({showAllSuggestions: false, active: null}); - }; + this.updateQuery(query, true); + this.setState({ showAllSuggestions: false, active: null }); + }; - handleQueryFocus = (event) => { - this.suggestionsNode.scrollTop = 0; - this.setState({active: '', focus: true}); - if (this.props.onFocus) this.props.onFocus(event); - }; + handleQueryFocus = (event) => { + this.suggestionsNode.scrollTop = 0; + this.setState({ active: '', focus: true }); + if (this.props.onFocus) this.props.onFocus(event); + }; - handleQueryKeyDown = (event) => { + handleQueryKeyDown = (event) => { // Mark query for clearing in handleQueryChange when pressing backspace and showing all suggestions. - this.clearQuery = ( + this.clearQuery = ( event.which === 8 && this.props.showSuggestionsWhenValueIsSet && this.state.showAllSuggestions ); - if (event.which === 13) { - this.selectOrCreateActiveItem(event); - } - }; + if (event.which === 13) { + this.selectOrCreateActiveItem(event); + } + }; - handleQueryKeyUp = (event) => { - if (event.which === 27) ReactDOM.findDOMNode(this).querySelector('input').blur(); + handleQueryKeyUp = (event) => { + if (event.which === 27) ReactDOM.findDOMNode(this).querySelector('input').blur(); - if ([40, 38].indexOf(event.which) !== -1) { - const suggestionsKeys = [...this.suggestions().keys()]; - let index = suggestionsKeys.indexOf(this.state.active) + (event.which === 40 ? +1 : -1); - if (index < 0) index = suggestionsKeys.length - 1; - if (index >= suggestionsKeys.length) index = 0; - this.setState({active: suggestionsKeys[index]}); - } - }; + if ([40, 38].indexOf(event.which) !== -1) { + const suggestionsKeys = [...this.suggestions().keys()]; + let index = suggestionsKeys.indexOf(this.state.active) + (event.which === 40 ? +1 : -1); + if (index < 0) index = suggestionsKeys.length - 1; + if (index >= suggestionsKeys.length) index = 0; + this.setState({ active: suggestionsKeys[index] }); + } + }; - handleSuggestionHover = (event) => { - this.setState({active: event.target.id}); - }; + handleSuggestionHover = (event) => { + this.setState({ active: event.target.id }); + }; - calculateDirection () { - if (this.props.direction === 'auto') { - const client = ReactDOM.findDOMNode(this.inputNode).getBoundingClientRect(); - const screen_height = window.innerHeight || document.documentElement.offsetHeight; - const up = client.top > ((screen_height / 2) + client.height); - return up ? 'up' : 'down'; - } else { - return this.props.direction; - } - } + calculateDirection() { + if (this.props.direction === 'auto') { + const client = ReactDOM.findDOMNode(this.inputNode).getBoundingClientRect(); + const screen_height = window.innerHeight || document.documentElement.offsetHeight; + const up = client.top > ((screen_height / 2) + client.height); + return up ? 'up' : 'down'; + } + return this.props.direction; + } - query (key) { + query(key) { let query_value = ''; if (!this.props.multiple && key) { const source_value = this.source().get(`${key}`); - query_value = source_value ? source_value : key; + query_value = source_value || key; } return query_value; - } + } - selectOrCreateActiveItem (event) { - let target = this.state.active; - if (!target) { - target = this.props.allowCreate + selectOrCreateActiveItem(event) { + let target = this.state.active; + if (!target) { + target = this.props.allowCreate ? this.state.query : [...this.suggestions().keys()][0]; - this.setState({active: target}); - } - this.select(event, target); - } + this.setState({ active: target }); + } + this.select(event, target); + } - normalise (value) { + normalise(value) { const sdiak = 'áâäąáâäąččććççĉĉďđďđééěëēėęéěëēėęĝĝğğġġģģĥĥħħíîíîĩĩīīĭĭįįi̇ıĵĵķķĸĺĺļļŀŀłłĺľĺľňńņŋŋņňńʼnóöôőøōōóöőôøřřŕŕŗŗššśśŝŝşşţţťťŧŧũũūūŭŭůůűűúüúüűųųŵŵýyŷŷýyžžźźżżß'; const bdiak = 'AAAAAAAACCCCCCCCDDDDEEEEEEEEEEEEEGGGGGGGGHHHHIIIIIIIIIIIIIIJJKKKLLLLLLLLLLLLNNNNNNNNNOOOOOOOOOOOORRRRRRSSSSSSSSTTTTTTUUUUUUUUUUUUUUUUUWWYYYYYYZZZZZZS'; @@ -209,209 +209,206 @@ const factory = (Chip, Input) => { } return normalised.toLowerCase().trim(); - } + } - suggestions () { - let suggest = new Map(); - const rawQuery = this.state.query || (this.props.multiple ? '' : this.props.value); - const query = this.normalise((`${rawQuery}`)); - const values = this.values(); - const source = this.source(); + suggestions() { + let suggest = new Map(); + const rawQuery = this.state.query || (this.props.multiple ? '' : this.props.value); + const query = this.normalise((`${rawQuery}`)); + const values = this.values(); + const source = this.source(); // Suggest any non-set value which matches the query - if (this.props.multiple) { - for (const [key, value] of source) { - if (!values.has(key) && this.matches(this.normalise(value), query)) { - suggest.set(key, value); - } - } + if (this.props.multiple) { + for (const [key, value] of source) { + if (!values.has(key) && this.matches(this.normalise(value), query)) { + suggest.set(key, value); + } + } // When multiple is false, suggest any value which matches the query if showAllSuggestions is false - } else if (query && !this.state.showAllSuggestions) { - for (const [key, value] of source) { - if (this.matches(this.normalise(value), query)) { - suggest.set(key, value); - } - } + } else if (query && !this.state.showAllSuggestions) { + for (const [key, value] of source) { + if (this.matches(this.normalise(value), query)) { + suggest.set(key, value); + } + } // When multiple is false, suggest all values when showAllSuggestions is true - } else { - suggest = source; - } + } else { + suggest = source; + } - return suggest; - } + return suggest; + } - matches (value, query) { - const { suggestionMatch } = this.props; + matches(value, query) { + const { suggestionMatch } = this.props; - if (suggestionMatch === 'disabled') { - return true; - } else if (suggestionMatch === 'start') { - return value.startsWith(query); - } else if (suggestionMatch === 'anywhere') { - return value.includes(query); - } else if (suggestionMatch === 'word') { - const re = new RegExp(`\\b${query}`, 'g'); - return re.test(value); - } + if (suggestionMatch === 'disabled') { + return true; + } else if (suggestionMatch === 'start') { + return value.startsWith(query); + } else if (suggestionMatch === 'anywhere') { + return value.includes(query); + } else if (suggestionMatch === 'word') { + const re = new RegExp(`\\b${query}`, 'g'); + return re.test(value); + } - return false; - } + return false; + } - source () { - const { source: src } = this.props; - if (src.hasOwnProperty('length')) { - return new Map(src.map((item) => Array.isArray(item) ? [...item] : [item, item])); - } else { - return new Map(Object.keys(src).map((key) => [`${key}`, src[key]])); - } - } + source() { + const { source: src } = this.props; + if (src.hasOwnProperty('length')) { + return new Map(src.map(item => Array.isArray(item) ? [...item] : [item, item])); + } + return new Map(Object.keys(src).map(key => [`${key}`, src[key]])); + } - values () { - let vals = this.props.multiple ? this.props.value : [this.props.value]; + values() { + let vals = this.props.multiple ? this.props.value : [this.props.value]; - if (!vals) vals = []; + if (!vals) vals = []; - if (this.props.showSelectedWhenNotInSource && this.isValueAnObject()) { - return new Map(Object.entries(vals)); - } + if (this.props.showSelectedWhenNotInSource && this.isValueAnObject()) { + return new Map(Object.entries(vals)); + } - const valueMap = new Map(); + const valueMap = new Map(); - const stringVals = vals.map(v => `${v}`); - for (const [k, v] of this.source()) { - if (stringVals.indexOf(k) !== -1) valueMap.set(k, v); - } + const stringVals = vals.map(v => `${v}`); + for (const [k, v] of this.source()) { + if (stringVals.indexOf(k) !== -1) valueMap.set(k, v); + } - return valueMap; - } + return valueMap; + } - select = (event, target) => { - events.pauseEvent(event); - const values = this.values(this.props.value); - const source = this.source(); - const newValue = target === void 0 ? event.target.id : target; + select = (event, target) => { + events.pauseEvent(event); + const values = this.values(this.props.value); + const source = this.source(); + const newValue = target === void 0 ? event.target.id : target; - if (this.isValueAnObject()) { - const newItem = Array.from(source).reduce((obj, [k, value]) => { - if (k === newValue) { - obj[k] = value; - } - return obj; - }, {}); + if (this.isValueAnObject()) { + const newItem = Array.from(source).reduce((obj, [k, value]) => { + if (k === newValue) { + obj[k] = value; + } + return obj; + }, {}); - return this.handleChange(Object.assign(this.mapToObject(values), newItem), event); - } + return this.handleChange(Object.assign(this.mapToObject(values), newItem), event); + } - this.handleChange([newValue, ...values.keys()], event); - }; + this.handleChange([newValue, ...values.keys()], event); + }; - unselect (key, event) { - if (!this.props.disabled) { - const values = this.values(this.props.value); + unselect(key, event) { + if (!this.props.disabled) { + const values = this.values(this.props.value); - values.delete(key); + values.delete(key); - if (this.isValueAnObject()) { - return this.handleChange(this.mapToObject(values), event); - } + if (this.isValueAnObject()) { + return this.handleChange(this.mapToObject(values), event); + } - this.handleChange([...values.keys()], event); - } - } + this.handleChange([...values.keys()], event); + } + } - isValueAnObject () { + isValueAnObject() { return !Array.isArray(this.props.value) && typeof this.props.value === 'object'; - } + } - mapToObject (map) { + mapToObject(map) { return Array.from(map).reduce((obj, [k, value]) => { obj[k] = value; return obj; }, {}); - } + } - renderSelected () { - if (this.props.multiple) { - const selectedItems = [...this.values()].map(([key, value]) => { - return ( - - {value} - - ); - }); + renderSelected() { + if (this.props.multiple) { + const selectedItems = [...this.values()].map(([key, value]) => ( + + {value} + + )); - return ; - } - } + return ; + } + } - renderSuggestions () { - const { theme } = this.props; - const suggestions = [...this.suggestions()].map(([key, value]) => { - const className = classnames(theme.suggestion, {[theme.active]: this.state.active === key}); - return ( -
  • - {value} -
  • - ); - }); + renderSuggestions() { + const { theme } = this.props; + const suggestions = [...this.suggestions()].map(([key, value]) => { + const className = classnames(theme.suggestion, { [theme.active]: this.state.active === key }); + return ( +
  • + {value} +
  • + ); + }); - return ( - - ); - } + return ( + + ); + } - render () { - const { - allowCreate, error, label, source, suggestionMatch, query, //eslint-disable-line no-unused-vars - selectedPosition, keepFocusOnChange, showSuggestionsWhenValueIsSet, showSelectedWhenNotInSource, onQueryChange, //eslint-disable-line no-unused-vars + render() { + const { + allowCreate, error, label, source, suggestionMatch, query, // eslint-disable-line no-unused-vars + selectedPosition, keepFocusOnChange, showSuggestionsWhenValueIsSet, showSelectedWhenNotInSource, onQueryChange, // eslint-disable-line no-unused-vars theme, ...other } = this.props; - const className = classnames(theme.autocomplete, { - [theme.focus]: this.state.focus - }, this.props.className); + const className = classnames(theme.autocomplete, { + [theme.focus]: this.state.focus, + }, this.props.className); - return ( -
    - {this.props.selectedPosition === 'above' ? this.renderSelected() : null} - { this.inputNode = node; }} - autoComplete="off" - className={theme.input} - error={error} - label={label} - onBlur={this.handleQueryBlur} - onChange={this.handleQueryChange} - onFocus={this.handleQueryFocus} - onKeyDown={this.handleQueryKeyDown} - onKeyUp={this.handleQueryKeyUp} - theme={theme} - themeNamespace="input" - value={this.state.query} - /> - {this.renderSuggestions()} - {this.props.selectedPosition === 'below' ? this.renderSelected() : null} -
    - ); - } + return ( +
    + {this.props.selectedPosition === 'above' ? this.renderSelected() : null} + { this.inputNode = node; }} + autoComplete="off" + className={theme.input} + error={error} + label={label} + onBlur={this.handleQueryBlur} + onChange={this.handleQueryChange} + onFocus={this.handleQueryFocus} + onKeyDown={this.handleQueryKeyDown} + onKeyUp={this.handleQueryKeyUp} + theme={theme} + themeNamespace="input" + value={this.state.query} + /> + {this.renderSuggestions()} + {this.props.selectedPosition === 'below' ? this.renderSelected() : null} +
    + ); + } } return Autocomplete; diff --git a/components/autocomplete/index.js b/components/autocomplete/index.js index 1f0842ed..a0fa86cb 100644 --- a/components/autocomplete/index.js +++ b/components/autocomplete/index.js @@ -1,8 +1,8 @@ -import { AUTOCOMPLETE } from '../identifiers.js'; import { themr } from 'react-css-themr'; -import { autocompleteFactory } from './Autocomplete.js'; -import Chip from '../chip'; -import Input from '../input'; +import { AUTOCOMPLETE } from '../identifiers'; +import { autocompleteFactory } from './Autocomplete'; +import { Chip } from '../chip'; +import { Input } from '../input'; import theme from './theme.css'; const Autocomplete = autocompleteFactory(Chip, Input); diff --git a/components/avatar/Avatar.js b/components/avatar/Avatar.js index 7579b35a..e73ebe99 100644 --- a/components/avatar/Avatar.js +++ b/components/avatar/Avatar.js @@ -1,14 +1,14 @@ import React, { PropTypes } from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; -import { AVATAR } from '../identifiers.js'; -import InjectFontIcon from '../font_icon/FontIcon.js'; +import { AVATAR } from '../identifiers'; +import InjectFontIcon from '../font_icon/FontIcon'; const factory = (FontIcon) => { - const Avatar = ({alt, children, className, cover, icon, image, theme, title, ...other}) => ( -
    + const Avatar = ({ alt, children, className, cover, icon, image, theme, title, ...other }) => ( +
    {children} - {cover && typeof image === 'string' && } + {cover && typeof image === 'string' && } {!cover && (typeof image === 'string' ? {alt} : image)} {typeof icon === 'string' ? : icon} {title ? {title[0]} : null} @@ -25,14 +25,14 @@ const factory = (FontIcon) => { theme: PropTypes.shape({ avatar: PropTypes.string, image: PropTypes.string, - letter: PropTypes.string + letter: PropTypes.string, }), - title: PropTypes.string + title: PropTypes.string, }; Avatar.defaultProps = { alt: '', - cover: false + cover: false, }; return Avatar; diff --git a/components/avatar/index.js b/components/avatar/index.js index 6b2896bc..1bb9d9bc 100644 --- a/components/avatar/index.js +++ b/components/avatar/index.js @@ -1,7 +1,7 @@ -import { AVATAR } from '../identifiers.js'; import { themr } from 'react-css-themr'; -import { avatarFactory } from './Avatar.js'; -import FontIcon from '../font_icon/FontIcon.js'; +import { AVATAR } from '../identifiers'; +import { avatarFactory } from './Avatar'; +import { FontIcon } from '../font_icon/FontIcon'; import theme from './theme.css'; const Avatar = avatarFactory(FontIcon); diff --git a/components/button/BrowseButton.js b/components/button/BrowseButton.js index 50d17d73..199b27c6 100644 --- a/components/button/BrowseButton.js +++ b/components/button/BrowseButton.js @@ -1,9 +1,9 @@ import React, { Component, PropTypes } from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; -import { BUTTON } from '../identifiers.js'; -import InjectFontIcon from '../font_icon/FontIcon.js'; -import rippleFactory from '../ripple/Ripple.js'; +import { BUTTON } from '../identifiers'; +import InjectFontIcon from '../font_icon/FontIcon'; +import rippleFactory from '../ripple/Ripple'; const factory = (ripple, FontIcon) => { class SimpleBrowseButton extends Component { @@ -16,7 +16,7 @@ const factory = (ripple, FontIcon) => { floating: PropTypes.bool, icon: PropTypes.oneOfType([ PropTypes.string, - PropTypes.element + PropTypes.element, ]), inverse: PropTypes.bool, label: PropTypes.string, @@ -39,9 +39,9 @@ const factory = (ripple, FontIcon) => { primary: PropTypes.string, raised: PropTypes.string, rippleWrapper: PropTypes.string, - toggle: PropTypes.string + toggle: PropTypes.string, }), - type: PropTypes.string + type: PropTypes.string, }; static defaultProps = { @@ -52,16 +52,28 @@ const factory = (ripple, FontIcon) => { mini: false, neutral: true, primary: false, - raised: false + raised: false, }; + getLevel = () => { + if (this.props.primary) return 'primary'; + if (this.props.accent) return 'accent'; + return 'neutral'; + } + + getShape = () => { + if (this.props.raised) return 'raised'; + if (this.props.floating) return 'floating'; + return 'flat'; + } + handleMouseUp = (event) => { - this.refs.label.blur(); + this.labelNode.blur(); if (this.props.onMouseUp) this.props.onMouseUp(event); }; handleMouseLeave = (event) => { - this.refs.label.blur(); + this.labelNode.blur(); if (this.props.onMouseLeave) this.props.onMouseLeave(event); }; @@ -69,34 +81,48 @@ const factory = (ripple, FontIcon) => { if (this.props.onChange) this.props.onChange(event); }; - render () { - const { accent, children, className, flat, floating, icon, - inverse, label, mini, neutral, primary, theme, raised, ...others} = this.props; - const element = 'label'; - const level = primary ? 'primary' : accent ? 'accent' : 'neutral'; - const shape = flat ? 'flat' : raised ? 'raised' : floating ? 'floating' : 'flat'; + render() { + const { + accent, // eslint-disable-line + children, + className, + flat, // eslint-disable-line + floating, // eslint-disable-line + icon, + inverse, + label, + mini, + neutral, + primary, // eslint-disable-line + raised, // eslint-disable-line + theme, + ...others + } = this.props; + const element = 'label'; + const level = this.getLevel(); + const shape = this.getShape(); - const classes = classnames(theme.button, [theme[shape]], { - [theme[level]]: neutral, - [theme.mini]: mini, - [theme.inverse]: inverse - }, className); + const classes = classnames(theme.button, [theme[shape]], { + [theme[level]]: neutral, + [theme.mini]: mini, + [theme.inverse]: inverse, + }, className); - const props = { - ...others, - ref: 'label', - className: classes, - disabled: this.props.disabled, - onMouseUp: this.handleMouseUp, - onMouseLeave: this.handleMouseLeave, - 'data-react-toolbox': 'label' - }; + const props = { + ...others, + ref: (node) => { this.labelNode = node; }, + className: classes, + disabled: this.props.disabled, + onMouseUp: this.handleMouseUp, + onMouseLeave: this.handleMouseLeave, + 'data-react-toolbox': 'label', + }; - return React.createElement(element, props, - icon ? : null, - {label}, - , - children + return React.createElement(element, props, + icon ? : null, + {label}, + , + children, ); } } diff --git a/components/button/Button.js b/components/button/Button.js index 3ffc90aa..5584e3ff 100644 --- a/components/button/Button.js +++ b/components/button/Button.js @@ -1,9 +1,9 @@ import React, { Component, PropTypes } from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; -import { BUTTON } from '../identifiers.js'; -import InjectFontIcon from '../font_icon/FontIcon.js'; -import rippleFactory from '../ripple/Ripple.js'; +import { BUTTON } from '../identifiers'; +import InjectFontIcon from '../font_icon/FontIcon'; +import rippleFactory from '../ripple/Ripple'; const factory = (ripple, FontIcon) => { class Button extends Component { @@ -17,7 +17,7 @@ const factory = (ripple, FontIcon) => { href: PropTypes.string, icon: PropTypes.oneOfType([ PropTypes.string, - PropTypes.element + PropTypes.element, ]), inverse: PropTypes.bool, label: PropTypes.string, @@ -39,9 +39,9 @@ const factory = (ripple, FontIcon) => { primary: PropTypes.string, raised: PropTypes.string, rippleWrapper: PropTypes.string, - toggle: PropTypes.string + toggle: PropTypes.string, }), - type: PropTypes.string + type: PropTypes.string, }; static defaultProps = { @@ -53,48 +53,76 @@ const factory = (ripple, FontIcon) => { neutral: true, primary: false, raised: false, - type: 'button' + type: 'button', }; + getLevel = () => { + if (this.props.primary) return 'primary'; + if (this.props.accent) return 'accent'; + return 'neutral'; + } + + getShape = () => { + if (this.props.raised) return 'raised'; + if (this.props.floating) return 'floating'; + return 'flat'; + } + handleMouseUp = (event) => { - this.refs.button.blur(); + this.buttonNode.blur(); if (this.props.onMouseUp) this.props.onMouseUp(event); }; handleMouseLeave = (event) => { - this.refs.button.blur(); + this.buttonNode.blur(); if (this.props.onMouseLeave) this.props.onMouseLeave(event); }; - render () { - const { accent, children, className, flat, floating, href, icon, - inverse, label, mini, neutral, primary, theme, type, raised, ...others} = this.props; + render() { + const { + accent, // eslint-disable-line + children, + className, + flat, // eslint-disable-line + floating, // eslint-disable-line + href, + icon, + inverse, + label, + mini, + neutral, + primary, // eslint-disable-line + raised, // eslint-disable-line + theme, + type, + ...others + } = this.props; const element = href ? 'a' : 'button'; - const level = primary ? 'primary' : accent ? 'accent' : 'neutral'; - const shape = flat ? 'flat' : raised ? 'raised' : floating ? 'floating' : 'flat'; + const level = this.getLevel(); + const shape = this.getShape(); const classes = classnames(theme.button, [theme[shape]], { [theme[level]]: neutral, [theme.mini]: mini, - [theme.inverse]: inverse + [theme.inverse]: inverse, }, className); const props = { ...others, href, - ref: 'button', + ref: (node) => { this.buttonNode = node; }, className: classes, disabled: this.props.disabled, onMouseUp: this.handleMouseUp, onMouseLeave: this.handleMouseLeave, type: !href ? type : null, - 'data-react-toolbox': 'button' + 'data-react-toolbox': 'button', }; return React.createElement(element, props, - icon ? : null, + icon ? : null, label, - children + children, ); } } diff --git a/components/button/IconButton.js b/components/button/IconButton.js index d0cec6eb..14992756 100644 --- a/components/button/IconButton.js +++ b/components/button/IconButton.js @@ -1,9 +1,9 @@ import React, { Component, PropTypes } from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; -import { BUTTON } from '../identifiers.js'; -import InjectFontIcon from '../font_icon/FontIcon.js'; -import rippleFactory from '../ripple/Ripple.js'; +import { BUTTON } from '../identifiers'; +import InjectFontIcon from '../font_icon/FontIcon'; +import rippleFactory from '../ripple/Ripple'; const factory = (ripple, FontIcon) => { class IconButton extends Component { @@ -15,15 +15,28 @@ const factory = (ripple, FontIcon) => { href: PropTypes.string, icon: PropTypes.oneOfType([ PropTypes.string, - PropTypes.element + PropTypes.element, ]), inverse: PropTypes.bool, neutral: PropTypes.bool, onMouseLeave: PropTypes.func, onMouseUp: PropTypes.func, primary: PropTypes.bool, - theme: PropTypes.object, - type: PropTypes.string + theme: PropTypes.shape({ + accent: PropTypes.string, + button: PropTypes.string, + flat: PropTypes.string, + floating: PropTypes.string, + icon: PropTypes.string, + inverse: PropTypes.string, + mini: PropTypes.string, + neutral: PropTypes.string, + primary: PropTypes.string, + raised: PropTypes.string, + rippleWrapper: PropTypes.string, + toggle: PropTypes.string, + }), + type: PropTypes.string, }; static defaultProps = { @@ -31,44 +44,65 @@ const factory = (ripple, FontIcon) => { className: '', neutral: true, primary: false, - type: 'button' + type: 'button', }; + getLevel = () => { + if (this.props.primary) return 'primary'; + if (this.props.accent) return 'accent'; + return 'neutral'; + } + handleMouseUp = (event) => { - this.refs.button.blur(); + this.buttonNode.blur(); if (this.props.onMouseUp) this.props.onMouseUp(event); }; handleMouseLeave = (event) => { - this.refs.button.blur(); + this.buttonNode.blur(); if (this.props.onMouseLeave) this.props.onMouseLeave(event); }; - render () { - const {accent, children, className, href, icon, inverse, neutral, - primary, theme, type, ...others} = this.props; + render() { + const { + accent, // eslint-disable-line + children, + className, + href, + icon, + inverse, + neutral, + primary, // eslint-disable-line + theme, + type, + ...others + } = this.props; const element = href ? 'a' : 'button'; - const level = primary ? 'primary' : accent ? 'accent' : 'neutral'; + const level = this.getLevel(); const classes = classnames([theme.toggle], { [theme[level]]: neutral, - [theme.inverse]: inverse + [theme.inverse]: inverse, }, className); const props = { ...others, href, - ref: 'button', + ref: (node) => { this.buttonNode = node; }, className: classes, disabled: this.props.disabled, onMouseUp: this.handleMouseUp, onMouseLeave: this.handleMouseLeave, type: !href ? type : null, - 'data-react-toolbox': 'button' + 'data-react-toolbox': 'button', }; + const iconElement = typeof icon === 'string' + ? + : icon; + return React.createElement(element, props, - icon ? typeof icon === 'string' ? : icon : null, - children + icon && iconElement, + children, ); } } @@ -76,7 +110,7 @@ const factory = (ripple, FontIcon) => { return ripple(IconButton); }; -const IconButton = factory(rippleFactory({centered: true}), InjectFontIcon); +const IconButton = factory(rippleFactory({ centered: true }), InjectFontIcon); export default themr(BUTTON)(IconButton); export { factory as iconButtonFactory }; export { IconButton }; diff --git a/components/button/__test__/index.spec.js b/components/button/__test__/index.spec.js index e217195d..1e83db91 100644 --- a/components/button/__test__/index.spec.js +++ b/components/button/__test__/index.spec.js @@ -1,3 +1,4 @@ +/* eslint-disable */ import expect from 'expect'; import React from 'react'; import ReactDOM from 'react-dom'; @@ -10,23 +11,23 @@ const getRenderedClassName = (tree, Component) => { return ReactDOM.findDOMNode(rendered).getAttribute('class'); }; -describe('Button', function () { - describe('#render', function () { - it('uses flat and neutral styles by default', function () { +describe('Button', () => { + describe('#render', () => { + it('uses flat and neutral styles by default', () => { const tree = TestUtils.renderIntoDocument(
    ); @@ -154,30 +169,22 @@ const factory = (Input) => { const { theme } = this.props; const className = classnames({ [theme.selected]: item.value === this.props.value, - [theme.disabled]: item.disabled + [theme.disabled]: item.disabled, }); return ( -
  • +
  • {this.props.template ? this.props.template(item) : item.label}
  • ); }; - handleFocus = event => { - event.stopPropagation(); - if (!this.props.disabled) this.open(event); - if (this.props.onFocus) this.props.onFocus(event); - }; - - handleBlur = event => { - event.stopPropagation(); - if (this.state.active) this.close(); - if (this.props.onBlur) this.props.onBlur(event); - } - - render () { + render() { const { - allowBlank, auto, required, onChange, onFocus, onBlur, //eslint-disable-line no-unused-vars + allowBlank, auto, required, onChange, onFocus, onBlur, // eslint-disable-line no-unused-vars source, template, theme, ...others } = this.props; const selected = this.getSelectedItem(); @@ -185,13 +192,13 @@ const factory = (Input) => { [theme.up]: this.state.up, [theme.active]: this.state.active, [theme.disabled]: this.props.disabled, - [theme.required]: this.props.required + [theme.required]: this.props.required, }, this.props.className); return (
    @@ -202,14 +209,14 @@ const factory = (Input) => { onClick={this.handleClick} required={this.props.required} readOnly - ref={node => { this.inputNode = node && node.getWrappedInstance(); }} + ref={(node) => { this.inputNode = node && node.getWrappedInstance(); }} type={template && selected ? 'hidden' : null} theme={theme} themeNamespace="input" value={selected && selected.label ? selected.label : ''} /> - {template && selected ? this.renderTemplateValue(selected) : null} -
    diff --git a/components/dropdown/__test__/index.spec.js b/components/dropdown/__test__/index.spec.js index f47e8cd8..a5c1558a 100644 --- a/components/dropdown/__test__/index.spec.js +++ b/components/dropdown/__test__/index.spec.js @@ -1,29 +1,30 @@ +/* eslint-disable */ import expect from 'expect'; import React from 'react'; import { renderIntoDocument, scryRenderedDOMComponentsWithClass, - Simulate + Simulate, } from 'react-addons-test-utils'; import sinon from 'sinon'; import theme from '../theme.css'; import Dropdown from '../Dropdown'; -describe('Dropdown', function () { - describe('#renderValue', function () { +describe('Dropdown', () => { + describe('#renderValue', () => { const source = [ { value: 'EN-gb', label: 'England' }, { value: 'ES-es', label: 'Spain', disabled: true }, { value: 'TH-th', label: 'Thailand', disabled: true }, - { value: 'EN-en', label: 'USA'} + { value: 'EN-en', label: 'USA' }, ]; - it('renders dropdown item with disabled style', function () { + it('renders dropdown item with disabled style', () => { const tree = renderIntoDocument(); const disabled = scryRenderedDOMComponentsWithClass(tree, theme.disabled); expect(disabled.length).toEqual(2); }); - it('does not call onChange callback when disabled dorpdown item is clicked', function () { + it('does not call onChange callback when disabled dorpdown item is clicked', () => { const spy = sinon.spy(); const tree = renderIntoDocument( ( // eslint-disable-line @@ -15,18 +15,18 @@ const FontIcon = ({ alt, children, className, theme, value, ...other}) => ( // e FontIcon.propTypes = { alt: PropTypes.string, - children: PropTypes.any, + children: PropTypes.node, className: PropTypes.string, - theme: PropTypes.object, + theme: PropTypes.object, // eslint-disable-line value: PropTypes.oneOfType([ PropTypes.string, - PropTypes.element - ]) + PropTypes.element, + ]), }; FontIcon.defaultProps = { alt: '', - className: '' + className: '', }; export default FontIcon; diff --git a/components/font_icon/index.js b/components/font_icon/index.js index 726aec89..15ace6be 100644 --- a/components/font_icon/index.js +++ b/components/font_icon/index.js @@ -1,4 +1,4 @@ -import FontIcon from './FontIcon.js'; +import { FontIcon } from './FontIcon'; export default FontIcon; export { FontIcon }; diff --git a/components/form/Form.js b/components/form/Form.js deleted file mode 100644 index 3f313399..00000000 --- a/components/form/Form.js +++ /dev/null @@ -1,86 +0,0 @@ -import React, { Component, PropTypes } from 'react'; -import InjectAutocomplete from '../autocomplete/Autocomplete.js'; -import InjectButton from '../button/Button.js'; -import InjectCheckbox from '../checkbox/Checkbox.js'; -import InjectDatePicker from '../date_picker/DatePicker.js'; -import InjectDropdown from '../dropdown/Dropdown.js'; -import InjectInput from '../input/Input.js'; -import InjectRadioGroup from '../radio/RadioGroup.js'; -import InjectSlider from '../slider/Slider.js'; -import InjectSwitch from '../switch/Switch.js'; -import InjectTimePicker from '../time_picker/TimePicker.js'; - -const factory = ( - Autocomplete, Button, Checkbox, DatePicker, Dropdown, - Input, RadioGroup, Slider, Switch, TimePicker - ) => { - - const COMPONENTS = { - 'autocomplete': Autocomplete, - 'button': Button, - 'checkbox': Checkbox, - 'datepicker': DatePicker, - 'dropdown': Dropdown, - 'input': Input, - 'radioGroup': RadioGroup, - 'slider': Slider, - 'switch': Switch, - 'timepicker': TimePicker - }; - - class Form extends Component { - static propTypes = { - attributes: PropTypes.array, - children: PropTypes.node, - className: PropTypes.string, - model: PropTypes.object, - onChange: PropTypes.func, - onError: PropTypes.func, - onSubmit: PropTypes.func, - onValid: PropTypes.func, - storage: PropTypes.string - }; - - static defaultProps = { - attributes: [], - className: '' - }; - - onSubmit = (event) => { - event.preventDefault(); - if (this.props.onSubmit) this.props.onSubmit(event); - }; - - onChange = (field, value, event) => { - if (this.props.onChange) this.props.onChange(field, value, event); - }; - - renderFields () { - return Object.keys(this.props.model).map((field, index) => { - const properties = this.props.model[field]; - const Field = COMPONENTS[properties.kind.toLowerCase()]; - return ; - }); - } - - render () { - return ( -
    - {this.renderFields()} - {this.props.children} -
    - ); - } - } - - return Form; -}; - -const Form = factory( - InjectAutocomplete, InjectButton, InjectCheckbox, InjectDatePicker, InjectDropdown, - InjectInput, InjectRadioGroup, InjectSlider, InjectSwitch, InjectTimePicker -); - -export default Form; -export { factory as formFactory }; -export { Form }; diff --git a/components/form/index.js b/components/form/index.js deleted file mode 100644 index 7ae8c7f4..00000000 --- a/components/form/index.js +++ /dev/null @@ -1,19 +0,0 @@ -import { formFactory } from './Form.js'; -import Autocomplete from '../autocomplete'; -import Button from '../button'; -import Checkbox from '../checkbox'; -import DatePicker from '../date_picker'; -import Dropdown from '../dropdown'; -import Input from '../input'; -import RadioGroup from '../radio'; -import Slider from '../slider'; -import Switch from '../switch'; -import TimePicker from '../time_picker'; - -const ThemedForm = formFactory( - Autocomplete, Button, Checkbox, DatePicker, Dropdown, - Input, RadioGroup, Slider, Switch, TimePicker -); - -export default ThemedForm; -export { ThemedForm as Form }; diff --git a/components/form/readme.md b/components/form/readme.md deleted file mode 100644 index a26b1238..00000000 --- a/components/form/readme.md +++ /dev/null @@ -1,24 +0,0 @@ -# Form - -``` -var Form = require('react-toolbox/components/form'); -var fields : [ - {ref: "name", label: "Your Name", required: true, storage: true}, - {ref: "description", multiline: true, label: "Description", value: "Doer"}, - {ref: "birthdate", type: "date", label: "Birthdate"} -] - -
    -``` - -## Properties - -| Name | Type | Default | Description| -|:- |:-: | :- |:-| -| **attributes** | array | | Array of fields you want hold, fields can be instances of ,
    ); diff --git a/components/snackbar/index.js b/components/snackbar/index.js index e2e4ea03..d812ec1b 100644 --- a/components/snackbar/index.js +++ b/components/snackbar/index.js @@ -1,6 +1,6 @@ import { themr } from 'react-css-themr'; -import { SNACKBAR } from '../identifiers.js'; -import { snackbarFactory } from './Snackbar.js'; +import { SNACKBAR } from '../identifiers'; +import { snackbarFactory } from './Snackbar'; import { Button } from '../button'; import theme from './theme.css'; diff --git a/components/switch/Switch.js b/components/switch/Switch.js index 0262d919..cdbcb909 100644 --- a/components/switch/Switch.js +++ b/components/switch/Switch.js @@ -1,9 +1,9 @@ import React, { Component, PropTypes } from 'react'; import classnames from 'classnames'; import { themr } from 'react-css-themr'; -import { SWITCH } from '../identifiers.js'; -import rippleFactory from '../ripple/Ripple.js'; -import thumbFactory from './Thumb.js'; +import { SWITCH } from '../identifiers'; +import rippleFactory from '../ripple/Ripple'; +import thumbFactory from './Thumb'; const factory = (Thumb) => { class Switch extends Component { @@ -25,14 +25,14 @@ const factory = (Thumb) => { on: PropTypes.string, ripple: PropTypes.string, text: PropTypes.string, - thumb: PropTypes.string - }) + thumb: PropTypes.string, + }), }; static defaultProps = { checked: false, className: '', - disabled: false + disabled: false, }; handleToggle = (event) => { @@ -42,27 +42,35 @@ const factory = (Thumb) => { } }; - blur () { - this.refs.input.blur(); + blur() { + this.inputNode.blur(); } - focus () { - this.refs.input.focus(); + focus() { + this.inputNode.focus(); } - render () { - const { className, checked, ripple, disabled, onChange, theme, ...others } = this.props; //eslint-disable-line no-unused-vars + render() { + const { + checked, + className, + disabled, + onChange, // eslint-disable-line no-unused-vars + ripple, + theme, + ...others + } = this.props; const _className = classnames(theme[disabled ? 'disabled' : 'field'], className); return ( -