This guide explains how to set up a property editor and hook it into Umbraco's Data Types. It also covers the creation of a basic property editor and how we can test our property editor.
At the tutorial's end, we'll have a Umbraco Suggestions Data Type, registered in the backoffice, and assigned to a Document Type. This Data Type can create and suggest values.
At each step, you will find a dropdown for suggestions-property-editor-ui.element.ts and umbraco-package.json to confirm your placement for code snippets.
Setting up a plugin
Follow the Vite Package Setup by creating a new project folder called "suggestions" in App_Plugins.
Then create the manifest file named umbraco-package.json at the root of the suggestions folder. Here we define and configure our dashboard.
The umbraco-package.json files are cached by the server. When creating new umbraco-package.json files, it might take a few seconds before those are loaded into the server cache.
It is important to select the right propertyEditorSchemaAlias as it affects how the Property Editor data is made available when rendering the website.
In this example, we selected the Umbraco.Plain.String because we want a string value. For more options, see the default Property Editor Schema aliases article.
Creating a Web Component
Now let's create the web component we need for our property editor.
Create a file in the src folder with the name suggestions-property-editor-ui.element.ts
In this new file, add the following code:
suggestions-property-editor-ui.element.ts
import { LitElement, html, customElement, property } from"@umbraco-cms/backoffice/external/lit";import { UmbPropertyEditorUiElement } from"@umbraco-cms/backoffice/extension-registry";@customElement('my-suggestions-property-editor-ui')exportdefaultclassMySuggestionsPropertyEditorUIElementextendsLitElementimplementsUmbPropertyEditorUiElement { @property({ type: String })public value ="";render() {returnhtml`I'm a property editor!`; }}declare global {interfaceHTMLElementTagNameMap {'my-suggestions-property-editor-ui':MySuggestionsPropertyEditorUIElement; }}
In the vite.config.ts file replace the entry to our newly created .ts file:
It's starting to look good! Next, let's look into setting up the event logic.
Setup Event Logic
Setup Input Field
Let's start with the input field. When we type something in the input field, we want the property editor's value to change to the input field's current value.
We then have to dispatch an property-value-change event which can be done in two ways:
Using new CustomEvent('property-value-change') or
Using new UmbPropertyValueChangeEvent() which is recommended as you can leverage the core class
When we press the suggestion button we want the text to update to the suggestion that we get. Similar to how the value of our property editor changes when we write in the input field.
We also want the value to change when we press the suggestion button.
Update the import for Lit:
suggestions-property-editor-ui.element.ts
import { LitElement, html, css, customElement, property, state } from"@umbraco-cms/backoffice/external/lit";
Add suggestions to the property editor:
suggestions-property-editor-ui.element.ts
@state() private _suggestions = ['You should take a break','I suggest that you visit the Eiffel Tower','How about starting a book club today or this week?','Are you hungry?', ];render() {...}
Update the suggestion button in the render method to call a onSuggestion method when we press the button:
suggestions-property-editor-ui.element.ts
#onSuggestion() {constrandomIndex= (this._suggestions.length*Math.random()) |0;this.value =this._suggestions[randomIndex];this.#dispatchChangeEvent(); }render() {returnhtml` ... <uui-button id="suggestion-button" class="element" look="primary" label="give me suggestions" @click=${this.#onSuggestion} > Give me suggestions! </uui-button> ... `; }
See the entire file: suggestions-property-editor-ui.element.ts
suggestions-property-editor-ui.element.ts
import { LitElement, css, html, customElement, property, state } from"@umbraco-cms/backoffice/external/lit";import { UmbPropertyEditorUiElement } from"@umbraco-cms/backoffice/extension-registry";import { UmbPropertyValueChangeEvent } from'@umbraco-cms/backoffice/property-editor';@customElement('my-suggestions-property-editor-ui')exportdefaultclassMySuggestionsPropertyEditorUIElementextendsLitElementimplementsUmbPropertyEditorUiElement { @property({ type: String })public value =""; @state()private _suggestions = ["You should take a break","I suggest that you visit the Eiffel Tower","How about starting a book club today or this week?","Are you hungry?", ]; #onInput(e:InputEvent) {this.value = (e.target asHTMLInputElement).value;this.#dispatchChangeEvent(); } #onSuggestion() {constrandomIndex= (this._suggestions.length*Math.random()) |0;this.value =this._suggestions[randomIndex];this.#dispatchChangeEvent(); } #dispatchChangeEvent() {this.dispatchEvent(newUmbPropertyValueChangeEvent()); }render() {returnhtml` <uui-input id="suggestion-input" class="element" label="text input" .value=${this.value ||""} @input=${this.#onInput} > </uui-input> <div id="wrapper"> <uui-button id="suggestion-button" class="element" look="primary" label="give me suggestions" @click=${this.#onSuggestion} > Give me suggestions! </uui-button> <uui-button id="suggestion-trimmer" class="element" look="outline" label="Trim text" > Trim text </uui-button> </div> `; }static styles = [css` #wrapper { margin-top: 10px; display: flex; gap: 10px; } .element { width: 100%; } `, ];}declare global {interfaceHTMLElementTagNameMap {'my-suggestions-property-editor-ui':MySuggestionsPropertyEditorUIElement; }}
Clear your cache, reload the document, and see the Suggestions Data Type running.
When we save or publish, the value of the Data Type is now automatically synced to the current content object and sent to the server.