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