Align tag inputs with other input boxes (#2965)
* Wrap tag input component * Postcss nested selectors * Chips has same size as in ui * Input matches with sizes/paddings of others * Adjust colours, move hint text * Added ChipInput from search in wrapper * Using InputChip Wrapper in search (#2965)
This commit is contained in:
		
							parent
							
								
									04432b2766
								
							
						
					
					
						commit
						381af547fa
					
				| @ -92,6 +92,7 @@ | |||||||
|     "nock": "^8.0.0", |     "nock": "^8.0.0", | ||||||
|     "postcss-import": "^8.1.2", |     "postcss-import": "^8.1.2", | ||||||
|     "postcss-loader": "^0.8.1", |     "postcss-loader": "^0.8.1", | ||||||
|  |     "postcss-nested": "^1.0.0", | ||||||
|     "postcss-simple-vars": "^3.0.0", |     "postcss-simple-vars": "^3.0.0", | ||||||
|     "react-addons-test-utils": "^15.3.0", |     "react-addons-test-utils": "^15.3.0", | ||||||
|     "react-copy-to-clipboard": "^4.2.3", |     "react-copy-to-clipboard": "^4.2.3", | ||||||
|  | |||||||
| @ -17,10 +17,8 @@ | |||||||
| import React, { Component, PropTypes } from 'react'; | import React, { Component, PropTypes } from 'react'; | ||||||
| import ContentClear from 'material-ui/svg-icons/content/clear'; | import ContentClear from 'material-ui/svg-icons/content/clear'; | ||||||
| import ContentSave from 'material-ui/svg-icons/content/save'; | import ContentSave from 'material-ui/svg-icons/content/save'; | ||||||
| // import ChipInput from 'material-ui-chip-input';
 |  | ||||||
| import ChipInput from 'material-ui-chip-input/src/ChipInput'; |  | ||||||
| 
 | 
 | ||||||
| import { Button, Form, Input, Modal } from '../../ui'; | import { Button, Form, Input, InputChip, Modal } from '../../ui'; | ||||||
| import { validateName } from '../../util/validation'; | import { validateName } from '../../util/validation'; | ||||||
| 
 | 
 | ||||||
| export default class EditMeta extends Component { | export default class EditMeta extends Component { | ||||||
| @ -104,53 +102,20 @@ export default class EditMeta extends Component { | |||||||
|     const { tags } = meta || []; |     const { tags } = meta || []; | ||||||
| 
 | 
 | ||||||
|     return ( |     return ( | ||||||
|       <ChipInput |       <InputChip | ||||||
|         ref='tagsInput' |         tokens={ tags } | ||||||
|         value={ tags } |         onTokensChange={ this.onTagsChange } | ||||||
|         onRequestAdd={ this.onAddTag } |         label='(optional) tags' | ||||||
|         onRequestDelete={ this.onDeleteTag } |         hint='press <Enter> to add a tag' | ||||||
|         floatingLabelText='(optional) tags' |         clearOnBlur | ||||||
|         hintText='press <Enter> to add a tag' |  | ||||||
|         onUpdateInput={ this.onTagsInputChange } |  | ||||||
|         floatingLabelFixed |  | ||||||
|         fullWidth |  | ||||||
|       /> |       /> | ||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   onAddTag = (tag) => { |   onTagsChange = (newTags) => { | ||||||
|     const { meta } = this.state; |  | ||||||
|     const { tags } = meta || []; |  | ||||||
| 
 |  | ||||||
|     this.onMetaChange('tags', [].concat(tags, tag)); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   onDeleteTag = (tag) => { |  | ||||||
|     const { meta } = this.state; |  | ||||||
|     const { tags } = meta || []; |  | ||||||
| 
 |  | ||||||
|     const newTags = tags |  | ||||||
|       .filter(t => t !== tag); |  | ||||||
| 
 |  | ||||||
|     this.onMetaChange('tags', newTags); |     this.onMetaChange('tags', newTags); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   onTagsInputChange = (value) => { |  | ||||||
|     const { meta } = this.state; |  | ||||||
|     const { tags = [] } = meta; |  | ||||||
| 
 |  | ||||||
|     const tokens = value.split(/[\s,;]+/); |  | ||||||
| 
 |  | ||||||
|     const newTokens = tokens |  | ||||||
|       .slice(0, -1) |  | ||||||
|       .filter(t => t.length > 0); |  | ||||||
| 
 |  | ||||||
|     const inputValue = tokens.slice(-1)[0].trim(); |  | ||||||
| 
 |  | ||||||
|     this.onMetaChange('tags', [].concat(tags, newTokens)); |  | ||||||
|     this.refs.tagsInput.setState({ inputValue }); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   onNameChange = (name) => { |   onNameChange = (name) => { | ||||||
|     this.setState(validateName(name)); |     this.setState(validateName(name)); | ||||||
|   } |   } | ||||||
|  | |||||||
| @ -41,11 +41,3 @@ | |||||||
|   width: 0; |   width: 0; | ||||||
|   height: 0; |   height: 0; | ||||||
| } | } | ||||||
| 
 |  | ||||||
| .chip > svg { |  | ||||||
|   width: 1.2rem !important; |  | ||||||
|   height: 1.2rem !important; |  | ||||||
|   margin: initial !important; |  | ||||||
|   margin-right: 4px !important; |  | ||||||
|   padding: 4px 0 !important; |  | ||||||
| } |  | ||||||
|  | |||||||
| @ -15,14 +15,9 @@ | |||||||
| // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
| 
 | 
 | ||||||
| import React, { Component, PropTypes } from 'react'; | import React, { Component, PropTypes } from 'react'; | ||||||
| import { Chip } from 'material-ui'; |  | ||||||
| import { blue300 } from 'material-ui/styles/colors'; |  | ||||||
| // import ChipInput from 'material-ui-chip-input';
 |  | ||||||
| import ChipInput from 'material-ui-chip-input/src/ChipInput'; |  | ||||||
| import ActionSearch from 'material-ui/svg-icons/action/search'; | import ActionSearch from 'material-ui/svg-icons/action/search'; | ||||||
| import { uniq } from 'lodash'; |  | ||||||
| 
 | 
 | ||||||
| import { Button } from '../../'; | import { Button, InputChip } from '../../'; | ||||||
| 
 | 
 | ||||||
| import styles from './search.css'; | import styles from './search.css'; | ||||||
| 
 | 
 | ||||||
| @ -74,28 +69,14 @@ export default class ActionbarSearch extends Component { | |||||||
|         className={ styles.searchcontainer } |         className={ styles.searchcontainer } | ||||||
|         key='searchAccount'> |         key='searchAccount'> | ||||||
|         <div className={ inputContainerClasses.join(' ') }> |         <div className={ inputContainerClasses.join(' ') }> | ||||||
|           <ChipInput |           <InputChip | ||||||
|             clearOnBlur={ false } |  | ||||||
|             className={ styles.input } |             className={ styles.input } | ||||||
|             chipRenderer={ this.chipRenderer } |             hint='Enter search input...' | ||||||
|             hintText='Enter search input...' |             tokens={ tokens } | ||||||
|             ref='searchInput' | 
 | ||||||
|             value={ tokens } |  | ||||||
|             onBlur={ this.handleSearchBlur } |             onBlur={ this.handleSearchBlur } | ||||||
|             onRequestAdd={ this.handleTokenAdd } |             onInputChange={ this.handleInputChange } | ||||||
|             onRequestDelete={ this.handleTokenDelete } |             onTokensChange={ this.handleTokensChange } | ||||||
|             onUpdateInput={ this.handleInputChange } |  | ||||||
|             hintStyle={ { |  | ||||||
|               bottom: 16, |  | ||||||
|               left: 2, |  | ||||||
|               transition: 'none' |  | ||||||
|             } } |  | ||||||
|             inputStyle={ { |  | ||||||
|               marginBottom: 18 |  | ||||||
|             } } |  | ||||||
|             textFieldStyle={ { |  | ||||||
|               height: 42 |  | ||||||
|             } } |  | ||||||
|           /> |           /> | ||||||
|         </div> |         </div> | ||||||
| 
 | 
 | ||||||
| @ -108,72 +89,13 @@ export default class ActionbarSearch extends Component { | |||||||
|     ); |     ); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   chipRenderer = (state, key) => { |   handleTokensChange = (tokens) => { | ||||||
|     const { value, isFocused, isDisabled, handleClick, handleRequestDelete } = state; |     this.handleSearchChange(tokens); | ||||||
| 
 |  | ||||||
|     return ( |  | ||||||
|       <Chip |  | ||||||
|         key={ key } |  | ||||||
|         className={ styles.chip } |  | ||||||
|         style={ { |  | ||||||
|           margin: '8px 8px 0 0', |  | ||||||
|           float: 'left', |  | ||||||
|           pointerEvents: isDisabled ? 'none' : undefined, |  | ||||||
|           alignItems: 'center' |  | ||||||
|         } } |  | ||||||
|         labelStyle={ { |  | ||||||
|           paddingRight: 6, |  | ||||||
|           fontSize: '0.9rem', |  | ||||||
|           lineHeight: 'initial' |  | ||||||
|         } } |  | ||||||
|         backgroundColor={ isFocused ? blue300 : 'rgba(0, 0, 0, 0.73)' } |  | ||||||
|         onTouchTap={ handleClick } |  | ||||||
|         onRequestDelete={ handleRequestDelete } |  | ||||||
|       > |  | ||||||
|         { value } |  | ||||||
|       </Chip> |  | ||||||
|     ); |  | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleTokenAdd = (value) => { |   handleInputChange = (inputValue) => { | ||||||
|     const { tokens } = this.props; |  | ||||||
|     const { inputValue } = this.state; |  | ||||||
| 
 |  | ||||||
|     const newSearchTokens = uniq([].concat(tokens, value)); |  | ||||||
| 
 |  | ||||||
|     this.setState({ |  | ||||||
|       inputValue: inputValue === value ? '' : inputValue |  | ||||||
|     }, () => { |  | ||||||
|       this.handleSearchChange(newSearchTokens); |  | ||||||
|     }); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   handleTokenDelete = (value) => { |  | ||||||
|     const { tokens } = this.props; |  | ||||||
| 
 |  | ||||||
|     const newSearchTokens = [] |  | ||||||
|       .concat(tokens) |  | ||||||
|       .filter(v => v !== value); |  | ||||||
| 
 |  | ||||||
|     this.handleSearchChange(newSearchTokens); |  | ||||||
|     this.refs.searchInput.focus(); |  | ||||||
|   } |  | ||||||
| 
 |  | ||||||
|   handleInputChange = (value) => { |  | ||||||
|     const splitTokens = value.split(/[\s,;]/); |  | ||||||
| 
 |  | ||||||
|     const inputValue = (splitTokens.length <= 1) |  | ||||||
|       ? value |  | ||||||
|       : splitTokens.slice(-1)[0].trim(); |  | ||||||
| 
 |  | ||||||
|     this.refs.searchInput.setState({ inputValue }); |  | ||||||
|     this.setState({ inputValue }, () => { |     this.setState({ inputValue }, () => { | ||||||
|       if (splitTokens.length > 1) { |       this.handleSearchChange(); | ||||||
|         const tokensToAdd = splitTokens.slice(0, -1); |  | ||||||
|         tokensToAdd.forEach(token => this.handleTokenAdd(token)); |  | ||||||
|       } else { |  | ||||||
|         this.handleSearchChange(); |  | ||||||
|       } |  | ||||||
|     }); |     }); | ||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
| @ -182,12 +104,10 @@ export default class ActionbarSearch extends Component { | |||||||
|     const { inputValue } = this.state; |     const { inputValue } = this.state; | ||||||
| 
 | 
 | ||||||
|     const newSearchTokens = [] |     const newSearchTokens = [] | ||||||
|       .concat(searchTokens || tokens) |       .concat(searchTokens || tokens); | ||||||
|       .filter(v => v.length > 0); |  | ||||||
| 
 | 
 | ||||||
|     const newSearchValues = [] |     const newSearchValues = [] | ||||||
|       .concat(searchTokens || tokens, inputValue) |       .concat(searchTokens || tokens, inputValue); | ||||||
|       .filter(v => v.length > 0); |  | ||||||
| 
 | 
 | ||||||
|     onChange(newSearchTokens, newSearchValues); |     onChange(newSearchTokens, newSearchValues); | ||||||
|   } |   } | ||||||
| @ -214,19 +134,15 @@ export default class ActionbarSearch extends Component { | |||||||
|   } |   } | ||||||
| 
 | 
 | ||||||
|   handleOpenSearch = (showSearch, force) => { |   handleOpenSearch = (showSearch, force) => { | ||||||
|     if (this.state.stateChanging && !force) return false; |     if (this.state.stateChanging && !force) { | ||||||
|  |       return false; | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     this.setState({ |     this.setState({ | ||||||
|       showSearch: showSearch, |       showSearch: showSearch, | ||||||
|       stateChanging: true |       stateChanging: true | ||||||
|     }); |     }); | ||||||
| 
 | 
 | ||||||
|     if (showSearch) { |  | ||||||
|       this.refs.searchInput.focus(); |  | ||||||
|     } else { |  | ||||||
|       this.refs.searchInput.getInputNode().blur(); |  | ||||||
|     } |  | ||||||
| 
 |  | ||||||
|     const timeoutId = window.setTimeout(() => { |     const timeoutId = window.setTimeout(() => { | ||||||
|       this.setState({ stateChanging: false }); |       this.setState({ stateChanging: false }); | ||||||
|     }, 450); |     }, 450); | ||||||
|  | |||||||
							
								
								
									
										17
									
								
								js/src/ui/Form/InputChip/index.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										17
									
								
								js/src/ui/Form/InputChip/index.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,17 @@ | |||||||
|  | // Copyright 2015, 2016 Ethcore (UK) Ltd.
 | ||||||
|  | // This file is part of Parity.
 | ||||||
|  | 
 | ||||||
|  | // Parity is free software: you can redistribute it and/or modify
 | ||||||
|  | // it under the terms of the GNU General Public License as published by
 | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or
 | ||||||
|  | // (at your option) any later version.
 | ||||||
|  | 
 | ||||||
|  | // Parity is distributed in the hope that it will be useful,
 | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||||
|  | // GNU General Public License for more details.
 | ||||||
|  | 
 | ||||||
|  | // You should have received a copy of the GNU General Public License
 | ||||||
|  | // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  | 
 | ||||||
|  | export default from './inputChip'; | ||||||
							
								
								
									
										26
									
								
								js/src/ui/Form/InputChip/inputChip.css
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										26
									
								
								js/src/ui/Form/InputChip/inputChip.css
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,26 @@ | |||||||
|  | /* Copyright 2015, 2016 Ethcore (UK) Ltd. | ||||||
|  | /* This file is part of Parity. | ||||||
|  | /* | ||||||
|  | /* Parity is free software: you can redistribute it and/or modify | ||||||
|  | /* it under the terms of the GNU General Public License as published by | ||||||
|  | /* the Free Software Foundation, either version 3 of the License, or | ||||||
|  | /* (at your option) any later version. | ||||||
|  | /* | ||||||
|  | /* Parity is distributed in the hope that it will be useful, | ||||||
|  | /* but WITHOUT ANY WARRANTY; without even the implied warranty of | ||||||
|  | /* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the | ||||||
|  | /* GNU General Public License for more details. | ||||||
|  | /* | ||||||
|  | /* You should have received a copy of the GNU General Public License | ||||||
|  | /* along with Parity.  If not, see <http://www.gnu.org/licenses/>. | ||||||
|  | */ | ||||||
|  | 
 | ||||||
|  | .chip { | ||||||
|  |   & > svg { | ||||||
|  |     width: 1.2rem !important; | ||||||
|  |     height: 1.2rem !important; | ||||||
|  |     margin: initial !important; | ||||||
|  |     margin-right: 4px !important; | ||||||
|  |     padding: 4px 0 !important; | ||||||
|  |   } | ||||||
|  | } | ||||||
							
								
								
									
										164
									
								
								js/src/ui/Form/InputChip/inputChip.js
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										164
									
								
								js/src/ui/Form/InputChip/inputChip.js
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,164 @@ | |||||||
|  | // Copyright 2015, 2016 Ethcore (UK) Ltd.
 | ||||||
|  | // This file is part of Parity.
 | ||||||
|  | 
 | ||||||
|  | // Parity is free software: you can redistribute it and/or modify
 | ||||||
|  | // it under the terms of the GNU General Public License as published by
 | ||||||
|  | // the Free Software Foundation, either version 3 of the License, or
 | ||||||
|  | // (at your option) any later version.
 | ||||||
|  | 
 | ||||||
|  | // Parity is distributed in the hope that it will be useful,
 | ||||||
|  | // but WITHOUT ANY WARRANTY; without even the implied warranty of
 | ||||||
|  | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | ||||||
|  | // GNU General Public License for more details.
 | ||||||
|  | 
 | ||||||
|  | // You should have received a copy of the GNU General Public License
 | ||||||
|  | // along with Parity.  If not, see <http://www.gnu.org/licenses/>.
 | ||||||
|  | 
 | ||||||
|  | import React, { Component, PropTypes } from 'react'; | ||||||
|  | import { Chip } from 'material-ui'; | ||||||
|  | import ChipInput from 'material-ui-chip-input'; | ||||||
|  | import { blue300 } from 'material-ui/styles/colors'; | ||||||
|  | import { uniq } from 'lodash'; | ||||||
|  | 
 | ||||||
|  | import styles from './inputChip.css'; | ||||||
|  | 
 | ||||||
|  | export default class InputChip extends Component { | ||||||
|  |   static propTypes = { | ||||||
|  |     tokens: PropTypes.array.isRequired, | ||||||
|  |     className: PropTypes.string, | ||||||
|  |     hint: PropTypes.string, | ||||||
|  |     label: PropTypes.string, | ||||||
|  |     onTokensChange: PropTypes.func, | ||||||
|  |     onInputChange: PropTypes.func, | ||||||
|  |     onBlur: PropTypes.func, | ||||||
|  |     clearOnBlur: PropTypes.bool | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   static defaultProps = { | ||||||
|  |     clearOnBlur: false | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   render () { | ||||||
|  |     const { clearOnBlur, className, hint, label, tokens } = this.props; | ||||||
|  |     const classes = `${className}`; | ||||||
|  | 
 | ||||||
|  |     return ( | ||||||
|  |       <ChipInput | ||||||
|  |         className={ classes } | ||||||
|  |         ref='chipInput' | ||||||
|  | 
 | ||||||
|  |         value={ tokens } | ||||||
|  |         clearOnBlur={ clearOnBlur } | ||||||
|  |         floatingLabelText={ label } | ||||||
|  |         hintText={ hint } | ||||||
|  | 
 | ||||||
|  |         chipRenderer={ this.chipRenderer } | ||||||
|  | 
 | ||||||
|  |         onBlur={ this.handleBlur } | ||||||
|  |         onRequestAdd={ this.handleTokenAdd } | ||||||
|  |         onRequestDelete={ this.handleTokenDelete } | ||||||
|  |         onUpdateInput={ this.handleInputChange } | ||||||
|  | 
 | ||||||
|  |         floatingLabelFixed | ||||||
|  |         fullWidth | ||||||
|  | 
 | ||||||
|  |         hintStyle={ { | ||||||
|  |           bottom: 16, | ||||||
|  |           left: 1, | ||||||
|  |           transition: 'none' | ||||||
|  |         } } | ||||||
|  |         inputStyle={ { | ||||||
|  |           marginBottom: 18 | ||||||
|  |         } } | ||||||
|  |         textFieldStyle={ { | ||||||
|  |           height: 42 | ||||||
|  |         } } /> | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   chipRenderer = (state, key) => { | ||||||
|  |     const { value, isFocused, isDisabled, handleClick, handleRequestDelete } = state; | ||||||
|  | 
 | ||||||
|  |     return ( | ||||||
|  |       <Chip | ||||||
|  |         key={ key } | ||||||
|  |         className={ styles.chip } | ||||||
|  |         style={ { | ||||||
|  |           margin: '8px 8px 0 0', | ||||||
|  |           float: 'left', | ||||||
|  |           pointerEvents: isDisabled ? 'none' : undefined, | ||||||
|  |           alignItems: 'center' | ||||||
|  |         } } | ||||||
|  |         labelStyle={ { | ||||||
|  |           paddingRight: 6, | ||||||
|  |           fontSize: '0.9rem', | ||||||
|  |           lineHeight: 'initial' | ||||||
|  |         } } | ||||||
|  |         backgroundColor={ isFocused ? blue300 : 'rgba(50, 50, 50, 0.73)' } | ||||||
|  |         onTouchTap={ handleClick } | ||||||
|  |         onRequestDelete={ handleRequestDelete } | ||||||
|  |       > | ||||||
|  |         { value } | ||||||
|  |       </Chip> | ||||||
|  |     ); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   handleBlur = () => { | ||||||
|  |     const { onBlur } = this.props; | ||||||
|  | 
 | ||||||
|  |     if (typeof onBlur === 'function') { | ||||||
|  |       onBlur(); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   handleTokenAdd = (value) => { | ||||||
|  |     const { tokens, onInputChange } = this.props; | ||||||
|  | 
 | ||||||
|  |     const newTokens = uniq([].concat(tokens, value)); | ||||||
|  | 
 | ||||||
|  |     this.handleTokensChange(newTokens); | ||||||
|  | 
 | ||||||
|  |     if (value === this.refs.chipInput.state.inputValue && typeof onInputChange === 'function') { | ||||||
|  |       onInputChange(''); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   handleTokenDelete = (value) => { | ||||||
|  |     const { tokens } = this.props; | ||||||
|  | 
 | ||||||
|  |     const newTokens = uniq([] | ||||||
|  |       .concat(tokens) | ||||||
|  |       .filter(v => v !== value)); | ||||||
|  | 
 | ||||||
|  |     this.handleTokensChange(newTokens); | ||||||
|  |     this.refs.chipInput.focus(); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   handleInputChange = (value) => { | ||||||
|  |     const { onInputChange } = this.props; | ||||||
|  | 
 | ||||||
|  |     const splitTokens = value.split(/[\s,;]/); | ||||||
|  | 
 | ||||||
|  |     const inputValue = (splitTokens.length <= 1) | ||||||
|  |       ? value | ||||||
|  |       : splitTokens.slice(-1)[0].trim(); | ||||||
|  | 
 | ||||||
|  |     this.refs.chipInput.setState({ inputValue }); | ||||||
|  | 
 | ||||||
|  |     if (splitTokens.length > 1) { | ||||||
|  |       const tokensToAdd = splitTokens.slice(0, -1); | ||||||
|  |       tokensToAdd.forEach(token => this.handleTokenAdd(token)); | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     if (typeof onInputChange === 'function') { | ||||||
|  |       onInputChange(inputValue); | ||||||
|  |     } | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  |   handleTokensChange = (tokens) => { | ||||||
|  |     const { onTokensChange } = this.props; | ||||||
|  | 
 | ||||||
|  |     onTokensChange(tokens.filter(token => token && token.length > 0)); | ||||||
|  |   } | ||||||
|  | 
 | ||||||
|  | } | ||||||
| @ -19,6 +19,7 @@ import FormWrap from './FormWrap'; | |||||||
| import Input from './Input'; | import Input from './Input'; | ||||||
| import InputAddress from './InputAddress'; | import InputAddress from './InputAddress'; | ||||||
| import InputAddressSelect from './InputAddressSelect'; | import InputAddressSelect from './InputAddressSelect'; | ||||||
|  | import InputChip from './InputChip'; | ||||||
| import InputInline from './InputInline'; | import InputInline from './InputInline'; | ||||||
| import Select from './Select'; | import Select from './Select'; | ||||||
| 
 | 
 | ||||||
| @ -29,6 +30,7 @@ export { | |||||||
|   Input, |   Input, | ||||||
|   InputAddress, |   InputAddress, | ||||||
|   InputAddressSelect, |   InputAddressSelect, | ||||||
|  |   InputChip, | ||||||
|   InputInline, |   InputInline, | ||||||
|   Select |   Select | ||||||
| }; | }; | ||||||
|  | |||||||
| @ -25,7 +25,7 @@ import ConfirmDialog from './ConfirmDialog'; | |||||||
| import Container, { Title as ContainerTitle } from './Container'; | import Container, { Title as ContainerTitle } from './Container'; | ||||||
| import ContextProvider from './ContextProvider'; | import ContextProvider from './ContextProvider'; | ||||||
| import Errors from './Errors'; | import Errors from './Errors'; | ||||||
| import Form, { AddressSelect, FormWrap, Input, InputAddress, InputAddressSelect, InputInline, Select } from './Form'; | import Form, { AddressSelect, FormWrap, Input, InputAddress, InputAddressSelect, InputChip, InputInline, Select } from './Form'; | ||||||
| import IdentityIcon from './IdentityIcon'; | import IdentityIcon from './IdentityIcon'; | ||||||
| import IdentityName from './IdentityName'; | import IdentityName from './IdentityName'; | ||||||
| import MethodDecoding from './MethodDecoding'; | import MethodDecoding from './MethodDecoding'; | ||||||
| @ -57,6 +57,7 @@ export { | |||||||
|   Input, |   Input, | ||||||
|   InputAddress, |   InputAddress, | ||||||
|   InputAddressSelect, |   InputAddressSelect, | ||||||
|  |   InputChip, | ||||||
|   InputInline, |   InputInline, | ||||||
|   Select, |   Select, | ||||||
|   IdentityIcon, |   IdentityIcon, | ||||||
|  | |||||||
| @ -17,6 +17,7 @@ | |||||||
| const HappyPack = require('happypack'); | const HappyPack = require('happypack'); | ||||||
| const path = require('path'); | const path = require('path'); | ||||||
| const postcssImport = require('postcss-import'); | const postcssImport = require('postcss-import'); | ||||||
|  | const postcssNested = require('postcss-nested'); | ||||||
| const postcssVars = require('postcss-simple-vars'); | const postcssVars = require('postcss-simple-vars'); | ||||||
| const rucksack = require('rucksack-css'); | const rucksack = require('rucksack-css'); | ||||||
| const webpack = require('webpack'); | const webpack = require('webpack'); | ||||||
| @ -113,6 +114,7 @@ module.exports = { | |||||||
|     postcssImport({ |     postcssImport({ | ||||||
|       addDependencyTo: webpack |       addDependencyTo: webpack | ||||||
|     }), |     }), | ||||||
|  |     postcssNested({}), | ||||||
|     postcssVars({ |     postcssVars({ | ||||||
|       unknown: function (node, name, result) { |       unknown: function (node, name, result) { | ||||||
|         node.warn(result, `Unknown variable ${name}`); |         node.warn(result, `Unknown variable ${name}`); | ||||||
|  | |||||||
		Loading…
	
		Reference in New Issue
	
	Block a user