Move Notetype buttons to using slots instead of dynamic components

This commit is contained in:
Henrik Giesel 2021-04-27 21:01:44 +02:00
parent 6d6c798ca3
commit 4736b1ce1c
20 changed files with 557 additions and 638 deletions

View file

@ -1,10 +0,0 @@
// 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 ButtonGroupProps {
id: string;
className?: string;
items: ToolbarItem[];
fullWidth?: boolean;
}

View file

@ -3,19 +3,31 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="typescript"> <script lang="typescript">
import type { ToolbarItem } from "./types"; import { setContext, getContext } from "svelte";
import { getContext } from "svelte"; import { nightModeKey, buttonGroupKey } from "./contextKeys";
import { nightModeKey } from "./contextKeys";
export let id: string | undefined = undefined; export let id: string | undefined = undefined;
export let className = ""; let className = "";
export let items: ToolbarItem[];
function filterHidden({ hidden = false, ...props }) { export { className as class };
return props; const nightMode = getContext(nightModeKey);
export let api = {};
let index = 0;
interface ButtonRegistration {
order: number;
} }
const nightMode = getContext(nightModeKey); function registerButton(): ButtonRegistration {
index++;
return { order: index };
}
setContext(buttonGroupKey, Object.assign(api, {
registerButton,
}))
</script> </script>
<style lang="scss"> <style lang="scss">
@ -65,9 +77,5 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:border-overlap-group={!nightMode} class:border-overlap-group={!nightMode}
class:gap-group={nightMode} class:gap-group={nightMode}
div="ltr"> div="ltr">
{#each items as button} <slot />
{#if !button.hidden}
<svelte:component this={button.component} {...filterHidden(button)} />
{/if}
{/each}
</div> </div>

View file

@ -0,0 +1,13 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import { getContext } from "svelte";
import { buttonGroupKey } from "./contextKeys";
const { registerButton } = getContext(buttonGroupKey);
const { order } = registerButton();
</script>
<slot {order} />

View file

@ -21,15 +21,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { Identifier } from "./identifiable"; import type { Identifier } from "./identifiable";
import type { ToolbarItem, IterableToolbarItem } from "./types"; import type { ToolbarItem, IterableToolbarItem } from "./types";
import { setContext } from "svelte"; import { setContext, onMount } from "svelte";
import { disabledKey, nightModeKey } from "./contextKeys"; import { disabledKey, nightModeKey } from "./contextKeys";
import { add, insert, updateRecursive } from "./identifiable"; import { add, insert, updateRecursive } from "./identifiable";
import { showComponent, hideComponent, toggleComponent } from "./hideable"; import { showComponent, hideComponent, toggleComponent } from "./hideable";
import ButtonGroup from "./ButtonGroup.svelte"; import NoteTypeButtons from "./NoteTypeButtons.svelte";
let api = {};
export let buttons: IterableToolbarItem[];
export let menus: ToolbarItem[];
export let nightMode: boolean; export let nightMode: boolean;
setContext(nightModeKey, nightMode); setContext(nightModeKey, nightMode);
@ -41,77 +41,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: style = `--toolbar-size: ${size}px; --toolbar-wrap: ${ $: style = `--toolbar-size: ${size}px; --toolbar-wrap: ${
wraps ? "wrap" : "nowrap" wraps ? "wrap" : "nowrap"
}`; }`;
export function updateButton(
update: (component: ToolbarItem) => ToolbarItem,
...identifiers: Identifier[]
): void {
buttons = updateRecursive(
update,
({ items: buttons } as unknown) as ToolbarItem,
...identifiers
).items as IterableToolbarItem[];
}
export function showButton(...identifiers: Identifier[]): void {
updateButton(showComponent, ...identifiers);
}
export function hideButton(...identifiers: Identifier[]): void {
updateButton(hideComponent, ...identifiers);
}
export function toggleButton(...identifiers: Identifier[]): void {
updateButton(toggleComponent, ...identifiers);
}
export function insertButton(
newButton: ToolbarItem,
...identifiers: Identifier[]
): void {
const initIdentifiers = identifiers.slice(0, -1);
const lastIdentifier = identifiers[identifiers.length - 1];
updateButton(
(component: ToolbarItem) =>
insert(component as IterableToolbarItem, newButton, lastIdentifier),
...initIdentifiers
);
}
export function addButton(
newButton: ToolbarItem,
...identifiers: Identifier[]
): void {
const initIdentifiers = identifiers.slice(0, -1);
const lastIdentifier = identifiers[identifiers.length - 1];
updateButton(
(component: ToolbarItem) =>
add(component as IterableToolbarItem, newButton, lastIdentifier),
...initIdentifiers
);
}
export function updateMenu(
update: (component: ToolbarItem) => ToolbarItem,
...identifiers: Identifier[]
): void {
menus = updateRecursive(
update,
({ items: menus } as unknown) as ToolbarItem,
...identifiers
).items as ToolbarItem[];
}
export function addMenu(newMenu: ToolbarItem, ...identifiers: Identifier[]): void {
const initIdentifiers = identifiers.slice(0, -1);
const lastIdentifier = identifiers[identifiers.length - 1];
updateMenu(
(component: ToolbarItem) =>
add(component as IterableToolbarItem, newMenu, lastIdentifier),
...initIdentifiers
);
}
</script> </script>
<style lang="scss"> <style lang="scss">
@ -126,10 +55,6 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
} }
</style> </style>
<nav {style}> <nav {style} class="pb-1">
{#each menus as menu} <NoteTypeButtons />
<svelte:component this={menu.component} {...menu} />
{/each}
<ButtonGroup items={buttons} className="p-0 mb-1" />
</nav> </nav>

View file

@ -1,11 +0,0 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export interface LabelButtonProps {
id?: string;
className?: string;
label: string;
tooltip: string;
onClick: (event: MouseEvent) => void;
disables?: boolean;
}

View file

@ -4,19 +4,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="typescript"> <script lang="typescript">
import type { Readable } from "svelte/store"; import type { Readable } from "svelte/store";
import ButtonGroupButton from "./ButtonGroupButton.svelte";
import { onMount, createEventDispatcher, getContext } from "svelte"; import { onMount, createEventDispatcher, getContext } from "svelte";
import { disabledKey, nightModeKey } from "./contextKeys"; import { disabledKey, nightModeKey } from "./contextKeys";
import { mergeTooltipAndShortcut } from "./helpers";
export let id: string; export let id: string | undefined;
export let className = ""; export let className = "";
export let tooltip: string | undefined; export let tooltip: string | undefined;
export let shortcutLabel: string | undefined;
export let label: string;
$: title = mergeTooltipAndShortcut(tooltip, shortcutLabel);
export let onClick: (event: MouseEvent) => void;
export let disables = true; export let disables = true;
export let dropdownToggle = false; export let dropdownToggle = false;
@ -56,6 +51,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
@include button.btn-night; @include button.btn-night;
</style> </style>
<ButtonGroupButton let:order={order}>
<button <button
bind:this={buttonRef} bind:this={buttonRef}
{id} {id}
@ -63,11 +59,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
class:dropdown-toggle={dropdownToggle} class:dropdown-toggle={dropdownToggle}
class:btn-day={!nightMode} class:btn-day={!nightMode}
class:btn-night={nightMode} class:btn-night={nightMode}
style={`order: ${order};`}
tabindex="-1" tabindex="-1"
disabled={_disabled} disabled={_disabled}
{title} title={tooltip}
{...extraProps} {...extraProps}
on:click={onClick} on:click
on:mousedown|preventDefault> on:mousedown|preventDefault>
{label} <slot />
</button> </button>
</ButtonGroupButton>

View file

@ -0,0 +1,33 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import { bridgeCommand } from "lib/bridgecommand";
import * as tr from "lib/i18n";
import ButtonGroup from "./ButtonGroup.svelte";
import LabelButton from "./LabelButton.svelte";
import WithShortcut from "./WithShortcut.svelte";
export let api = {};
</script>
<ButtonGroup id="notetype" class="" {api}>
<LabelButton
disables={false}
tooltip={tr.editingCustomizeFields()}
on:click={() => bridgeCommand("fields")}>
{tr.editingFields()}...
</LabelButton>
<WithShortcut shortcut="Control+KeyL" let:createShortcut let:shortcutLabel>
<LabelButton
disables={false}
tooltip={`${tr.editingCustomizeCardTemplates()} (${shortcutLabel})`}
on:click={() => bridgeCommand("cards")}
on:mount={createShortcut}>
{tr.editingCards()}...
</LabelButton>
</WithShortcut>
</ButtonGroup>

View file

@ -1,9 +0,0 @@
// 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 WithShortcutProps {
button: ToolbarItem;
shortcut: string;
optionalModifiers: string[];
}

