---
url: /documentation/concepts/elements/definition.md
description: >-
  Reference for element definitions, covering IDs, labels, icons, groups,
  properties, dialogs, restrictions, inheritance, and masks.
---

# Defining Elements

## Basic Definition Structure

Each element has a definition which describes how it should be composed and used.
If an element node is created, this definition is used to set up the edit dialog and further options.

A definition consists of a basic object shaped like the following:

```js
{
  id: 'my-element',
  label: 'My Element',
  icon: '...',
  tags: ['tag1', 'tag2'],
  isContainer: true,
  groups: ['example', 'other'],
  allowedGroups: ['group3'],
  allowCustomCss: false,
  properties: [],
}
```

The following options are available:

| Option | Values | Default | Description |
| - | - | - | - |
| `id` | `string` | - | Unique identifier for the element type. |
| `label` | `string` | - | Human readable name of the element. |
| `icon` | `string` | - | HTML code used as element icon. Could be a [Dashicons](https://developer.wordpress.org/resource/dashicons/) `<span>` or an inline `<svg>`. |
| `tags` | `string[]` | `[]` | A list of keywords that help the user find the element. |
| `isContainer` | `boolean` | `false` | Whether the element can contain child elements. |
| `groups` | `string[] \| '*'` | `[]` | A list of all group names which the element belongs to. Groups define which elements can be encapsulated within each other. "\*" means that this element can be placed anywhere. |
| `allowedGroups`  | `string[] \| '*'` | `[]` | A list of all group names that are allowed to be contained by this element. Only applicable for container elements. |
| `allowCustomCss` | `boolean` | `false` | Whether the element allows defining one-off CSS for individual element instances. Requires setting a `data-css-locator="[element-guid]"` attribute on the element's template root. |
| `properties` | `Property[]` | `[]` | A list of objects in the property format (see [Defining Properties](#defining-properties))                                                                                           |
| `dialog` | `boolean` | `true` | If `false`, the element is not editable (has no dialog window).                                                                                                                    |
| `restrictions` | `Record<string, boolean>` | `{}` | A set of flags, restricting how the editor is allowed to interact with the element (see [Restrictions](./restrictions)).                                                           |
| `extends` | `string` | - | Element ID of parent element, from which should be inherited. For more, see [Inheritance and Masking](./inheritance-and-masking).                                                  |
| `mask` | `Record<string, any>` | - | An object containing key value pairs of the property (key) and the prefilled value (value) which should masked.                                                                    |

## Define Properties

Properties are used to model the data stored in an instance of an element.
Properties consist of at least an unique identifier `id` a `label` and an `input`.
There are more options to specify e.g. a description or a default value etc.

The following example defines a property for a title text field:

```js
{
  id: 'title',
  label: 'Title',
  input: {
    type: 'text'
  }
}
```

The following options are available for each property:

| Option | Values | Default | Description |
| - | - | - | - |
| `id` | `string` | - | Identifier for the property, unique across this element's properties. |
| `label` | `string` | - | Human readable name for the property. |
| `description` | `string`  | - | Description of the property. |
| `input` | `object` | - | An object with a `type` property specifying the input type. Depending on the chosen input type, further options may be needed, see the *Input Types* section. |
| `defaultValue` | `any` | - | The default value that should be used for the property. |
| `isHidden`  | `boolean` | `false` | Whether the property is hidden in the property form.This option has been replaced with the more powerful `isVisible` in  and has therefore been deprecated. |
| `isVisible`  | `boolean` | `false` | Whether the property is hidden in the property form. |
| `groups` | `string[]` | - | An array with group identifiers; defines which groups of users can see the property. |
| `collapsed`  | `boolean` | `false` | Whether the property is collapsed in its initial state.This option is a no-op since  and has therefore been deprecated. |
| `layout`  | `'row' \| 'column' \| 'auto' \| 'followup'` | `'auto'` | How the label/description and the interactive part of the property should be arranged.Using `'auto'` falls back to the `layout` option [during registration](../input-types#registering-an-input-type).Using `'followup'`  reduces distinction between the property and its predecessor, making them feel more cohesive. |

## Property Visibility

### Static Visibility

To (temporarily) hide a property, you can set the `isVisible` option to `false`:

```js
{
  id: 'my-property',
  label: 'My Property',
  isVisible: false
}
```

:::info
Up until , the `isHidden` option was used for this purpose. It has been deprecated in favor of `isVisible` in .
:::

### Dynamic Visibility&#x20;

A property can be shown based on the value of another property in the same property form by passing conditions to the `isVisible` option:

```js
{
  id: 'my-property',
  label: 'My Property',
  isVisible: [
    ['other-property', 'equals', 'foo'],
  ]
}
```

#### Condition Structure

Each condition is a 3-tuple consisting of

1. the depended-on property's ID
2. the condition name and
3. a (sometimes optional) payload.

Which particular conditions are available depends on the input type of the depended-on property. See the individual input types' documentation for more information.

#### Condition Grouping

For more complex scenarios, you can group conditions:

```js
{
  type: 'all', // type can be 'all', 'some' or 'none'
  conditions: [
    // condition 1,
    // condition 2,
    // ...
  ]
}
```

These condition groups can also be arbitrarily nested.

:::info
The format used in the introductory example above...

```js
isVisible: [
  ['other-property', 'equals', 'foo']
]
```

...is just a shorthand for the most common case, which is a condtion group of type `all`:

```js
isVisible: {
  type: 'all',
  conditions: [
    ['other-property', 'equals', 'foo']
  ]
}
```

:::

### Group-based Visibility

You can control which user should see which property by assigning groups to the a property.

```js
{
  id: 'my-property',
  label: 'My Property',
  groups: ['experts']
}
```

If the group attribute is not defined, everyone is allowed to see this property.
