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 error: (text: string|Error) => void; // Error reporting function
18 manager: EditorUIManager; // UI Manager instance for this editor
19 options: Record<string, any>; // General user options which may be used by sub elements
22 export interface EditorUiBuilderDefinition {
23 build: () => EditorUiElement;
26 export function isUiBuilderDefinition(object: any): object is EditorUiBuilderDefinition {
27 return 'build' in object;
30 export abstract class EditorUiElement {
31 protected dom: HTMLElement|null = null;
32 private context: EditorUiContext|null = null;
34 protected abstract buildDOM(): HTMLElement;
36 setContext(context: EditorUiContext): void {
37 this.context = context;
40 getContext(): EditorUiContext {
41 if (this.context === null) {
42 throw new Error('Attempted to use EditorUIContext before it has been set');
48 getDOMElement(): HTMLElement {
50 this.dom = this.buildDOM();
57 return this.getContext().translate(text);
60 updateState(state: EditorUiStateUpdate): void {
65 export class EditorContainerUiElement extends EditorUiElement {
66 protected children : EditorUiElement[] = [];
68 constructor(children: EditorUiElement[]) {
70 this.children.push(...children);
73 protected buildDOM(): HTMLElement {
74 return el('div', {}, this.getChildren().map(child => child.getDOMElement()));
77 getChildren(): EditorUiElement[] {
81 protected addChildren(...children: EditorUiElement[]): void {
82 this.children.push(...children);
85 protected removeChildren(...children: EditorUiElement[]): void {
86 for (const child of children) {
87 this.removeChild(child);
91 protected removeChild(child: EditorUiElement) {
92 const index = this.children.indexOf(child);
94 this.children.splice(index, 1);
98 updateState(state: EditorUiStateUpdate): void {
99 for (const child of this.children) {
100 child.updateState(state);
104 setContext(context: EditorUiContext) {
105 super.setContext(context);
106 for (const child of this.getChildren()) {
107 child.setContext(context);
112 export class EditorSimpleClassContainer extends EditorContainerUiElement {
115 constructor(className: string, children: EditorUiElement[]) {
117 this.className = className;
120 protected buildDOM(): HTMLElement {
122 class: this.className,
123 }, this.getChildren().map(child => child.getDOMElement()));