Refactored umb-input-tiptap to await loading extensions

before initializing the Tiptap editor.
This commit is contained in:
leekelleher
2024-09-16 15:26:18 +01:00
parent a42068607b
commit 37ec15f440

View File

@@ -1,31 +1,60 @@
import type { UmbTiptapFixedMenuElement } from './tiptap-fixed-menu.element.js';
import type { PropertyValueMap } from '@umbraco-cms/backoffice/external/lit';
import { css, customElement, html, property, query, state } from '@umbraco-cms/backoffice/external/lit';
import type { UmbTiptapExtensionBase } from './tiptap-extension.js';
import { css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import { loadManifestApi } from '@umbraco-cms/backoffice/extension-api';
import { umbExtensionsRegistry } from '@umbraco-cms/backoffice/extension-registry';
import { Editor, Link, StarterKit, TextAlign, Underline } from '@umbraco-cms/backoffice/external/tiptap';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
import { UmbLitElement } from '@umbraco-cms/backoffice/lit-element';
import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
import { UmbFormControlMixin } from '@umbraco-cms/backoffice/validation';
import type { UmbPropertyEditorConfigCollection } from '@umbraco-cms/backoffice/property-editor';
import './tiptap-fixed-menu.element.js';
import './tiptap-hover-menu.element.js';
import { Editor, Link, StarterKit, TextAlign, Underline } from '@umbraco-cms/backoffice/external/tiptap';
import { UmbChangeEvent } from '@umbraco-cms/backoffice/event';
@customElement('umb-input-tiptap')
export class UmbInputTiptapElement extends UUIFormControlMixin(UmbLitElement, '') {
@query('umb-tiptap-fixed-menu') _fixedMenuElement!: UmbTiptapFixedMenuElement;
export class UmbInputTiptapElement extends UmbFormControlMixin(UmbLitElement, '') {
@state()
private _extensions: Array<UmbTiptapExtensionBase> = [];
@property({ attribute: false })
configuration?: UmbPropertyEditorConfigCollection;
@state()
_editor!: Editor;
private _editor!: Editor;
protected override firstUpdated(): void {
const editor = this.shadowRoot?.querySelector('#editor');
protected override async firstUpdated() {
await Promise.all([await this.#loadExtensions(), await this.#loadEditor()]);
}
if (!editor) return;
async #loadExtensions() {
await new Promise<void>((resolve) => {
this.observe(umbExtensionsRegistry.byType('tiptapExtension'), async (manifests) => {
this._extensions = [];
for (const manifest of manifests) {
if (manifest.api) {
const extension = await loadManifestApi(manifest.api);
if (extension) {
this._extensions.push(new extension(this));
}
}
}
this.requestUpdate('_extensions');
resolve();
});
});
}
async #loadEditor() {
const element = this.shadowRoot?.querySelector('#editor');
if (!element) return;
const extensions = this._extensions.map((ext) => ext.getExtensions()).flat();
this._editor = new Editor({
element: editor,
element: element,
extensions: [
StarterKit,
TextAlign.configure({
@@ -33,6 +62,7 @@ export class UmbInputTiptapElement extends UUIFormControlMixin(UmbLitElement, ''
}),
Link.configure({ openOnClick: false }),
Underline,
...extensions,
],
content: this.value.toString(),
onUpdate: ({ editor }) => {
@@ -42,14 +72,11 @@ export class UmbInputTiptapElement extends UUIFormControlMixin(UmbLitElement, ''
});
}
protected getFormElement() {
return null;
}
override render() {
if (!this._extensions?.length) return html`<uui-loader></uui-loader>`;
return html`
<umb-tiptap-hover-menu .editor=${this._editor}></umb-tiptap-hover-menu>
<umb-tiptap-fixed-menu .editor=${this._editor}></umb-tiptap-fixed-menu>
<umb-tiptap-fixed-menu .editor=${this._editor} .extensions=${this._extensions}></umb-tiptap-fixed-menu>
<div id="editor"></div>
`;
}