diff --git a/17/umbraco-cms/SUMMARY.md b/17/umbraco-cms/SUMMARY.md
index 0743edc8530..e1919216f9b 100644
--- a/17/umbraco-cms/SUMMARY.md
+++ b/17/umbraco-cms/SUMMARY.md
@@ -183,6 +183,8 @@
* [Modals](customizing/extending-overview/extension-types/modals/README.md)
* [Custom Modals](customizing/extending-overview/extension-types/modals/custom-modals.md)
* [Modal Route Registration](customizing/extending-overview/extension-types/modals/route-registration.md)
+ * [Property Editor Schema](customizing/extending-overview/extension-types/property-editor-schema.md)
+ * [Property Editor UI](customizing/extending-overview/extension-types/property-editor-ui.md)
* [Property Value Preset](customizing/extending-overview/extension-types/property-value-preset.md)
* [Sections](customizing/extending-overview/extension-types/sections/README.md)
* [Section](customizing/extending-overview/extension-types/sections/section.md)
diff --git a/17/umbraco-cms/customizing/extending-overview/extension-types/README.md b/17/umbraco-cms/customizing/extending-overview/extension-types/README.md
index 3634a36610b..a15ddbe2df2 100644
--- a/17/umbraco-cms/customizing/extending-overview/extension-types/README.md
+++ b/17/umbraco-cms/customizing/extending-overview/extension-types/README.md
@@ -159,8 +159,8 @@ These are the current types of UI Extensions:
| packageView | A package view is an optional view that can be shown in the "Packages" section of the Backoffice. The user can navigate to this view to see more information about the package and to manage it. |
| previewAppProvider | A preview app provider is a provider that can be used to provide a preview app for the Save and Preview action on a document. |
| propertyAction | A property action is a button that can be added to the property actions menu. |
-| propertyEditorSchema | A property editor schema is a model that describes a Data Editor and its properties from the backend to the UI. It is used by Property Editor UIs. Read more about [Property Editors](../../property-editors/). |
-| propertyEditorUi | A property editor UI is a UI component that can be added to content types. It is used to render the UI of a Data Editor. Read more about [Property Editors](../../property-editors/). |
+| propertyEditorSchema | A property editor schema is a model that describes a Data Editor and its properties from the backend to the UI. It is used by Property Editor UIs. Read more about [Property Editor Schema](property-editor-schema.md). |
+| propertyEditorUi | A property editor UI is a UI component that can be added to content types. It is used to render the UI of a Data Editor. Read more about [Property Editor UI](property-editor-ui.md). |
| searchProvider | A search provider is a provider that can be used to provide search results for the search bar in the Backoffice. |
| searchResultItem | A search result item is a component that can be added to the search results. |
| theme | A theme is a set of styles that can be added to the Backoffice. The user can select their preferred theme in the current user modal. |
diff --git a/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-schema.md b/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-schema.md
index e69de29bb2d..dec423881e2 100644
--- a/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-schema.md
+++ b/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-schema.md
@@ -0,0 +1,216 @@
+---
+description: Reference documentation for the propertyEditorSchema extension type
+---
+
+# Property Editor Schema
+
+The `propertyEditorSchema` extension type registers a Property Editor Schema in the Umbraco backoffice. A Property Editor Schema defines the server-side data contract for a property editor, including data storage type, validation rules, and configuration options.
+
+{% hint style="info" %}
+For detailed information about implementing Property Editor Schemas with C# classes (`DataEditor` and `DataValueEditor`), see the [Property Editor Schema Guide](../../property-editors/composition/property-editor-schema.md).
+{% endhint %}
+
+## Manifest Structure
+
+The manifest defines how the schema appears in the backoffice and what configuration options are available when creating Data Types.
+
+### Basic Example
+
+A minimal schema manifest specifies which Property Editor UI should be used by default:
+
+```typescript
+import type { ManifestPropertyEditorSchema } from '@umbraco-cms/backoffice/property-editor';
+
+export const manifest: ManifestPropertyEditorSchema = {
+ type: 'propertyEditorSchema',
+ name: 'Text Box',
+ alias: 'Umbraco.TextBox',
+ meta: {
+ defaultPropertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
+ },
+};
+```
+
+### Example with Configuration
+
+If your Property Editor Schema has configurable settings, define them in the manifest to enable administrators to configure the Data Type in the backoffice:
+
+```typescript
+export const manifest: ManifestPropertyEditorSchema = {
+ type: 'propertyEditorSchema',
+ name: 'Decimal',
+ alias: 'Umbraco.Decimal',
+ meta: {
+ defaultPropertyEditorUiAlias: 'Umb.PropertyEditorUi.Decimal',
+ settings: {
+ properties: [
+ {
+ alias: 'placeholder',
+ label: 'Placeholder text',
+ description: 'Enter the text to be displayed when the value is empty',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
+ },
+ {
+ alias: 'step',
+ label: 'Step size',
+ description: 'The increment size for the numeric input',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
+ },
+ ],
+ defaultData: [
+ {
+ alias: 'step',
+ value: '0.01',
+ },
+ ],
+ },
+ },
+};
+```
+
+## Manifest Properties
+
+The `propertyEditorSchema` manifest can contain the following properties:
+
+### Required Properties
+
+| Property | Type | Description |
+| -------- | ------ | --------------------------------------------------------------------------- |
+| type | string | Must be `"propertyEditorSchema"`. |
+| alias | string | Unique identifier for the schema. Must match the C# `DataEditor` alias. |
+| name | string | Friendly name displayed in the backoffice. |
+| meta | object | Metadata object containing schema configuration (see Meta Properties below). |
+
+### Optional Properties
+
+| Property | Type | Description |
+| -------- | ------ | -------------------------------------------------------------- |
+| weight | number | Ordering weight. Higher numbers appear first in lists. |
+| kind | string | Optional kind identifier for grouping related schemas. |
+
+## Meta Properties
+
+The `meta` object contains the following properties:
+
+### Required Meta Properties
+
+| Property | Type | Description |
+| ---------------------------- | ------ | --------------------------------------------------------------------- |
+| defaultPropertyEditorUiAlias | string | The alias of the default Property Editor UI to use with this schema. |
+
+### Optional Meta Properties
+
+| Property | Type | Description |
+| -------- | ------ | ------------------------------------------------------------------------ |
+| settings | object | Configuration settings for the property editor (see Settings below). |
+
+## Settings Structure
+
+The `settings` object defines what configuration options appear when creating or editing a Data Type:
+
+```typescript
+settings: {
+ properties: PropertyEditorSettingsProperty[];
+ defaultData?: PropertyEditorSettingsDefaultData[];
+}
+```
+
+### Settings Properties Array
+
+Each object in the `properties` array defines a configuration field:
+
+| Property | Type | Required | Description |
+| ------------------------ | ------ | -------- | ------------------------------------------------------------------------------ |
+| alias | string | Yes | Unique identifier. Must match the C# `ConfigurationEditor` property name. |
+| label | string | Yes | Display label for the configuration field. |
+| description | string | No | Help text shown below the label. |
+| propertyEditorUiAlias | string | Yes | The Property Editor UI to use for editing this configuration value. |
+| config | object | No | Optional configuration to pass to the Property Editor UI. |
+| weight | number | No | Optional ordering weight for the configuration field. |
+
+### Settings Default Data Array
+
+Each object in the `defaultData` array provides default values:
+
+| Property | Type | Required | Description |
+| -------- | ------- | -------- | --------------------------------------------- |
+| alias | string | Yes | The alias of the configuration property. |
+| value | unknown | Yes | The default value for this configuration. |
+
+## Complete Example
+
+```typescript
+import type { ManifestPropertyEditorSchema } from '@umbraco-cms/backoffice/property-editor';
+
+export const manifest: ManifestPropertyEditorSchema = {
+ type: 'propertyEditorSchema',
+ name: 'Suggestions Editor',
+ alias: 'My.PropertyEditor.Suggestions',
+ weight: 100,
+ meta: {
+ defaultPropertyEditorUiAlias: 'My.PropertyEditorUi.Suggestions',
+ settings: {
+ properties: [
+ {
+ alias: 'maxChars',
+ label: 'Maximum characters allowed',
+ description: 'The maximum number of allowed characters in a suggestion',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.Integer',
+ weight: 10,
+ },
+ {
+ alias: 'placeholder',
+ label: 'Placeholder text',
+ description: 'Text displayed when the field is empty',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
+ weight: 20,
+ },
+ {
+ alias: 'disabled',
+ label: 'Disabled',
+ description: 'Disables the suggestion button',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle',
+ weight: 30,
+ },
+ ],
+ defaultData: [
+ {
+ alias: 'maxChars',
+ value: 50,
+ },
+ {
+ alias: 'placeholder',
+ value: 'Write a suggestion',
+ },
+ {
+ alias: 'disabled',
+ value: true,
+ },
+ ],
+ },
+ },
+};
+```
+
+## Important Notes
+
+{% hint style="warning" %}
+The `alias` in the manifest **must exactly match** the alias used in the C# `DataEditor` attribute. The alias is the only connection between the server-side schema implementation and the client-side manifest.
+{% endhint %}
+
+{% hint style="warning" %}
+Configuration property aliases in `settings.properties` **must match** the property names defined in your C# `ConfigurationEditor` class. If they don't match, configuration values won't be properly passed to the backend for validation and storage.
+{% endhint %}
+
+{% hint style="info" %}
+
+Umbraco ships with [default property editor schemas](../../../tutorials/creating-a-property-editor/default-property-editor-schema-aliases.md) that you can use without creating custom C# classes.
+
+{% endhint %}
+
+## Related Documentation
+
+* [Property Editor Schema Guide](../../property-editors/composition/property-editor-schema.md) - Learn about implementing the C# classes (`DataEditor` and `DataValueEditor`).
+* [Property Editor UI Extension Type](property-editor-ui.md) - Reference for the Property Editor UI extension type.
+* [Creating a Property Editor Tutorial](../../../tutorials/creating-a-property-editor/) - Step-by-step guide to building a custom property editor.
+* [Adding Server-Side Validation](../../../tutorials/creating-a-property-editor/adding-server-side-validation.md) - Tutorial on implementing validation in your schema.
diff --git a/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-ui.md b/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-ui.md
index e69de29bb2d..fba92178348 100644
--- a/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-ui.md
+++ b/17/umbraco-cms/customizing/extending-overview/extension-types/property-editor-ui.md
@@ -0,0 +1,289 @@
+---
+description: Reference documentation for the propertyEditorUi extension type
+---
+
+# Property Editor UI
+
+The `propertyEditorUi` extension type registers a Property Editor UI in the Umbraco backoffice. A Property Editor UI is the client-side component that renders the editing interface for content editors to input and manage their data.
+
+{% hint style="info" %}
+For detailed information about implementing Property Editor UI web components using Lit, read the [Property Editor UI Guide](../../property-editors/composition/property-editor-ui.md).
+{% endhint %}
+
+## Manifest Structure
+
+The manifest defines how the UI appears in the backoffice, which schema it works with, and what configuration options are available.
+
+### Basic Example
+
+A minimal UI manifest specifies the element location and which schema to use:
+
+```typescript
+import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/property-editor';
+
+export const manifest: ManifestPropertyEditorUi = {
+ type: 'propertyEditorUi',
+ alias: 'My.PropertyEditorUi.TextBox',
+ name: 'My Text Box Property Editor UI',
+ element: () => import('./my-text-box.element.js'),
+ meta: {
+ label: 'My Text Box',
+ propertyEditorSchemaAlias: 'Umbraco.TextBox',
+ icon: 'icon-autofill',
+ group: 'common',
+ },
+};
+```
+
+### Example with Settings
+
+If your Property Editor UI has configurable settings, define them in the manifest:
+
+```typescript
+export const manifest: ManifestPropertyEditorUi = {
+ type: 'propertyEditorUi',
+ alias: 'My.PropertyEditorUi.Suggestions',
+ name: 'Suggestions Editor UI',
+ element: () => import('./suggestions.element.js'),
+ meta: {
+ label: 'Suggestions',
+ propertyEditorSchemaAlias: 'My.PropertyEditor.Suggestions',
+ icon: 'icon-chat',
+ group: 'pickers',
+ settings: {
+ properties: [
+ {
+ alias: 'placeholder',
+ label: 'Placeholder text',
+ description: 'Text shown when the field is empty',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
+ },
+ {
+ alias: 'showButton',
+ label: 'Show suggestion button',
+ description: 'Display a button to generate suggestions',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle',
+ },
+ ],
+ defaultData: [
+ {
+ alias: 'showButton',
+ value: true,
+ },
+ ],
+ },
+ },
+};
+```
+
+## Manifest Properties
+
+The `propertyEditorUi` manifest can contain the following properties:
+
+### Required Properties
+
+| Property | Type | Description |
+| -------- | ------------------------- | ---------------------------------------------------------------- |
+| type | string | Must be `"propertyEditorUi"`. |
+| alias | string | Unique identifier for the UI. |
+| name | string | Friendly name displayed in the backoffice. |
+| element | function \| string | Path to or import function for the web component element. |
+| meta | object | Metadata object containing UI configuration (see Meta Properties).|
+
+### Optional Properties
+
+| Property | Type | Description |
+| -------- | ------ | -------------------------------------------------------------- |
+| weight | number | Ordering weight. Higher numbers appear first in lists. |
+
+## Meta Properties
+
+The `meta` object contains the following properties:
+
+### Required Meta Properties
+
+| Property | Type | Description |
+| ---------------------------- | ------ | --------------------------------------------------------------------- |
+| label | string | Display label shown in the UI picker. |
+| propertyEditorSchemaAlias | string | The alias of the Property Editor Schema this UI works with. |
+| icon | string | Icon identifier (e.g., `"icon-autofill"`). |
+| group | string | Group name for categorizing property editors. |
+
+### Optional Meta Properties
+
+| Property | Type | Description |
+| ---------------- | ------- | ------------------------------------------------------------------------ |
+| settings | object | Configuration settings for the UI (see Settings below). |
+| supportsReadOnly | boolean | Indicates whether the UI supports read-only mode. |
+
+## Settings Structure
+
+The `settings` object defines what configuration options appear when creating or editing a Data Type:
+
+```typescript
+settings: {
+ properties: PropertyEditorSettingsProperty[];
+ defaultData?: PropertyEditorSettingsDefaultData[];
+}
+```
+
+### Settings Properties Array
+
+Each object in the `properties` array defines a configuration field:
+
+| Property | Type | Required | Description |
+| ------------------------ | ------ | -------- | ------------------------------------------------------------------------------ |
+| alias | string | Yes | Unique identifier for this configuration property. |
+| label | string | Yes | Display label for the configuration field. |
+| description | string | No | Help text shown below the label. |
+| propertyEditorUiAlias | string | Yes | The Property Editor UI to use for editing this configuration value. |
+| config | object | No | Optional configuration to pass to the Property Editor UI. |
+| weight | number | No | Ordering weight for the configuration field. Higher numbers appear first. |
+| validation | object | No | Validation rules. Object with `mandatory` (boolean) and optional `mandatoryMessage` (string) properties. |
+| propertyEditorDataSourceAlias | string | No | Alias of a data source to use with this configuration property. |
+
+### Settings Default Data Array
+
+Each object in the `defaultData` array provides default values:
+
+| Property | Type | Required | Description |
+| -------- | ------- | -------- | --------------------------------------------- |
+| alias | string | Yes | The alias of the configuration property. |
+| value | unknown | Yes | The default value for this configuration. |
+
+## Element Loading
+
+The `element` property accepts three formats.
+
+### Import Function (Recommended)
+
+```typescript
+element: () => import('./my-editor.element.js')
+```
+
+The Import Function uses dynamic imports for better code splitting and lazy loading.
+
+### String Path
+
+```typescript
+element: '/App_Plugins/MyEditor/my-editor.element.js'
+```
+
+The String Path loads the element from a static file path.
+
+### Class Constructor
+
+```typescript
+import { MyEditorElement } from './my-editor.element.js';
+
+element: MyEditorElement
+```
+
+The Class Constructor directly provides the custom element class constructor.
+
+## Complete Example
+
+```typescript
+import type { ManifestPropertyEditorUi } from '@umbraco-cms/backoffice/property-editor';
+
+export const manifest: ManifestPropertyEditorUi = {
+ type: 'propertyEditorUi',
+ alias: 'My.PropertyEditorUi.AdvancedTextBox',
+ name: 'Advanced Text Box UI',
+ element: () => import('./advanced-text-box.element.js'),
+ weight: 200,
+ meta: {
+ label: 'Advanced Text Box',
+ propertyEditorSchemaAlias: 'Umbraco.TextBox',
+ icon: 'icon-edit',
+ group: 'common',
+ settings: {
+ properties: [
+ {
+ alias: 'placeholder',
+ label: 'Placeholder text',
+ description: 'Text displayed when the field is empty',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.TextBox',
+ },
+ {
+ alias: 'showCharacterCount',
+ label: 'Show character count',
+ description: 'Display the number of characters entered',
+ propertyEditorUiAlias: 'Umb.PropertyEditorUi.Toggle',
+ },
+ ],
+ defaultData: [
+ {
+ alias: 'placeholder',
+ value: 'Enter text here...',
+ },
+ {
+ alias: 'showCharacterCount',
+ value: true,
+ },
+ ],
+ },
+ },
+};
+```
+
+## Icon Names
+
+The `icon` property uses Umbraco's built-in icon set. Common icon names include:
+
+- `icon-autofill` - Text and input-related editors
+- `icon-list` - List and collection editors
+- `icon-calendar` - Date and time editors
+- `icon-picture` - Media and image editors
+- `icon-user` - User and member-related editors
+- `icon-link` - Link and URL editors
+- `icon-readonly` - Read-only or display editors
+
+While any string value is technically accepted, using unrecognized icon names may result in a missing or default icon being displayed.
+
+## Group Names
+
+The `group` property categorizes property editors in the backoffice UI. Common group names include:
+
+- `common` - General-purpose editors (default if not specified)
+- `pickers` - Content, media, and member pickers
+- `lists` - List-based editors like checkboxes and dropdowns
+- `richContent` - Rich text and block-based editors
+- `media` - Media-specific editors
+- `date` - Date and time editors
+- `people` - User and member editors
+- `advanced` - Advanced or specialized editors
+
+While technically a free-form string, using these documented values ensures proper grouping in the UI.
+
+## Read-Only Support
+
+Set `supportsReadOnly: true` in the `meta` object if your Property Editor UI implements read-only mode:
+
+```typescript
+meta: {
+ label: 'My Editor',
+ propertyEditorSchemaAlias: 'My.Schema',
+ icon: 'icon-edit',
+ group: 'common',
+ supportsReadOnly: true,
+}
+```
+
+When enabled, your element will receive a `readonly` property that indicates whether it should display in read-only mode. Your implementation must handle this property appropriately.
+
+## Important Notes
+
+{% hint style="warning" %}
+The `propertyEditorSchemaAlias` in the manifest **must match** an existing Property Editor Schema alias. This connects the UI to the backend data handling and validation.
+{% endhint %}
+
+{% hint style="info" %}
+The web component element specified in the `element` property must implement the `UmbPropertyEditorUiElement` interface. See the [Property Editor UI Guide](../../property-editors/composition/property-editor-ui.md) for implementation details.
+{% endhint %}
+
+## Related Documentation
+
+* [Property Editor UI Guide](../../property-editors/composition/property-editor-ui.md) - Learn about implementing the web component
+* [Property Editor Schema Extension Type](property-editor-schema.md) - Reference for the Property Editor Schema extension type
+* [Creating a Property Editor Tutorial](../../../tutorials/creating-a-property-editor/) - Step-by-step guide to building a custom property editor
diff --git a/17/umbraco-cms/customizing/property-editors/composition/README.md b/17/umbraco-cms/customizing/property-editors/composition/README.md
index 1305f631b49..abe51f6e22e 100644
--- a/17/umbraco-cms/customizing/property-editors/composition/README.md
+++ b/17/umbraco-cms/customizing/property-editors/composition/README.md
@@ -4,26 +4,68 @@ description: This section describes how to work with and create Property Editors
# Property Editors Composition
-{% hint style="warning" %}
-This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
-{% endhint %}
+A Property Editor is the fundamental building block for content editing in Umbraco. It defines how content editors input data, how that data is validated and stored, and how it appears in templates.
-A property editor is an editor used to insert content into Umbraco. A Property Editor is composed of two extensions. To form a full Property Editor you will need a:
+Property Editors enable content creation through familiar interfaces. Text boxes, rich text editors, media pickers, and date selectors are all Property Editors. Complex editors, such as the Block List and Block Grid, are also Property Editors following the same underlying architecture.
-* [Property Editor Schema](property-editor-schema.md)
-* [Property Editor UI](property-editor-ui.md)
+Every Property Editor has two distinct parts: a frontend UI component and a backend schema definition. The UI provides the visual editing experience in the backoffice. The schema defines data validation, storage format, and server-side processing rules.
-A Property Editor UI is utilizing a Property Editor Schema, and you can have multiple Property Editor UIs for one Schema. This means you can find a Schema that solves your needs. You only need to build a Property Editor UI.
+To use a Property Editor in your content, you create a Data Type. A Data Type connects a schema with a UI and applies specific configuration settings. This allows the same Property Editor to serve different purposes with different validation rules or display options.
-* Each Property Editor can have multiple Property Editor UIs.
-* Both a Property Editor Schema and Property Editor UI can define the Settings used for their configuration.
+## Property Editor Architecture
-### Configuration
+A Property Editor consists of two independent parts that work together: a backend schema definition and a frontend UI component.
-* Data Type Settings for a Property Editor or Property Editor UI is defined in the manifests.
-* They both use the same format for their settings.
+### Property Editor Schema - the backend part
-## Property Editor Data Sources
-A Property Editor Data Source is an optional way to provide data to a Property Editor UI. This allows for reuse of the same Property Editor UI but with different data sources.
+The Property Editor Schema defines the data contract and server-side processing rules. It specifies the database storage type, provides server-side validation, and handles data conversion between the UI and database. Property Editor Schemas are implemented in C# on the server side.
+
+The schema has the final authority on data validation. Client-side validation provides immediate feedback, but server-side validation always runs regardless of the UI used. The schema ensures data integrity and defines what constitutes valid data for storage.
+
+### Property Editor UI - the frontend part
+
+The Property Editor UI is the visual interface that content editors interact with in the backoffice. It renders the input controls, provides client-side validation, and displays user feedback. Property Editor UIs are built using web components.
+
+The UI component can be replaced without affecting stored data as long as the same schema is used. This allows different editing experiences while maintaining the same underlying data structure and validation rules.
+
+### Separation of Concerns
+
+This architectural separation provides flexibility. Multiple UIs can use the same schema with different visual presentations. The schema ensures data integrity, allowing you to swap the UI component without migration or data loss.
+
+
+
+### Data Types: Configuring Property Editors
+
+A Data Type is a configured instance of a Property Editor that you create in the Umbraco backoffice. A Data Type is the entity that you add as a property on a Document, Media, or Member Type. It defines how editors will manage a particular item of data.
+
+With Data Types, you can create one or multiple instances of the same Property Editor with different settings. When users are editing content, the Data Type recognizes which UI element to display and which settings to use. When content is saved, the Data Type knows how to process the data. It stores the Property Editor UI alias, the Property Editor Schema alias, and the Data Type settings.
+
+Take the __Text Box__ Property Editor for example. It has a setting for 'Maximum allowed characters'. You can create multiple Data Types using the Text Box Property Editor with different settings, based on your needs.
+
+### Settings
+
+Settings are what make each instance of a Property Editor unique. When creating a Data Type, you give the settings a value specific to that Data Type.
+
+Settings can be defined on both the Property Editor Schema and the Property Editor UI manifest. These settings are merged into one list. When you create a Data Type based on the Property Editor, the settings from the Schema and UI are both displayed. All settings and their values for that specific Data Type are also available to both the Schema and UI in code.
+
+It is best practice to define settings that impact how data is processed and stored on the Property Editor Schema. For instance, settings for whether a certain field on the Property Editor is required or has a maximum length. Settings that only impact the UI but not the data should be set on the Property Editor UI.
+
+There is technically nothing stopping you from doing it differently. However, remember the separation of concerns. The UI and Schema can be swapped out for another. When considering where to define the setting, always think about whether the Property Editor still works if the UI is swapped out.
+
+## Creating custom Property Editors
+
+When creating a custom Property Editor, consider what needs to be implemented. As discussed, the architecture of the Property Editor is flexible with separation of concerns. For a custom Property Editor, you need to decide what to implement yourself and what to reuse from existing components.
+
+If Umbraco already has a UI available that you can use, you do not have to implement the UI. In this case, you reuse a UI and implement a custom Schema for custom data handling. However, in most common scenarios, you will create a new Property Editor UI to work with. For more information about how to create a UI, see the [Property Editor UI](./property-editor-ui.md) article.
+
+When it comes to a Property Editor Schema, whether you need to create a custom Schema depends on your needs. Does your Property Editor require custom data validation and logic? Umbraco comes with a selection of default Property Editor Schemas that are suitable for many common scenarios. The article about the [Property Editor Schema](./property-editor-schema.md) provides more information about how to create a Schema. It also provides considerations on whether a custom Property Editor Schema is needed.
+
+## Advanced
+
+This chapter covers advanced scenarios. It is intended for developers who understand the basics of Property Editors and want to explore more sophisticated patterns.
+
+### Property Editor Data Sources
+
+A Property Editor Data Source is an optional way to provide data to a Property Editor UI. This allows for the reuse of the same Property Editor UI but with different data sources. This means that you can provide dynamic data to a Property Editor UI without modifying the UI itself.
* [Property Editor Data Source](property-editor-data-source.md)
diff --git a/17/umbraco-cms/customizing/property-editors/composition/images/creating-textbox-datatype-example.jpg b/17/umbraco-cms/customizing/property-editors/composition/images/creating-textbox-datatype-example.jpg
new file mode 100644
index 00000000000..54fb5a56ea0
Binary files /dev/null and b/17/umbraco-cms/customizing/property-editors/composition/images/creating-textbox-datatype-example.jpg differ
diff --git a/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-schema-alias-in-backoffice.jpg b/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-schema-alias-in-backoffice.jpg
new file mode 100644
index 00000000000..865f86e049a
Binary files /dev/null and b/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-schema-alias-in-backoffice.jpg differ
diff --git a/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-schema-backend.jpg b/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-schema-backend.jpg
new file mode 100644
index 00000000000..4fbe5c313f5
Binary files /dev/null and b/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-schema-backend.jpg differ
diff --git a/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-simplified-flow.jpg b/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-simplified-flow.jpg
new file mode 100644
index 00000000000..e834d6d961b
Binary files /dev/null and b/17/umbraco-cms/customizing/property-editors/composition/images/property-editor-simplified-flow.jpg differ
diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md
index 2b0d2728eda..b928b219a42 100644
--- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md
+++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-schema.md
@@ -3,23 +3,176 @@ description: The Server side part of a Property Editor
---
# Property Editor Schema
+A Property Editor Schema is the data part of a Property Editor in Umbraco. It defines what type of data can be stored (string, number, date, JSON, etc.) and how that data should be validated. It can also perform conversions of the data going in or coming out of the database.
+
+The schema's `settings` define what configuration options are available for the Property Editor (like maximum characters, allowed file types, etc.). When you create a Data Type, you provide values for these settings. Those configured values are then passed to both the server-side validation and the Property Editor UI.
{% hint style="warning" %}
-This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
+You can define settings on both the Property Editor Schema and the Property Editor UI. It's good practice to define settings that have impact on the data (like validation rules) on the Property Editor Schema. Settings that only impact the UI should be set on the Property Editor UI.
+ {% endhint %}
+
+For details on the settings structure, see the [Property Editor Schema Extension Type](../../extending-overview/extension-types/property-editor-schema.md) documentation.
+
+In essence, the Property Editor Schema defines the data contract for a Property Editor.
+
+{% hint style="info" %}
+When you want to use a Property Editor to edit content in Umbraco, the Property Editor needs to have a schema. If it does not have a schema, you cannot select the Property Editor when creating a [Data Type](../../../fundamentals/data/data-types/). In other scenarios - when using a Property Editor to edit Data Type settings for instance - a schema is not required.
{% endhint %}
-The Property Editor Schema is server code, written in C#. This handles the storage of a Property Editor and defines _Server Side Validation_ and _Property Value Converters_.
+The Property Editor Schema runs server-side (in C# code) and has the final authority on whether data is valid to commit to the database. The Property Editor UI is where the user inputs their data. You can have client-side validation, but the Property Editor Schema always makes the ultimate decision. When there is a mismatch between client-side and server-side validation, the server rejects data that the client considers valid.
+
+Because the Property Editor Schema defines how to process and validate data, you can have multiple Property Editor UIs using the same schema. As long as they work with the data as defined in the schema, this works. It also makes it possible to swap out the UI while maintaining the same data.
+
+You can see the used schema of a Property Editor in the backoffice of Umbraco when you create a new [Data Type](../../../fundamentals/data/data-types/).
+
+
+
+## A custom schema or not?
+Umbraco ships with a number of [default property editor schemas](../../../tutorials/creating-a-property-editor/default-property-editor-schema-aliases) that cover most scenarios that are less demanding. Although each situation is different, if you answer yes to any of the following statements, it makes sense to create a custom schema:
+
+* You expect the schema to be used by multiple Property Editor UIs.
+* You need a custom [Property Value Converter](../property-value-converters.md) because you need to convert the data going into the cache or you want the Umbraco ModelsBuilder to have a more specific strongly-typed model.
+* You need specific server-side validation of your data that is not covered in the default schemas.
+* You have specific needs for converting data going into or coming out of the database that are not covered in the default schemas.
+* You want to be flexible and prepared for future development.
+
+Otherwise the default schemas are probably fine.
+
+## Property Editor Schema anatomy
+A Property Editor Schema consists of two server side and one optional client side component. This chapter explains these components and how they are related.
+
+The server side components are:
+* `DataEditor`: serves as the definition and factory.
+* `DataValueEditor`: performs the actual data handling work.
+
+The client side component is:
+* `Property Editor Schema extension`: the registration of the schema in the Extension Registry for use by the frontend.
+
+This components are related in the following way:
-### Property Editor Schema
+
-The Property Editor Schema settings are used for configuration that the server needs to know about.
+{% hint style="info" %}
-**Manifest**
+For a complete example, there is a tutorial for creating a Property Editor. It shows how to [implement a schema to add server-side validation](../../../tutorials/creating-a-property-editor/adding-server-side-validation.md). Use this article together with that tutorial.
+
+{% endhint %}
+
+### DataEditor
+The `DataEditor` is the C# class that implements the Property Editor Schema on the server side. It serves as the blueprint that defines how a Property Editor should work. The `DataEditor` defines the schema's unique alias, the type of data stored in the database, and the default configuration settings. There is only one `DataEditor` instance per Property Editor Schema.
+
+A class becomes a Data Editor by inheriting the `DataEditor` class and adding the `DataEditor` attribute:
+```csharp
+[DataEditor("My.DataEditor.Suggestions")]
+public class MySuggestionsDataEditor : DataEditor
+```
+Notice the string `My.DataEditor.Suggestions`. This is the alias of the Property Editor Schema and is the only connection between the frontend and backend.
+
+The `DataEditor` attribute has additional optional parameters:
+```csharp
+[DataEditor("My.DataEditor.Suggestions", ValueType = ValueTypes.String, ValueEditorIsReusable = true)]
+public class MySuggestionsDataEditor : DataEditor
+```
+* `ValueType`: Defines how the data is stored in the database. The default is `String`. Other options are: `Integer`, `Decimal`, `DateTime`, `Date`, `Time`, `Text`, and `Json`.
+* `ValueEditorIsReusable`: Defines if the `DataValueEditor` instance is cached and reused as a singleton or created fresh each time. For most custom Property Editors, the default `true` value is best for performance. Set this to `false` if your editor:
+ * Maintains state between operations
+ * Has complex configuration that varies per Data Type
+ * Is a block-based editor or similar complex scenario
+
+See the [full tutorial](../../../tutorials/creating-a-property-editor/adding-server-side-validation.md) on how to implement the DataEditor.
+
+### DataValueEditor
+The `DataValueEditor` is the workhorse that handles all data operations for the Property Editor Schema. When property values need saving or loading, the `DataEditor` creates a `DataValueEditor` instance to do the actual work. This instance converts data between what the editor displays and what gets stored in the database. It also runs server-side validation to ensure data integrity and handles any necessary data transformations.
+
+The `DataEditor` creates `DataValueEditor` instances through its `CreateValueEditor()` method. Each instance is configured with specific settings from the [Data Type](../../../fundamentals/data/data-types/). For example, a textbox Property Editor might have one Data Type configured for short text and another for long text. Both use the same `DataEditor` (the blueprint), but each creates `DataValueEditor` instances with different maximum length settings.
+
+A class becomes a Data Value Editor by inheriting the `DataValueEditor` class:
+
+```csharp
+public class MySuggestionsDataValueEditor : DataValueEditor
+{
+ public MySuggestionsDataValueEditor(
+ IShortStringHelper shortStringHelper,
+ IJsonSerializer jsonSerializer,
+ IIOHelper ioHelper,
+ DataEditorAttribute attribute)
+ : base(shortStringHelper, jsonSerializer, ioHelper, attribute)
+ => Validators.Add(new MySuggestionsValueValidator());
+}
+```
+Data Value Editors can have one or more validators. These validators check if the data complies with any settings that the Property Editor might have.
+
+See the [full tutorial](../../../tutorials/creating-a-property-editor/adding-server-side-validation.md) on how to implement the `DataValueEditor`.
+
+### Register the schema client-side
+Before the Property Editor UI can use the schema, it needs to be registered in the Extension Registry using a manifest. This covers only the basics. For the complete manifest reference including configuration settings, see the [Property Editor Schema Extension Type](../../extending-overview/extension-types/property-editor-schema.md) documentation.
+
+{% hint style="info" %}
+If the Property Editor has no settings, it is technically not required to register the schema in the Extension Registry. The Property Editor UI can reference the alias as defined in the `DataEditor` and that will work. However, to show intent and make the schema more visible for frontend developers, it is recommended to register the schema anyway. This also provides a fallback for which Property Editor UI to use in case that cannot be determined.
+{% endhint %}
+
+At minimum, the schema manifest must specify the type, alias, name, and which Property Editor UI should be used by default:
```json
{
"type": "propertyEditorSchema",
"name": "Text Box",
"alias": "Umbraco.TextBox",
-};
+ "meta": {
+ "defaultPropertyEditorUiAlias": "Umb.PropertyEditorUi.TextBox"
+ }
+}
+```
+
+{% hint style="warning" %}
+The `alias` in the manifest must exactly match the alias used in the C# `DataEditor` attribute. This alias string is the only connection between the server-side implementation and the client-side manifest.
+{% endhint %}
+
+If the schema alias is referenced but not properly registered, the backoffice will display a "Missing Property Editor" error state.
+
+The Property Editor Schema is now complete and ready to be used.
+
+## Advanced
+{% hint style="info" %}
+This chapter covers advanced scenarios in Property Editor Schema development. It is intended for developers who understand the basic `DataEditor` and `DataValueEditor` concepts and want to explore more sophisticated patterns.
+{% endhint %}
+
+### Custom Data Editors without a Data Value Editor
+Usually when you create a custom Data Editor Schema, you implement both the Data Editor and the Data Value Editor. If you do not need custom validation or data manipulation, you can use one of the [default property editor schemas](../../../tutorials/creating-a-property-editor/default-property-editor-schema-aliases) instead. In most cases, you do not need to create a Property Editor Schema at all.
+
+However, it is possible to create a custom Data Editor but let the handling of the data be handled by the `DataValueEditor` base class itself. On a Data Editor, you can specify the `ValueType`. This is the type that determines how the data is stored in the database. The `DataValueEditor` can process the data based on the `ValueType`. This means you can create a Data Editor without implementing a custom Data Value Editor.
+
+This pattern is valuable when you need a unique schema identifier. You might use this for targeting in Property Value Converters or custom indexing. However, you do not need custom validation or data conversion.
+
+This example creates a custom `DataEditor` that reuses the standard JSON `DataValueEditor`:
+
+{% code title="ProductConfigurationDataEditor.cs" %}
+
+```csharp
+[DataEditor("MyCompany.ProductConfiguration", ValueType = ValueTypes.Json]
+public class ProductConfigurationDataEditor : DataEditor
+{
+ public ProductConfigurationDataEditor(IDataValueEditorFactory dataValueEditorFactory)
+ : base(dataValueEditorFactory)
+ {
+ }
+
+ // Do not override CreateValueEditor()
+ // This uses the base DataValueEditor with ValueType.Json as the type
+}
+```
+{% endcode %}
+
+Now you can target this specific schema in your Property Value Converter:
+
+{% code title="ProductConfigurationValueConverter.cs" %}
+```csharp
+public class ProductConfigurationValueConverter : PropertyValueConverterBase
+{
+ public override bool IsConverter(IPublishedPropertyType propertyType)
+ => propertyType.EditorAlias == "MyCompany.ProductConfiguration";
+
+ ...
+}
```
+{% endcode %}
\ No newline at end of file
diff --git a/17/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md b/17/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md
index b0b3c5c6624..98ba580c542 100644
--- a/17/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md
+++ b/17/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md
@@ -3,141 +3,315 @@ description: Presenting the Editing Experience of a Property Editor
---
# Property Editor UI
+The Property Editor UI is the client-side component that renders the editing interface in the Umbraco backoffice. It provides the visual interface for content editors to interact with their data. The Property Editor Schema validates and stores data on the server. The Property Editor UI focuses on providing an intuitive editing experience in the browser.
-{% hint style="warning" %}
-This page is a work in progress and may undergo further revisions, updates, or amendments. The information contained herein is subject to change without notice.
-{% endhint %}
-The Property Editor UI is the UI that is used to edit the data in the backoffice.
+## Creating a Property Editor UI
+A Property Editor UI is a purely frontend extension in the shape of a web component. In this example, we will create a Property Editor UI using an Umbraco Lit element step by step. At the end, the full example is provided. To create a Property Editor UI, the following needs to be done:
-The Property Editor UI is a pure front-end extension. This determines how the data of a Property Editor is presented and manipulated. The Extension points to a Web Component.
+* Implement the Umbraco Lit component - the actual visible part
+* Register the Property Editor UI using a manifest
-### Property Editor UI
+### Implement the interface
+What makes a standard Umbraco Lit component a Property Editor UI is the implementation of the `UmbPropertyEditorUiElement` interface. The `UmbPropertyEditorUiElement` interface ensures that your element has the necessary properties and methods to be used as a Property Editor UI element. See the [UI API documentation](https://apidocs.umbraco.com/v17/ui-api/interfaces/packages_core_property-editor.UmbPropertyEditorUiElement.html) for the full interface definition.
-{% code title="umbraco-package.json" %}
-```json
-{
- "type": "propertyEditorUi",
- "alias": "Umb.PropertyEditorUi.TextBox",
- "name": "Text Box Property Editor UI",
- "element": "/App_Plugins/my-text-box/dist/my-text-box.js",
- "elementName": "my-text-box",
- "meta": {
- "label": "My Text Box",
- "propertyEditorSchemaAlias": "Umbraco.TextBox",
- "icon": "icon-autofill",
- "group": "common"
- }
+```typescript
+import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
+import type { UmbPropertyEditorUiElement } from '@umbraco-cms/backoffice/property-editor';
+
+// Implement the UmbPropertyEditorUiElement
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ ...
}
```
-{% endcode %}
-The Property Editor UI cannot be used for Content Types if no Property Editor Schema is specified in the manifest. However, it can still be utilized to manipulate JSON. A case of that could be a Settings property for another Property Editor UI or Schema.
+This interface gives access to important information about the data and configuration through a number of properties. None of them are technically required to implement, but in practice you need `value` and probably also `config`.
-### Settings
-
-The Property Editor UI settings are used for configuration related to rendering the UI in the backoffice. This is the same for Property Editor Schemas:
+* `value`: Contains the actual value that will be processed and stored when the content is saved and retrieved. The value is automatically populated when the component loads. When saved, the value is sent to be processed and saved to the database.
+* `config`: The configuration as set on the Data Type.
+* `readonly`: If you support read-only mode, this will indicate whether the component should be read-only.
{% hint style="info" %}
-The Property Editor UI inherits the Settings of its Property Editor Schema.
+For the full interface properties of the `UmbPropertyEditorUiElement`, see the [UI API documentation](https://apidocs.umbraco.com/v17/ui-api/interfaces/packages_core_property-editor.UmbPropertyEditorUiElement.html) for more information.
{% endhint %}
-**Manifest**
+A minimal implementation where the value is read and placed in a textbox looks like this:
-{% code title="umbraco-package.json" %}
-```json
-{
- "type": "propertyEditorUi",
- "alias": "My.PropertyEditorUI.TextArea",
- //... more
- "meta": {
- //... more
- "settings": {
- "properties": [
- {
- "alias": "rows",
- "label": "Number of rows",
- "description": "If empty - 10 rows would be set as the default value",
- "propertyEditorUiAlias": "Umb.PropertyEditorUi.Integer",
- },
- ],
- "defaultData": [
- {
- "alias": "rows",
- "value": 10,
- },
- ],
- },
- },
-};
-```
-{% endcode %}
+```typescript
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ /* Represents the value of the content */
+ @property()
+ value?: string;
-## The Property Editor UI Element
+ /* this.value will automatically get set and display in the textbox */
+ override render() {
+ return html``;
+ }
+}
+```
-Implement the `UmbPropertyEditorUiElement` interface, to secure your Element live up to the requirements of this.
+### Handle value changes
+In the previous example, the value is read and placed in a text box. However, it will not react to changes in the value. When the value needs to be changed, it is required to dispatch an `UmbChangeEvent`.
```typescript
-interface UmbPropertyEditorUiElement extends HTMLElement {
- name?: string;
- value?: unknown;
- config?: UmbPropertyEditorConfigCollection;
- mandatory?: boolean;
- mandatoryMessage?: string;
- destroy?: () => void;
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ /* Represents the value of the content */
+ @property()
+ value?: string;
+
+ /* Fires when the text of the text box changes */
+ #onInput(e: InputEvent) {
+ // Get the value from the text box and set it to the value property
+ this.value = (e.target as HTMLInputElement).value;
+
+ // Dispatch event that the value has changed
+ this.dispatchEvent(new UmbChangeEvent());
+ }
+
+ /* this.value will automatically get set and display in the text box */
+ override render() {
+ return html``;
+ }
}
```
-{% hint style="info" %}
-The `UmbPropertyEditorUiElement` interface ensures that your Element has the necessary properties and methods to be used as a Property Editor UI Element.
+### Handle configuration
+As discussed before, both the Property Editor UI and the Property Editor Schema can have settings that are set when creating a Data Type. You can access these settings like this:
+
+```typescript
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ @property()
+ value?: string;
+
+ /* Property to store the 'maxLength' setting in */
+ @state()
+ private maxLength?: number;
-See the [UI API documentation](https://apidocs.umbraco.com/v15/ui-api/interfaces/packages_core_property-editor.UmbPropertyEditorUiElement.html) for more information.
+ /*
+ * When the config property is set (which happens automatically):
+ * Get the configuration value of the configuration with the alias 'maxLength'
+ * Store it in a property to make it easier to work with
+ */
+ @property({ attribute: false })
+ public set config(config: UmbPropertyEditorConfigCollection | undefined) {
+ if (!config) return;
+ this.maxLength = config.getValueByAlias("maxLength") ?? undefined;
+ }
+
+ /*
+ * When this.maxLength has a value, the max length is set on the text box
+ * This prevents the user from entering more characters
+ */
+ override render() {
+ return html``;
+ }
+}
+```
+{% hint style="warning" %}
+Setting the `maxlength` attribute is only used for client-side validation and to help editors adhere to data validation rules. This does not automatically trigger server-side validation on save. If you need server-side validation, the Property Editor Schema needs to explicitly implement this.
{% endhint %}
-**Example with LitElement**
+### Handle mandatory and validation
+When an editor is creating a Document Type in the backoffice and adds properties, properties can be marked as mandatory. There is also an option to add a custom validation message for that property.
+
+When a property is marked as mandatory, it will automatically perform validation when the content node with that property is saved. This validates whether the `value` property has a value or not. If not, the custom validation message is displayed.
+
+This validation is automatically handled by Umbraco. However, if it makes sense in the context of your Property Editor UI, you can access both the mandatory flag and the custom error message.
-{% code title="my-text-box.ts" lineNumbers="true" %}
```typescript
-import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
-import { css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ @property()
+ value?: string;
+
+ /*
+ * Automatically set by Umbraco when the property is marked as mandatory.
+ * Makes the field required for validation.
+ */
+ @property({ type: Boolean })
+ mandatory?: boolean;
+
+ /**
+ * Custom validation message when mandatory field is empty.
+ * Set in the Document Type property settings in the backoffice
+ * and is automatically populated.
+ */
+ @property({ type: String })
+ mandatoryMessage = UMB_VALIDATION_EMPTY_LOCALIZATION_KEY;
+
+ override render() {
+ return html``;
+ }
+}
+```
+This validation is only performed on the value of the property editor as a whole. When you have complex Property Editor UIs with multiple inputs and advanced validation, you need more advanced validation techniques. See the [UI Library Form Validation documentation](../../ui-library.md#form-validation) on how to implement advanced validation.
+
+### Handle readonly
+The `readonly` property indicates whether the Property Editor should be in read-only mode. This happens automatically based on:
+
+- User permissions - The current user does not have update permissions for this content
+- Content locks - Another user is currently editing the content
+- Workflow states - Content is in a state that prevents editing (for example, awaiting approval)
+- Variant restrictions - Editing a culture/segment variant without proper permissions
+
+By default, Umbraco places an overlay on the Property Editor if it needs to be read-only. In most cases, this is sufficient. However, you can also handle read-only mode in the Property Editor more gracefully.
+
+If you want to properly support read-only mode, the manifest should set the `supportsReadOnly` property to `true` and you need to handle read-only yourself. This means you need to ensure the editor cannot change any content in read-only mode.
+
+ ```typescript
+export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
+ @property()
+ value?: string;
+
+ /*
+ * Indicates if the Property Editor is in read-only mode
+ */
+ @property({ type: Boolean })
+ readonly?: boolean;
+
+ override render() {
+ return html``;
+ }
+}
+```
+
+### Full example
+This is a full example based on all the previous examples. This example Property Editor UI:
+* Reads and updates the value
+* Handles configuration
+* Handles mandatory and the mandatory message
+* Handles read-only mode
+
+```typescript
+import { html, customElement, property, state, ifDefined } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
-import type {
- UmbPropertyEditorConfigCollection,
- UmbPropertyEditorUiElement,
+import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
+import { UMB_VALIDATION_EMPTY_LOCALIZATION_KEY } from '@umbraco-cms/backoffice/validation';
+import type {
+ UmbPropertyEditorUiElement,
+ UmbPropertyEditorConfigCollection
} from '@umbraco-cms/backoffice/property-editor';
-import { UmbTextStyles } from '@umbraco-cms/backoffice/style';
+/**
+ * Property Editor UI for a text box with configurable max length
+ */
@customElement('umb-property-editor-ui-text-box')
-export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
- @property()
- value?: string;
+export default class UmbPropertyEditorUITextBoxElement
+ extends UmbLitElement
+ implements UmbPropertyEditorUiElement {
+
+ /**
+ * The current value of the property.
+ * Automatically set by Umbraco and updated when the user types.
+ */
+ @property()
+ value?: string;
- @property({ attribute: false })
- config?: UmbPropertyEditorConfigCollection;
+ /**
+ * Indicates if the property is required/mandatory.
+ * Automatically set by Umbraco based on Document Type property settings.
+ */
+ @property({ type: Boolean })
+ mandatory?: boolean;
- #onInput(e: InputEvent) {
- this.value = (e.target as HTMLInputElement).value;
- this.dispatchEvent(new UmbChangeEvent());
- }
+ /**
+ * Custom validation message when mandatory field is empty.
+ * Set in the Document Type property settings in the backoffice.
+ * Defaults to a localized "This field is required" message.
+ */
+ @property({ type: String })
+ mandatoryMessage = UMB_VALIDATION_EMPTY_LOCALIZATION_KEY;
- override render() {
- return html``;
- }
+ /**
+ * Indicates if the Property Editor is in read-only mode.
+ * Set automatically by Umbraco based on user permissions, content locks, etc.
+ * When true, the value can be read and selected but not modified.
+ */
+ @property({ type: Boolean })
+ readonly?: boolean;
+
+ /**
+ * Maximum allowed characters for the text input.
+ * Configured via the Data Type settings.
+ */
+ @state()
+ private maxLength?: number;
- static override readonly styles = [
- UmbTextStyles,
- css`
- uui-input {
- width: 100%;
- }
- `,
- ];
+ /**
+ * Configuration from the Data Type.
+ * Automatically set by Umbraco when the Property Editor is initialized.
+ * Extracts settings like maxLength for use in the UI.
+ */
+ @property({ attribute: false })
+ public set config(config: UmbPropertyEditorConfigCollection | undefined) {
+ if (!config) return;
+ this.maxLength = config.getValueByAlias("maxLength") ?? undefined;
+ }
+
+ /**
+ * Handles input events from the text box.
+ * Updates the value and notifies Umbraco of the change.
+ */
+ #onInput(e: InputEvent) {
+ const newValue = (e.target as HTMLInputElement).value;
+ if (newValue === this.value) return;
+
+ // Update the value
+ this.value = newValue;
+
+ // Notify Umbraco that the value has changed
+ this.dispatchEvent(new UmbChangeEvent());
+ }
+
+ /**
+ * Renders the text input with all configured properties
+ */
+ override render() {
+ return html``;
+ }
}
declare global {
- interface HTMLElementTagNameMap {
- 'umb-property-editor-ui-text-box': UmbPropertyEditorUITextBoxElement;
- }
+ interface HTMLElementTagNameMap {
+ 'umb-property-editor-ui-text-box': UmbPropertyEditorUITextBoxElement;
+ }
+}
+```
+## Register the Property Editor UI
+To make your Property Editor UI available in Umbraco, you need to register it using a manifest. The manifest defines the alias, element location, and metadata like the label, icon, and which schema it works with.
+
+For details on the manifest structure and all available options, see the [Property Editor UI Extension Type](../../extending-overview/extension-types/property-editor-ui.md) documentation.
+
+### Basic example
+{% code title="umbraco-package.json" %}
+```json
+{
+ "type": "propertyEditorUi",
+ "alias": "My.PropertyEditorUI.TextBox",
+ "name": "My Text Box Property Editor UI",
+ "element": "/App_Plugins/my-text-box/dist/my-text-box.js",
+ "meta": {
+ "label": "My Text Box",
+ "propertyEditorSchemaAlias": "Umbraco.TextBox",
+ "icon": "icon-autofill",
+ "group": "common"
+ }
}
```
-{% endcode %}
+{% endcode %}
\ No newline at end of file