UNPKG

@patternfly/react-core

Version:

This library provides a set of common React components for use with the PatternFly reference implementation.

134 lines • 7.56 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.DropdownMenu = void 0; const tslib_1 = require("tslib"); const React = tslib_1.__importStar(require("react")); const ReactDOM = tslib_1.__importStar(require("react-dom")); const dropdown_1 = tslib_1.__importDefault(require("@patternfly/react-styles/css/components/Dropdown/dropdown")); const react_styles_1 = require("@patternfly/react-styles"); const util_1 = require("../../../helpers/util"); const dropdownConstants_1 = require("./dropdownConstants"); class DropdownMenu extends React.Component { constructor() { super(...arguments); this.refsCollection = []; this.componentWillUnmount = () => { document.removeEventListener('keydown', this.onKeyDown); }; this.onKeyDown = (event) => { if (!this.props.isOpen || !Array.from(document.activeElement.classList).find((className) => DropdownMenu.validToggleClasses.concat(this.context.toggleClass).includes(className))) { return; } const refs = this.refsCollection; if (event.key === 'ArrowDown') { const firstFocusTargetCollection = refs.find((ref) => ref && ref[0] && !ref[0].hasAttribute('disabled')); DropdownMenu.focusFirstRef(firstFocusTargetCollection); event.stopPropagation(); } else if (event.key === 'ArrowUp') { const collectionLength = refs.length; const lastFocusTargetCollection = refs.slice(collectionLength - 1, collectionLength); const lastFocusTarget = lastFocusTargetCollection && lastFocusTargetCollection[0]; DropdownMenu.focusFirstRef(lastFocusTarget); event.stopPropagation(); } }; this.childKeyHandler = (index, innerIndex, position, custom = false) => { (0, util_1.keyHandler)(index, innerIndex, position, this.refsCollection, this.props.isGrouped ? this.refsCollection : React.Children.toArray(this.props.children), custom); }; this.sendRef = (index, nodes, isDisabled, isSeparator) => { this.refsCollection[index] = []; nodes.map((node, innerIndex) => { if (!node) { this.refsCollection[index][innerIndex] = null; } else if (!node.getAttribute) { // eslint-disable-next-line react/no-find-dom-node this.refsCollection[index][innerIndex] = ReactDOM.findDOMNode(node); } else if (isSeparator) { this.refsCollection[index][innerIndex] = null; } else { this.refsCollection[index][innerIndex] = node; } }); }; } componentDidMount() { document.addEventListener('keydown', this.onKeyDown); const { autoFocus } = this.props; if (autoFocus) { // Focus first non-disabled element const focusTargetCollection = this.refsCollection.find((ref) => ref && ref[0] && !ref[0].hasAttribute('disabled')); const focusTarget = focusTargetCollection && focusTargetCollection[0]; if (focusTarget && focusTarget.focus) { setTimeout(() => focusTarget.focus()); } } } shouldComponentUpdate() { // reset refsCollection before updating to account for child removal between mounts this.refsCollection = []; return true; } extendChildren() { const { children, isGrouped } = this.props; if (isGrouped) { let index = 0; return React.Children.map(children, (groupedChildren) => { const group = groupedChildren; const props = {}; if (group.props && group.props.children) { if (Array.isArray(group.props.children)) { props.children = React.Children.map(group.props.children, (option) => React.cloneElement(option, { index: index++ })); } else { props.children = React.cloneElement(group.props.children, { index: index++ }); } } return React.cloneElement(group, props); }); } return React.Children.map(children, (child, index) => React.cloneElement(child, { index })); } render() { const _a = this.props, { className, isOpen, position, children, component, isGrouped, setMenuComponentRef, alignments } = _a, props = tslib_1.__rest(_a, ["className", "isOpen", "position", "children", "component", "isGrouped", "setMenuComponentRef", "alignments"]); return (React.createElement(dropdownConstants_1.DropdownArrowContext.Provider, { value: { keyHandler: this.childKeyHandler, sendRef: this.sendRef } }, component === 'div' ? (React.createElement(dropdownConstants_1.DropdownContext.Consumer, null, ({ onSelect, menuClass }) => (React.createElement("div", { className: (0, react_styles_1.css)(menuClass, position === dropdownConstants_1.DropdownPosition.right && dropdown_1.default.modifiers.alignRight, (0, util_1.formatBreakpointMods)(alignments, dropdown_1.default, 'align-'), className), hidden: !isOpen, onClick: (event) => onSelect && onSelect(event), ref: setMenuComponentRef }, children)))) : ((isGrouped && (React.createElement(dropdownConstants_1.DropdownContext.Consumer, null, ({ menuClass, menuComponent }) => { const MenuComponent = (menuComponent || 'div'); return (React.createElement(MenuComponent, Object.assign({}, props, { className: (0, react_styles_1.css)(menuClass, position === dropdownConstants_1.DropdownPosition.right && dropdown_1.default.modifiers.alignRight, (0, util_1.formatBreakpointMods)(alignments, dropdown_1.default, 'align-'), className), hidden: !isOpen, role: "menu", ref: setMenuComponentRef }), this.extendChildren())); }))) || (React.createElement(dropdownConstants_1.DropdownContext.Consumer, null, ({ menuClass, menuComponent }) => { const MenuComponent = (menuComponent || component); return (React.createElement(MenuComponent, Object.assign({}, props, { className: (0, react_styles_1.css)(menuClass, position === dropdownConstants_1.DropdownPosition.right && dropdown_1.default.modifiers.alignRight, (0, util_1.formatBreakpointMods)(alignments, dropdown_1.default, 'align-'), className), hidden: !isOpen, role: "menu", ref: setMenuComponentRef }), this.extendChildren())); }))))); } } exports.DropdownMenu = DropdownMenu; DropdownMenu.displayName = 'DropdownMenu'; DropdownMenu.defaultProps = { className: '', isOpen: true, autoFocus: true, position: dropdownConstants_1.DropdownPosition.left, component: 'ul', isGrouped: false, setMenuComponentRef: null }; DropdownMenu.validToggleClasses = [dropdown_1.default.dropdownToggle, dropdown_1.default.dropdownToggleButton]; DropdownMenu.focusFirstRef = (refCollection) => { if (refCollection && refCollection[0] && refCollection[0].focus) { setTimeout(() => refCollection[0].focus()); } }; DropdownMenu.contextType = dropdownConstants_1.DropdownContext; //# sourceMappingURL=DropdownMenu.js.map