// components/Tabs.js import { Tag, $, Watch } from "sigpro"; export const Tabs = (props) => { const { items, class: className, onTabClose, ...rest } = props; const itemsSignal = typeof items === "function" ? items : () => items || []; const activeIndex = $(0); Watch(() => { const list = itemsSignal(); const idx = list.findIndex(it => { const active = it.active; return typeof active === "function" ? active() : active; }); if (idx !== -1 && activeIndex() !== idx) activeIndex(idx); }); const removeTab = (idx, item) => { item.onClose?.(); onTabClose?.(item, idx); const current = itemsSignal(); if (typeof items !== "function" || items._isComputed) return; const newItems = current.filter((_, i) => i !== idx); items(newItems); if (newItems.length) { let newIdx = activeIndex(); if (idx < newIdx) newIdx--; else if (idx === newIdx) newIdx = Math.min(newIdx, newItems.length - 1); activeIndex(newIdx); } }; return Tag("div", { ...rest, class: `tabs ${className || ''}`.trim() }, () => { const list = itemsSignal(); const elements = []; for (let i = 0; i < list.length; i++) { const item = list[i]; const label = typeof item.label === "function" ? item.label() : item.label; const closable = typeof item.closable === "function" ? item.closable() : item.closable; const btnContent = closable ? Tag("span", { class: "flex items-center" }, [ label, Tag("span", { class: "icon-[lucide--x] w-3.5 h-3.5 ml-2 cursor-pointer hover:opacity-70", onclick: (e) => { e.stopPropagation(); removeTab(i, item); } }) ]) : label; const tabBtn = Tag("button", { class: () => `tab ${activeIndex() === i ? 'tab-active' : ''}`, onclick: (e) => { e.preventDefault(); const disabled = typeof item.disabled === "function" ? item.disabled() : item.disabled; if (!disabled) { item.onclick?.(); activeIndex(i); } } }, btnContent); elements.push(item.tip ? Tag("div", { class: "tooltip", "data-tip": item.tip }, tabBtn) : tabBtn); const content = typeof item.content === "function" ? item.content() : item.content; elements.push( Tag("div", { class: "tab-content bg-base-100 border-base-300 p-6", style: () => `display: ${activeIndex() === i ? 'block' : 'none'}` }, content) ); } return elements; }); };