UNPKG

@lyra/form-builder

Version:
198 lines (178 loc) 6.65 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); 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 _react2 = _interopRequireDefault(_react); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } function _objectWithoutProperties(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 sizerStyle = { position: 'absolute', top: 0, left: 0, visibility: 'hidden', height: 0, overflow: 'scroll', whiteSpace: 'pre' }; class AutosizeInput extends _react.Component { constructor(props) { super(props); this.inputRef = el => { this.input = el; if (typeof this.props.inputRef === 'function') { this.props.inputRef(el); } }; this.placeHolderSizerRef = el => { this.placeHolderSizer = el; }; this.sizerRef = el => { this.sizer = el; }; this.state = { inputWidth: props.minWidth, inputId: `_${Math.random().toString(36).substr(2, 12)}` }; } componentDidMount() { this.mounted = true; this.copyInputStyles(); this.updateInputWidth(); } componentDidUpdate(prevProps, prevState) { if (prevState.inputWidth !== this.state.inputWidth) { if (typeof this.props.onAutosize === 'function') { this.props.onAutosize(this.state.inputWidth); } } this.updateInputWidth(); } componentWillUnmount() { this.mounted = false; } copyInputStyles() { if (!this.mounted || !window.getComputedStyle) { return; } const inputStyle = this.input && window.getComputedStyle(this.input); if (!inputStyle) { return; } const widthNode = this.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; widthNode.style.textTransform = inputStyle.textTransform; if (this.props.placeholder) { const placeholderNode = this.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; placeholderNode.style.textTransform = inputStyle.textTransform; } } updateInputWidth() { if (!this.mounted || !this.sizer || typeof this.sizer.scrollWidth === 'undefined') { return; } let newInputWidth; if (this.props.placeholder && (!this.props.value || this.props.value && this.props.placeholderIsMinWidth)) { newInputWidth = Math.max(this.sizer.scrollWidth, this.placeHolderSizer.scrollWidth) + 2; } else { newInputWidth = this.sizer.scrollWidth + 2; } if (newInputWidth < this.props.minWidth) { newInputWidth = this.props.minWidth; } if (newInputWidth !== this.state.inputWidth) { this.setState({ inputWidth: newInputWidth }); } } getInput() { return this.input; } focus() { this.input.focus(); } blur() { this.input.blur(); } select() { this.input.select(); } render() { const sizerValue = [this.props.defaultValue, this.props.value, ''].reduce((previousValue, currentValue) => { if (previousValue !== null && previousValue !== undefined) { return previousValue; } return currentValue; }); const wrapperStyle = _extends({}, this.props.style); if (!wrapperStyle.display) { wrapperStyle.display = 'inline-block'; } const inputStyle = _extends({}, this.props.inputStyle); inputStyle.width = `${this.state.inputWidth}px`; inputStyle.boxSizing = 'content-box'; const inputProps = _objectWithoutProperties(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.onAutosize; delete inputProps.placeholderIsMinWidth; delete inputProps.inputRef; return _react2.default.createElement( 'div', { className: this.props.className, style: wrapperStyle }, _react2.default.createElement('style', { dangerouslySetInnerHTML: { __html: [`input#${this.state.id}::-ms-clear {display: none;}`].join('\n') } }), _react2.default.createElement('input', _extends({ id: this.state.id }, inputProps, { ref: this.inputRef })), _react2.default.createElement( 'div', { ref: this.sizerRef, style: sizerStyle }, sizerValue ), this.props.placeholder ? _react2.default.createElement( 'div', { ref: this.placeHolderSizerRef, style: sizerStyle }, this.props.placeholder ) : null ); } } AutosizeInput.propTypes = { className: _propTypes2.default.string, // className for the outer element defaultValue: _propTypes2.default.any, // default field value inputClassName: _propTypes2.default.string, // className for the input element inputRef: _propTypes2.default.func, // ref callback for the input element inputStyle: _propTypes2.default.object, // css styles for the input element minWidth: _propTypes2.default.oneOfType([ // minimum width for input element _propTypes2.default.number, _propTypes2.default.string]), onAutosize: _propTypes2.default.func, // onAutosize handler: function(newWidth) {} onChange: _propTypes2.default.func, // onChange handler: function(newValue) {} placeholder: _propTypes2.default.string, // placeholder text placeholderIsMinWidth: _propTypes2.default.bool, // don't collapse size to less than the placeholder style: _propTypes2.default.object, // css styles for the outer element value: _propTypes2.default.any // field value }; AutosizeInput.defaultProps = { minWidth: 1 }; exports.default = AutosizeInput;