Schema is the most important property of a No-Code Component definition. It defines visually editable properties and subcomponents of a No-Code Component.
In our SimpleBanner example the schema looks like this:
The first 5 properties are "basic properties" (backgroundColor, hasBorder, padding, gap and buttonsGap) whereas the Title and Buttons are subcomponents.
Basic properties
Responsiveness
The great thing about Easyblocks is built-in responsiveness. The space and color properties are responsive by default whereas for boolean property (hasBorder) we enabled it with responsive: true flag. Thanks to this each property can be overridden on mobile:
Subcomponents (children components)
The Title and Buttons schema properties are respectively of component and component-collection types. The subcomponents allow for nested selection in the editor. Important notes:
accepts property defines what kind of components are allowed as children for a specific subcomponent schema property. It's a very powerful property that allows for adding constraints to your visual builder and making sure non-technical users will always produce a correct output.
Title has a flag required: true which means that it's always defined.
Buttons is a component-collection which means an array of components of type Button.
placeholderAppearance determines the appearance of the placeholder shown in the layout when the list is empty.
In the video below you can see children components in action with nested selection and drag&drop:
Passing to React component
Each schema property will be passed as a prop to your React component. You can override this behaviour by setting buildOnly: true for your schema property:
Under the hood each No-Code Component instance added to the canvas is represented by a JSON called No-Code Entry. In this case our component JSON representation for selected element looks like this:
Each time makes changes to the fields, the underlying No-Code Entry changes.
No-Code Entry is the most important data format used in Easyblocks. It's a full JSON representation of what is visually built in the Easyblocks Editor. It's a tree structure so if a No-Code Component has children components (component or component-collection fields) then the children are represented by nested No-Code Entries (look at Title field in example above).
Select type requires options parameter to be set to know what options are available. Options can be simple array of strings or each option can be an object of type { value: string; label: string } which allows for better control how options are shown on the list.
String
String type holds a string value that's not localizable.
{
prop: "slug",
type: "string",
label: "Slug"
}
Text
Text type is similiar to type String, but the value can vary between locales - it's localizable.
{
prop: "title",
type: "text",
label: "Title"
}
Value of field of type text is stored in No-Code Entry in the following way:
{
...,
"title": {
"en-US": "Hello world"
}
}
Easyblocks offers a built-in component @easyblocks/text utilising text type.
Responsiveness
Most of the types can be responsive. It means that the user in the editor will be able to set different values for different breakpoints. boolean, select and string types can be optionally responsive. You can enable responsiveness with responsive flag.
The underlying data format of responsive fields in the No-Code Entry is different from non-reponsive fields. Here's an example for boolean:
// NON-RESPONSIVE
{
prop: "isDisabled",
type: "boolean",
label: "Disabled?"
}
// value in No-Code Entry
{
// ...
isDisabled: true
}
// RESPONSIVE FIELD
{
prop: "isDisabled",
type: "boolean",
label: "Disabled?"
responsive: true
}
// value in No-Code Entry
{
isDisabled: {
$res: true
xs: false
xl: true
}
}
Token types
All built-in token fields are responsive by default and it can't be disabled.
Color
Color type allows to select single value from the list of values coming from Config.tokens.colors. You can also set a custom HEX value.
Color type allows to select single value from the list of values based on the Config.tokens.space. Easyblocks also supplies for each space field type a set of predefined space values.
Component based types are special kind of fields. Instead of extending the sidebar experience, they allow you to extend capabilities of your component by defining nested components that can also be selected and can have their own set of fields. Component fields can't be responsive.
Component
Component field creates a slot which can be filled with single component.
component field, as other field types, is passed within props to your React component. The passed component prop is a React element, not a React component. It's super important to remember it. Below is the example how you can use passed Component field:
import type { ReactElement } from "react";
type MyNoCodeComponentProps = {
Component: ReactElement;
};
function MyNoCodeComponent({ Component }: MyNoCodeComponentProps) {
return <Component.type {...Component.props} />;
}
accepts
In the code example above, we tell editor to only allow to add built-in Rich Text component to our Component field by setting accepts property. You can limit number of accepted components also to your own No-Code Components by specifying their id property.
// "MyComponent" No-Code Component definiton
{
id: "MyComponent",
schema: [...]
}
// Component field of type "MyComponent"
{
prop: "Component",
type: "component",
accepts: ["MyComponent"]
}
When defining No-Code component you can set its type. You can think of this value as a tag or interface. It lets you gather multiple components under one name and then tell your component field to accept all components of given type ex.:
By default, each component field is optional and can be left empty and it won't render anything (or a placeholder when in the editor). By setting required: true, we mark the field as non removable.
{
prop: "Component",
type: "component",
accepts: ["MyComponent"],
// This field can't be empty
required: true
}
It's great when your component should have a fixed element. Imagine a card component that always has to have heading, but subheading is optional. We could implement it like this:
Easyblocks is shipped with two built-in components that can be handy:
@easyblocks/rich-text - rich text component for text editing values that's also localizable
@easyblocks/text - a simpler version component for text editing component that's also localizable, but without being rich (single font and color, no links).
Component Collection
Component collection field creates a slot which can be filled with any number of components.
Since the field represents a collection, it means that when the field is passed to your React component it's going to be an array of React elements. You can render it similarly to component field:
import type { ReactElement } from "react";
type MyNoCodeComponentProps = {
Components: Array<ReactElement>;
};
function MyNoCodeComponent({ Component }: MyNoCodeComponentProps) {
return Components.map((Component, index) => {
return <Component.type key={index} {...Component.props} />;
});
}
Items adding direction
By default, when you use component-collection field and start adding items on the canvas the buttons for adding items at the beginning or at the end of each item are rendered vertically. If your collection is oriented horizontally, you cen edit this behaviour by using editing method of component definition and specifying direction property for each item.
It's a common practise for parent component to determine how it should render based on its children. Let's imagine you're building a Grid component for displaying your Card components. In the simplest case we could just render each item using CSS Grid using fixed number of rows and columns. Each card would occupy one row and column.
To put more emphasise on some cards we would like to make them occupy 2 columns and 1 row or even 2 columns and 2 rows. This behaviour would affect how the parent component should render the grid. This would require to have information about each size of card within the parent, but allow to configure it on each grid item separately. To make it possible you can use itemFields property for your component-collection field. This property allows you to declare additional fields that are stored within the component defining the collection field, but these fields are configurable from the fields of collection items.
{
prop: "Cards",
type: "component-collection",
accepts: ["MyNoCodeCardComponent"],
itemFields: [
{
prop: "size",
type: "select",
label: "Size",
params: {
options: ["1x1", "2x1", "2x2"]
}
}
],
styles({ values: { Cards } }) {
// Now we have full access to each size of card
const cardSizes = Cards.map(Card => Card.size);
return {
styled: {
CardsGrid: {
display: "grid";
// Calculate the final layout based on card sizes
}
}
}
}
}
Basic properties are displayed in the sidebar when the component is selected (it's a default behaviour but it can be overridden via ).
In this example we use built-in space, color and boolean properties. The full list of properties can be found in the section below.
When buildOnly is set to true the property will be passed as a parameter to styles and editing functions but it won't be passed to the React component. It's often good to set this flag for properties used only in styles function (read to learn more).
This type can optionally be .
This type can optionally be .
This type can optionally be .
Easyblocks comes with handy built-in types that are based on design tokens you can specify in your config ()
Easyblocks allows to add custom types. Read the guide to learn more.