var __defProp = Object.defineProperty; var __export = (target, all) => { for (var name in all) __defProp(target, name, { get: all[name], enumerable: true, configurable: true, set: (newValue) => all[name] = () => newValue }); }; // src/sigpro.js var doc = typeof document !== "undefined" ? document : null; var isArr = Array.isArray; var isFunc = (f) => typeof f === "function"; var isObj = (o) => o && typeof o === "object"; var ensureNode = (n) => n?._isRuntime ? n.container : n instanceof Node ? n : doc.createTextNode(n == null ? "" : String(n)); var activeEffect = null; var activeOwner = null; var isFlushing = false; var effectQueue = new Set; var MOUNTED_NODES = new WeakMap; var dispose = (eff) => { if (!eff || eff._disposed) return; eff._disposed = true; const stack = [eff]; while (stack.length) { const e = stack.pop(); if (e._cleanups) { e._cleanups.forEach((fn) => fn()); e._cleanups.clear(); } if (e._children) { e._children.forEach((child) => stack.push(child)); e._children.clear(); } if (e._deps) { e._deps.forEach((depSet) => depSet.delete(e)); e._deps.clear(); } } }; var onUnmount = (fn) => { if (activeOwner) (activeOwner._cleanups ||= new Set).add(fn); }; var createEffect = (fn, isComputed = false) => { const effect = () => { if (effect._disposed) return; if (effect._deps) effect._deps.forEach((depSet) => depSet.delete(effect)); if (effect._cleanups) { effect._cleanups.forEach((cl) => cl()); effect._cleanups.clear(); } const prevEffect = activeEffect, prevOwner = activeOwner; activeEffect = activeOwner = effect; try { const res = isComputed ? fn() : (fn(), undefined); if (!isComputed) effect._result = res; return res; } finally { activeEffect = prevEffect; activeOwner = prevOwner; } }; effect._deps = effect._cleanups = effect._children = null; effect._disposed = false; effect._isComputed = isComputed; effect._depth = activeEffect ? activeEffect._depth + 1 : 0; effect._mounts = []; effect._parent = activeOwner; if (activeOwner) (activeOwner._children ||= new Set).add(effect); return effect; }; var flush = () => { if (isFlushing) return; isFlushing = true; const sorted = Array.from(effectQueue).sort((a, b) => a._depth - b._depth); effectQueue.clear(); for (const e of sorted) if (!e._disposed) e(); isFlushing = false; }; var trackUpdate = (subs, trigger = false) => { if (!trigger && activeEffect && !activeEffect._disposed) { subs.add(activeEffect); (activeEffect._deps ||= new Set).add(subs); } else if (trigger) { let hasQueue = false; subs.forEach((e) => { if (e === activeEffect || e._disposed) return; if (e._isComputed) { e._dirty = true; if (e._subs) trackUpdate(e._subs, true); } else { effectQueue.add(e); hasQueue = true; } }); if (hasQueue && !isFlushing) queueMicrotask(flush); } }; var untrack = (fn) => { const p = activeEffect; activeEffect = null; try { return fn(); } finally { activeEffect = p; } }; var onMount = (fn) => { if (activeOwner) (activeOwner._mounts ||= []).push(fn); }; var $2 = (val, key = null) => { const subs = new Set; if (isFunc(val)) { let cache, dirty = true; const computed = () => { if (dirty) { const prev = activeEffect; activeEffect = computed; try { const next = val(); if (!Object.is(cache, next)) { cache = next; dirty = false; trackUpdate(subs, true); } } finally { activeEffect = prev; } } trackUpdate(subs); return cache; }; computed._isComputed = true; computed._subs = subs; computed._dirty = true; computed._deps = null; computed._disposed = false; computed.markDirty = () => { dirty = true; }; computed.stop = () => { computed._disposed = true; if (computed._deps) { computed._deps.forEach((depSet) => depSet.delete(computed)); computed._deps.clear(); } subs.clear(); }; if (activeOwner) onUnmount(computed.stop); return computed; } if (key) try { val = JSON.parse(localStorage.getItem(key)) ?? val; } catch (e) {} return (...args) => { if (args.length) { const next = isFunc(args[0]) ? args[0](val) : args[0]; if (!Object.is(val, next)) { val = next; if (key) localStorage.setItem(key, JSON.stringify(val)); trackUpdate(subs, true); } } trackUpdate(subs); return val; }; }; var $$ = (obj, cache = new WeakMap) => { if (!isObj(obj)) return obj; if (cache.has(obj)) return cache.get(obj); const subs = {}; const proxy = new Proxy(obj, { get: (t, k) => { trackUpdate(subs[k] ??= new Set); return isObj(t[k]) ? $$(t[k], cache) : t[k]; }, set: (t, k, v) => { if (!Object.is(t[k], v)) { t[k] = v; if (subs[k]) trackUpdate(subs[k], true); } return true; } }); cache.set(obj, proxy); return proxy; }; var Watch2 = (sources, cb) => { if (cb === undefined) { const effect2 = createEffect(sources); effect2(); return () => dispose(effect2); } const effect = createEffect(() => { const vals = Array.isArray(sources) ? sources.map((s) => s()) : sources(); untrack(() => cb(vals)); }); effect(); return () => dispose(effect); }; var cleanupNode = (node) => { if (node._cleanups) { node._cleanups.forEach((fn) => fn()); node._cleanups.clear(); } if (node._ownerEffect) dispose(node._ownerEffect); if (node.childNodes) node.childNodes.forEach(cleanupNode); }; var DANGEROUS_PROTOCOL = /^\s*(javascript|data|vbscript):/i; var isDangerousAttr = (key) => key === "src" || key === "href" || key.startsWith("on"); var validateAttr = (key, val) => { if (val == null || val === false) return null; if (isDangerousAttr(key)) { const sVal = String(val); if (DANGEROUS_PROTOCOL.test(sVal)) { console.warn(`[SigPro] Bloqueado protocolo peligroso en ${key}`); return "#"; } } return val; }; var Tag2 = (tag, props = {}, children = []) => { if (props instanceof Node || isArr(props) || !isObj(props)) { children = props; props = {}; } if (isFunc(tag)) { const ctx = { _mounts: [], _cleanups: new Set }; const effect = createEffect(() => { const result2 = tag(props, { children, emit: (ev, ...args) => props[`on${ev[0].toUpperCase()}${ev.slice(1)}`]?.(...args) }); effect._result = result2; return result2; }); effect(); ctx._mounts = effect._mounts || []; ctx._cleanups = effect._cleanups || new Set; const result = effect._result; const attachLifecycle = (node) => node && typeof node === "object" && !node._isRuntime && (node._mounts = ctx._mounts, node._cleanups = ctx._cleanups, node._ownerEffect = effect); isArr(result) ? result.forEach(attachLifecycle) : attachLifecycle(result); if (result == null) return null; if (result instanceof Node || isArr(result) && result.every((n) => n instanceof Node)) return result; return doc.createTextNode(String(result)); } const isSVG = /^(svg|path|circle|rect|line|polyline|polygon|g|defs|text|tspan|use)$/.test(tag); const el = isSVG ? doc.createElementNS("http://www.w3.org/2000/svg", tag) : doc.createElement(tag); el._cleanups = new Set; for (let k in props) { if (!props.hasOwnProperty(k)) continue; let v = props[k]; if (k === "ref") { isFunc(v) ? v(el) : v.current = el; continue; } if (k.startsWith("on")) { const ev = k.slice(2).toLowerCase(); el.addEventListener(ev, v); const off = () => el.removeEventListener(ev, v); el._cleanups.add(off); onUnmount(off); } else if (isFunc(v)) { const effect = createEffect(() => { const val = validateAttr(k, v()); if (k === "class") el.className = val || ""; else if (val == null) el.removeAttribute(k); else if (k in el && !isSVG) el[k] = val; else el.setAttribute(k, val === true ? "" : val); }); effect(); el._cleanups.add(() => dispose(effect)); onUnmount(() => dispose(effect)); if (/^(INPUT|TEXTAREA|SELECT)$/.test(el.tagName) && (k === "value" || k === "checked")) { const evType = k === "checked" ? "change" : "input"; el.addEventListener(evType, (ev) => v(ev.target[k])); } } else { const val = validateAttr(k, v); if (val != null) { if (k in el && !isSVG) el[k] = val; else el.setAttribute(k, val === true ? "" : val); } } } const append = (c) => { if (isArr(c)) return c.forEach(append); if (isFunc(c)) { const anchor = doc.createTextNode(""); el.appendChild(anchor); let currentNodes = []; const effect = createEffect(() => { const res = c(); const next = (isArr(res) ? res : [res]).map(ensureNode); currentNodes.forEach((n) => { if (n._isRuntime) n.destroy(); else cleanupNode(n); if (n.parentNode) n.remove(); }); let ref = anchor; for (let i = next.length - 1;i >= 0; i--) { const node = next[i]; if (node.parentNode !== ref.parentNode) ref.parentNode?.insertBefore(node, ref); if (node._mounts) node._mounts.forEach((fn) => fn()); ref = node; } currentNodes = next; }); effect(); el._cleanups.add(() => dispose(effect)); onUnmount(() => dispose(effect)); } else { const node = ensureNode(c); el.appendChild(node); if (node._mounts) node._mounts.forEach((fn) => fn()); } }; append(children); return el; }; var Render = (renderFn) => { const cleanups = new Set; const mounts = []; const previousOwner = activeOwner; const container = doc.createElement("div"); container.style.display = "contents"; activeOwner = { _cleanups: cleanups, _mounts: mounts }; const processResult = (result) => { if (!result) return; if (result._isRuntime) { cleanups.add(result.destroy); container.appendChild(result.container); } else if (isArr(result)) { result.forEach(processResult); } else { container.appendChild(result instanceof Node ? result : doc.createTextNode(String(result == null ? "" : result))); } }; try { processResult(renderFn({ onCleanup: (fn) => cleanups.add(fn) })); } finally { activeOwner = previousOwner; } mounts.forEach((fn) => fn()); return { _isRuntime: true, container, destroy: () => { cleanups.forEach((fn) => fn()); cleanupNode(container); container.remove(); } }; }; var If2 = (cond, ifYes, ifNot = null, trans = null) => { const anchor = doc.createTextNode(""); const root = Tag2("div", { style: "display:contents" }, [anchor]); let currentView = null, last = null; Watch2(() => !!(isFunc(cond) ? cond() : cond), (show) => { if (show === last) return; last = show; const disposeView = () => { if (currentView) { currentView.destroy(); currentView = null; } }; if (currentView && !show && trans?.out) trans.out(currentView.container, disposeView); else disposeView(); const content = show ? ifYes : ifNot; if (content) { currentView = Render(() => isFunc(content) ? content() : content); root.insertBefore(currentView.container, anchor); if (trans?.in) trans.in(currentView.container); } }); return root; }; var For2 = (src, itemFn, keyFn) => { const anchor = doc.createTextNode(""); const root = Tag2("div", { style: "display:contents" }, [anchor]); let cache = new Map; Watch2(() => (isFunc(src) ? src() : src) || [], (items) => { const nextCache = new Map; const nextOrder = []; const newItems = items || []; for (let i = 0;i < newItems.length; i++) { const item = newItems[i]; const key = keyFn ? keyFn(item, i) : item?.id ?? i; let view = cache.get(key); if (!view) view = Render(() => itemFn(item, i)); else cache.delete(key); nextCache.set(key, view); nextOrder.push(view); } cache.forEach((view) => view.destroy()); let lastRef = anchor; for (let i = nextOrder.length - 1;i >= 0; i--) { const view = nextOrder[i]; const node = view.container; if (node.nextSibling !== lastRef) root.insertBefore(node, lastRef); lastRef = node; } cache = nextCache; }); return root; }; var Router = (routes) => { const getHash = () => window.location.hash.slice(1) || "/"; const path = $2(getHash()); const handler = () => path(getHash()); window.addEventListener("hashchange", handler); onUnmount(() => window.removeEventListener("hashchange", handler)); const outlet = Tag2("div", { class: "router-outlet" }); let currentView = null; Watch2([path], () => { const cur = path(); const route = routes.find((r) => { const p1 = r.path.split("/").filter(Boolean); const p2 = cur.split("/").filter(Boolean); return p1.length === p2.length && p1.every((p, i) => p[0] === ":" || p === p2[i]); }) || routes.find((r) => r.path === "*"); if (route) { currentView?.destroy(); const params = {}; route.path.split("/").filter(Boolean).forEach((p, i) => { if (p[0] === ":") params[p.slice(1)] = cur.split("/").filter(Boolean)[i]; }); Router.params(params); currentView = Render(() => isFunc(route.component) ? route.component(params) : route.component); outlet.replaceChildren(currentView.container); } }); return outlet; }; Router.params = $2({}); Router.to = (p) => window.location.hash = p.replace(/^#?\/?/, "#/"); Router.back = () => window.history.back(); Router.path = () => window.location.hash.replace(/^#/, "") || "/"; var Mount2 = (comp, target) => { const t = typeof target === "string" ? doc.querySelector(target) : target; if (!t) return; if (MOUNTED_NODES.has(t)) MOUNTED_NODES.get(t).destroy(); const inst = Render(isFunc(comp) ? comp : () => comp); t.replaceChildren(inst.container); MOUNTED_NODES.set(t, inst); return inst; }; var SigPro = Object.freeze({ $: $2, $$, Watch: Watch2, Tag: Tag2, Render, If: If2, For: For2, Router, Mount: Mount2, onMount, onUnmount }); if (typeof window !== "undefined") { Object.assign(window, SigPro); "div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer ul ol li a em strong pre code form label input textarea select button img svg".split(" ").forEach((t) => window[t[0].toUpperCase() + t.slice(1)] = (p, c) => SigPro.Tag(t, p, c)); } // src/components/index.js var exports_components = {}; __export(exports_components, { default: () => components_default, Tooltip: () => Tooltip, Toast: () => Toast, Timeline: () => Timeline, Tabs: () => Tabs, Table: () => Table, Swap: () => Swap, Stat: () => Stat, Stack: () => Stack, Select: () => Select, Rating: () => Rating, Range: () => Range, Radio: () => Radio, Navbar: () => Navbar, Modal: () => Modal, Menu: () => Menu, List: () => List, Label: () => Label, Input: () => Input, Indicator: () => Indicator, Fileinput: () => Fileinput, Fieldset: () => Fieldset, Fab: () => Fab, Dropdown: () => Dropdown, Drawer: () => Drawer, Datepicker: () => Datepicker, Colorpicker: () => Colorpicker, Checkbox: () => Checkbox, Button: () => Button, Badge: () => Badge, Autocomplete: () => Autocomplete, Alert: () => Alert, Accordion: () => Accordion }); // src/components/Accordion.js var exports_Accordion = {}; __export(exports_Accordion, { Accordion: () => Accordion }); // src/core/utils.js var exports_utils = {}; __export(exports_utils, { val: () => val, ui: () => ui, getIcon: () => getIcon }); var val = (t) => typeof t === "function" ? t() : t; var ui = (baseClass, additionalClassOrFn) => typeof additionalClassOrFn === "function" ? () => `${baseClass} ${additionalClassOrFn() || ""}`.trim() : `${baseClass} ${additionalClassOrFn || ""}`.trim(); var getIcon = (icon) => { if (!icon) return null; if (typeof icon === "function") { return Tag("span", { class: "mr-1" }, icon()); } if (typeof icon === "object") { return Tag("span", { class: "mr-1" }, icon); } if (typeof icon === "string") { const parts = icon.trim().split(/\s+/); const hasRight = parts[parts.length - 1] === "right"; const iconClass = hasRight ? parts.slice(0, -1).join(" ") : icon; const spacing = hasRight ? "ml-1" : "mr-1"; if (iconClass && !iconClass.startsWith("icon-[") && !iconClass.includes("--")) { return Tag("span", { class: spacing }, iconClass); } return Tag("span", { class: `${iconClass} ${spacing}`.trim() }); } return null; }; // src/components/Accordion.js var Accordion = (props, children) => { const { class: className, title, name, open, ...rest } = props; return Tag("div", { ...rest, class: ui("collapse collapse-arrow bg-base-200 mb-2", className) }, [ Tag("input", { type: name ? "radio" : "checkbox", name, checked: val(open) }), Tag("div", { class: "collapse-title text-xl font-medium" }, title), Tag("div", { class: "collapse-content" }, children) ]); }; // src/components/Alert.js var exports_Alert = {}; __export(exports_Alert, { Alert: () => Alert }); var Alert = (props, children) => { const { class: className, actions, type = "info", soft = true, ...rest } = props; const iconMap = { info: "icon-[lucide--info]", success: "icon-[lucide--check-circle]", warning: "icon-[lucide--alert-triangle]", error: "icon-[lucide--alert-circle]" }; const typeClass = `alert-${type}`; const softClass = soft ? "alert-soft" : ""; const allClasses = [typeClass, softClass, className].filter(Boolean).join(" "); const content = children || props.message; return Tag("div", { ...rest, role: "alert", class: ui("alert", allClasses) }, () => [ getIcon(iconMap[type]), Tag("div", { class: "flex-1" }, [ Tag("span", {}, [typeof content === "function" ? content() : content]) ]), actions ? Tag("div", { class: "flex-none" }, [ typeof actions === "function" ? actions() : actions ]) : null ].filter(Boolean)); }; // src/components/Autocomplete.js var exports_Autocomplete = {}; __export(exports_Autocomplete, { Autocomplete: () => Autocomplete }); // src/core/i18n.js var i18n = { es: { close: "Cerrar", confirm: "Confirmar", cancel: "Cancelar", search: "Buscar...", loading: "Cargando...", nodata: "Sin datos" }, en: { close: "Close", confirm: "Confirm", cancel: "Cancel", search: "Search...", loading: "Loading...", nodata: "No data" } }; var currentLocale = $("es"); var tt = (t) => () => i18n[currentLocale()][t] || t; // src/components/Input.js var exports_Input = {}; __export(exports_Input, { Input: () => Input }); var Input = (props) => { const { class: className, value, type = "text", icon, oninput, placeholder, disabled, validate, label, ...rest } = props; const isPassword = type === "password"; const visible = $(false); const errorMsg = $(null); const iconMap = { text: "icon-[lucide--text]", password: "icon-[lucide--lock]", date: "icon-[lucide--calendar]", number: "icon-[lucide--hash]", email: "icon-[lucide--mail]", search: "icon-[lucide--search]", tel: "icon-[lucide--phone]", url: "icon-[lucide--link]" }; const leftIcon = icon ? getIcon(icon) : iconMap[type] ? getIcon(iconMap[type]) : null; const getPasswordIcon = () => getIcon(visible() ? "icon-[lucide--eye-off]" : "icon-[lucide--eye]"); const paddingLeft = leftIcon ? "pl-10" : ""; const paddingRight = isPassword ? "pr-10" : ""; const buttonSize = () => { if (className?.includes("input-xs")) return "btn-xs"; if (className?.includes("input-sm")) return "btn-sm"; if (className?.includes("input-lg")) return "btn-lg"; return "btn-md"; }; const handleInput = (e) => { const newValue = e.target.value; if (validate) { const result = validate(newValue); errorMsg(result || null); } oninput?.(e); }; const hasError = () => errorMsg() && errorMsg() !== ""; const inputClasses = () => { let classes = `input w-full ${paddingLeft} ${paddingRight}`; if (className) classes += ` ${className}`; if (hasError()) classes += " input-error"; return classes.trim(); }; const inputElement = Tag("input", { ...rest, type: () => isPassword ? visible() ? "text" : "password" : type, placeholder: placeholder || (label ? " " : placeholder), class: inputClasses, value, oninput: handleInput, disabled: () => val(disabled), "aria-invalid": () => hasError() ? "true" : "false" }); const inputContent = () => [ inputElement, leftIcon ? Tag("div", { class: "absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60" }, leftIcon) : null, isPassword ? Tag("button", { type: "button", class: ui("absolute right-3 inset-y-0 flex items-center", "btn btn-ghost btn-circle opacity-50 hover:opacity-100", buttonSize()), onclick: (e) => { e.preventDefault(); visible(!visible()); } }, () => getPasswordIcon()) : null, Tag("div", { class: "text-error text-xs mt-1 px-3 absolute -bottom-5 left-0" }, () => hasError() ? errorMsg() : null) ]; if (label) { return Tag("label", { class: ui("floating-label w-full", className) }, () => [ Tag("div", { class: "relative w-full" }, inputContent), Tag("span", {}, val(label)) ]); } return Tag("div", { class: "relative w-full" }, inputContent); }; // src/components/Autocomplete.js var Autocomplete = (props) => { const { class: className, items = [], value, onselect, label, placeholder, ...rest } = props; const query = $(val(value) || ""); const isOpen = $(false); const cursor = $(-1); const list = $(() => { const q = query().toLowerCase(); const data = val(items) || []; return q ? data.filter((o) => (typeof o === "string" ? o : o.label).toLowerCase().includes(q)) : data; }); const pick = (opt) => { const valStr = typeof opt === "string" ? opt : opt.value; const labelStr = typeof opt === "string" ? opt : opt.label; query(labelStr); if (typeof value === "function") value(valStr); onselect?.(opt); isOpen(false); cursor(-1); }; const nav = (e) => { const items2 = list(); if (e.key === "ArrowDown") { e.preventDefault(); isOpen(true); cursor(Math.min(cursor() + 1, items2.length - 1)); } else if (e.key === "ArrowUp") { e.preventDefault(); cursor(Math.max(cursor() - 1, 0)); } else if (e.key === "Enter" && cursor() >= 0) { e.preventDefault(); pick(items2[cursor()]); } else if (e.key === "Escape") { isOpen(false); } }; return Tag("div", { class: "relative w-full" }, [ Input({ label, class: className, placeholder: placeholder || tt("search")(), value: query, onfocus: () => isOpen(true), onblur: () => setTimeout(() => isOpen(false), 150), onkeydown: nav, oninput: (e) => { const v = e.target.value; query(v); if (typeof value === "function") value(v); isOpen(true); cursor(-1); }, ...rest }), Tag("ul", { class: "absolute dropdown-menu left-0 w-full menu bg-base-100 rounded-box mt-1 p-2 shadow-xl max-h-60 overflow-y-auto border border-base-300 z-50", style: () => isOpen() && list().length ? "display:block" : "display:none" }, [ For(list, (opt, i) => Tag("li", {}, [ Tag("a", { class: () => `block w-full ${cursor() === i ? "active bg-primary text-primary-content" : ""}`, onclick: () => pick(opt), onmouseenter: () => cursor(i) }, typeof opt === "string" ? opt : opt.label) ]), (opt, i) => (typeof opt === "string" ? opt : opt.value) + i), () => list().length ? null : Tag("li", { class: "p-2 text-center opacity-50" }, tt("nodata")()) ]) ]); }; // src/components/Badge.js var exports_Badge = {}; __export(exports_Badge, { Badge: () => Badge }); var Badge = (props, children) => { const { class: className, ...rest } = props; return Tag("span", { ...rest, class: ui("badge", className) }, children); }; // src/components/Button.js var exports_Button = {}; __export(exports_Button, { Button: () => Button }); var Button = (props, children) => { const { class: className, loading, icon, ...rest } = props; const iconEl = getIcon(icon); return Tag("button", { ...rest, class: ui("btn", className), disabled: () => val(loading) || val(props.disabled) }, () => [ val(loading) && Tag("span", { class: "loading loading-spinner" }), iconEl, children ].filter(Boolean)); }; // src/components/Checkbox.js var exports_Checkbox = {}; __export(exports_Checkbox, { Checkbox: () => Checkbox }); var Checkbox = (props) => { const { class: className, value, toggle, label, ...rest } = props; const checkEl = Tag("input", { ...rest, type: "checkbox", class: () => ui(val(toggle) ? "toggle" : "checkbox", className), checked: value }); return Tag("label", { class: "label cursor-pointer justify-start gap-3" }, [ checkEl, label ? Tag("span", { class: "label-text" }, label) : null ]); }; // src/components/Colorpicker.js var exports_Colorpicker = {}; __export(exports_Colorpicker, { Colorpicker: () => Colorpicker }); var Colorpicker = (props) => { const { class: className, value, label, ...rest } = props; const isOpen = $(false); const palette = [ ...["#000", "#1A1A1A", "#333", "#4D4D4D", "#666", "#808080", "#B3B3B3", "#FFF"], ...["#450a0a", "#7f1d1d", "#991b1b", "#b91c1c", "#dc2626", "#ef4444", "#f87171", "#fca5a5"], ...["#431407", "#7c2d12", "#9a3412", "#c2410c", "#ea580c", "#f97316", "#fb923c", "#ffedd5"], ...["#713f12", "#a16207", "#ca8a04", "#eab308", "#facc15", "#fde047", "#fef08a", "#fff9c4"], ...["#064e3b", "#065f46", "#059669", "#10b981", "#34d399", "#4ade80", "#84cc16", "#d9f99d"], ...["#082f49", "#075985", "#0284c7", "#0ea5e9", "#38bdf8", "#7dd3fc", "#22d3ee", "#cffafe"], ...["#1e1b4b", "#312e81", "#4338ca", "#4f46e5", "#6366f1", "#818cf8", "#a5b4fc", "#e0e7ff"], ...["#2e1065", "#4c1d95", "#6d28d9", "#7c3aed", "#8b5cf6", "#a855f7", "#d946ef", "#fae8ff"] ]; const getColor = () => val(value) || "#000000"; return Tag("div", { class: ui("relative w-fit", className) }, [ Tag("button", { type: "button", class: "btn px-3 bg-base-100 border-base-300 hover:border-primary/50 flex items-center gap-2 shadow-sm font-normal normal-case", onclick: (e) => { e.stopPropagation(); isOpen(!isOpen()); }, ...rest }, [ Tag("div", { class: "size-5 rounded-sm shadow-inner border border-black/10 shrink-0", style: () => `background-color: ${getColor()}` }), label ? Tag("span", { class: "opacity-80" }, label) : null ]), If(isOpen, () => Tag("div", { class: "absolute left-0 mt-2 p-3 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[110] w-64 select-none", onclick: (e) => e.stopPropagation() }, [ Tag("div", { class: "grid grid-cols-8 gap-1" }, palette.map((c) => Tag("button", { type: "button", style: `background-color: ${c}`, class: () => { const active = getColor().toLowerCase() === c.toLowerCase(); return `size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 ${active ? "ring-2 ring-offset-1 ring-primary z-10 scale-110" : ""}`; }, onclick: () => { if (typeof value === "function") value(c); isOpen(false); } }))) ])), If(isOpen, () => Tag("div", { class: "fixed inset-0 z-[100]", onclick: () => isOpen(false) })) ]); }; // src/components/Datepicker.js var exports_Datepicker = {}; __export(exports_Datepicker, { Datepicker: () => Datepicker }); var Datepicker = (props) => { const { class: className, value, range, label, placeholder, hour = false, ...rest } = props; const isOpen = $(false); const internalDate = $(new Date); const hoverDate = $(null); const startHour = $(0); const endHour = $(0); const isRangeMode = () => val(range) === true; const now = new Date; const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`; const formatDate = (d) => { const year = d.getFullYear(); const month = String(d.getMonth() + 1).padStart(2, "0"); const day = String(d.getDate()).padStart(2, "0"); return `${year}-${month}-${day}`; }; const selectDate = (date) => { const dateStr = formatDate(date); const current = val(value); if (isRangeMode()) { if (!current?.start || current.start && current.end) { if (typeof value === "function") { value({ start: dateStr, end: null, ...hour && { startHour: startHour() } }); } } else { const start = current.start; if (typeof value === "function") { const newValue = dateStr < start ? { start: dateStr, end: start } : { start, end: dateStr }; if (hour) { newValue.startHour = current.startHour || startHour(); newValue.endHour = current.endHour || endHour(); } value(newValue); } isOpen(false); } } else { if (typeof value === "function") { value(hour ? `${dateStr}T${String(startHour()).padStart(2, "0")}:00:00` : dateStr); } isOpen(false); } }; const displayValue = $(() => { const v = val(value); if (!v) return ""; if (typeof v === "string") { if (hour && v.includes("T")) return v.replace("T", " "); return v; } if (v.start && v.end) { const startStr = hour && v.startHour ? `${v.start} ${String(v.startHour).padStart(2, "0")}:00` : v.start; const endStr = hour && v.endHour ? `${v.end} ${String(v.endHour).padStart(2, "0")}:00` : v.end; return `${startStr} - ${endStr}`; } if (v.start) { const startStr = hour && v.startHour ? `${v.start} ${String(v.startHour).padStart(2, "0")}:00` : v.start; return `${startStr}...`; } return ""; }); const move = (m) => { const d = internalDate(); internalDate(new Date(d.getFullYear(), d.getMonth() + m, 1)); }; const moveYear = (y) => { const d = internalDate(); internalDate(new Date(d.getFullYear() + y, d.getMonth(), 1)); }; const HourSlider = ({ value: hVal, onChange }) => { return Tag("div", { class: "flex-1" }, [ Tag("div", { class: "flex gap-2 items-center" }, [ Tag("input", { type: "range", min: 0, max: 23, value: hVal, class: "range range-xs flex-1", oninput: (e) => { const newHour = parseInt(e.target.value); onChange(newHour); } }), Tag("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(val(hVal)).padStart(2, "0") + ":00") ]) ]); }; return Tag("div", { class: ui("relative w-full", className) }, [ Input({ label, placeholder: placeholder || (isRangeMode() ? "Seleccionar rango..." : "Seleccionar fecha..."), value: displayValue, readonly: true, icon: getIcon("icon-[lucide--calendar]"), onclick: (e) => { e.stopPropagation(); isOpen(!isOpen()); }, ...rest }), If(isOpen, () => Tag("div", { class: "absolute left-0 mt-2 p-4 bg-base-100 border border-base-300 shadow-2xl rounded-box z-[100] w-80 select-none", onclick: (e) => e.stopPropagation() }, [ Tag("div", { class: "flex justify-between items-center mb-4 gap-1" }, [ Tag("div", { class: "flex gap-0.5" }, [ Tag("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => moveYear(-1) }, getIcon("icon-[lucide--chevrons-left]")), Tag("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => move(-1) }, getIcon("icon-[lucide--chevron-left]")) ]), Tag("span", { class: "font-bold uppercase flex-1 text-center" }, [ () => internalDate().toLocaleString("es-ES", { month: "short", year: "numeric" }) ]), Tag("div", { class: "flex gap-0.5" }, [ Tag("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => move(1) }, getIcon("icon-[lucide--chevron-right]")), Tag("button", { type: "button", class: "btn btn-ghost btn-xs px-1", onclick: () => moveYear(1) }, getIcon("icon-[lucide--chevrons-right]")) ]) ]), Tag("div", { class: "grid grid-cols-7 gap-1", onmouseleave: () => hoverDate(null) }, [ ...["L", "M", "X", "J", "V", "S", "D"].map((d) => Tag("div", { class: "text-[10px] opacity-40 font-bold text-center" }, d)), () => { const d = internalDate(); const year = d.getFullYear(); const month = d.getMonth(); const firstDay = new Date(year, month, 1).getDay(); const offset = firstDay === 0 ? 6 : firstDay - 1; const daysInMonth = new Date(year, month + 1, 0).getDate(); const nodes = []; for (let i = 0;i < offset; i++) nodes.push(Tag("div")); for (let i = 1;i <= daysInMonth; i++) { const date = new Date(year, month, i); const dStr = formatDate(date); nodes.push(Tag("button", { type: "button", class: () => { const v = val(value); const h = hoverDate(); const isStart = typeof v === "string" ? v.split("T")[0] === dStr : v?.start === dStr; const isEnd = v?.end === dStr; let inRange = false; if (isRangeMode() && v?.start) { const start = v.start; if (!v.end && h) { inRange = dStr > start && dStr <= h || dStr < start && dStr >= h; } else if (v.end) { inRange = dStr > start && dStr < v.end; } } const base = "btn btn-xs p-0 aspect-square min-h-0 h-auto font-normal relative"; const state = isStart || isEnd ? "btn-primary z-10" : inRange ? "bg-primary/20 border-none rounded-none" : "btn-ghost"; const today = dStr === todayStr ? "ring-1 ring-primary ring-inset font-black text-primary" : ""; return `${base} ${state} ${today}`; }, onmouseenter: () => { if (isRangeMode()) hoverDate(dStr); }, onclick: () => selectDate(date) }, [i.toString()])); } return nodes; } ]), hour ? Tag("div", { class: "mt-3 pt-2 border-t border-base-300" }, [ isRangeMode() ? Tag("div", { class: "flex gap-4" }, [ HourSlider({ value: startHour, onChange: (newHour) => { startHour(newHour); const currentVal = val(value); if (currentVal?.start) value({ ...currentVal, startHour: newHour }); } }), HourSlider({ value: endHour, onChange: (newHour) => { endHour(newHour); const currentVal = val(value); if (currentVal?.end) value({ ...currentVal, endHour: newHour }); } }) ]) : HourSlider({ value: startHour, onChange: (newHour) => { startHour(newHour); const currentVal = val(value); if (currentVal && typeof currentVal === "string" && currentVal.includes("-")) { value(currentVal.split("T")[0] + "T" + String(newHour).padStart(2, "0") + ":00:00"); } } }) ]) : null ])), If(isOpen, () => Tag("div", { class: "fixed inset-0 z-[90]", onclick: () => isOpen(false) })) ]); }; // src/components/Drawer.js var exports_Drawer = {}; __export(exports_Drawer, { Drawer: () => Drawer }); var Drawer = (props, children) => { const { class: className, id, open, side, content, ...rest } = props; const drawerId = id || `drawer-${Math.random().toString(36).slice(2, 9)}`; return Tag("div", { ...rest, class: ui("drawer", className) }, [ Tag("input", { id: drawerId, type: "checkbox", class: "drawer-toggle", checked: () => typeof open === "function" ? open() : open, onchange: (e) => { if (typeof open === "function") open(e.target.checked); } }), Tag("div", { class: "drawer-content" }, [ typeof content === "function" ? content() : content ]), Tag("div", { class: "drawer-side" }, [ Tag("label", { for: drawerId, class: "drawer-overlay", onclick: () => { if (typeof open === "function") open(false); } }), Tag("div", { class: "min-h-full bg-base-200 w-80" }, [ typeof side === "function" ? side() : side ]) ]) ]); }; // src/components/Dropdown.js var exports_Dropdown = {}; __export(exports_Dropdown, { Dropdown: () => Dropdown }); var currentOpen = null; if (typeof window !== "undefined" && !window.__dropdownHandlerRegistered) { window.addEventListener("click", (e) => { if (currentOpen && !currentOpen.contains(e.target)) { currentOpen.open = false; currentOpen = null; } }); window.__dropdownHandlerRegistered = true; } var Dropdown = (props) => { const { class: className, label, icon, items, ...rest } = props; return Tag("details", { ...rest, class: ui("dropdown", className) }, [ Tag("summary", { class: "btn m-1 flex items-center gap-2 list-none cursor-pointer", style: "display: inline-flex;", onclick: (e) => { const details = e.currentTarget.closest("details"); if (currentOpen && currentOpen !== details) { currentOpen.open = false; } setTimeout(() => { currentOpen = details.open ? details : null; }, 0); } }, [ () => icon ? typeof icon === "function" ? icon() : icon : null, () => label ? typeof label === "function" ? label() : label : null ]), Tag("ul", { tabindex: "-1", class: "dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300" }, [ () => { const currentItems = typeof items === "function" ? items() : items || []; return currentItems.map((item) => Tag("li", {}, [ Tag("a", { class: item.class || "", onclick: (e) => { if (item.onclick) item.onclick(e); const details = e.currentTarget.closest("details"); if (details) { details.open = false; if (currentOpen === details) currentOpen = null; } } }, [ item.icon ? Tag("span", {}, item.icon) : null, Tag("span", {}, item.label) ]) ])); } ]) ]); }; // src/components/Fab.js var exports_Fab = {}; __export(exports_Fab, { Fab: () => Fab }); var Fab = (props) => { const { class: className, icon, label, actions = [], position = "bottom-6 right-6", ...rest } = props; return Tag("div", { ...rest, class: ui(`fab absolute ${position} flex flex-col-reverse items-end gap-3 z-[100]`, className) }, [ Tag("div", { tabindex: 0, role: "button", class: "btn btn-lg btn-circle btn-primary shadow-2xl" }, [ icon ? getIcon(icon) : null, !icon && label ? label : null ]), ...val(actions).map((act) => Tag("div", { class: "flex items-center gap-3 transition-all duration-300" }, [ act.label ? Tag("span", { class: "badge badge-ghost shadow-sm whitespace-nowrap" }, act.label) : null, Tag("button", { type: "button", class: `btn btn-circle shadow-lg ${act.class || ""}`, onclick: (e) => { e.stopPropagation(); act.onclick?.(e); } }, [act.icon ? getIcon(act.icon) : act.text || ""]) ])) ]); }; // src/components/Fieldset.js var exports_Fieldset = {}; __export(exports_Fieldset, { Fieldset: () => Fieldset }); var Fieldset = (props, children) => { const { class: className, legend, ...rest } = props; return Tag("fieldset", { ...rest, class: ui("fieldset bg-base-200 border border-base-300 p-4 rounded-lg", className) }, [ () => { const legendText = val(legend); return legendText ? Tag("legend", { class: "fieldset-legend font-bold" }, [legendText]) : null; }, children ]); }; // src/components/Fileinput.js var exports_Fileinput = {}; __export(exports_Fileinput, { Fileinput: () => Fileinput }); var Fileinput = (props) => { const { class: className, tooltip, max = 2, accept = "*", onselect, ...rest } = props; const selectedFiles = $([]); const isDragging = $(false); const error = $(null); const MAX_BYTES = max * 1024 * 1024; const handleFiles = (files) => { const fileList = Array.from(files); error(null); const oversized = fileList.find((f) => f.size > MAX_BYTES); if (oversized) { error(`Máx ${max}MB`); return; } selectedFiles([...selectedFiles(), ...fileList]); onselect?.(selectedFiles()); }; const removeFile = (index) => { const updated = selectedFiles().filter((_, i) => i !== index); selectedFiles(updated); onselect?.(updated); }; return Tag("fieldset", { ...rest, class: ui("fieldset w-full p-0", className) }, [ Tag("div", { class: () => `w-full ${tooltip ? "tooltip tooltip-top before:z-50 after:z-50" : ""}`, "data-tip": tooltip }, [ Tag("label", { class: () => ` relative flex items-center justify-between w-full h-12 px-4 border-2 border-dashed rounded-lg cursor-pointer transition-all duration-200 ${isDragging() ? "border-primary bg-primary/10" : "border-base-content/20 bg-base-100 hover:bg-base-200"} `, ondragover: (e) => { e.preventDefault(); isDragging(true); }, ondragleave: () => isDragging(false), ondrop: (e) => { e.preventDefault(); isDragging(false); handleFiles(e.dataTransfer.files); } }, [ Tag("div", { class: "flex items-center gap-3 w-full" }, [ getIcon("icon-[lucide--upload]"), Tag("span", { class: "text-sm opacity-70 truncate grow text-left" }, "Arrastra o selecciona archivos..."), Tag("span", { class: "text-[10px] opacity-40 shrink-0" }, `Máx ${max}MB`) ]), Tag("input", { type: "file", multiple: true, accept, class: "hidden", onchange: (e) => handleFiles(e.target.files) }) ]) ]), () => error() ? Tag("span", { class: "text-[10px] text-error mt-1 px-1 font-medium" }, error()) : null, If(() => selectedFiles().length > 0, () => Tag("ul", { class: "mt-2 space-y-1" }, [ For(selectedFiles, (file, index) => Tag("li", { class: "flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300" }, [ Tag("div", { class: "flex items-center gap-2 truncate" }, [ Tag("span", { class: "opacity-50" }, "\uD83D\uDCC4"), Tag("span", { class: "truncate font-medium max-w-[200px]" }, file.name), Tag("span", { class: "text-[9px] opacity-40" }, `(${(file.size / 1024).toFixed(0)} KB)`) ]), Tag("button", { type: "button", class: "btn btn-ghost btn-xs btn-circle", onclick: (e) => { e.preventDefault(); e.stopPropagation(); removeFile(index); } }, [getIcon("icon-[lucide--x]")]) ]), (file) => file.name + file.lastModified) ])) ]); }; // src/components/Indicator.js var exports_Indicator = {}; __export(exports_Indicator, { Indicator: () => Indicator }); var Indicator = (props, children) => { const { value, class: className, ...rest } = props; return Tag("div", { ...rest, class: "indicator" }, () => [ value ? Tag("span", { class: ui("indicator-item badge", className) }, () => typeof value === "function" ? value() : value) : null, children ].filter(Boolean)); }; // src/components/Label.js var exports_Label = {}; __export(exports_Label, { Label: () => Label }); var Label = (props) => { const { children, value, floating = false, class: className, ...rest } = props; if (floating) { return Tag("label", { class: ui("floating-label", className), ...rest }, () => [ typeof children === "function" ? children() : children, value ? Tag("span", {}, val(value)) : null ]); } return Tag("label", { class: ui("label", className), ...rest }, () => [ value ? Tag("span", { class: "label-text" }, val(value)) : null, typeof children === "function" ? children() : children ]); }; // src/components/List.js var exports_List = {}; __export(exports_List, { List: () => List }); var List = (props) => { const { class: className, items, header, render = (item) => item, keyFn = (item, index) => item.id ?? index, ...rest } = props; const listItems = For(items, (item, index) => Tag("li", { class: "list-row", style: "width: 100%; display: block;" }, [ Tag("div", { style: "width: 100%;" }, [render(item, index)]) ]), keyFn); return Tag("ul", { ...rest, style: "display: block; width: 100%;", class: ui("list bg-base-100 rounded-box shadow-md", className) }, header ? [If(header, () => Tag("li", { class: "p-4 pb-2 text-xs opacity-60", style: "width: 100%;" }, [val(header)])), listItems] : listItems); }; // src/components/Menu.js var exports_Menu = {}; __export(exports_Menu, { Menu: () => Menu }); var Menu = (props) => { const { class: className, items, ...rest } = props; const renderItems = (items2) => For(() => items2 || [], (it) => Tag("li", {}, [ it.children ? Tag("details", { open: it.open }, [ Tag("summary", {}, [it.icon && Tag("span", { class: "mr-2" }, it.icon), it.label]), Tag("ul", {}, renderItems(it.children)) ]) : Tag("a", { class: () => val(it.active) ? "active" : "", onclick: it.onclick }, [ it.icon && Tag("span", { class: "mr-2" }, it.icon), it.label ]) ]), (it, i) => it.label || i); return Tag("ul", { ...rest, class: ui("menu bg-base-200 rounded-box", className) }, renderItems(items)); }; // src/components/Modal.js var exports_Modal = {}; __export(exports_Modal, { Modal: () => Modal }); var Modal = (props, children) => { const { class: className, title, buttons, open, ...rest } = props; let dialogElement = null; const handleOpen = () => { const isOpen = typeof open === "function" ? open() : open; if (!dialogElement) return; if (isOpen) { if (!dialogElement.open) dialogElement.showModal(); } else { if (dialogElement.open) dialogElement.close(); } }; Watch(() => handleOpen()); const close = () => { if (typeof open === "function") open(false); }; return Tag("dialog", { ...rest, ref: (el) => { dialogElement = el; if (el) handleOpen(); }, class: ui("modal", className), onclose: close, oncancel: close }, [ Tag("div", { class: "modal-box" }, [ title ? Tag("h3", { class: "text-lg font-bold mb-4" }, () => typeof title === "function" ? title() : title) : null, Tag("div", { class: "py-2" }, [ typeof children === "function" ? children() : children ]), Tag("div", { class: "modal-action" }, [ Tag("form", { method: "dialog", class: "flex gap-2" }, [ ...(Array.isArray(buttons) ? buttons : [buttons]).filter(Boolean), Button({ type: "submit" }, tt("close")()) ]) ]) ]), Tag("form", { method: "dialog", class: "modal-backdrop" }, [ Tag("button", {}, "close") ]) ]); }; // src/components/Navbar.js var exports_Navbar = {}; __export(exports_Navbar, { Navbar: () => Navbar }); var Navbar = (props, children) => { const { class: className, ...rest } = props; return Tag("div", { ...rest, class: ui("navbar bg-base-100 shadow-sm px-4", className) }, children); }; // src/components/Radio.js var exports_Radio = {}; __export(exports_Radio, { Radio: () => Radio }); var Radio = (props) => { const { class: className, label, tooltip, value, inputValue, name, ...rest } = props; const radioEl = Tag("input", { ...rest, type: "radio", name, class: ui("radio", className), checked: () => val(value) === inputValue, onclick: () => { if (typeof value === "function") value(inputValue); } }); if (!label && !tooltip) return radioEl; const layout = Tag("label", { class: "label cursor-pointer justify-start gap-3" }, [ radioEl, label ? Tag("span", { class: "label-text" }, label) : null ]); return tooltip ? Tag("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout; }; // src/components/Range.js var exports_Range = {}; __export(exports_Range, { Range: () => Range }); var Range = (props) => { const { class: className, label, tooltip, value, ...rest } = props; const rangeEl = Tag("input", { ...rest, type: "range", class: ui("range", className), value, disabled: () => val(props.disabled) }); if (!label && !tooltip) return rangeEl; const layout = Tag("div", { class: "flex flex-col gap-2" }, [ label ? Tag("span", { class: "label-text" }, label) : null, rangeEl ]); return tooltip ? Tag("div", { class: "tooltip", "data-tip": tooltip }, layout) : layout; }; // src/components/Rating.js var exports_Rating = {}; __export(exports_Rating, { Rating: () => Rating }); var Rating = (props) => { const { class: className, value, count = 5, mask = "mask-star", readonly = false, onchange, ...rest } = props; const ratingGroup = `rating-${Math.random().toString(36).slice(2, 7)}`; return Tag("div", { ...rest, class: () => ui(`rating ${val(readonly) ? "pointer-events-none" : ""}`, className) }, Array.from({ length: val(count) }, (_, i) => { const starValue = i + 1; return Tag("input", { type: "radio", name: ratingGroup, class: `mask ${mask}`, checked: () => Math.round(val(value)) === starValue, onchange: () => { if (!val(readonly)) { if (typeof onchange === "function") { onchange(starValue); } else if (typeof value === "function") { value(starValue); } } } }); })); }; // src/components/Select.js var exports_Select = {}; __export(exports_Select, { Select: () => Select }); var Select = (props) => { const { class: className, label, items, value, ...rest } = props; const selectEl = Tag("select", { ...rest, class: ui("select select-bordered w-full", className), value }, For(() => val(items) || [], (opt) => Tag("option", { value: opt.value, $selected: () => String(val(value)) === String(opt.value) }, opt.label), (opt) => opt.value)); if (!label) return selectEl; return Tag("label", { class: "fieldset-label flex flex-col gap-1" }, [ Tag("span", {}, label), selectEl ]); }; // src/components/Stack.js var exports_Stack = {}; __export(exports_Stack, { Stack: () => Stack }); var Stack = (props, children) => { const { class: className, ...rest } = props; return Tag("div", { ...rest, class: ui("stack", className) }, children); }; // src/components/Stat.js var exports_Stat = {}; __export(exports_Stat, { Stat: () => Stat }); var Stat = (props) => { const { class: className, icon, label, value, desc, ...rest } = props; return Tag("div", { ...rest, class: ui("stat", className) }, [ icon && Tag("div", { class: "stat-figure text-secondary" }, icon), label && Tag("div", { class: "stat-title" }, label), Tag("div", { class: "stat-value" }, () => val(value) ?? value), desc && Tag("div", { class: "stat-desc" }, desc) ]); }; // src/components/Swap.js var exports_Swap = {}; __export(exports_Swap, { Swap: () => Swap }); var Swap = (props) => { const { class: className, value, on, off, ...rest } = props; return Tag("label", { ...rest, class: ui("swap", className) }, [ Tag("input", { type: "checkbox", checked: () => val(value), onclick: (e) => { if (typeof value === "function") { value(e.target.checked); } } }), Tag("div", { class: "swap-on" }, on), Tag("div", { class: "swap-off" }, off) ]); }; // src/components/Table.js var exports_Table = {}; __export(exports_Table, { Table: () => Table }); var Table = (props) => { const { class: className, items = [], columns = [], keyFn, zebra = false, pinRows = false, empty = tt("nodata")(), ...rest } = props; const tableClass = () => { const zebraClass = val(zebra) ? "table-zebra" : ""; const pinRowsClass = val(pinRows) ? "table-pin-rows" : ""; return ui("table", className, zebraClass, pinRowsClass); }; const getInternalKeyFn = keyFn || ((item, idx) => item.id || idx); return Tag("div", { class: "overflow-x-auto w-full bg-base-100 rounded-box border border-base-300" }, [ Tag("table", { ...rest, class: tableClass }, [ Tag("thead", {}, [ Tag("tr", {}, columns.map((col) => Tag("th", { class: col.class || "" }, col.label))) ]), Tag("tbody", {}, [ For(items, (item, index) => { const it = () => { const currentItems = val(items); const key = getInternalKeyFn(item, index); return currentItems.find((u, i) => getInternalKeyFn(u, i) === key) || item; }; return Tag("tr", { class: "hover" }, columns.map((col) => { const cellContent = () => { const latestItem = it(); if (col.render) return col.render(latestItem, index); return val(latestItem[col.key]); }; return Tag("td", { class: col.class || "" }, [cellContent]); })); }, getInternalKeyFn), If(() => val(items).length === 0, () => Tag("tr", {}, [ Tag("td", { colspan: columns.length, class: "text-center p-10 opacity-50" }, [ val(empty) ]) ])) ]) ]) ]); }; // src/components/Tabs.js var exports_Tabs = {}; __export(exports_Tabs, { Tabs: () => Tabs }); var 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); }); 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; 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); } } }); const label = val(item.label); if (label instanceof Node) { button.replaceChildren(label); } else { button.textContent = String(label); } elements.push(button); const panel = Tag("div", { class: "tab-content bg-base-100 border-base-300 p-6", style: () => isActive() ? "display: block" : "display: none" }, () => val(item.content)); elements.push(panel); } return elements; }); }; // src/components/Timeline.js var exports_Timeline = {}; __export(exports_Timeline, { Timeline: () => Timeline }); var Timeline = (props) => { const { class: className, items = [], vertical = true, compact = false, ...rest } = props; const iconMap = { info: "icon-[lucide--info]", success: "icon-[lucide--check-circle]", warning: "icon-[lucide--alert-triangle]", error: "icon-[lucide--alert-circle]" }; return Tag("ul", { ...rest, class: () => ui(`timeline ${val(vertical) ? "timeline-vertical" : "timeline-horizontal"} ${val(compact) ? "timeline-compact" : ""}`, className) }, () => { const list = (typeof items === "function" ? items() : items) || []; return list.map((item, i) => { const isFirst = i === 0; const isLast = i === list.length - 1; const itemType = item.type || "success"; const isCompleted = () => val(item.completed); const prevCompleted = () => i > 0 && val(list[i - 1].completed); const renderSlot = (content) => typeof content === "function" ? content() : content; return Tag("li", { class: "flex-1" }, [ !isFirst ? Tag("hr", { class: () => prevCompleted() ? "bg-primary" : "" }) : null, Tag("div", { class: "timeline-start" }, [() => renderSlot(item.title)]), Tag("div", { class: "timeline-middle" }, [ () => item.icon ? getIcon(item.icon) : getIcon(iconMap[itemType] || iconMap.success) ]), Tag("div", { class: "timeline-end timeline-box shadow-sm" }, [() => renderSlot(item.detail)]), !isLast ? Tag("hr", { class: () => isCompleted() ? "bg-primary" : "" }) : null ]); }); }); }; // src/components/Toast.js var exports_Toast = {}; __export(exports_Toast, { Toast: () => Toast }); var Toast = (message, type = "alert-success", duration = 3500) => { let container = document.getElementById("sigpro-toast-container"); if (!container) { container = Tag("div", { id: "sigpro-toast-container", class: "fixed top-0 right-0 z-[9999] p-4 flex flex-col gap-2 pointer-events-none" }); document.body.appendChild(container); } const toastHost = Tag("div", { style: "display: contents" }); container.appendChild(toastHost); let timeoutId; const close = () => { clearTimeout(timeoutId); const el = toastHost.firstElementChild; if (el && !el.classList.contains("opacity-0")) { el.classList.add("translate-x-full", "opacity-0"); setTimeout(() => { instance.destroy(); toastHost.remove(); if (!container.hasChildNodes()) container.remove(); }, 300); } else { instance.destroy(); toastHost.remove(); } }; const ToastComponent = () => { const closeIcon = getIcon("icon-[lucide--x]"); const el = Tag("div", { class: `alert alert-soft ${type} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto` }, [ Tag("span", {}, [typeof message === "function" ? message() : message]), Button({ class: "btn-xs btn-circle btn-ghost", onclick: close }, closeIcon) ]); requestAnimationFrame(() => el.classList.remove("translate-x-10", "opacity-0")); return el; }; const instance = Mount(ToastComponent, toastHost); if (duration > 0) { timeoutId = setTimeout(close, duration); } return close; }; // src/components/Tooltip.js var exports_Tooltip = {}; __export(exports_Tooltip, { Tooltip: () => Tooltip }); var Tooltip = (props, children) => Tag("div", { ...props, class: () => ui("tooltip w-full", props.class), "data-tip": props.tip }, children); // src/components/index.js var Components = { ...exports_Accordion, ...exports_Alert, ...exports_Autocomplete, ...exports_Badge, ...exports_Button, ...exports_Checkbox, ...exports_Colorpicker, ...exports_Datepicker, ...exports_Drawer, ...exports_Dropdown, ...exports_Fab, ...exports_Fieldset, ...exports_Fileinput, ...exports_Indicator, ...exports_Input, ...exports_Label, ...exports_List, ...exports_Menu, ...exports_Modal, ...exports_Navbar, ...exports_Radio, ...exports_Range, ...exports_Rating, ...exports_Select, ...exports_Stack, ...exports_Stat, ...exports_Swap, ...exports_Table, ...exports_Tabs, ...exports_Timeline, ...exports_Toast, ...exports_Tooltip }; var components_default = { ...Components, install: (target = window) => { Object.entries(Components).forEach(([name, component]) => { target[name] = component; }); console.log("\uD83D\uDE80 SigproUI"); } }; // index.js if (typeof window !== "undefined") { Object.entries(exports_components).forEach(([name, component]) => { Object.defineProperty(window, name, { value: component, writable: false, configurable: true, enumerable: true }); }); Object.entries(exports_utils).forEach(([name, fn]) => { Object.defineProperty(window, name, { value: fn, writable: false, configurable: true, enumerable: true }); }); Object.defineProperty(window, "tt", { value: tt, writable: false, configurable: true, enumerable: true }); Object.defineProperty(window, "SigProUI", { value: { ...exports_components, Utils: exports_utils, tt }, writable: false, configurable: true, enumerable: true }); console.log("\uD83C\uDFA8 SigProUI ready"); } export { val, ui, tt, getIcon, Watch2 as Watch, Tooltip, Toast, Timeline, Tag2 as Tag, Tabs, Table, Swap, Stat, Stack, Select, Router, Render, Rating, Range, Radio, Navbar, Mount2 as Mount, Modal, Menu, List, Label, Input, Indicator, If2 as If, For2 as For, Fileinput, Fieldset, Fab, Dropdown, Drawer, Datepicker, Colorpicker, Checkbox, Button, Badge, Autocomplete, Alert, Accordion, $$, $2 as $ };