mirror of
https://github.com/ankitects/anki.git
synced 2025-09-18 14:02:21 -04:00
Add IterableToolbarItem interface for easier typing
This commit is contained in:
parent
7cd779063f
commit
bda99ee0f1
19 changed files with 55 additions and 84 deletions
|
@ -175,7 +175,7 @@ class Editor:
|
|||
f"""
|
||||
$editorToolbar.addButtonGroup({{
|
||||
id: "addons",
|
||||
buttons: [ {righttopbtns_defs} ]
|
||||
items: [ {righttopbtns_defs} ]
|
||||
}});
|
||||
"""
|
||||
if righttopbtns_defs
|
||||
|
|
2
ts/editor-toolbar/ButtonDropdown.d.ts
vendored
2
ts/editor-toolbar/ButtonDropdown.d.ts
vendored
|
@ -5,5 +5,5 @@ import type { ToolbarItem } from "./types";
|
|||
export interface ButtonDropdownProps {
|
||||
id: string;
|
||||
className?: string;
|
||||
buttons: ToolbarItem[];
|
||||
items: ToolbarItem[];
|
||||
}
|
||||
|
|
|
@ -13,7 +13,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
return `dropdown-menu btn-dropdown-menu py-1 mb-0 ${className}`;
|
||||
}
|
||||
|
||||
export let buttons: ToolbarItem[];
|
||||
export let items: ToolbarItem[];
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
@ -24,4 +24,4 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
}
|
||||
</style>
|
||||
|
||||
<ButtonGroup {id} className={extendClassName(className)} {buttons} />
|
||||
<ButtonGroup {id} className={extendClassName(className)} {items} />
|
||||
|
|
2
ts/editor-toolbar/ButtonGroup.d.ts
vendored
2
ts/editor-toolbar/ButtonGroup.d.ts
vendored
|
@ -5,5 +5,5 @@ import type { ToolbarItem } from "./types";
|
|||
export interface ButtonGroupProps {
|
||||
id: string;
|
||||
className?: string;
|
||||
buttons: ToolbarItem[];
|
||||
items: ToolbarItem[];
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
export let id: string | undefined = undefined;
|
||||
export let className = "";
|
||||
export let buttons: ToolbarItem[];
|
||||
export let items: ToolbarItem[];
|
||||
|
||||
function filterHidden({ hidden = false, ...props }) {
|
||||
return props;
|
||||
|
@ -73,7 +73,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</style>
|
||||
|
||||
<ul {id} class={className} class:border-overlap-group={!nightMode}>
|
||||
{#each buttons as button}
|
||||
{#each items as button}
|
||||
{#if !button.hidden}
|
||||
<li class:gap-item={nightMode}>
|
||||
<svelte:component this={button.component} {...filterHidden(button)} />
|
||||
|
|
2
ts/editor-toolbar/DropdownMenu.d.ts
vendored
2
ts/editor-toolbar/DropdownMenu.d.ts
vendored
|
@ -4,5 +4,5 @@ import type { ToolbarItem } from "./types";
|
|||
|
||||
export interface DropdownMenuProps {
|
||||
id: string;
|
||||
menuItems: ToolbarItem[];
|
||||
items: ToolbarItem[];
|
||||
}
|
||||
|
|
|
@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
import { nightModeKey } from "./contextKeys";
|
||||
|
||||
export let id: string;
|
||||
export let menuItems: DynamicSvelteComponent[];
|
||||
export let items: ToolbarItem[];
|
||||
|
||||
const nightMode = getContext<boolean>(nightModeKey);
|
||||
</script>
|
||||
|
@ -27,7 +27,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</style>
|
||||
|
||||
<ul {id} class="dropdown-menu" class:night-mode={nightMode}>
|
||||
{#each menuItems as menuItem}
|
||||
{#each items as menuItem}
|
||||
<li>
|
||||
<svelte:component this={menuItem.component} {...menuItem} />
|
||||
</li>
|
||||
|
|
|
@ -19,16 +19,14 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
|
||||
<script lang="typescript">
|
||||
import type { Readable } from "svelte/store";
|
||||
import type { ToolbarItem } from "./types";
|
||||
import type { ToolbarItem, IterableToolbarItem } from "./types";
|
||||
import { setContext } from "svelte";
|
||||
import { disabledKey, nightModeKey } from "./contextKeys";
|
||||
|
||||
import ButtonGroup from "./ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "./ButtonGroup";
|
||||
|
||||
export let buttons: Readable<
|
||||
(ToolbarItem<typeof ButtonGroup> & ButtonGroupProps)[]
|
||||
>;
|
||||
export let buttons: Readable<IterableToolbarItem>[];
|
||||
export let menus: Readable<ToolbarItem[]>;
|
||||
|
||||
$: _buttons = $buttons;
|
||||
|
@ -77,5 +75,5 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
|||
</div>
|
||||
|
||||
<nav {style}>
|
||||
<ButtonGroup buttons={_buttons} className="mt-0" />
|
||||
<ButtonGroup items={_buttons} className="mt-0" />
|
||||
</nav>
|
||||
|
|
3
ts/editor-toolbar/SelectButton.d.ts
vendored
3
ts/editor-toolbar/SelectButton.d.ts
vendored
|
@ -1,7 +1,5 @@
|
|||
// 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 Option {
|
||||
label: string;
|
||||
value: string;
|
||||
|
@ -12,7 +10,6 @@ export interface SelectButtonProps {
|
|||
id: string;
|
||||
className?: string;
|
||||
tooltip?: string;
|
||||
buttons: ToolbarItem[];
|
||||
disables: boolean;
|
||||
options: Option[];
|
||||
}
|
||||
|
|
|
@ -12,11 +12,9 @@ function normalize<T extends Identifiable>(
|
|||
|
||||
if (typeof idOrIndex === "string") {
|
||||
normalizedIndex = values.findIndex((value) => value.id === idOrIndex);
|
||||
}
|
||||
else if (idOrIndex < 0) {
|
||||
} else if (idOrIndex < 0) {
|
||||
normalizedIndex = values.length + idOrIndex;
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
normalizedIndex = idOrIndex;
|
||||
}
|
||||
|
||||
|
|
|
@ -134,7 +134,7 @@ export class EditorToolbar extends HTMLElement {
|
|||
button: string | number
|
||||
): void {
|
||||
this.updateButtonGroup((foundGroup) => {
|
||||
const foundButton = search(foundGroup.buttons, button);
|
||||
const foundButton = search(foundGroup.items, button);
|
||||
|
||||
if (foundButton) {
|
||||
update(foundButton);
|
||||
|
@ -160,8 +160,8 @@ export class EditorToolbar extends HTMLElement {
|
|||
button: string | number = 0
|
||||
): void {
|
||||
this.updateButtonGroup((component) => {
|
||||
component.buttons = insert(
|
||||
component.buttons as (ToolbarItem & Identifiable)[],
|
||||
component.items = insert(
|
||||
component.items as (ToolbarItem & Identifiable)[],
|
||||
newButton,
|
||||
button
|
||||
);
|
||||
|
@ -174,8 +174,8 @@ export class EditorToolbar extends HTMLElement {
|
|||
button: string | number = -1
|
||||
): void {
|
||||
this.updateButtonGroup((component) => {
|
||||
component.buttons = add(
|
||||
component.buttons as (ToolbarItem & Identifiable)[],
|
||||
component.items = add(
|
||||
component.items as (ToolbarItem & Identifiable)[],
|
||||
newButton,
|
||||
button
|
||||
);
|
||||
|
|
|
@ -3,8 +3,15 @@
|
|||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
import type { SvelteComponentDev } from "svelte/internal";
|
||||
|
||||
interface ToolbarItem<T extends typeof SvelteComponentDev = typeof SvelteComponentDev>
|
||||
extends DynamicSvelteComponent<T> {
|
||||
export interface ToolbarItem<
|
||||
T extends typeof SvelteComponentDev = typeof SvelteComponentDev
|
||||
> extends DynamicSvelteComponent<T> {
|
||||
id?: string;
|
||||
hidden?: boolean;
|
||||
}
|
||||
|
||||
export interface IterableToolbarItem<
|
||||
T extends typeof SvelteComponentDev = typeof SvelteComponentDev
|
||||
> extends ToolbarItem<T> {
|
||||
items: ToolbarItem[];
|
||||
}
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type WithShortcut from "editor-toolbar/WithShortcut.svelte";
|
||||
import type { WithShortcutProps } from "editor-toolbar/WithShortcut";
|
||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
import type { ToolbarItem } from "editor-toolbar/types";
|
||||
|
||||
import * as tr from "lib/i18n";
|
||||
import { iconButton, withShortcut } from "editor-toolbar/dynamicComponents";
|
||||
|
@ -40,8 +38,7 @@ function onCloze(event: KeyboardEvent | MouseEvent): void {
|
|||
wrap(`{{c${highestCloze}::`, "}}");
|
||||
}
|
||||
|
||||
export function getClozeButton(): DynamicSvelteComponent<typeof WithShortcut> &
|
||||
WithShortcutProps {
|
||||
export function getClozeButton(): ToolbarItem {
|
||||
return withShortcut({
|
||||
id: "cloze",
|
||||
shortcut: "Control+Shift+KeyC",
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type ButtonGroup from "editor-toolbar/ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup";
|
||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
import type { IterableToolbarItem } from "editor-toolbar/types";
|
||||
|
||||
import {
|
||||
iconButton,
|
||||
|
@ -29,8 +27,7 @@ function wrapWithForecolor(color: string): void {
|
|||
document.execCommand("forecolor", false, color);
|
||||
}
|
||||
|
||||
export function getColorGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
||||
ButtonGroupProps {
|
||||
export function getColorGroup(): IterableToolbarItem {
|
||||
const forecolorButton = withShortcut({
|
||||
shortcut: "F7",
|
||||
button: iconButton({
|
||||
|
@ -52,6 +49,6 @@ export function getColorGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
|||
|
||||
return buttonGroup({
|
||||
id: "color",
|
||||
buttons: [forecolorButton, colorpickerButton],
|
||||
items: [forecolorButton, colorpickerButton],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,11 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type ButtonGroup from "editor-toolbar/ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup";
|
||||
import type ButtonDropdown from "editor-toolbar/ButtonDropdown.svelte";
|
||||
import type { ButtonDropdownProps } from "editor-toolbar/ButtonDropdown";
|
||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
|
||||
import type { IterableToolbarItem } from "editor-toolbar/types";
|
||||
import type { EditingArea } from "./editingArea";
|
||||
|
||||
import * as tr from "lib/i18n";
|
||||
|
@ -45,8 +40,7 @@ const indentListItem = () => {
|
|||
}
|
||||
};
|
||||
|
||||
export function getFormatBlockMenus(): (DynamicSvelteComponent<typeof ButtonDropdown> &
|
||||
ButtonDropdownProps)[] {
|
||||
export function getFormatBlockMenus(): IterableToolbarItem[] {
|
||||
const justifyLeftButton = commandIconButton({
|
||||
icon: justifyLeftIcon,
|
||||
command: "justifyLeft",
|
||||
|
@ -73,7 +67,7 @@ export function getFormatBlockMenus(): (DynamicSvelteComponent<typeof ButtonDrop
|
|||
|
||||
const justifyGroup = buttonGroup({
|
||||
id: "justify",
|
||||
buttons: [
|
||||
items: [
|
||||
justifyLeftButton,
|
||||
justifyCenterButton,
|
||||
justifyRightButton,
|
||||
|
@ -95,19 +89,18 @@ export function getFormatBlockMenus(): (DynamicSvelteComponent<typeof ButtonDrop
|
|||
|
||||
const indentationGroup = buttonGroup({
|
||||
id: "indentation",
|
||||
buttons: [outdentButton, indentButton],
|
||||
items: [outdentButton, indentButton],
|
||||
});
|
||||
|
||||
const formattingOptions = buttonDropdown({
|
||||
id: "listFormatting",
|
||||
buttons: [justifyGroup, indentationGroup],
|
||||
items: [justifyGroup, indentationGroup],
|
||||
});
|
||||
|
||||
return [formattingOptions];
|
||||
}
|
||||
|
||||
export function getFormatBlockGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
||||
ButtonGroupProps {
|
||||
export function getFormatBlockGroup(): IterableToolbarItem {
|
||||
const ulButton = commandIconButton({
|
||||
icon: ulIcon,
|
||||
command: "insertUnorderedList",
|
||||
|
@ -131,6 +124,6 @@ export function getFormatBlockGroup(): DynamicSvelteComponent<typeof ButtonGroup
|
|||
|
||||
return buttonGroup({
|
||||
id: "blockFormatting",
|
||||
buttons: [ulButton, olButton, listFormatting],
|
||||
items: [ulButton, olButton, listFormatting],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type ButtonGroup from "editor-toolbar/ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup";
|
||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
import type { IterableToolbarItem } from "editor-toolbar/types";
|
||||
|
||||
import * as tr from "lib/i18n";
|
||||
import {
|
||||
|
@ -19,8 +17,7 @@ import superscriptIcon from "./format-superscript.svg";
|
|||
import subscriptIcon from "./format-subscript.svg";
|
||||
import eraserIcon from "./eraser.svg";
|
||||
|
||||
export function getFormatInlineGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
||||
ButtonGroupProps {
|
||||
export function getFormatInlineGroup(): IterableToolbarItem {
|
||||
const boldButton = withShortcut({
|
||||
shortcut: "Control+KeyB",
|
||||
button: commandIconButton({
|
||||
|
@ -79,7 +76,7 @@ export function getFormatInlineGroup(): DynamicSvelteComponent<typeof ButtonGrou
|
|||
|
||||
return buttonGroup({
|
||||
id: "inlineFormatting",
|
||||
buttons: [
|
||||
items: [
|
||||
boldButton,
|
||||
italicButton,
|
||||
underlineButton,
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type ButtonGroup from "editor-toolbar/ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup";
|
||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
import type { IterableToolbarItem } from "editor-toolbar/types";
|
||||
|
||||
import { bridgeCommand } from "lib/bridgecommand";
|
||||
import * as tr from "lib/i18n";
|
||||
|
@ -12,8 +10,7 @@ import {
|
|||
withShortcut,
|
||||
} from "editor-toolbar/dynamicComponents";
|
||||
|
||||
export function getNotetypeGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
||||
ButtonGroupProps {
|
||||
export function getNotetypeGroup(): IterableToolbarItem {
|
||||
const fieldsButton = labelButton({
|
||||
onClick: () => bridgeCommand("fields"),
|
||||
disables: false,
|
||||
|
@ -33,6 +30,6 @@ export function getNotetypeGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
|||
|
||||
return buttonGroup({
|
||||
id: "notetype",
|
||||
buttons: [fieldsButton, cardsButton],
|
||||
items: [fieldsButton, cardsButton],
|
||||
});
|
||||
}
|
||||
|
|
|
@ -1,10 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type DropdownMenu from "editor-toolbar/DropdownMenu.svelte";
|
||||
import type { DropdownMenuProps } from "editor-toolbar/DropdownMenu";
|
||||
import type ButtonGroup from "editor-toolbar/ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup";
|
||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||
import type { IterableToolbarItem } from "editor-toolbar/types";
|
||||
|
||||
import { bridgeCommand } from "lib/bridgecommand";
|
||||
import {
|
||||
|
@ -40,8 +36,7 @@ function onHtmlEdit(): void {
|
|||
|
||||
const mathjaxMenuId = "mathjaxMenu";
|
||||
|
||||
export function getTemplateGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
||||
ButtonGroupProps {
|
||||
export function getTemplateGroup(): IterableToolbarItem {
|
||||
const attachmentButton = withShortcut({
|
||||
shortcut: "F3",
|
||||
button: iconButton({
|
||||
|
@ -80,7 +75,7 @@ export function getTemplateGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
|||
|
||||
return buttonGroup({
|
||||
id: "template",
|
||||
buttons: [
|
||||
items: [
|
||||
attachmentButton,
|
||||
recordButton,
|
||||
getClozeButton(),
|
||||
|
@ -90,8 +85,7 @@ export function getTemplateGroup(): DynamicSvelteComponent<typeof ButtonGroup> &
|
|||
});
|
||||
}
|
||||
|
||||
export function getTemplateMenus(): (DynamicSvelteComponent<typeof DropdownMenu> &
|
||||
DropdownMenuProps)[] {
|
||||
export function getTemplateMenus(): IterableToolbarItem[] {
|
||||
const mathjaxMenuItems = [
|
||||
withShortcut({
|
||||
shortcut: "Control+KeyM, KeyM",
|
||||
|
@ -142,7 +136,7 @@ export function getTemplateMenus(): (DynamicSvelteComponent<typeof DropdownMenu>
|
|||
|
||||
const mathjaxMenu = dropdownMenu({
|
||||
id: mathjaxMenuId,
|
||||
menuItems: [...mathjaxMenuItems, ...latexMenuItems],
|
||||
items: [...mathjaxMenuItems, ...latexMenuItems],
|
||||
});
|
||||
|
||||
return [mathjaxMenu];
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
// Copyright: Ankitects Pty Ltd and contributors
|
||||
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
|
||||
import type { ToolbarItem } from "editor-toolbar/types";
|
||||
import type ButtonGroup from "editor-toolbar/ButtonGroup.svelte";
|
||||
import type { ButtonGroupProps } from "editor-toolbar/ButtonGroup";
|
||||
import type { ToolbarItem, IterableToolbarItem } from "editor-toolbar/types";
|
||||
import type { Writable } from "svelte/store";
|
||||
|
||||
import { getNotetypeGroup } from "./notetype";
|
||||
|
@ -16,10 +14,8 @@ export function initToolbar(i18n: Promise<void>): void {
|
|||
i18n.then(() => {
|
||||
globalThis.$editorToolbar.buttonsPromise.then(
|
||||
(
|
||||
buttons: Writable<
|
||||
(ToolbarItem<typeof ButtonGroup> & ButtonGroupProps)[]
|
||||
>
|
||||
): Writable<(ToolbarItem<typeof ButtonGroup> & ButtonGroupProps)[]> => {
|
||||
buttons: Writable<IterableToolbarItem[]>
|
||||
): Writable<IterableToolbarItem[]> => {
|
||||
buttons.update(() => [
|
||||
getNotetypeGroup(),
|
||||
getFormatInlineGroup(),
|
||||
|
|
Loading…
Reference in a new issue