initial attempt with pwa

This commit is contained in:
Chris Kruining 2024-10-29 13:33:01 +01:00
parent ddf4519f41
commit b27abe928d
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
16 changed files with 382 additions and 220 deletions

View file

@ -3,6 +3,10 @@
grid: auto 1fr / 100%;
& > button {
display: flex;
flex-flow: row;
gap: var(--padding-s);
align-items: center;
inline-size: max-content;
padding: 0;
background-color: var(--surface-1);

View file

@ -14,13 +14,32 @@
border-block-end: 1px solid var(--surface-5);
& > button {
& > .handle {
display: grid;
grid-auto-flow: column;
column-gap: var(--padding-m);
background-color: var(--surface-1);
color: var(--text-2);
padding: var(--padding-m) var(--padding-l);
border: none;
cursor: pointer;
& > button {
display: grid;
align-content: center;
background-color: inherit;
color: inherit;
padding: var(--padding-m) 0;
border: none;
&:first-child {
padding-inline-start: var(--padding-l);
}
&:last-child {
padding-inline-end: var(--padding-l);
}
}
&.active {
background-color: var(--surface-3);
color: var(--text-1);

View file

@ -1,8 +1,17 @@
import { Accessor, children, createContext, createEffect, createMemo, createRenderEffect, createSignal, createUniqueId, For, JSX, onMount, ParentComponent, Setter, Show, useContext } from "solid-js";
import { Accessor, children, createContext, createEffect, createMemo, createSignal, For, onCleanup, ParentComponent, Setter, Show, useContext } from "solid-js";
import { IoCloseCircleOutline } from "solid-icons/io";
import css from "./tabs.module.css";
import { Command, CommandType, commandArguments, noop, useCommands } from "~/features/command";
commandArguments;
interface TabsContextType {
register(id: string, label: string): Accessor<boolean>;
register(id: string, label: string, options?: Partial<TabOptions>): Accessor<boolean>;
readonly onClose: Accessor<CommandType<[string]> | undefined>
}
interface TabOptions {
closable: boolean;
}
const TabsContext = createContext<TabsContextType>();
@ -17,9 +26,10 @@ const useTabs = () => {
return context!;
}
export const Tabs: ParentComponent<{ active?: Setter<string | undefined> }> = (props) => {
export const Tabs: ParentComponent<{ active?: Setter<string | undefined>, onClose?: CommandType<[string]> }> = (props) => {
const commandsContext = useCommands();
const [active, setActive] = createSignal<string | undefined>(undefined);
const [tabs, setTabs] = createSignal<Map<string, string>>(new Map());
const [tabs, setTabs] = createSignal<Map<string, { label: string, options: Partial<TabOptions> }>>(new Map());
createEffect(() => {
props.active?.(active());
@ -30,35 +40,53 @@ export const Tabs: ParentComponent<{ active?: Setter<string | undefined> }> = (p
});
const ctx = {
register(id: string, label: string) {
register(id: string, label: string, options: Partial<TabOptions>) {
setTabs(tabs => {
tabs.set(id, label);
tabs.set(id, { label, options });
return new Map(tabs);
});
return createMemo(() => active() === id);
},
onClose: createMemo(() => props.onClose),
};
const onClose = (e: Event) => {
if (!commandsContext || !props.onClose) {
return;
}
return commandsContext.execute(props.onClose, e);
};
return <TabsContext.Provider value={ctx}>
<div class={css.tabs}>
<header>
<For each={tabs().entries().toArray()}>{
([id, label]) => <button onpointerdown={() => setActive(id)} classList={{ [css.active]: active() === id }}>{label}</button>
([id, { label, options: { closable = false } }]) => <Command.Context for={props.onClose} with={[id]}>
<span class={css.handle} classList={{ [css.active]: active() === id }}>
<button onpointerdown={() => setActive(id)}>{label}</button>
<Show when={closable}>
<button onPointerDown={onClose}> <IoCloseCircleOutline /></button>
</Show>
</span>
</Command.Context>
}</For>
</header>
{props.children}
</div>
</TabsContext.Provider>;
</TabsContext.Provider >;
}
export const Tab: ParentComponent<{ id: string, label: string }> = (props) => {
export const Tab: ParentComponent<{ id: string, label: string, closable?: boolean }> = (props) => {
const context = useTabs();
const isActive = context.register(props.id, props.label);
const isActive = context.register(props.id, props.label, {
closable: props.closable ?? false
});
const resolved = children(() => props.children);
return <Show when={isActive()}>{resolved()}</Show>;
return <Show when={isActive()}><Command.Context for={context.onClose()} with={[props.id]}>{resolved()}</Command.Context></Show>;
}