dynamic property editors

This commit is contained in:
Niels Lyngsø
2022-05-26 12:14:13 +02:00
parent 87f72e57b2
commit 255a034149
5 changed files with 126 additions and 9 deletions

View File

@@ -6,8 +6,9 @@ import './installer/installer.element';
import './auth/login/login.element';
import './auth/auth-layout.element';
import './backoffice/backoffice.element';
import './backoffice/node-editor-layout.element';
import './property-editors/node-property.element';
import './node-editor/node-editor-layout.element';
import './node-editor/node-property-control.element';
import './node-editor/node-property.element';
import './property-editors/property-editor-text.element';
import './property-editors/property-editor-textarea.element';

View File

@@ -53,6 +53,39 @@ class UmbContentEditor extends LitElement {
console.log('Save and preview');
}
private properties = [
{
label: 'Text string label',
description: 'This is the a text string property',
dataTypeAlias: 'myTextStringEditor',
value: 'hello world'
},
{
label: 'Textarea label',
description: 'this is a textarea property',
dataTypeAlias: 'myTextAreaEditor',
value: 'Teeeeexxxt areaaaaaa'
}
]
/*
import { unsafeHTML } from 'lit-html/directives/unsafe-html';
// ...
const template = `
<h${this.rank} class="a-heading">
<slot></slot>
</h${this.rank}>
`;
return html`
${unsafeHTML(template)}
`;
*/
render() {
return html`
<umb-node-editor-layout>
@@ -64,13 +97,13 @@ class UmbContentEditor extends LitElement {
</uui-tab-group>
<uui-box slot="content">
<umb-node-property label="Text string label" description="This is the a text string property">
<umb-property-editor-text></umb-property-editor-text>
</umb-node-property>
<hr />
<umb-node-property label="Textarea label" description="this is a textarea property">
<umb-property-editor-textarea></umb-property-editor-textarea>
</umb-node-property>
${this.properties.map(
property => html`
<umb-node-property label="${property.label}" description="${property.description}">
<umb-node-property-control .dataTypeAlias=${property.dataTypeAlias} .value=${property.value}></umb-node-property-control>
</umb-node-property>
<hr />
`)}
</uui-box>
<div slot="actions">

View File

@@ -0,0 +1,83 @@
import { css, LitElement, PropertyValueMap } from 'lit';
import { UUITextStyles } from '@umbraco-ui/uui-css/lib';
import { customElement, property } from 'lit/decorators.js';
// TODO: get from Data Type Service?
const DataTypeInGlobalService = [
{
alias: 'myTextStringEditor',
elementName: 'umb-property-editor-text'
},
{
alias: 'myTextAreaEditor',
elementName: 'umb-property-editor-textarea'
}
];
@customElement('umb-node-property-control')
class UmbNodePropertyControl extends LitElement {
static styles = [
UUITextStyles,
css`
:host {
display: block;
width: 100%;
height: 100%;
}
`,
];
@property()
private _dataTypeAlias?: string | undefined;
public get dataTypeAlias(): string | undefined {
return this._dataTypeAlias;
}
public set dataTypeAlias(alias: string | undefined) {
//const oldValue = this._dataTypeAlias
this._dataTypeAlias = alias;
const found = DataTypeInGlobalService.find(x => x.alias === alias);
this.elementName = found?.elementName || undefined;
// TODO: Consider error if undefined, showing a error-data-type, if super duper admin we might show a good error message(as always) and a editable textarea with the value, so there is some debug option available?
//this.requestUpdate('dataTypeAlias', oldValue);
}
@property()
elementName?:string
@property()
value?:string
private _element?:HTMLElement;
/** Lit does not currently handle dynamic tag names, therefor we are doing some manual rendering */
// TODO: Refactor into a base class for dynamic-tag element? we will be using this a lot for extensions.
// This could potentially hook into Lit and parse all properties defined in the specific class on to the dynamic-element. (see static elementProperties: PropertyDeclarationMap;)
willUpdate(changedProperties: PropertyValueMap<any> | Map<PropertyKey, unknown>) {
super.willUpdate(changedProperties);
// only need to check changed properties for an expensive computation.
const elementNameHasChanged = changedProperties.has('elementName');
if (elementNameHasChanged) {
if (this._element) {
this.shadowRoot?.removeChild(this._element);
}
if(this.elementName) {
this._element = document.createElement(this.elementName)
this.shadowRoot?.appendChild(this._element);
}
}
const hasChangedProps = changedProperties.has('value');
if(hasChangedProps || elementNameHasChanged) {
this._element?.setAttribute('value', this.value as any);
}
}
}
declare global {
interface HTMLElementTagNameMap {
'umb-node-property-control': UmbNodePropertyControl;
}
}