Add Section and SectionItem for the deckoptions

This commit is contained in:
Henrik Giesel 2021-05-27 15:50:49 +02:00
parent da076aa48e
commit c49ad009d0
8 changed files with 132 additions and 34 deletions

View file

@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import { writable } from "svelte/store"; import { writable } from "svelte/store";
import { buttonGroupKey } from "./contextKeys"; import { buttonGroupKey } from "./contextKeys";
import type { Identifier } from "./identifier"; import type { Identifier } from "./identifier";
import { insert, add } from "./identifier"; import { insertElement, appendElement } from "./identifier";
import type { ButtonRegistration } from "./buttons"; import type { ButtonRegistration } from "./buttons";
import { ButtonPosition } from "./buttons"; import { ButtonPosition } from "./buttons";
import type { SvelteComponent } from "./registration"; import type { SvelteComponent } from "./registration";
@ -62,9 +62,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
getDynamicInterface(buttonGroupRef); getDynamicInterface(buttonGroupRef);
const insertButton = (button: SvelteComponent, position: Identifier = 0) => const insertButton = (button: SvelteComponent, position: Identifier = 0) =>
addComponent(button, (added, parent) => insert(added, parent, position)); addComponent(button, (added, parent) =>
insertElement(added, parent, position)
);
const appendButton = (button: SvelteComponent, position: Identifier = -1) => const appendButton = (button: SvelteComponent, position: Identifier = -1) =>
addComponent(button, (added, parent) => add(added, parent, position)); addComponent(button, (added, parent) =>
appendElement(added, parent, position)
);
const showButton = (id: Identifier) => const showButton = (id: Identifier) =>
updateRegistration(({ detach }) => detach.set(false), id); updateRegistration(({ detach }) => detach.set(false), id);

View file

@ -8,7 +8,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import SectionItem from "./SectionItem.svelte"; import SectionItem from "./SectionItem.svelte";
import { sectionKey } from "./contextKeys"; import { sectionKey } from "./contextKeys";
import type { Identifier } from "./identifier"; import type { Identifier } from "./identifier";
import { insert, add } from "./identifier"; import { insertElement, appendElement } from "./identifier";
import type { SvelteComponent, Registration } from "./registration"; import type { SvelteComponent, Registration } from "./registration";
import { makeInterface } from "./registration"; import { makeInterface } from "./registration";
@ -47,9 +47,13 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
getDynamicInterface(buttonToolbarRef); getDynamicInterface(buttonToolbarRef);
const insertGroup = (group: SvelteComponent, position: Identifier = 0) => const insertGroup = (group: SvelteComponent, position: Identifier = 0) =>
addComponent(group, (added, parent) => insert(added, parent, position)); addComponent(group, (added, parent) =>
insertElement(added, parent, position)
);
const appendGroup = (group: SvelteComponent, position: Identifier = -1) => const appendGroup = (group: SvelteComponent, position: Identifier = -1) =>
addComponent(group, (added, parent) => add(added, parent, position)); addComponent(group, (added, parent) =>
appendElement(added, parent, position)
);
const showGroup = (id: Identifier) => const showGroup = (id: Identifier) =>
updateRegistration(({ detach }) => detach.set(false), id); updateRegistration(({ detach }) => detach.set(false), id);

View file

