Skip to content

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

Heading Selector Dropdown Menu for Vue

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 Vue, 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 :asChild="true">
    <Button variant="outline">
      <HeadingIcon aria-hidden="true" data-icon="inline-start" />{{ heading.toUpperCase() }}
    </Button>
  </DropdownMenuTrigger>
  <DropdownMenuContent class="w-48">
    <DropdownMenuRadioGroup @value-change="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 @value-change 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 asChild, value-change="handleHeadingChange", value="heading", value="h1", value="h2" and value="h3". The rest is on the Dropdown Menu page.

Button

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