UNPKG

react-fantastic

Version:

Fantastic react component library

184 lines 7.39 kB
import React, { Component } from 'react'; import ReactDOM from 'react-dom'; import PropTypes from 'prop-types'; import classNames from 'classnames'; import warning from 'warning'; import TextField from './TextField'; const objectWithoutProperties = function(obj, keys) { var target = {}; for (var i in obj) { if (keys.indexOf(i) >= 0) continue; if (!Object.prototype.hasOwnProperty.call(obj, i)) continue; target[i] = obj[i]; } return target; } const propTypes = { className: PropTypes.string, type: PropTypes.string, name: PropTypes.string, placeholder: PropTypes.string, value: PropTypes.any, bordered: PropTypes.bool, multiline: PropTypes.bool, autoFocus: PropTypes.bool, onChange: PropTypes.func, color: PropTypes.string, labelColor: PropTypes.string, borderFocusColor: PropTypes.string }; const defaultProps = { type: 'text', name: '', placeholder: '', bordered: false, multiline: false, autoFocus: false, color: '#222', labelColor: '#0ab2f7', borderFocusColor: '#0ab2f7' }; const contextTypes = { hasIcon: PropTypes.bool, hasLabel: PropTypes.bool, icon: PropTypes.oneOfType([PropTypes.func, PropTypes.node]) }; class EditText extends Component { constructor(props, context) { super(props, context); this.state = { value: props.value }; this.handleChange = this.handleChange.bind(this); this.handleFocus = this.handleFocus.bind(this); this.handleBlur = this.handleBlur.bind(this); }; componentWillReceiveProps(nextProps) { nextProps.value !== this.props.value && this.setState({value: nextProps.value}); }; handleChange(e) { e.preventDefault(); const { onChange } = this.props; onChange && onChange(e); }; handleFocus(e) { e.preventDefault(); const { color, labelColor, borderFocusColor, onFocus } = this.props, { hasLabel } = this.context, edittext = e.target; if(hasLabel) { if(edittext) { const textfield = edittext.parentElement.className.indexOf('text-field') !== -1 && edittext.parentElement; let label; if(textfield) { for (const i in textfield.children) { const collections = textfield.children[i]; if(typeof collections === 'object') { if(collections.className.indexOf('text-field-label') !== -1) { label = collections; } } } } const focus = { top: 'auto', bottom: '100%', left: '0px', fontSize: '12px', zIndex: 5, color: this.props.labelColor }; label && Object.assign(label.style, focus); } } edittext && Object.assign(edittext.style, {borderColor: borderFocusColor, color}); if(onFocus) { onFocus(e); } }; handleBlur(e) { e.preventDefault(); const { bordered, onBlur } = this.props, { hasLabel } = this.context, edittext = e.target; if(hasLabel && edittext) { const textfield = edittext.parentElement.className.indexOf('text-field') !== -1 && edittext.parentElement; let label; if(textfield) { for (const i in textfield.children) { const collections = textfield.children[i]; if(typeof collections === 'object') { if(collections.className.indexOf('text-field-label') !== -1) { label = collections; } } } } if(!this.state.value) { const blur = { top: '20%', left: textfield && textfield.className.indexOf('has-icon') != -1 ? '28px' : '4px', color: '#757575', fontSize: '14px' }; label && Object.assign(label.style, blur); } else { const focus = { top: 'auto', bottom: '100%', left: '0px', fontSize: '12px', zIndex: 5, color: this.props.labelColor }; label && Object.assign(label.style, focus); } } edittext && Object.assign(edittext.style, {borderColor: '#ccc'}); if(onBlur) { onBlur(e); } }; render() { const { className, type, multiline, name, placeholder, value, bordered, onChange, autoFocus } = this.props, { hasLabel, hasIcon, icon } = this.context; const classes = classNames(!bordered ? 'edittext': 'edittext-bordered', className), typesAllowed = ['text', 'email', 'password', 'time', 'date', 'datetime', 'datetime-local', 'number', 'month', 'search', 'tel', 'url', 'week']; let tag = multiline ? 'textarea' : 'input'; if(typesAllowed.indexOf(type) !== -1) { if(hasLabel){ return React.createElement( tag, Object.assign({}, objectWithoutProperties(this.props, Object.keys(propTypes)), { className: classes, type, name, value: this.state.value, autoFocus, onChange: this.handleChange, onFocus: this.handleFocus, onBlur: this.handleBlur, autoComplete: 'off' } ) ); } else { return React.createElement( tag, Object.assign({}, objectWithoutProperties(this.props, Object.keys(propTypes)), { className: classes, type, name, placeholder, value: this.state.value, autoFocus, onChange: this.handleChange, autoComplete: 'off' } ) ) } } else { if(process.env.NODE_ENV !== 'production'){ warning(typesAllowed.indexOf(type) !== -1, 'EditText type must be one of '+typesAllowed.toString()+'. Otherwise use another input like checkbox, radiobutton, switch, autcomplete etc.') } React.createElement('input', this.props); } }; }; EditText.propTypes = propTypes; EditText.defaultProps = defaultProps; EditText.contextTypes = contextTypes; export default EditText;