UNPKG

@lyra/components

Version:
188 lines (151 loc) 5.59 kB
'use strict'; Object.defineProperty(exports, "__esModule", { value: true }); var _propTypes = require('prop-types'); var _propTypes2 = _interopRequireDefault(_propTypes); var _react = require('react'); var _react2 = _interopRequireDefault(_react); var _defaultStyle = require('part:@lyra/components/menus/default-style'); var _defaultStyle2 = _interopRequireDefault(_defaultStyle); var _reactInk = require('react-ink'); var _reactInk2 = _interopRequireDefault(_reactInk); var _reactClickOutside = require('react-click-outside'); var _reactClickOutside2 = _interopRequireDefault(_reactClickOutside); var _classnames = require('classnames'); var _classnames2 = _interopRequireDefault(_classnames); function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } class DefaultMenu extends _react2.default.Component { constructor(props) { super(props); this.lastWindowHeight = 0; this.scrollOffset = 0; this.handleClickOutside = event => { if (this.props.isOpen) { this.props.onClickOutside(event); } }; this.handleKeyDown = event => { const items = this.props.items; const selectedItem = this.state.selectedItem; const currentIndex = items.indexOf(selectedItem) || 0; const isOpen = this.props.isOpen || this.props.opened; // eslint-disable-line if (event.key == 'Escape' && isOpen) { this.props.onClose(); } if (event.key == 'ArrowDown' && isOpen && currentIndex < items.length - 1) { this.setState({ focusedItem: this.props.items[currentIndex + 1] }); } if (event.key == 'ArrowUp' && isOpen && currentIndex > 0) { this.setState({ focusedItem: this.props.items[currentIndex - 1] }); } if (event.key == 'Enter' && isOpen && this.state.selectedItem) { this.props.onAction(this.props.items[currentIndex]); } }; this.handleItemClick = event => { const actionId = event.currentTarget.getAttribute('data-action-id'); this.props.onAction(this.props.items[actionId]); }; this.handleFocus = event => { const index = event.target.getAttribute('data-action-id'); this.setState({ focusedItem: this.props.items[index] }); }; this.handleKeyPress = event => { const index = event.target.getAttribute('data-action-id'); if (event.key === 'Enter') { this.props.onAction(this.props.items[index]); } }; this.setRootElement = element => { this._rootElement = element; }; this.state = { focusedItem: null }; } componentDidMount() { window.addEventListener('keydown', this.handleKeyDown, false); window.addEventListener('resize', this.handleResize, false); } componentWillUnmount() { window.removeEventListener('resize', this.handleResize, false); window.removeEventListener('keydown', this.handleKeyDown, false); } render() { const focusedItem = this.state.focusedItem; var _props = this.props; const items = _props.items, ripple = _props.ripple, className = _props.className, opened = _props.opened; const isOpen = opened || this.props.isOpen; return _react2.default.createElement( 'div', { ref: this.setRootElement, className: `${isOpen ? _defaultStyle2.default.isOpen : _defaultStyle2.default.closed} ${className || ''}` }, _react2.default.createElement( 'ul', { className: _defaultStyle2.default.list }, items.map((item, i) => { const Icon = item.icon; return _react2.default.createElement( 'li', { key: i, className: (0, _classnames2.default)([item === focusedItem ? _defaultStyle2.default.focusedItem : _defaultStyle2.default.item, item.isDisabled && _defaultStyle2.default.isDisabled, item.divider && _defaultStyle2.default.divider]) }, _react2.default.createElement( 'a', { onClick: item.isDisabled ? null : this.handleItemClick, 'data-action-id': i, className: item.danger ? _defaultStyle2.default.dangerLink : _defaultStyle2.default.link, onFocus: this.handleFocus, tabIndex: '0', onKeyPress: this.handleKeyPress }, Icon && _react2.default.createElement( 'span', { className: _defaultStyle2.default.iconContainer }, _react2.default.createElement(Icon, { className: _defaultStyle2.default.icon }) ), item.title, ripple && !item.isDisabled && _react2.default.createElement(_reactInk2.default, { duration: 200, opacity: 0.1, radius: 200 }) ) ); }) ) ); } } DefaultMenu.propTypes = { onAction: _propTypes2.default.func.isRequired, isOpen: _propTypes2.default.bool, ripple: _propTypes2.default.bool, className: _propTypes2.default.string, onClickOutside: _propTypes2.default.func, onClose: _propTypes2.default.func, items: _propTypes2.default.arrayOf(_propTypes2.default.shape({ title: _propTypes2.default.node.isRequired, icon: _propTypes2.default.func })) }; DefaultMenu.defaultProps = { menuOpened: false, isOpen: false, fullWidth: false, icon: false, ripple: true, onClickOutside() {}, onClose() {} }; exports.default = (0, _reactClickOutside2.default)(DefaultMenu);