dynamic property editors
This commit is contained in:
@@ -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';
|
||||
|
||||
|
||||
@@ -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">
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user