initial attempt with pwa
This commit is contained in:
parent
ddf4519f41
commit
b27abe928d
16 changed files with 382 additions and 220 deletions
|
@ -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>;
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue