From 5546b8ff435b268369855106116968e704335e92 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 23 Jun 2024 15:50:41 +0100 Subject: [PATCH] Lexical: Added more icons, made reflective text/bg color buttons --- resources/icons/editor/highlighter.svg | 1 + resources/icons/editor/list-check.svg | 2 +- resources/icons/editor/list-numbered.svg | 2 +- resources/icons/editor/table.svg | 1 + resources/icons/editor/text-color.svg | 1 + .../wysiwyg/ui/defaults/button-definitions.ts | 9 +++-- .../ui/framework/blocks/color-button.ts | 35 +++++++++++++++++++ .../ui/framework/blocks/dropdown-button.ts | 24 +++++++------ resources/js/wysiwyg/ui/framework/buttons.ts | 18 ++++++++-- resources/js/wysiwyg/ui/toolbars.ts | 5 +-- 10 files changed, 79 insertions(+), 19 deletions(-) create mode 100644 resources/icons/editor/highlighter.svg create mode 100644 resources/icons/editor/table.svg create mode 100644 resources/icons/editor/text-color.svg create mode 100644 resources/js/wysiwyg/ui/framework/blocks/color-button.ts diff --git a/resources/icons/editor/highlighter.svg b/resources/icons/editor/highlighter.svg new file mode 100644 index 000000000..b2eaacdb2 --- /dev/null +++ b/resources/icons/editor/highlighter.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/icons/editor/list-check.svg b/resources/icons/editor/list-check.svg index f30266b27..4517d0d53 100644 --- a/resources/icons/editor/list-check.svg +++ b/resources/icons/editor/list-check.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/resources/icons/editor/list-numbered.svg b/resources/icons/editor/list-numbered.svg index 92cdbf0ae..4bc0fc1ba 100644 --- a/resources/icons/editor/list-numbered.svg +++ b/resources/icons/editor/list-numbered.svg @@ -1 +1 @@ - \ No newline at end of file + \ No newline at end of file diff --git a/resources/icons/editor/table.svg b/resources/icons/editor/table.svg new file mode 100644 index 000000000..15425063c --- /dev/null +++ b/resources/icons/editor/table.svg @@ -0,0 +1 @@ + \ No newline at end of file diff --git a/resources/icons/editor/text-color.svg b/resources/icons/editor/text-color.svg new file mode 100644 index 000000000..a862e1962 --- /dev/null +++ b/resources/icons/editor/text-color.svg @@ -0,0 +1 @@ + diff --git a/resources/js/wysiwyg/ui/defaults/button-definitions.ts b/resources/js/wysiwyg/ui/defaults/button-definitions.ts index 589567c03..5e5f0d409 100644 --- a/resources/js/wysiwyg/ui/defaults/button-definitions.ts +++ b/resources/js/wysiwyg/ui/defaults/button-definitions.ts @@ -34,6 +34,8 @@ import redoIcon from "@icons/editor/redo.svg" import boldIcon from "@icons/editor/bold.svg" import italicIcon from "@icons/editor/italic.svg" import underlinedIcon from "@icons/editor/underlined.svg" +import textColorIcon from "@icons/editor/text-color.svg"; +import highlightIcon from "@icons/editor/highlighter.svg"; import strikethroughIcon from "@icons/editor/strikethrough.svg" import superscriptIcon from "@icons/editor/superscript.svg" import subscriptIcon from "@icons/editor/subscript.svg" @@ -43,6 +45,7 @@ import listBulletIcon from "@icons/editor/list-bullet.svg" import listNumberedIcon from "@icons/editor/list-numbered.svg" import listCheckIcon from "@icons/editor/list-check.svg" import linkIcon from "@icons/editor/link.svg" +import tableIcon from "@icons/editor/table.svg" import imageIcon from "@icons/editor/image.svg" import detailsIcon from "@icons/editor/details.svg" import sourceIcon from "@icons/editor/source-view.svg" @@ -167,8 +170,8 @@ function buildFormatButton(label: string, format: TextFormatType, icon: string): export const bold: EditorButtonDefinition = buildFormatButton('Bold', 'bold', boldIcon); export const italic: EditorButtonDefinition = buildFormatButton('Italic', 'italic', italicIcon); export const underline: EditorButtonDefinition = buildFormatButton('Underline', 'underline', underlinedIcon); -export const textColor: EditorBasicButtonDefinition = {label: 'Text color'}; -export const highlightColor: EditorBasicButtonDefinition = {label: 'Highlight color'}; +export const textColor: EditorBasicButtonDefinition = {label: 'Text color', icon: textColorIcon}; +export const highlightColor: EditorBasicButtonDefinition = {label: 'Highlight color', icon: highlightIcon}; export const strikethrough: EditorButtonDefinition = buildFormatButton('Strikethrough', 'strikethrough', strikethroughIcon); export const superscript: EditorButtonDefinition = buildFormatButton('Superscript', 'superscript', superscriptIcon); @@ -183,6 +186,7 @@ export const clearFormating: EditorButtonDefinition = { for (const node of selection?.getNodes() || []) { if ($isTextNode(node)) { node.setFormat(0); + node.setStyle(''); } } }); @@ -254,6 +258,7 @@ export const link: EditorButtonDefinition = { export const table: EditorBasicButtonDefinition = { label: 'Table', + icon: tableIcon, }; export const image: EditorButtonDefinition = { diff --git a/resources/js/wysiwyg/ui/framework/blocks/color-button.ts b/resources/js/wysiwyg/ui/framework/blocks/color-button.ts new file mode 100644 index 000000000..e81521a26 --- /dev/null +++ b/resources/js/wysiwyg/ui/framework/blocks/color-button.ts @@ -0,0 +1,35 @@ +import {EditorBasicButtonDefinition, EditorButton} from "../buttons"; +import {EditorUiStateUpdate} from "../core"; +import {$isRangeSelection} from "lexical"; +import {$getSelectionStyleValueForProperty} from "@lexical/selection"; + +export class EditorColorButton extends EditorButton { + protected style: string; + + constructor(definition: EditorBasicButtonDefinition, style: string) { + super(definition); + + this.style = style; + } + + getColorBar(): HTMLElement { + const colorBar = this.getDOMElement().querySelector('svg .editor-icon-color-bar'); + + if (!colorBar) { + throw new Error(`Could not find expected color bar in the icon for this ${this.definition.label} button`); + } + + return (colorBar as HTMLElement); + } + + updateState(state: EditorUiStateUpdate): void { + super.updateState(state); + + if ($isRangeSelection(state.selection)) { + const value = $getSelectionStyleValueForProperty(state.selection, this.style); + const colorBar = this.getColorBar(); + colorBar.setAttribute('fill', value); + } + } + +} \ No newline at end of file diff --git a/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts b/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts index 199c7728d..a419b92b2 100644 --- a/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts +++ b/resources/js/wysiwyg/ui/framework/blocks/dropdown-button.ts @@ -8,19 +8,23 @@ export class EditorDropdownButton extends EditorContainerUiElement { protected childItems: EditorUiElement[]; protected open: boolean = false; - constructor(buttonDefinition: EditorBasicButtonDefinition, children: EditorUiElement[]) { + constructor(button: EditorBasicButtonDefinition|EditorButton, children: EditorUiElement[]) { super(children); this.childItems = children - this.button = new EditorButton({ - ...buttonDefinition, - action() { - return false; - }, - isActive: () => { - return this.open; - } - }); + if (button instanceof EditorButton) { + this.button = button; + } else { + this.button = new EditorButton({ + ...button, + action() { + return false; + }, + isActive: () => { + return this.open; + } + }); + } this.children.push(this.button); } diff --git a/resources/js/wysiwyg/ui/framework/buttons.ts b/resources/js/wysiwyg/ui/framework/buttons.ts index 02f88dac8..7e8df076a 100644 --- a/resources/js/wysiwyg/ui/framework/buttons.ts +++ b/resources/js/wysiwyg/ui/framework/buttons.ts @@ -1,7 +1,6 @@ import {BaseSelection} from "lexical"; import {EditorUiContext, EditorUiElement, EditorUiStateUpdate} from "./core"; import {el} from "../../helpers"; -import {context} from "esbuild"; export interface EditorBasicButtonDefinition { label: string; @@ -20,9 +19,22 @@ export class EditorButton extends EditorUiElement { protected completedSetup: boolean = false; protected disabled: boolean = false; - constructor(definition: EditorButtonDefinition) { + constructor(definition: EditorButtonDefinition|EditorBasicButtonDefinition) { super(); - this.definition = definition; + + if ((definition as EditorButtonDefinition).action !== undefined) { + this.definition = definition as EditorButtonDefinition; + } else { + this.definition = { + ...definition, + action() { + return false; + }, + isActive: () => { + return false; + } + }; + } } setContext(context: EditorUiContext) { diff --git a/resources/js/wysiwyg/ui/toolbars.ts b/resources/js/wysiwyg/ui/toolbars.ts index 4dbf9bb7e..821c9f9cf 100644 --- a/resources/js/wysiwyg/ui/toolbars.ts +++ b/resources/js/wysiwyg/ui/toolbars.ts @@ -16,6 +16,7 @@ import {FormatPreviewButton} from "./framework/blocks/format-preview-button"; import {EditorDropdownButton} from "./framework/blocks/dropdown-button"; import {EditorColorPicker} from "./framework/blocks/color-picker"; import {EditorTableCreator} from "./framework/blocks/table-creator"; +import {EditorColorButton} from "./framework/blocks/color-button"; export function getMainEditorFullToolbar(): EditorContainerUiElement { return new EditorSimpleClassContainer('editor-toolbar-main', [ @@ -41,10 +42,10 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement { new EditorButton(bold), new EditorButton(italic), new EditorButton(underline), - new EditorDropdownButton(textColor, [ + new EditorDropdownButton(new EditorColorButton(textColor, 'color'), [ new EditorColorPicker('color'), ]), - new EditorDropdownButton(highlightColor, [ + new EditorDropdownButton(new EditorColorButton(highlightColor, 'background-color'), [ new EditorColorPicker('background-color'), ]), new EditorButton(strikethrough),