mirror of
				https://github.com/BookStackApp/BookStack.git
				synced 2025-11-03 02:13:16 +03:00 
			
		
		
		
	Lexical: Worked on toolbar styling, got format submenu working
This commit is contained in:
		@@ -7,10 +7,12 @@ export class EditorDropdownButton extends EditorContainerUiElement {
 | 
			
		||||
    protected button: EditorButton;
 | 
			
		||||
    protected childItems: EditorUiElement[];
 | 
			
		||||
    protected open: boolean = false;
 | 
			
		||||
    protected showOnHover: boolean = false;
 | 
			
		||||
 | 
			
		||||
    constructor(button: EditorBasicButtonDefinition|EditorButton, children: EditorUiElement[]) {
 | 
			
		||||
    constructor(button: EditorBasicButtonDefinition|EditorButton, showOnHover: boolean, children: EditorUiElement[]) {
 | 
			
		||||
        super(children);
 | 
			
		||||
        this.childItems = children
 | 
			
		||||
        this.childItems = children;
 | 
			
		||||
        this.showOnHover = showOnHover;
 | 
			
		||||
 | 
			
		||||
        if (button instanceof EditorButton) {
 | 
			
		||||
            this.button = button;
 | 
			
		||||
@@ -47,13 +49,15 @@ export class EditorDropdownButton extends EditorContainerUiElement {
 | 
			
		||||
            class: 'editor-dropdown-menu-container',
 | 
			
		||||
        }, [button, menu]);
 | 
			
		||||
 | 
			
		||||
        handleDropdown(button, menu, () => {
 | 
			
		||||
        handleDropdown({toggle : button, menu : menu,
 | 
			
		||||
            showOnHover: this.showOnHover,
 | 
			
		||||
            onOpen : () => {
 | 
			
		||||
            this.open = true;
 | 
			
		||||
            this.getContext().manager.triggerStateUpdateForElement(this.button);
 | 
			
		||||
        }, () => {
 | 
			
		||||
        }, onClose : () => {
 | 
			
		||||
            this.open = false;
 | 
			
		||||
            this.getContext().manager.triggerStateUpdateForElement(this.button);
 | 
			
		||||
        });
 | 
			
		||||
        }});
 | 
			
		||||
 | 
			
		||||
        return wrapper;
 | 
			
		||||
    }
 | 
			
		||||
 
 | 
			
		||||
@@ -20,7 +20,7 @@ export class EditorFormatMenu extends EditorContainerUiElement {
 | 
			
		||||
            class: 'editor-format-menu editor-dropdown-menu-container',
 | 
			
		||||
        }, [toggle, menu]);
 | 
			
		||||
 | 
			
		||||
        handleDropdown(toggle, menu);
 | 
			
		||||
        handleDropdown({toggle : toggle, menu : menu});
 | 
			
		||||
 | 
			
		||||
        return wrapper;
 | 
			
		||||
    }
 | 
			
		||||
