Menu
import "@taprootio/espalier/menu";
<esp-menu>
Shared navigation primitive for top navigation, sidebar navigation, and drawer navigation.
Use mode="horizontal" for top navigation, mode="vertical" for
sidebar navigation, and mode="drawer" for drawer-only navigation.
The same tree of esp-menu-item and esp-menu-group children can
render inline and as a drawer so consumers do not need duplicate
navigation markup for desktop and mobile. An inline vertical rail keeps
its intrinsic height so a page-level layout can move a tall sidebar with
document scroll; the fixed drawer presentation supplies its own vertical
scrolling instead.
2.4 migration: inline vertical rails no longer create their own bounded scroller. A standalone menu inside a fixed-height or overflow-hidden shell can restore that presentation by bounding and scrolling the host:
A published site usually wants the other common mobile pattern: a panel
that covers the whole viewport with the site's brand centered above large,
centered items. Set drawer-presentation="full-screen" for that; the side
panel stays the default for application menus. The panel is modal: the
content beside it goes inert, scrolling locks, focus moves in, Tab cycles
its controls, and Escape closes it. Any drawer sits on the top layer, so a
dialog or lightbox opened from one of its items cannot stack above it: an
open drawer closes when another overlay opens, and that overlay returns
focus to the drawer's trigger when it closes. An owning esp-header mirrors its
configured brand into the panel and keeps its own menu toggle on the top
layer so the burger closes the panel it opened:
Slots
<esp-menu> has the following slots:
Default
esp-menu-item and esp-menu-group children.
drawer-brand
Custom brand markup for the full-screen drawer. When empty, the brand an owning esp-header mirrors in renders instead.
Attributes
<esp-menu> has the following attributes:
mode
mode has a default value of "horizontal".
Rendering mode: horizontal top navigation, vertical sidebar navigation, or drawer-only navigation.
overflow
overflow has a default value of "auto".
Overflow behavior for horizontal navigation.
left-drawer and right-drawer force drawer access from the
chosen side. wrap and scroll keep navigation inline.
auto lets an owning component such as esp-header opt into
drawer fallback when inline content does not fit.
side
side has a default value of "left".
Which side the drawer is attached to.
drawer-presentation
drawer-presentation has a default value of "panel".
How the drawer presents: panel slides a side panel in beside a scrim
(the default, suited to application menus); full-screen covers the
viewport from its top edge with the brand centered above large,
centered items and no scrim. Unsupported values read as panel.
full-screen-transition
full-screen-transition has a default value of "fade".
Motion the full-screen drawer enters and leaves with: fade (default),
slide-down from above, slide-up from below, slide-left from the
right edge, or slide-right from the left edge. Timed by
--esp-menu-drawer-transition-duration and disabled under reduced
motion. The side panel keeps its own slide.
aria-label
aria-label has a default value of null.
Accessible label for the navigation landmark.
auto-expand
auto-expand has a default value of false.
Automatically expand groups to reveal the current page.
sliding
sliding has a default value of undefined.
Compatibility hook used by esp-header when inline navigation
becomes too wide. Prefer mode/overflow in application code.
collapsed
collapsed has a default value of undefined.
Compatibility alias for the old vertical menu drawer state.
intent
intent has a default value of undefined.
The element's intent — its meaning: neutral
(no pin), or success, warning, danger, info — each pinned
to its fixed status family (blue for info), retunable per theme
via intents. On token-emitting controls a non-neutral intent pins the
filled-action pair to that family, derived over the governing
zone's theme; class-styled chrome (badges, callouts, status pills)
opts out of inline emission and renders its treatment from CSS
classes instead. An intent never repaints the surrounding zone,
which is what contexts are for. Removing the attribute restores
the element's own default intent.
context
context has a default value of undefined.
A theme-defined color zone. The selected context rebinds designer-facing roles and emits a complete, contrast-enforced semantic token table on this host for descendants to inherit.
Methods
<esp-menu> has the following methods:
ownsDrawerLock
Host hook for the swipe controller: a full-screen open is modal-managed here.
openDrawer
Open the drawer overlay when this menu is drawer-capable.
Pass the control that opened the drawer so focus can return to it when the drawer closes.
closeDrawer
Close the drawer overlay.
toggleDrawer
Toggle the drawer overlay open or closed.
toggleOpened
Compatibility alias used by the old header menu integration.
traverseToClosest
Traverse up the DOM tree to find the closest element that matches the selector. This method is aware of shadow DOM boundaries and will traverse through them to find the element.
Events
<esp-menu> emits the following events:
esp-menu-drawer-opened
esp-menu-drawer-opened is of type CustomEvent.
Fired when the drawer opens.
esp-menu-drawer-presented
esp-menu-drawer-presented is of type CustomEvent.
Fired once the drawer's popover is on the top layer, so an opener can stack its own control above it.
esp-menu-drawer-closed
esp-menu-drawer-closed is of type CustomEvent.
Fired when the drawer closes.
CSS Properties
<esp-menu> has the following CSS properties:
--esp-menu-background
Background color of vertical and drawer menus.
--esp-menu-border-color
Border color of menu rails and drawers.
--esp-menu-horizontal-justify-content
Main-axis alignment for horizontal menu items. Defaults to flex-start.
--esp-menu-scrim-color
Scrim color when the drawer is open.
--esp-menu-drawer-shadow
Box shadow for the drawer overlay.
--esp-menu-drawer-width
Drawer width. Defaults to min(22rem, 86vw).
--esp-menu-drawer-item-font-size
Item label size in the full-screen drawer. Defaults to var(--esp-type-large).
--esp-menu-drawer-transition-duration
Duration of the full-screen drawer's transition. Defaults to 0.3s; reduced motion disables it.
--esp-menu-drawer-brand-logo-size
Logo height of the brand centered in the full-screen drawer. Defaults to calc(3 * var(--esp-size-medium)).
--esp-menu-drawer-brand-color
Text and logo color of the full-screen drawer's brand. Defaults to the mirrored brand color, then var(--esp-color-headings).
--esp-menu-top-offset
Top offset for drawers below fixed headers.
--esp-field-background
Background color of the shared field shell. Defaults to var(--esp-color-layer-2).
--esp-field-border-color
Border color of the shared field shell. Defaults to var(--esp-color-border).
--esp-field-border-width
Border width of the shared field shell. Defaults to 1px.
--esp-field-text-color
Text color used inside the shared field shell. Defaults to var(--esp-color-text).
--esp-field-hover-bg
Hover background color of the shared field shell. Derived from --esp-field-background.
--esp-field-focus-bg
Focus background color of the shared field shell. Derived from --esp-field-background.
--esp-field-focus-shadow
Shadow color used for shared field focus treatment. Defaults to var(--esp-color-shadow).