var __assign = (this && this.__assign) || function () {
    __assign = Object.assign || function(t) {
        for (var s, i = 1, n = arguments.length; i < n; i++) {
            s = arguments[i];
            for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
                t[p] = s[p];
        }
        return t;
    };
    return __assign.apply(this, arguments);
};
var __rest = (this && this.__rest) || function (s, e) {
    var t = {};
    for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0)
        t[p] = s[p];
    if (s != null && typeof Object.getOwnPropertySymbols === "function")
        for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) {
            if (e.indexOf(p[i]) < 0 && Object.prototype.propertyIsEnumerable.call(s, p[i]))
                t[p[i]] = s[p[i]];
        }
    return t;
};
import { EllipsisVertical } from '@procore/core-icons/dist';
import React from 'react';
import { useClickOutside } from '../../effects/ClickOutside';
import { Trigger } from '../../state/Trigger';
import { Card } from '../Card';
import { DropdownButton } from '../Dropdown';
import { Overlay } from '../Overlay';
import { StyledDropdownFlyout, StyledDropdownFlyoutItem, } from './DropdownFlyout.styles';
import { rootId, } from './DropdownFlyout.types';
import { defaultOptionRenderer, noop, useDropdownFlyout, transformOption, DropdownFlyoutContext, useDropdownFlyoutContext, } from './DropdownFlyout.helpers';
export var FlyoutCaption = React.forwardRef(function FlyoutCaption(_a, ref) {
    var option = _a.option, highlighted = _a.highlighted, optionRenderer = _a.optionRenderer, props = __rest(_a, ["option", "highlighted", "optionRenderer"]);
    return (React.createElement(StyledDropdownFlyoutItem, __assign({}, props, { ref: ref, "data-highlighted": highlighted }), optionRenderer(option)));
});
FlyoutCaption.displayName = 'FlyoutCaption';
export function FlyoutItem(_a) {
    var option = _a.option, container = _a.container, placement = _a.placement;
    var captionRef = React.useRef(null);
    var overlayRef = React.useRef(null);
    var _b = useDropdownFlyoutContext(), isHighlighted = _b.isHighlighted, isExpanded = _b.isExpanded, _onClick = _b.onClick, expand = _b.expand, collapse = _b.collapse, optionRenderer = _b.optionRenderer;
    var onMouseEnter = React.useCallback(function () { return expand(option); }, [option, expand]);
    var onMouseLeave = React.useCallback(function (e) {
        var _a;
        if (e.relatedTarget instanceof Node &&
            !((_a = overlayRef.current) === null || _a === void 0 ? void 0 : _a.contains(e.relatedTarget))) {
            collapse(option);
        }
    }, [collapse, option]);
    var onClick = React.useCallback(function () { return _onClick(option); }, [_onClick, option]);
    return (React.createElement(React.Fragment, null,
        React.createElement(FlyoutCaption, { ref: captionRef, option: option.origin, onClick: onClick, optionRenderer: optionRenderer, highlighted: isHighlighted(option), onMouseEnter: onMouseEnter, onMouseLeave: onMouseLeave }),
        Array.isArray(option.children) && isExpanded(option) ? (React.createElement(FlyoutList, { options: option.children, overlayRef: overlayRef, targetRef: captionRef, container: container, placement: placement })) : null));
}
export function FlyoutList(_a) {
    var options = _a.options, targetRef = _a.targetRef, ref = _a.overlayRef, container = _a.container, placement = _a.placement, props = __rest(_a, ["options", "targetRef", "overlayRef", "container", "placement"]);
    var overlayRef = React.useRef(null);
    return (React.createElement(Overlay, __assign({}, __assign({ ref: ref, overlayRef: overlayRef, targetRef: targetRef, placement: placement, container: container, padding: 0 }, props)),
        React.createElement(Card, { shadowStrength: 2 },
            React.createElement(StyledDropdownFlyout, null, options.map(function (option) { return (React.createElement(FlyoutItem, { key: option.id, option: option, container: container, placement: placement })); })))));
}
var DefaultButton = React.forwardRef(function DefaultButton(_a, ref) {
    var children = _a.children, icon = _a.icon, props = __rest(_a, ["children", "icon"]);
    return (React.createElement(DropdownButton, __assign({}, props, { icon: props.loading ? undefined : !icon && !children ? (React.createElement(EllipsisVertical, null)) : (icon), arrow: !children ? false : true, ref: ref }), children));
});
/**

 The dropdown flyout allows for additional menu items to be nested within
 parent items, which allows more menu options for users.

 @since 10.19.0

 @see [Storybook](https://procore.github.io/core/latest/?path=/story/demos-dropdownflyout--demo)

 @see [Design Guidelines](https://design.procore.com/dropdown-flyout)

 */
