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",
|
"EditorToolbar",
|
||||||
"lib",
|
"lib",
|
||||||
"//ts/lib",
|
"//ts/lib",
|
||||||
|
"//ts/sveltelib",
|
||||||
"@npm//svelte",
|
"@npm//svelte",
|
||||||
"@npm//svelte2tsx",
|
"@npm//svelte2tsx",
|
||||||
],
|
],
|
||||||
@ -40,9 +41,9 @@ ts_library(
|
|||||||
exclude = ["index.ts"],
|
exclude = ["index.ts"],
|
||||||
),
|
),
|
||||||
deps = [
|
deps = [
|
||||||
"//ts/sveltelib",
|
|
||||||
"//ts/lib",
|
"//ts/lib",
|
||||||
"//ts/lib:backend_proto",
|
"//ts/lib:backend_proto",
|
||||||
|
"//ts/sveltelib",
|
||||||
"//ts:image_module_support",
|
"//ts:image_module_support",
|
||||||
"@npm//svelte",
|
"@npm//svelte",
|
||||||
],
|
],
|
||||||
|
@ -1,10 +1,20 @@
|
|||||||
<script lang="typescript">
|
<script lang="typescript">
|
||||||
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
import type { DynamicSvelteComponent } from "sveltelib/dynamicComponent";
|
||||||
|
|
||||||
|
interface Hidden {
|
||||||
|
hidden: boolean;
|
||||||
|
}
|
||||||
|
|
||||||
export let id;
|
export let id;
|
||||||
export let className = "";
|
export let className = "";
|
||||||
|
export let buttons: DynamicSvelteComponent<Hidden>[];
|
||||||
|
|
||||||
export let buttons: DynamicSvelteComponent[];
|
function filterHidden({
|
||||||
|
hidden,
|
||||||
|
...props
|
||||||
|
}: DynamicSvelteComponent & Hidden): DynamicSvelteComponent {
|
||||||
|
return props;
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss">
|
<style lang="scss">
|
||||||
@ -51,8 +61,10 @@
|
|||||||
|
|
||||||
<ul {id} class={className} {...$$restProps}>
|
<ul {id} class={className} {...$$restProps}>
|
||||||
{#each buttons as button}
|
{#each buttons as button}
|
||||||
<li>
|
{#if !button.hidden}
|
||||||
<svelte:component this={button.component} {...button} />
|
<li>
|
||||||
</li>
|
<svelte:component this={button.component} {...filterHidden(button)} />
|
||||||
|
</li>
|
||||||
|
{/if}
|
||||||
{/each}
|
{/each}
|
||||||
</ul>
|
</ul>
|
||||||
|
@ -79,7 +79,7 @@ const removeFormatButton = commandIconButton<CommandIconButtonProps, "tooltip">(
|
|||||||
const buttonGroup = dynamicComponent(ButtonGroup);
|
const buttonGroup = dynamicComponent(ButtonGroup);
|
||||||
export const formatGroup = buttonGroup<ButtonGroupProps>(
|
export const formatGroup = buttonGroup<ButtonGroupProps>(
|
||||||
{
|
{
|
||||||
id: "color",
|
id: "format",
|
||||||
buttons: [
|
buttons: [
|
||||||
boldButton,
|
boldButton,
|
||||||
italicButton,
|
italicButton,
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
import type { SvelteComponent } from "svelte";
|
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 { writable } from "svelte/store";
|
||||||
|
|
||||||
import EditorToolbarSvelte from "./EditorToolbar.svelte";
|
import EditorToolbarSvelte from "./EditorToolbar.svelte";
|
||||||
@ -18,6 +23,31 @@ export { enableButtons, disableButtons } from "./EditorToolbar.svelte";
|
|||||||
const defaultButtons = [notetypeGroup, formatGroup, colorGroup, templateGroup];
|
const defaultButtons = [notetypeGroup, formatGroup, colorGroup, templateGroup];
|
||||||
const defaultMenus = [...templateMenus];
|
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 {
|
class EditorToolbar extends HTMLElement {
|
||||||
component?: SvelteComponent;
|
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);
|
customElements.define("anki-editor-toolbar", EditorToolbar);
|
||||||
|
@ -60,6 +60,7 @@ const recordButton = iconButton(
|
|||||||
|
|
||||||
const clozeButton = iconButton<IconButtonProps, "tooltip">(
|
const clozeButton = iconButton<IconButtonProps, "tooltip">(
|
||||||
{
|
{
|
||||||
|
id: "cloze",
|
||||||
icon: bracketsIcon,
|
icon: bracketsIcon,
|
||||||
onClick: onCloze,
|
onClick: onCloze,
|
||||||
},
|
},
|
||||||
|
Loading…
Reference in New Issue
Block a user