@1771technologies/lytenyte-pro
Version:
Blazingly fast headless React data grid with 100s of features.
56 lines (55 loc) • 2.4 kB
JavaScript
import { jsx as _jsx } from "react/jsx-runtime";
import { forwardRef, useCallback, useEffect, useMemo, useState } from "react";
import { useSubmenuPosition } from "./use-submenu-position.js";
import { submenuContext } from "./submenu-context.js";
import { useCombinedRefs, useControlled } from "@1771technologies/lytenyte-core/internal";
import { useTransitioned } from "../../../../hooks/use-transitioned-open.js";
function SubmenuImpl({ open: userOpen, onOpenChange, placement = "right-start", shiftPadding, sideOffset = 2, alignOffset = 0, ...props }, ref) {
const [open, setOpen] = useControlled({ controlled: userOpen, default: false });
const [sub, submenuRef] = useState(null);
const [, shouldMount] = useTransitioned(open, sub);
const openChange = useCallback((b) => {
setOpen(b);
onOpenChange?.(b);
}, [onOpenChange, setOpen]);
const [root, setRoot] = useState(null);
const combined = useCombinedRefs(ref, setRoot);
useSubmenuPosition({
placement,
shiftPadding,
sideOffset,
alignOffset,
sub,
root,
});
useEffect(() => {
if (!root)
return;
const controller = new AbortController();
const signal = controller.signal;
root.addEventListener("ln-close", () => {
openChange(false);
}, { signal });
return () => controller.abort();
}, [openChange, root]);
return (_jsx(submenuContext.Provider, { value: useMemo(() => ({
submenuRef,
open: shouldMount,
onOpenChange: openChange,
}), [openChange, shouldMount]), children: _jsx("div", { ...props, "data-ln-open": open, "data-ln-submenu-root": true, role: "menuitem", style: {
...props.style,
position: "relative",
}, ref: combined, onKeyDown: (ev) => {
props.onKeyDown?.(ev);
if (ev.isPropagationStopped())
return;
if (ev.key === "ArrowLeft") {
setOpen(false);
const trigger = ev.currentTarget.querySelector('[data-ln-subtrigger="true"]');
trigger?.focus();
ev.stopPropagation();
ev.preventDefault();
}
}, children: props.children }) }));
}
export const Submenu = forwardRef(SubmenuImpl);