View file

@ -3,26 +3,16 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
--> -->
<script lang="typescript"> <script lang="typescript">
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
import type { ToolbarItem } from "./types";
import type { Modifier } from "lib/shortcuts"; import type { Modifier } from "lib/shortcuts";
import { onDestroy } from "svelte"; import { onDestroy } from "svelte";
import { registerShortcut, getPlatformString } from "lib/shortcuts"; import { registerShortcut, getPlatformString } from "lib/shortcuts";
export let button: ToolbarItem;
export let shortcut: string; export let shortcut: string;
export let optionalModifiers: Modifier[]; export let optionalModifiers: Modifier[] | undefined = [];
function extend({ ...rest }: DynamicSvelteComponent): DynamicSvelteComponent {
const shortcutLabel = getPlatformString(shortcut); const shortcutLabel = getPlatformString(shortcut);
return {
shortcutLabel,
...rest,
};
}
let deregister: () => void; let deregister: () => void;
function createShortcut({ detail }: CustomEvent): void { function createShortcut({ detail }: CustomEvent): void {
@ -40,7 +30,4 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
onDestroy(() => deregister()); onDestroy(() => deregister());
</script> </script>
<svelte:component <slot {createShortcut} {shortcutLabel} />
this={button.component}
{...extend(button)}
on:mount={createShortcut} />

View file

@ -2,3 +2,5 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export const nightModeKey = Symbol("nightMode"); export const nightModeKey = Symbol("nightMode");
export const disabledKey = Symbol("disabled"); export const disabledKey = Symbol("disabled");
export const buttonGroupKey = Symbol("buttonGroup");

View file

@ -1,8 +1,6 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import RawButton from "./RawButton.svelte"; import RawButton from "./RawButton.svelte";
import LabelButton from "./LabelButton.svelte";
import type { LabelButtonProps } from "./LabelButton";
import IconButton from "./IconButton.svelte"; import IconButton from "./IconButton.svelte";
import type { IconButtonProps } from "./IconButton"; import type { IconButtonProps } from "./IconButton";
import CommandIconButton from "./CommandIconButton.svelte"; import CommandIconButton from "./CommandIconButton.svelte";
@ -11,8 +9,6 @@ import ColorPicker from "./ColorPicker.svelte";
import type { ColorPickerProps } from "./ColorPicker"; import type { ColorPickerProps } from "./ColorPicker";
import SelectButton from "./SelectButton.svelte"; import SelectButton from "./SelectButton.svelte";
import type { SelectButtonProps } from "./SelectButton"; import type { SelectButtonProps } from "./SelectButton";
import ButtonGroup from "./ButtonGroup.svelte";
import type { ButtonGroupProps } from "./ButtonGroup";
import ButtonDropdown from "./ButtonDropdown.svelte"; import ButtonDropdown from "./ButtonDropdown.svelte";
import type { ButtonDropdownProps } from "./ButtonDropdown"; import type { ButtonDropdownProps } from "./ButtonDropdown";
@ -23,9 +19,6 @@ import type { DropdownItemProps } from "./DropdownItem";
import WithDropdownMenu from "./WithDropdownMenu.svelte"; import WithDropdownMenu from "./WithDropdownMenu.svelte";
import type { WithDropdownMenuProps } from "./WithDropdownMenu"; import type { WithDropdownMenuProps } from "./WithDropdownMenu";
import WithShortcut from "./WithShortcut.svelte";
import type { WithShortcutProps } from "./WithShortcut";
import WithLabel from "./WithLabel.svelte"; import WithLabel from "./WithLabel.svelte";
import type { WithLabelProps } from "./WithLabel"; import type { WithLabelProps } from "./WithLabel";
@ -34,9 +27,6 @@ import { dynamicComponent } from "sveltelib/dynamicComponent";
export const rawButton = dynamicComponent<typeof RawButton, { html: string }>( export const rawButton = dynamicComponent<typeof RawButton, { html: string }>(
RawButton RawButton
); );
export const labelButton = dynamicComponent<typeof LabelButton, LabelButtonProps>(
LabelButton
);
export const iconButton = dynamicComponent<typeof IconButton, IconButtonProps>( export const iconButton = dynamicComponent<typeof IconButton, IconButtonProps>(
IconButton IconButton
); );
@ -51,9 +41,6 @@ export const selectButton = dynamicComponent<typeof SelectButton, SelectButtonPr
SelectButton SelectButton
); );
export const buttonGroup = dynamicComponent<typeof ButtonGroup, ButtonGroupProps>(
ButtonGroup
);
export const buttonDropdown = dynamicComponent< export const buttonDropdown = dynamicComponent<
typeof ButtonDropdown, typeof ButtonDropdown,
ButtonDropdownProps ButtonDropdownProps
@ -71,8 +58,4 @@ export const withDropdownMenu = dynamicComponent<
WithDropdownMenuProps WithDropdownMenuProps
>(WithDropdownMenu); >(WithDropdownMenu);
export const withShortcut = dynamicComponent<typeof WithShortcut, WithShortcutProps>(
WithShortcut
);
export const withLabel = dynamicComponent<typeof WithLabel, WithLabelProps>(WithLabel); export const withLabel = dynamicComponent<typeof WithLabel, WithLabelProps>(WithLabel);

