Menu List

Keyboard-driven option list that leaves focus in the text field.

@paneui/themeclass-variance-authority
Blocks
TextPlain paragraph
Heading 1Big section heading#
To-do listTrack tasks[]
QuoteCapture a quote>
ImageUpload or embed
TableRows and columns

Focus stays in the input.

Installation

pnpm dlx shadcn@latest add @paneui/menu-list

Usage

Composition

Examples

Plain

Why not Menu

Menu moves focus into its popup. Slash menus, mention pickers and autocomplete need focus to stay in the text, so MenuList tracks a highlighted value and exposes it with aria-activedescendant. The block and email editors use it for / and {{.

Keyboard

ref.current.onKeyDown(event) handles ArrowUp / ArrowDown (looping), Home / End, and Enter / Tab (clicks the highlighted item); it returns true when it used the key. The highlight resets to the first item when the list changes under it.

API Reference

MenuList

Also accepts every prop of div.

ref
React.Ref<MenuListHandle>
{ onKeyDown(event): boolean, move(delta), select(): boolean }.
variant= "popup"
"popup" | "plain"
popup is the menu surface (rounded-xl, p-1, max-height 320px, scrolls).
activeValue
string
Controlled highlighted item.
defaultActiveValue
string
Initial highlight (else the first item).
onActiveValueChange
(value: string) => void
Called as the highlight moves.
loop= true
boolean
Wrap from the last item to the first.
PropTypeDefaultDescription
refReact.Ref<MenuListHandle>—{ onKeyDown(event): boolean, move(delta), select(): boolean }.
variant"popup" | "plain""popup"popup is the menu surface (rounded-xl, p-1, max-height 320px, scrolls).
activeValuestring—Controlled highlighted item.
defaultActiveValuestring—Initial highlight (else the first item).
onActiveValueChange(value: string) => void—Called as the highlight moves.
loopbooleantrueWrap from the last item to the first.

MenuListItem

Also accepts every prop of div.

value*
string
Unique value for the highlight.
onSelect
() => void
Called on click or Enter.
disabled
boolean
Skipped by the keyboard, dimmed.
PropTypeDefaultDescription
value*string—Unique value for the highlight.
onSelect() => void—Called on click or Enter.
disabledboolean—Skipped by the keyboard, dimmed.
data-highlighted
Present on the highlighted item.
Data attributeDescription
data-highlightedPresent on the highlighted item.

MenuListItemText

Also accepts every prop of span.

title*
React.ReactNode
The item label.
description
React.ReactNode
A muted second line.
PropTypeDefaultDescription
title*React.ReactNode—The item label.
descriptionReact.ReactNode—A muted second line.