Custom UI

Keep custom controls in sync

Render selection-aware controls and confirm what each command did.

The Bold button from the first control guide changes as you move the selection. It does not inspect the document DOM. It renders command state from the Editor, runs the command, and handles the result.

Follow one control through the loop

Choose each sample selection below. Press Bold when it is available. The model shows the state your control renders and the result it handles after the command runs.

Interactive modelWatch one control follow the selection

Choose sample content, then press Bold. The selection is simulated so each state is immediate. A real controller derives the same values from the active Editor selection.

Your toolbar
enabled
true
active
false
reason
undefined
result
Run Bold to see the command result.

Every custom control repeats the same four steps:

  1. Read the command's current state.
  2. Render that state in your control.
  3. Run the command from the user's action.
  4. Inspect the result before reporting success or starting dependent work.

Render the current state

Each command exposes a small state object:

FieldWhat your control should do
enabledDisable the action when it cannot run
activeShow whether a toggle is applied
valueShow the current value for a picker
reasonExplain why an action is disabled
supportedCheck whether the controller recognizes and can route the command

Use getState() for the initial value and observe() for later changes. In React, useSuperDocCommand(id) does both and rerenders the component when the state changes.

Do not derive state from the rendered document DOM. Selection, mode, history, and document content can all change whether a command is available.

Disable a control when enabled is false. Show reason when it helps someone recover. Remove the control only when the workflow does not need it.

Confirm the command result

Use executeAsync() when your interface or later work depends on the action:

ResultMeaning
falseThe controller could not route the command
trueThe host completed the command without a receipt
{ success: true }The document operation completed
{ success: false }The receipt explains why the operation did not finish

Command state is a snapshot, so check the result even when enabled was true. For receipt failure codes, see Receipts and errors.

Choose commands deliberately

Use BuiltInCommandId when a control accepts only SuperDoc commands. Use CommandId when it can also accept commands registered by your application. Both types are exported from superdoc/ui.

ui.commands.ids lists the commands known to the current controller, and ui.commands.has(id) checks one ID. Use those methods for discovery or capability checks. Choose the actions your workflow needs instead of generating a toolbar from the entire list.

Next, build a custom toolbar that applies this loop to Bold, font, and size. If you do not need to own the toolbar's markup or interaction design, configure the built-in toolbar instead.

On this page