Heading Dropdown Menu

Available for free

A fully accessible heading dropdown menu for Tiptap editors. Easily select and apply heading levels (H1-H6) with a clean dropdown interface and flexible customization options.

Installation

Add the component via the Tiptap CLI:

npx @tiptap/cli@latest add heading-dropdown-menu

Components

<HeadingDropdownMenu />

A prebuilt React component that provides a dropdown menu for selecting heading levels.

Usage

export default function MyEditor() {
  return (
    <HeadingDropdownMenu
      editor={editor}
      levels={[1, 2, 3, 4, 5, 6]}
      hideWhenUnavailable={true}
      portal={false}
      onOpenChange={(isOpen) => console.log('Dropdown', isOpen ? 'opened' : 'closed')}
    />
  )
}

Props

NameTypeDefaultDescription
editorEditor | nullundefinedThe Tiptap editor instance
levelsLevel[][1,2,3,4,5,6]Available heading levels to show in dropdown
hideWhenUnavailablebooleanfalseHides the dropdown when headings are not available
portalbooleanfalseWhether to render the dropdown menu in a portal
onOpenChange(boolean) => voidundefinedCallback for when the dropdown opens or closes

Hooks

useHeadingDropdownMenu()

A custom hook to build your own heading dropdown menu with full control over rendering and behavior.

Usage

function MyHeadingDropdown() {
  const { isVisible, activeLevel, isActive, canToggle, levels, label, Icon } =
    useHeadingDropdownMenu({
      editor: myEditor,
      levels: [1, 2, 3],
      hideWhenUnavailable: true,
    })

  if (!isVisible) return null

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <button disabled={!canToggle} aria-label={label} aria-pressed={isActive}>
          <Icon />
          {label}
          <ChevronDownIcon />
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        {levels.map((level) => (
          <DropdownMenuItem key={level}>
            <HeadingButton editor={editor} level={level} text={`Heading ${level}`} />
          </DropdownMenuItem>
        ))}
      </DropdownMenuContent>
    </DropdownMenu>
  )
}

Props

NameTypeDefaultDescription
editorEditor | nullundefinedThe Tiptap editor instance
levelsLevel[][1,2,3,4,5,6]Available heading levels to show in dropdown
hideWhenUnavailablebooleanfalseHides the dropdown if headings cannot be applied

Return Values

NameTypeDescription
isVisiblebooleanWhether the dropdown should be rendered
activeLevelLevel | undefinedCurrently active heading level (1-6)
isActivebooleanIf any heading is currently active
canTogglebooleanIf heading formatting is currently allowed
levelsLevel[]Array of available heading levels
labelstringAccessible label text for the dropdown
IconReact.FCIcon component for the current heading state

Utilities

getActiveHeadingLevel(editor, levels?)

Gets the currently active heading level from the available levels.

import { getActiveHeadingLevel } from '@/components/tiptap-ui/heading-dropdown-menu'

const activeLevel = getActiveHeadingLevel(editor, [1, 2, 3]) // Returns active level or undefined

Individual Heading Functions

The heading dropdown menu leverages functions from the heading button component:

isHeadingActive(editor, level?)

Checks if a specific heading level is active, or if any heading is active.

import { isHeadingActive } from '@/components/tiptap-ui/heading-button'

const isH1Active = isHeadingActive(editor, 1) // Check if H1 is active
const isAnyHeadingActive = isHeadingActive(editor) // Check if any heading is active

canToggle(editor)

Checks if heading formatting can be toggled in the current editor state.

import { canToggle } from '@/components/tiptap-ui/heading-button'

const canApplyHeading = canToggle(editor)

Keyboard Shortcuts

Individual heading levels support keyboard shortcuts when using HeadingButton components:

  • Cmd/Ctrl + Alt + 1: Toggle H1
  • Cmd/Ctrl + Alt + 2: Toggle H2
  • Cmd/Ctrl + Alt + 3: Toggle H3
  • Cmd/Ctrl + Alt + 4: Toggle H4
  • Cmd/Ctrl + Alt + 5: Toggle H5
  • Cmd/Ctrl + Alt + 6: Toggle H6

The dropdown itself doesn't register shortcuts but provides access to all heading options in one interface.

Requirements

Dependencies

  • @tiptap/react - Core Tiptap React integration
  • @tiptap/starter-kit - Basic Tiptap extensions including heading support

Referenced Components

  • use-tiptap-editor (hook)
  • use-heading-dropdown-menu (hook)
  • heading-button (component)
  • button (primitive)
  • dropdown-menu (primitive)
  • card (primitive)
  • chevron-down-icon (icon)
  • heading-icon (icon)
  • heading-one-icon (icon)
  • heading-two-icon (icon)
  • heading-three-icon (icon)
  • heading-four-icon (icon)
  • heading-five-icon (icon)
  • heading-six-icon (icon)