UNPKG

react-input-autosize

Version:
129 lines (123 loc) 4.65 kB
'use strict'; var _extends = Object.assign || function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; var React = require('react'); var sizerStyle = { position: 'absolute', top: 0, left: 0, visibility: 'hidden', height: 0, overflow: 'scroll', whiteSpace: 'pre' }; var AutosizeInput = React.createClass({ displayName: 'AutosizeInput', propTypes: { className: React.PropTypes.string, // className for the outer element defaultValue: React.PropTypes.any, // default field value inputClassName: React.PropTypes.string, // className for the input element inputStyle: React.PropTypes.object, // css styles for the input element minWidth: React.PropTypes.oneOfType([// minimum width for input element React.PropTypes.number, React.PropTypes.string]), onChange: React.PropTypes.func, // onChange handler: function(newValue) {} placeholder: React.PropTypes.string, // placeholder text placeholderIsMinWidth: React.PropTypes.bool, // don't collapse size to less than the placeholder style: React.PropTypes.object, // css styles for the outer element value: React.PropTypes.any }, // field value getDefaultProps: function getDefaultProps() { return { minWidth: 1 }; }, getInitialState: function getInitialState() { return { inputWidth: this.props.minWidth }; }, componentDidMount: function componentDidMount() { this.copyInputStyles(); this.updateInputWidth(); }, componentDidUpdate: function componentDidUpdate() { this.updateInputWidth(); }, copyInputStyles: function copyInputStyles() { if (!this.isMounted() || !window.getComputedStyle) { return; } var inputStyle = window.getComputedStyle(this.refs.input); if (!inputStyle) { return; } var widthNode = this.refs.sizer; widthNode.style.fontSize = inputStyle.fontSize; widthNode.style.fontFamily = inputStyle.fontFamily; widthNode.style.fontWeight = inputStyle.fontWeight; widthNode.style.fontStyle = inputStyle.fontStyle; widthNode.style.letterSpacing = inputStyle.letterSpacing; if (this.props.placeholder) { var placeholderNode = this.refs.placeholderSizer; placeholderNode.style.fontSize = inputStyle.fontSize; placeholderNode.style.fontFamily = inputStyle.fontFamily; placeholderNode.style.fontWeight = inputStyle.fontWeight; placeholderNode.style.fontStyle = inputStyle.fontStyle; placeholderNode.style.letterSpacing = inputStyle.letterSpacing; } }, updateInputWidth: function updateInputWidth() { if (!this.isMounted() || typeof this.refs.sizer.scrollWidth === 'undefined') { return; } var newInputWidth = undefined; if (this.props.placeholder && (!this.props.value || this.props.value && this.props.placeholderIsMinWidth)) { newInputWidth = Math.max(this.refs.sizer.scrollWidth, this.refs.placeholderSizer.scrollWidth) + 2; } else { newInputWidth = this.refs.sizer.scrollWidth + 2; } if (newInputWidth < this.props.minWidth) { newInputWidth = this.props.minWidth; } if (newInputWidth !== this.state.inputWidth) { this.setState({ inputWidth: newInputWidth }); } }, getInput: function getInput() { return this.refs.input; }, focus: function focus() { this.refs.input.focus(); }, blur: function blur() { this.refs.input.blur(); }, select: function select() { this.refs.input.select(); }, render: function render() { var sizerValue = this.props.defaultValue || this.props.value || ''; var wrapperStyle = this.props.style || {}; if (!wrapperStyle.display) wrapperStyle.display = 'inline-block'; var inputStyle = _extends({}, this.props.inputStyle); inputStyle.width = this.state.inputWidth + 'px'; inputStyle.boxSizing = 'content-box'; var inputProps = _extends({}, this.props); inputProps.className = this.props.inputClassName; inputProps.style = inputStyle; // ensure props meant for `AutosizeInput` don't end up on the `input` delete inputProps.inputClassName; delete inputProps.inputStyle; delete inputProps.minWidth; delete inputProps.placeholderIsMinWidth; return React.createElement( 'div', { className: this.props.className, style: wrapperStyle }, React.createElement('input', _extends({}, inputProps, { ref: 'input' })), React.createElement( 'div', { ref: 'sizer', style: sizerStyle }, sizerValue ), this.props.placeholder ? React.createElement( 'div', { ref: 'placeholderSizer', style: sizerStyle }, this.props.placeholder ) : null ); } }); module.exports = AutosizeInput;