1
0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-07-31 15:24:31 +03:00

Lexical: Refined editor UI

- Cleaned up dropdown lists to look integrated
- Added icons for color picker clear and menu list items
This commit is contained in:
Dan Brown
2024-09-09 14:06:41 +01:00
parent fd07aa0f05
commit fb49371c6b
9 changed files with 87 additions and 11 deletions

View File

@ -11,6 +11,7 @@
## Secondary Todo
- Color picker support in table form color fields
- Color picker for color controls
- Table caption text support
- Support media src conversions (https://github.com/tinymce/tinymce/blob/release/6.6/modules/tinymce/src/plugins/media/main/ts/core/UrlPatterns.ts)

View File

@ -347,6 +347,7 @@ export const deleteColumn: EditorButtonDefinition = {
export const cellProperties: EditorButtonDefinition = {
label: 'Cell properties',
format: 'long',
action(context: EditorUiContext) {
context.editor.getEditorState().read(() => {
const cell = $getNodeFromSelection($getSelection(), $isCustomTableCellNode);
@ -361,6 +362,7 @@ export const cellProperties: EditorButtonDefinition = {
export const mergeCells: EditorButtonDefinition = {
label: 'Merge cells',
format: 'long',
action(context: EditorUiContext) {
context.editor.update(() => {
const selection = $getSelection();
@ -377,6 +379,7 @@ export const mergeCells: EditorButtonDefinition = {
export const splitCell: EditorButtonDefinition = {
label: 'Split cell',
format: 'long',
action(context: EditorUiContext) {
context.editor.update(() => {
$unmergeCell();

View File

@ -3,6 +3,8 @@ import {$getSelection} from "lexical";
import {$patchStyleText} from "@lexical/selection";
import {el} from "../../../utils/dom";
import removeIcon from "@icons/editor/color-clear.svg";
const colorChoices = [
'#000000',
'#ffffff',
@ -52,11 +54,13 @@ export class EditorColorPicker extends EditorUiElement {
});
});
colorOptions.push(el('div', {
const removeButton = el('div', {
class: 'editor-color-select-option',
'data-color': '',
title: 'Clear color',
}, ['x']));
}, []);
removeButton.innerHTML = removeIcon;
colorOptions.push(removeButton);
const colorRows = [];
for (let i = 0; i < colorOptions.length; i+=5) {

View File

@ -2,6 +2,7 @@ import {handleDropdown} from "../helpers/dropdowns";
import {EditorContainerUiElement, EditorUiElement} from "../core";
import {EditorBasicButtonDefinition, EditorButton} from "../buttons";
import {el} from "../../../utils/dom";
import {EditorMenuButton} from "./menu-button";
export type EditorDropdownButtonOptions = {
showOnHover?: boolean;
@ -29,7 +30,8 @@ export class EditorDropdownButton extends EditorContainerUiElement {
if (options.button instanceof EditorButton) {
this.button = options.button;
} else {
this.button = new EditorButton({
const type = options.button.format === 'long' ? EditorMenuButton : EditorButton;
this.button = new type({
...options.button,
action() {
return false;

View File

@ -0,0 +1,15 @@
import {EditorButton} from "../buttons";
import {el} from "../../../utils/dom";
import arrowIcon from "@icons/chevron-right.svg"
export class EditorMenuButton extends EditorButton {
protected buildDOM(): HTMLButtonElement {
const dom = super.buildDOM();
const icon = el('div', {class: 'editor-menu-button-icon'});
icon.innerHTML = arrowIcon;
dom.append(icon);
return dom;
}
}

View File

@ -0,0 +1,10 @@
import {EditorUiElement} from "../core";
import {el} from "../../../utils/dom";
export class EditorSeparator extends EditorUiElement {
buildDOM(): HTMLElement {
return el('div', {
class: 'editor-separator',
});
}
}

View File

@ -65,6 +65,7 @@ import {
} from "./defaults/buttons/objects";
import {el} from "../utils/dom";
import {EditorButtonWithMenu} from "./framework/blocks/button-with-menu";
import {EditorSeparator} from "./framework/blocks/separator";
export function getMainEditorFullToolbar(): EditorContainerUiElement {
return new EditorSimpleClassContainer('editor-toolbar-main', [
@ -83,7 +84,7 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
new FormatPreviewButton(el('h5'), h5),
new FormatPreviewButton(el('blockquote'), blockquote),
new FormatPreviewButton(el('p'), paragraph),
new EditorDropdownButton({button: {label: 'Callouts'}, showOnHover: true, direction: 'vertical'}, [
new EditorDropdownButton({button: {label: 'Callouts', format: 'long'}, showOnHover: true, direction: 'vertical'}, [
new FormatPreviewButton(el('p', {class: 'callout info'}), infoCallout),
new FormatPreviewButton(el('p', {class: 'callout success'}), successCallout),
new FormatPreviewButton(el('p', {class: 'callout warning'}), warningCallout),
@ -125,37 +126,41 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
]),
// Insert types
new EditorOverflowContainer(8, [
new EditorOverflowContainer(4, [
new EditorButton(link),
new EditorDropdownButton({button: table, direction: 'vertical'}, [
new EditorDropdownButton({button: {...table, format: 'long'}, showOnHover: true}, [
new EditorDropdownButton({button: {label: 'Insert', format: 'long'}, showOnHover: true}, [
new EditorTableCreator(),
]),
new EditorDropdownButton({button: {label: 'Cell'}, direction: 'vertical', showOnHover: true}, [
new EditorSeparator(),
new EditorDropdownButton({button: {label: 'Cell', format: 'long'}, direction: 'vertical', showOnHover: true}, [
new EditorButton(cellProperties),
new EditorButton(mergeCells),
new EditorButton(splitCell),
]),
new EditorDropdownButton({button: {label: 'Row'}, direction: 'vertical', showOnHover: true}, [
new EditorDropdownButton({button: {label: 'Row', format: 'long'}, direction: 'vertical', showOnHover: true}, [
new EditorButton({...insertRowAbove, format: 'long'}),
new EditorButton({...insertRowBelow, format: 'long'}),
new EditorButton({...deleteRow, format: 'long'}),
new EditorButton(rowProperties),
new EditorSeparator(),
new EditorButton(cutRow),
new EditorButton(copyRow),
new EditorButton(pasteRowBefore),
new EditorButton(pasteRowAfter),
]),
new EditorDropdownButton({button: {label: 'Column'}, direction: 'vertical', showOnHover: true}, [
new EditorDropdownButton({button: {label: 'Column', format: 'long'}, direction: 'vertical', showOnHover: true}, [
new EditorButton({...insertColumnBefore, format: 'long'}),
new EditorButton({...insertColumnAfter, format: 'long'}),
new EditorButton({...deleteColumn, format: 'long'}),
new EditorSeparator(),
new EditorButton(cutColumn),
new EditorButton(copyColumn),
new EditorButton(pasteColumnBefore),
new EditorButton(pasteColumnAfter),
]),
new EditorSeparator(),
new EditorButton({...tableProperties, format: 'long'}),
new EditorButton(clearTableFormatting),
new EditorButton(resizeTableToContents),