From 255a0341495fc4ee0f69cff60dd4ebffa3453288 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Niels=20Lyngs=C3=B8?= Date: Thu, 26 May 2022 12:14:13 +0200 Subject: [PATCH] dynamic property editors --- src/Umbraco.Web.UI.Client/src/app.ts | 5 +- .../src/content/content-editor.element.ts | 47 +++++++++-- .../node-editor-layout.element.ts | 0 .../node-property-control.element.ts | 83 +++++++++++++++++++ .../node-property.element.ts | 0 5 files changed, 126 insertions(+), 9 deletions(-) rename src/Umbraco.Web.UI.Client/src/{backoffice => node-editor}/node-editor-layout.element.ts (100%) create mode 100644 src/Umbraco.Web.UI.Client/src/node-editor/node-property-control.element.ts rename src/Umbraco.Web.UI.Client/src/{property-editors => node-editor}/node-property.element.ts (100%) diff --git a/src/Umbraco.Web.UI.Client/src/app.ts b/src/Umbraco.Web.UI.Client/src/app.ts index eb69dda6ce..6c67c6a0ea 100644 --- a/src/Umbraco.Web.UI.Client/src/app.ts +++ b/src/Umbraco.Web.UI.Client/src/app.ts @@ -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'; diff --git a/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts b/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts index 365458f54e..684344973b 100644 --- a/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts +++ b/src/Umbraco.Web.UI.Client/src/content/content-editor.element.ts @@ -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 = ` + + + + `; + + return html` + ${unsafeHTML(template)} + `; + + */ + render() { return html` @@ -64,13 +97,13 @@ class UmbContentEditor extends LitElement { - - - -
- - - + ${this.properties.map( + property => html` + + + +
+ `)}
diff --git a/src/Umbraco.Web.UI.Client/src/backoffice/node-editor-layout.element.ts b/src/Umbraco.Web.UI.Client/src/node-editor/node-editor-layout.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/backoffice/node-editor-layout.element.ts rename to src/Umbraco.Web.UI.Client/src/node-editor/node-editor-layout.element.ts diff --git a/src/Umbraco.Web.UI.Client/src/node-editor/node-property-control.element.ts b/src/Umbraco.Web.UI.Client/src/node-editor/node-property-control.element.ts new file mode 100644 index 0000000000..27602f9ce0 --- /dev/null +++ b/src/Umbraco.Web.UI.Client/src/node-editor/node-property-control.element.ts @@ -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 | Map) { + 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; + } +} diff --git a/src/Umbraco.Web.UI.Client/src/property-editors/node-property.element.ts b/src/Umbraco.Web.UI.Client/src/node-editor/node-property.element.ts similarity index 100% rename from src/Umbraco.Web.UI.Client/src/property-editors/node-property.element.ts rename to src/Umbraco.Web.UI.Client/src/node-editor/node-property.element.ts