import { Meta } from '@storybook/addon-docs';

<Meta
	title="Guides/Extending the Backoffice/Property Editors"
	parameters={{ previewTabs: { canvas: { hidden: true } } }}
/>

# Property Editors

// TODO: add description
(rough notes. We have a lot on docs.umbraco.com we can use)

- This section describes how to work with and create Property Editors. A property editor is the editor used to insert content into Umbraco.
- A whole Property Editor is defined by two parts.
- The Property Editor and the Property Editor UI.
- The Property Editor UI is the UI that is used to edit the data in the backoffice.
- 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.
- The Property Editor Schema settings is used for configuration that the server needs to know about.
- The Property Editor UI settings is used for configuration that is related to rendering the UI in the backoffice.
- Both will be available for the Property Editor UI to use.

## Property Editor Schema

**Manifest**

```json
{
	"type": "propertyEditorSchema",
	"name": "Text Box",
	"alias": "Umbraco.TextBox",
};
```

## Property Editor UI

```json
{
	"type": "propertyEditorUi",
	"alias": "Umb.PropertyEditorUi.TextBox",
	"name": "Text Box Property Editor UI",
	"elementName": "my-text-box",
	"js": "./my-text-box.element.js",
	"meta": {
		"label": "My Text Box",
		"propertyEditorSchema": "Umbraco.TextBox",
		"icon": "umb:autofill",
		"group": "common"
	}
}
```

If no Property Editor Schema is specified in the manifest, the Propety Editor UI will use a generic JSON Property Editor Model

## Configuration

// TODO: add description

- 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.

**Manifest**

```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",
					"propertyEditorUi": "Umb.PropertyEditorUi.Number",
				},
			],
			"defaultData": [
				{
					"alias": "rows",
					"value": 10,
				},
			],
		},
	},
};
```

## The Property Editor UI Element

```ts
// TODO: get interface
interface UmbPropertyEditorUIElement {}
```

**Example with LitElement**

```ts
import { LitElement, html, css } from 'lit';
import { customElement, property } from 'lit/decorators.js';
import { UUITextStyles } from '@umbraco-ui/uui-base/lib/styles';
import { UmbElement } from '@umbraco-cms/element';

// TODO: should we make examples with LitElement or just vanilla JS? or should we have for more libraries?
@customElement('my-text-box')
export class UmbPropertyEditorUITextBoxElement extends UmbElement(LitElement) {
	static styles = [
		UUITextStyles,
		css`
			uui-input {
				width: 100%;
			}
		`,
	];

	@property()
	value = '';

	@property({ type: Array, attribute: false })
	public config = [];

	private onInput(e: InputEvent) {
		this.value = (e.target as HTMLInputElement).value;
		this.dispatchEvent(new CustomEvent('property-value-change'));
	}

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