UNPKG

@elastic/eui

Version:

Elastic UI Component Library

328 lines (324 loc) 19.3 kB
"use strict"; var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault"); var _typeof3 = require("@babel/runtime/helpers/typeof"); Object.defineProperty(exports, "__esModule", { value: true }); exports.EuiComboBoxInput = void 0; var _extends2 = _interopRequireDefault(require("@babel/runtime/helpers/extends")); var _objectWithoutProperties2 = _interopRequireDefault(require("@babel/runtime/helpers/objectWithoutProperties")); var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof")); var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck")); var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass")); var _assertThisInitialized2 = _interopRequireDefault(require("@babel/runtime/helpers/assertThisInitialized")); var _inherits2 = _interopRequireDefault(require("@babel/runtime/helpers/inherits")); var _possibleConstructorReturn2 = _interopRequireDefault(require("@babel/runtime/helpers/possibleConstructorReturn")); var _getPrototypeOf2 = _interopRequireDefault(require("@babel/runtime/helpers/getPrototypeOf")); var _defineProperty2 = _interopRequireDefault(require("@babel/runtime/helpers/defineProperty")); var _react = _interopRequireWildcard(require("react")); var _propTypes = _interopRequireDefault(require("prop-types")); var _classnames = _interopRequireDefault(require("classnames")); var _reactInputAutosize = _interopRequireDefault(require("react-input-autosize")); var _services = require("../../../services"); var _accessibility = require("../../accessibility"); var _form_control_layout = require("../../form/form_control_layout"); var _num_icons = require("../../form/form_control_layout/_num_icons"); var _combo_box_pill = require("./combo_box_pill"); var _react2 = require("@emotion/react"); var _excluded = ["key", "label", "color", "onClick"]; 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 || _typeof3(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 _createSuper(Derived) { var hasNativeReflectConstruct = _isNativeReflectConstruct(); return function _createSuperInternal() { var Super = (0, _getPrototypeOf2.default)(Derived), result; if (hasNativeReflectConstruct) { var NewTarget = (0, _getPrototypeOf2.default)(this).constructor; result = Reflect.construct(Super, arguments, NewTarget); } else { result = Super.apply(this, arguments); } return (0, _possibleConstructorReturn2.default)(this, result); }; } function _isNativeReflectConstruct() { if (typeof Reflect === "undefined" || !Reflect.construct) return false; if (Reflect.construct.sham) return false; if (typeof Proxy === "function") return true; try { Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); return true; } catch (e) { return false; } } /* * Copyright Elasticsearch B.V. and/or licensed to Elasticsearch B.V. under one * or more contributor license agreements. Licensed under the Elastic License * 2.0 and the Server Side Public License, v 1; you may not use this file except * in compliance with, at your election, the Elastic License 2.0 or the Server * Side Public License, v 1. */ var EuiComboBoxInput = /*#__PURE__*/function (_Component) { (0, _inherits2.default)(EuiComboBoxInput, _Component); var _super = _createSuper(EuiComboBoxInput); function EuiComboBoxInput() { var _this; (0, _classCallCheck2.default)(this, EuiComboBoxInput); for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) { args[_key] = arguments[_key]; } _this = _super.call.apply(_super, [this].concat(args)); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "state", { hasFocus: false }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "updatePosition", function () { // Wait a beat for the DOM to update, since we depend on DOM elements' bounds. requestAnimationFrame(function () { _this.props.updatePosition(); }); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onFocus", function (event) { _this.props.onFocus(event); _this.setState({ hasFocus: true }); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onBlur", function (event) { if (_this.props.onBlur) { _this.props.onBlur(event); } _this.setState({ hasFocus: false }); }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "onKeyDown", function (event) { var _this$props = _this.props, searchValue = _this$props.searchValue, selectedOptions = _this$props.selectedOptions, onRemoveOption = _this$props.onRemoveOption, singleSelection = _this$props.singleSelection, isListOpen = _this$props.isListOpen, onOpenListClick = _this$props.onOpenListClick; // When backspacing from an empty input, delete the last pill option in the list var searchIsEmpty = !searchValue.length; var hasPills = selectedOptions.length; if (event.key === _services.keys.BACKSPACE && searchIsEmpty && hasPills) { onRemoveOption(selectedOptions[selectedOptions.length - 1]); if (!!singleSelection && !isListOpen) { onOpenListClick(); } } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "inputOnChange", function (event) { var _this$props2 = _this.props, onChange = _this$props2.onChange, searchValue = _this$props2.searchValue; if (onChange) { onChange(event.target.value); } }); (0, _defineProperty2.default)((0, _assertThisInitialized2.default)(_this), "inputRefCallback", function (ref) { var autoSizeInputRef = _this.props.autoSizeInputRef; if (autoSizeInputRef) { autoSizeInputRef(ref); } }); return _this; } (0, _createClass2.default)(EuiComboBoxInput, [{ key: "componentDidUpdate", value: function componentDidUpdate(prevProps) { var searchValue = prevProps.searchValue; // We need to update the position of everything if the user enters enough input to change // the size of the input. if (searchValue !== this.props.searchValue) { this.updatePosition(); } } }, { key: "render", value: function render() { var _this$props3 = this.props, compressed = _this$props3.compressed, focusedOptionId = _this$props3.focusedOptionId, fullWidth = _this$props3.fullWidth, hasSelectedOptions = _this$props3.hasSelectedOptions, id = _this$props3.id, inputRef = _this$props3.inputRef, isDisabled = _this$props3.isDisabled, isListOpen = _this$props3.isListOpen, noIcon = _this$props3.noIcon, onClear = _this$props3.onClear, onClick = _this$props3.onClick, onCloseListClick = _this$props3.onCloseListClick, onOpenListClick = _this$props3.onOpenListClick, onRemoveOption = _this$props3.onRemoveOption, placeholder = _this$props3.placeholder, rootId = _this$props3.rootId, searchValue = _this$props3.searchValue, selectedOptions = _this$props3.selectedOptions, singleSelectionProp = _this$props3.singleSelection, toggleButtonRef = _this$props3.toggleButtonRef, value = _this$props3.value, prepend = _this$props3.prepend, append = _this$props3.append, isLoading = _this$props3.isLoading, isInvalid = _this$props3.isInvalid, autoFocus = _this$props3.autoFocus, ariaLabel = _this$props3['aria-label'], ariaLabelledby = _this$props3['aria-labelledby']; var singleSelection = Boolean(singleSelectionProp); var asPlainText = singleSelectionProp && (0, _typeof2.default)(singleSelectionProp) === 'object' && singleSelectionProp.asPlainText || false; var pills = selectedOptions ? selectedOptions.map(function (option) { var key = option.key, label = option.label, color = option.color, onClick = option.onClick, rest = (0, _objectWithoutProperties2.default)(option, _excluded); var pillOnClose = isDisabled || singleSelection || onClick ? undefined : onRemoveOption; return (0, _react2.jsx)(_combo_box_pill.EuiComboBoxPill, (0, _extends2.default)({ option: option, onClose: pillOnClose, key: key !== null && key !== void 0 ? key : label.toLowerCase(), color: color, onClick: onClick, onClickAriaLabel: onClick ? 'Change' : undefined, asPlainText: asPlainText }, rest), label); }) : null; var removeOptionMessage; var removeOptionMessageId; if (this.state.hasFocus) { var readPlaceholder = placeholder ? "".concat(placeholder, ".") : ''; var removeOptionMessageContent = "Combo box. Selected. ".concat(searchValue ? "".concat(searchValue, ". Selected. ") : '').concat(selectedOptions && selectedOptions.length > 0 ? "".concat(value, ". Press Backspace to delete ").concat(selectedOptions[selectedOptions.length - 1].label, ". ") : '', "Combo box input. ").concat(readPlaceholder, " Type some text or, to display a list of choices, press Down Arrow. ") + 'To exit the list of choices, press Escape.'; removeOptionMessageId = rootId('removeOptionMessage'); // aria-live="assertive" will read this message aloud immediately once it enters the DOM. // We'll render to the DOM when the input gains focus and remove it when the input loses focus. // We'll use aria-hidden to prevent default aria information from being read by the screen // reader. removeOptionMessage = (0, _react2.jsx)(_accessibility.EuiScreenReaderOnly, null, (0, _react2.jsx)("span", { "aria-live": "polite", id: removeOptionMessageId }, removeOptionMessageContent)); } var placeholderMessage; if (placeholder && selectedOptions && !selectedOptions.length && !searchValue) { placeholderMessage = (0, _react2.jsx)("p", { className: "euiComboBoxPlaceholder" }, placeholder); } var clickProps = {}; if (!isDisabled && onClear && hasSelectedOptions) { clickProps.clear = { 'data-test-subj': 'comboBoxClearButton', onClick: onClear }; } var icon; if (!noIcon && !isDisabled) { icon = { 'aria-label': isListOpen ? 'Close list of options' : 'Open list of options', 'data-test-subj': 'comboBoxToggleListButton', disabled: isDisabled, onClick: isListOpen && !isDisabled ? onCloseListClick : onOpenListClick, ref: toggleButtonRef, side: 'right', tabIndex: -1, type: 'arrowDown' }; } var numIconsClass = (0, _num_icons.getFormControlClassNameForIconCount)({ isDropdown: !noIcon, clear: !!clickProps.clear, isInvalid: isInvalid, isLoading: isLoading }); var wrapClasses = (0, _classnames.default)('euiComboBox__inputWrap', numIconsClass, { 'euiComboBox__inputWrap--compressed': compressed, 'euiComboBox__inputWrap--fullWidth': fullWidth, 'euiComboBox__inputWrap--noWrap': singleSelection, 'euiComboBox__inputWrap--inGroup': prepend || append }); return (0, _react2.jsx)(_form_control_layout.EuiFormControlLayout, (0, _extends2.default)({ icon: icon }, clickProps, { inputId: id, isLoading: isLoading, isInvalid: isInvalid, compressed: compressed, fullWidth: fullWidth, prepend: prepend, append: append }), (0, _react2.jsx)("div", { className: wrapClasses, "data-test-subj": "comboBoxInput", onClick: onClick, tabIndex: -1 // becomes onBlur event's relatedTarget, otherwise relatedTarget is null when clicking on this div }, !singleSelection || !searchValue ? pills : null, placeholderMessage, (0, _react2.jsx)(_reactInputAutosize.default, { "aria-activedescendant": focusedOptionId, "aria-autocomplete": "list", "aria-controls": isListOpen ? rootId('listbox') : '', "aria-expanded": isListOpen, "aria-label": ariaLabel, "aria-labelledby": ariaLabelledby, "aria-invalid": isInvalid, className: "euiComboBox__input", "data-test-subj": "comboBoxSearchInput", disabled: isDisabled, id: id, inputRef: inputRef, onBlur: this.onBlur, onChange: this.inputOnChange, onFocus: this.onFocus, onKeyDown: this.onKeyDown, ref: this.inputRefCallback, role: "combobox", style: { fontSize: 14 }, value: searchValue, autoFocus: autoFocus }), removeOptionMessage)); } }]); return EuiComboBoxInput; }(_react.Component); exports.EuiComboBoxInput = EuiComboBoxInput; EuiComboBoxInput.propTypes = { autoSizeInputRef: _propTypes.default.any, compressed: _propTypes.default.bool.isRequired, focusedOptionId: _propTypes.default.string, fullWidth: _propTypes.default.bool, hasSelectedOptions: _propTypes.default.bool.isRequired, id: _propTypes.default.string, inputRef: _propTypes.default.any, isDisabled: _propTypes.default.bool, isListOpen: _propTypes.default.bool.isRequired, noIcon: _propTypes.default.bool.isRequired, onBlur: _propTypes.default.any, onChange: _propTypes.default.func, onClear: _propTypes.default.func, onClick: _propTypes.default.func, onCloseListClick: _propTypes.default.func.isRequired, onFocus: _propTypes.default.any.isRequired, onOpenListClick: _propTypes.default.func.isRequired, onRemoveOption: _propTypes.default.func.isRequired, placeholder: _propTypes.default.string, rootId: _propTypes.default.any.isRequired, searchValue: _propTypes.default.string.isRequired, selectedOptions: _propTypes.default.arrayOf(_propTypes.default.shape({ isGroupLabelOption: _propTypes.default.bool, label: _propTypes.default.string.isRequired, key: _propTypes.default.string, options: _propTypes.default.arrayOf(_propTypes.default.shape({ isGroupLabelOption: _propTypes.default.bool, label: _propTypes.default.string.isRequired, key: _propTypes.default.string, options: _propTypes.default.arrayOf(_propTypes.default.any.isRequired), value: _propTypes.default.any, className: _propTypes.default.string, "aria-label": _propTypes.default.string, "data-test-subj": _propTypes.default.string, css: _propTypes.default.any }).isRequired), value: _propTypes.default.any, className: _propTypes.default.string, "aria-label": _propTypes.default.string, "data-test-subj": _propTypes.default.string, css: _propTypes.default.any }).isRequired).isRequired, singleSelection: _propTypes.default.oneOfType([_propTypes.default.bool.isRequired, _propTypes.default.shape({ asPlainText: _propTypes.default.bool }).isRequired]), toggleButtonRef: _propTypes.default.any, updatePosition: _propTypes.default.func.isRequired, value: _propTypes.default.string, prepend: _propTypes.default.oneOfType([_propTypes.default.oneOfType([_propTypes.default.string.isRequired, _propTypes.default.element.isRequired]).isRequired, _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.string.isRequired, _propTypes.default.element.isRequired]).isRequired).isRequired]), append: _propTypes.default.oneOfType([_propTypes.default.oneOfType([_propTypes.default.string.isRequired, _propTypes.default.element.isRequired]).isRequired, _propTypes.default.arrayOf(_propTypes.default.oneOfType([_propTypes.default.string.isRequired, _propTypes.default.element.isRequired]).isRequired).isRequired]), isLoading: _propTypes.default.bool, isInvalid: _propTypes.default.bool, autoFocus: _propTypes.default.bool, "aria-label": _propTypes.default.string, "aria-labelledby": _propTypes.default.string, className: _propTypes.default.string, "data-test-subj": _propTypes.default.string, css: _propTypes.default.any };