186 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
			
		
		
	
	
			186 lines
		
	
	
		
			4.6 KiB
		
	
	
	
		
			JavaScript
		
	
	
	
	
	
| // Copyright (c) 2018 Dominic Masters
 | |
| //
 | |
| // MIT License
 | |
| //
 | |
| // Permission is hereby granted, free of charge, to any person obtaining
 | |
| // a copy of this software and associated documentation files (the
 | |
| // "Software"), to deal in the Software without restriction, including
 | |
| // without limitation the rights to use, copy, modify, merge, publish,
 | |
| // distribute, sublicense, and/or sell copies of the Software, and to
 | |
| // permit persons to whom the Software is furnished to do so, subject to
 | |
| // the following conditions:
 | |
| //
 | |
| // The above copyright notice and this permission notice shall be
 | |
| // included in all copies or substantial portions of the Software.
 | |
| //
 | |
| // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
 | |
| // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
 | |
| // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
 | |
| // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
 | |
| // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
 | |
| // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
 | |
| // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 | |
| 
 | |
| import React from 'react';
 | |
| 
 | |
| import Button from './button/Button';
 | |
| import ButtonGroup from './button/ButtonGroup';
 | |
| import Form, { FormManager } from './form/Form';
 | |
| import InputGroup from './group/InputGroup';
 | |
| import Label from './label/Label';
 | |
| import Keyboard from './../../keyboard/Keyboard';
 | |
| 
 | |
| export default class Input extends React.Component {
 | |
|   constructor(props) {
 | |
|     super(props);
 | |
| 
 | |
|     this.state = {
 | |
|       value: props.value,
 | |
|       focused: false
 | |
|     };
 | |
|   }
 | |
| 
 | |
|   isFocused() {
 | |
|     return this.state && this.state.focused === true;
 | |
|   }
 | |
| 
 | |
|   componentDidMount() {
 | |
|     if(this.props.manager) this.props.manager.addInput(this);
 | |
|     Keyboard.addListener(this);
 | |
|   }
 | |
| 
 | |
|   componentWillUnmount() {
 | |
|     if(this.props.manager) this.props.manager.removeInput(this);
 | |
|     Keyboard.removeListener(this);
 | |
|   }
 | |
| 
 | |
|   onKeyUp(e, k) {
 | |
|     if(!this.props.manager) return;
 | |
|     if(!this.isFocused()) return;
 | |
|     if(!k.isSubmit()) return;
 | |
|     this.props.manager.submit();
 | |
|   }
 | |
| 
 | |
|   onChange(e, a, b) {
 | |
|     //Try my props
 | |
|     if(this.props.onChange && this.props.onChange(e) === false) return false;
 | |
| 
 | |
|     //Try the form manager
 | |
|     if(this.props.manager && this.props.manager.onChange(this, e) === false) {
 | |
|       return false;
 | |
|     }
 | |
| 
 | |
|     //Try something else?
 | |
|     this.setState({
 | |
|       value: e.target.value
 | |
|     });
 | |
|   }
 | |
| 
 | |
|   onFocus() {
 | |
|     this.setState({ focused: true });
 | |
|   }
 | |
| 
 | |
|   onBlur() {
 | |
|     this.setState({ focused: false });
 | |
|   }
 | |
| 
 | |
|   render() {
 | |
|     let ElementType = "input";
 | |
|     let type = "text";
 | |
|     let value;
 | |
|     let clazzes = "o-input";
 | |
|     let innerClazzes = "o-input__inner";
 | |
|     let style;
 | |
|     let props = Object.assign({}, this.props);
 | |
| 
 | |
|     //Determining
 | |
|     if(props.type) type = props.type;
 | |
| 
 | |
|     //Values
 | |
|     if(props.value) {
 | |
|       value = props.value;
 | |
|     } else {
 | |
|       value = props.children;
 | |
|     }
 | |
| 
 | |
|     //Style
 | |
|     if(props.style) {
 | |
|       style = props.style;
 | |
|     } else if(props.error || props.danger) {
 | |
|       style = "danger";
 | |
|     } else if(props.warning) {
 | |
|       style = "warning";
 | |
|     } else if(props.primary) {
 | |
|       style = "primary";
 | |
|     }
 | |
| 
 | |
|     //Classes
 | |
|     clazzes += " is-"+type;
 | |
| 
 | |
|     if(style) {
 | |
|       clazzes += " o-input--style-"+style;
 | |
|       innerClazzes += " o-input--style-"+style+"__inner";
 | |
|     }
 | |
|     if(props.className) {
 | |
|       clazzes += " " + props.className;
 | |
|       innerClazzes += " " + props.className + "-element";
 | |
|     }
 | |
| 
 | |
|     //Clear junk props
 | |
|     delete props.manager;
 | |
| 
 | |
|     //Now create the element
 | |
|     let element;
 | |
| 
 | |
|     //First we need to switch things like submit and reset
 | |
|     if(type == "submit" || type == "reset" || type == "button") {
 | |
|       return (<Button
 | |
|         {...props}
 | |
|         className={props.className}
 | |
|         value={this.state.value}
 | |
|       />);
 | |
| 
 | |
|     } else if(type == "textarea") {
 | |
|       element = (<textarea
 | |
|           {...props}
 | |
|           className={innerClazzes}
 | |
|           onChange={this.onChange.bind(this)}
 | |
|           onFocus={this.onFocus.bind(this)}
 | |
|           onBlur={this.onBlur.bind(this)}
 | |
|         >{ this.state.value }</textarea>
 | |
|       );
 | |
| 
 | |
|     } else {
 | |
|       element = (<ElementType
 | |
|         {...props}
 | |
|         onChange={this.onChange.bind(this)}
 | |
|         onFocus={this.onFocus.bind(this)}
 | |
|         onBlur={this.onBlur.bind(this)}
 | |
|         type={type}
 | |
|         value={ this.state.value }
 | |
|         className={innerClazzes}
 | |
|       />);
 | |
|     }
 | |
| 
 | |
|     return (
 | |
|       <div className={clazzes}>
 | |
|         { element }
 | |
|       </div>
 | |
|     )
 | |
|   }
 | |
| }
 | |
| 
 | |
| const TextArea = props => {
 | |
|   return <Input {...props} type="textarea" />
 | |
| }
 | |
| 
 | |
| export {
 | |
|   Button,
 | |
|   ButtonGroup,
 | |
|   Form,
 | |
|   FormManager,
 | |
|   InputGroup,
 | |
|   TextArea,
 | |
|   Label
 | |
| };
 |