Block format

A combo box that shows the block type under the cursor and changes it when you pick another one.

Installation

This pattern is built from files in @intentui/editor. Install the editor, then copy the code above into a component of your own.

npx shadcn@latest add @intentui/editor

What's included

PieceWhy it is here
RichTextExtensionLexical's rich text behavior. It provides paragraphs, headings and quotes.
InitialStateExtensionApplies the seeded content immediately, so the server and the client render the same. Leave it out if your editor starts empty. See Seeding initial content.
ListExtensionNumbered and bulleted lists. Remove it and those two options disappear from the selector.
CheckListExtensionCheck lists. Remove it and the Check list option disappears.
ShortcutsExtensionRegisters the block keyboard shortcuts below. Remove it and the selector still works, but the shortcuts do not.
BlockFormatToolbarPluginThe combo box. It takes no props.
ToolbarThe container that holds toolbar plugins. See Toolbar.

Options

The selector lists only what the editor can create. Type in the input to filter the list.

OptionShortcut
ParagraphCtrl Alt 0
Heading 1Ctrl Alt 1
Heading 2Ctrl Alt 2
Heading 3Ctrl Alt 3
Numbered listCtrl Shift 7
Bulleted listCtrl Shift 8
Check listCtrl Shift 9
QuoteCtrl Shift Q

Use Cmd instead of Ctrl on macOS, except for Quote, which uses Ctrl on every platform. Pressing a list shortcut while already in that list turns the block back into a paragraph.

Fewer block types

The list items are shown only when the matching extension is registered. To offer only paragraphs, headings and quotes, drop the two list extensions.

dependencies: [RichTextExtension, ShortcutsExtension],

Styling

The combo box is w-48 with the compact input size. Each block is styled by the heading, quote and list entries in components/editor/theme.ts.

components/editor/theme.ts
quote: "relative my-4 border-s-2 ps-6 text-muted-foreground italic first:mt-0 last:mb-0",