Generalize ButtonToolbarItem to SectionItem

This commit is contained in:
Henrik Giesel 2021-05-27 13:55:13 +02:00
parent 4ab0820bbc
commit da076aa48e
8 changed files with 46 additions and 47 deletions

View file

@ -5,12 +5,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="typescript"> <script lang="typescript">
import { setContext } from "svelte"; import { setContext } from "svelte";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import ButtonToolbarItem from "./ButtonToolbarItem.svelte"; import SectionItem from "./SectionItem.svelte";
import type { ButtonGroupRegistration } from "./buttons"; import { sectionKey } from "./contextKeys";
import { buttonToolbarKey } from "./contextKeys";
import type { Identifier } from "./identifier"; import type { Identifier } from "./identifier";
import { insert, add } from "./identifier"; import { insert, add } from "./identifier";
import type { SvelteComponent } from "./registration"; import type { SvelteComponent, Registration } from "./registration";
import { makeInterface } from "./registration"; import { makeInterface } from "./registration";
export let id: string | undefined = undefined; export let id: string | undefined = undefined;
@ -30,7 +29,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
$: style = buttonSize + buttonWrap; $: style = buttonSize + buttonWrap;
function makeRegistration(): ButtonGroupRegistration { function makeRegistration(): Registration {
const detach = writable(false); const detach = writable(false);
return { detach }; return { detach };
} }
@ -38,7 +37,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
const { registerComponent, dynamicItems, getDynamicInterface } = const { registerComponent, dynamicItems, getDynamicInterface } =
makeInterface(makeRegistration); makeInterface(makeRegistration);
setContext(buttonToolbarKey, registerComponent); setContext(sectionKey, registerComponent);
export let api: Record<string, unknown> | undefined = undefined; export let api: Record<string, unknown> | undefined = undefined;
let buttonToolbarRef: HTMLDivElement; let buttonToolbarRef: HTMLDivElement;
@ -81,9 +80,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
> >
<slot /> <slot />
{#each $dynamicItems as item} {#each $dynamicItems as item}
<ButtonToolbarItem id={item[0].id} registration={item[1]}> <SectionItem id={item[0].id} registration={item[1]}>
<svelte:component this={item[0].component} {...item[0].props} /> <svelte:component this={item[0].component} {...item[0].props} />
</ButtonToolbarItem> </SectionItem>
{/each} {/each}
</div> </div>

View file

@ -5,23 +5,21 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<script lang="typescript"> <script lang="typescript">
import Detachable from "components/Detachable.svelte"; import Detachable from "components/Detachable.svelte";
import type { ButtonGroupRegistration } from "./buttons"; import type { Register, Registration } from "./registration";
import type { Register } from "./registration";
import { getContext, hasContext } from "svelte"; import { getContext, hasContext } from "svelte";
import { buttonToolbarKey } from "./contextKeys"; import { sectionKey } from "./contextKeys";
export let id: string | undefined = undefined; export let id: string | undefined = undefined;
export let registration: ButtonGroupRegistration | undefined = undefined; export let registration: Registration | undefined = undefined;
let detached: boolean; let detached: boolean;
if (registration) { if (registration) {
const { detach } = registration; const { detach } = registration;
detach.subscribe((value: boolean) => (detached = value)); detach.subscribe((value: boolean) => (detached = value));
} else if (hasContext(buttonToolbarKey)) { } else if (hasContext(sectionKey)) {
const registerComponent = const registerComponent = getContext<Register<Registration>>(sectionKey);
getContext<Register<ButtonGroupRegistration>>(buttonToolbarKey);
const { detach } = registerComponent(); const { detach } = registerComponent();
detach.subscribe((value: boolean) => (detached = value)); detach.subscribe((value: boolean) => (detached = value));
} else { } else {

View file

@ -1,6 +1,7 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { Writable } from "svelte/store"; import type { Writable } from "svelte/store";
import type { Registration } from "./registration";
export enum ButtonPosition { export enum ButtonPosition {
Standalone, Standalone,
@ -9,11 +10,6 @@ export enum ButtonPosition {
Rightmost, Rightmost,
} }
export interface ButtonRegistration { export interface ButtonRegistration extends Registration {
detach: Writable<boolean>;
position: Writable<ButtonPosition>; position: Writable<ButtonPosition>;
} }
export interface ButtonGroupRegistration {
detach: Writable<boolean>;
}

View file

@ -3,7 +3,7 @@
export const nightModeKey = Symbol("nightMode"); export const nightModeKey = Symbol("nightMode");
export const disabledKey = Symbol("disabled"); export const disabledKey = Symbol("disabled");
export const buttonToolbarKey = Symbol("buttonToolbar"); export const sectionKey = Symbol("section");
export const buttonGroupKey = Symbol("buttonGroup"); export const buttonGroupKey = Symbol("buttonGroup");
export const dropdownKey = Symbol("dropdown"); export const dropdownKey = Symbol("dropdown");
export const modalsKey = Symbol("modals"); export const modalsKey = Symbol("modals");

View file

@ -1,7 +1,7 @@
// Copyright: Ankitects Pty Ltd and contributors // Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html // License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { SvelteComponentTyped } from "svelte/internal"; import type { SvelteComponentTyped } from "svelte/internal";
import type { Readable } from "svelte/store"; import type { Writable, Readable } from "svelte/store";
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import type { Identifier } from "./identifier"; import type { Identifier } from "./identifier";
import { find } from "./identifier"; import { find } from "./identifier";
@ -12,9 +12,13 @@ export interface SvelteComponent {
props: Record<string, unknown> | undefined; props: Record<string, unknown> | undefined;
} }
export type Register<T> = (index?: number, registration?: T) => T; export interface Registration {
detach: Writable<boolean>;
}
export interface RegistrationAPI<T> { export type Register<T extends Registration> = (index?: number, registration?: T) => T;
export interface RegistrationAPI<T extends Registration> {
registerComponent: Register<T>; registerComponent: Register<T>;
items: Readable<T[]>; items: Readable<T[]>;
dynamicItems: Readable<[SvelteComponent, T][]>; dynamicItems: Readable<[SvelteComponent, T][]>;
@ -36,7 +40,9 @@ export function nodeIsElement(node: Node): node is Element {
return node.nodeType === Node.ELEMENT_NODE; return node.nodeType === Node.ELEMENT_NODE;
} }
export function makeInterface<T>(makeRegistration: () => T): RegistrationAPI<T> { export function makeInterface<T extends Registration>(
makeRegistration: () => T
): RegistrationAPI<T> {
const registrations: T[] = []; const registrations: T[] = [];
const items = writable(registrations); const items = writable(registrations);

View file

@ -12,7 +12,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import TextInputModal from "./TextInputModal.svelte"; import TextInputModal from "./TextInputModal.svelte";
import StickyBar from "components/StickyBar.svelte"; import StickyBar from "components/StickyBar.svelte";
import ButtonToolbar from "components/ButtonToolbar.svelte"; import ButtonToolbar from "components/ButtonToolbar.svelte";
import ButtonToolbarItem from "components/ButtonToolbarItem.svelte"; import SectionItem from "components/SectionItem.svelte";
import ButtonGroup from "components/ButtonGroup.svelte"; import ButtonGroup from "components/ButtonGroup.svelte";
import ButtonGroupItem from "components/ButtonGroupItem.svelte"; import ButtonGroupItem from "components/ButtonGroupItem.svelte";
@ -89,7 +89,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<StickyBar> <StickyBar>
<ButtonToolbar class="justify-content-between" size={2.3} wrap={false}> <ButtonToolbar class="justify-content-between" size={2.3} wrap={false}>
<ButtonToolbarItem> <SectionItem>
<ButtonGroup class="flex-grow-1"> <ButtonGroup class="flex-grow-1">
<ButtonGroupItem> <ButtonGroupItem>
<SelectButton class="flex-grow-1" on:change={blur}> <SelectButton class="flex-grow-1" on:change={blur}>
@ -104,15 +104,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</SelectButton> </SelectButton>
</ButtonGroupItem> </ButtonGroupItem>
</ButtonGroup> </ButtonGroup>
</ButtonToolbarItem> </SectionItem>
<ButtonToolbarItem> <SectionItem>
<SaveButton <SaveButton
{state} {state}
on:add={promptToAdd} on:add={promptToAdd}
on:clone={promptToClone} on:clone={promptToClone}
on:rename={promptToRename} on:rename={promptToRename}
/> />
</ButtonToolbarItem> </SectionItem>
</ButtonToolbar> </ButtonToolbar>
</StickyBar> </StickyBar>

View file

@ -33,7 +33,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { isApplePlatform } from "lib/platform"; import { isApplePlatform } from "lib/platform";
import StickyBar from "components/StickyBar.svelte"; import StickyBar from "components/StickyBar.svelte";
import ButtonToolbar from "components/ButtonToolbar.svelte"; import ButtonToolbar from "components/ButtonToolbar.svelte";
import ButtonToolbarItem from "components/ButtonToolbarItem.svelte"; import SectionItem from "components/SectionItem.svelte";
import NoteTypeButtons from "./NoteTypeButtons.svelte"; import NoteTypeButtons from "./NoteTypeButtons.svelte";
import FormatInlineButtons from "./FormatInlineButtons.svelte"; import FormatInlineButtons from "./FormatInlineButtons.svelte";
@ -54,24 +54,24 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
<StickyBar> <StickyBar>
<ButtonToolbar {size} {wrap} api={toolbar}> <ButtonToolbar {size} {wrap} api={toolbar}>
<ButtonToolbarItem id="notetype"> <SectionItem id="notetype">
<NoteTypeButtons api={notetypeButtons} /> <NoteTypeButtons api={notetypeButtons} />
</ButtonToolbarItem> </SectionItem>
<ButtonToolbarItem id="inlineFormatting"> <SectionItem id="inlineFormatting">
<FormatInlineButtons api={formatInlineButtons} /> <FormatInlineButtons api={formatInlineButtons} />
</ButtonToolbarItem> </SectionItem>
<ButtonToolbarItem id="blockFormatting"> <SectionItem id="blockFormatting">
<FormatBlockButtons api={formatBlockButtons} /> <FormatBlockButtons api={formatBlockButtons} />
</ButtonToolbarItem> </SectionItem>
<ButtonToolbarItem id="color"> <SectionItem id="color">
<ColorButtons api={colorButtons} /> <ColorButtons api={colorButtons} />
</ButtonToolbarItem> </SectionItem>
<ButtonToolbarItem id="template"> <SectionItem id="template">
<TemplateButtons api={templateButtons} /> <TemplateButtons api={templateButtons} />
</ButtonToolbarItem> </SectionItem>
</ButtonToolbar> </ButtonToolbar>
</StickyBar> </StickyBar>

View file

@ -10,7 +10,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import ButtonGroupItem from "components/ButtonGroupItem.svelte"; import ButtonGroupItem from "components/ButtonGroupItem.svelte";
import IconButton from "components/IconButton.svelte"; import IconButton from "components/IconButton.svelte";
import ButtonDropdown from "components/ButtonDropdown.svelte"; import ButtonDropdown from "components/ButtonDropdown.svelte";
import ButtonToolbarItem from "components/ButtonToolbarItem.svelte"; import SectionItem from "components/SectionItem.svelte";
import WithDropdownMenu from "components/WithDropdownMenu.svelte"; import WithDropdownMenu from "components/WithDropdownMenu.svelte";
import OnlyEditable from "./OnlyEditable.svelte"; import OnlyEditable from "./OnlyEditable.svelte";
import CommandIconButton from "./CommandIconButton.svelte"; import CommandIconButton from "./CommandIconButton.svelte";
@ -71,7 +71,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</OnlyEditable> </OnlyEditable>
<ButtonDropdown id={menuId}> <ButtonDropdown id={menuId}>
<ButtonToolbarItem id="justify"> <SectionItem id="justify">
<ButtonGroup> <ButtonGroup>
<ButtonGroupItem> <ButtonGroupItem>
<CommandIconButton <CommandIconButton
@ -109,9 +109,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
> >
</ButtonGroupItem> </ButtonGroupItem>
</ButtonGroup> </ButtonGroup>
</ButtonToolbarItem> </SectionItem>
<ButtonToolbarItem id="indentation"> <SectionItem id="indentation">
<ButtonGroup> <ButtonGroup>
<ButtonGroupItem> <ButtonGroupItem>
<OnlyEditable let:disabled> <OnlyEditable let:disabled>
@ -137,7 +137,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
</OnlyEditable> </OnlyEditable>
</ButtonGroupItem> </ButtonGroupItem>
</ButtonGroup> </ButtonGroup>
</ButtonToolbarItem> </SectionItem>
</ButtonDropdown> </ButtonDropdown>
</WithDropdownMenu> </WithDropdownMenu>
</ButtonGroupItem> </ButtonGroupItem>