UNPKG

wix-style-react

Version:
405 lines (328 loc) • 15.5 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 _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;