Skip to main content
The editor’s handle, EmbedEditorHandle, runs the editor from code. Its commands do what the controls on screen do, its reads tell what the editor holds, and its events tell you what changed.

Get the Handle

The same handle comes three ways: a ref on EmbedEditor, or what mountEditor and openEditor return. Both entries export the EmbedEditorHandle type.
  • EmbedEditor forwards its ref, in React 18 and 19. The handle is made once and stays the same through every new set of props.
  • mountEditor returns the handle with update and destroy. See mountEditor().
  • openEditor returns the handle with close. See openEditor().
The examples on these pages call the handle editor.

How Every Command Behaves

  • It returns a Promise. It resolves once the editor rendered the result: the step is in the history and on screen. It resolves to null, or to what it made (output.save gives { dest, state }). A command that changes nothing, such as an undo with nothing to undo, still resolves.
  • It takes one object, or nothing: editor.menu.select({ item: 'FILTER' }). The same object is its input in run.
  • It waits its turn. Commands run one at a time, in the order you call them. You don’t need to await one before you call the next.
  • It waits for the image. ready resolves once the image is on screen, and commands start then. A command called before that waits for it, and doesn’t fail. A load that fails keeps it waiting until a new src, or a picked image, loads.
  • It never runs under the user’s hand. While the user holds a drag, a pinch or an arrow key on a control, while a Save is on its way, or while they type the words of an annotation or a mark, a command waits, then runs.
  • An edit is one undo step, as the same control on screen makes, and history.undo takes it back. A command that only changes what is shown, such as menu.select, makes no step.
  • Its values are the saved state’s. Coordinates are in the px of the size the editor works the image at (read.size()), adjustments run −100 to 100, rotation is in degrees, and filters and frames go by the ids the state writes. If you can read an EditState, you can write a command.
  • It acts from outside. A command runs the same code as the control on screen, with its motion and its undo step, but not as a hand: the tool’s name doesn’t show over the photo, and a ruler doesn’t go into its focus mode.
The undo below runs once the toggle is done, and takes it back:
queue.ts

When the Editor Leaves

Once the editor leaves the page, every command waiting and every one you call after rejects with NOT_AVAILABLE. A command running as it leaves rejects too, though what it already changed stays, and it changes nothing more, even once the editor is back. ready rejects the same way if the image wasn’t on screen yet, and stays rejected: an editor shown again takes commands, but its ready doesn’t come back.
  • EmbedEditor unmounted. Hidden by an <Activity> instead, its commands work again once it is shown.
  • mountEditor’s destroy, or another mountEditor on the same element: that handle takes no more commands.
  • openEditor’s modal closed, however it closes (close, its Close button, Escape, a Save that went through): that handle takes no more commands.
Before the editor first mounts, a command waits for it.

What Isn’t a Command

Copy, Share and the eyedropper. The browser allows the clipboard, the share sheet and the eyedropper only inside a gesture of the user’s own, so they stay buttons. For the file, call output.exportFile() and copy or share it yourself.

Errors

A command rejects with an EmbedEditorError, whose code says what to fix. A rejected command changes nothing.
errors.ts

Events

on calls handler with what each event says, until you call the function it returns. A handler’s own error is logged with console.error, never the editor’s. After destroy, or once the modal closed, no event fires. Keep a draft of every step, to reopen it later with the state prop:
draft.ts
Call stop() when you no longer need it.

Editions

Every edition has the same EmbedEditorHandle, as it has the same props. The Free and the Lite have Adjust alone:
  • A command of a tool only the Full has is still on the handle. It rejects with NOT_AVAILABLE, and a read of it answers null. commands() leaves it out, so a model never sees it.
  • menu.select and menu.toggle reject with NOT_AVAILABLE for an item the edition doesn’t have, as for one a prop turned off.
The Full has every command.

History and Output

Undo, Redo, Reset, Save, the file and Close.

Menu and Reads

The menu’s items and what the editor holds.

Adjust Commands

The crop, the size and the view.

Filter, Frame and Adjustments

The filter, the frame, the adjustments, Auto and the palette.

Obfuscate and Marks

The areas that hide parts of the photo, the watermark and the signature.

Annotate

The annotations, their style, the action bar’s verbs and the Numbers’ list.

For AI

run, commands() and a model’s tools.

EmbedEditorError

The error and its codes.