PettyUI/packages/core/src/components/navigation-menu/navigation-menu-trigger.tsx
Mats Bosson 56f06c961d NavigationMenu component
Horizontal nav with dropdown submenus, hover-intent delay, keyboard-accessible
trigger/content parts, and full Zod v4 schema + ComponentMeta.
2026-03-29 20:53:17 +07:00

54 lines
1.7 KiB
TypeScript

import type { JSX } from "solid-js";
import { splitProps } from "solid-js";
import { useNavigationMenuContext, useNavigationMenuItemContext } from "./navigation-menu-context";
import type { NavigationMenuTriggerProps } from "./navigation-menu.props";
/**
* Button that opens the associated NavigationMenu.Content on click or hover.
* Manages hover-intent via the root context's scheduleOpen/cancelAndClose.
*/
export function NavigationMenuTrigger(props: NavigationMenuTriggerProps): JSX.Element {
const [local, rest] = splitProps(props, [
"children",
"onClick",
"onPointerEnter",
"onPointerLeave",
]);
const ctx = useNavigationMenuContext();
const itemCtx = useNavigationMenuItemContext();
const handleClick: JSX.EventHandler<HTMLButtonElement, MouseEvent> = (e) => {
if (typeof local.onClick === "function") local.onClick(e);
const next = ctx.value() === itemCtx.value ? "" : itemCtx.value;
ctx.setValue(next);
};
const handlePointerEnter: JSX.EventHandler<HTMLButtonElement, PointerEvent> = (e) => {
if (typeof local.onPointerEnter === "function") local.onPointerEnter(e);
ctx.scheduleOpen(itemCtx.value);
};
const handlePointerLeave: JSX.EventHandler<HTMLButtonElement, PointerEvent> = (e) => {
if (typeof local.onPointerLeave === "function") local.onPointerLeave(e);
ctx.cancelAndClose();
};
return (
<button
type="button"
role="menuitem"
data-scope="navigation-menu"
data-part="trigger"
aria-expanded={itemCtx.isActive()}
data-active={itemCtx.isActive() ? "" : undefined}
onClick={handleClick}
onPointerEnter={handlePointerEnter}
onPointerLeave={handlePointerLeave}
{...rest}
>
{local.children}
</button>
);
}