---
title: "List Dropdown Menu"
description: "Add a dropdown menu that helps selecting different list types in your Tiptap editor. More in the docs."
canonical_url: "https://tiptap.dev/docs/ui-components/components/list-dropdown-menu"
---

# List Dropdown Menu

Add a dropdown menu that helps selecting different list types in your Tiptap editor. More in the docs.

A fully accessible list dropdown menu for Tiptap editors. Easily toggle between different list types (bullet, ordered, task) with keyboard shortcut support and flexible customization options.

> **Interactive demo:** [list dropdown menu](https://template.tiptap.dev/preview/tiptap-ui/list-dropdown-menu)

## Installation

Add the component via the Tiptap CLI:

```bash
npx @tiptap/cli@latest add list-dropdown-menu
```

## Components

### `<ListDropdownMenu />`

A prebuilt React component that provides a dropdown menu for selecting different list types.

#### Usage

```tsx
import { EditorContent, EditorContext, useEditor } from '@tiptap/react'
import { StarterKit } from '@tiptap/starter-kit'
import { TaskList } from '@tiptap/extension-task-list'
import { TaskItem } from '@tiptap/extension-task-item'
import { ListDropdownMenu } from '@/components/tiptap-ui/list-dropdown-menu'

import '@/components/tiptap-node/code-block-node/code-block-node.scss'
import '@/components/tiptap-node/list-node/list-node.scss'
import '@/components/tiptap-node/paragraph-node/paragraph-node.scss'

export default function MyEditor() {
  const editor = useEditor({
    immediatelyRender: false,
    extensions: [StarterKit, TaskList, TaskItem.configure({ nested: true })],
    content: `
        <ul>
            <li>
                <strong>Bold</strong> for emphasis with <code>**</code> or <code>⌘+B</code> or the <code>B</code> button.
            </li>
            <li>
                <em>Italic</em> for subtle nuances with <code>*</code> or <code>⌘+I</code> or the <code>I</code> button.
            </li>
            <li>
                <s>Strikethrough</s> to show revisions with <code>~~</code> or the <code>~~S~~</code> button.
            </li>
        </ul>
        <ul data-type="taskList">
            <li data-type="taskItem" data-checked="true">
                <div>
                    Test template
                </div>
            </li>
            <li data-type="taskItem" data-checked="false">
                <div>
                    <a target="_blank" rel="noopener noreferrer nofollow" href="https://tiptap.dev/pricing">Create account</a>
                </div>
            </li>
            <li data-type="taskItem" data-checked="false">
                <div>
                   Download free template
                </div>
            </li>
        </ul>
        `,
  })

  return (
    <EditorContext.Provider value={{ editor }}>
      <ListDropdownMenu
        editor={editor}
        types={['bulletList', 'orderedList', 'taskList']}
        hideWhenUnavailable={true}
        portal={false}
        onOpenChange={(isOpen) => console.log('Dropdown opened:', isOpen)}
      />

      <EditorContent editor={editor} role="presentation" />
    </EditorContext.Provider>
  )
}
```

#### Props

| Name                  | Type                        | Default                                     | Description                                         |
| --------------------- | --------------------------- | ------------------------------------------- | --------------------------------------------------- |
| `editor`              | `Editor \| null`            | `undefined`                                 | The Tiptap editor instance                          |
| `types`               | `ListType[]`                | `["bulletList", "orderedList", "taskList"]` | The list types to display in the dropdown           |
| `hideWhenUnavailable` | `boolean`                   | `false`                                     | Hides the dropdown when no list types are available |
| `onOpenChange`        | `(isOpen: boolean) => void` | `undefined`                                 | Callback fired when the dropdown opens or closes    |
| `portal`              | `boolean`                   | `false`                                     | Whether to render the dropdown menu in a portal     |

## Hooks

### `useListDropdownMenu()`

A custom hook for managing list dropdown state and determining which options are available.

#### Usage

```tsx
import { useListDropdownMenu } from '@/components/tiptap-ui/list-dropdown-menu'
import { ListButton } from '@/components/tiptap-ui/list-button'
import {
  DropdownMenu,
  DropdownMenuTrigger,
  DropdownMenuContent,
  DropdownMenuItem,
} from '@/components/tiptap-ui-primitive/dropdown-menu'
import { ButtonGroup } from '@/components/tiptap-ui-primitive/button'

function MyListDropdown() {
  const { filteredLists, canToggle, isActive, isVisible, Icon, activeType } = useListDropdownMenu({
    editor,
    types: ['bulletList', 'orderedList', 'taskList'],
    hideWhenUnavailable: true,
  })

  if (!isVisible) return null

  return (
    <DropdownMenu>
      <DropdownMenuTrigger asChild>
        <button disabled={!canToggle}>
          <Icon />
          Lists {isActive ? '(Active)' : ''}
        </button>
      </DropdownMenuTrigger>
      <DropdownMenuContent>
        <ButtonGroup>
          {filteredLists.map((option) => (
            <DropdownMenuItem key={option.type} asChild>
              <ListButton editor={editor} type={option.type} text={option.label} />
            </DropdownMenuItem>
          ))}
        </ButtonGroup>
      </DropdownMenuContent>
    </DropdownMenu>
  )
}
```

#### Props

| Name                  | Type             | Default                                     | Description                                    |
| --------------------- | ---------------- | ------------------------------------------- | ---------------------------------------------- |
| `editor`              | `Editor \| null` | `undefined`                                 | The Tiptap editor instance                     |
| `types`               | `ListType[]`     | `["bulletList", "orderedList", "taskList"]` | Array of list types to display in the dropdown |
| `hideWhenUnavailable` | `boolean`        | `false`                                     | Whether to hide when no lists can be toggled   |

#### Return Values

| Name            | Type                    | Description                                   |
| --------------- | ----------------------- | --------------------------------------------- |
| `isVisible`     | `boolean`               | Whether the dropdown should be rendered       |
| `activeType`    | `ListType \| undefined` | Currently active list type                    |
| `isActive`      | `boolean`               | If any list type is currently active          |
| `canToggle`     | `boolean`               | If any list type can be toggled               |
| `types`         | `ListType[]`            | Array of list types from configuration        |
| `filteredLists` | `ListOption[]`          | List options filtered by available types      |
| `label`         | `string`                | Accessible label text for the dropdown        |
| `Icon`          | `React.FC`              | Icon component for the active list or default |

## Utilities

### `canToggleAnyList(editor, listTypes)`

Checks if any of the specified list types can be toggled in the current editor state.

```tsx
import { canToggleAnyList } from '@/components/tiptap-ui/list-dropdown-menu'

const canToggle = canToggleAnyList(editor, ['bulletList', 'orderedList'])
if (canToggle) {
  console.log('At least one list type can be toggled')
}
```

#### Parameters

| Name        | Type             | Description                  |
| ----------- | ---------------- | ---------------------------- |
| `editor`    | `Editor \| null` | The Tiptap editor instance   |
| `listTypes` | `ListType[]`     | Array of list types to check |

#### Returns

`boolean` - Whether at least one list type can be toggled.

### `isAnyListActive(editor, listTypes)`

Checks if any of the specified list types are currently active in the editor.

```tsx
import { isAnyListActive } from '@/components/tiptap-ui/list-dropdown-menu'

const isActive = isAnyListActive(editor, ['bulletList', 'orderedList', 'taskList'])
if (isActive) {
  console.log('At least one list type is currently active')
}
```

#### Parameters

| Name        | Type             | Description                  |
| ----------- | ---------------- | ---------------------------- |
| `editor`    | `Editor \| null` | The Tiptap editor instance   |
| `listTypes` | `ListType[]`     | Array of list types to check |

#### Returns

`boolean` - Whether at least one list type is currently active.

### `getFilteredListOptions(availableTypes)`

Filters the predefined list options based on the available types.

```tsx
import { getFilteredListOptions } from '@/components/tiptap-ui/list-dropdown-menu'

const availableOptions = getFilteredListOptions(['bulletList', 'taskList'])
// Returns only bullet list and task list options
```

#### Parameters

| Name             | Type         | Description                    |
| ---------------- | ------------ | ------------------------------ |
| `availableTypes` | `ListType[]` | Array of list types to include |

#### Returns

`ListOption[]` - Filtered array of list options.

### `getActiveListType(editor, availableTypes)`

Gets the currently active list type from the available types.

```tsx
import { getActiveListType } from '@/components/tiptap-ui/list-dropdown-menu'

const activeType = getActiveListType(editor, ['bulletList', 'orderedList', 'taskList'])
console.log('Current list type:', activeType)
```

#### Parameters

| Name             | Type             | Description                  |
| ---------------- | ---------------- | ---------------------------- |
| `editor`         | `Editor \| null` | The Tiptap editor instance   |
| `availableTypes` | `ListType[]`     | Array of list types to check |

#### Returns

`ListType | undefined` - The active list type, or `undefined` if no list is active.

## Keyboard Shortcuts

Each list type supports keyboard shortcuts (inherited from the underlying `ListButton` components):

- **Cmd/Ctrl + Shift + 8**: Toggle bullet list
- **Cmd/Ctrl + Shift + 7**: Toggle ordered list
- **Cmd/Ctrl + Shift + 9**: Toggle task list

The shortcuts are automatically registered when the list types are available in the editor schema.

## Requirements

### Dependencies

- `@tiptap/react` - Core Tiptap React integration
- `@tiptap/starter-kit` - Basic Tiptap extensions including list support
- `@tiptap/extension-task-list` - Task list extension
- `@tiptap/extension-task-item` - Task item extension

### Referenced Components

- `use-tiptap-editor` (hook)
- `list-button` (component)
- `button` (primitive)
- `dropdown-menu` (primitive)
- `card` (primitive)
- `tiptap-utils` (lib)
- `chevron-down-icon` (icon)
- `list-icon` (icon)
- `list-ordered-icon` (icon)
- `list-todo-icon` (icon)
