wix-style-react
Version:
wix-style-react
405 lines (328 loc) • 15.5 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 _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
var _get = function get(object, property, receiver) { if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { return get(parent, property, receiver); } } else if ("value" in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } };
var _class, _temp;
var _react = require('react');
var _react2 = _interopRequireDefault(_react);
var _propTypes = require('prop-types');
var _propTypes2 = _interopRequireDefault(_propTypes);
var _classnames = require('classnames');
var _classnames2 = _interopRequireDefault(_classnames);
var _Exclamation = require('./Exclamation');
var _Exclamation2 = _interopRequireDefault(_Exclamation);
var _WixComponent2 = require('../BaseComponents/WixComponent');
var _WixComponent3 = _interopRequireDefault(_WixComponent2);
var _debounce = require('lodash/debounce');
var _debounce2 = _interopRequireDefault(_debounce);
var _isNaN = require('lodash/isNaN');
var _isNaN2 = _interopRequireDefault(_isNaN);
var _InputArea = require('./InputArea.scss');
var _InputArea2 = _interopRequireDefault(_InputArea);
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; }
function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }
/**
* General inputArea container
*/
var InputArea = (_temp = _class = function (_WixComponent) {
_inherits(InputArea, _WixComponent);
function InputArea(props) {
_classCallCheck(this, InputArea);
var _this = _possibleConstructorReturn(this, (InputArea.__proto__ || Object.getPrototypeOf(InputArea)).call(this, props));
_this.state = {
focus: false,
counter: (_this.props.value || _this.props.defaultValue || '').length,
computedRows: InputArea.MIN_ROWS
};
_this._updateComputedStyle = (0, _debounce2.default)(function () {
_this._computedStyle = window.getComputedStyle(_this.textArea);
}, 500, { leading: true });
_this._onKeyDown = _this._onKeyDown.bind(_this);
_this._onChange = _this._onChange.bind(_this);
_this._onInput = _this._onInput.bind(_this);
_this._onFocus = _this._onFocus.bind(_this);
_this._onBlur = _this._onBlur.bind(_this);
_this.focus = _this.focus.bind(_this);
_this.blur = _this.blur.bind(_this);
_this.select = _this.select.bind(_this);
_this._computedStyle = null;
return _this;
}
// For autoGrow prop min rows is 2 so the textarea doesn't look like an input
_createClass(InputArea, [{
key: 'componentDidMount',
value: function componentDidMount() {
_get(InputArea.prototype.__proto__ || Object.getPrototypeOf(InputArea.prototype), 'componentDidMount', this).call(this);
this.props.autoFocus && this._onFocus();
}
}, {
key: 'render',
value: function render() {
var _classNames,
_this2 = this;
var _props = this.props,
autoFocus = _props.autoFocus,
defaultValue = _props.defaultValue,
disabled = _props.disabled,
error = _props.error,
forceFocus = _props.forceFocus,
forceHover = _props.forceHover,
id = _props.id,
name = _props.name,
onKeyUp = _props.onKeyUp,
placeholder = _props.placeholder,
readOnly = _props.readOnly,
tabIndex = _props.tabIndex,
rows = _props.rows,
autoGrow = _props.autoGrow,
value = _props.value,
minHeight = _props.minHeight,
maxHeight = _props.maxHeight,
maxLength = _props.maxLength,
resizable = _props.resizable,
hasCounter = _props.hasCounter,
theme = _props.theme,
errorMessage = _props.errorMessage,
tooltipPlacement = _props.tooltipPlacement,
onTooltipShow = _props.onTooltipShow;
var inlineStyle = {};
var rowsAttr = rows ? rows : autoGrow ? this.state.computedRows : undefined;
var onInput = !rows && autoGrow ? this._onInput : undefined;
if (minHeight) {
inlineStyle.minHeight = minHeight;
}
if (maxHeight) {
inlineStyle.maxHeight = maxHeight;
}
var classes = (0, _classnames2.default)((_classNames = {}, _defineProperty(_classNames, _InputArea2.default.root, true), _defineProperty(_classNames, _InputArea2.default['theme-' + theme], true), _defineProperty(_classNames, _InputArea2.default.hasError, !!error), _defineProperty(_classNames, _InputArea2.default.hasHover, forceHover), _defineProperty(_classNames, _InputArea2.default.hasFocus, forceFocus || this.state.focus), _defineProperty(_classNames, _InputArea2.default.resizable, !!resizable), _defineProperty(_classNames, _InputArea2.default.nonResizable, !resizable || !!disabled), _defineProperty(_classNames, _InputArea2.default.disabled, !!disabled), _classNames));
var ariaAttribute = {};
Object.keys(this.props).filter(function (key) {
return key.startsWith('aria');
}).map(function (key) {
return ariaAttribute['aria-' + key.substr(4).toLowerCase()] = _this2.props[key];
});
return _react2.default.createElement(
'div',
{ className: _InputArea2.default.wrapper },
_react2.default.createElement(
'div',
{ className: classes },
_react2.default.createElement('textarea', _extends({
rows: rowsAttr,
maxLength: maxLength,
ref: function ref(_ref) {
return _this2.textArea = _ref;
},
className: _InputArea2.default.inputArea,
id: id,
name: name,
style: inlineStyle,
defaultValue: defaultValue,
disabled: disabled,
value: value,
onFocus: this._onFocus,
onBlur: this._onBlur,
onKeyDown: this._onKeyDown,
onChange: this._onChange,
onInput: onInput,
onDoubleClick: this._onDoubleClick,
placeholder: placeholder,
tabIndex: tabIndex,
autoFocus: autoFocus,
onKeyUp: onKeyUp
}, ariaAttribute, {
readOnly: readOnly
})),
theme === 'material' && _react2.default.createElement('div', { className: _InputArea2.default.bar }),
hasCounter && maxLength && _react2.default.createElement(
'span',
{ className: _InputArea2.default.counter, 'data-hook': 'counter' },
this.state.counter,
'/',
maxLength
)
),
_react2.default.createElement(
'div',
{ className: _InputArea2.default.error },
error && !disabled && _react2.default.createElement(_Exclamation2.default, {
errorMessage: errorMessage,
tooltipPlacement: tooltipPlacement,
onTooltipShow: onTooltipShow
})
)
);
}
}, {
key: 'focus',
value: function focus() {
this.textArea && this.textArea.focus();
}
}, {
key: 'blur',
value: function blur() {
this.textArea && this.textArea.blur();
}
}, {
key: 'select',
value: function select() {
this.textArea && this.textArea.select();
}
}, {
key: '_onFocus',
value: function _onFocus(e) {
var _this3 = this;
this.setState({ focus: true });
this.props.onFocus && this.props.onFocus(e);
if (this.props.autoSelect) {
// Set timeout is needed here since onFocus is called before react
// gets the reference for the input (specifically when autoFocus
// is on. So setTimeout ensures we have the ref.input needed in select)
setTimeout(function () {
return _this3.select();
}, 0);
}
}
}, {
key: '_onBlur',
value: function _onBlur(e) {
this.setState({ focus: false });
this.props.onBlur && this.props.onBlur(e);
}
}, {
key: '_onKeyDown',
value: function _onKeyDown(e) {
this.props.onKeyDown && this.props.onKeyDown(e);
if (e.key === 'Enter') {
this.props.onEnterPressed && this.props.onEnterPressed();
} else if (e.key === 'Escape') {
this.props.onEscapePressed && this.props.onEscapePressed();
}
}
}, {
key: '_onChange',
value: function _onChange(e) {
this.props.hasCounter && this.setState({ counter: e.target.value.length });
this.props.onChange && this.props.onChange(e);
}
}, {
key: '_onInput',
value: function _onInput() {
var _this4 = this;
this.setState({ computedRows: 1 }, function () {
var rowsCount = _this4._getRowsCount();
var computedRows = Math.max(InputArea.MIN_ROWS, rowsCount);
_this4.setState({
computedRows: computedRows
});
});
}
}, {
key: '_getComputedStyle',
value: function _getComputedStyle() {
this._updateComputedStyle();
return this._computedStyle;
}
}, {
key: '_getRowsCount',
value: function _getRowsCount() {
var computedStyle = this._getComputedStyle();
var fontSize = parseInt(computedStyle.getPropertyValue('font-size'), 10);
var lineHeight = parseInt(computedStyle.getPropertyValue('line-height'), 10);
var lineHeightValue = (0, _isNaN2.default)(lineHeight) ? this._getDefaultLineHeight() * fontSize : lineHeight;
return Math.floor(this.textArea.scrollHeight / lineHeightValue);
}
}, {
key: '_getDefaultLineHeight',
value: function _getDefaultLineHeight() {
if (!this._defaultLineHeight) {
var parentNode = this.textArea.parentNode;
var computedStyles = this._getComputedStyle();
var fontFamily = computedStyles.getPropertyValue('font-family');
var fontSize = computedStyles.getPropertyValue('font-size');
var tempElement = document.createElement('span');
var defaultStyles = 'position:absolute;display:inline;border:0;margin:0;padding:0;line-height:normal;';
tempElement.setAttribute('style', defaultStyles + 'font-family:' + fontFamily + ';font-size:' + fontSize + ';');
tempElement.innerText = 'M';
parentNode.appendChild(tempElement);
this._defaultLineHeight = parseInt(tempElement.clientHeight, 10) / parseInt(fontSize, 10);
tempElement.parentNode.removeChild(tempElement);
}
return this._defaultLineHeight;
}
}]);
return InputArea;
}(_WixComponent3.default), _class.MIN_ROWS = 2, _temp);
InputArea.displayName = 'InputArea';
InputArea.defaultProps = {
theme: 'normal'
};
InputArea.propTypes = {
ariaControls: _propTypes2.default.string,
ariaDescribedby: _propTypes2.default.string,
ariaLabel: _propTypes2.default.string,
/** Standard React Input autoFocus (focus the element on mount) */
autoFocus: _propTypes2.default.bool,
/** Standard React Input autoSelect (select the entire text of the element on focus) */
autoSelect: _propTypes2.default.bool,
dataHook: _propTypes2.default.string,
/** Default value for those who wants to use this component un-controlled */
defaultValue: _propTypes2.default.string,
/** Disables the input */
disabled: _propTypes2.default.bool,
/** Sets UI to erroneous */
error: _propTypes2.default.bool,
/** The error message to display when hovering the error icon, if not given or empty there will be no tooltip */
errorMessage: _propTypes2.default.string,
forceFocus: _propTypes2.default.bool,
forceHover: _propTypes2.default.bool,
/** When true a letters counter will appear */
hasCounter: _propTypes2.default.bool,
id: _propTypes2.default.string,
/** Name Attribute */
name: _propTypes2.default.string,
/** i.e. '12px' */
maxHeight: _propTypes2.default.string,
/** Define max length allowed in the inputArea */
maxLength: _propTypes2.default.number,
menuArrow: _propTypes2.default.bool,
/** i.e. '12px' */
minHeight: _propTypes2.default.string,
/** onBlur callback */
onBlur: _propTypes2.default.func,
/** onChange callback */
onChange: _propTypes2.default.func,
onClear: _propTypes2.default.func,
onEnterPressed: _propTypes2.default.func,
onEscapePressed: _propTypes2.default.func,
/** onFocus callback */
onFocus: _propTypes2.default.func,
onKeyDown: _propTypes2.default.func,
onKeyUp: _propTypes2.default.func,
/** onShow prop for the error tooltip */
onTooltipShow: _propTypes2.default.func,
/** Placeholder to display */
placeholder: _propTypes2.default.string,
/** Sets the input to readOnly */
readOnly: _propTypes2.default.bool,
resizable: _propTypes2.default.bool,
/** Sets initial height according to the number of rows (chrome uses the rows for minHeight as well) */
rows: _propTypes2.default.number,
/** Will cause the Input Area to grow and shrink according to user input */
autoGrow: _propTypes2.default.bool,
style: _propTypes2.default.oneOf(['normal', 'paneltitle', 'material', 'amaterial']),
tabIndex: _propTypes2.default.number,
/** The theme of the input, can be one of `normal`, `paneltitle` */
theme: _propTypes2.default.oneOf(['normal', 'paneltitle', 'material', 'amaterial']),
/** Placement of the error tooltip */
tooltipPlacement: _propTypes2.default.string,
/** Inputs value */
value: _propTypes2.default.string
};
exports.default = InputArea;