Skip to content
Merged
Show file tree
Hide file tree
Changes from 8 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ The manifest can also be written in TypeScript.
For this TypeScript example we used a [Backoffice Entry Point](../../extending-overview/extension-types/backoffice-entry-point.md) extension to register the manifests.

```typescript
import { ManifestMenu } from "@umbraco-cms/backoffice/extension-registry";
import type { ManifestMenu } from "@umbraco-cms/backoffice/menu";

const menuManifest: Array<ManifestMenu> = [
{
Expand All @@ -55,7 +55,7 @@ const menuManifest: Array<ManifestMenu> = [

<figure><img src="../../../.gitbook/assets/menu-item.png" alt="" width="250"><figcaption><p>Menu Item</p></figcaption></figure>

Menu items are the items that appear in the menu.
Menu items are the items that appear in the menu.

## Creating a custom menu items

Expand Down Expand Up @@ -139,10 +139,9 @@ You can fetch the data and render the menu items using the Lit element above. By

{% code title="menu-items.ts" overflow="wrap" lineNumbers="true" %}
```typescript
import { UmbMenuItemElement } from '@umbraco-cms/backoffice/extension-registry';
import type { UmbMenuItemElement } from '@umbraco-cms/backoffice/menu';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { html, TemplateResult } from 'lit';
import { customElement, state } from 'lit/decorators.js';
import { html, TemplateResult, customElement, state } from '@umbraco-cms/backoffice/external/lit';
import { MyMenuItemResponseModel, MyMenuResource } from '../../../api';

