Skip to main content

Command System

The command system allows you to execute arbitrary operation against a design. Under the hood our workflow experience is built using composed commands. But at any time you can break out of this and execute commands directly. This is a great way to add custom functionality to your workflow experience. After building a workflow experience you can obtain a command context from it using the following.

Usage

const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontColorCommand(elementId, "#FFFFFF"))

Undo & Redo

The command context supports undo and redo operations. This allows you to give your customers the power to quickly jump back and forth between changes.

const ctx = workflowExperience.getCommandContext();
ctx.undo();
ctx.redo();

Commands

Generic

Generic commands apply to all elements that we provide. These commands relate to functionality that is common to all elements or to the design itself.

MoveCommand

The move command allows you to set a new position for an element. After being dispatched the target element will have its x, y properties updated to reflect the new position.

Things to Note
  • This command is affected by limitations imposed by configuration such as editable areas.
  • Movements are absolute, not relative. Passing x = 100, y = 100 will not be relative to the current position.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new MoveCommand(targetElementID, 100, 100))

RotateCommand

The rotate command allows you to set a new rotation for an element in degrees. After being dispatched the target element will have its rotation property updated to reflect the new rotation.

Things to Note
  • This command is affected by limitations imposed by configuration such as editable areas.
  • Rotations are in degrees.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new RotateCommand(targetElementID, 45))

ResizeCommand

The resize command allows you to set a new size for an element. After being dispatched the target element will have its width, height properties updated to reflect the new size.

Things to Note
  • This command is affected by limitations imposed by configuration such as editable areas.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new ResizeCommand(targetElementID, 100, 100))

BringToFrontCommand

This command allows you to shift an element to the top index in accordance to the layering system. After being dispatched the target element will have its layerIndex property updated to reflect the new position.

Things to Note
  • If the element is already on the top index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new BringToFrontCommand(targetElementID))

BringForwardCommand

This command allows you to shift an element forward by one index in accordance to the layering system. After being dispatched the target element will have its layerIndex property updated to reflect the new position.

Things to Note
  • If the element is already on the top index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new BringForwardCommand(targetElementID))

BringToBackCommand

This command allows you to shift an element to the bottom index in accordance to the layering system. After being dispatched the target element will have its layerIndex property updated to reflect the new position.

Things to Note
  • If the element is already on the bottom index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new BringToBackCommand(targetElementID))

SendBackwardsCommand

This command allows you to shift an element backwards by one index in accordance to the layering system. After being dispatched the target element will have its 'layerIndex' property updated to reflect the new position.

Things to Note
  • If the element is already on the bottom index within its current layer, this command will have no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new SendBackwardsCommand(targetElementID))

LayerCommand

With the layering command you can change the layer group of a specific element in accordance to the layering system. After being dispatched the target element will have its 'layer' property updated to reflect the new position.

const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new LayerCommand(targetElementID, 3))

GroupCommand

The group command allows you to batch multiple commands into a single undoable/redoable group. Undo / Redo behavior is explained in further detail above.

warning

This command will be renamed to 'CompositeCommand' in the future. The GroupCommand will then be used to group elements together within a container element. Please keep this in mind when upgrading versions as it will be a breaking change. The interface typing will change so adapting your code should be easy.

const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new GroupCommand([
new MoveCommand(targetElementID, 100, 100),
new RotateCommand(targetElementID, 45)
]))

CreateElementCommand

Creating arbitrary elements is also achieved with the CreateElementCommand. This command allows you to create a new element and add it to the design. You may express all of the properties of the element you wish to create. If you do not provide a given property, sensible defaults will be used.

To ease the creation of elements, we provide a set of helper functions that will create elements with the correct properties for you. These are static methods on the LayoutElementFactory class. For example to create an Illustration element you could use the following.

await LayoutElementFactory.getIllustration(layout, { src: link })

This will load an SVG asset from the provided link and return an Illustration element with the correct properties set. Width and height would be inferred from the 'viewbox' attribute.

Things to Note
  • If no explicit region is provided, the element will be positioned at the center of the editable area if defined, otherwise it will be positioned at the center of the layout.
const { state, uiDispatcher } = useEditorState();
const { getLayoutById } = useLayouts();
const layout = getLayoutById(state.layoutId);
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new CreateElementCommand({ ...elementProperties }, layout.layoutState.layout))

DeleteElementCommand

The delete element command allows you to remove an element from the design.

const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new DeleteElementCommand(targetElementID))

CloneElementCommand

Cloning elements can be achieved with a target element & layout. All properties from the original element will be copied across, the original ID will be replaced with a new one.

const { state, uiDispatcher } = useEditorState();
const { getLayoutById } = useLayouts();
const layout = getLayoutById(state.layoutId);
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new CloneElementCommand(targetElementID, , layout.layoutState.layout))

Text

Text commands only work with Textbox elements. They provide functionality specific to the rendering of text.

FontColorCommand

Text elements can have their color changed with the FontColorCommand. This command will update the color property of the target element.

Setting Spot Colors

Color profiles are a topic on their own. Our system allows you to upload & embed color profiles into illustrations & on text. You can learn more about them on their support page. You'll find an example of setting color with a profile below.

// Set the color to black
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontColorCommand(targetElementID, '#000000'))
// To use a color profile, you can pass in a profile name and a named color
ctx.commandDispatcher(new FontColorCommand(targetElementID, '#000000', {profileName: "my-color-profile", namedColor: "Gold"}))

FontSizeCommand

You may change the font size of a textbox element with the FontSizeCommand. This command will update the 'fontSize' property of the target element.

const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontSizeCommand(targetElementID, 16))

FontAlgorithmCommand

Updates the algorithm used to render text. Use the TextAlgorithm enumeration to specify. There are two algorithms to choose from

  • Traditional - This is favored in any case where user manipulates text in an 'editor' style. It renders a sentence out to the width of the element and then breaks to a new line.
  • Autosize - This algorithm computes the size of the text to fit the element. It will not break to a new line unless configured to do so.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontAlgorithmCommand(targetElementID, TextAlgorithm.Traditional))

FontSourceCommand

Changes the font family used to render a text element. Fonts can be loaded from an asset link. The asset must be of type 'Font' and have a 'cdn' rel. The font will be loaded from the provided link and then the font family will be updated on the target element.

const src = asset.links.find((l) => l.rel === "cdn")?.href;
const font = await loadFontFromExternalUrl(src!);
const fontData = {
assetUrl: src!,
name: font.names.fullName["en"],
};
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontSourceCommand(targetElementID, fontData))

FontAlignmentCommand

Changes the alignment of text within a text element. The available values are "left", "center", "right".

Things to Note
  • The alignment is computed base on the width of a rendered line and the size of the textbox element itself. If the line matches the width of the element, there will be no effect.
const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new FontAlignmentCommand(targetElementID, "right"))

TextChangeCommand

Modifies the text within a textbox element. This command will update the 'text' property of the target element. As an example you may dispatch this event from a text input field.

const ctx = workflowExperience.getCommandContext();
ctx.commandDispatcher(new TextChangeCommand(targetElementID, "The quick brown fox jumps over the lazy dog."))