@ -0,0 +1,65 @@
<!--
Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import { setContext } from "svelte";
import { writable } from "svelte/store";
import SectionItem from "./SectionItem.svelte";
import { sectionKey } from "./contextKeys";
import type { Identifier } from "./identifier";
import { insertElement, appendElement } from "./identifier";
import type { SvelteComponent, Registration } from "./registration";
import { makeInterface } from "./registration";
export let id: string | undefined = undefined;
let className: string = "";
export { className as class };
function makeRegistration(): Registration {
const detach = writable(false);
return { detach };
}
const { registerComponent, dynamicItems, getDynamicInterface } =
makeInterface(makeRegistration);
setContext(sectionKey, registerComponent);
export let api: Record<string, never> | undefined = undefined;
let sectionRef: HTMLDivElement;
$: if (sectionRef && api) {
const { addComponent, updateRegistration } = getDynamicInterface(sectionRef);
const insert = (group: SvelteComponent, position: Identifier = 0) =>
addComponent(group, (added, parent) =>
insertElement(added, parent, position)
);
const append = (group: SvelteComponent, position: Identifier = -1) =>
addComponent(group, (added, parent) =>
appendElement(added, parent, position)
);
const show = (id: Identifier) =>
updateRegistration(({ detach }) => detach.set(false), id);
const hide = (id: Identifier) =>
updateRegistration(({ detach }) => detach.set(true), id);
const toggle = (id: Identifier) =>
updateRegistration(
({ detach }) => detach.update((old: boolean): boolean => !old),
id
);
Object.assign(api, { insert, append, show, hide, toggle });
}
</script>
<div bind:this={sectionRef} {id} class={className}>
<slot />
{#each $dynamicItems as item}
<SectionItem id={item[0].id} registration={item[1]}>
<svelte:component this={item[0].component} {...item[0].props} />
</SectionItem>
{/each}
</div>

View file

@ -2,7 +2,7 @@
// 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
export type Identifier = string | number; export type Identifier = string | number;
export function find( export function findElement(
collection: HTMLCollection, collection: HTMLCollection,
idOrIndex: Identifier idOrIndex: Identifier
): [number, Element] | null { ): [number, Element] | null {
@ -34,12 +34,12 @@ export function find(
return result; return result;
} }
export function insert( export function insertElement(
element: Element, element: Element,
collection: Element, collection: Element,
idOrIndex: Identifier idOrIndex: Identifier
): number { ): number {
const match = find(collection.children, idOrIndex); const match = findElement(collection.children, idOrIndex);
if (match) { if (match) {
const [index, reference] = match; const [index, reference] = match;
@ -51,12 +51,12 @@ export function insert(
return -1; return -1;
} }
export function add( export function appendElement(
element: Element, element: Element,
collection: Element, collection: Element,
idOrIndex: Identifier idOrIndex: Identifier
): number { ): number {
const match = find(collection.children, idOrIndex); const match = findElement(collection.children, idOrIndex);
if (match) { if (match) {
const [index, before] = match; const [index, before] = match;
@ -69,12 +69,12 @@ export function add(
return -1; return -1;
} }
export function update( export function updateElement(
f: (element: Element) => void, f: (element: Element) => void,
collection: Element, collection: Element,
idOrIndex: Identifier idOrIndex: Identifier
): number { ): number {
const match = find(collection.children, idOrIndex); const match = findElement(collection.children, idOrIndex);
if (match) { if (match) {
const [index, element] = match; const [index, element] = match;

View file

@ -4,7 +4,7 @@ import type { SvelteComponentTyped } from "svelte/internal";
import type { Writable, 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 { findElement } from "./identifier";
export interface SvelteComponent { export interface SvelteComponent {
component: SvelteComponentTyped; component: SvelteComponentTyped;
@ -98,7 +98,7 @@ export function makeInterface<T extends Registration>(
update: (registration: T) => void, update: (registration: T) => void,
position: Identifier position: Identifier
): void { ): void {
const match = find(elementRef.children, position); const match = findElement(elementRef.children, position);
if (match) { if (match) {
const [index] = match; const [index] = match;

View file

@ -3,6 +3,9 @@ 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
--> -->
<script lang="ts"> <script lang="ts">
import Section from "components/Section.svelte";
import SectionItem from "components/SectionItem.svelte";
import DailyLimits from "./DailyLimits.svelte"; import DailyLimits from "./DailyLimits.svelte";
import DisplayOrder from "./DisplayOrder.svelte"; import DisplayOrder from "./DisplayOrder.svelte";
import NewOptions from "./NewOptions.svelte"; import NewOptions from "./NewOptions.svelte";
@ -14,20 +17,40 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { DeckOptionsState } from "./lib"; import type { DeckOptionsState } from "./lib";
export let state: DeckOptionsState; export let state: DeckOptionsState;
export let options: Record<string, never> | undefined = undefined;
</script> </script>
<div class="outer"> <Section api={options}>
<DailyLimits {state} /> <SectionItem>
<NewOptions {state} /> <DailyLimits {state} />
<LapseOptions {state} /> </SectionItem>
<BuryOptions {state} />
<SectionItem>
<NewOptions {state} />
</SectionItem>
<SectionItem>
<LapseOptions {state} />
</SectionItem>
<SectionItem>
<BuryOptions {state} />
</SectionItem>
{#if state.v3Scheduler} {#if state.v3Scheduler}
<DisplayOrder {state} /> <SectionItem>
<DisplayOrder {state} />
</SectionItem>
{/if} {/if}
<GeneralOptions {state} />
<Addons {state} /> <SectionItem>
<AdvancedOptions {state} /> <GeneralOptions {state} />
</div> </SectionItem>
<SectionItem>
<Addons {state} />
</SectionItem>
<SectionItem>
<AdvancedOptions {state} />
</SectionItem>
</Section>
<style lang="scss"> <style lang="scss">
:global(h2) { :global(h2) {
@ -40,9 +63,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
margin-right: 16px; margin-right: 16px;
margin-bottom: 0.5em; margin-bottom: 0.5em;
} }
.outer { /* .outer { */
// the right margin has an indent to allow for the undo /* // the right margin has an indent to allow for the undo */
// buttons; add the same indent on the left for balance /* // buttons; add the same indent on the left for balance */
padding-left: 16px; /* padding-left: 16px; */
} /* } */
</style> </style>

View file

@ -31,7 +31,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}, },
]; ];
} }
export const options = {};
</script> </script>
<ConfigSelector {state} /> <ConfigSelector {state} />
<ConfigEditor {state} /> <ConfigEditor {state} {options} />

View file

@ -41,15 +41,15 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import ColorButtons from "./ColorButtons.svelte"; import ColorButtons from "./ColorButtons.svelte";
import TemplateButtons from "./TemplateButtons.svelte"; import TemplateButtons from "./TemplateButtons.svelte";
export let size = isApplePlatform() ? 1.6 : 2.0;
export let wrap = true;
export const toolbar = {}; export const toolbar = {};
export const notetypeButtons = {}; export const notetypeButtons = {};
export const formatInlineButtons = {}; export const formatInlineButtons = {};
export const formatBlockButtons = {}; export const formatBlockButtons = {};
export const colorButtons = {}; export const colorButtons = {};
export const templateButtons = {}; export const templateButtons = {};
export let size = isApplePlatform() ? 1.6 : 2.0;
export let wrap = true;
</script> </script>
<StickyBar> <StickyBar>