Skip to content

shadcn.io is an independent project built on shadcn/ui

Heading Selector Dropdown Menu for Svelte

A heading level picker from H1 to H6, each row drawn at its own size and the button showing the current level.

UI library: Ark UI

The outline button shows the current level, starting at H1. Heading 1 through Heading 6 are radio items, each drawn at its own size, and only one stays checked.

Use it in a document editor when the level should be obvious before the click. The rows are not real headings. For a form field, use a Select. In Svelte, Ark UI stores the level and does not change the document.

Preview

Preview width

Installation

MCP · Pro
Make your AI a shadcn expert
Your agent installs components, builds pages and restyles your app from one prompt, in Claude Code, Cursor or VS Code.
Part of Pro

Anatomy

Dropdown Menu anatomy: trigger, label, item, shortcut, separator, sub trigger, content

Usage

<DropdownMenu><DropdownMenuTrigger>{#snippet asChild(props)}<Button {...props()} variant="outline"><HeadingIcon aria-hidden="true" data-icon="inline-start" />{heading.toUpperCase()}</Button>{/snippet}</DropdownMenuTrigger><DropdownMenuContent class="w-48"><DropdownMenuRadioGroup onValueChange={handleHeadingChange} value={heading}><DropdownMenuRadioItem value="h1"><span class="font-bold text-2xl">Heading 1</span></DropdownMenuRadioItem><DropdownMenuRadioItem value="h2"><span class="font-bold text-xl">Heading 2</span></DropdownMenuRadioItem><DropdownMenuRadioItem value="h3"><span class="font-bold text-lg">Heading 3</span></DropdownMenuRadioItem><DropdownMenuRadioItem value="h4"><span class="font-bold text-base">Heading 4</span></DropdownMenuRadioItem><DropdownMenuRadioItem value="h5"><span class="font-bold text-sm">Heading 5</span></DropdownMenuRadioItem><DropdownMenuRadioItem value="h6"><span class="font-bold text-xs">Heading 6</span></DropdownMenuRadioItem></DropdownMenuRadioGroup></DropdownMenuContent></DropdownMenu>

FAQ

How does the current heading show on the button?

The value starts at h1, and the button prints it in uppercase, H1, after a heading icon. Picking another row updates the value and the button. DropdownMenuRadioGroup takes value, and onValueChange receives details.value.

How are the rows sized?

Each row wraps its label in a bold span: Heading 1 is text-2xl, then text-xl, text-lg, text-base and text-sm, down to text-xs for Heading 6.

How wide is the menu?

w-48, and the six radio rows are the whole menu.

Can two heading levels be selected?

No. The radio group keeps one value. Choosing Heading 3 stores h3, moves the check to that row and changes the button to H3.

Can I pick a heading from the keyboard?

Yes. Arrow Up and Arrow Down move between rows, Enter picks one, typing H jumps through the Heading rows, and Escape closes the menu and returns focus to the button.

Are the rows real heading elements?

No. Each row's label is a styled span, which keeps the menu's structure valid for screen readers. The value is just the string h1 to h6; apply the real heading in your editor.

API Reference

Dropdown Menu

Sets onValueChange={handleHeadingChange}, value={heading}, value="h1", value="h2", value="h3" and value="h4". The rest is on the Dropdown Menu page.

Button

Sets props and variant="outline". The rest is on the Button page.