UNPKG

@helpscout/hsds-react

Version:

React component library for Help Scout's Design System

436 lines (375 loc) 16.5 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); exports.__esModule = true; exports.default = exports.EditableFieldInput = void 0; var _inheritsLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/inheritsLoose")); var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutPropertiesLoose2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutPropertiesLoose")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _EditableField = require("./EditableField.css"); var _DropList = _interopRequireDefault(require("../DropList")); var _Icon = _interopRequireDefault(require("../Icon")); var _Tooltip = _interopRequireDefault(require("../Tooltip")); var _Truncate = _interopRequireDefault(require("../Truncate")); var _getValidProps = _interopRequireDefault(require("@helpscout/react-utils/dist/getValidProps")); var _EditableField2 = require("./EditableField.constants"); var _EditableField3 = require("./EditableField.utils"); var _classnames = _interopRequireDefault(require("classnames")); var _Keys = require("../../constants/Keys"); var _fastDeepEqual = _interopRequireDefault(require("fast-deep-equal")); var _jsxRuntime = require("react/jsx-runtime"); function _getRequireWildcardCache(nodeInterop) { if (typeof WeakMap !== "function") return null; var cacheBabelInterop = new WeakMap(); var cacheNodeInterop = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(nodeInterop) { return nodeInterop ? cacheNodeInterop : cacheBabelInterop; })(nodeInterop); } function _interopRequireWildcard(obj, nodeInterop) { if (!nodeInterop && obj && obj.__esModule) { return obj; } if (obj === null || typeof obj !== "object" && typeof obj !== "function") { return { default: obj }; } var cache = _getRequireWildcardCache(nodeInterop); if (cache && cache.has(obj)) { return cache.get(obj); } var newObj = {}; var hasPropertyDescriptor = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var key in obj) { if (key !== "default" && Object.prototype.hasOwnProperty.call(obj, key)) { var desc = hasPropertyDescriptor ? Object.getOwnPropertyDescriptor(obj, key) : null; if (desc && (desc.get || desc.set)) { Object.defineProperty(newObj, key, desc); } else { newObj[key] = obj[key]; } } } newObj.default = obj; if (cache) { cache.set(obj, newObj); } return newObj; } function noop() {} var Toggler = /*#__PURE__*/(0, _react.forwardRef)(function (_ref, ref) { var _ref$disabled = _ref.disabled, disabled = _ref$disabled === void 0 ? false : _ref$disabled, _ref$isActive = _ref.isActive, isActive = _ref$isActive === void 0 ? false : _ref$isActive, _ref$onBlur = _ref.onBlur, onBlur = _ref$onBlur === void 0 ? noop : _ref$onBlur, _ref$onClick = _ref.onClick, onClick = _ref$onClick === void 0 ? noop : _ref$onClick, _ref$onFocus = _ref.onFocus, onFocus = _ref$onFocus === void 0 ? noop : _ref$onFocus, fieldValue = _ref.fieldValue, rest = (0, _objectWithoutPropertiesLoose2.default)(_ref, ["disabled", "isActive", "onBlur", "onClick", "onFocus", "fieldValue"]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_EditableField.TriggerUI, (0, _extends2.default)({ "aria-label": "toggle menu", "aria-haspopup": "true", "aria-expanded": isActive, "data-cy": "EditableFieldOptionsTrigger", disabled: disabled, onClick: onClick, onFocus: onFocus, onBlur: onBlur, ref: ref, type: "button" }, rest, { children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_EditableField.OptionsDropdownUI, { className: (0, _classnames.default)(_EditableField3.INPUT_CLASSNAMES.optionsDropdown, isActive && 'menu-open'), children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_Truncate.default, { className: _EditableField3.INPUT_CLASSNAMES.selectedOption, children: fieldValue.option }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, { name: _EditableField2.ACTION_ICONS.valueOption })] }), /*#__PURE__*/(0, _jsxRuntime.jsx)(_EditableField.FocusIndicatorUI, { className: _EditableField3.INPUT_CLASSNAMES.focusIndicator })] })); }); var EditableFieldInput = /*#__PURE__*/function (_React$Component) { (0, _inheritsLoose2.default)(EditableFieldInput, _React$Component); function EditableFieldInput() { var _this; for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _React$Component.call.apply(_React$Component, [this].concat(args)) || this; _this.inputRef = void 0; _this.inputWrapperRef = /*#__PURE__*/_react.default.createRef(); _this._isMounted = false; _this.state = { isDropListOpen: false }; _this.setInputNode = function (node) { _this.inputRef = node; }; _this.setInputTitle = function () { var fieldValue = _this.props.fieldValue; var inputNode = _this.inputRef; var parentNode = (0, _EditableField3.findParentByClassName)(inputNode, _EditableField3.EDITABLEFIELD_CLASSNAMES.field); if (!parentNode) return; var contentNode = parentNode.querySelector("." + _EditableField3.MASK_CLASSNAMES.value + " ." + _EditableField3.OTHERCOMPONENTS_CLASSNAMES.truncateContent); var firstChunkNode = parentNode.querySelector("." + _EditableField3.MASK_CLASSNAMES.value + " ." + _EditableField3.TRUNCATED_CLASSNAMES.firstChunk); if ((0, _EditableField3.isEllipsisActive)(contentNode) || (0, _EditableField3.isEllipsisActive)(firstChunkNode)) { inputNode && inputNode.setAttribute('title', fieldValue.value); } }; _this.handleInputFocus = function (event) { var _this$props = _this.props, name = _this$props.name, onInputFocus = _this$props.onInputFocus; onInputFocus({ name: name, event: event }); }; _this.handleInputBlur = function (event) { var _this$props2 = _this.props, name = _this$props2.name, onInputBlur = _this$props2.onInputBlur, valueOptions = _this$props2.valueOptions; // Lots of async stuff happening that need this event as is // so allow references to it to be maintained event && event.persist && event.persist(); if (valueOptions) { setTimeout(function () { if (!_this.state.isDropListOpen) { onInputBlur({ name: name, event: event }); } }, 100); } else { onInputBlur({ name: name, event: event }); } }; _this.handleOptionFocus = function (event) { var _this$props3 = _this.props, disabled = _this$props3.disabled, name = _this$props3.name, onOptionFocus = _this$props3.onOptionFocus; if (!disabled) { onOptionFocus({ name: name, event: event }); } }; _this.handleChange = function (event) { var onChange = _this.props.onChange; onChange({ inputValue: event.currentTarget.value, name: _this.props.name, event: event }); }; _this.handleKeyDown = function (event) { var isEnter = event.key === _Keys.key.ENTER; var isDropdownTrigger = event.target.classList.contains(_EditableField3.OTHERCOMPONENTS_CLASSNAMES.dropdownTrigger); if (isEnter && isDropdownTrigger) { return; } var _this$props4 = _this.props, name = _this$props4.name, onKeyDown = _this$props4.onKeyDown; var inputNode = _this.inputRef; onKeyDown({ event: event, name: name }).then(function () { // In case the value is longer than the width of the input // lets move the cursor to the very beginning // when clicking the input the cursor will be at the expected position :) if (inputNode && inputNode.setSelectionRange) { inputNode.setSelectionRange(0, 0); } }).catch(function (err) {// Do nothing }); }; _this.handleKeyPress = function (event) { var _this$props5 = _this.props, name = _this$props5.name, onKeyPress = _this$props5.onKeyPress; onKeyPress({ event: event, name: name }); }; _this.handleKeyUp = function (event) { var _this$props6 = _this.props, name = _this$props6.name, onKeyUp = _this$props6.onKeyUp; onKeyUp({ event: event, name: name }); }; _this.handleDropdownSelect = function (selection) { var _this$props7 = _this.props, name = _this$props7.name, onOptionSelection = _this$props7.onOptionSelection; onOptionSelection({ name: name, selection: selection }); }; _this.handleOpenCloseDropList = function (isOpen) { if (_this._isMounted) { _this.setState({ isDropListOpen: isOpen }); } }; _this.renderOptions = function () { var _this$props8 = _this.props, disabled = _this$props8.disabled, fieldValue = _this$props8.fieldValue, valueOptions = _this$props8.valueOptions; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_EditableField.OptionsWrapperUI, { className: _EditableField3.INPUT_CLASSNAMES.optionsWrapper, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_DropList.default, { className: _EditableField3.INPUT_CLASSNAMES.dropdown, items: valueOptions, onSelect: _this.handleDropdownSelect, onOpenedStateChange: _this.handleOpenCloseDropList, toggler: /*#__PURE__*/(0, _jsxRuntime.jsx)(Toggler, { className: _EditableField3.INPUT_CLASSNAMES.optionsTrigger, disabled: disabled, fieldValue: fieldValue, onFocus: _this.handleOptionFocus }), tippyOptions: { appendTo: function appendTo(reference) { return reference.closest('.EditableField__field.has-options'); }, offset: [0, 10] } }) }); }; _this.renderValidationInfo = function () { var _this$props9 = _this.props, name = _this$props9.name, validationInfo = _this$props9.validationInfo; if (!validationInfo) return null; if (name !== validationInfo.name) return null; var DEFAULT_ICON = 'alert-small'; return /*#__PURE__*/(0, _jsxRuntime.jsx)(_EditableField.ValidationIconUI, { className: _EditableField3.INPUT_CLASSNAMES.validation, color: (0, _EditableField3.getValidationColor)(validationInfo), children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Tooltip.default, { animationDelay: 0, animationDuration: 0, display: "block", placement: "top-end", title: validationInfo.message, appendTo: _this.inputWrapperRef.current, children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_Icon.default, { name: validationInfo.icon || DEFAULT_ICON, size: 24 }) }) }); }; return _this; } var _proto = EditableFieldInput.prototype; _proto.componentDidMount = function componentDidMount() { this._isMounted = true; var isActive = this.props.isActive; this.setInputTitle(); if (isActive) { var inputNode = this.inputRef; inputNode && inputNode.focus(); } }; _proto.componentWillUnmount = function componentWillUnmount() { this._isMounted = false; }; _proto.shouldComponentUpdate = function shouldComponentUpdate(nextProps) { if (!(0, _fastDeepEqual.default)(this.props.fieldValue, nextProps.fieldValue)) { return true; } if (this.props.isActive !== nextProps.isActive) { return true; } if (this.props.disabled !== nextProps.disabled) { return true; } if (!(0, _fastDeepEqual.default)(this.props.validationInfo, nextProps.validationInfo)) { return true; } return false; }; _proto.componentDidUpdate = function componentDidUpdate() { this.setInputTitle(); }; _proto.render = function render() { var _this$props10 = this.props, disabled = _this$props10.disabled, fieldValue = _this$props10.fieldValue, isActive = _this$props10.isActive, inline = _this$props10.inline, name = _this$props10.name, placeholder = _this$props10.placeholder, type = _this$props10.type, validationInfo = _this$props10.validationInfo, valueOptions = _this$props10.valueOptions, rest = (0, _objectWithoutPropertiesLoose2.default)(_this$props10, ["disabled", "fieldValue", "isActive", "inline", "name", "placeholder", "type", "validationInfo", "valueOptions"]); return /*#__PURE__*/(0, _jsxRuntime.jsxs)(_EditableField.EditableFieldInputUI, { className: (0, _classnames.default)(_EditableField3.INPUT_CLASSNAMES.content, inline && _EditableField3.STATES_CLASSNAMES.isInline, disabled && _EditableField3.STATES_CLASSNAMES.isDisabled, validationInfo && name === validationInfo.name && _EditableField3.STATES_CLASSNAMES.withValidation), children: [valueOptions ? this.renderOptions() : null, /*#__PURE__*/(0, _jsxRuntime.jsxs)(_EditableField.InputWrapperUI, { className: _EditableField3.INPUT_CLASSNAMES.inputWrapper, withPlaceholder: placeholder, value: fieldValue.value, ref: this.inputWrapperRef, children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_EditableField.InputUI, (0, _extends2.default)({}, (0, _getValidProps.default)(rest), { className: _EditableField3.INPUT_CLASSNAMES.input, id: name, ref: this.setInputNode, name: name, placeholder: placeholder, type: type === 'password' ? type : 'text', value: fieldValue.value, onBlur: this.handleInputBlur, onChange: this.handleChange, onFocus: this.handleInputFocus, onKeyDown: this.handleKeyDown })), this.renderValidationInfo(), /*#__PURE__*/(0, _jsxRuntime.jsx)(_EditableField.FocusIndicatorUI, { className: _EditableField3.INPUT_CLASSNAMES.focusIndicator, color: (0, _EditableField3.getValidationColor)(validationInfo) })] })] }); }; return EditableFieldInput; }(_react.default.Component); exports.EditableFieldInput = EditableFieldInput; EditableFieldInput.className = _EditableField3.INPUT_CLASSNAMES.component; EditableFieldInput.defaultProps = { 'data-cy': 'EditableFieldInput', disabled: false, fieldValue: '', isActive: false, inline: false, placeholder: '', type: _EditableField2.FIELDTYPES.text, innerRef: noop, onInputFocus: noop, onInputBlur: noop, onOptionFocus: noop, onOptionSelection: noop, onOptionBlur: noop, onChange: noop, onKeyDown: noop, onKeyPress: noop, onKeyUp: noop, deleteAction: noop, customAction: noop }; EditableFieldInput.propTypes = { actions: _propTypes.default.arrayOf(_propTypes.default.object), className: _propTypes.default.string, /** Data attr for Cypress tests. */ 'data-cy': _propTypes.default.string, disabled: _propTypes.default.bool, fieldValue: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.object]), inline: _propTypes.default.bool, isActive: _propTypes.default.bool, name: _propTypes.default.oneOfType([_propTypes.default.string, _propTypes.default.number]), placeholder: _propTypes.default.string, type: _propTypes.default.string, validationInfo: _propTypes.default.object, valueOptions: _propTypes.default.arrayOf(_propTypes.default.object), innerRef: _propTypes.default.func, onInputFocus: _propTypes.default.func, onInputBlur: _propTypes.default.func, onOptionFocus: _propTypes.default.func, onOptionBlur: _propTypes.default.func, onOptionSelection: _propTypes.default.func, onChange: _propTypes.default.func, onKeyDown: _propTypes.default.func, onKeyPress: _propTypes.default.func, onKeyUp: _propTypes.default.func, deleteAction: _propTypes.default.func, customAction: _propTypes.default.func }; var _default = EditableFieldInput; exports.default = _default;