diff --git a/ts/components/ButtonGroup.svelte b/ts/components/ButtonGroup.svelte
index bad832a90..421f3b107 100644
--- a/ts/components/ButtonGroup.svelte
+++ b/ts/components/ButtonGroup.svelte
@@ -3,32 +3,83 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
@@ -37,48 +88,16 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
div {
display: flex;
justify-items: start;
-
flex-wrap: var(--toolbar-wrap);
padding: calc(var(--toolbar-size) / 10);
margin: 0;
-
- > :global(button),
- > :global(select) {
- border-radius: calc(var(--toolbar-size) / 7.5);
-
- &:not(:nth-of-type(1)) {
- border-top-left-radius: 0;
- border-bottom-left-radius: 0;
- }
-
- &:not(:nth-last-of-type(1)) {
- border-top-right-radius: 0;
- border-bottom-right-radius: 0;
- }
- }
-
- &.border-overlap-group {
- :global(button),
- :global(select) {
- margin-left: -1px;
- }
- }
-
- &.gap-group {
- :global(button),
- :global(select) {
- margin-left: 1px;
- }
- }
}
-
+
+ {#each dynamic as component}
+
+ {/each}
diff --git a/ts/components/ButtonGroupItem.svelte b/ts/components/ButtonGroupItem.svelte
index 1bb1e8f4a..7e886737d 100644
--- a/ts/components/ButtonGroupItem.svelte
+++ b/ts/components/ButtonGroupItem.svelte
@@ -3,11 +3,15 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
-
+
+
+
diff --git a/ts/components/Detachable.svelte b/ts/components/Detachable.svelte
new file mode 100644
index 000000000..d58037b37
--- /dev/null
+++ b/ts/components/Detachable.svelte
@@ -0,0 +1,11 @@
+
+
+
+{#if !detach}
+
+{/if}
diff --git a/ts/components/LabelButton.svelte b/ts/components/LabelButton.svelte
index a999d4b61..a7cd701cf 100644
--- a/ts/components/LabelButton.svelte
+++ b/ts/components/LabelButton.svelte
@@ -4,35 +4,32 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
@@ -45,27 +42,36 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
font-size: calc(var(--toolbar-size) / 2.3);
width: auto;
height: var(--toolbar-size);
+
+ border-radius: calc(var(--toolbar-size) / 7.5);
+
+ &:not(:nth-of-type(1)) {
+ border-top-left-radius: 0;
+ border-bottom-left-radius: 0;
+ }
+
+ &:not(:nth-last-of-type(1)) {
+ border-top-right-radius: 0;
+ border-bottom-right-radius: 0;
+ }
}
@include button.btn-day;
@include button.btn-night;
-
-
-
+
diff --git a/ts/components/StickyBar.svelte b/ts/components/StickyBar.svelte
index e3a9679c8..5f85b8802 100644
--- a/ts/components/StickyBar.svelte
+++ b/ts/components/StickyBar.svelte
@@ -3,7 +3,7 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
diff --git a/ts/components/hideable.ts b/ts/components/hideable.ts
deleted file mode 100644
index 4df9af725..000000000
--- a/ts/components/hideable.ts
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright: Ankitects Pty Ltd and contributors
-// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-interface Hideable {
- hidden?: boolean;
-}
-
-export function showComponent
(component: T): T {
- component.hidden = false;
- return component;
-}
-
-export function hideComponent(component: T): T {
- component.hidden = true;
- return component;
-}
-
-export function toggleComponent(component: T): T {
- component.hidden = !component.hidden;
- return component;
-}
diff --git a/ts/components/identifiable.ts b/ts/components/identifiable.ts
deleted file mode 100644
index f44015d19..000000000
--- a/ts/components/identifiable.ts
+++ /dev/null
@@ -1,92 +0,0 @@
-// Copyright: Ankitects Pty Ltd and contributors
-// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-export interface Identifiable {
- id?: string;
-}
-
-interface IterableIdentifiable extends Identifiable {
- items: T[];
-}
-
-export type Identifier = string | number;
-
-function normalize(
- iterable: IterableIdentifiable,
- idOrIndex: Identifier
-): number {
- let normalizedIndex: number;
-
- if (typeof idOrIndex === "string") {
- normalizedIndex = iterable.items.findIndex((value) => value.id === idOrIndex);
- } else if (idOrIndex < 0) {
- normalizedIndex = iterable.items.length + idOrIndex;
- } else {
- normalizedIndex = idOrIndex;
- }
-
- return normalizedIndex >= iterable.items.length ? -1 : normalizedIndex;
-}
-
-function search(values: T[], index: number): T | null {
- return index >= 0 ? values[index] : null;
-}
-
-export function insert(
- iterable: IterableIdentifiable & T,
- value: T,
- idOrIndex: Identifier
-): IterableIdentifiable & T {
- const index = normalize(iterable, idOrIndex);
-
- if (index >= 0) {
- iterable.items = iterable.items.slice();
- iterable.items.splice(index, 0, value);
- }
-
- return iterable;
-}
-
-export function add(
- iterable: IterableIdentifiable & T,
- value: T,
- idOrIndex: Identifier
-): IterableIdentifiable & T {
- const index = normalize(iterable, idOrIndex);
-
- if (index >= 0) {
- iterable.items = iterable.items.slice();
- iterable.items.splice(index + 1, 0, value);
- }
-
- return iterable;
-}
-
-function isRecursive(component: Identifiable): component is IterableIdentifiable {
- return Boolean(Object.prototype.hasOwnProperty.call(component, "items"));
-}
-
-export function updateRecursive(
- update: (component: T) => T,
- component: T,
- ...identifiers: Identifier[]
-): T {
- if (identifiers.length === 0) {
- return update(component);
- } else if (isRecursive(component)) {
- const [identifier, ...restIdentifiers] = identifiers;
- const normalizedIndex = normalize(component, identifier);
- const foundComponent = search(component.items, normalizedIndex);
-
- if (foundComponent) {
- component.items[normalizedIndex] = updateRecursive(
- update,
- foundComponent as T,
- ...restIdentifiers
- );
- }
-
- return component;
- }
-
- return component;
-}
diff --git a/ts/components/identifier.ts b/ts/components/identifier.ts
new file mode 100644
index 000000000..7d29362c6
--- /dev/null
+++ b/ts/components/identifier.ts
@@ -0,0 +1,55 @@
+// Copyright: Ankitects Pty Ltd and contributors
+// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
+export type Identifier = string | number;
+
+function find(collection: HTMLCollection, idOrIndex: Identifier): Element | null {
+ let element: Element | null = null;
+
+ if (typeof idOrIndex === "string") {
+ element = collection.namedItem(idOrIndex);
+ } else if (idOrIndex < 0) {
+ const normalizedIndex = collection.length + idOrIndex;
+ element = collection.item(normalizedIndex);
+ } else {
+ element = collection.item(idOrIndex);
+ }
+
+ return element;
+}
+
+export function insert(
+ element: Element,
+ collection: Element,
+ idOrIndex: Identifier
+): void {
+ const reference = find(collection.children, idOrIndex);
+
+ if (reference) {
+ collection.insertBefore(element, reference);
+ }
+}
+
+export function add(
+ element: Element,
+ collection: Element,
+ idOrIndex: Identifier
+): void {
+ const before = find(collection.children, idOrIndex);
+
+ if (before) {
+ const reference = before.nextElementSibling ?? null;
+ collection.insertBefore(element, reference);
+ }
+}
+
+export function update(
+ f: (element: Element) => void,
+ collection: Element,
+ idOrIndex: Identifier
+): void {
+ const element = find(collection.children, idOrIndex);
+
+ if (element) {
+ f(element);
+ }
+}
diff --git a/ts/editor/EditorToolbar.svelte b/ts/editor/EditorToolbar.svelte
index 217475d15..09bbccdc5 100644
--- a/ts/editor/EditorToolbar.svelte
+++ b/ts/editor/EditorToolbar.svelte
@@ -25,6 +25,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export function clearActiveButtons() {
resetAllState(false);
}
+
+ /* Export components */
+ import LabelButton from "components/LabelButton.svelte";
+ import IconButton from "components/IconButton.svelte";
+
+ export const editorToolbar = { LabelButton, IconButton };