Set ButtonPosition via ButtonGroupItem

This commit is contained in:
Henrik Giesel 2021-05-06 01:22:55 +02:00
parent e1cc22b9ee
commit bcb1b5d214
4 changed files with 88 additions and 25 deletions

View file

@ -6,11 +6,12 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import ButtonGroupItem from "./ButtonGroupItem.svelte";
import type { SvelteComponentTyped } from "svelte";
import { setContext } from "svelte";
import type { Writable } from "svelte/store";
import { writable } from "svelte/store";
import { buttonGroupKey } from "./contextKeys";
import type { Identifier } from "./identifier";
import { insert, add, update, find } from "./identifier";
import type { ButtonRegistration } from "./buttons";
import { ButtonPosition } from "./buttons";
export let id: string | undefined = undefined;
let className: string = "";
@ -19,15 +20,26 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
export let api = {};
let buttonGroupRef: HTMLDivElement;
interface ButtonRegistration {
detach: Writable<boolean>;
}
let items: ButtonRegistration[] = [];
const items: ButtonRegistration[] = [];
$: {
for (const [index, item] of items.entries()) {
if (items.length === 1) {
item.position.set(ButtonPosition.Standalone);
} else if (index === 0) {
item.position.set(ButtonPosition.Leftmost);
} else if (index === items.length - 1) {
item.position.set(ButtonPosition.Rightmost);
} else {
item.position.set(ButtonPosition.Center);
}
}
}
function makeRegistration(): ButtonRegistration {
const detach = writable(false);
return { detach };
const position = writable(ButtonPosition.Standalone);
return { detach, position };
}
function registerButton(
@ -35,6 +47,7 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
registration = makeRegistration()
): ButtonRegistration {
items.splice(index, 0, registration);
items = items;
return registration;
}
@ -92,9 +105,9 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
}
const showButton = (id: Identifier) =>
updateRegistration(({ detach }) => detach.update(() => false), id);
updateRegistration(({ detach }) => detach.set(false), id);
const hideButton = (id: Identifier) =>
updateRegistration(({ detach }) => detach.update(() => true), id);
updateRegistration(({ detach }) => detach.set(true), id);
const toggleButton = (id: Identifier) =>
updateRegistration(({ detach }) => detach.update((old) => !old), id);

View file

@ -3,17 +3,58 @@ Copyright: Ankitects Pty Ltd and contributors
License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
-->
<script lang="typescript">
import WithTheming from "components/WithTheming.svelte";
import Detachable from "components/Detachable.svelte";
import { getContext } from "svelte";
import type { ButtonRegistration } from "./buttons";
import { ButtonPosition } from "./buttons";
import { getContext, hasContext } from "svelte";
import { buttonGroupKey } from "./contextKeys";
export let registration = undefined;
export let registration: ButtonRegistration | undefined = undefined;
const { registerButton } = getContext(buttonGroupKey);
const { detach } = registration ?? registerButton();
let detach_: boolean;
let position_: ButtonPosition;
let style: string;
const radius = "calc(var(--toolbar-size) / 7.5)";
$: {
switch (position_) {
case ButtonPosition.Standalone:
style = `--border-left-radius: ${radius}; --border-right-radius: ${radius}; `;
break;
case ButtonPosition.Leftmost:
style = `--border-left-radius: ${radius}; --border-right-radius: 0; `;
break;
case ButtonPosition.Center:
style = "--border-left-radius: 0; --border-right-radius: 0; ";
break;
case ButtonPosition.Rightmost:
style = `--border-left-radius: 0; --border-right-radius: ${radius}; `;
break;
}
}
if (registration) {
const { detach, position } = registration;
detach.subscribe((value: boolean) => (detach_ = value));
position.subscribe((value: ButtonPosition) => (position_ = value));
} else if (hasContext(buttonGroupKey)) {
const { registerButton } = getContext(buttonGroupKey);
const { detach, position } = registerButton();
detach.subscribe((value: boolean) => (detach_ = value));
position.subscribe((value: ButtonPosition) => (position_ = value));
} else {
detach_ = false;
position_ = ButtonPosition.Standalone;
}
</script>
<Detachable detach={$detach}>
<slot />
</Detachable>
<!-- div in WithTheming is necessary to preserve item position -->
<WithTheming {style}>
<Detachable detach={detach_}>
<slot />
</Detachable>
</WithTheming>

View file

@ -43,17 +43,11 @@ License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
width: auto;
height: var(--toolbar-size);
border-radius: calc(var(--toolbar-size) / 7.5);
border-top-left-radius: var(--border-left-radius);
border-bottom-left-radius: var(--border-left-radius);
&: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-top-right-radius: var(--border-right-radius);
border-bottom-right-radius: var(--border-right-radius);
}
@include button.btn-day;

15
ts/components/buttons.ts Normal file
View file

@ -0,0 +1,15 @@
// Copyright: Ankitects Pty Ltd and contributors
// License: GNU AGPL, version 3 or later; http://www.gnu.org/licenses/agpl.html
import type { Writable } from "svelte/store";
export enum ButtonPosition {
Standalone,
Leftmost,
Center,
Rightmost,
}
export interface ButtonRegistration {
detach: Writable<boolean>;
position: Writable<ButtonPosition>;
}