"use strict";
const jsxRuntime = require("react/jsx-runtime");
const assert = require("assert");
const React = require("react");
const styles_lib_components_Accordion_AccordionItem_cjs = require("../Accordion/AccordionItem.cjs");
const styles_lib_components_Box_Box_cjs = require("../Box/Box.cjs");
const styles_lib_components_Divider_Divider_cjs = require("../Divider/Divider.cjs");
const styles_lib_components_MenuItem_useMenuItem_cjs = require("../MenuItem/useMenuItem.cjs");
const styles_lib_components_Autosuggest_Autosuggest_cjs = require("../Autosuggest/Autosuggest.cjs");
const styles_lib_components_Accordion_Accordion_cjs = require("../Accordion/Accordion.cjs");
const styles_lib_components_MenuRenderer_MenuRenderer_css_cjs = require("./MenuRenderer.css.cjs");
const _interopDefaultCompat = (e) => e && typeof e === "object" && "default" in e ? e : { default: e };
const assert__default = /* @__PURE__ */ _interopDefaultCompat(assert);
const MenuItemDivider = () => {
  assert__default.default(
    React.useContext(styles_lib_components_MenuItem_useMenuItem_cjs.MenuRendererContext),
    "MenuItemDivider must be rendered within a menu component. See the documentation for correct usage: https://seek-oss.github.io/braid-design-system/components/MenuItemDivider"
  );
  return /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_Box_Box_cjs.Box, { paddingY: "xxsmall", children: /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_Divider_Divider_cjs.Divider, {}) });
};
MenuItemDivider.__isMenuItem__ = true;
const {
  MENU_TRIGGER_UP,
  MENU_ITEM_UP,
  MENU_TRIGGER_DOWN,
  MENU_ITEM_DOWN,
  MENU_ITEM_ESCAPE,
  MENU_ITEM_TAB,
  MENU_ITEM_ENTER,
  MENU_ITEM_SPACE,
  MENU_ITEM_CLICK,
  MENU_ITEM_HOVER,
  MENU_TRIGGER_ENTER,
  MENU_TRIGGER_SPACE,
  MENU_TRIGGER_CLICK,
  MENU_TRIGGER_TAB,
  MENU_TRIGGER_ESCAPE,
  BACKDROP_CLICK
} = styles_lib_components_MenuItem_useMenuItem_cjs.actionTypes;
const CLOSED_INDEX = -1;
const CLOSE_REASON_EXIT = { reason: "exit" };
const initialState = {
  open: false,
  highlightIndex: CLOSED_INDEX,
  closeReason: CLOSE_REASON_EXIT
};
const MenuRenderer = ({
  onOpen,
  onClose,
  trigger,
  width = "content",
  align = "left",
  offsetSpace = "none",
  reserveIconSpace = false,
  placement = "bottom",
  children,
  data,
  ...restProps
}) => {
  const buttonRef = React.useRef(null);
  const lastOpen = React.useRef(false);
  const items = styles_lib_components_Accordion_AccordionItem_cjs.flattenChildren(children);
  const itemCount = items.filter((item) => !isDivider(item)).length;
  assert__default.default(
    items.every(
      (item) => typeof item === "object" && "type" in item && // @ts-expect-error
      item.type.__isMenuItem__
    ),
    "All child nodes within a menu component must be a MenuItem, MenuItemLink, MenuItemCheckbox or MenuItemDivider: https://seek-oss.github.io/braid-design-system/components/MenuRenderer"
  );
  const [{ open, highlightIndex, closeReason }, dispatch] = React.useReducer(
    (state, action) => {
      switch (action.type) {
        case MENU_TRIGGER_UP:
        case MENU_ITEM_UP: {
          return {
            ...state,
            open: true,
            closeReason: CLOSE_REASON_EXIT,
            highlightIndex: styles_lib_components_Autosuggest_Autosuggest_cjs.getNextIndex(-1, state.highlightIndex, itemCount)
          };
        }
        case MENU_TRIGGER_DOWN:
        case MENU_ITEM_DOWN: {
          return {
            ...state,
            open: true,
            closeReason: CLOSE_REASON_EXIT,
            highlightIndex: styles_lib_components_Autosuggest_Autosuggest_cjs.getNextIndex(1, state.highlightIndex, itemCount)
          };
        }
        case BACKDROP_CLICK:
        case MENU_TRIGGER_ESCAPE:
        case MENU_TRIGGER_TAB:
        case MENU_ITEM_ESCAPE:
        case MENU_ITEM_TAB: {
          return {
            ...state,
            open: false,
            closeReason: CLOSE_REASON_EXIT,
            highlightIndex: CLOSED_INDEX
          };
        }
        case MENU_ITEM_ENTER:
        case MENU_ITEM_SPACE:
        case MENU_ITEM_CLICK: {
          if ("formElement" in action && action.formElement) {
            return state;
          }
          return {
            ...state,
            open: false,
            closeReason: {
              reason: "selection",
              index: action.index,
              id: action.id
            },
            highlightIndex: CLOSED_INDEX
          };
        }
        case MENU_ITEM_HOVER: {
          return { ...state, highlightIndex: action.value };
        }
        case MENU_TRIGGER_ENTER:
        case MENU_TRIGGER_SPACE: {
          const nextOpen = !state.open;
          return {
            ...state,
            open: nextOpen,
            closeReason: CLOSE_REASON_EXIT,
            highlightIndex: nextOpen ? 0 : CLOSED_INDEX
          };
        }
        case MENU_TRIGGER_CLICK: {
          const nextOpen = !state.open;
          return {
            ...state,
            open: nextOpen,
            closeReason: CLOSE_REASON_EXIT
          };
        }
        default:
          return state;
      }
    },
    initialState
  );
  React.useEffect(() => {
    if (lastOpen.current === open) {
      return;
    }
    if (open && typeof onOpen === "function") {
      onOpen();
    } else if (!open && typeof onClose === "function") {
      onClose(closeReason);
    }
    lastOpen.current = open;
  }, [onOpen, onClose, open, closeReason]);
  const focusTrigger = () => {
    if (buttonRef && buttonRef.current) {
      buttonRef.current.focus();
    }
  };
  const onTriggerKeyUp = (event) => {
    const targetKey = styles_lib_components_Autosuggest_Autosuggest_cjs.normalizeKey(event);
    if (targetKey === " " && /firefox|iceweasel|fxios/i.test(navigator.userAgent)) {
      return;
    }
    const action = {
      ArrowDown: { type: MENU_TRIGGER_DOWN },
      ArrowUp: { type: MENU_TRIGGER_UP },
      Enter: { type: MENU_TRIGGER_ENTER },
      " ": { type: MENU_TRIGGER_SPACE },
      Escape: { type: MENU_TRIGGER_ESCAPE }
    };
    if (action[targetKey]) {
      dispatch(action[targetKey]);
    }
  };
  const onTriggerKeyDown = (event) => {
    const targetKey = styles_lib_components_Autosuggest_Autosuggest_cjs.normalizeKey(event);
    if (targetKey === "Tab") {
      dispatch({ type: MENU_ITEM_TAB });
    }
    const isArrowPress = targetKey.indexOf("Arrow") === 0;
    const isActionKeyPress = targetKey === "Enter" || targetKey === " ";
    if (isArrowPress || isActionKeyPress) {
      event.preventDefault();
    }
  };
  const triggerProps = {
    "aria-haspopup": true,
    "aria-expanded": open,
    role: "button",
    tabIndex: 0,
    ref: buttonRef,
    onKeyUp: onTriggerKeyUp,
    onKeyDown: onTriggerKeyDown,
    onClick: (event) => {
      event.stopPropagation();
      event.preventDefault();
      dispatch({ type: MENU_TRIGGER_CLICK });
    }
  };
  return /* @__PURE__ */ jsxRuntime.jsxs(styles_lib_components_Box_Box_cjs.Box, { ...styles_lib_components_Accordion_Accordion_cjs.buildDataAttributes({ data, validateRestProps: restProps }), children: [
    /* @__PURE__ */ jsxRuntime.jsxs(styles_lib_components_Box_Box_cjs.Box, { position: "relative", children: [
      trigger(triggerProps, { open }),
      /* @__PURE__ */ jsxRuntime.jsx(
        Menu,
        {
          open,
          align,
          width,
          placement,
          offsetSpace,
          highlightIndex,
          reserveIconSpace,
          focusTrigger,
          dispatch,
          children: items
        }
      )
    ] }),
    open ? /* @__PURE__ */ jsxRuntime.jsx(
      styles_lib_components_Box_Box_cjs.Box,
      {
        onClick: (event) => {
          event.stopPropagation();
          event.preventDefault();
          dispatch({ type: BACKDROP_CLICK });
        },
        position: "fixed",
        zIndex: "dropdownBackdrop",
        top: 0,
        left: 0,
        className: styles_lib_components_MenuRenderer_MenuRenderer_css_cjs.backdrop
      }
    ) : null
  ] });
};
const isDivider = (node) => typeof node === "object" && node !== null && "type" in node && node.type === MenuItemDivider;
const borderRadius = "large";
function Menu({
  offsetSpace,
  align,
  width,
  placement,
  children,
  open,
  dispatch,
  focusTrigger,
  highlightIndex,
  reserveIconSpace,
  position = "absolute"
}) {
  let dividerCount = 0;
  return /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_MenuItem_useMenuItem_cjs.MenuRendererContext.Provider, { value: { reserveIconSpace }, children: /* @__PURE__ */ jsxRuntime.jsxs(
    styles_lib_components_Box_Box_cjs.Box,
    {
      role: "menu",
      position,
      zIndex: "dropdown",
      boxShadow: placement === "top" ? "small" : "medium",
      borderRadius,
      background: "surface",
      marginTop: placement === "bottom" ? offsetSpace : void 0,
      marginBottom: placement === "top" ? offsetSpace : void 0,
      transition: "fast",
      right: align === "right" ? 0 : void 0,
      opacity: !open ? 0 : void 0,
      overflow: "hidden",
      className: [
        !open && styles_lib_components_MenuRenderer_MenuRenderer_css_cjs.menuIsClosed,
        width !== "content" && styles_lib_components_MenuRenderer_MenuRenderer_css_cjs.width[width],
        placement === "top" && styles_lib_components_MenuRenderer_MenuRenderer_css_cjs.placementBottom
      ],
      children: [
        /* @__PURE__ */ jsxRuntime.jsx(styles_lib_components_Box_Box_cjs.Box, { paddingY: "xxsmall", children: React.Children.map(children, (item, i) => {
          if (isDivider(item)) {
            dividerCount++;
            return item;
          }
          const menuItemIndex = i - dividerCount;
          return /* @__PURE__ */ jsxRuntime.jsx(
            styles_lib_components_MenuItem_useMenuItem_cjs.MenuRendererItemContext.Provider,
            {
              value: {
                isHighlighted: menuItemIndex === highlightIndex,
                index: menuItemIndex,
                dispatch,
                focusTrigger
              },
              children: item
            },
            menuItemIndex
          );
        }) }),
        /* @__PURE__ */ jsxRuntime.jsx(
          styles_lib_components_Accordion_AccordionItem_cjs.Overlay,
          {
            boxShadow: "borderNeutralLight",
            borderRadius,
            visible: true
          }
        )
      ]
    }
  ) });
}
exports.MenuItemDivider = MenuItemDivider;
exports.MenuRenderer = MenuRenderer;
