Make buttons and button groups easily toggleable through hidden web component
This commit is contained in:
parent
4c273caedb
commit
cbf72c0f05
@ -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",
|
||||
],
|
||||
|
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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);
|
||||
|
@ -60,6 +60,7 @@ const recordButton = iconButton(
|
||||
|
||||
const clozeButton = iconButton<IconButtonProps, "tooltip">(
|
||||
{
|
||||
id: "cloze",
|
||||
icon: bracketsIcon,
|
||||
onClick: onCloze,
|
||||
},
|
||||
|
Loading…
Reference in New Issue
Block a user