UNPKG

@skbkontur/ui-kit

Version:

201 lines 8.07 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var tslib_1 = require("tslib"); var React = tslib_1.__importStar(require("react")); var react_dom_1 = tslib_1.__importDefault(require("react-dom")); var ScrollContainer_1 = tslib_1.__importDefault(require("../../ScrollContainer/ScrollContainer")); var utils_1 = require("./utils"); var InternalMenuView_1 = require("./InternalMenuView"); var InternalMenu = /** @class */ (function (_super) { tslib_1.__extends(InternalMenu, _super); function InternalMenu() { var _this = _super !== null && _super.apply(this, arguments) || this; _this.state = { highlightedIndex: -1 }; _this.scrollContainer = null; _this.highlighted = null; _this.rootElement = null; _this.focusWithScrollRestore = function () { if (_this.rootElement && window) { var scrollX_1 = window.scrollX; var scrollY_1 = window.scrollY; _this.rootElement.focus(); window.scrollTo(scrollX_1, scrollY_1); } }; _this.setInitialSelection = function () { if (_this.props.initialSelectedItemIndex === undefined) { return; } for (var i = _this.props.initialSelectedItemIndex; i > -1; i--) { _this.moveDown(); } }; _this.refScrollContainer = function (scrollContainer) { _this.scrollContainer = scrollContainer; }; _this.scrollToSelected = function () { if (_this.scrollContainer && _this.highlighted) { var highlightedDomNode = react_dom_1.default.findDOMNode(_this.highlighted); if (highlightedDomNode instanceof HTMLElement) { _this.scrollContainer.scrollTo(highlightedDomNode); } } }; _this.highlightItem = function (index) { _this.setState({ highlightedIndex: index }); if (_this.rootElement && _this.rootElement.focus) { _this.rootElement.focus(); } }; _this.unhighlight = function () { _this.setState({ highlightedIndex: -1 }); }; _this.moveUp = function () { _this.move(-1); }; _this.moveDown = function () { _this.move(1); }; _this.handleKeyDown = function (event) { if (typeof _this.props.onKeyDown === 'function') { _this.props.onKeyDown(event); } if (event.defaultPrevented) { return; } switch (event.key) { case 'ArrowUp': event.preventDefault(); _this.moveUp(); break; case 'ArrowDown': event.preventDefault(); _this.moveDown(); break; case 'Enter': event.preventDefault(); _this.select(_this.state.highlightedIndex, false, event); break; default: break; } }; return _this; } InternalMenu.prototype.componentDidMount = function () { this.focusWithScrollRestore(); this.setInitialSelection(); }; InternalMenu.prototype.render = function () { var _this = this; var enableIconPadding = React.Children.toArray(this.props.children).some(function (x) { return x && typeof x === 'object' && x.props.icon; }); if (this.isEmpty()) { return null; } return (React.createElement(InternalMenuView_1.InternalMenuStyledWrapper, { style: { width: this.props.width, maxHeight: this.props.maxHeight }, onKeyDown: this.handleKeyDown, innerRef: function (element) { _this.rootElement = element; }, tabIndex: 0 }, React.createElement(ScrollContainer_1.default, { ref: this.refScrollContainer, maxHeight: this.props.maxHeight, preventWindowScroll: this.props.preventWindowScroll }, React.Children.map(this.props.children, function (child, index) { if (!React.isValidElement(child)) { return child; } if (enableIconPadding && (utils_1.isMenuItem(child) || utils_1.isMenuHeader(child))) { child = React.cloneElement(child, { _enableIconPadding: true }); } if (utils_1.isActiveElement(child)) { var isHighlightedMenuItem_1 = _this.state.highlightedIndex === index; return React.cloneElement(child, { ref: function (element) { if (isHighlightedMenuItem_1) { _this.highlighted = element; } return element; }, state: isHighlightedMenuItem_1 ? 'hover' : child.props.state, onClick: _this.select.bind(_this, index, false), onMouseEnter: function () { return _this.highlightItem(index); }, onMouseLeave: _this.unhighlight }); } return child; })))); }; InternalMenu.prototype.select = function (index, shouldHandleHref, event) { var item = childrenToArray(this.props.children)[index]; if (utils_1.isActiveElement(item)) { if (shouldHandleHref && item.props.href) { if (item.props.target) { window.open(item.props.href, item.props.target); } else { location.href = item.props.href; } } if (item.props.onClick) { item.props.onClick(event); } if (this.props.onItemClick) { this.props.onItemClick(event.type); } return true; } return false; }; InternalMenu.prototype.move = function (step) { var _this = this; this.setState(function (state) { var children = childrenToArray(_this.props.children); if (!children.some(utils_1.isActiveElement)) { return null; } var index = state.highlightedIndex; do { index += step; if (!_this.props.cyclicSelection && (index < 0 || index > children.length)) { return null; } if (index < 0) { index = children.length - 1; } else if (index > children.length) { index = 0; } var child = children[index]; if (utils_1.isActiveElement(child)) { return { highlightedIndex: index }; } } while (index !== state.highlightedIndex); return null; }, this.scrollToSelected); }; InternalMenu.prototype.isEmpty = function () { var children = this.props.children; return !children || !childrenToArray(children).filter(isExist).length; }; InternalMenu.defaultProps = { width: 'auto', maxHeight: 301, hasShadow: true, preventWindowScroll: true, cyclicSelection: true, initialSelectedItemIndex: -1 }; return InternalMenu; }(React.Component)); exports.default = InternalMenu; function isExist(value) { return value !== null && value !== undefined; } function childrenToArray(children) { var ret = []; // Use forEach instead of map to avoid cloning for key unifying. React.Children.toArray(children).forEach(function (child) { ret.push(child); }); return ret; } //# sourceMappingURL=InternalMenu.js.map