Editor.Root
The orchestrator. Owns the document state, the history timeline, and the DnD provider. Every other primitive reads from its context.
Editor.Root is the entry point. It owns the document state (controlled or uncontrolled), mounts a single react-dnd MultiBackend (HTML5 on desktop, auto-transitioning to touch) for the whole tree, and provides the editor + config contexts every other Editor.* primitive consumes.
Installation
bun add @docmosaic/react @docmosaic/coreUsage
import { Editor } from '@docmosaic/react';
import '@docmosaic/react/styles.css';
export function MyEditor() {
return (
<Editor.Root>
<Editor.Properties />
<Editor.Toolbar />
<Editor.Pages />
<Editor.Canvas>
<Editor.Section />
</Editor.Canvas>
<Editor.Preview />
</Editor.Root>
);
}Composition
Editor.Root arranges its children into the default shell automatically - Pages is forced to the left of Canvas regardless of source order. Drop any primitive in the child tree; it'll find its place.
Don't nest another <DndProvider> underneath - Editor.Root already mounts one.
Examples
Controlled
Lift the document state out so you can persist it or sync it across collaborators.
const [doc, setDoc] = useState<Document>(() => createDocument());
<Editor.Root document={doc} onDocumentChange={setDoc}>
{/* ... */}
</Editor.Root>;Read-only
Flip the editor into viewer mode. Mutating interactions are suppressed; preview / print / download stay live.
<Editor.Root defaultDocument={signedContract} readOnly>
<Editor.Properties />
<Editor.Toolbar />
<Editor.Canvas />
<Editor.Preview />
</Editor.Root>Custom PDF backend
Swap the bundled jspdf pipeline for your own renderer (or run it in a Worker).
<Editor.Root
pdf={{
generate: myCustomRenderer,
estimate: mySizeHeuristic,
}}
>
{/* ... */}
</Editor.Root>See the custom PDF backend recipe for a full example.
Rulers + minimap
<Editor.Root showRuler showMinimap rulerUnit="mm">
{/* ... */}
</Editor.Root>API Reference
| Prop | Type | Default | Description |
|---|---|---|---|
| children | ReactNode | - | Extra nodes mounted **after** the default app-shell
|
| themeToggle | ReactNode | - | Theme-toggle slot rendered in the top-bar right group. The package never imports |
| showLeftRail | boolean | undefined | - | Render the left rail (tool palette + Pages + Layers). Defaults to |
| showToolPalette | boolean | undefined | - | Render the tool palette inside the left rail. Defaults to |
| showPages | boolean | undefined | - | Render the "Pages" section inside the left rail. Defaults to |
| showLayers | boolean | undefined | - | Render the "Layers" section inside the left rail. Defaults to |
| showInspector | boolean | undefined | - | Render the right inspector panel. Defaults to |
| Partial<EditorPdfBackend> | undefined | - | Pluggable PDF backend. Either or both functions can be overridden. Anything omitted falls back to the bundled | |
| keybindings | false | Partial<EditorKeymap> | undefined | - | Keyboard shortcuts.
|
| readOnly | boolean | undefined | - | Render the editor in read-only / viewer mode. Defaults to
|
| showRuler | boolean | undefined | - | Render |
| showMinimap | boolean | undefined | - | Render
|
| rulerUnit | enum | - | Unit used by |
| document | Document | undefined | - | Controlled: caller owns the document. |
| onDocumentChange | ((next: Document) => void) | undefined | - | - |
| defaultDocument | Document | undefined | - | Uncontrolled: optional seed for the internally-owned document. |
Related
- Canvas - the interactive workspace
- Properties - document name + page size + orientation bar
- Toolbar - top action bar
- Controlled vs uncontrolled - the two state modes