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; readonly onClose: Accessor } const TabsContext = createContext(); const useTabs = () => { const context = useContext(TabsContext); if (context === undefined) { throw new Error(' is used outside of a ') } return context!; } export const Tabs: ParentComponent<{ class?: string, active?: string, setActive?: Setter, onClose?: CloseTabCommandType }> = (props) => { const [active, setActive] = createSignal(props.active); createEffect(() => { props.setActive?.(active()); }); const ctx = { activate(id: string) { setActive(id); }, isActive(id: string) { return createMemo(() => active() === id); }, onClose: createMemo(() => props.onClose), }; return <_Tabs class={props.class} active={active()} onClose={props.onClose}>{props.children} ; } 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') } }))); const onClose = (e: Event) => { if (!commandsContext || !props.onClose) { return; } return commandsContext.execute(props.onClose, e); }; return
{ ({ id, label, options: { closable } }) => }
{resolved()}
; }; export const Tab: ParentComponent<{ id: string, label: string, closable?: boolean }> = (props) => { const context = useTabs(); const resolved = children(() => props.children); const isActive = context.isActive(props.id); return
{resolved()}
; }