Make buttons and button groups easily toggleable through hidden web component

This commit is contained in:
Henrik Giesel 2021-04-08 22:11:50 +02:00
parent 4c273caedb
commit cbf72c0f05
5 changed files with 121 additions and 6 deletions

View File

@ -28,6 +28,7 @@ ts_library(
"EditorToolbar",
"lib",
"//ts/lib",
"//ts/sveltelib",
"@npm//svelte",
"@npm//svelte2tsx",
],
@ -40,9 +41,9 @@ ts_library(
exclude = ["index.ts"],
),
deps = [
"//ts/sveltelib",
"//ts/lib",
"//ts/lib:backend_proto",
"//ts/sveltelib",
"//ts:image_module_support",
"@npm//svelte",
],

View File

@ -1,10 +1,20 @@
<script lang="typescript">
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
interface Hidden {
hidden: boolean;
}
export let id;
export let className = "";
export let buttons: DynamicSvelteComponent<Hidden>[];
export let buttons: DynamicSvelteComponent[];
function filterHidden({
hidden,
...props
}: DynamicSvelteComponent & Hidden): DynamicSvelteComponent {
return props;
}
</script>
<style lang="scss">
@ -51,8 +61,10 @@
<ul {id} class={className} {...$$restProps}>
{#each buttons as button}
<li>
<svelte:component this={button.component} {...button} />
</li>
{#if !button.hidden}
<li>
<svelte:component this={button.component} {...filterHidden(button)} />
</li>
{/if}
{/each}
</ul>

View File

@ -79,7 +79,7 @@ const removeFormatButton = commandIconButton<CommandIconButtonProps, "tooltip">(
const buttonGroup = dynamicComponent(ButtonGroup);
export const formatGroup = buttonGroup<ButtonGroupProps>(
{
id: "color",
id: "format",
buttons: [
boldButton,
italicButton,

View File

@ -1,4 +1,9 @@
import type { SvelteComponent } from "svelte";
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
import type ButtonGroup from "./ButtonGroup.svelte";
import type { ButtonGroupProps } from "./ButtonGroup";
import { writable } from "svelte/store";
import EditorToolbarSvelte from "./EditorToolbar.svelte";
@ -18,6 +23,31 @@ export { enableButtons, disableButtons } from "./EditorToolbar.svelte";
const defaultButtons = [notetypeGroup, formatGroup, colorGroup, templateGroup];
const defaultMenus = [...templateMenus];
interface Hideable {
hidden?: boolean;
}
function searchByIdOrIndex<T extends { id?: string }>(
values: T[],
idOrIndex: string | number
): T | undefined {
return typeof idOrIndex === "string"
? values.find((value) => value.id === idOrIndex)
: values[idOrIndex];
}
function hideComponent(component: Hideable) {
component.hidden = false;
}
function showComponent(component: Hideable) {
component.hidden = true;
}
function toggleComponent(component: Hideable) {
component.hidden = !component.hidden;
}
class EditorToolbar extends HTMLElement {
component?: SvelteComponent;
@ -36,6 +66,77 @@ class EditorToolbar extends HTMLElement {
});
});
}
updateButtonGroup<T>(
update: (component: DynamicSvelteComponent<typeof ButtonGroup> & T) => void,
group: string | number
): void {
this.buttons.update(
(
buttonGroups: (DynamicSvelteComponent<typeof ButtonGroup> &
ButtonGroupProps)[]
) => {
const foundGroup = searchByIdOrIndex(buttonGroups, group);
if (foundGroup) {
update(
foundGroup as DynamicSvelteComponent<typeof ButtonGroup> &
ButtonGroupProps &
T
);
}
return buttonGroups;
}
);
}
showButtonGroup(group: string | number): void {
this.updateButtonGroup<Hideable>(showComponent, group);
}
hideButtonGroup(group: string | number): void {
this.updateButtonGroup<Hideable>(hideComponent, group);
}
toggleButtonGroup(group: string | number): void {
this.updateButtonGroup<Hideable>(toggleComponent, group);
}
updateButton<T>(
update: (component: DynamicSvelteComponent & T) => void,
group: string | number,
button: string | number
): void {
this.updateButtonGroup(
(
foundGroup: DynamicSvelteComponent<typeof ButtonGroup> &
ButtonGroupProps
) => {
const foundButton = searchByIdOrIndex(
foundGroup.buttons as (DynamicSvelteComponent & { id?: string })[],
button
);
if (foundButton) {
update(foundButton as DynamicSvelteComponent & T);
}
},
group
);
}
showButton(group: string | number, button: string | number): void {
this.updateButton<Hideable>(showComponent, group, button);
}
hideButton(group: string | number, button: string | number): void {
this.updateButton<Hideable>(hideComponent, group, button);
}
toggleButton(group: string | number, button: string | number): void {
this.updateButton<Hideable>(toggleComponent, group, button);
}
}
customElements.define("anki-editor-toolbar", EditorToolbar);

View File

@ -60,6 +60,7 @@ const recordButton = iconButton(
const clozeButton = iconButton<IconButtonProps, "tooltip">(
{
id: "cloze",
icon: bracketsIcon,
onClick: onCloze,
},