export var DropdownFlyout = React.forwardRef(function DropdownFlyout(_a, ref) {
    var disabled = _a.disabled, icon = _a.icon, label = _a.label, loading = _a.loading, _options = _a.options, _b = _a.onClick, _onClick = _b === void 0 ? noop : _b, _c = _a.optionRenderer, optionRenderer = _c === void 0 ? defaultOptionRenderer : _c, children = _a.children, _d = _a.placement, placement = _d === void 0 ? 'right-bottom' : _d, _onKeyDown = _a.onKeyDown, onFocus = _a.onFocus, onBlur = _a.onBlur, onMouseDown = _a.onMouseDown, onMouseEnter = _a.onMouseEnter, onMouseLeave = _a.onMouseLeave, size = _a.size, _e = _a.variant, variant = _e === void 0 ? 'secondary' : _e, props = __rest(_a, ["disabled", "icon", "label", "loading", "options", "onClick", "optionRenderer", "children", "placement", "onKeyDown", "onFocus", "onBlur", "onMouseDown", "onMouseEnter", "onMouseLeave", "size", "variant"]);
    var innerRef = React.useRef(null);
    var container = ref || innerRef;
    var overlayRef = React.useRef(null);
    var targetRef = React.useRef(null);
    var flyoutOptions = React.useMemo(function () { return transformOption(_options, rootId); }, [_options]);
    var _f = useDropdownFlyout({
        flyoutOptions: flyoutOptions,
        onClick: _onClick,
        onKeyDown: _onKeyDown,
    }), options = _f.options, collapse = _f.collapse, expand = _f.expand, closeDropdown = _f.closeDropdown, openDropdown = _f.openDropdown, isOpen = _f.isOpen, onClick = _f.onClick, onKeyDown = _f.onKeyDown, setMouseOver = _f.setMouseOver, setFocused = _f.setFocused, isExpanded = _f.isExpanded, isHighlighted = _f.isHighlighted;
    useClickOutside({
        onClickOutside: closeDropdown,
        refs: [container],
    });
    var element = typeof children === 'function' ? children({ isOpen: isOpen }) : children;
    var trigger = React.isValidElement(element) ? (element) : (React.createElement(DefaultButton, { children: label, disabled: disabled, loading: loading, icon: icon, size: size, variant: variant }));
    return (React.createElement("div", __assign({}, props, { ref: container, onKeyDown: onKeyDown, onMouseEnter: function (e) {
            setMouseOver(true);
            onMouseEnter === null || onMouseEnter === void 0 ? void 0 : onMouseEnter(e);
        }, onMouseLeave: function (e) {
            setMouseOver(false);
            onMouseLeave === null || onMouseLeave === void 0 ? void 0 : onMouseLeave(e);
        }, onFocus: function (e) {
            setFocused(true);
            onFocus === null || onFocus === void 0 ? void 0 : onFocus(e);
        }, onMouseDown: function (e) {
            var _a, _b;
            // Discard firing of blur event
            // when click was inside the dropdown
            if (e.target instanceof Node && ((_a = container.current) === null || _a === void 0 ? void 0 : _a.contains(e.target))) {
                e.preventDefault();
                (_b = targetRef.current) === null || _b === void 0 ? void 0 : _b.focus();
            }
            onMouseDown === null || onMouseDown === void 0 ? void 0 : onMouseDown(e);
        }, onBlur: function (e) {
            setFocused(false);
            closeDropdown();
            onBlur === null || onBlur === void 0 ? void 0 : onBlur(e);
        } }),
        React.createElement(Trigger, __assign({}, {
            isEnabled: isOpen,
            enable: openDropdown,
            disable: closeDropdown,
            trigger: ['click'],
            triggerRef: targetRef,
        }), React.cloneElement(trigger, __assign(__assign({}, trigger.props), { tabIndex: 0 }))),
        React.createElement(DropdownFlyoutContext.Provider, { value: {
                expand: expand,
                collapse: collapse,
                onClick: onClick,
                isExpanded: isExpanded,
                isHighlighted: isHighlighted,
                optionRenderer: optionRenderer,
            } }, isOpen && (React.createElement(FlyoutList, { options: options, targetRef: targetRef, overlayRef: overlayRef, placement: placement, container: container.current || undefined, padding: 4 })))));
});
export default DropdownFlyout;
//# sourceMappingURL=DropdownFlyout.js.map