diff --git a/ts/editor-toolbar/BUILD.bazel b/ts/editor-toolbar/BUILD.bazel index 8d2b2cbc5..b8bf53313 100644 --- a/ts/editor-toolbar/BUILD.bazel +++ b/ts/editor-toolbar/BUILD.bazel @@ -67,6 +67,7 @@ ts_library( copy_bootstrap_icons( name = "bootstrap-icons", icons = [ + # inline formatting "type-bold.svg", "type-italic.svg", "type-underline.svg", @@ -74,6 +75,17 @@ copy_bootstrap_icons( "square-fill.svg", "paperclip.svg", "mic.svg", + + # block formatting + "list-ul.svg", + "list-ol.svg", + "text-paragraph.svg", + "justify.svg", + "text-left.svg", + "text-right.svg", + "text-center.svg", + "text-indent-left.svg", + "text-indent-right.svg", ], ) diff --git a/ts/editor-toolbar/ButtonDropdown.d.ts b/ts/editor-toolbar/ButtonDropdown.d.ts new file mode 100644 index 000000000..ad869013e --- /dev/null +++ b/ts/editor-toolbar/ButtonDropdown.d.ts @@ -0,0 +1,9 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import type { ToolbarItem } from "./types"; + +export interface ButtonDropdownProps { + id: string; + className?: string; + buttons: ToolbarItem[]; +} diff --git a/ts/editor-toolbar/formatBlock.ts b/ts/editor-toolbar/formatBlock.ts new file mode 100644 index 000000000..ac51751c7 --- /dev/null +++ b/ts/editor-toolbar/formatBlock.ts @@ -0,0 +1,63 @@ +// Copyright: Ankitects Pty Ltd and contributors +// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html +import CommandIconButton from "./CommandIconButton.svelte"; +import type { CommandIconButtonProps } from "./CommandIconButton"; +import IconButton from "./IconButton.svelte"; +import type { IconButtonProps } from "./IconButton"; +import ButtonGroup from "./ButtonGroup.svelte"; +import type { ButtonGroupProps } from "./ButtonGroup"; + +import type ButtonDropdown from "./ButtonDropdown.svelte"; +import type { ButtonDropdownProps } from "./ButtonDropdown"; + +import { DynamicSvelteComponent, dynamicComponent } from "sveltelib/dynamicComponent"; +import * as tr from "anki/i18n"; + +import ulIcon from "./list-ul.svg"; +import olIcon from "./list-ol.svg"; +import listOptionsIcon from "./text-paragraph.svg"; + +import justifyIcon from "./justify.svg"; +import justifyLeftIcon from "./text-left.svg"; +import justifyRightIcon from "./text-right.svg"; +import justifyCenterIcon from "./text-center.svg"; + +import indentIcon from "./text-indent-left.svg"; +import outdentIcon from "./text-indent-right.svg"; + +const commandIconButton = dynamicComponent< + typeof CommandIconButton, + CommandIconButtonProps +>(CommandIconButton); +const iconButton = dynamicComponent(IconButton); +const buttonGroup = dynamicComponent(ButtonGroup); + +export function getFormatBlockGroup(): DynamicSvelteComponent & + ButtonGroupProps { + const ulButton = commandIconButton({ + icon: ulIcon, + command: "insertUnorderedList", + tooltip: "Insert unordered list", + }); + + const olButton = commandIconButton({ + icon: olIcon, + command: "insertOrderedList", + tooltip: "Insert ordered list", + }); + + const listFormattingButton = iconButton({ + icon: listOptionsIcon, + tooltip: "More list options", + }); + + return buttonGroup({ + id: "formatInline", + buttons: [ulButton, olButton, listFormattingButton], + }); +} + +export function getFormatBlockMenus(): (DynamicSvelteComponent & + ButtonDropdownProps)[] { + return []; +} diff --git a/ts/editor-toolbar/format.ts b/ts/editor-toolbar/formatInline.ts similarity index 95% rename from ts/editor-toolbar/format.ts rename to ts/editor-toolbar/formatInline.ts index b555f8ae8..4d6f50c3c 100644 --- a/ts/editor-toolbar/format.ts +++ b/ts/editor-toolbar/formatInline.ts @@ -21,7 +21,7 @@ const commandIconButton = dynamicComponent< >(CommandIconButton); const buttonGroup = dynamicComponent(ButtonGroup); -export function getFormatGroup(): DynamicSvelteComponent & +export function getFormatInlineGroup(): DynamicSvelteComponent & ButtonGroupProps { const boldButton = commandIconButton({ icon: boldIcon, @@ -61,7 +61,7 @@ export function getFormatGroup(): DynamicSvelteComponent & }); return buttonGroup({ - id: "format", + id: "formatInline", buttons: [ boldButton, italicButton, diff --git a/ts/editor-toolbar/index.ts b/ts/editor-toolbar/index.ts index 1d6e0f4b0..b411cf8f8 100644 --- a/ts/editor-toolbar/index.ts +++ b/ts/editor-toolbar/index.ts @@ -16,7 +16,8 @@ import { setupI18n, ModuleName } from "anki/i18n"; import "./bootstrap.css"; import { getNotetypeGroup } from "./notetype"; -import { getFormatGroup } from "./format"; +import { getFormatInlineGroup } from "./formatInline"; +import { getFormatBlockGroup, getFormatBlockMenus } from "./formatBlock"; import { getColorGroup } from "./color"; import { getTemplateGroup, getTemplateMenus } from "./template"; import { Identifiable, search, add, insert } from "./identifiable"; @@ -60,11 +61,12 @@ class EditorToolbar extends HTMLElement { setupI18n({ modules: [ModuleName.EDITING] }).then(() => { const buttons = writable([ getNotetypeGroup(), - getFormatGroup(), + getFormatInlineGroup(), + getFormatBlockGroup(), getColorGroup(), getTemplateGroup(), ]); - const menus = writable([...getTemplateMenus()]); + const menus = writable([...getTemplateMenus(), ...getFormatBlockMenus()]); this.component = new EditorToolbarSvelte({ target: this,