1 import {BaseSelection, LexicalEditor} from "lexical";
2 import {EditorUIManager} from "./manager";
4 import {el} from "../../utils/dom";
6 export type EditorUiStateUpdate = {
8 selection: BaseSelection|null;
11 export type EditorUiContext = {
12 editor: LexicalEditor; // Lexical editor instance
13 editorDOM: HTMLElement; // DOM element the editor is bound to
14 containerDOM: HTMLElement; // DOM element which contains all editor elements
15 scrollDOM: HTMLElement; // DOM element which is the main content scroll container
16 translate: (text: string) => string; // Translate function
17 manager: EditorUIManager; // UI Manager instance for this editor
18 options: Record<string, any>; // General user options which may be used by sub elements
21 export interface EditorUiBuilderDefinition {
22 build: () => EditorUiElement;
25 export function isUiBuilderDefinition(object: any): object is EditorUiBuilderDefinition {
26 return 'build' in object;
29 export abstract class EditorUiElement {
30 protected dom: HTMLElement|null = null;
31 private context: EditorUiContext|null = null;
33 protected abstract buildDOM(): HTMLElement;
35 setContext(context: EditorUiContext): void {
36 this.context = context;
39 getContext(): EditorUiContext {
40 if (this.context === null) {
41 throw new Error('Attempted to use EditorUIContext before it has been set');
47 getDOMElement(): HTMLElement {
49 this.dom = this.buildDOM();
56 return this.getContext().translate(text);
59 updateState(state: EditorUiStateUpdate): void {
64 export class EditorContainerUiElement extends EditorUiElement {
65 protected children : EditorUiElement[] = [];
67 constructor(children: EditorUiElement[]) {
69 this.children.push(...children);
72 protected buildDOM(): HTMLElement {
73 return el('div', {}, this.getChildren().map(child => child.getDOMElement()));
76 getChildren(): EditorUiElement[] {
80 protected addChildren(...children: EditorUiElement[]): void {
81 this.children.push(...children);
84 protected removeChildren(...children: EditorUiElement[]): void {
85 for (const child of children) {
86 this.removeChild(child);
90 protected removeChild(child: EditorUiElement) {
91 const index = this.children.indexOf(child);
93 this.children.splice(index, 1);
97 updateState(state: EditorUiStateUpdate): void {
98 for (const child of this.children) {
99 child.updateState(state);
103 setContext(context: EditorUiContext) {
104 super.setContext(context);
105 for (const child of this.getChildren()) {
106 child.setContext(context);
111 export class EditorSimpleClassContainer extends EditorContainerUiElement {
114 constructor(className: string, children: EditorUiElement[]) {
116 this.className = className;
119 protected buildDOM(): HTMLElement {
121 class: this.className,
122 }, this.getChildren().map(child => child.getDOMElement()));