persist selected tab on edit page

This commit is contained in:
Chris Kruining 2025-01-07 16:06:46 +01:00
parent 5774cc1299
commit 4592a6f1bc
No known key found for this signature in database
GPG key ID: EB894A3560CCCAD2
2 changed files with 12 additions and 13 deletions

View file

@ -1,12 +1,13 @@
import { Accessor, children, createContext, createEffect, createMemo, createSignal, For, JSX, onCleanup, ParentComponent, Setter, Show, useContext } from "solid-js";
import { Accessor, children, createContext, createEffect, createMemo, createSignal, For, ParentComponent, Setter, Show, useContext } from "solid-js";
import { Command, CommandType, noop, useCommands } from "~/features/command";
import { AiOutlineClose } from "solid-icons/ai";
import css from "./tabs.module.css";
type CloseTabCommandType = CommandType<(id: string) => any>;
interface TabsContextType {
activate(id: string | undefined): void;
isActive(id: string): Accessor<boolean>;
readonly onClose: Accessor<CommandType<[string]> | undefined>
readonly onClose: Accessor<CloseTabCommandType | undefined>
}
const TabsContext = createContext<TabsContextType>();
@ -21,11 +22,11 @@ const useTabs = () => {
return context!;
}
export const Tabs: ParentComponent<{ class?: string, active?: Setter<string | undefined>, onClose?: CommandType<[string]> }> = (props) => {
const [active, setActive] = createSignal<string | undefined>(undefined);
export const Tabs: ParentComponent<{ class?: string, active?: string, setActive?: Setter<string | undefined>, onClose?: CloseTabCommandType }> = (props) => {
const [active, setActive] = createSignal<string | undefined>(props.active);
createEffect(() => {
props.active?.(active());
props.setActive?.(active());
});
const ctx = {
@ -45,17 +46,13 @@ export const Tabs: ParentComponent<{ class?: string, active?: Setter<string | un
</TabsContext.Provider >;
}
const _Tabs: ParentComponent<{ class?: string, active: string | undefined, onClose?: CommandType<[string]> }> = (props) => {
const _Tabs: ParentComponent<{ class?: string, active: string | undefined, onClose?: CloseTabCommandType }> = (props) => {
const commandsContext = useCommands();
const tabsContext = useTabs();
const resolved = children(() => props.children);
const tabs = createMemo(() => resolved.toArray().filter(c => c instanceof HTMLElement).map(({ id, dataset }, i) => ({ id, label: dataset.tabLabel ?? '', options: { closable: Boolean(dataset.tabClosable ?? 'false') } })));
createEffect(() => {
tabsContext.activate(tabs().at(-1)?.id);
});
const onClose = (e: Event) => {
if (!commandsContext || !props.onClose) {
return;
@ -67,7 +64,7 @@ const _Tabs: ParentComponent<{ class?: string, active: string | undefined, onClo
return <div class={`${css.tabs} ${props.class}`}>
<header>
<For each={tabs()}>{
({ id, label, options: { closable } }) => <Command.Context for={props.onClose} with={[id]}>
({ id, label, options: { closable } }) => <Command.Context for={props.onClose!} with={[id]}>
<span class={css.handle} classList={{ [css.active]: props.active === id }}>
<button onpointerdown={(e) => {
if (closable && e.pointerType === 'mouse' && e.button === 1) {

View file

@ -11,6 +11,7 @@ import { isServer } from "solid-js/web";
import { Prompt, PromptApi } from "~/components/prompt";
import EditBlankImage from '~/assets/edit-blank.svg'
import { useI18n } from "~/features/i18n";
import { makePersisted } from "@solid-primitives/storage";
import css from "./edit.module.css";
const isInstalledPWA = !isServer && window.matchMedia('(display-mode: standalone)').matches;
@ -91,7 +92,7 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => {
return ({ key, handle, api, setApi, entries, setEntries, files });
}));
const [active, setActive] = createSignal<string>();
const [active, setActive] = makePersisted(createSignal<string>(), { name: 'edit__aciveTab' });
const [contents, setContents] = createSignal<Map<string, Map<string, string>>>(new Map());
const [tree, setFiles] = createSignal<FolderEntry>(emptyFolder);
const [newKeyPrompt, setNewKeyPrompt] = createSignal<PromptApi>();
@ -367,12 +368,13 @@ const Editor: Component<{ root: FileSystemDirectoryHandle }> = (props) => {
return <Context.Handle classList={{ [css.mutated]: mutated() }} onDblClick={() => {
const folder = file().directory;
filesContext?.set(folder.name, folder);
setActive(folder.name);
}}>{file().name}</Context.Handle>;
},
] as const}</Tree>
</Sidebar>
<Tabs class={css.content} active={setActive} onClose={commands.closeTab}>
<Tabs class={css.content} active={active()} setActive={setActive} onClose={commands.closeTab}>
<For each={tabs()}>{
({ key, handle, setApi, setEntries }) => <Tab id={key} label={handle.name} closable>
<Content directory={handle} api={setApi} entries={setEntries} />