mirror of
https://github.com/BookStackApp/BookStack.git
synced 2024-12-12 05:23:40 +08:00
63f4b42453
Also added smarter above/below positioning to respond if toolbar would be off the bottom of the editor, and added hide/show when they'd go outside editor scroll bounds.
71 lines
2.2 KiB
TypeScript
71 lines
2.2 KiB
TypeScript
import {EditorContainerUiElement, EditorUiElement} from "./core";
|
|
import {el} from "../../helpers";
|
|
|
|
export type EditorContextToolbarDefinition = {
|
|
selector: string;
|
|
content: EditorUiElement[],
|
|
displayTargetLocator?: (originalTarget: HTMLElement) => HTMLElement;
|
|
};
|
|
|
|
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()));
|
|
}
|
|
|
|
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 (!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[]) {
|
|
this.addChildren(...children);
|
|
const dom = this.getDOMElement();
|
|
dom.append(...children.map(child => child.getDOMElement()));
|
|
}
|
|
|
|
protected empty() {
|
|
const children = this.getChildren();
|
|
for (const child of children) {
|
|
child.getDOMElement().remove();
|
|
}
|
|
this.removeChildren(...children);
|
|
}
|
|
|
|
destroy() {
|
|
this.empty();
|
|
this.getDOMElement().remove();
|
|
}
|
|
} |