@lyra/form-builder
Version:
Lyra form builder
198 lines (178 loc) • 6.65 kB
JavaScript
'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;