]> BookStack Code Mirror - bookstack/blobdiff - resources/js/wysiwyg/ui/framework/toolbars.ts
Lexical: Added a media toolbar, improved toolbars and media selection
[bookstack] / resources / js / wysiwyg / ui / framework / toolbars.ts
index a844161f468e7767399636ee876b71629f2f56e3..de2255444ebf6fcfc43fb7a9a225c3f36c208cc1 100644 (file)
@@ -1,5 +1,6 @@
 import {EditorContainerUiElement, EditorUiElement} from "./core";
-import {el} from "../../helpers";
+
+import {el} from "../../utils/dom";
 
 export type EditorContextToolbarDefinition = {
     selector: string;
@@ -9,15 +10,49 @@ export type EditorContextToolbarDefinition = {
 
 export class EditorContextToolbar extends EditorContainerUiElement {
 
+    protected target: HTMLElement;
+
+    constructor(target: HTMLElement, children: EditorUiElement[]) {
+        super(children);
+        this.target = target;
+    }
+
     protected buildDOM(): HTMLElement {
         return el('div', {
             class: 'editor-context-toolbar',
         }, this.getChildren().map(child => child.getDOMElement()));
     }
 
-    attachTo(target: HTMLElement) {
-        // Todo - attach to target position
-        console.log('attaching context toolbar to', target);
+    updatePosition() {
+        const editorBounds = this.getContext().scrollDOM.getBoundingClientRect();
+        const targetBounds = this.target.getBoundingClientRect();
+        const dom = this.getDOMElement();
+        const domBounds = dom.getBoundingClientRect();
+
+        const showing = targetBounds.bottom > editorBounds.top
+            && targetBounds.top < editorBounds.bottom;
+
+        dom.hidden = !showing;
+
+        if (!this.target.isConnected) {
+            // If our target is no longer in the DOM, tell the manager an update is needed.
+            this.getContext().manager.triggerFutureStateRefresh();
+            return;
+        } else if (!showing) {
+            return;
+        }
+
+        const showAbove: boolean = targetBounds.bottom + 6 + domBounds.height > editorBounds.bottom;
+        dom.classList.toggle('is-above', showAbove);
+
+        const targetMid = targetBounds.left + (targetBounds.width / 2);
+        const targetLeft = targetMid - (domBounds.width / 2);
+        if (showAbove) {
+            dom.style.top = (targetBounds.top - 6 - domBounds.height) + 'px';
+        } else {
+            dom.style.top = (targetBounds.bottom + 6) + 'px';
+        }
+        dom.style.left = targetLeft + 'px';
     }
 
     insert(children: EditorUiElement[]) {
@@ -26,11 +61,16 @@ export class EditorContextToolbar extends EditorContainerUiElement {
         dom.append(...children.map(child => child.getDOMElement()));
     }
 
-    empty() {
+    protected empty() {
         const children = this.getChildren();
         for (const child of children) {
             child.getDOMElement().remove();
         }
         this.removeChildren(...children);
     }
+
+    destroy() {
+        this.empty();
+        this.getDOMElement().remove();
+    }
 }
\ No newline at end of file