Rebuild all components
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 4s

This commit is contained in:
2026-04-21 18:00:17 +02:00
parent d900659d88
commit 16afea2768
67 changed files with 1820 additions and 2132 deletions

View File

@@ -1,75 +1,49 @@
// components/Tabs.js
import { Tag, $, Watch } from "sigpro";
import { Tag, For } from "sigpro";
export const Tabs = (props) => {
const { items, class: className, onTabClose, ...rest } = props;
const itemsSignal = typeof items === "function" ? items : () => items || [];
const activeIndex = $(0);
export const Tabs = (props, children) => {
children === undefined && (children = props, props = {});
return Tag("div", { ...props, class: `tabs ${props.class ?? ''}` }, children);
};
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);
});
export const Tab = (props, children) => {
children === undefined && (children = props, props = {});
return Tag("a", { ...props, role: "tab", class: `tab ${props.class ?? ''}` }, children);
};
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);
}
};
export const TabContent = (props, children) => {
children === undefined && (children = props, props = {});
return Tag("div", { ...props, class: `tab-content ${props.class ?? ''}` }, children);
};
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;
export const TabClose = (props) => Tag("a", { ...props, role: "tab", class: `tab ${props.class ?? ''}` }, [
Tag("span", { class: "flex items-center" }, [
props.label,
Tag("span", {
class: "icon-[lucide--x] w-3.5 h-3.5 ml-2 cursor-pointer hover:opacity-70",
onclick: (e) => { e.stopPropagation(); props.onClose?.(e); }
})
])
]);
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;
});
export const TabItems = (props) => {
const items = typeof props.items === "function" ? props.items : () => props.items || [];
return For(
items,
(item, idx) => {
const TabComp = item.closable ? TabClose : Tab;
return [
TabComp({
...item,
class: () => props.activeIndex() === idx ? `tab-active ${item.class ?? ''}` : item.class,
onclick: (e) => { e.preventDefault(); props.activeIndex(idx); item.onclick?.(e); },
onClose: () => props.onClose?.(idx, item)
}),
TabContent({
style: () => `display: ${props.activeIndex() === idx ? "block" : "none"};`
}, typeof item.content === "function" ? item.content() : item.content)
];
},
(item, idx) => item.id ?? idx
);
};