import { createSignal, onCleanup, onMount, Show, For, JSXElement } from "solid-js";
// CrmTabGroup / CrmSubTabGroup — drop-in, behaviourally identical siblings of
// TabGroup (same props, storageKey syncing, controlled/uncontrolled index) with
// a different look:
// - CrmTabGroup → boxed tabs with a sky-blue top accent (ported from the old cdrl_2.0 tabs)
// - CrmSubTabGroup → interlocking right-pointing arrows (a process-flow strip)
interface CrmTabItem {
title: string;
badge?: number;
content: JSXElement;
}
interface CrmTabGroupProps {
items: CrmTabItem[];
storageKey?: string;
activeIndex?: number;
onTabChange?: (index: number) => void;
defaultIndex?: number;
}
function resolveCrmBadge(badge: number | undefined): number | undefined {
return typeof badge === "function" ? (badge as () => number)() : badge;
}
// Shared active-index state: mirrors TabGroup exactly (localStorage persistence,
// cross-component sync via synthetic storage events, optional controlled index).
function createCrmTabState(props: CrmTabGroupProps) {
const getInitialIndex = () => {
if (props.storageKey) {
const stored = localStorage.getItem(props.storageKey);
if (stored !== null) {
const parsed = parseInt(stored, 10);
if (!isNaN(parsed) && parsed >= 0 && parsed < props.items.length) {
return parsed;
}
}
}
return props.defaultIndex ?? 0;
};
const [_activeIndex, _setActiveIndex] = createSignal(getInitialIndex());
const activeIndex = (): number => {
const controlled = props.activeIndex;
if (controlled != null) {
return typeof controlled === "function" ? (controlled as () => number)() : controlled;
}
return _activeIndex();
};
const setActiveIndex = (i: number) => {
_setActiveIndex(i);
if (props.storageKey) {
const v = String(i);
localStorage.setItem(props.storageKey, v);
window.dispatchEvent(new StorageEvent("storage", { key: props.storageKey, newValue: v }));
}
props.onTabChange && props.onTabChange(i);
};
onMount(() => {
if (!props.storageKey) return;
const handler = (e: StorageEvent) => {
if (e.key !== props.storageKey || e.newValue == null) return;
const n = parseInt(e.newValue, 10);
if (!isNaN(n) && n >= 0 && n < props.items.length && n !== _activeIndex()) {
_setActiveIndex(n);
props.onTabChange && props.onTabChange(n);
}
};
window.addEventListener("storage", handler);
onCleanup(() => window.removeEventListener("storage", handler));
});
return { activeIndex, setActiveIndex };
}
function crmTabContent(items: CrmTabItem[], activeIndex: () => number) {
return