Switch from lazy loading of properties to wrapping the buttons in a function
This commit is contained in:
parent
d6ad5084f1
commit
b364ae5542
@ -33,14 +33,13 @@ function onCloze(event: MouseEvent): void {
|
|||||||
wrap(`{{c${highestCloze}::`, "}}");
|
wrap(`{{c${highestCloze}::`, "}}");
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconButton = dynamicComponent(IconButton);
|
const iconButton = dynamicComponent<typeof IconButton, IconButtonProps>(IconButton);
|
||||||
export const clozeButton = iconButton<IconButtonProps, "tooltip">(
|
|
||||||
{
|
export function getClozeButton() {
|
||||||
|
return iconButton({
|
||||||
id: "cloze",
|
id: "cloze",
|
||||||
icon: bracketsIcon,
|
icon: bracketsIcon,
|
||||||
onClick: onCloze,
|
onClick: onCloze,
|
||||||
},
|
tooltip: tr.editingClozeDeletionCtrlandshiftandc(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingClozeDeletionCtrlandshiftandc,
|
}
|
||||||
}
|
|
||||||
);
|
|
||||||
|
@ -25,35 +25,27 @@ function wrapWithForecolor(color: string): void {
|
|||||||
document.execCommand("forecolor", false, color);
|
document.execCommand("forecolor", false, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconButton = dynamicComponent(IconButton);
|
const iconButton = dynamicComponent<typeof IconButton, IconButtonProps>(IconButton);
|
||||||
const forecolorButton = iconButton<IconButtonProps, "tooltip">(
|
const colorPicker = dynamicComponent<typeof ColorPicker, ColorPickerProps>(ColorPicker);
|
||||||
{
|
const buttonGroup = dynamicComponent<typeof ButtonGroup, ButtonGroupProps>(ButtonGroup);
|
||||||
|
|
||||||
|
export function getColorGroup() {
|
||||||
|
const forecolorButton = iconButton({
|
||||||
icon: squareFillIcon,
|
icon: squareFillIcon,
|
||||||
className: "forecolor",
|
className: "forecolor",
|
||||||
onClick: () => wrapWithForecolor(getForecolor()),
|
onClick: () => wrapWithForecolor(getForecolor()),
|
||||||
},
|
tooltip: tr.editingSetForegroundColourF7(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingSetForegroundColourF7,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const colorPicker = dynamicComponent(ColorPicker);
|
const colorpickerButton = colorPicker({
|
||||||
const colorpickerButton = colorPicker<ColorPickerProps, "tooltip">(
|
|
||||||
{
|
|
||||||
className: "rainbow",
|
className: "rainbow",
|
||||||
onChange: ({ currentTarget }) =>
|
onChange: ({ currentTarget }) =>
|
||||||
setForegroundColor((currentTarget as HTMLInputElement).value),
|
setForegroundColor((currentTarget as HTMLInputElement).value),
|
||||||
},
|
tooltip: tr.editingChangeColourF8(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingChangeColourF8,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
return buttonGroup({
|
||||||
export const colorGroup = buttonGroup<ButtonGroupProps>(
|
|
||||||
{
|
|
||||||
id: "color",
|
id: "color",
|
||||||
buttons: [forecolorButton, colorpickerButton],
|
buttons: [forecolorButton, colorpickerButton],
|
||||||
},
|
});
|
||||||
{}
|
}
|
||||||
);
|
|
||||||
|
@ -13,72 +13,51 @@ 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";
|
||||||
|
|
||||||
const commandIconButton = dynamicComponent(CommandIconButton);
|
const commandIconButton = dynamicComponent<
|
||||||
|
typeof CommandIconButton,
|
||||||
|
CommandIconButtonProps
|
||||||
|
>(CommandIconButton);
|
||||||
|
const buttonGroup = dynamicComponent<typeof ButtonGroup, ButtonGroupProps>(ButtonGroup);
|
||||||
|
|
||||||
const boldButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
export function getFormatGroup() {
|
||||||
{
|
const boldButton = commandIconButton({
|
||||||
icon: boldIcon,
|
icon: boldIcon,
|
||||||
command: "bold",
|
command: "bold",
|
||||||
},
|
tooltip: tr.editingBoldTextCtrlandb(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingBoldTextCtrlandb,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const italicButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
const italicButton = commandIconButton({
|
||||||
{
|
|
||||||
icon: italicIcon,
|
icon: italicIcon,
|
||||||
command: "italic",
|
command: "italic",
|
||||||
},
|
tooltip: tr.editingItalicTextCtrlandi(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingItalicTextCtrlandi,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const underlineButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
const underlineButton = commandIconButton({
|
||||||
{
|
|
||||||
icon: underlineIcon,
|
icon: underlineIcon,
|
||||||
command: "underline",
|
command: "underline",
|
||||||
},
|
tooltip: tr.editingUnderlineTextCtrlandu(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingUnderlineTextCtrlandu,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const superscriptButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
const superscriptButton = commandIconButton({
|
||||||
{
|
|
||||||
icon: superscriptIcon,
|
icon: superscriptIcon,
|
||||||
command: "superscript",
|
command: "superscript",
|
||||||
},
|
tooltip: tr.editingSuperscriptCtrlandand(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingSuperscriptCtrlandand,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const subscriptButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
const subscriptButton = commandIconButton({
|
||||||
{
|
|
||||||
icon: subscriptIcon,
|
icon: subscriptIcon,
|
||||||
command: "subscript",
|
command: "subscript",
|
||||||
},
|
tooltip: tr.editingSubscriptCtrland(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingSubscriptCtrland,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const removeFormatButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
const removeFormatButton = commandIconButton({
|
||||||
{
|
|
||||||
icon: eraserIcon,
|
icon: eraserIcon,
|
||||||
command: "removeFormat",
|
command: "removeFormat",
|
||||||
activatable: false,
|
activatable: false,
|
||||||
},
|
tooltip: tr.editingRemoveFormattingCtrlandr(),
|
||||||
{
|
});
|
||||||
tooltip: tr.editingRemoveFormattingCtrlandr,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
return buttonGroup({
|
||||||
export const formatGroup = buttonGroup<ButtonGroupProps>(
|
|
||||||
{
|
|
||||||
id: "format",
|
id: "format",
|
||||||
buttons: [
|
buttons: [
|
||||||
boldButton,
|
boldButton,
|
||||||
@ -88,6 +67,5 @@ export const formatGroup = buttonGroup<ButtonGroupProps>(
|
|||||||
subscriptButton,
|
subscriptButton,
|
||||||
removeFormatButton,
|
removeFormatButton,
|
||||||
],
|
],
|
||||||
},
|
});
|
||||||
{}
|
}
|
||||||
);
|
|
||||||
|
@ -5,17 +5,17 @@ import ButtonGroup from "./ButtonGroup.svelte";
|
|||||||
import type { ButtonGroupProps } from "./ButtonGroup";
|
import type { ButtonGroupProps } from "./ButtonGroup";
|
||||||
|
|
||||||
import { dynamicComponent } from "sveltelib/dynamicComponent";
|
import { dynamicComponent } from "sveltelib/dynamicComponent";
|
||||||
import { writable } from "svelte/store";
|
import { Writable, writable } from "svelte/store";
|
||||||
|
|
||||||
import EditorToolbarSvelte from "./EditorToolbar.svelte";
|
import EditorToolbarSvelte from "./EditorToolbar.svelte";
|
||||||
|
|
||||||
import { checkNightMode } from "anki/nightmode";
|
import { checkNightMode } from "anki/nightmode";
|
||||||
import { setupI18n, ModuleName } from "anki/i18n";
|
import { setupI18n, ModuleName } from "anki/i18n";
|
||||||
|
|
||||||
import { notetypeGroup } from "./notetype";
|
import { getNotetypeGroup } from "./notetype";
|
||||||
import { formatGroup } from "./format";
|
import { getFormatGroup } from "./format";
|
||||||
import { colorGroup } from "./color";
|
import { getColorGroup } from "./color";
|
||||||
import { templateGroup, templateMenus } from "./template";
|
import { getTemplateGroup, getTemplateMenus } from "./template";
|
||||||
|
|
||||||
import { Identifiable, search, add, insert } from "./identifiable";
|
import { Identifiable, search, add, insert } from "./identifiable";
|
||||||
|
|
||||||
@ -35,17 +35,26 @@ function toggleComponent(component: Hideable) {
|
|||||||
component.hidden = !component.hidden;
|
component.hidden = !component.hidden;
|
||||||
}
|
}
|
||||||
|
|
||||||
const defaultButtons = [notetypeGroup, formatGroup, colorGroup, templateGroup];
|
const buttonGroup = dynamicComponent<typeof ButtonGroup, ButtonGroupProps>(ButtonGroup);
|
||||||
const defaultMenus = [...templateMenus];
|
|
||||||
|
|
||||||
class EditorToolbar extends HTMLElement {
|
class EditorToolbar extends HTMLElement {
|
||||||
component?: SvelteComponent;
|
component?: SvelteComponent;
|
||||||
|
|
||||||
buttons = writable(defaultButtons);
|
buttons?: Writable<
|
||||||
menus = writable(defaultMenus);
|
(DynamicSvelteComponent<typeof ButtonGroup> & ButtonGroupProps)[]
|
||||||
|
>;
|
||||||
|
menus?: Writable<DynamicSvelteComponent[]>;
|
||||||
|
|
||||||
connectedCallback(): void {
|
connectedCallback(): void {
|
||||||
setupI18n({ modules: [ModuleName.EDITING] }).then(() => {
|
setupI18n({ modules: [ModuleName.EDITING] }).then(() => {
|
||||||
|
this.buttons = writable([
|
||||||
|
getNotetypeGroup(),
|
||||||
|
getFormatGroup(),
|
||||||
|
getColorGroup(),
|
||||||
|
getTemplateGroup(),
|
||||||
|
]);
|
||||||
|
this.menus = writable([...getTemplateMenus()]);
|
||||||
|
|
||||||
this.component = new EditorToolbarSvelte({
|
this.component = new EditorToolbarSvelte({
|
||||||
target: this,
|
target: this,
|
||||||
props: {
|
props: {
|
||||||
@ -58,27 +67,24 @@ class EditorToolbar extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateButtonGroup<T>(
|
updateButtonGroup<T>(
|
||||||
update: (component: DynamicSvelteComponent<typeof ButtonGroup> & T) => void,
|
update: (
|
||||||
|
component: DynamicSvelteComponent<typeof ButtonGroup> & ButtonGroupProps & T
|
||||||
|
) => void,
|
||||||
group: string | number
|
group: string | number
|
||||||
): void {
|
): void {
|
||||||
this.buttons.update(
|
this.buttons?.update((buttonGroups) => {
|
||||||
(
|
const foundGroup = search(buttonGroups, group);
|
||||||
buttonGroups: (DynamicSvelteComponent<typeof ButtonGroup> &
|
|
||||||
ButtonGroupProps)[]
|
|
||||||
) => {
|
|
||||||
const foundGroup = search(buttonGroups, group);
|
|
||||||
|
|
||||||
if (foundGroup) {
|
if (foundGroup) {
|
||||||
update(
|
update(
|
||||||
foundGroup as DynamicSvelteComponent<typeof ButtonGroup> &
|
foundGroup as DynamicSvelteComponent<typeof ButtonGroup> &
|
||||||
ButtonGroupProps &
|
ButtonGroupProps &
|
||||||
T
|
T
|
||||||
);
|
);
|
||||||
}
|
|
||||||
|
|
||||||
return buttonGroups;
|
|
||||||
}
|
}
|
||||||
);
|
|
||||||
|
return buttonGroups;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
showButtonGroup(group: string | number): void {
|
showButtonGroup(group: string | number): void {
|
||||||
@ -94,29 +100,17 @@ class EditorToolbar extends HTMLElement {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insertButtonGroup(newGroup: ButtonGroupProps, group: string | number = 0) {
|
insertButtonGroup(newGroup: ButtonGroupProps, group: string | number = 0) {
|
||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
this.buttons?.update((buttonGroups) => {
|
||||||
this.buttons.update(
|
const newButtonGroup = buttonGroup(newGroup);
|
||||||
(
|
return insert(buttonGroups, newButtonGroup, group);
|
||||||
buttonGroups: (DynamicSvelteComponent<typeof ButtonGroup> &
|
});
|
||||||
ButtonGroupProps)[]
|
|
||||||
) => {
|
|
||||||
const newButtonGroup = buttonGroup<ButtonGroupProps>(newGroup, {});
|
|
||||||
return insert(buttonGroups, newButtonGroup, group);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addButtonGroup(newGroup: ButtonGroupProps, group: string | number = -1) {
|
addButtonGroup(newGroup: ButtonGroupProps, group: string | number = -1) {
|
||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
this.buttons?.update((buttonGroups) => {
|
||||||
this.buttons.update(
|
const newButtonGroup = buttonGroup(newGroup);
|
||||||
(
|
return add(buttonGroups, newButtonGroup, group);
|
||||||
buttonGroups: (DynamicSvelteComponent<typeof ButtonGroup> &
|
});
|
||||||
ButtonGroupProps)[]
|
|
||||||
) => {
|
|
||||||
const newButtonGroup = buttonGroup<ButtonGroupProps>(newGroup, {});
|
|
||||||
return add(buttonGroups, newButtonGroup, group);
|
|
||||||
}
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
updateButton<T>(
|
updateButton<T>(
|
||||||
@ -124,22 +118,16 @@ class EditorToolbar extends HTMLElement {
|
|||||||
group: string | number,
|
group: string | number,
|
||||||
button: string | number
|
button: string | number
|
||||||
): void {
|
): void {
|
||||||
this.updateButtonGroup(
|
this.updateButtonGroup((foundGroup) => {
|
||||||
(
|
const foundButton = search(
|
||||||
foundGroup: DynamicSvelteComponent<typeof ButtonGroup> &
|
foundGroup.buttons as (DynamicSvelteComponent & Identifiable)[],
|
||||||
ButtonGroupProps
|
button
|
||||||
) => {
|
);
|
||||||
const foundButton = search(
|
|
||||||
foundGroup.buttons as (DynamicSvelteComponent & Identifiable)[],
|
|
||||||
button
|
|
||||||
);
|
|
||||||
|
|
||||||
if (foundButton) {
|
if (foundButton) {
|
||||||
update(foundButton as DynamicSvelteComponent & T);
|
update(foundButton as DynamicSvelteComponent & T);
|
||||||
}
|
}
|
||||||
},
|
}, group);
|
||||||
group
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
showButton(group: string | number, button: string | number): void {
|
showButton(group: string | number, button: string | number): void {
|
||||||
@ -159,18 +147,13 @@ class EditorToolbar extends HTMLElement {
|
|||||||
group: string | number,
|
group: string | number,
|
||||||
button: string | number = 0
|
button: string | number = 0
|
||||||
) {
|
) {
|
||||||
this.updateButtonGroup(
|
this.updateButtonGroup((component) => {
|
||||||
(
|
component.buttons = insert(
|
||||||
component: DynamicSvelteComponent<typeof ButtonGroup> & ButtonGroupProps
|
component.buttons as (DynamicSvelteComponent & Identifiable)[],
|
||||||
) => {
|
newButton,
|
||||||
component.buttons = insert(
|
button
|
||||||
component.buttons as (DynamicSvelteComponent & Identifiable)[],
|
);
|
||||||
newButton,
|
}, group);
|
||||||
button
|
|
||||||
);
|
|
||||||
},
|
|
||||||
group
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
addButton(
|
addButton(
|
||||||
@ -178,18 +161,13 @@ class EditorToolbar extends HTMLElement {
|
|||||||
group: string | number,
|
group: string | number,
|
||||||
button: string | number = -1
|
button: string | number = -1
|
||||||
) {
|
) {
|
||||||
this.updateButtonGroup(
|
this.updateButtonGroup((component) => {
|
||||||
(
|
component.buttons = add(
|
||||||
component: DynamicSvelteComponent<typeof ButtonGroup> & ButtonGroupProps
|
component.buttons as (DynamicSvelteComponent & Identifiable)[],
|
||||||
) => {
|
newButton,
|
||||||
component.buttons = add(
|
button
|
||||||
component.buttons as (DynamicSvelteComponent & Identifiable)[],
|
);
|
||||||
newButton,
|
}, group);
|
||||||
button
|
|
||||||
);
|
|
||||||
},
|
|
||||||
group
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,34 +7,26 @@ import { dynamicComponent } from "sveltelib/dynamicComponent";
|
|||||||
import { bridgeCommand } from "anki/bridgecommand";
|
import { bridgeCommand } from "anki/bridgecommand";
|
||||||
import * as tr from "anki/i18n";
|
import * as tr from "anki/i18n";
|
||||||
|
|
||||||
const labelButton = dynamicComponent(LabelButton);
|
const labelButton = dynamicComponent<typeof LabelButton, LabelButtonProps>(LabelButton);
|
||||||
const fieldsButton = labelButton<LabelButtonProps, "label" | "tooltip">(
|
const buttonGroup = dynamicComponent<typeof ButtonGroup, ButtonGroupProps>(ButtonGroup);
|
||||||
{
|
|
||||||
|
export function getNotetypeGroup() {
|
||||||
|
const fieldsButton = labelButton({
|
||||||
onClick: () => bridgeCommand("fields"),
|
onClick: () => bridgeCommand("fields"),
|
||||||
disables: false,
|
disables: false,
|
||||||
},
|
label: `${tr.editingFields()}...`,
|
||||||
{
|
tooltip: tr.editingCustomizeFields(),
|
||||||
label: () => `${tr.editingFields()}...`,
|
});
|
||||||
tooltip: tr.editingCustomizeFields,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const cardsButton = labelButton<LabelButtonProps, "label" | "tooltip">(
|
const cardsButton = labelButton({
|
||||||
{
|
|
||||||
onClick: () => bridgeCommand("cards"),
|
onClick: () => bridgeCommand("cards"),
|
||||||
disables: false,
|
disables: false,
|
||||||
},
|
label: `${tr.editingCards()}...`,
|
||||||
{
|
tooltip: tr.editingCustomizeCardTemplatesCtrlandl(),
|
||||||
label: () => `${tr.editingCards()}...`,
|
});
|
||||||
tooltip: tr.editingCustomizeCardTemplatesCtrlandl,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
return buttonGroup({
|
||||||
export const notetypeGroup = buttonGroup<ButtonGroupProps>(
|
|
||||||
{
|
|
||||||
id: "notetype",
|
id: "notetype",
|
||||||
buttons: [fieldsButton, cardsButton],
|
buttons: [fieldsButton, cardsButton],
|
||||||
},
|
});
|
||||||
{}
|
}
|
||||||
);
|
|
||||||
|
@ -18,7 +18,7 @@ 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 { clozeButton } from "./cloze";
|
import { getClozeButton } from "./cloze";
|
||||||
|
|
||||||
function onAttachment(): void {
|
function onAttachment(): void {
|
||||||
bridgeCommand("attach");
|
bridgeCommand("attach");
|
||||||
@ -32,105 +32,89 @@ function onHtmlEdit(): void {
|
|||||||
bridgeCommand("htmlEdit");
|
bridgeCommand("htmlEdit");
|
||||||
}
|
}
|
||||||
|
|
||||||
const iconButton = dynamicComponent(IconButton);
|
|
||||||
|
|
||||||
const withDropdownMenu = dynamicComponent(WithDropdownMenu);
|
|
||||||
const dropdownMenu = dynamicComponent(DropdownMenu);
|
|
||||||
const dropdownItem = dynamicComponent(DropdownItem);
|
|
||||||
|
|
||||||
const attachmentButton = iconButton<IconButtonProps, "tooltip">(
|
|
||||||
{
|
|
||||||
icon: paperclipIcon,
|
|
||||||
onClick: onAttachment,
|
|
||||||
},
|
|
||||||
{
|
|
||||||
tooltip: tr.editingAttachPicturesaudiovideoF3,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const recordButton = iconButton(
|
|
||||||
{ icon: micIcon, onClick: onRecord },
|
|
||||||
{
|
|
||||||
tooltip: tr.editingRecordAudioF5,
|
|
||||||
}
|
|
||||||
);
|
|
||||||
|
|
||||||
const mathjaxButton = iconButton<Omit<IconButtonProps, "onClick" | "tooltip">>(
|
|
||||||
{
|
|
||||||
icon: functionIcon,
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
const mathjaxMenuId = "mathjaxMenu";
|
const mathjaxMenuId = "mathjaxMenu";
|
||||||
|
|
||||||
const mathjaxMenu = dropdownMenu<DropdownMenuProps>(
|
const iconButton = dynamicComponent<typeof IconButton, IconButtonProps>(IconButton);
|
||||||
{
|
const withDropdownMenu = dynamicComponent<
|
||||||
id: mathjaxMenuId,
|
typeof WithDropdownMenu,
|
||||||
menuItems: [
|
WithDropdownMenuProps
|
||||||
dropdownItem<DropdownItemProps, "label">(
|
>(WithDropdownMenu);
|
||||||
{
|
const dropdownMenu = dynamicComponent<typeof DropdownMenu, DropdownMenuProps>(
|
||||||
// @ts-expect-error
|
DropdownMenu
|
||||||
onClick: () => wrap("\\(", "\\)"),
|
|
||||||
tooltip: "test",
|
|
||||||
endLabel: "test",
|
|
||||||
},
|
|
||||||
{ label: tr.editingMathjaxInline }
|
|
||||||
),
|
|
||||||
dropdownItem<DropdownItemProps, "label">(
|
|
||||||
{
|
|
||||||
// @ts-expect-error
|
|
||||||
onClick: () => wrap("\\[", "\\]"),
|
|
||||||
tooltip: "test",
|
|
||||||
endLabel: "test",
|
|
||||||
},
|
|
||||||
{ label: tr.editingMathjaxBlock }
|
|
||||||
),
|
|
||||||
dropdownItem<DropdownItemProps, "label">(
|
|
||||||
{
|
|
||||||
// @ts-expect-error
|
|
||||||
onClick: () => wrap("\\(\\ce{", "}\\)"),
|
|
||||||
tooltip: "test",
|
|
||||||
endLabel: "test",
|
|
||||||
},
|
|
||||||
{ label: tr.editingMathjaxChemistry }
|
|
||||||
),
|
|
||||||
],
|
|
||||||
},
|
|
||||||
{}
|
|
||||||
);
|
);
|
||||||
|
const dropdownItem = dynamicComponent<typeof DropdownItem, DropdownItemProps>(
|
||||||
|
DropdownItem
|
||||||
|
);
|
||||||
|
const buttonGroup = dynamicComponent<typeof ButtonGroup, ButtonGroupProps>(ButtonGroup);
|
||||||
|
|
||||||
const mathjaxButtonWithMenu = withDropdownMenu<WithDropdownMenuProps>(
|
export function getTemplateGroup() {
|
||||||
{
|
const attachmentButton = iconButton({
|
||||||
|
icon: paperclipIcon,
|
||||||
|
onClick: onAttachment,
|
||||||
|
tooltip: tr.editingAttachPicturesaudiovideoF3(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const recordButton = iconButton({
|
||||||
|
icon: micIcon,
|
||||||
|
onClick: onRecord,
|
||||||
|
tooltip: tr.editingRecordAudioF5(),
|
||||||
|
});
|
||||||
|
|
||||||
|
const mathjaxButton = iconButton({
|
||||||
|
icon: functionIcon,
|
||||||
|
foo: 5,
|
||||||
|
});
|
||||||
|
|
||||||
|
const mathjaxButtonWithMenu = withDropdownMenu({
|
||||||
button: mathjaxButton,
|
button: mathjaxButton,
|
||||||
menuId: mathjaxMenuId,
|
menuId: mathjaxMenuId,
|
||||||
},
|
});
|
||||||
{}
|
|
||||||
);
|
|
||||||
|
|
||||||
const htmlButton = iconButton<IconButtonProps, "tooltip">(
|
const htmlButton = iconButton({
|
||||||
{
|
|
||||||
icon: xmlIcon,
|
icon: xmlIcon,
|
||||||
onClick: onHtmlEdit,
|
onClick: onHtmlEdit,
|
||||||
},
|
|
||||||
{
|
|
||||||
tooltip: tr.editingHtmlEditor,
|
tooltip: tr.editingHtmlEditor,
|
||||||
}
|
});
|
||||||
);
|
|
||||||
|
|
||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
return buttonGroup({
|
||||||
export const templateGroup = buttonGroup<ButtonGroupProps>(
|
|
||||||
{
|
|
||||||
id: "template",
|
id: "template",
|
||||||
buttons: [
|
buttons: [
|
||||||
attachmentButton,
|
attachmentButton,
|
||||||
recordButton,
|
recordButton,
|
||||||
clozeButton,
|
getClozeButton(),
|
||||||
mathjaxButtonWithMenu,
|
mathjaxButtonWithMenu,
|
||||||
htmlButton,
|
htmlButton,
|
||||||
],
|
],
|
||||||
},
|
});
|
||||||
{}
|
}
|
||||||
);
|
|
||||||
|
|
||||||
export const templateMenus = [mathjaxMenu];
|
export function getTemplateMenus() {
|
||||||
|
const mathjaxMenu = dropdownMenu({
|
||||||
|
id: mathjaxMenuId,
|
||||||
|
menuItems: [
|
||||||
|
dropdownItem({
|
||||||
|
// @ts-expect-error
|
||||||
|
onClick: () => wrap("\\(", "\\)"),
|
||||||
|
tooltip: "test",
|
||||||
|
endLabel: "test",
|
||||||
|
label: tr.editingMathjaxInline(),
|
||||||
|
}),
|
||||||
|
dropdownItem({
|
||||||
|
// @ts-expect-error
|
||||||
|
onClick: () => wrap("\\[", "\\]"),
|
||||||
|
tooltip: "test",
|
||||||
|
endLabel: "test",
|
||||||
|
label: tr.editingMathjaxBlock(),
|
||||||
|
}),
|
||||||
|
dropdownItem({
|
||||||
|
// @ts-expect-error
|
||||||
|
onClick: () => wrap("\\(\\ce{", "}\\)"),
|
||||||
|
tooltip: "test",
|
||||||
|
endLabel: "test",
|
||||||
|
label: tr.editingMathjaxChemistry(),
|
||||||
|
}),
|
||||||
|
],
|
||||||
|
});
|
||||||
|
|
||||||
|
return [mathjaxMenu];
|
||||||
|
}
|
||||||
|
@ -6,26 +6,11 @@ export interface DynamicSvelteComponent<
|
|||||||
component: T;
|
component: T;
|
||||||
}
|
}
|
||||||
|
|
||||||
export const dynamicComponent = <Comp extends typeof SvelteComponentDev>(
|
export const dynamicComponent = <
|
||||||
component: Comp
|
Comp extends typeof SvelteComponentDev,
|
||||||
) => <
|
DefaultProps = NonNullable<ConstructorParameters<Comp>[0]["props"]>
|
||||||
Props extends NonNullable<ConstructorParameters<Comp>[0]["props"]>,
|
|
||||||
Lazy extends string = never
|
|
||||||
>(
|
>(
|
||||||
props: Omit<Props, Lazy>,
|
component: Comp
|
||||||
lazyProps: {
|
) => <Props = DefaultProps>(props: Props): DynamicSvelteComponent<Comp> & Props => {
|
||||||
[Property in keyof Pick<Props, Lazy>]: () => Pick<Props, Lazy>[Property];
|
return { component, ...props };
|
||||||
}
|
|
||||||
): DynamicSvelteComponent<Comp> & Props => {
|
|
||||||
const dynamicComponent = { component, ...props };
|
|
||||||
|
|
||||||
for (const property in lazyProps) {
|
|
||||||
const get = lazyProps[property];
|
|
||||||
const propertyDescriptor: TypedPropertyDescriptor<
|
|
||||||
Pick<Props, Lazy>[Extract<keyof Pick<Props, Lazy>, string>]
|
|
||||||
> = { get, enumerable: true };
|
|
||||||
Object.defineProperty(dynamicComponent, property, propertyDescriptor);
|
|
||||||
}
|
|
||||||
|
|
||||||
return dynamicComponent as DynamicSvelteComponent<Comp> & Props;
|
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user