Saltar al contenido
MellowCAD

Esta sección solo está escrita en inglés.

Cómo…

En npm

Customizing 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

SlotThe piece
TopBarAcross the top: the application menu, Quick Access, layers and properties
ToolRailDown the start side: the tool palette
PalettePanelDown the end side: Properties, Layers, Blocks and Styles, as tabs
CommandLineUnder the drawing: the command line and its history
StatusBarAcross the bottom: the coordinates, the drafting modes and Customization
ViewportControlsOn the drawing, top start corner: [Top], the preset views
ViewCubeOn the drawing, top end corner
NavigationBarOn the drawing, under the ViewCube: Pan, Zoom and Orbit
DynamicInputOn 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 }} />
  • state changes 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 with useEngineSelector(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 .flex and 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

  • mark is your product's glyph on the application menu's button, which shows a menu icon without it.

  • help is where F1 opens help, in a new tab, as AutoCAD does: index with no command running, and command while 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. Without help, F1 is the browser's.

  • layoutStorage names the localStorage keys 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, palette needs the layout script too, or the panel shows as the window's width decides until the scripts run, then changes.

  • sheet gives the drawing's cell an id and a view-transition-name, for a page that grows into the editor with a view transition.