define(["require", "exports", "tslib", "react", "./ContextualMenu.types", "../../FocusZone", "./ContextualMenu.classNames", "../../Utilities", "../../utilities/contextualMenu/index", "../../utilities/decorators/withResponsiveMode", "../../Callout", "../../Divider", "./ContextualMenuItem"], function (require, exports, tslib_1, React, ContextualMenu_types_1, FocusZone_1, ContextualMenu_classNames_1, Utilities_1, index_1, withResponsiveMode_1, Callout_1, Divider_1, ContextualMenuItem_1) {
    "use strict";
    Object.defineProperty(exports, "__esModule", { value: true });
    function getSubmenuItems(item) {
        return item.subMenuProps ? item.subMenuProps.items : item.items;
    }
    exports.getSubmenuItems = getSubmenuItems;
    /**
     * Returns true if a list of menu items can contain a checkbox
     */
    function canAnyMenuItemsCheck(items) {
        return items.some(function (item) {
            if (item.canCheck) {
                return true;
            }
            // If the item is a section, check if any of the items in the section can check.
            if (item.sectionProps && item.sectionProps.items.some(function (submenuItem) { return submenuItem.canCheck === true; })) {
                return true;
            }
            return false;
        });
    }
    exports.canAnyMenuItemsCheck = canAnyMenuItemsCheck;
    var ContextualMenu = /** @class */ (function (_super) {
        tslib_1.__extends(ContextualMenu, _super);
        function ContextualMenu(props) {
            var _this = _super.call(this, props) || this;
            _this._navigationIdleDelay = 250 /* ms */;
            _this.dismiss = function (ev, dismissAll) {
                var onDismiss = _this.props.onDismiss;
                if (onDismiss) {
                    onDismiss(ev, dismissAll);
                }
            };
            _this._onKeyDown = function (ev) {
                if (ev.which === 27 /* escape */ ||
                    ev.altKey ||
                    ev.metaKey ||
                    _this._shouldCloseSubMenu(ev)) {
                    // When a user presses escape, we will try to refocus the previous focused element.
                    _this._isFocusingPreviousElement = true;
                    ev.preventDefault();
                    ev.stopPropagation();
                    _this.dismiss(ev);
                }
            };
            /**
             * Checks if the submenu should be closed
             */
            _this._shouldCloseSubMenu = function (ev) {
                var submenuCloseKey = Utilities_1.getRTL() ? 39 /* right */ : 37 /* left */;
                if (ev.which !== submenuCloseKey || !_this.props.isSubMenu) {
                    return false;
                }
                return _this._adjustedFocusZoneProps.direction === FocusZone_1.FocusZoneDirection.vertical ||
                    (!!_this._adjustedFocusZoneProps.checkForNoWrap && !Utilities_1.shouldWrapFocus(ev.target, 'data-no-horizontal-wrap'));
            };
            _this._onMenuKeyDown = function (ev) {
                if (ev.which === 27 /* escape */ || ev.altKey || ev.metaKey) {
                    _this._isFocusingPreviousElement = true;
                    ev.preventDefault();
                    ev.stopPropagation();
                    _this.dismiss(ev);
                    return;
                }
                if (!_this._host) {
                    return;
                }
                var elementToFocus = ev.which === 38 /* up */ ?
                    Utilities_1.getLastFocusable(_this._host, _this._host.lastChild, true) :
                    ev.which === 40 /* down */ ?
                        Utilities_1.getFirstFocusable(_this._host, _this._host.firstChild, true) :
                        null;
                if (elementToFocus) {
                    elementToFocus.focus();
                    ev.preventDefault();
                    ev.stopPropagation();
                }
            };
            /**
             * Scroll handler for the callout to make sure the mouse events
             * for updating focus are not interacting during scroll
             */
            _this._onScroll = function () {
                if (!_this._isScrollIdle && _this._scrollIdleTimeoutId !== undefined) {
                    _this._async.clearTimeout(_this._scrollIdleTimeoutId);
                    _this._scrollIdleTimeoutId = undefined;
                }
                else {
                    _this._isScrollIdle = false;
                }
                _this._scrollIdleTimeoutId = _this._async.setTimeout(function () { _this._isScrollIdle = true; }, _this._navigationIdleDelay);
            };
            _this._onMouseItemLeave = function (item, ev) {
                if (!_this._isScrollIdle) {
                    return;
                }
                if (_this._enterTimerId !== undefined) {
                    _this._async.clearTimeout(_this._enterTimerId);
                    _this._enterTimerId = undefined;
                }
                if (_this.state.expandedMenuItemKey !== undefined) {
                    return;
                }
                /**
                 * IE11 focus() method forces parents to scroll to top of element.
                 * Edge and IE expose a setActive() function for focusable divs that
                 * sets the page focus but does not scroll the parent element.
                 */
                if (_this._host.setActive) {
                    _this._host.setActive();
                }
                else {
                    _this._host.focus();
                }
            };
            _this._onSubMenuDismiss = function (ev, dismissAll) {
                if (dismissAll) {
                    _this.dismiss(ev, dismissAll);
                }
                else {
                    _this.setState({
                        dismissedMenuItemKey: _this.state.expandedMenuItemKey,
                        expandedMenuItemKey: undefined,
                        submenuTarget: undefined
                    });
                }
            };
            _this.state = {
                contextualMenuItems: undefined,
                subMenuId: Utilities_1.getId('ContextualMenu')
            };
            _this._warnDeprecations({
                'targetPoint': 'target',
                'useTargetPoint': 'target',
                'arrowDirection': 'focusZoneProps'
            });
            _this._isFocusingPreviousElement = false;
            _this._isScrollIdle = true;
            return _this;
        }
        ContextualMenu_1 = ContextualMenu;
        ContextualMenu.prototype.componentWillUpdate = function (newProps) {
            if (newProps.target !== this.props.target) {
                var newTarget = newProps.target;
                this._setTargetWindowAndElement(newTarget);
            }
        };
        // Invoked once, both on the client and server, immediately before the initial rendering occurs.
        ContextualMenu.prototype.componentWillMount = function () {
            var target = this.props.target;
            this._setTargetWindowAndElement(target);
            this._previousActiveElement = this._targetWindow ? this._targetWindow.document.activeElement : null;
        };
        // Invoked once, only on the client (not on the server), immediately after the initial rendering occurs.
        ContextualMenu.prototype.componentDidMount = function () {
            this._events.on(this._targetWindow, 'resize', this.dismiss);
            this._splitButtonContainers = new Map();
            if (this.props.onMenuOpened) {
                this.props.onMenuOpened(this.props);
            }
        };
        // Invoked immediately before a component is unmounted from the DOM.
        ContextualMenu.prototype.componentWillUnmount = function () {
            var _this = this;
            if (this._isFocusingPreviousElement && this._previousActiveElement) {
                // This slight delay is required so that we can unwind the stack, const react try to mess with focus, and then
                // apply the correct focus. Without the setTimeout, we end up focusing the correct thing, and then React wants
                // to reset the focus back to the thing it thinks should have been focused.
                setTimeout(function () { return _this._previousActiveElement.focus(); }, 0);
            }
            if (this.props.onMenuDismissed) {
                this.props.onMenuDismissed(this.props);
            }
            this._events.dispose();
            this._async.dispose();
        };
        ContextualMenu.prototype.render = function () {
            var _this = this;
            var isBeakVisible = this.props.isBeakVisible;
            var _a = this.props, className = _a.className, items = _a.items, labelElementId = _a.labelElementId, id = _a.id, targetPoint = _a.targetPoint, useTargetPoint = _a.useTargetPoint, beakWidth = _a.beakWidth, directionalHint = _a.directionalHint, directionalHintForRTL = _a.directionalHintForRTL, gapSpace = _a.gapSpace, coverTarget = _a.coverTarget, ariaLabel = _a.ariaLabel, doNotLayer = _a.doNotLayer, target = _a.target, bounds = _a.bounds, useTargetWidth = _a.useTargetWidth, useTargetAsMinWidth = _a.useTargetAsMinWidth, directionalHintFixed = _a.directionalHintFixed, shouldFocusOnMount = _a.shouldFocusOnMount, title = _a.title, theme = _a.theme, calloutProps = _a.calloutProps, _b = _a.onRenderSubMenu, onRenderSubMenu = _b === void 0 ? this._onRenderSubMenu : _b, focusZoneProps = _a.focusZoneProps;
            var menuClassNames = this.props.getMenuClassNames || ContextualMenu_classNames_1.getContextualMenuClassNames;
            this._classNames = menuClassNames(theme, className);
            var hasIcons = itemsHaveIcons(items);
            function itemsHaveIcons(contextualMenuItems) {
                for (var _i = 0, contextualMenuItems_1 = contextualMenuItems; _i < contextualMenuItems_1.length; _i++) {
                    var item = contextualMenuItems_1[_i];
                    if (!!item.icon || !!item.iconProps) {
                        return true;
                    }
                    if (item.itemType === ContextualMenu_types_1.ContextualMenuItemType.Section && item.sectionProps && itemsHaveIcons(item.sectionProps.items)) {
                        return true;
                    }
                }
                return false;
            }
            this._adjustedFocusZoneProps = tslib_1.__assign({}, focusZoneProps, { direction: this._getFocusZoneDirection() });
            var hasCheckmarks = canAnyMenuItemsCheck(items);
            var submenuProps = this.state.expandedMenuItemKey ? this._getSubmenuProps() : null;
            isBeakVisible = isBeakVisible === undefined ? this.props.responsiveMode <= withResponsiveMode_1.ResponsiveMode.medium : isBeakVisible;
            /**
             * When useTargetWidth is true, get the width of the target element and apply it for the context menu container
             */
            var contextMenuStyle;
            var targetAsHtmlElement = this._target;
            if ((useTargetWidth || useTargetAsMinWidth) && targetAsHtmlElement && targetAsHtmlElement.offsetWidth) {
                var targetBoundingRect = targetAsHtmlElement.getBoundingClientRect();
                var targetWidth = targetBoundingRect.width - 2 /* Accounts for 1px border */;
                if (useTargetWidth) {
                    contextMenuStyle = {
                        width: targetWidth
                    };
                }
                else if (useTargetAsMinWidth) {
                    contextMenuStyle = {
                        minWidth: targetWidth
                    };
                }
            }
            // The menu should only return if items were provided, if no items were provided then it should not appear.
            if (items && items.length > 0) {
                var indexCorrection_1 = 0;
                var totalItemCount_1 = 0;
                for (var _i = 0, items_1 = items; _i < items_1.length; _i++) {
                    var item = items_1[_i];
                    if (item.itemType !== ContextualMenu_types_1.ContextualMenuItemType.Divider &&
                        item.itemType !== ContextualMenu_types_1.ContextualMenuItemType.Header) {
                        var itemCount = item.customOnRenderListLength ? item.customOnRenderListLength : 1;
                        totalItemCount_1 += itemCount;
                    }
                }
                return (React.createElement(Callout_1.Callout, tslib_1.__assign({}, calloutProps, { target: useTargetPoint ? targetPoint : target, isBeakVisible: isBeakVisible, beakWidth: beakWidth, directionalHint: directionalHint, directionalHintForRTL: directionalHintForRTL, gapSpace: gapSpace, coverTarget: coverTarget, doNotLayer: doNotLayer, className: Utilities_1.css('ms-ContextualMenu-Callout', calloutProps ? calloutProps.className : undefined), setInitialFocus: shouldFocusOnMount, onDismiss: this.props.onDismiss, onScroll: this._onScroll, bounds: bounds, directionalHintFixed: directionalHintFixed }),
                    React.createElement("div", { role: 'menu', "aria-label": ariaLabel, "aria-labelledby": labelElementId, style: contextMenuStyle, ref: function (host) { return _this._host = host; }, id: id, className: this._classNames.container, tabIndex: 0, onKeyDown: this._onMenuKeyDown },
                        title && React.createElement("div", { className: this._classNames.title, role: 'heading', "aria-level": 1 },
                            " ",
                            title,
                            " "),
                        (items && items.length) ? (React.createElement(FocusZone_1.FocusZone, tslib_1.__assign({}, this._adjustedFocusZoneProps, { className: this._classNames.root, isCircularNavigation: true, handleTabKey: 1 /* all */ }),
                            React.createElement("ul", { role: 'presentation', className: this._classNames.list, onKeyDown: this._onKeyDown }, items.map(function (item, index) {
                                var menuItem = _this._renderMenuItem(item, index, indexCorrection_1, totalItemCount_1, hasCheckmarks, hasIcons);
                                if (item.itemType !== ContextualMenu_types_1.ContextualMenuItemType.Divider &&
                                    item.itemType !== ContextualMenu_types_1.ContextualMenuItemType.Header) {
                                    var indexIncrease = item.customOnRenderListLength ? item.customOnRenderListLength : 1;
                                    indexCorrection_1 += indexIncrease;
                                }
                                return menuItem;
                            })))) : (null),
                        submenuProps && onRenderSubMenu(submenuProps, this._onRenderSubMenu))));
            }
            else {
                return null;
            }
        };
        /**
         * Gets the focusZoneDirection by using the arrowDirection if specified,
         * the direction specificed in the focusZoneProps, or defaults to FocusZoneDirection.vertical
         */
        ContextualMenu.prototype._getFocusZoneDirection = function () {
            var _a = this.props, arrowDirection = _a.arrowDirection, focusZoneProps = _a.focusZoneProps;
            return arrowDirection !== undefined ? arrowDirection :
                focusZoneProps && focusZoneProps.direction !== undefined ? focusZoneProps.direction : FocusZone_1.FocusZoneDirection.vertical;
        };
        ContextualMenu.prototype._onRenderSubMenu = function (subMenuProps) {
            return React.createElement(ContextualMenu_1, tslib_1.__assign({}, subMenuProps));
        };
        ContextualMenu.prototype._renderMenuItem = function (item, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons) {
            var renderedItems = [];
            var iconProps = this._getIconProps(item);
            // We only send a dividerClassName when the item to be rendered is a divider. For all other cases, the default divider style is used.
            var dividerClassName = item.itemType === ContextualMenu_types_1.ContextualMenuItemType.Divider ? item.className : undefined;
            var subMenuIconClassName = item.submenuIconProps ? item.submenuIconProps.className : '';
            var getClassNames = item.getItemClassNames || ContextualMenu_classNames_1.getItemClassNames;
            var itemClassNames = getClassNames(this.props.theme, this._isItemDisabled(item), (this.state.expandedMenuItemKey === item.key), !!index_1.getIsChecked(item), !!item.href, (iconProps.iconName !== 'None'), item.className, dividerClassName, iconProps.className, subMenuIconClassName);
            if (item.name === '-') {
                item.itemType = ContextualMenu_types_1.ContextualMenuItemType.Divider;
            }
            switch (item.itemType) {
                case ContextualMenu_types_1.ContextualMenuItemType.Divider:
                    renderedItems.push(this._renderSeparator(index, itemClassNames));
                    break;
                case ContextualMenu_types_1.ContextualMenuItemType.Header:
                    renderedItems.push(this._renderSeparator(index, itemClassNames));
                    var headerItem = this._renderHeaderMenuItem(item, itemClassNames, index, hasCheckmarks, hasIcons);
                    renderedItems.push(this._renderListItem(headerItem, item.key || index, itemClassNames, item.title));
                    break;
                case ContextualMenu_types_1.ContextualMenuItemType.Section:
                    renderedItems.push(this._renderSectionItem(item, itemClassNames, index, hasCheckmarks, hasIcons));
                    break;
                default:
                    var menuItem = this._renderNormalItem(item, itemClassNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons);
                    renderedItems.push(this._renderListItem(menuItem, item.key || index, itemClassNames, item.title));
                    break;
            }
            return renderedItems;
        };
        ContextualMenu.prototype._renderSectionItem = function (item, menuClassNames, index, hasCheckmarks, hasIcons) {
            var _this = this;
            var section = item.sectionProps;
            if (!section) {
                return;
            }
            var headerItem;
            if (section.title) {
                var headerContextualMenuItem = {
                    key: "section-" + section.title + "-title",
                    itemType: ContextualMenu_types_1.ContextualMenuItemType.Header,
                    name: section.title,
                };
                headerItem = this._renderHeaderMenuItem(headerContextualMenuItem, menuClassNames, index, hasCheckmarks, hasIcons);
            }
            if (section.items && section.items.length > 0) {
                return (React.createElement("li", { role: 'presentation', key: section.key },
                    React.createElement("div", { role: 'group' },
                        React.createElement("ul", { className: this._classNames.list },
                            section.topDivider && this._renderSeparator(index, menuClassNames, true, true),
                            headerItem && this._renderListItem(headerItem, item.key || index, menuClassNames, item.title),
                            section.items.map(function (contextualMenuItem, itemsIndex) { return (_this._renderMenuItem(contextualMenuItem, itemsIndex, itemsIndex, section.items.length, hasCheckmarks, hasIcons)); }),
                            section.bottomDivider && this._renderSeparator(index, menuClassNames, false, true)))));
            }
        };
        ContextualMenu.prototype._renderListItem = function (content, key, classNames, title) {
            return (React.createElement("li", { role: 'presentation', title: title, key: key, className: classNames.item }, content));
        };
        ContextualMenu.prototype._renderSeparator = function (index, classNames, top, fromSection) {
            if (fromSection || index > 0) {
                return (React.createElement("li", { role: 'separator', key: 'separator-' + index + (top === undefined ? '' : (top ? '-top' : '-bottom')), className: classNames.divider }));
            }
            return null;
        };
        ContextualMenu.prototype._renderNormalItem = function (item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons) {
            if (item.onRender) {
                return [item.onRender(tslib_1.__assign({ 'aria-posinset': focusableElementIndex + 1, 'aria-setsize': totalItemCount }, item), this.dismiss)];
            }
            if (item.href) {
                return this._renderAnchorMenuItem(item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons);
            }
            if (item.split && index_1.hasSubmenu(item)) {
                return this._renderSplitButton(item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons);
            }
            return this._renderButtonItem(item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons);
        };
        ContextualMenu.prototype._renderHeaderMenuItem = function (item, classNames, index, hasCheckmarks, hasIcons) {
            var _a = this.props.contextualMenuItemAs, ChildrenRenderer = _a === void 0 ? ContextualMenuItem_1.ContextualMenuItem : _a;
            return (React.createElement("div", { className: this._classNames.header, style: item.style, role: 'heading', "aria-level": this.props.title ? 2 : 1 },
                React.createElement(ChildrenRenderer, { item: item, classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks ? this._onItemClick : undefined, hasIcons: hasIcons })));
        };
        ContextualMenu.prototype._renderAnchorMenuItem = function (item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons) {
            var expandedMenuItemKey = this.state.expandedMenuItemKey;
            var _a = this.props.contextualMenuItemAs, ChildrenRenderer = _a === void 0 ? ContextualMenuItem_1.ContextualMenuItem : _a;
            var anchorRel = item.rel;
            if (item.target && item.target.toLowerCase() === '_blank') {
                anchorRel = anchorRel ? anchorRel : 'nofollow noopener noreferrer'; // Safe default to prevent tabjacking
            }
            var subMenuId = this._getSubMenuId(item);
            var itemHasSubmenu = index_1.hasSubmenu(item);
            return (React.createElement("div", null,
                React.createElement("a", tslib_1.__assign({}, Utilities_1.getNativeProps(item, Utilities_1.anchorProperties), { href: item.href, target: item.target, rel: anchorRel, className: classNames.root, role: 'menuitem', "aria-owns": item.key === expandedMenuItemKey ? subMenuId : null, "aria-haspopup": itemHasSubmenu || null, "aria-expanded": itemHasSubmenu ? item.key === expandedMenuItemKey : null, "aria-posinset": focusableElementIndex + 1, "aria-setsize": totalItemCount, "aria-disabled": this._isItemDisabled(item), style: item.style, onClick: this._onAnchorClick.bind(this, item), onMouseEnter: this._onItemMouseEnter.bind(this, item), onMouseLeave: this._onMouseItemLeave.bind(this, item), onKeyDown: itemHasSubmenu ? this._onItemKeyDown.bind(this, item) : null }),
                    React.createElement(ChildrenRenderer, { item: item, classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks ? this._onItemClick : undefined, hasIcons: hasIcons }))));
        };
        ContextualMenu.prototype._renderButtonItem = function (item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons) {
            var _this = this;
            var expandedMenuItemKey = this.state.expandedMenuItemKey;
            var _a = this.props.contextualMenuItemAs, ChildrenRenderer = _a === void 0 ? ContextualMenuItem_1.ContextualMenuItem : _a;
            var subMenuId = this._getSubMenuId(item);
            var ariaLabel = '';
            if (item.ariaLabel) {
                ariaLabel = item.ariaLabel;
            }
            else if (item.name) {
                ariaLabel = item.name;
            }
            var isChecked = index_1.getIsChecked(item);
            var canCheck = isChecked !== null;
            var defaultRole = canCheck ? 'menuitemcheckbox' : 'menuitem';
            var itemHasSubmenu = index_1.hasSubmenu(item);
            var buttonNativeProperties = Utilities_1.getNativeProps(item, Utilities_1.buttonProperties);
            // Do not add the disabled attribute to the button so that it is focusable
            delete buttonNativeProperties.disabled;
            var itemButtonProperties = {
                className: classNames.root,
                onClick: this._onItemClick.bind(this, item),
                onKeyDown: itemHasSubmenu ? this._onItemKeyDown.bind(this, item) : null,
                onMouseEnter: this._onItemMouseEnter.bind(this, item),
                onMouseLeave: this._onMouseItemLeave.bind(this, item),
                onMouseDown: function (ev) { return _this._onItemMouseDown(item, ev); },
                onMouseMove: this._onItemMouseMove.bind(this, item),
                href: item.href,
                title: item.title,
                'aria-label': ariaLabel,
                'aria-haspopup': itemHasSubmenu || null,
                'aria-owns': item.key === expandedMenuItemKey ? subMenuId : null,
                'aria-expanded': itemHasSubmenu ? item.key === expandedMenuItemKey : null,
                'aria-checked': isChecked,
                'aria-posinset': focusableElementIndex + 1,
                'aria-setsize': totalItemCount,
                'aria-disabled': this._isItemDisabled(item),
                role: item.role || defaultRole,
                style: item.style
            };
            return (React.createElement("button", tslib_1.__assign({}, buttonNativeProperties, itemButtonProperties),
                React.createElement(ChildrenRenderer, { item: item, classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks ? this._onItemClick : undefined, hasIcons: hasIcons })));
        };
        ContextualMenu.prototype._renderSplitButton = function (item, classNames, index, focusableElementIndex, totalItemCount, hasCheckmarks, hasIcons) {
            var _this = this;
            return (React.createElement("div", { ref: function (el) {
                    return _this._splitButtonContainers.set(item.key, el);
                }, role: 'button', "aria-labelledby": item.ariaLabel, className: classNames.splitContainerFocus, "aria-disabled": this._isItemDisabled(item), "aria-haspopup": true, "aria-describedby": item.ariaDescription, "aria-checked": item.isChecked || item.checked, "aria-posinset": focusableElementIndex + 1, "aria-setsize": totalItemCount, onKeyDown: this._onSplitContainerItemKeyDown.bind(this, item), onClick: this._executeItemClick.bind(this, item), tabIndex: 0, "data-is-focusable": true },
                React.createElement("span", { "aria-hidden": true, className: classNames.splitContainer },
                    this._renderSplitPrimaryButton(item, classNames, index, hasCheckmarks, hasIcons),
                    this._renderSplitDivider(item),
                    this._renderSplitIconButton(item, classNames, index))));
        };
        ContextualMenu.prototype._renderSplitPrimaryButton = function (item, classNames, index, hasCheckmarks, hasIcons) {
            var isChecked = index_1.getIsChecked(item);
            var canCheck = isChecked !== null;
            var defaultRole = canCheck ? 'menuitemcheckbox' : 'menuitem';
            var _a = this.props.contextualMenuItemAs, ChildrenRenderer = _a === void 0 ? ContextualMenuItem_1.ContextualMenuItem : _a;
            var itemProps = {
                key: item.key,
                disabled: this._isItemDisabled(item) || item.primaryDisabled,
                name: item.name,
                className: classNames.splitPrimary,
                role: item.role || defaultRole,
                canCheck: item.canCheck,
                isChecked: item.isChecked,
                checked: item.checked,
                icon: item.icon,
                iconProps: item.iconProps,
                'data-is-focusable': false
            };
            return React.createElement('button', Utilities_1.getNativeProps(itemProps, Utilities_1.buttonProperties), React.createElement(ChildrenRenderer, { item: itemProps, classNames: classNames, index: index, onCheckmarkClick: hasCheckmarks ? this._onItemClick : undefined, hasIcons: hasIcons }));
        };
        ContextualMenu.prototype._onSplitContainerItemKeyDown = function (item, ev) {
            if (ev.which === 13 /* enter */) {
                this._executeItemClick(item, ev);
                ev.preventDefault();
                ev.stopPropagation();
            }
            else {
                this._onItemKeyDown(item, ev);
            }
        };
        ContextualMenu.prototype._renderSplitIconButton = function (item, classNames, index) {
            var _this = this;
            var _a = this.props.contextualMenuItemAs, ChildrenRenderer = _a === void 0 ? ContextualMenuItem_1.ContextualMenuItem : _a;
            var itemProps = {
                onClick: this._onSplitItemClick.bind(this, item),
                disabled: this._isItemDisabled(item),
                className: classNames.splitMenu,
                subMenuProps: item.subMenuProps,
                submenuIconProps: item.submenuIconProps,
                split: true,
            };
            return React.createElement('button', Utilities_1.assign({}, Utilities_1.getNativeProps(itemProps, Utilities_1.buttonProperties), {
                onMouseEnter: this._onItemMouseEnter.bind(this, item),
                onMouseLeave: this._onMouseItemLeave.bind(this, item),
                onMouseDown: function (ev) { return _this._onItemMouseDown(item, ev); },
                onMouseMove: this._onItemMouseMove.bind(this, item),
                'data-is-focusable': false
            }), React.createElement(ChildrenRenderer, { item: itemProps, classNames: classNames, index: index, hasIcons: false }));
        };
        ContextualMenu.prototype._renderSplitDivider = function (item) {
            var getDividerClassnames = item.getSplitButtonVerticalDividerClassNames || ContextualMenu_classNames_1.getSplitButtonVerticalDividerClassNames;
            return React.createElement(Divider_1.VerticalDivider, { getClassNames: getDividerClassnames });
        };
        ContextualMenu.prototype._getIconProps = function (item) {
            var iconProps = item.iconProps ? item.iconProps : {
                iconName: item.icon
            };
            return iconProps;
        };
        ContextualMenu.prototype._onItemMouseEnter = function (item, ev) {
            if (!this._isScrollIdle) {
                return;
            }
            this._updateFocusOnMouseEvent(item, ev);
        };
        ContextualMenu.prototype._onItemMouseMove = function (item, ev) {
            var targetElement = ev.currentTarget;
            if (!this._isScrollIdle || targetElement === this._targetWindow.document.activeElement) {
                return;
            }
            this._updateFocusOnMouseEvent(item, ev);
        };
        /**
         * Handles updating focus when mouseEnter or mouseMove fire.
         * As part of updating focus, This function will also update
         * the expand/collapse state accordingly.
         */
        ContextualMenu.prototype._updateFocusOnMouseEvent = function (item, ev) {
            var _this = this;
            var targetElement = ev.currentTarget;
            var _a = this.props.subMenuHoverDelay, timeoutDuration = _a === void 0 ? this._navigationIdleDelay : _a;
            if (item.key === this.state.expandedMenuItemKey) {
                return;
            }
            if (this._enterTimerId !== undefined) {
                this._async.clearTimeout(this._enterTimerId);
                this._enterTimerId = undefined;
            }
            // If the menu is not expanded we can update focus without any delay
            if (this.state.expandedMenuItemKey === undefined) {
                targetElement.focus();
            }
            // Delay updating expanding/dismissing the submenu
            // and only set focus if we have not already done so
            if (index_1.hasSubmenu(item)) {
                this._enterTimerId = this._async.setTimeout(function () {
                    targetElement.focus();
                    var splitButtonContainer = _this._splitButtonContainers.get(item.key);
                    _this._onItemSubMenuExpand(item, ((item.split && splitButtonContainer) ? splitButtonContainer : targetElement));
                }, this._navigationIdleDelay);
            }
            else {
                this._enterTimerId = this._async.setTimeout(function () {
                    _this._onSubMenuDismiss(ev);
                    targetElement.focus();
                }, timeoutDuration);
            }
        };
        ContextualMenu.prototype._onItemMouseDown = function (item, ev) {
            if (item.onMouseDown) {
                item.onMouseDown(item, ev);
            }
        };
        ContextualMenu.prototype._onItemClick = function (item, ev) {
            this._onItemClickBase(item, ev, ev.currentTarget);
        };
        ContextualMenu.prototype._onSplitItemClick = function (item, ev) {
            var splitButtonContainer = this._splitButtonContainers.get(item.key);
            // get the whole splitButton container to base the menu off of
            this._onItemClickBase(item, ev, (splitButtonContainer ? splitButtonContainer : ev.currentTarget));
        };
        ContextualMenu.prototype._onItemClickBase = function (item, ev, target) {
            var items = getSubmenuItems(item);
            if (!index_1.hasSubmenu(item) && (!items || !items.length)) {
                this._executeItemClick(item, ev);
            }
            else {
                if (item.key === this.state.expandedMenuItemKey) {
                    this._onSubMenuDismiss(ev);
                }
                else {
                    this._onItemSubMenuExpand(item, target);
                }
            }
            ev.stopPropagation();
            ev.preventDefault();
        };
        ContextualMenu.prototype._onAnchorClick = function (item, ev) {
            this._executeItemClick(item, ev);
            ev.stopPropagation();
        };
        ContextualMenu.prototype._executeItemClick = function (item, ev) {
            if (item.disabled || item.isDisabled) {
                return;
            }
            var dismiss = false;
            if (item.onClick) {
                dismiss = !!item.onClick(ev, item);
            }
            else if (this.props.onItemClick) {
                dismiss = !!this.props.onItemClick(ev, item);
            }
            (dismiss || !ev.defaultPrevented) && this.dismiss(ev, true);
        };
        ContextualMenu.prototype._onItemKeyDown = function (item, ev) {
            var openKey = Utilities_1.getRTL() ? 37 /* left */ : 39 /* right */;
            if (ev.which === openKey && !item.disabled) {
                this._onItemSubMenuExpand(item, ev.currentTarget);
                ev.preventDefault();
            }
        };
        ContextualMenu.prototype._onItemSubMenuExpand = function (item, target) {
            if (this.state.expandedMenuItemKey !== item.key) {
                if (this.state.expandedMenuItemKey) {
                    this._onSubMenuDismiss();
                }
                // Focus the target to ensure when we close it, we're focusing on the correct element.
                target.focus();
                this.setState({
                    expandedMenuItemKey: item.key,
                    submenuTarget: target
                });
            }
        };
        ContextualMenu.prototype._getSubmenuProps = function () {
            var _a = this.state, submenuTarget = _a.submenuTarget, expandedMenuItemKey = _a.expandedMenuItemKey;
            var item = this._findItemByKey(expandedMenuItemKey);
            var submenuProps = null;
            if (item) {
                submenuProps = {
                    items: getSubmenuItems(item),
                    target: submenuTarget,
                    onDismiss: this._onSubMenuDismiss,
                    isSubMenu: true,
                    id: this.state.subMenuId,
                    shouldFocusOnMount: true,
                    directionalHint: Utilities_1.getRTL() ? 8 /* leftTopEdge */ : 11 /* rightTopEdge */,
                    className: this.props.className,
                    gapSpace: 0,
                    isBeakVisible: false
                };
                if (item.subMenuProps) {
                    Utilities_1.assign(submenuProps, item.subMenuProps);
                }
            }
            return submenuProps;
        };
        ContextualMenu.prototype._findItemByKey = function (key) {
            var items = this.props.items;
            return this._findItemByKeyFromItems(key, items);
        };
        /**
         * Returns the item that mathes a given key if any.
         * @param key The key of the item to match
         * @param items The items to look for the key
         */
        ContextualMenu.prototype._findItemByKeyFromItems = function (key, items) {
            for (var _i = 0, items_2 = items; _i < items_2.length; _i++) {
                var item = items_2[_i];
                if (item.itemType === ContextualMenu_types_1.ContextualMenuItemType.Section && item.sectionProps) {
                    var match = this._findItemByKeyFromItems(key, item.sectionProps.items);
                    if (match) {
                        return match;
                    }
                }
                else if (item.key && item.key === key) {
                    return item;
                }
            }
        };
        ContextualMenu.prototype._setTargetWindowAndElement = function (target) {
            if (target) {
                if (typeof target === 'string') {
                    var currentDoc = Utilities_1.getDocument();
                    this._target = currentDoc ? currentDoc.querySelector(target) : null;
                    this._targetWindow = Utilities_1.getWindow();
                }
                else if (target.stopPropagation) {
                    this._targetWindow = Utilities_1.getWindow(target.toElement);
                    this._target = target;
                }
                else if (target.x !== undefined && target.y !== undefined) {
                    this._targetWindow = Utilities_1.getWindow();
                    this._target = target;
                }
                else {
                    var targetElement = target;
                    this._targetWindow = Utilities_1.getWindow(targetElement);
                    this._target = target;
                }
            }
            else {
                this._targetWindow = Utilities_1.getWindow();
            }
        };
        ContextualMenu.prototype._isItemDisabled = function (item) {
            return !!(item.isDisabled || item.disabled);
        };
        ContextualMenu.prototype._getSubMenuId = function (item) {
            var subMenuId = this.state.subMenuId;
            if (item.subMenuProps && item.subMenuProps.id) {
                subMenuId = item.subMenuProps.id;
            }
            return subMenuId;
        };
        // The default ContextualMenu properties have no items and beak, the default submenu direction is right and top.
        ContextualMenu.defaultProps = {
            items: [],
            shouldFocusOnMount: true,
            gapSpace: 0,
            directionalHint: 7 /* bottomAutoEdge */,
            beakWidth: 16,
            getMenuClassNames: ContextualMenu_classNames_1.getContextualMenuClassNames
        };
        ContextualMenu = ContextualMenu_1 = tslib_1.__decorate([
            Utilities_1.customizable('ContextualMenu', ['theme']),
            withResponsiveMode_1.withResponsiveMode
        ], ContextualMenu);
        return ContextualMenu;
        var ContextualMenu_1;
    }(Utilities_1.BaseComponent));
    exports.ContextualMenu = ContextualMenu;
});
//# sourceMappingURL=ContextualMenu.js.map