Skip to content

useMenuPress

@astryxdesign/core v0.7.1 · useMenuPress

Parameters ​

NameTypeDefaultDescription
optionsMenuPressOptions—Configuration object. Required.
options.menuRefRef<HTMLElement | null>—The menu root carrying role="menu": the surface whose rows a press picks from. Required.
options.isEnabledMaybeRefOrGetter<boolean>trueWhether the model is live, read on each press. Pass the menu's open state.
options.onDismiss() => void—A mouse was released outside the menu with nothing acting: close it. A finger released outside leaves the menu open, so this is never called then.
options.itemSelectorstringenabled [role="menuitem"], menuitemradio, menuitemcheckboxSelector matching the ENABLED rows. A pointer over anything else inside the menu (a divider, a heading, a disabled row) picks nothing. Rows must still sit inside a [role="menu"] boundary.
options.triggerRefRef<HTMLElement | null>—The control that opens the menu, when a press may start there.
options.onTriggerPress(pointerType: MenuPressPointerType) => boolean—A mouse pressed the trigger, or a finger rested on it for longPressDelayMs: open the menu under the held pointer and return whether it opened. Return false when the press closed an open menu instead.
options.onHighlight(row: HTMLElement | null) => void—Move the highlight. Defaults to moving DOM focus with preventScroll onto the row. A picker that highlights through aria-activedescendant supplies its own.
options.onActivate(row: HTMLElement, release: PointerEvent) => void—Act on the row under the release. Defaults to dispatching a click on the row that carries the release button and modifier keys.
options.getScroller() => HTMLElement | nullthe overflowing menu rootThe element to scroll while a held pointer rests within 24 px of its top or bottom edge. Return null for none.
options.hitTest(x: number, y: number) => Element | nulldocument.elementFromPointResolves the element under a viewport point. A finger's events stay with the element it landed on, so the row under it is found by position. A test seam.
options.longPressDelayMsnumber500How long a finger must rest on the trigger before the menu opens under it.

Returns ​

NameTypeDescription
menuProps{ onPointerdown, 'data-astryx-menu-press': '' }Spread onto the menu root (v-bind="press.menuProps"). Claims presses that begin inside it and marks the root as carrying the press model.
onPointerDown(event: PointerEvent) => voidThe same handler as menuProps.onPointerdown, on its own. Bind it to the menu root's pointerdown when an object spread is not an option.
triggerProps{ onPointerdown, onContextmenu }Spread onto the trigger: a primary-button press opens the menu at once; a finger held for the delay opens it with the finger still down. A right-click is left alone, so its contextmenu route keeps working. The contextmenu handler suppresses the browser's own long-press menu for a finger, and leaves a mouse's right-click to the application.
isTriggerClickFromPress() => booleanWhether the click reaching the trigger belongs to the gesture that just pressed it. That press already opened or closed the menu, so the click must neither toggle nor reopen.
cancel() => voidEnd the gesture in flight with nothing acting, for when the menu closes under it.

The module also exports:

  • resetMenuPress(): forgets an armed stray-click swallower. Call it when a surface unmounts outside the hook's own teardown, and in tests.
  • isMenuPressActivation(): true for the synchronous extent of a row activation the model dispatched, so a row that forwards activation to a link inside it can tell the model's click from the browser's stray one.
  • MENU_PRESS_MARKER: the attribute name that marks a menu root.
  • menuPressStep, MENU_PRESS_SETTLE_MS and their types: the pure state machine. The release of the press that opened the menu acts only once the pointer has entered the menu or the press has lasted 300 ms; otherwise the menu stays open and nothing acts.