How to Write Custom Components
The CE.SDK web editor provides a set of built-in components that you can reference and render in a specific order. You can see a list of all available components in the respective documentation, including Dock, Canvas Menu, Inspector Bar, Navigation Bar and Canvas Bar.
Additionally, you can write your own custom components, register them, and use them just like the built-in components. This allows you to extend the functionality of the CE.SDK web editor with custom logic and create a more personalized experience for your users.
Registering a Custom Component#
The entry point for writing a custom component is the method registerComponent
. For a given identifier, you add a function that will be called repeatedly to render this component. Several arguments are passed to this function that can be used to access the current state of the engine
and render an UI with the help of the builder
.
cesdk.ui.registerComponent('myCustomComponent', ({ builder: { Button }, engine }) => {const selectedIds = engine.block.findAllSelected();if (selectedIds.length !== 1) return;Button('button-id', {label: 'My Button',onClick: () => {console.log('Button clicked');}});});
When is a Component Rendered?#
It is important concept to understand when a registered component re-renders after its initial rendering. The component assumes that all its state is stored in the engine
or the local state. Whenever we detect a change that is relevant for this component it will re-render.
Using the Engine#
In the above example, we query for all selected blocks and based on the result we render a button or not. The engine detects the call to findAllSelected
and now knows that if the selection changes, it needs to re-render this component. This works with all methods provided by the engine.
Using Local State#
Besides the engine
, the render function also receives a state
argument to manage local state. This can be used to control input components or store state in general. When the state changes, the component will be re-rendered as well.
The state
argument is a function that is called with a unique ID for the state. Any subsequent call to the state within this registered component will return the same state. The second optional argument is the default value for this state. If the state has not been set yet, it will return this value. Without this argument, you'll need to handle undefined
values manually.
The return value of the state call is an object with value
and setValue
properties, which can be used to get and set the state. Since these property names match those used by input components, the object can be directly spread into the component options.
cesdk.ui.registerComponent('counter', ({ builder, state }) => {const { value, setValue } = state('counter', 0);builder.Button('counter-button', {label: `${value} clicks`,onClick: () => {const pressed = value + 1;setValue(pressed);}});});
Passing Data to a Custom Component#
If you add a component to an order, you can either pass a string representing the component or an object with the id and additional data. This data can be accessed in the component function with inside the payload
property.
cesdk.ui.registerComponent('myDockEnry.dock',({ builder: { Button }, engine, payload }) => {const { label } = payload;console.log("Label", label);});cesdk.ui.setDockOrder([{id: 'myDockEnry.dock',label: "Custom Label"}]);
Using the Builder#
The builder
object passed to the render function provides a set of methods to create UI elements. Calling this method will add a builder component to the user interface. This includes buttons, dropdowns, text, etc.
Available Builder components#
Not every location supports every builder component yet. It will be extended over time. If you are unsure, you can always check the documentation of the respective component.
Builder Component | Description | Properties | Available For |
---|---|---|---|
Builder Component builder.Button | Description A simple button to react on a user click. | Properties label: The label inside the button. If it is a i18n key, it will be used for translation.onClick: Executed when the button is clicked. variant: The variant of the button. regular is the default variant, plain is a variant without any background or border.color: The color of the button. accent is the accent color to stand out, danger is a red color.icon: The icon of the button. isActive: A boolean to indicate that the button is active. isSelected: A boolean to indicate that the button is selected. isDisabled: A boolean to indicate that the button is disabled. isLoading: A boolean to indicate that the button is in a loading state. loadingProgress: A number between 0 and 1 to indicate the progress of a loading button. tooltip: A tooltip displayed upon hover. If it is a i18n key, it will be used for translation. | Available For Dock, Canvas Menu, Inspector Bar, Navigation Bar and Canvas Bar |
Builder Component builder.ButtonGroup | Description Grouping of multiple buttons in a single segmented control. | Properties children: A function executed to render grouped buttons. Only the Button and Dropdown builder components are allowed to be rendered inside this function. | Available For Dock, Canvas Menu, Inspector Bar, Navigation Bar and Canvas Bar |
Builder Component builder.Dropdown | Description A button that opens a dropdown with additional content when the user clicks on it. | Properties The same properties as for builder.Button , but instead of onClick it provides: children: A function executed to render the content of the dropdown. Every builder component called in this children function, will be rendered in the dropdown | Available For Canvas Menu, Inspector Bar and Navigation Bar |
Builder Component builder.Heading | Description Renders its content as heading to the navigation bar. | Properties content: The content of the header as a string | Available For Navigation Bar |
Builder Component builder.Separator | Description Adds a small space (invisible <hr> element) in the canvas menu to help the visual separation of entries.Separators follow some special layouting rules: - If 2 or more separators end up next to each other (e.g. due to other components not rendering), only 1 separator will be rendered. - Separators that end up being the first or last element in the canvas menu will not be rendered. - Separators directly adjacent to the top side of a spacer (see below) will not be rendered. | Properties - | Available For Dock, Canvas Menu, Inspector Bar, Navigation Bar and Canvas Bar |