1 import {BaseSelection} from "lexical";
2 import {EditorUiContext, EditorUiElement, EditorUiStateUpdate} from "./core";
3 import {el} from "../../helpers";
5 export interface EditorButtonDefinition {
7 action: (context: EditorUiContext) => void;
8 isActive: (selection: BaseSelection|null) => boolean;
11 export class EditorButton extends EditorUiElement {
12 protected definition: EditorButtonDefinition;
13 protected active: boolean = false;
15 constructor(definition: EditorButtonDefinition) {
17 this.definition = definition;
20 protected buildDOM(): HTMLButtonElement {
21 const button = el('button', {
23 class: 'editor-button',
24 }, [this.getLabel()]) as HTMLButtonElement;
26 button.addEventListener('click', this.onClick.bind(this));
32 this.definition.action(this.getContext());
35 updateActiveState(selection: BaseSelection|null) {
36 this.active = this.definition.isActive(selection);
37 this.dom?.classList.toggle('editor-button-active', this.active);
40 updateState(state: EditorUiStateUpdate): void {
41 this.updateActiveState(state.selection);
49 return this.trans(this.definition.label);
53 export class FormatPreviewButton extends EditorButton {
54 protected previewSampleElement: HTMLElement;
56 constructor(previewSampleElement: HTMLElement,definition: EditorButtonDefinition) {
58 this.previewSampleElement = previewSampleElement;
61 protected buildDOM(): HTMLButtonElement {
62 const button = super.buildDOM();
63 button.innerHTML = '';
65 const preview = el('span', {
66 class: 'editor-button-format-preview'
67 }, [this.getLabel()]);
69 const stylesToApply = this.getStylesFromPreview();
70 for (const style of Object.keys(stylesToApply)) {
71 preview.style.setProperty(style, stylesToApply[style]);
74 button.append(preview);
78 protected getStylesFromPreview(): Record<string, string> {
79 const wrap = el('div', {style: 'display: none', hidden: 'true', class: 'page-content'});
80 const sampleClone = this.previewSampleElement.cloneNode() as HTMLElement;
81 sampleClone.textContent = this.getLabel();
82 wrap.append(sampleClone);
83 document.body.append(wrap);
85 const propertiesToFetch = ['color', 'font-size', 'background-color', 'border-inline-start'];
86 const propertiesToReturn: Record<string, string> = {};
88 const computed = window.getComputedStyle(sampleClone);
89 for (const property of propertiesToFetch) {
90 propertiesToReturn[property] = computed.getPropertyValue(property);
94 return propertiesToReturn;