Shortcuts

A command-line icon button in the activity bar. It opens a dialog that groups the shortcuts by History, Formatting, Blocks and Lists, with key labels for the visitor's platform.

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. Every pattern needs it.
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.
ShortcutsExtensionBinds the keys and runs the actions. Remove it and the dialog still opens, but the custom shortcuts below stop working.
HistoryExtensionUndo and redo.
ListExtension, CheckListExtensionThe numbered, bulleted and check list shortcuts.
CodeExtensionThe code block shortcut.
TabIndentationExtensionMakes Tab indent.
ShortcutPluginThe button and dialog. It takes no props.
ActivityBarThe strip that holds the button. See Activity bar.

Removing ShortcutPlugin only removes the dialog. The shortcuts keep working. The dialog lists every shortcut the pattern registers, so if you drop an extension such as ListExtension, remove its rows from SHORTCUT_GROUPS too.

Customizing

Bindings live in the SHORTCUT_BINDINGS object in extensions/shortcuts-extension.ts, each as a key plus modifiers. Change a binding there and both the shortcut and the dialog label update. The dialog rows come from the SHORTCUT_GROUPS array in shortcut-plugin.tsx.

Shortcut reference

Use Cmd instead of Ctrl and Option instead of Alt on macOS, except where noted.

History and text

ActionShortcut
UndoCtrl Z
RedoCtrl Y, or Cmd Shift Z on macOS
BoldCtrl B
ItalicCtrl I
UnderlineCtrl U
StrikethroughCtrl Shift X
Inline codeCtrl Shift C
SubscriptCtrl ,
SuperscriptCtrl .
LowercaseCtrl Shift 1
UppercaseCtrl Shift 2
Title caseCtrl Shift 3
Clear formattingCtrl \

Lowercase, uppercase and title case use Ctrl on every platform, including macOS. Highlight has no shortcut.

Alignment and indent

ActionShortcut
Align leftCtrl Shift L
Align centerCtrl Shift E
Align rightCtrl Shift R
JustifyCtrl Shift J
IndentCtrl ]
OutdentCtrl [

Blocks and lists

ActionShortcut
ParagraphCtrl Alt 0
Heading 1Ctrl Alt 1
Heading 2Ctrl Alt 2
Heading 3Ctrl Alt 3
QuoteCtrl Shift Q
Code blockCtrl Alt C
Numbered listCtrl Shift 7
Bulleted listCtrl Shift 8
Check listCtrl Shift 9

Quote is Ctrl Shift Q on every platform, including macOS. A heading or quote shortcut on a block that already has that type does nothing. A list shortcut on a block that is already that list turns it back into a paragraph.

Other keys

KeyWhat it does
TabIndents. Inside a code block it inserts a 2-space indent.
ArrowAt the start or end of a code block or columns block that is the first or last block, an arrow key creates a paragraph so you can move out.
Tab or RightAccepts the autocomplete suggestion when one is shown.
EscCloses the link editor.

Markdown shortcuts

Type these at the start of a line, then a space, to convert the block. They come from the transformers registered in editor.tsx, so they only work in editors that call registerMarkdownShortcuts. See Markdown shortcuts. The pattern above does not register them.

TypeResult
# to ###### Heading 1 to 6
> Quote
- , * or + Bulleted list
1. Numbered list
[ ] or - [ ] Check list ([x] for a checked item)
```js then spaceCode block, language optional
---, *** or ___Divider
| a | b |Table row
![alt](url)Image, converted when you type the closing )
:name:Emoji, for example :smile:

Inline formatting converts when you type the closing marker:

TypeResult
**text** or __text__Bold
*text* or _text_Italic
***text*** or ___text___Bold and italic
~~text~~Strikethrough
==text==Highlight
`text`Inline code
[text](url)Link