const elementName = 'my-menu-item';
Expand All @@ -151,13 +150,14 @@ const elementName = 'my-menu-item';
class MyMenuItems extends UmbLitElement implements UmbMenuItemElement {
@state()
private _items: MyMenuItemResponseModel[] = []; // Store fetched items

@state()
private _loading: boolean = true; // Track loading state

@state()
private _error: string | null = null; // Track any errors

constructor() {
super();
override firstUpdated() {
this.fetchInitialItems(); // Start fetching on component load
}

Expand All @@ -178,8 +178,8 @@ class MyMenuItems extends UmbLitElement implements UmbMenuItemElement {
return html`
${items.map(element => html`
<uui-menu-item label="${element.name}" ?has-children=${element.hasChildren}>
${element.type === 1
? html`<uui-icon slot="icon" name="icon-folder"></uui-icon>`
${element.type === 1
? html`<uui-icon slot="icon" name="icon-folder"></uui-icon>`
: html`<uui-icon slot="icon" name="icon-autofill"></uui-icon>`}
<!-- recursively render children -->
${element.hasChildren ? this.renderItems(element.children) : ''}
Expand All @@ -189,7 +189,7 @@ class MyMenuItems extends UmbLitElement implements UmbMenuItemElement {
}

// Main render function
render() {
override render() {
if (this._loading) {
return html`<uui-loader></uui-loader>`;
}
Expand All @@ -200,7 +200,7 @@ class MyMenuItems extends UmbLitElement implements UmbMenuItemElement {
}

// Render items if loading is done and no error occurred
return html`${this.renderItems(this._items)}`;
return this.renderItems(this._items);
}
}

Expand All @@ -212,15 +212,15 @@ declare global {
}
}

```
```
{% endcode %}


## Tree Menu Item

### Manifest

```typescript
```json
// it will be something like this
{
"type": "menuItem",
Expand All @@ -236,9 +236,10 @@ declare global {

#### Default Element

The default element supports rendering a subtree of menu items.

```typescript
// get interface
interface UmbTreeMenuItemElement {}
class UmbMenuItemTreeDefaultElement {}
```

### Adding menu items to an existing menu
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,8 @@ Additionally, the modal element can see its data parameters through the `modalCo
```ts
import { html, LitElement, property, customElement } from "@umbraco-cms/backoffice/external/lit";
import { UmbElementMixin } from "@umbraco-cms/backoffice/element-api";
import type { UmbModalContext } from "@umbraco-cms/backoffice/modal";
import { type UmbModalContext, UmbModalExtensionElement } from "@umbraco-cms/backoffice/modal";
import type { MyModalData, MyModalValue } from "./my-modal.token.ts";
import { UmbModalExtensionElement } from "@umbraco-cms/backoffice/extension-registry";

@customElement('my-dialog')
export default class MyDialogElement
Expand Down Expand Up @@ -109,8 +108,7 @@ To open the modal, you need to consume the `UmbModalManagerContext` and then use
import { MY_MODAL_TOKEN } from './my-modal.token';
import { UMB_MODAL_MANAGER_CONTEXT } from '@umbraco-cms/backoffice/modal';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
import { LitElement, html } from 'lit';
import { customElement } from 'lit/decorators.js';
import { LitElement, html, customElement } from '@umbraco-cms/backoffice/external/lit';

@customElement('my-element')
class MyElement extends UmbElementMixin(LitElement) {
Expand All @@ -124,7 +122,7 @@ class MyElement extends UmbElementMixin(LitElement) {
});
}

render() {
override render() {
return html`
<uui-button look="primary" label="Open modal" @click=${this._openModal}></uui-button>
`;
Expand All @@ -138,5 +136,11 @@ class MyElement extends UmbElementMixin(LitElement) {
});
}
}

declare global {
interface HTMLElementTagNameMap {
'my-element': MyElement;
}
}
```
{% endcode %}
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ The manifest can also be written in TypeScript.
For this TypeScript example we used a [Backoffice Entry Point](../backoffice-entry-point.md) extension to register the manifests.

```typescript
import { ManifestSectionView } from "@umbraco-cms/backoffice/extension-registry";
import { ManifestSectionView } from "@umbraco-cms/backoffice/section";

const sectionViews: Array<ManifestSectionView> = [
{
Expand Down Expand Up @@ -89,15 +89,15 @@ import { css, html, customElement, property } from '@umbraco-cms/backoffice/exte
@customElement('my-sectionview-element')
export class MySectionViewElement extends UmbLitElement {

render() {
override render() {
return html`
<uui-box headline="Sectionview Title goes here">
Sectionview content goes here
</uui-box>
`
}

static override styles = [
static override readonly styles = [
css`
:host {
display: block;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@

### Property Editor UI

{% code title="umbraco-package.json" %}

Check warning on line 17 in 15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [UmbracoDocs.UmbracoTerms] We prefer 'Umbraco' over 'umbraco.' Raw Output: {"message": "[UmbracoDocs.UmbracoTerms] We prefer 'Umbraco' over 'umbraco.'", "location": {"path": "15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md", "range": {"start": {"line": 17, "column": 16}}}, "severity": "WARNING"}
```json
{
"type": "propertyEditorUi",
Expand All @@ -29,6 +30,7 @@
}
}
```
{% 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.

Expand All @@ -42,6 +44,7 @@

**Manifest**

{% code title="umbraco-package.json" %}

Check warning on line 47 in 15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [UmbracoDocs.UmbracoTerms] We prefer 'Umbraco' over 'umbraco.' Raw Output: {"message": "[UmbracoDocs.UmbracoTerms] We prefer 'Umbraco' over 'umbraco.'", "location": {"path": "15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md", "range": {"start": {"line": 47, "column": 16}}}, "severity": "WARNING"}
```json
{
"type": "propertyEditorUi",
Expand All @@ -68,47 +71,71 @@
},
};
```
{% endcode %}

## The Property Editor UI Element

Inherit the interface, to secure your Element live up to the requirements of this.
Implement the `UmbPropertyEditorUiElement` interface, to secure your Element live up to the requirements of this.

```typescript
// TODO: get interface
interface UmbPropertyEditorUIElement {}
interface UmbPropertyEditorUiElement extends HTMLElement {
name?: string;
value?: unknown;
config?: UmbPropertyEditorConfigCollection;
mandatory?: boolean;
mandatoryMessage?: string;
destroy?: () => void;
}
```

{% hint style="info" %}

Check warning on line 91 in 15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [UmbracoDocs.SentenceLength] Write shorter sentences (less than 25 words). Raw Output: {"message": "[UmbracoDocs.SentenceLength] Write shorter sentences (less than 25 words).", "location": {"path": "15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md", "range": {"start": {"line": 91, "column": 4}}}, "severity": "WARNING"}
The `UmbPropertyEditorUiElement` interface is a TypeScript interface that ensures that your Element has the necessary properties and methods to be used as a Property Editor UI Element. See the [UI API Docs](https://apidocs.umbraco.com/v15/ui-api/interfaces/packages_core_property-editor.UmbPropertyEditorUiElement.html) for more information.

Check warning on line 92 in 15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md

View workflow job for this annotation

GitHub Actions / runner / vale

[vale] reported by reviewdog 🐶 [UmbracoDocs.Terms] We prefer 'documentation' over 'Docs.' Raw Output: {"message": "[UmbracoDocs.Terms] We prefer 'documentation' over 'Docs.'", "location": {"path": "15/umbraco-cms/customizing/property-editors/composition/property-editor-ui.md", "range": {"start": {"line": 92, "column": 202}}}, "severity": "WARNING"}
{% endhint %}

**Example with LitElement**

{% code title="my-text-box.ts" lineNumbers="true" %}
```typescript
import { LitElement, html, css, customElement, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbElementMixin } from '@umbraco-cms/backoffice/element-api';
import { UmbPropertyValueChangeEvent } from '@umbraco-cms/backoffice/property-editor';

@customElement('my-text-box')
export default class UmbPropertyEditorUITextBoxElement extends UmbElementMixin(LitElement) {

@property()
value: string | undefined;

@property({ attribute: false })
public config: UmbPropertyEditorConfigCollection | undefined;

private onInput(e: InputEvent) {
this.value = (e.target as HTMLInputElement).value;
this.dispatchEvent(new UmbPropertyValueChangeEvent());
}
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import type {
UmbPropertyEditorConfigCollection,
UmbPropertyEditorUiElement,
} from '@umbraco-cms/backoffice/property-editor';
import { UmbTextStyles } from '@umbraco-cms/backoffice/style';

@customElement('umb-property-editor-ui-text-box')
export default class UmbPropertyEditorUITextBoxElement extends UmbLitElement implements UmbPropertyEditorUiElement {
@property()
value?: string;

@property({ attribute: false })
config?: UmbPropertyEditorConfigCollection;

#onInput(e: InputEvent) {
this.value = (e.target as HTMLInputElement).value;
this.dispatchEvent(new UmbChangeEvent());
}

override render() {
return html`<uui-input .value=${this.value ?? ''} type="text" @input=${this.#onInput}></uui-input>`;
}

static override readonly styles = [
UmbTextStyles,
css`
uui-input {
width: 100%;
}
`,
];
}

render() {
return html`<uui-input .value=${this.value} type="text" @input=${this.onInput}></uui-input>`;
}

static styles = [
css`
uui-input {
width: 100%;
}
`,
];
declare global {
interface HTMLElementTagNameMap {
'umb-property-editor-ui-text-box': UmbPropertyEditorUITextBoxElement;
}
}
```
{% endcode %}
Original file line number Diff line number Diff line change
Expand Up @@ -99,15 +99,15 @@ Now let's create the web component we need for our property editor. This web com
1. Create a file in the `src` folder with the name `welcome-dashboard.element.ts`
2. In this new file, add the following code:

{% code title="welcome-dashboard.element.ts" lineNumbers="true" %}
{% code title="welcome-dashboard.element.ts" lineNumbers="true" overflow="wrap" %}
```typescript
import { LitElement, css, html, customElement } from "@umbraco-cms/backoffice/external/lit";
import { UmbLitElement } from "@umbraco-cms/backoffice/lit-element";

@customElement('my-welcome-dashboard')
export class MyWelcomeDashboardElement extends UmbLitElement {

render() {
override render() {
return html`
<h1>Welcome Dashboard</h1>
<div>
Expand All @@ -120,7 +120,7 @@ export class MyWelcomeDashboardElement extends UmbLitElement {
`;
}

static styles = [
static override readonly styles = [
css`
:host {
display: block;
Expand Down
Loading
Loading