Content area

ContentEditable is the editable element. It wraps the Lexical component with Intent UI styling and a placeholder.

Usage

import { ContentEditable } from "@/components/editor/plugins/content-editable"

<div className="relative flex-1 overflow-y-auto">
  <ContentEditable variant="draggable" placeholder="Write something..." />
</div>

Put it in a scrollable, relative parent. The placeholder is absolutely positioned and the floating plugins use the parent as their anchor. The element itself has min-h-full w-full, so the parent decides the editor height.

The editor is created by LexicalExtensionComposer with contentEditable={null}, which means you must render ContentEditable yourself, exactly once.

Seeding an editor with $initialEditorState in a server-rendered app needs one extra line, so the server and the client start from the same content. See Seeding initial content.

Variants

The variant prop only changes padding. The placeholder is offset to match.

VariantPaddingUse it for
defaultpx-2.5 py-2A bare editor without chrome.
toolbarpx-4 py-4An editor under a toolbar.
draggablepx-12 py-4An editor with the drag handle, which needs room in the left gutter.

Styling

Pass className to style the editable element. It is merged with the base classes (min-h-full w-full bg-transparent text-sm outline-none) using twMerge, so your classes win.

<ContentEditable variant="toolbar" className="text-base leading-7" />

Typography for the content itself (headings, quotes, lists, links, inline code) comes from src/components/editor/theme.ts. Edit the entries there to restyle content, see Theming.

Overlays

The floating toolbar, link editor, table actions, context menu and pickers render inside the same relative container as the content area. Add them next to ContentEditable, see the full editor.

API

Extends ContentEditableElementProps from Lexical, without editor and className.
variant"default" | "toolbar" | "draggable"
Sets the padding of the editable element and the placeholder.
Default: "default"
placeholderstring
Text shown while the editor is empty. It is also used as aria-placeholder.
Default: empty string
classNamestring
Classes merged onto the editable element.
placeholderClassNamestring
Classes merged onto the placeholder element.