UNPKG

@lyra/components

Version:
316 lines (278 loc) 10.8 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _includes2 = require('lodash/includes'); var _includes3 = _interopRequireDefault(_includes2); var _uniqueId2 = require('lodash/uniqueId'); var _uniqueId3 = _interopRequireDefault(_uniqueId2); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _styleStyle = require('part:@lyra/components/selects/style-style'); var _styleStyle2 = _interopRequireDefault(_styleStyle); var _angleDownIcon = require('part:@lyra/base/angle-down-icon'); var _angleDownIcon2 = _interopRequireDefault(_angleDownIcon); var _circleThinIcon = require('part:@lyra/base/circle-thin-icon'); var _circleThinIcon2 = _interopRequireDefault(_circleThinIcon); var _circleCheckIcon = require('part:@lyra/base/circle-check-icon'); var _circleCheckIcon2 = _interopRequireDefault(_circleCheckIcon); 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 _default = require('part:@lyra/components/lists/default'); var _reactPopper = require('react-popper'); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } /* eslint-disable complexity */ class StyleSelect extends _react2.default.PureComponent { constructor(...args) { var _temp; return _temp = super(...args), this._inputId = (0, _uniqueId3.default)('StyleSelect'), this._keyUpHandler = null, this._keyDownHandler = null, this.state = { hasFocus: false, arrowNavigationPosition: 0 }, this.handleClickOutside = () => { this.handleCloseList(); }, this.handleFocus = event => { this.setState({ hasFocus: true }); if (this.props.onFocus) { this.props.onFocus(event); } }, this.handleBlur = event => { this.setState({ hasFocus: false }); if (this.props.onBlur) { this.props.onBlur(event); } }, this.handleSelect = item => { this.props.onChange(item); this.handleCloseList(); }, this.handleOpenList = () => { const disabled = this.props.disabled; if (!disabled) { this.setState({ showList: true }); this.props.onOpen(); } }, this.handleCloseList = () => { this.setState({ showList: false }); this.props.onClose(); }, this.handleInnerClick = () => { if (this.state.showList) { this.handleCloseList(); } else { this.handleOpenList(); } }, this.handleKeyDown = event => { var _props = this.props; const items = _props.items, value = _props.value; var _state = this.state; const hasFocus = _state.hasFocus, showList = _state.showList, arrowNavigationPosition = _state.arrowNavigationPosition; if (!hasFocus) { return; } if (event.key === 'Tab') { this.handleCloseList(); } if (items) { if (['ArrowUp', 'ArrowDown'].includes(event.key) && !showList) { event.preventDefault(); const openPosition = value ? items.indexOf(value[0]) || 0 : 0; this.setState({ showList: true, arrowNavigationPosition: openPosition }); } if (showList && event.key == 'ArrowUp' && arrowNavigationPosition > 0) { event.preventDefault(); this.setState({ arrowNavigationPosition: arrowNavigationPosition - 1 }); return; } if (showList && event.key == 'ArrowDown' && arrowNavigationPosition < items.length - 1) { event.preventDefault(); this.setState({ arrowNavigationPosition: arrowNavigationPosition + 1 }); } } }, this.handleKeyUp = event => { const items = this.props.items; var _state2 = this.state; const showList = _state2.showList, hasFocus = _state2.hasFocus, arrowNavigationPosition = _state2.arrowNavigationPosition; if (!hasFocus) { return; } if (event.key === 'Enter' && showList) { this.setState({ showList: true }); this.handleSelect(items[arrowNavigationPosition]); } if (event.key === 'Enter' && !showList) { this.handleOpenList(); } }, this.setPopperElement = element => { this._popperElement = element; }, _temp; } componentDidMount() { this._keyUpHandler = document.body.addEventListener('keyup', this.handleKeyUp); this._keyDownHandler = document.body.addEventListener('keydown', this.handleKeyDown); } componentWillUnmount() { document.body.removeEventListener('keyup', this._keyUpHandler); document.body.removeEventListener('keydown', this._keyDownHandler); } render() { var _props2 = this.props; const className = _props2.className, disabled = _props2.disabled, items = _props2.items, placeholder = _props2.placeholder, transparent = _props2.transparent, value = _props2.value; const showList = this.state.showList; return _react2.default.createElement( _reactPopper.Manager, null, _react2.default.createElement( 'div', { className: ` ${_styleStyle2.default.root} ${transparent ? _styleStyle2.default.transparent : ''} ${disabled ? _styleStyle2.default.disabled : ''} ${className || ''} `, tabIndex: 0, onClick: this.handleInnerClick, onBlur: this.handleBlur, onFocus: this.handleFocus }, _react2.default.createElement( _reactPopper.Target, null, _react2.default.createElement( 'div', { className: _styleStyle2.default.inner }, _react2.default.createElement( 'div', { className: _styleStyle2.default.selectContainer }, _react2.default.createElement( 'span', { className: _styleStyle2.default.text }, value && value.length > 1 && 'Multiple', value && value.length === 1 && value[0].title, !value && placeholder ), _react2.default.createElement( 'div', { className: _styleStyle2.default.arrow }, _react2.default.createElement(_angleDownIcon2.default, { color: 'inherit' }) ) ) ) ), showList && _react2.default.createElement( _portal.Portal, null, _react2.default.createElement( _stacked2.default, null, isActive => { return _react2.default.createElement( 'div', { className: _styleStyle2.default.portal }, _react2.default.createElement( _reactPopper.Popper, { placement: 'bottom-start' }, _react2.default.createElement(_escapable2.default, { onEscape: isActive ? this.handleCloseList : undefined }), _react2.default.createElement( _captureOutsideClicks2.default, { onClickOutside: isActive ? this.handleCloseList : undefined }, _react2.default.createElement( 'div', { ref: this.setPopperElement }, _react2.default.createElement( _default.List, { className: _styleStyle2.default.list }, items.map((item, index) => { const isMultiple = value && value.length > 1 && (0, _includes3.default)(value, item); const isItemActive = value && value.length === 1 && value[0] == item; const isSelected = index === this.state.arrowNavigationPosition; const classNames = [isItemActive ? _styleStyle2.default.itemActive : _styleStyle2.default.item, isMultiple ? _styleStyle2.default.itemMultiple : null, isSelected ? _styleStyle2.default.itemSelected : null].filter(Boolean); return _react2.default.createElement( 'a', { className: classNames.join(' '), key: item.key, title: item.title, onClick: () => this.handleSelect(item) }, _react2.default.createElement( 'div', { className: _styleStyle2.default.itemIcon }, isItemActive && _react2.default.createElement(_circleCheckIcon2.default, null), isMultiple && _react2.default.createElement(_circleThinIcon2.default, null) ), _react2.default.createElement( 'div', { className: _styleStyle2.default.itemContent }, this.props.renderItem(item) ) ); }) ) ) ) ) ); } ) ) ) ); } } StyleSelect.propTypes = { className: _propTypes2.default.string, disabled: _propTypes2.default.bool, items: _propTypes2.default.arrayOf(_propTypes2.default.shape({ title: _propTypes2.default.string, active: _propTypes2.default.bool })), onBlur: _propTypes2.default.func, onChange: _propTypes2.default.func, onClose: _propTypes2.default.func, onFocus: _propTypes2.default.func, onOpen: _propTypes2.default.func, placeholder: _propTypes2.default.string, renderItem: _propTypes2.default.func, transparent: _propTypes2.default.bool, value: _propTypes2.default.array }; StyleSelect.defaultProps = { className: '', disabled: false, onChange() {}, onOpen() {}, onClose() {}, items: [] }; exports.default = StyleSelect;