@lyra/components
Version:
Basic UX components
188 lines (151 loc) • 5.59 kB
JavaScript
'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);