View file

@ -1,35 +1,35 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent"; // import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
import { // import {
buttonGroup, // buttonGroup,
rawButton, // rawButton,
labelButton, // labelButton,
iconButton, // iconButton,
commandIconButton, // commandIconButton,
selectButton, // selectButton,
dropdownMenu, // dropdownMenu,
dropdownItem, // dropdownItem,
buttonDropdown, // buttonDropdown,
withDropdownMenu, // withDropdownMenu,
withLabel, // withLabel,
} from "editor-toolbar/dynamicComponents"; // } from "editor-toolbar/dynamicComponents";
export const editorToolbar: Record< // export const editorToolbar: Record<
string, // string,
(props: Record<string, unknown>) => DynamicSvelteComponent // (props: Record<string, unknown>) => DynamicSvelteComponent
> = { // > = {
buttonGroup, // buttonGroup,
rawButton, // rawButton,
labelButton, // labelButton,
iconButton, // iconButton,
commandIconButton, // commandIconButton,
selectButton, // selectButton,
dropdownMenu, // dropdownMenu,
dropdownItem, // dropdownItem,
buttonDropdown, // buttonDropdown,
withDropdownMenu, // withDropdownMenu,
withLabel, // withLabel,
}; // };

View file

@ -1,52 +1,52 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { ToolbarItem } from "editor-toolbar/types"; // import type { ToolbarItem } from "editor-toolbar/types";
import * as tr from "lib/i18n"; // import * as tr from "lib/i18n";
import { iconButton, withShortcut } from "editor-toolbar/dynamicComponents"; // import { iconButton, withShortcut } from "editor-toolbar/dynamicComponents";
import bracketsIcon from "./code-brackets.svg"; // import bracketsIcon from "./code-brackets.svg";
import { forEditorField } from "."; // import { forEditorField } from ".";
import { wrap } from "./wrap"; // import { wrap } from "./wrap";
const clozePattern = /\{\{c(\d+)::/gu; // const clozePattern = /\{\{c(\d+)::/gu;
function getCurrentHighestCloze(increment: boolean): number { // function getCurrentHighestCloze(increment: boolean): number {
let highest = 0; // let highest = 0;
forEditorField([], (field) => { // forEditorField([], (field) => {
const fieldHTML = field.editingArea.editable.fieldHTML; // const fieldHTML = field.editingArea.editable.fieldHTML;
const matches: number[] = []; // const matches: number[] = [];
let match: RegExpMatchArray | null = null; // let match: RegExpMatchArray | null = null;
while ((match = clozePattern.exec(fieldHTML))) { // while ((match = clozePattern.exec(fieldHTML))) {
matches.push(Number(match[1])); // matches.push(Number(match[1]));
} // }
highest = Math.max(highest, ...matches); // highest = Math.max(highest, ...matches);
}); // });
if (increment) { // if (increment) {
highest++; // highest++;
} // }
return Math.max(1, highest); // return Math.max(1, highest);
} // }
function onCloze(event: KeyboardEvent | MouseEvent): void { // function onCloze(event: KeyboardEvent | MouseEvent): void {
const highestCloze = getCurrentHighestCloze(!event.getModifierState("Alt")); // const highestCloze = getCurrentHighestCloze(!event.getModifierState("Alt"));
wrap(`{{c${highestCloze}::`, "}}"); // wrap(`{{c${highestCloze}::`, "}}");
} // }
export function getClozeButton(): ToolbarItem { // export function getClozeButton(): ToolbarItem {
return withShortcut({ // return withShortcut({
id: "cloze", // id: "cloze",
shortcut: "Control+Shift+KeyC", // shortcut: "Control+Shift+KeyC",
optionalModifiers: ["Alt"], // optionalModifiers: ["Alt"],
button: iconButton({ // button: iconButton({
icon: bracketsIcon, // icon: bracketsIcon,
onClick: onCloze, // onClick: onCloze,
tooltip: tr.editingClozeDeletion(), // tooltip: tr.editingClozeDeletion(),
}), // }),
}); // });
} // }

View file

@ -1,54 +1,54 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { IterableToolbarItem } from "editor-toolbar/types"; // import type { IterableToolbarItem } from "editor-toolbar/types";
import { // import {
iconButton, // iconButton,
colorPicker, // colorPicker,
buttonGroup, // buttonGroup,
withShortcut, // withShortcut,
} from "editor-toolbar/dynamicComponents"; // } from "editor-toolbar/dynamicComponents";
import * as tr from "lib/i18n"; // import * as tr from "lib/i18n";
import squareFillIcon from "./square-fill.svg"; // import squareFillIcon from "./square-fill.svg";
import "./color.css"; // import "./color.css";
const foregroundColorKeyword = "--foreground-color"; // const foregroundColorKeyword = "--foreground-color";
function setForegroundColor(color: string): void { // function setForegroundColor(color: string): void {
document.documentElement.style.setProperty(foregroundColorKeyword, color); // document.documentElement.style.setProperty(foregroundColorKeyword, color);
} // }
function getForecolor(): string { // function getForecolor(): string {
return document.documentElement.style.getPropertyValue(foregroundColorKeyword); // return document.documentElement.style.getPropertyValue(foregroundColorKeyword);
} // }
function wrapWithForecolor(color: string): void { // function wrapWithForecolor(color: string): void {
document.execCommand("forecolor", false, color); // document.execCommand("forecolor", false, color);
} // }
export function getColorGroup(): IterableToolbarItem { // export function getColorGroup(): IterableToolbarItem {
const forecolorButton = withShortcut({ // const forecolorButton = withShortcut({
shortcut: "F7", // shortcut: "F7",
button: iconButton({ // button: iconButton({
icon: squareFillIcon, // icon: squareFillIcon,
className: "forecolor", // className: "forecolor",
onClick: () => wrapWithForecolor(getForecolor()), // onClick: () => wrapWithForecolor(getForecolor()),
tooltip: tr.editingSetForegroundColor(), // tooltip: tr.editingSetForegroundColor(),
}), // }),
}); // });
const colorpickerButton = withShortcut({ // const colorpickerButton = withShortcut({
shortcut: "F8", // shortcut: "F8",
button: colorPicker({ // button: colorPicker({
onChange: ({ currentTarget }) => // onChange: ({ currentTarget }) =>
setForegroundColor((currentTarget as HTMLInputElement).value), // setForegroundColor((currentTarget as HTMLInputElement).value),
tooltip: tr.editingChangeColor(), // tooltip: tr.editingChangeColor(),
}), // }),
}); // });
return buttonGroup({ // return buttonGroup({
id: "color", // id: "color",
items: [forecolorButton, colorpickerButton], // items: [forecolorButton, colorpickerButton],
}); // });
} // }

View file

@ -1,129 +1,129 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { IterableToolbarItem } from "editor-toolbar/types"; // import type { IterableToolbarItem } from "editor-toolbar/types";
import type { EditingArea } from "./editingArea"; // import type { EditingArea } from "./editingArea";
import * as tr from "lib/i18n"; // import * as tr from "lib/i18n";
import { // import {
commandIconButton, // commandIconButton,
iconButton, // iconButton,
buttonGroup, // buttonGroup,
buttonDropdown, // buttonDropdown,
withDropdownMenu, // withDropdownMenu,
} from "editor-toolbar/dynamicComponents"; // } from "editor-toolbar/dynamicComponents";
import { getListItem } from "./helpers"; // import { getListItem } from "./helpers";
import ulIcon from "./list-ul.svg"; // import ulIcon from "./list-ul.svg";
import olIcon from "./list-ol.svg"; // import olIcon from "./list-ol.svg";
import listOptionsIcon from "./text-paragraph.svg"; // import listOptionsIcon from "./text-paragraph.svg";
import justifyFullIcon from "./justify.svg"; // import justifyFullIcon from "./justify.svg";
import justifyLeftIcon from "./text-left.svg"; // import justifyLeftIcon from "./text-left.svg";
import justifyRightIcon from "./text-right.svg"; // import justifyRightIcon from "./text-right.svg";
import justifyCenterIcon from "./text-center.svg"; // import justifyCenterIcon from "./text-center.svg";
import indentIcon from "./text-indent-left.svg"; // import indentIcon from "./text-indent-left.svg";
import outdentIcon from "./text-indent-right.svg"; // import outdentIcon from "./text-indent-right.svg";
const outdentListItem = () => { // const outdentListItem = () => {
const currentField = document.activeElement as EditingArea; // const currentField = document.activeElement as EditingArea;
if (getListItem(currentField.shadowRoot!)) { // if (getListItem(currentField.shadowRoot!)) {
document.execCommand("outdent"); // document.execCommand("outdent");
} // }
}; // };
const indentListItem = () => { // const indentListItem = () => {
const currentField = document.activeElement as EditingArea; // const currentField = document.activeElement as EditingArea;
if (getListItem(currentField.shadowRoot!)) { // if (getListItem(currentField.shadowRoot!)) {
document.execCommand("indent"); // document.execCommand("indent");
} // }
}; // };
export function getFormatBlockMenus(): IterableToolbarItem[] { // export function getFormatBlockMenus(): IterableToolbarItem[] {
const justifyLeftButton = commandIconButton({ // const justifyLeftButton = commandIconButton({
icon: justifyLeftIcon, // icon: justifyLeftIcon,
command: "justifyLeft", // command: "justifyLeft",
tooltip: tr.editingAlignLeft(), // tooltip: tr.editingAlignLeft(),
}); // });
const justifyCenterButton = commandIconButton({ // const justifyCenterButton = commandIconButton({
icon: justifyCenterIcon, // icon: justifyCenterIcon,
command: "justifyCenter", // command: "justifyCenter",
tooltip: tr.editingCenter(), // tooltip: tr.editingCenter(),
}); // });
const justifyRightButton = commandIconButton({ // const justifyRightButton = commandIconButton({
icon: justifyRightIcon, // icon: justifyRightIcon,
command: "justifyRight", // command: "justifyRight",
tooltip: tr.editingAlignRight(), // tooltip: tr.editingAlignRight(),
}); // });
const justifyFullButton = commandIconButton({ // const justifyFullButton = commandIconButton({
icon: justifyFullIcon, // icon: justifyFullIcon,
command: "justifyFull", // command: "justifyFull",
tooltip: tr.editingJustify(), // tooltip: tr.editingJustify(),
}); // });
const justifyGroup = buttonGroup({ // const justifyGroup = buttonGroup({
id: "justify", // id: "justify",
items: [ // items: [
justifyLeftButton, // justifyLeftButton,
justifyCenterButton, // justifyCenterButton,
justifyRightButton, // justifyRightButton,
justifyFullButton, // justifyFullButton,
], // ],
}); // });
const outdentButton = iconButton({ // const outdentButton = iconButton({
icon: outdentIcon, // icon: outdentIcon,
onClick: outdentListItem, // onClick: outdentListItem,
tooltip: tr.editingOutdent(), // tooltip: tr.editingOutdent(),
}); // });
const indentButton = iconButton({ // const indentButton = iconButton({
icon: indentIcon, // icon: indentIcon,
onClick: indentListItem, // onClick: indentListItem,
tooltip: tr.editingIndent(), // tooltip: tr.editingIndent(),
}); // });
const indentationGroup = buttonGroup({ // const indentationGroup = buttonGroup({
id: "indentation", // id: "indentation",
items: [outdentButton, indentButton], // items: [outdentButton, indentButton],
}); // });
const formattingOptions = buttonDropdown({ // const formattingOptions = buttonDropdown({
id: "listFormatting", // id: "listFormatting",
items: [justifyGroup, indentationGroup], // items: [justifyGroup, indentationGroup],
}); // });
return [formattingOptions]; // return [formattingOptions];
} // }
export function getFormatBlockGroup(): IterableToolbarItem { // export function getFormatBlockGroup(): IterableToolbarItem {
const ulButton = commandIconButton({ // const ulButton = commandIconButton({
icon: ulIcon, // icon: ulIcon,
command: "insertUnorderedList", // command: "insertUnorderedList",
tooltip: tr.editingUnorderedList(), // tooltip: tr.editingUnorderedList(),
}); // });
const olButton = commandIconButton({ // const olButton = commandIconButton({
icon: olIcon, // icon: olIcon,
command: "insertOrderedList", // command: "insertOrderedList",
tooltip: tr.editingOrderedList(), // tooltip: tr.editingOrderedList(),
}); // });
const listFormattingButton = iconButton({ // const listFormattingButton = iconButton({
icon: listOptionsIcon, // icon: listOptionsIcon,
}); // });
const listFormatting = withDropdownMenu({ // const listFormatting = withDropdownMenu({
button: listFormattingButton, // button: listFormattingButton,
menuId: "listFormatting", // menuId: "listFormatting",
}); // });
return buttonGroup({ // return buttonGroup({
id: "blockFormatting", // id: "blockFormatting",
items: [ulButton, olButton, listFormatting], // items: [ulButton, olButton, listFormatting],
}); // });
} // }

View file

@ -1,88 +1,88 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { IterableToolbarItem } from "editor-toolbar/types"; // import type { IterableToolbarItem } from "editor-toolbar/types";
import * as tr from "lib/i18n"; // import * as tr from "lib/i18n";
import { // import {
commandIconButton, // commandIconButton,
iconButton, // iconButton,
buttonGroup, // buttonGroup,
withShortcut, // withShortcut,
} from "editor-toolbar/dynamicComponents"; // } from "editor-toolbar/dynamicComponents";
import boldIcon from "./type-bold.svg"; // import boldIcon from "./type-bold.svg";
import italicIcon from "./type-italic.svg"; // import italicIcon from "./type-italic.svg";
import underlineIcon from "./type-underline.svg"; // import underlineIcon from "./type-underline.svg";
import superscriptIcon from "./format-superscript.svg"; // import superscriptIcon from "./format-superscript.svg";
import subscriptIcon from "./format-subscript.svg"; // import subscriptIcon from "./format-subscript.svg";
import eraserIcon from "./eraser.svg"; // import eraserIcon from "./eraser.svg";
export function getFormatInlineGroup(): IterableToolbarItem { // export function getFormatInlineGroup(): IterableToolbarItem {
const boldButton = withShortcut({ // const boldButton = withShortcut({
shortcut: "Control+KeyB", // shortcut: "Control+KeyB",
button: commandIconButton({ // button: commandIconButton({
icon: boldIcon, // icon: boldIcon,
tooltip: tr.editingBoldText(), // tooltip: tr.editingBoldText(),
command: "bold", // command: "bold",
}), // }),
}); // });
const italicButton = withShortcut({ // const italicButton = withShortcut({
shortcut: "Control+KeyI", // shortcut: "Control+KeyI",
button: commandIconButton({ // button: commandIconButton({
icon: italicIcon, // icon: italicIcon,
tooltip: tr.editingItalicText(), // tooltip: tr.editingItalicText(),
command: "italic", // command: "italic",
}), // }),
}); // });
const underlineButton = withShortcut({ // const underlineButton = withShortcut({
shortcut: "Control+KeyU", // shortcut: "Control+KeyU",
button: commandIconButton({ // button: commandIconButton({
icon: underlineIcon, // icon: underlineIcon,
tooltip: tr.editingUnderlineText(), // tooltip: tr.editingUnderlineText(),
command: "underline", // command: "underline",
}), // }),
}); // });
const superscriptButton = withShortcut({ // const superscriptButton = withShortcut({
shortcut: "Control+Shift+Equal", // shortcut: "Control+Shift+Equal",
button: commandIconButton({ // button: commandIconButton({
icon: superscriptIcon, // icon: superscriptIcon,
tooltip: tr.editingSuperscript(), // tooltip: tr.editingSuperscript(),
command: "superscript", // command: "superscript",
}), // }),
}); // });
const subscriptButton = withShortcut({ // const subscriptButton = withShortcut({
shortcut: "Control+Equal", // shortcut: "Control+Equal",
button: commandIconButton({ // button: commandIconButton({
icon: subscriptIcon, // icon: subscriptIcon,
tooltip: tr.editingSubscript(), // tooltip: tr.editingSubscript(),
command: "subscript", // command: "subscript",
}), // }),
}); // });
const removeFormatButton = withShortcut({ // const removeFormatButton = withShortcut({
shortcut: "Control+KeyR", // shortcut: "Control+KeyR",
button: iconButton({ // button: iconButton({
icon: eraserIcon, // icon: eraserIcon,
tooltip: tr.editingRemoveFormatting(), // tooltip: tr.editingRemoveFormatting(),
onClick: () => { // onClick: () => {
document.execCommand("removeFormat"); // document.execCommand("removeFormat");
}, // },
}), // }),
}); // });
return buttonGroup({ // return buttonGroup({
id: "inlineFormatting", // id: "inlineFormatting",
items: [ // items: [
boldButton, // boldButton,
italicButton, // italicButton,
underlineButton, // underlineButton,
superscriptButton, // superscriptButton,
subscriptButton, // subscriptButton,
removeFormatButton, // removeFormatButton,
], // ],
}); // });
} // }

View file

@ -20,7 +20,7 @@ export { setNoteId, getNoteId } from "./noteId";
export { saveNow } from "./changeTimer"; export { saveNow } from "./changeTimer";
export { wrap, wrapIntoText } from "./wrap"; export { wrap, wrapIntoText } from "./wrap";
export * from "./addons"; // export * from "./addons";
declare global { declare global {
interface Selection { interface Selection {

View file

@ -1,35 +1,35 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { IterableToolbarItem } from "editor-toolbar/types"; // import type { IterableToolbarItem } from "editor-toolbar/types";
import { bridgeCommand } from "lib/bridgecommand"; // import { bridgeCommand } from "lib/bridgecommand";
import * as tr from "lib/i18n"; // import * as tr from "lib/i18n";
import { // import {
labelButton, // labelButton,
buttonGroup, // buttonGroup,
withShortcut, // withShortcut,
} from "editor-toolbar/dynamicComponents"; // } from "editor-toolbar/dynamicComponents";
export function getNotetypeGroup(): IterableToolbarItem { // export function getNotetypeGroup(): IterableToolbarItem {
const fieldsButton = labelButton({ // const fieldsButton = labelButton({
onClick: () => bridgeCommand("fields"), // onClick: () => bridgeCommand("fields"),
disables: false, // disables: false,
label: `${tr.editingFields()}...`, // label: `${tr.editingFields()}...`,
tooltip: tr.editingCustomizeFields(), // tooltip: tr.editingCustomizeFields(),
}); // });
const cardsButton = withShortcut({ // const cardsButton = withShortcut({
shortcut: "Control+KeyL", // shortcut: "Control+KeyL",
button: labelButton({ // button: labelButton({
onClick: () => bridgeCommand("cards"), // onClick: () => bridgeCommand("cards"),
disables: false, // disables: false,
label: `${tr.editingCards()}...`, // label: `${tr.editingCards()}...`,
tooltip: tr.editingCustomizeCardTemplates(), // tooltip: tr.editingCustomizeCardTemplates(),
}), // }),
}); // });
return buttonGroup({ // return buttonGroup({
id: "notetype", // id: "notetype",
items: [fieldsButton, cardsButton], // items: [fieldsButton, cardsButton],
}); // });
} // }

View file

@ -1,143 +1,143 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { IterableToolbarItem } from "editor-toolbar/types"; // import type { IterableToolbarItem } from "editor-toolbar/types";
import { bridgeCommand } from "lib/bridgecommand"; // import { bridgeCommand } from "lib/bridgecommand";
import { // import {
iconButton, // iconButton,
withDropdownMenu, // withDropdownMenu,
dropdownMenu, // dropdownMenu,
dropdownItem, // dropdownItem,
buttonGroup, // buttonGroup,
withShortcut, // withShortcut,
} from "editor-toolbar/dynamicComponents"; // } from "editor-toolbar/dynamicComponents";
import * as tr from "lib/i18n"; // import * as tr from "lib/i18n";
import { wrap } from "./wrap"; // import { wrap } from "./wrap";
import paperclipIcon from "./paperclip.svg"; // import paperclipIcon from "./paperclip.svg";
import micIcon from "./mic.svg"; // import micIcon from "./mic.svg";
import functionIcon from "./function-variant.svg"; // import functionIcon from "./function-variant.svg";
import xmlIcon from "./xml.svg"; // import xmlIcon from "./xml.svg";
import { getClozeButton } from "./cloze"; // import { getClozeButton } from "./cloze";
function onAttachment(): void { // function onAttachment(): void {
bridgeCommand("attach"); // bridgeCommand("attach");
} // }
function onRecord(): void { // function onRecord(): void {
bridgeCommand("record"); // bridgeCommand("record");
} // }
function onHtmlEdit(): void { // function onHtmlEdit(): void {
bridgeCommand("htmlEdit"); // bridgeCommand("htmlEdit");
} // }
const mathjaxMenuId = "mathjaxMenu"; // const mathjaxMenuId = "mathjaxMenu";
export function getTemplateGroup(): IterableToolbarItem { // export function getTemplateGroup(): IterableToolbarItem {
const attachmentButton = withShortcut({ // const attachmentButton = withShortcut({
shortcut: "F3", // shortcut: "F3",
button: iconButton({ // button: iconButton({
icon: paperclipIcon, // icon: paperclipIcon,
onClick: onAttachment, // onClick: onAttachment,
tooltip: tr.editingAttachPicturesaudiovideo(), // tooltip: tr.editingAttachPicturesaudiovideo(),
}), // }),
}); // });
const recordButton = withShortcut({ // const recordButton = withShortcut({
shortcut: "F5", // shortcut: "F5",
button: iconButton({ // button: iconButton({
icon: micIcon, // icon: micIcon,
onClick: onRecord, // onClick: onRecord,
tooltip: tr.editingRecordAudio(), // tooltip: tr.editingRecordAudio(),
}), // }),
}); // });
const mathjaxButton = iconButton({ // const mathjaxButton = iconButton({
icon: functionIcon, // icon: functionIcon,
}); // });
const mathjaxButtonWithMenu = withDropdownMenu({ // const mathjaxButtonWithMenu = withDropdownMenu({
button: mathjaxButton, // button: mathjaxButton,
menuId: mathjaxMenuId, // menuId: mathjaxMenuId,
}); // });
const htmlButton = withShortcut({ // const htmlButton = withShortcut({
shortcut: "Control+Shift+KeyX", // shortcut: "Control+Shift+KeyX",
button: iconButton({ // button: iconButton({
icon: xmlIcon, // icon: xmlIcon,
onClick: onHtmlEdit, // onClick: onHtmlEdit,
tooltip: tr.editingHtmlEditor(), // tooltip: tr.editingHtmlEditor(),
}), // }),
}); // });
return buttonGroup({ // return buttonGroup({
id: "template", // id: "template",
items: [ // items: [
attachmentButton, // attachmentButton,
recordButton, // recordButton,
getClozeButton(), // getClozeButton(),
mathjaxButtonWithMenu, // mathjaxButtonWithMenu,
htmlButton, // htmlButton,
], // ],
}); // });
} // }
export function getTemplateMenus(): IterableToolbarItem[] { // export function getTemplateMenus(): IterableToolbarItem[] {
const mathjaxMenuItems = [ // const mathjaxMenuItems = [
withShortcut({ // withShortcut({
shortcut: "Control+KeyM, KeyM", // shortcut: "Control+KeyM, KeyM",
button: dropdownItem({ // button: dropdownItem({
onClick: () => wrap("\\(", "\\)"), // onClick: () => wrap("\\(", "\\)"),
label: tr.editingMathjaxInline(), // label: tr.editingMathjaxInline(),
}), // }),
}), // }),
withShortcut({ // withShortcut({
shortcut: "Control+KeyM, KeyE", // shortcut: "Control+KeyM, KeyE",
button: dropdownItem({ // button: dropdownItem({
onClick: () => wrap("\\[", "\\]"), // onClick: () => wrap("\\[", "\\]"),
label: tr.editingMathjaxBlock(), // label: tr.editingMathjaxBlock(),
}), // }),
}), // }),
withShortcut({ // withShortcut({
shortcut: "Control+KeyM, KeyC", // shortcut: "Control+KeyM, KeyC",
button: dropdownItem({ // button: dropdownItem({
onClick: () => wrap("\\(\\ce{", "}\\)"), // onClick: () => wrap("\\(\\ce{", "}\\)"),
label: tr.editingMathjaxChemistry(), // label: tr.editingMathjaxChemistry(),
}), // }),
}), // }),
]; // ];
const latexMenuItems = [ // const latexMenuItems = [
withShortcut({ // withShortcut({
shortcut: "Control+KeyT, KeyT", // shortcut: "Control+KeyT, KeyT",
button: dropdownItem({ // button: dropdownItem({
onClick: () => wrap("[latex]", "[/latex]"), // onClick: () => wrap("[latex]", "[/latex]"),
label: tr.editingLatex(), // label: tr.editingLatex(),
}), // }),
}), // }),
withShortcut({ // withShortcut({
shortcut: "Control+KeyT, KeyE", // shortcut: "Control+KeyT, KeyE",
button: dropdownItem({ // button: dropdownItem({
onClick: () => wrap("[$]", "[/$]"), // onClick: () => wrap("[$]", "[/$]"),
label: tr.editingLatexEquation(), // label: tr.editingLatexEquation(),
}), // }),
}), // }),
withShortcut({ // withShortcut({
shortcut: "Control+KeyT, KeyM", // shortcut: "Control+KeyT, KeyM",
button: dropdownItem({ // button: dropdownItem({
onClick: () => wrap("[$$]", "[/$$]"), // onClick: () => wrap("[$$]", "[/$$]"),
label: tr.editingLatexMathEnv(), // label: tr.editingLatexMathEnv(),
}), // }),
}), // }),
]; // ];
const mathjaxMenu = dropdownMenu({ // const mathjaxMenu = dropdownMenu({
id: mathjaxMenuId, // id: mathjaxMenuId,
items: [...mathjaxMenuItems, ...latexMenuItems], // items: [...mathjaxMenuItems, ...latexMenuItems],
}); // });
return [mathjaxMenu]; // return [mathjaxMenu];
} // }

View file

@ -2,11 +2,11 @@
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { editorToolbar, EditorToolbar } from "editor-toolbar"; import { editorToolbar, EditorToolbar } from "editor-toolbar";
import { getNotetypeGroup } from "./notetype"; // import { getNotetypeGroup } from "./notetype";
import { getFormatInlineGroup } from "./formatInline"; // import { getFormatInlineGroup } from "./formatInline";
import { getFormatBlockGroup, getFormatBlockMenus } from "./formatBlock"; // import { getFormatBlockGroup, getFormatBlockMenus } from "./formatBlock";
import { getColorGroup } from "./color"; // import { getColorGroup } from "./color";
import { getTemplateGroup, getTemplateMenus } from "./template"; // import { getTemplateGroup, getTemplateMenus } from "./template";
export function initToolbar(i18n: Promise<void>) { export function initToolbar(i18n: Promise<void>) {
let toolbarResolve: (value: EditorToolbar) => void; let toolbarResolve: (value: EditorToolbar) => void;
@ -20,14 +20,14 @@ export function initToolbar(i18n: Promise<void>) {
const anchor = document.getElementById("fields")!; const anchor = document.getElementById("fields")!;
const buttons = [ const buttons = [
getNotetypeGroup(), // getNotetypeGroup(),
getFormatInlineGroup(), // getFormatInlineGroup(),
getFormatBlockGroup(), // getFormatBlockGroup(),
getColorGroup(), // getColorGroup(),
getTemplateGroup(), // getTemplateGroup(),
]; ];
const menus = [...getFormatBlockMenus(), ...getTemplateMenus()]; const menus = [/*...getFormatBlockMenus(), ...getTemplateMenus()*/];
toolbarResolve(editorToolbar({ target, anchor, buttons, menus })); toolbarResolve(editorToolbar({ target, anchor, buttons, menus }));
}); });