UNPKG

@lyra/components

Version:
313 lines (269 loc) 11 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _get2 = require('lodash/get'); var _get3 = _interopRequireDefault(_get2); 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 _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _searchableStyle = require('part:@lyra/components/selects/searchable-style'); var _searchableStyle2 = _interopRequireDefault(_searchableStyle); var _angleDownIcon = require('part:@lyra/base/angle-down-icon'); var _angleDownIcon2 = _interopRequireDefault(_angleDownIcon); var _default = require('part:@lyra/components/textinputs/default'); var _default2 = _interopRequireDefault(_default); var _spinner = require('part:@lyra/components/loading/spinner'); var _spinner2 = _interopRequireDefault(_spinner); var _closeIcon = require('part:@lyra/base/close-icon'); var _closeIcon2 = _interopRequireDefault(_closeIcon); var _SelectMenu = require('./SelectMenu'); var _SelectMenu2 = _interopRequireDefault(_SelectMenu); var _stacked = require('part:@lyra/components/utilities/stacked'); var _stacked2 = _interopRequireDefault(_stacked); var _captureOutsideClicks = require('part:@lyra/components/utilities/capture-outside-clicks'); var _captureOutsideClicks2 = _interopRequireDefault(_captureOutsideClicks); var _escapable = require('part:@lyra/components/utilities/escapable'); var _escapable2 = _interopRequireDefault(_escapable); var _portal = require('part:@lyra/components/utilities/portal'); var _reactPopper = require('react-popper'); 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; } /* eslint-disable complexity */ const noop = () => {}; class StatelessSearchableSelect extends _react2.default.PureComponent { constructor(...args) { var _temp; return _temp = super(...args), this.handleSelect = item => { this.props.onChange(item); }, this.handleArrowClick = () => { var _props = this.props; const isOpen = _props.isOpen, onOpen = _props.onOpen; if (isOpen) { this.handleClose(); } else { onOpen(); } }, this.handleArrowKeyPress = event => { if (event.key === 'Enter') { this.handleArrowClick(); } }, this.handleInputChange = event => { this.props.onInputChange(event.target.value); }, this.handleKeyDown = event => { var _props2 = this.props; const items = _props2.items, highlightIndex = _props2.highlightIndex, onHighlightIndexChange = _props2.onHighlightIndexChange, isOpen = _props2.isOpen, onOpen = _props2.onOpen; if (event.key === 'ArrowDown' && !isOpen) { onOpen(); } if (!items || items.length === 0) { return; } const lastIndex = items.length - 1; if (event.key === 'ArrowUp') { event.preventDefault(); const nextIndex = highlightIndex - 1; onHighlightIndexChange(nextIndex < 0 ? lastIndex : nextIndex); } if (event.key === 'ArrowDown') { event.preventDefault(); if (!isOpen) { onOpen(); } const nextIndex = highlightIndex + 1; onHighlightIndexChange(nextIndex > lastIndex ? 0 : nextIndex); } }, this.handleKeyUp = event => { var _props3 = this.props; const items = _props3.items, onChange = _props3.onChange, highlightIndex = _props3.highlightIndex; if (event.key === 'Enter' && highlightIndex > -1 && items[highlightIndex]) { onChange(items[highlightIndex]); } }, this.handleClose = event => { this.props.onClose(); }, this.setInput = input => { this._input = input; }, _temp; } focus() { this._input.focus(); } render() { var _props4 = this.props; const onClear = _props4.onClear, placeholder = _props4.placeholder, isLoading = _props4.isLoading, value = _props4.value, items = _props4.items, renderItem = _props4.renderItem, isOpen = _props4.isOpen, highlightIndex = _props4.highlightIndex, isInputSelected = _props4.isInputSelected, inputValue = _props4.inputValue, onChange = _props4.onChange, onInputChange = _props4.onInputChange, onOpen = _props4.onOpen, onClose = _props4.onClose, dropdownPosition = _props4.dropdownPosition, disabled = _props4.disabled, onHighlightIndexChange = _props4.onHighlightIndexChange, openItemElement = _props4.openItemElement, readOnly = _props4.readOnly, rest = _objectWithoutProperties(_props4, ['onClear', 'placeholder', 'isLoading', 'value', 'items', 'renderItem', 'isOpen', 'highlightIndex', 'isInputSelected', 'inputValue', 'onChange', 'onInputChange', 'onOpen', 'onClose', 'dropdownPosition', 'disabled', 'onHighlightIndexChange', 'openItemElement', 'readOnly']); return _react2.default.createElement( _reactPopper.Manager, null, _react2.default.createElement( _reactPopper.Target, { className: disabled ? _searchableStyle2.default.selectContainerDisabled : _searchableStyle2.default.selectContainer }, _react2.default.createElement(_default2.default, _extends({}, rest, { className: _searchableStyle2.default.select, placeholder: placeholder, onChange: this.handleInputChange, onKeyDown: this.handleKeyDown, onKeyUp: this.handleKeyUp, value: inputValue || '', selected: isInputSelected, disabled: disabled, ref: this.setInput })), _react2.default.createElement( 'div', { className: _searchableStyle2.default.functions }, openItemElement && value && _react2.default.createElement( 'span', { className: _searchableStyle2.default.openItem }, openItemElement(value) ), onClear && value && _react2.default.createElement( 'button', { type: 'button', className: _searchableStyle2.default.clearButton, onClick: onClear }, _react2.default.createElement(_closeIcon2.default, { color: 'inherit' }) ), !isLoading && _react2.default.createElement( 'div', { className: _searchableStyle2.default.arrow, onClick: disabled ? null : this.handleArrowClick, tabIndex: 0, onKeyPress: disabled ? null : this.handleArrowKeyPress }, _react2.default.createElement(_angleDownIcon2.default, { color: 'inherit' }) ), isLoading && _react2.default.createElement(_spinner2.default, null) ) ), isOpen && _react2.default.createElement( _stacked2.default, null, isActive => _react2.default.createElement( _portal.Portal, null, _react2.default.createElement( _reactPopper.Popper, { placement: 'bottom', className: _searchableStyle2.default.popper, modifiers: { preventOverflow: { boundariesElement: 'viewport' }, customStyle: { enabled: true, fn: data => { const width = (0, _get3.default)(data, 'instance.reference.clientWidth') || 500; data.styles = _extends({}, data.styles, { width: width }); return data; } } } }, _react2.default.createElement( 'div', null, _react2.default.createElement( _captureOutsideClicks2.default, { onClickOutside: isActive && isOpen ? this.handleClose : undefined }, _react2.default.createElement( 'div', { className: _searchableStyle2.default.listContainer }, _react2.default.createElement(_escapable2.default, { onEscape: event => (isActive || event.shiftKey) && this.handleClose() }), items.length === 0 && !isLoading && _react2.default.createElement( 'p', { className: _searchableStyle2.default.noResultText }, 'No results' ), items.length === 0 && isLoading && _react2.default.createElement( 'div', { className: _searchableStyle2.default.listSpinner }, _react2.default.createElement(_spinner2.default, { message: 'Loading items\u2026' }) ), items.length > 0 && _react2.default.createElement(_SelectMenu2.default, { items: items, value: value, onSelect: this.handleSelect, renderItem: renderItem, highlightIndex: highlightIndex }) ) ) ) ) ) ) ); } } exports.default = StatelessSearchableSelect; StatelessSearchableSelect.propTypes = { onChange: _propTypes2.default.func, value: _propTypes2.default.any, inputValue: _propTypes2.default.string, onInputChange: _propTypes2.default.func, onClear: _propTypes2.default.func, renderItem: _propTypes2.default.func, placeholder: _propTypes2.default.string, isLoading: _propTypes2.default.bool, isOpen: _propTypes2.default.bool, onOpen: _propTypes2.default.func, onClose: _propTypes2.default.func, openItemElement: _propTypes2.default.func, items: _propTypes2.default.array, highlightIndex: _propTypes2.default.number, onHighlightIndexChange: _propTypes2.default.func, isInputSelected: _propTypes2.default.bool, disabled: _propTypes2.default.bool, dropdownPosition: _propTypes2.default.string, readOnly: _propTypes2.default.bool }; StatelessSearchableSelect.defaultProps = { onChange: noop, onOpen: noop, onClose: noop, onInputChange: noop, isLoading: false, readOnly: false, renderItem: item => item, items: [], dropdownPosition: 'bottom' };