From 2d6c358a98f9c36eb99090a7012486d5821fdbfa Mon Sep 17 00:00:00 2001
From: JesmoDev <26099018+JesmoDev@users.noreply.github.com>
Date: Thu, 12 Sep 2024 15:06:27 +0200
Subject: [PATCH] fix update listeners
---
.../input-tiptap/input-tiptap.element.ts | 16 ++----
.../input-tiptap/tiptap-fixed-menu.element.ts | 36 +++++++++---
.../input-tiptap/tiptap-hover-menu.element.ts | 55 +++++++++++++++++++
3 files changed, 87 insertions(+), 20 deletions(-)
create mode 100644 src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-hover-menu.element.ts
diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts
index 209fb1836d..0b632b56d4 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/input-tiptap.element.ts
@@ -6,6 +6,7 @@ import { UUIFormControlMixin } from '@umbraco-cms/backoffice/external/uui';
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';
@@ -35,23 +36,18 @@ export class UmbInputTiptapElement extends UUIFormControlMixin(UmbLitElement, ''
TextAlign.configure({
types: ['heading', 'paragraph', 'blockquote', 'orderedList', 'bulletList', 'codeBlock'],
}),
- Link,
+ Link.configure({ openOnClick: false }),
Underline,
],
content: json,
onSelectionUpdate: ({ editor }) => {
const { $from } = editor.state.selection;
const activeMarks = $from.node();
-
- // Log the active marks
- console.log('Active Marks:', activeMarks);
- this._fixedMenuElement.onUpdate(); // TODO: This is a hack to force the fixed menu to update. We need to find a better way.
},
onUpdate: ({ editor }) => {
const json = editor.getJSON();
this.value = JSON.stringify(json);
this.dispatchEvent(new UmbChangeEvent());
- this._fixedMenuElement.onUpdate(); // TODO: This is a hack to force the fixed menu to update. We need to find a better way.
},
});
}
@@ -62,10 +58,8 @@ export class UmbInputTiptapElement extends UUIFormControlMixin(UmbLitElement, ''
override render() {
return html`
-
+
+
`;
}
@@ -108,7 +102,7 @@ export class UmbInputTiptapElement extends UUIFormControlMixin(UmbLitElement, ''
font-size: 0.8rem;
padding: 0;
}
- .ProseMirror {
+ .tiptap {
height: 100%;
width: 100%;
outline: none;
diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts
index e34eb1445f..a63fb72121 100644
--- a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts
+++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-fixed-menu.element.ts
@@ -17,6 +17,7 @@ import {
strikethrough,
underline,
} from './icons.js';
+import type { PropertyValues } from '@umbraco-cms/backoffice/external/lit';
import { LitElement, css, customElement, html, property, state } from '@umbraco-cms/backoffice/external/lit';
import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
@@ -133,24 +134,41 @@ export class UmbTiptapFixedMenuElement extends LitElement {
name: 'link',
icon: link,
command: () => {
+ const text = prompt('Enter the text');
const url = prompt('Enter the URL');
- if (url) {
- this.editor?.chain().focus().setLink({ href: url, target: '_blank' }).run();
+ if (url && text && this.editor) {
+ const { from } = this.editor.state.selection;
+ this.editor
+ .chain()
+ .focus()
+ .insertContent(text)
+ .setTextSelection({ from: from, to: from + text.length })
+ .setLink({ href: url, target: '_blank' })
+ .run();
}
},
},
];
@property({ attribute: false })
- editor?: Editor;
-
- public onUpdate() {
- //TODO: Find a better way to trigger a re-render of the menu when the editor is updated
- // This is used to update the active state of the buttons
- this.requestUpdate();
- console.log('onUpdate');
+ get editor() {
+ return this.#editor;
}
+ set editor(value) {
+ const oldValue = this.#editor;
+ if (value === oldValue) {
+ return;
+ }
+ this.#editor = value;
+ this.#editor?.on('selectionUpdate', this.#onUpdate);
+ this.#editor?.on('update', this.#onUpdate);
+ }
+ #editor?: Editor;
+
+ #onUpdate = () => {
+ this.requestUpdate();
+ };
override render() {
return html`
diff --git a/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-hover-menu.element.ts b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-hover-menu.element.ts
new file mode 100644
index 0000000000..6dfc91ac56
--- /dev/null
+++ b/src/Umbraco.Web.UI.Client/src/packages/tiptap/components/input-tiptap/tiptap-hover-menu.element.ts
@@ -0,0 +1,55 @@
+import { LitElement, PropertyValues, css, customElement, html, property } from '@umbraco-cms/backoffice/external/lit';
+import type { Editor } from '@umbraco-cms/backoffice/external/tiptap';
+
+@customElement('umb-tiptap-hover-menu')
+export class UmbTiptapHoverMenuElement extends LitElement {
+ @property({ attribute: false })
+ get editor() {
+ return this.#editor;
+ }
+ set editor(value) {
+ const oldValue = this.#editor;
+ if (value === oldValue) {
+ return;
+ }
+ this.#editor = value;
+ this.#editor?.on('selectionUpdate', this.#onUpdate);
+ this.#editor?.on('update', this.#onUpdate);
+ }
+ #editor?: Editor;
+
+ override connectedCallback(): void {
+ super.connectedCallback();
+ this.setAttribute('popover', '');
+ }
+
+ #onUpdate = () => {
+ console.log('LINK ACTIVE');
+ if (this.editor?.isActive('link')) {
+ // show the popover
+ this.showPopover();
+ } else {
+ this.requestUpdate();
+ }
+ };
+
+ override render() {
+ console.log('RENDER HOVER MENU');
+ return html``;
+ }
+
+ static override styles = css`
+ :host {
+ position: fixed;
+ background-color: var(--uui-color-surface-alt);
+ border: 1px solid var(--uui-color-border);
+ border-radius: var(--uui-size-border-radius);
+ }
+ `;
+}
+
+declare global {
+ interface HTMLElementTagNameMap {
+ 'umb-tiptap-hover-menu': UmbTiptapHoverMenuElement;
+ }
+}