// components/Tabs.js // import { $, Tag, For } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** * Tabs component * * daisyUI classes used: * - tabs, tabs-box, tabs-lift, tabs-border * - tab, tab-content * - bg-base-100, border-base-300, p-6 */ export const Tabs = (props) => { const { items, class: className, ...rest } = props; const itemsSignal = typeof items === "function" ? items : () => items || []; const activeIndex = $(0); Watch(() => { const idx = itemsSignal().findIndex(it => val(it.active) === true); if (idx !== -1 && idx !== activeIndex()) activeIndex(idx); }); // Contenedor principal con las clases de DaisyUI return Tag("div", { ...rest, class: ui('tabs', className) }, () => { const list = itemsSignal(); const elements = []; for (let i = 0; i < list.length; i++) { const item = list[i]; const isActive = () => activeIndex() === i; // Botón (tab) const button = Tag("button", { class: () => ui("tab", isActive() ? "tab-active" : ""), onclick: (e) => { e.preventDefault(); if (!val(item.disabled)) { if (item.onclick) item.onclick(); activeIndex(i); } } }); // Asignar etiqueta (puede ser texto o nodo) const label = val(item.label); if (label instanceof Node) { button.replaceChildren(label); } else { button.textContent = String(label); } elements.push(button); // Contenido (tab-content) - borde exterior estático const panel = Tag("div", { class: "tab-content bg-base-100 border-base-300 p-6", style: () => isActive() ? "display: block" : "display: none" }, [ // Contenedor interno con animación Tag("div", { class: "tab-content-inner" }, () => val(item.content)) ]); elements.push(panel); } return elements; }); };