How-to
On npmCustomizing the editor
Replace or remove the editor's top bar, status bar, palettes and the other pieces, or wrap them in your own.
The editor is nine pieces round the drawing. Each one is a slot of the components prop: give it
a component of your own and it renders in the piece's place, or give it null and the piece is
gone, with the room it took.
The pieces
| Slot | The piece |
|---|---|
TopBar | Across the top: the application menu, Quick Access, layers and properties |
ToolRail | Down the start side: the tool palette |
PalettePanel | Down the end side: Properties, Layers, Blocks and Styles, as tabs |
CommandLine | Under the drawing: the command line and its history |
StatusBar | Across the bottom: the coordinates, the drafting modes and Customization |
ViewportControls | On the drawing, top start corner: [Top], the preset views |
ViewCube | On the drawing, top end corner |
NavigationBar | On the drawing, under the ViewCube: Pan, Zoom and Orbit |
DynamicInput | On the drawing, at the cursor: the fields typed into while a command runs |
In a right-to-left page the start side is the right.
Replacing a piece
A replacement is handed what the piece is: PieceProps, the engine and its state, and for the
top bar and the status bar what you gave CadEditor for them (mark and languages, the status
bar's storageKey).
"use client"
import type { TopBarProps } from "@mellowcad/editor"
export function MyTopBar({ engine, state }: TopBarProps) { return ( <nav className="flex w-full items-center gap-1 px-2"> <span>My app</span> <button onClick={() => engine.runCommand("_QSAVE")}>Save</button> <span className="ms-auto">{state.entityCount} objects</span> </nav> )}<CadEditor components={{ TopBar: MyTopBar }} />statechanges when the drawing or a mode does, not with every mouse move. The cursor's coordinates and the dynamic input are left out of it; read them withuseEngineSelector(engine, (state) => state.cursorUcs)from@mellowcad/react, in the smallest component that shows them.- Everything a control does is a call to the engine:
runCommand("_LINE"),setActiveTool("line"),toggleSnap(). After a click,engine.focusSurface()gives the keys back to the drawing, so the next one types a command. Building a host goes through the state and the calls piece by piece. - It renders inside the editor's root, in the piece's zone: the editor's colours, its fonts and its language reach it. The zone's size and border stay the editor's, so the drawing keeps its place whatever the piece renders.
- Its classes are yours to compile. The editor's stylesheet holds only the classes the editor
uses. It is Tailwind 4's output, and Tailwind's classes are global: your
.flexand the editor's are the same rule under Tailwind's default theme, and a theme of yours that changes the spacing changes the editor's too.
Removing a piece
<CadEditor components={{ PalettePanel: null, NavigationBar: null }} />A piece set to null is gone from the first paint, and the drawing takes its room. A slot you
leave out keeps the editor's piece.
Wrapping a piece
The nine pieces are exported, so a replacement can render the editor's own piece and add to it:
"use client"
import { TopBar, type TopBarProps } from "@mellowcad/editor"
export function TopBarWithHelp(props: TopBarProps) { return ( <> <TopBar {...props} /> <a href="/help">Help</a> </> )}A piece renders only inside CadEditor. Outside it there is no root to give it colours or words,
and the menus and dialogs the editor mounts are missing, so a command that opens one would wait
for an answer that never comes. For a page with fewer pieces, turn the others off.
What is not a slot
The menus and dialogs the engine opens are part of the editor, not slots: the shortcut menu at the cursor, the object snap menu, selection cycling, the UNITS dialog and the task dialogs for locked objects and for unsaved text. The engine waits on their answer, so the editor always keeps them.
The rest of the chrome
-
markis your product's glyph on the application menu's button, which shows a menu icon without it. -
helpis where F1 opens help, in a new tab, as AutoCAD does:indexwith no command running, andcommandwhile one runs, with{command}replaced by its global name in lower case.<CadEditor help={{ index: "/help", command: "/help/commands#{command}" }} />F1 during LINE opens
/help/commands#line. Withouthelp, F1 is the browser's. -
layoutStoragenames thelocalStoragekeys under which this browser remembers the palette panel's width and fold (palette) and what the status bar shows (statusBar). A part without a key is not remembered. On a page rendered on a server,paletteneeds the layout script too, or the panel shows as the window's width decides until the scripts run, then changes. -
sheetgives the drawing's cell anidand aview-transition-name, for a page that grows into the editor with a view transition.