@@ -33,6 +33,15 @@ export class EditorFormatMenu extends EditorContainerUiElement {
 | 
			
		||||
                this.updateToggleLabel(child.getLabel());
 | 
			
		||||
                return;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (child instanceof EditorContainerUiElement) {
 | 
			
		||||
                for (const grandchild of child.getChildren()) {
 | 
			
		||||
                    if (grandchild instanceof EditorButton && grandchild.isActive()) {
 | 
			
		||||
                        this.updateToggleLabel(grandchild.getLabel());
 | 
			
		||||
                        return;
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        this.updateToggleLabel(this.trans('Formats'));
 | 
			
		||||
 
 | 
			
		||||
@@ -17,13 +17,14 @@ export class EditorOverflowContainer extends EditorContainerUiElement {
 | 
			
		||||
        this.overflowButton = new EditorDropdownButton({
 | 
			
		||||
            label: 'More',
 | 
			
		||||
            icon: moreHorizontal,
 | 
			
		||||
        }, []);
 | 
			
		||||
        }, false, []);
 | 
			
		||||
        this.addChildren(this.overflowButton);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    protected buildDOM(): HTMLElement {
 | 
			
		||||
        const visibleChildren = this.content.slice(0, this.size);
 | 
			
		||||
        const invisibleChildren = this.content.slice(this.size);
 | 
			
		||||
        const slicePosition = this.content.length > this.size ? this.size - 1 : this.size;
 | 
			
		||||
        const visibleChildren = this.content.slice(0, slicePosition);
 | 
			
		||||
        const invisibleChildren = this.content.slice(slicePosition);
 | 
			
		||||
 | 
			
		||||
        const visibleElements = visibleChildren.map(child => child.getDOMElement());
 | 
			
		||||
        if (invisibleChildren.length > 0) {
 | 
			
		||||
 
 | 
			
		||||
@@ -1,7 +1,16 @@
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
export function handleDropdown(toggle: HTMLElement, menu: HTMLElement, onOpen: Function|undefined = undefined, onClose: Function|undefined = undefined) {
 | 
			
		||||
interface HandleDropdownParams {
 | 
			
		||||
    toggle: HTMLElement;
 | 
			
		||||
    menu: HTMLElement;
 | 
			
		||||
    showOnHover?: boolean,
 | 
			
		||||
    onOpen?: Function | undefined;
 | 
			
		||||
    onClose?: Function | undefined;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
export function handleDropdown(options: HandleDropdownParams) {
 | 
			
		||||
    const {menu, toggle, onClose, onOpen, showOnHover} = options;
 | 
			
		||||
    let clickListener: Function|null = null;
 | 
			
		||||
 | 
			
		||||
    const hide = () => {
 | 
			
		||||
@@ -27,8 +36,13 @@ export function handleDropdown(toggle: HTMLElement, menu: HTMLElement, onOpen: F
 | 
			
		||||
        }
 | 
			
		||||
    };
 | 
			
		||||
 | 
			
		||||
    toggle.addEventListener('click', event => {
 | 
			
		||||
    const toggleShowing = (event: MouseEvent) => {
 | 
			
		||||
        menu.hasAttribute('hidden') ? show() : hide();
 | 
			
		||||
    });
 | 
			
		||||
    };
 | 
			
		||||
    toggle.addEventListener('click', toggleShowing);
 | 
			
		||||
    if (showOnHover) {
 | 
			
		||||
        toggle.addEventListener('mouseenter', toggleShowing);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    menu.addEventListener('mouseleave', hide);
 | 
			
		||||
}
 | 
			
		||||
@@ -21,9 +21,12 @@ import {EditorOverflowContainer} from "./framework/blocks/overflow-container";
 | 
			
		||||
 | 
			
		||||
export function getMainEditorFullToolbar(): EditorContainerUiElement {
 | 
			
		||||
    return new EditorSimpleClassContainer('editor-toolbar-main', [
 | 
			
		||||
 | 
			
		||||
        // History state
 | 
			
		||||
        new EditorOverflowContainer(2, [
 | 
			
		||||
            new EditorButton(undo),
 | 
			
		||||
            new EditorButton(redo),
 | 
			
		||||
        ]),
 | 
			
		||||
 | 
			
		||||
        // Block formats
 | 
			
		||||
        new EditorFormatMenu([
 | 
			
		||||
@@ -33,20 +36,23 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
 | 
			
		||||
            new FormatPreviewButton(el('h5'), h5),
 | 
			
		||||
            new FormatPreviewButton(el('blockquote'), blockquote),
 | 
			
		||||
            new FormatPreviewButton(el('p'), paragraph),
 | 
			
		||||
            new EditorDropdownButton({label: 'Callouts'}, true, [
 | 
			
		||||
                new FormatPreviewButton(el('p', {class: 'callout info'}), infoCallout),
 | 
			
		||||
                new FormatPreviewButton(el('p', {class: 'callout success'}), successCallout),
 | 
			
		||||
                new FormatPreviewButton(el('p', {class: 'callout warning'}), warningCallout),
 | 
			
		||||
                new FormatPreviewButton(el('p', {class: 'callout danger'}), dangerCallout),
 | 
			
		||||
            ]),
 | 
			
		||||
        ]),
 | 
			
		||||
 | 
			
		||||
        // Inline formats
 | 
			
		||||
        new EditorOverflowContainer(6, [
 | 
			
		||||
            new EditorButton(bold),
 | 
			
		||||
            new EditorButton(italic),
 | 
			
		||||
            new EditorButton(underline),
 | 
			
		||||
        new EditorDropdownButton(new EditorColorButton(textColor, 'color'), [
 | 
			
		||||
            new EditorDropdownButton(new EditorColorButton(textColor, 'color'), false, [
 | 
			
		||||
                new EditorColorPicker('color'),
 | 
			
		||||
            ]),
 | 
			
		||||
        new EditorDropdownButton(new EditorColorButton(highlightColor, 'background-color'), [
 | 
			
		||||
            new EditorDropdownButton(new EditorColorButton(highlightColor, 'background-color'), false, [
 | 
			
		||||
                new EditorColorPicker('background-color'),
 | 
			
		||||
            ]),
 | 
			
		||||
            new EditorButton(strikethrough),
 | 
			
		||||
@@ -54,16 +60,19 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
 | 
			
		||||
            new EditorButton(subscript),
 | 
			
		||||
            new EditorButton(code),
 | 
			
		||||
            new EditorButton(clearFormating),
 | 
			
		||||
        ]),
 | 
			
		||||
 | 
			
		||||
        // Lists
 | 
			
		||||
        new EditorOverflowContainer(3, [
 | 
			
		||||
            new EditorButton(bulletList),
 | 
			
		||||
            new EditorButton(numberList),
 | 
			
		||||
            new EditorButton(taskList),
 | 
			
		||||
        ]),
 | 
			
		||||
 | 
			
		||||
        // Insert types
 | 
			
		||||
        new EditorOverflowContainer(6, [
 | 
			
		||||
            new EditorButton(link),
 | 
			
		||||
            new EditorDropdownButton(table, [
 | 
			
		||||
            new EditorDropdownButton(table, false, [
 | 
			
		||||
                new EditorTableCreator(),
 | 
			
		||||
            ]),
 | 
			
		||||
            new EditorButton(image),
 | 
			
		||||
@@ -73,6 +82,7 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
 | 
			
		||||
        ]),
 | 
			
		||||
 | 
			
		||||
        // Meta elements
 | 
			
		||||
        new EditorOverflowContainer(3, [
 | 
			
		||||
            new EditorButton(source),
 | 
			
		||||
            new EditorButton(fullscreen),
 | 
			
		||||
 | 
			
		||||
@@ -88,6 +98,7 @@ export function getMainEditorFullToolbar(): EditorContainerUiElement {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            })
 | 
			
		||||
        ]),
 | 
			
		||||
    ]);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -37,12 +37,13 @@ body.editor-is-fullscreen {
 | 
			
		||||
// Buttons
 | 
			
		||||
.editor-button {
 | 
			
		||||
  font-size: 12px;
 | 
			
		||||
  padding: 4px 6px;
 | 
			
		||||
  padding: 4px;
 | 
			
		||||
  color: #444;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  align-items: center;
 | 
			
		||||
  justify-content: center;
 | 
			
		||||
  margin: 2px;
 | 
			
		||||
}
 | 
			
		||||
.editor-button:hover {
 | 
			
		||||
  background-color: #EEE;
 | 
			
		||||
@@ -67,6 +68,7 @@ body.editor-is-fullscreen {
 | 
			
		||||
  height: 24px;
 | 
			
		||||
  color: inherit;
 | 
			
		||||
  fill: currentColor;
 | 
			
		||||
  display: block;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Containers
 | 
			
		||||
@@ -79,22 +81,60 @@ body.editor-is-fullscreen {
 | 
			
		||||
  box-shadow: 0 0 6px 0 rgba(0, 0, 0, 0.15);
 | 
			
		||||
  z-index: 99;
 | 
			
		||||
  min-width: 120px;
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
}
 | 
			
		||||
.editor-menu-list {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
  align-items: stretch;
 | 
			
		||||
}
 | 
			
		||||
.editor-menu-list > .editor-button {
 | 
			
		||||
.editor-menu-list .editor-button {
 | 
			
		||||
  border-bottom: 0;
 | 
			
		||||
  text-align: start;
 | 
			
		||||
  display: block;
 | 
			
		||||
  width: 100%;
 | 
			
		||||
}
 | 
			
		||||
.editor-menu-list > .editor-dropdown-menu-container .editor-dropdown-menu {
 | 
			
		||||
  inset-inline-start: 100%;
 | 
			
		||||
  top: 0;
 | 
			
		||||
  flex-direction: column;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editor-format-menu-toggle {
 | 
			
		||||
  width: 130px;
 | 
			
		||||
  height: 32px;
 | 
			
		||||
  overflow: hidden;
 | 
			
		||||
  padding-inline: 12px;
 | 
			
		||||
  justify-content: start;
 | 
			
		||||
  background-image: url('data:image/svg+xml;utf8,<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path fill="%23666" d="M7.41 8L12 12.58 16.59 8 18 9.41l-6 6-6-6z"/></svg>');
 | 
			
		||||
  background-repeat: no-repeat;
 | 
			
		||||
  background-position: 98% 50%;
 | 
			
		||||
  background-size: 28px;
 | 
			
		||||
}
 | 
			
		||||
.editor-format-menu .editor-dropdown-menu {
 | 
			
		||||
  min-width: 320px;
 | 
			
		||||
  min-width: 300px;
 | 
			
		||||
  .editor-dropdown-menu {
 | 
			
		||||
    min-width: 220px;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
.editor-format-menu .editor-dropdown-menu .editor-dropdown-menu-container > .editor-button {
 | 
			
		||||
  padding: 8px 10px;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editor-overflow-container {
 | 
			
		||||
  display: flex;
 | 
			
		||||
  border-inline: 1px solid #DDD;
 | 
			
		||||
  padding-inline: 4px;
 | 
			
		||||
  &:first-child {
 | 
			
		||||
    border-inline-start: none;
 | 
			
		||||
  }
 | 
			
		||||
  &:last-child {
 | 
			
		||||
    border-inline-end: none;
 | 
			
		||||
  }
 | 
			
		||||
  + .editor-overflow-container {
 | 
			
		||||
    border-inline-start: none;
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
.editor-context-toolbar {
 | 
			
		||||
@@ -104,6 +144,8 @@ body.editor-is-fullscreen {
 | 
			
		||||
  padding: .2rem;
 | 
			
		||||
  border-radius: 4px;
 | 
			
		||||
  box-shadow: 0 2px 4px 0 rgba(0, 0, 0, 0.12);
 | 
			
		||||
  display: flex;
 | 
			
		||||
  flex-direction: row;
 | 
			
		||||
  &:before {
 | 
			
		||||
    content: '';
 | 
			
		||||
    z-index: -1;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user