diff --git a/dist/sigpro-ui.js b/dist/sigpro-ui.js index c845b01..e5d311d 100644 --- a/dist/sigpro-ui.js +++ b/dist/sigpro-ui.js @@ -68,7 +68,7 @@ Accordion: () => Accordion }); - // node_modules/sigpro/sigpro/index.js + // src/sigpro.js var activeEffect = null; var currentOwner = null; var effectQueue = new Set; @@ -272,6 +272,7 @@ } const el = document.createElement(tag), _sanitize = (key, val) => (key === "src" || key === "href") && String(val).toLowerCase().includes("javascript:") ? "#" : val; el._cleanups = new Set; + const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"]; for (let [key, val] of Object.entries(props)) { if (key === "ref") { typeof val === "function" ? val(el) : val.current = el; @@ -294,33 +295,54 @@ } else if (isSignal) { el._cleanups.add($watch2(() => { const currentVal = _sanitize(key, val()); - if (key === "class") + if (key === "class") { el.className = currentVal || ""; - else + } else if (boolAttrs.includes(key)) { + if (currentVal) { + el.setAttribute(key, ""); + el[key] = true; + } else { + el.removeAttribute(key); + el[key] = false; + } + } else { currentVal == null ? el.removeAttribute(key) : el.setAttribute(key, currentVal); + } })); } else { - el.setAttribute(key, _sanitize(key, val)); + if (boolAttrs.includes(key)) { + if (val) { + el.setAttribute(key, ""); + el[key] = true; + } else { + el.removeAttribute(key); + el[key] = false; + } + } else { + el.setAttribute(key, _sanitize(key, val)); + } } } const append = (child) => { if (Array.isArray(child)) return child.forEach(append); - if (typeof child === "function") { + if (child instanceof Node) { + el.appendChild(child); + } else if (typeof child === "function") { const marker = document.createTextNode(""); el.appendChild(marker); let nodes = []; el._cleanups.add($watch2(() => { - const result = child(), nextNodes = (Array.isArray(result) ? result : [result]).map((item) => item?._isRuntime ? item.container : item instanceof Node ? item : document.createTextNode(item ?? "")); - nodes.forEach((node) => { - sweep(node); - node.remove(); + const res = child(), next = (Array.isArray(res) ? res : [res]).map((i) => i?._isRuntime ? i.container : i instanceof Node ? i : document.createTextNode(i ?? "")); + nodes.forEach((n) => { + sweep?.(n); + n.remove(); }); - nextNodes.forEach((node) => marker.parentNode?.insertBefore(node, marker)); - nodes = nextNodes; + next.forEach((n) => marker.parentNode?.insertBefore(n, marker)); + nodes = next; })); } else - el.appendChild(child instanceof Node ? child : document.createTextNode(child ?? "")); + el.appendChild(document.createTextNode(child ?? "")); }; append(content); return el; @@ -345,9 +367,9 @@ return container; }; $if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal); - var $for = (source, render, keyFn) => { + var $for = (source, render, keyFn, tag = "div", props = { style: "display:contents" }) => { const marker = document.createTextNode(""); - const container = $html2("div", { style: "display:contents" }, [marker]); + const container = $html2(tag, props, [marker]); let cache = new Map; $watch2(() => { const items = (typeof source === "function" ? source() : source) || []; @@ -450,6 +472,7 @@ }; install(SigProCore); } + // src/components/index.js var exports_components = {}; __export(exports_components, { @@ -617,10 +640,12 @@ placeholder, disabled, size, + validate, ...rest } = props; const isPassword = type === "password"; const visible = $(false); + const errorMsg = $(null); const iconMap = { text: "icon-[lucide--text]", password: "icon-[lucide--lock]", @@ -644,16 +669,35 @@ 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 = $html2("input", { + ...rest, + type: () => isPassword ? visible() ? "text" : "password" : type, + placeholder: placeholder || " ", + class: inputClasses, + value, + oninput: handleInput, + disabled: () => val(disabled), + "aria-invalid": () => hasError() ? "true" : "false" + }); return $html2("div", { class: "relative w-full" }, () => [ - $html2("input", { - ...rest, - type: () => isPassword ? visible() ? "text" : "password" : type, - placeholder: placeholder || " ", - class: ui("input w-full", `${paddingLeft} ${paddingRight} ${className || ""}`.trim()), - value, - oninput: (e) => oninput?.(e), - disabled: () => val(disabled) - }), + inputElement, leftIcon ? $html2("div", { class: "absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60" }, leftIcon) : null, @@ -664,7 +708,10 @@ e.preventDefault(); visible(!visible()); } - }, () => getPasswordIcon()) : null + }, () => getPasswordIcon()) : null, + $html2("div", { + class: "text-error text-xs mt-1 px-3 absolute -bottom-5 left-0" + }, () => hasError() ? errorMsg() : null) ]); }; @@ -1353,7 +1400,7 @@ List: () => List }); var List = (props) => { - const { class: className, items, header, render, keyFn = (item, index) => index, ...rest } = props; + const { class: className, items, header, render, keyFn = (item, index) => item.id ?? index, ...rest } = props; const listItems = $for(items, (item, index) => $html2("li", { class: "list-row" }, [render(item, index)]), keyFn); return $html2("ul", { ...rest, @@ -1607,6 +1654,7 @@ const pinRowsClass = val(pinRows) ? "table-pin-rows" : ""; return ui("table", className, zebraClass, pinRowsClass); }; + const getInternalKeyFn = keyFn || ((item, idx) => item.id || idx); return $html2("div", { class: "overflow-x-auto w-full bg-base-100 rounded-box border border-base-300" }, [ $html2("table", { ...rest, class: tableClass }, [ $html2("thead", {}, [ @@ -1614,25 +1662,27 @@ ]), $html2("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 $html2("tr", { class: "hover" }, columns.map((col) => { const cellContent = () => { + const latestItem = it(); if (col.render) - return col.render(item, index); - const value = item[col.key]; - return val(value); + return col.render(latestItem, index); + return val(latestItem[col.key]); }; return $html2("td", { class: col.class || "" }, [cellContent]); })); - }, keyFn || ((item, idx) => item.id || idx)), + }, getInternalKeyFn), $if(() => val(items).length === 0, () => $html2("tr", {}, [ $html2("td", { colspan: columns.length, class: "text-center p-10 opacity-50" }, [ val(empty) ]) ])) - ]), - $if(() => columns.some((c) => c.footer), () => $html2("tfoot", {}, [ - $html2("tr", {}, columns.map((col) => $html2("th", {}, col.footer || ""))) - ])) + ]) ]) ]); }; @@ -1645,55 +1695,55 @@ var Tabs = (props) => { const { items, class: className, ...rest } = props; const itemsSignal = typeof items === "function" ? items : () => items || []; - const name = `tabs-${Math.random().toString(36).slice(2, 9)}`; - const getActiveIndex = () => { - const arr = itemsSignal(); - const idx = arr.findIndex((it) => val(it.active) === true); - return idx === -1 ? 0 : idx; - }; - const activeIndex = $(getActiveIndex); - const updateActiveIndex = () => { - const newIndex = getActiveIndex(); - if (newIndex !== activeIndex()) - activeIndex(newIndex); - }; - $watch(() => updateActiveIndex()); - return $html2("div", { - ...rest, - class: ui("tabs", className || "tabs-box") - }, [ - $for(itemsSignal, (it, idx) => { - const isChecked = () => activeIndex() === idx; - const getLabelText = () => { - const label = typeof it.label === "function" ? it.label() : it.label; - return typeof label === "string" ? label : `Tab ${idx + 1}`; - }; - return [ - $html2("input", { - type: "radio", - name, - class: "tab", - "aria-label": getLabelText(), - checked: isChecked, - disabled: () => val(it.disabled), - onchange: (e) => { - if (e.target.checked && !val(it.disabled)) { + const activeIndex = $(0); + $watch(() => { + const idx = itemsSignal().findIndex((it) => val(it.active) === true); + if (idx !== -1 && idx !== activeIndex()) + activeIndex(idx); + }); + return $html2("div", { ...rest, class: "w-full" }, [ + $html2("div", { + role: "tablist", + class: ui("tabs", className || "tabs-box") + }, () => { + const list = itemsSignal(); + return list.map((it, idx) => { + const isSelected = () => activeIndex() === idx; + const tab = $html2("button", { + role: "tab", + class: () => ui("tab", isSelected() ? "tab-active" : ""), + onclick: (e) => { + e.preventDefault(); + if (!val(it.disabled)) { if (it.onclick) it.onclick(); - if (typeof it.active === "function") - it.active(true); activeIndex(idx); } } - }), - $html2("div", { + }); + $watch(() => { + const content = val(it.label); + if (content instanceof Node) { + tab.replaceChildren(content); + } else { + tab.textContent = String(content); + } + }); + return tab; + }); + }), + $html2("div", { class: "tab-panels" }, () => { + return itemsSignal().map((it, idx) => { + const isVisible = () => activeIndex() === idx; + return $html2("div", { + role: "tabpanel", class: "tab-content bg-base-100 border-base-300 p-6", - style: () => isChecked() ? "display: block" : "display: none" + style: () => isVisible() ? "display: block" : "display: none" }, [ - typeof it.content === "function" ? it.content() : it.content - ]) - ]; - }, (it, idx) => idx) + () => typeof it.content === "function" ? it.content() : it.content + ]); + }); + }) ]); }; @@ -1710,27 +1760,29 @@ warning: "icon-[lucide--alert-triangle]", error: "icon-[lucide--alert-circle]" }; - const itemsSource = typeof items === "function" ? items : () => items || []; return $html2("ul", { ...rest, class: () => ui(`timeline ${val(vertical) ? "timeline-vertical" : "timeline-horizontal"} ${val(compact) ? "timeline-compact" : ""}`, className) - }, [ - $for(itemsSource, (item, i) => { + }, () => { + const list = (typeof items === "function" ? items() : items) || []; + return list.map((item, i) => { const isFirst = i === 0; - const isLast = i === itemsSource().length - 1; + 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 $html2("li", { class: "flex-1" }, [ - !isFirst ? $html2("hr", { class: () => item.completed ? "bg-primary" : "" }) : null, - $html2("div", { class: "timeline-start" }, () => renderSlot(item.title)), - $html2("div", { class: "timeline-middle" }, () => [ - item.icon ? getIcon(item.icon) : getIcon(iconMap[itemType] || iconMap.success) + !isFirst ? $html2("hr", { class: () => prevCompleted() ? "bg-primary" : "" }) : null, + $html2("div", { class: "timeline-start" }, [() => renderSlot(item.title)]), + $html2("div", { class: "timeline-middle" }, [ + () => item.icon ? getIcon(item.icon) : getIcon(iconMap[itemType] || iconMap.success) ]), - $html2("div", { class: "timeline-end timeline-box shadow-sm" }, () => renderSlot(item.detail)), - !isLast ? $html2("hr", { class: () => item.completed ? "bg-primary" : "" }) : null + $html2("div", { class: "timeline-end timeline-box shadow-sm" }, [() => renderSlot(item.detail)]), + !isLast ? $html2("hr", { class: () => isCompleted() ? "bg-primary" : "" }) : null ]); - }, (item, i) => item.id || i) - ]); + }); + }); }; // src/components/Toast.js diff --git a/dist/sigpro-ui.min.js b/dist/sigpro-ui.min.js index 70fd10d..aaa0514 100644 --- a/dist/sigpro-ui.min.js +++ b/dist/sigpro-ui.min.js @@ -1,7 +1,7 @@ -(()=>{var{defineProperty:e,getOwnPropertyNames:UJ,getOwnPropertyDescriptor:VJ}=Object,HJ=Object.prototype.hasOwnProperty;var TJ=new WeakMap,jJ=(W)=>{var X=TJ.get(W),Z;if(X)return X;if(X=e({},"__esModule",{value:!0}),W&&typeof W==="object"||typeof W==="function")UJ(W).map((J)=>!HJ.call(X,J)&&e(X,J,{get:()=>W[J],enumerable:!(Z=VJ(W,J))||Z.enumerable}));return TJ.set(W,X),X};var z=(W,X)=>{for(var Z in X)e(W,Z,{get:X[Z],enumerable:!0,configurable:!0,set:(J)=>X[Z]=()=>J})};var xJ={};z(xJ,{val:()=>_,ui:()=>P,tt:()=>x,getIcon:()=>V,Tooltip:()=>qJ,Toast:()=>QJ,Timeline:()=>GJ,Tabs:()=>ZJ,Table:()=>KJ,Swap:()=>MJ,Stat:()=>tM,Stack:()=>lM,Select:()=>aM,Rating:()=>iM,Range:()=>cM,Radio:()=>dM,Navbar:()=>mM,Modal:()=>gM,Menu:()=>vM,List:()=>yM,Label:()=>wM,Input:()=>g,Indicator:()=>xM,Fileinput:()=>OM,Fieldset:()=>EM,Fab:()=>jM,Dropdown:()=>VM,Drawer:()=>DM,Datepicker:()=>zM,Colorpicker:()=>CM,Checkbox:()=>PM,Button:()=>h,Badge:()=>BM,Autocomplete:()=>LM,Alert:()=>GM,Accordion:()=>ZM});var O=null,y=null,d=new Set,p=!1,MM=new WeakMap,SJ=()=>{if(p)return;p=!0;while(d.size>0){let W=Array.from(d).sort((X,Z)=>(X.depth||0)-(Z.depth||0));d.clear();for(let X of W)if(!X._deleted)X()}p=!1},CJ=(W)=>{if(O&&!O._deleted)W.add(O),O._deps.add(W)},JM=(W)=>{for(let X of W){if(X===O||X._deleted)continue;if(X._isComputed){if(X.markDirty(),X._subs)JM(X._subs)}else d.add(X)}if(!p)queueMicrotask(SJ)},KM=(W)=>{if(W._cleanups)W._cleanups.forEach((X)=>X()),W._cleanups.clear();W.childNodes?.forEach(KM)},c=(W)=>{let X=new Set,Z=y,J=document.createElement("div");J.style.display="contents",y={cleanups:X};try{let Y=W({onCleanup:(K)=>X.add(K)}),Q=(K)=>{if(!K)return;if(K._isRuntime)X.add(K.destroy),J.appendChild(K.container);else if(Array.isArray(K))K.forEach(Q);else J.appendChild(K instanceof Node?K:document.createTextNode(String(K)))};Q(Y)}finally{y=Z}return{_isRuntime:!0,container:J,destroy:()=>{X.forEach((Y)=>Y()),KM(J),J.remove()}}},U=(W,X=null)=>{if(typeof W==="function"){let Y=new Set,Q,K=!0,G=()=>{if(G._deleted)return;G._deps.forEach((L)=>L.delete(G)),G._deps.clear();let q=O;O=G;try{let L=W();if(!Object.is(Q,L)||K)Q=L,K=!1,JM(Y)}finally{O=q}};if(G._deps=new Set,G._isComputed=!0,G._subs=Y,G._deleted=!1,G.markDirty=()=>K=!0,G.stop=()=>{G._deleted=!0,G._deps.forEach((q)=>q.delete(G)),Y.clear()},y)y.cleanups.add(G.stop);return()=>{if(K)G();return CJ(Y),Q}}let Z=W;if(X)try{let Y=localStorage.getItem(X);if(Y!==null)Z=JSON.parse(Y)}catch(Y){console.warn("SigPro: LocalStorage locked",Y)}let J=new Set;return(...Y)=>{if(Y.length){let Q=typeof Y[0]==="function"?Y[0](Z):Y[0];if(!Object.is(Z,Q)){if(Z=Q,X)localStorage.setItem(X,JSON.stringify(Z));JM(J)}}return CJ(J),Z}},$=(W,X)=>{let Z=Array.isArray(W),J=Z?X:W,Y=Z?W:null;if(typeof J!=="function")return()=>{};let Q=y,K=()=>{if(K._deleted)return;K._deps.forEach((L)=>L.delete(K)),K._deps.clear(),K._cleanups.forEach((L)=>L()),K._cleanups.clear();let G=O,q=y;O=K,y={cleanups:K._cleanups},K.depth=G?G.depth+1:0;try{if(Z)O=null,J(),O=K,Y.forEach((L)=>typeof L==="function"&&L());else J()}finally{O=G,y=q}};if(K._deps=new Set,K._cleanups=new Set,K._deleted=!1,K.stop=()=>{if(K._deleted)return;if(K._deleted=!0,d.delete(K),K._deps.forEach((G)=>G.delete(K)),K._cleanups.forEach((G)=>G()),Q)Q.cleanups.delete(K.stop)},Q)Q.cleanups.add(K.stop);return K(),K.stop},M=(W,X={},Z=[])=>{if(X instanceof Node||Array.isArray(X)||typeof X!=="object")Z=X,X={};let J=document.createElement(W),Y=(K,G)=>(K==="src"||K==="href")&&String(G).toLowerCase().includes("javascript:")?"#":G;J._cleanups=new Set;for(let[K,G]of Object.entries(X)){if(K==="ref"){typeof G==="function"?G(J):G.current=J;continue}let q=typeof G==="function";if(["INPUT","TEXTAREA","SELECT"].includes(J.tagName)&&(K==="value"||K==="checked")&&q){J._cleanups.add($(()=>{let C=G();if(J[K]!==C)J[K]=C}));let A=K==="checked"?"change":"input",D=(C)=>G(C.target[K]);J.addEventListener(A,D),J._cleanups.add(()=>J.removeEventListener(A,D))}else if(K.startsWith("on")){let A=K.slice(2).toLowerCase().split(".")[0],D=(C)=>G(C);J.addEventListener(A,D),J._cleanups.add(()=>J.removeEventListener(A,D))}else if(q)J._cleanups.add($(()=>{let A=Y(K,G());if(K==="class")J.className=A||"";else A==null?J.removeAttribute(K):J.setAttribute(K,A)}));else J.setAttribute(K,Y(K,G))}let Q=(K)=>{if(Array.isArray(K))return K.forEach(Q);if(typeof K==="function"){let G=document.createTextNode("");J.appendChild(G);let q=[];J._cleanups.add($(()=>{let L=K(),B=(Array.isArray(L)?L:[L]).map((A)=>A?._isRuntime?A.container:A instanceof Node?A:document.createTextNode(A??""));q.forEach((A)=>{KM(A),A.remove()}),B.forEach((A)=>G.parentNode?.insertBefore(A,G)),q=B}))}else J.appendChild(K instanceof Node?K:document.createTextNode(K??""))};return Q(Z),J},E=(W,X,Z=null)=>{let J=document.createTextNode(""),Y=M("div",{style:"display:contents"},[J]),Q=null,K=null;return $(()=>{let G=!!(typeof W==="function"?W():W);if(G!==K){if(K=G,Q)Q.destroy();let q=G?X:Z;if(q)Q=c(()=>typeof q==="function"?q():q),Y.insertBefore(Q.container,J)}}),Y};E.not=(W,X,Z)=>E(()=>!(typeof W==="function"?W():W),X,Z);var j=(W,X,Z)=>{let J=document.createTextNode(""),Y=M("div",{style:"display:contents"},[J]),Q=new Map;return $(()=>{let K=(typeof W==="function"?W():W)||[],G=new Map,q=[];for(let B=0;BX(A,B));else Q.delete(D);G.set(D,C),q.push(D)}Q.forEach((B)=>{B.destroy(),B.container.remove()});let L=J;for(let B=q.length-1;B>=0;B--){let A=G.get(q[B]);if(A.container.nextSibling!==L)Y.insertBefore(A.container,L);L=A.container}Q=G}),Y},b=(W)=>{let X=U(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>X(window.location.hash.replace(/^#/,"")||"/"));let Z=M("div",{class:"router-outlet"}),J=null;return $([X],async()=>{let Y=X(),Q=W.find((K)=>{let G=K.path.split("/").filter(Boolean),q=Y.split("/").filter(Boolean);return G.length===q.length&&G.every((L,B)=>L.startsWith(":")||L===q[B])})||W.find((K)=>K.path==="*");if(Q){let K=Q.component;if(typeof K==="function"&&K.toString().includes("import"))K=(await K()).default||await K();let G={};if(Q.path.split("/").filter(Boolean).forEach((q,L)=>{if(q.startsWith(":"))G[q.slice(1)]=Y.split("/").filter(Boolean)[L]}),J)J.destroy();if(b.params)b.params(G);J=c(()=>{try{return typeof K==="function"?K(G):K}catch(q){return M("div",{class:"p-4 text-error"},"Error loading view")}}),Z.appendChild(J.container)}}),Z};b.params=U({});b.to=(W)=>window.location.hash=W.replace(/^#?\/?/,"#/");b.back=()=>window.history.back();b.path=()=>window.location.hash.replace(/^#/,"")||"/";var WM=(W,X)=>{let Z=typeof X==="string"?document.querySelector(X):X;if(!Z)return;if(MM.has(Z))MM.get(Z).destroy();let J=c(typeof W==="function"?W:()=>W);return Z.replaceChildren(J.container),MM.set(Z,J),J},EJ={$:U,$watch:$,$html:M,$if:E,$for:j,$router:b,$mount:WM};if(typeof window<"u")((X)=>{Object.keys(X).forEach((J)=>{window[J]=X[J]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((J)=>{let Y=J.charAt(0).toUpperCase()+J.slice(1);if(!(Y in window))window[Y]=(Q,K)=>M(J,Q,K)}),window.SigPro=Object.freeze(X)})(EJ);var i={};z(i,{default:()=>IJ,Tooltip:()=>qJ,Toast:()=>QJ,Timeline:()=>GJ,Tabs:()=>ZJ,Table:()=>KJ,Swap:()=>MJ,Stat:()=>tM,Stack:()=>lM,Select:()=>aM,Rating:()=>iM,Range:()=>cM,Radio:()=>dM,Navbar:()=>mM,Modal:()=>gM,Menu:()=>vM,List:()=>yM,Label:()=>wM,Input:()=>g,Indicator:()=>xM,Fileinput:()=>OM,Fieldset:()=>EM,Fab:()=>jM,Dropdown:()=>VM,Drawer:()=>DM,Datepicker:()=>zM,Colorpicker:()=>CM,Checkbox:()=>PM,Button:()=>h,Badge:()=>BM,Autocomplete:()=>LM,Alert:()=>GM,Accordion:()=>ZM});var XM={};z(XM,{Accordion:()=>ZM});var o={};z(o,{val:()=>_,ui:()=>P,getIcon:()=>V});var _=(W)=>typeof W==="function"?W():W,P=(W,X)=>typeof X==="function"?()=>`${W} ${X()||""}`.trim():`${W} ${X||""}`.trim(),V=(W)=>{if(!W)return null;if(typeof W==="function")return M("span",{class:"mr-1"},W());if(typeof W==="object")return M("span",{class:"mr-1"},W);if(typeof W==="string"){let X=W.trim().split(/\s+/),Z=X[X.length-1]==="right",J=Z?X.slice(0,-1).join(" "):W,Y=Z?"ml-1":"mr-1";if(J&&!J.startsWith("icon-[")&&!J.includes("--"))return M("span",{class:Y},J);return M("span",{class:`${J} ${Y}`.trim()})}return null};var ZM=(W,X)=>{let{class:Z,title:J,name:Y,open:Q,...K}=W;return M("div",{...K,class:P("collapse collapse-arrow bg-base-200 mb-2",Z)},[M("input",{type:Y?"radio":"checkbox",name:Y,checked:_(Q)}),M("div",{class:"collapse-title text-xl font-medium"},J),M("div",{class:"collapse-content"},X)])};var YM={};z(YM,{Alert:()=>GM});var GM=(W,X)=>{let{class:Z,actions:J,type:Y="info",soft:Q=!0,...K}=W,G={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"},B=[`alert-${Y}`,Q?"alert-soft":"",Z].filter(Boolean).join(" "),A=X||W.message;return M("div",{...K,role:"alert",class:P("alert",B)},()=>[V(G[Y]),M("div",{class:"flex-1"},[M("span",{},[typeof A==="function"?A():A])]),J?M("div",{class:"flex-none"},[typeof J==="function"?J():J]):null].filter(Boolean))};var qM={};z(qM,{Autocomplete:()=>LM});var NJ={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"}},OJ=U("es");var x=(W)=>()=>NJ[OJ()][W]||W;var QM={};z(QM,{Input:()=>g});var g=(W)=>{let{class:X,value:Z,type:J="text",icon:Y,oninput:Q,placeholder:K,disabled:G,size:q,...L}=W,B=J==="password",A=U(!1),D={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]"},C=Y?V(Y):D[J]?V(D[J]):null,R=()=>V(A()?"icon-[lucide--eye-off]":"icon-[lucide--eye]"),H=C?"pl-10":"",N=B?"pr-10":"",r=()=>{if(X?.includes("input-xs"))return"btn-xs";if(X?.includes("input-sm"))return"btn-sm";if(X?.includes("input-lg"))return"btn-lg";return"btn-md"};return M("div",{class:"relative w-full"},()=>[M("input",{...L,type:()=>B?A()?"text":"password":J,placeholder:K||" ",class:P("input w-full",`${H} ${N} ${X||""}`.trim()),value:Z,oninput:(m)=>Q?.(m),disabled:()=>_(G)}),C?M("div",{class:"absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60"},C):null,B?M("button",{type:"button",class:P("absolute right-3 inset-y-0 flex items-center","btn btn-ghost btn-circle opacity-50 hover:opacity-100",r()),onclick:(m)=>{m.preventDefault(),A(!A())}},()=>R()):null])};var LM=(W)=>{let{class:X,items:Z=[],value:J,onSelect:Y,label:Q,placeholder:K,...G}=W,q=U(_(J)||""),L=U(!1),B=U(-1),A=U(()=>{let R=q().toLowerCase(),H=_(Z)||[];return R?H.filter((N)=>(typeof N==="string"?N:N.label).toLowerCase().includes(R)):H}),D=(R)=>{let H=typeof R==="string"?R:R.value,N=typeof R==="string"?R:R.label;if(q(N),typeof J==="function")J(H);Y?.(R),L(!1),B(-1)},C=(R)=>{let H=A();if(R.key==="ArrowDown")R.preventDefault(),L(!0),B(Math.min(B()+1,H.length-1));else if(R.key==="ArrowUp")R.preventDefault(),B(Math.max(B()-1,0));else if(R.key==="Enter"&&B()>=0)R.preventDefault(),D(H[B()]);else if(R.key==="Escape")L(!1)};return M("div",{class:"relative w-full"},[g({label:Q,class:X,placeholder:K||x("search")(),value:q,onfocus:()=>L(!0),onblur:()=>setTimeout(()=>L(!1),150),onkeydown:C,oninput:(R)=>{let H=R.target.value;if(q(H),typeof J==="function")J(H);L(!0),B(-1)},...G}),M("ul",{class:"absolute 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:()=>L()&&A().length?"display:block":"display:none"},[j(A,(R,H)=>M("li",{},[M("a",{class:()=>`block w-full ${B()===H?"active bg-primary text-primary-content":""}`,onclick:()=>D(R),onmouseenter:()=>B(H)},typeof R==="string"?R:R.label)]),(R,H)=>(typeof R==="string"?R:R.value)+H),()=>A().length?null:M("li",{class:"p-2 text-center opacity-50"},x("nodata")())])])};var AM={};z(AM,{Badge:()=>BM});var BM=(W,X)=>{let{class:Z,...J}=W;return M("span",{...J,class:P("badge",Z)},X)};var _M={};z(_M,{Button:()=>h});var h=(W,X)=>{let{class:Z,loading:J,icon:Y,...Q}=W,K=V(Y);return M("button",{...Q,class:P("btn",Z),disabled:()=>_(J)||_(W.disabled)},()=>[_(J)&&M("span",{class:"loading loading-spinner"}),K,X].filter(Boolean))};var TM={};z(TM,{Checkbox:()=>PM});var PM=(W)=>{let{class:X,value:Z,tooltip:J,toggle:Y,label:Q,...K}=W,G=M("input",{...K,type:"checkbox",class:()=>P(_(Y)?"toggle":"checkbox",X),checked:Z}),q=M("label",{class:"label cursor-pointer justify-start gap-3"},[G,Q?M("span",{class:"label-text"},Q):null]);return J?M("div",{class:"tooltip","data-tip":J},q):q};var RM={};z(RM,{Colorpicker:()=>CM});var CM=(W)=>{let{class:X,value:Z,label:J,...Y}=W,Q=U(!1),K=["#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"],G=()=>_(Z)||"#000000";return M("div",{class:P("relative w-fit",X)},[M("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:(q)=>{q.stopPropagation(),Q(!Q())},...Y},[M("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${G()}`}),J?M("span",{class:"opacity-80"},J):null]),E(Q,()=>M("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:(q)=>q.stopPropagation()},[M("div",{class:"grid grid-cols-8 gap-1"},K.map((q)=>M("button",{type:"button",style:`background-color: ${q}`,class:()=>{return`size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 - ${G().toLowerCase()===q.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""}`},onclick:()=>{if(typeof Z==="function")Z(q);Q(!1)}})))])),E(Q,()=>M("div",{class:"fixed inset-0 z-[100]",onclick:()=>Q(!1)}))])};var FM={};z(FM,{Datepicker:()=>zM});var zM=(W)=>{let{class:X,value:Z,range:J,label:Y,placeholder:Q,hour:K=!1,...G}=W,q=U(!1),L=U(new Date),B=U(null),A=U(0),D=U(0),C=()=>_(J)===!0,R=new Date,H=`${R.getFullYear()}-${String(R.getMonth()+1).padStart(2,"0")}-${String(R.getDate()).padStart(2,"0")}`,N=(T)=>{let F=T.getFullYear(),S=String(T.getMonth()+1).padStart(2,"0"),k=String(T.getDate()).padStart(2,"0");return`${F}-${S}-${k}`},r=(T)=>{let F=N(T),S=_(Z);if(C())if(!S?.start||S.start&&S.end){if(typeof Z==="function")Z({start:F,end:null,...K&&{startHour:A()}})}else{let k=S.start;if(typeof Z==="function"){let u=F{let T=_(Z);if(!T)return"";if(typeof T==="string"){if(K&&T.includes("T"))return T.replace("T"," ");return T}if(T.start&&T.end){let F=K&&T.startHour?`${T.start} ${String(T.startHour).padStart(2,"0")}:00`:T.start,S=K&&T.endHour?`${T.end} ${String(T.endHour).padStart(2,"0")}:00`:T.end;return`${F} - ${S}`}if(T.start)return`${K&&T.startHour?`${T.start} ${String(T.startHour).padStart(2,"0")}:00`:T.start}...`;return""}),AJ=(T)=>{let F=L();L(new Date(F.getFullYear(),F.getMonth()+T,1))},_J=(T)=>{let F=L();L(new Date(F.getFullYear()+T,F.getMonth(),1))},a=({value:T,onChange:F})=>{return M("div",{class:"flex-1"},[M("div",{class:"flex gap-2 items-center"},[M("input",{type:"range",min:0,max:23,value:T,class:"range range-xs flex-1",oninput:(S)=>{let k=parseInt(S.target.value);F(k)}}),M("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(_(T)).padStart(2,"0")+":00")])])};return M("div",{class:P("relative w-full",X)},[g({label:Y,placeholder:Q||(C()?"Seleccionar rango...":"Seleccionar fecha..."),value:m,readonly:!0,icon:V("icon-[lucide--calendar]"),onclick:(T)=>{T.stopPropagation(),q(!q())},...G}),E(q,()=>M("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:(T)=>T.stopPropagation()},[M("div",{class:"flex justify-between items-center mb-4 gap-1"},[M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>_J(-1)},V("icon-[lucide--chevrons-left]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>AJ(-1)},V("icon-[lucide--chevron-left]"))]),M("span",{class:"font-bold uppercase flex-1 text-center"},[()=>L().toLocaleString("es-ES",{month:"short",year:"numeric"})]),M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>AJ(1)},V("icon-[lucide--chevron-right]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>_J(1)},V("icon-[lucide--chevrons-right]"))])]),M("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>B(null)},[...["L","M","X","J","V","S","D"].map((T)=>M("div",{class:"text-[10px] opacity-40 font-bold text-center"},T)),()=>{let T=L(),F=T.getFullYear(),S=T.getMonth(),k=new Date(F,S,1).getDay(),u=k===0?6:k-1,zJ=new Date(F,S+1,0).getDate(),s=[];for(let v=0;v{let f=_(Z),l=B(),FJ=typeof f==="string"?f.split("T")[0]===I:f?.start===I,DJ=f?.end===I,n=!1;if(C()&&f?.start){let t=f.start;if(!f.end&&l)n=I>t&&I<=l||I=l;else if(f.end)n=I>t&&I{if(C())B(I)},onclick:()=>r(PJ)},[v.toString()]))}return s}]),K?M("div",{class:"mt-3 pt-2 border-t border-base-300"},[C()?M("div",{class:"flex gap-4"},[a({value:A,onChange:(T)=>{A(T);let F=_(Z);if(F?.start)Z({...F,startHour:T})}}),a({value:D,onChange:(T)=>{D(T);let F=_(Z);if(F?.end)Z({...F,endHour:T})}})]):a({value:A,onChange:(T)=>{A(T);let F=_(Z);if(F&&typeof F==="string"&&F.includes("-"))Z(F.split("T")[0]+"T"+String(T).padStart(2,"0")+":00:00")}})]):null])),E(q,()=>M("div",{class:"fixed inset-0 z-[90]",onclick:()=>q(!1)}))])};var UM={};z(UM,{Drawer:()=>DM});var DM=(W,X)=>{let{class:Z,id:J,open:Y,side:Q,content:K,...G}=W,q=J||`drawer-${Math.random().toString(36).slice(2,9)}`;return M("div",{...G,class:P("drawer",Z)},[M("input",{id:q,type:"checkbox",class:"drawer-toggle",checked:()=>typeof Y==="function"?Y():Y,onchange:(L)=>{if(typeof Y==="function")Y(L.target.checked)}}),M("div",{class:"drawer-content"},[typeof K==="function"?K():K]),M("div",{class:"drawer-side"},[M("label",{for:q,class:"drawer-overlay",onclick:()=>{if(typeof Y==="function")Y(!1)}}),M("div",{class:"min-h-full bg-base-200 w-80"},[typeof Q==="function"?Q():Q])])])};var HM={};z(HM,{Dropdown:()=>VM});var w=null;if(typeof window<"u"&&!window.__dropdownHandlerRegistered)window.addEventListener("click",(W)=>{if(w&&!w.contains(W.target))w.open=!1,w=null}),window.__dropdownHandlerRegistered=!0;var VM=(W)=>{let{class:X,label:Z,icon:J,items:Y,...Q}=W;return $html("details",{...Q,class:P("dropdown",X)},[$html("summary",{class:"btn m-1 flex items-center gap-2 list-none cursor-pointer",style:"display: inline-flex;",onclick:(K)=>{let G=K.currentTarget.closest("details");if(w&&w!==G)w.open=!1;setTimeout(()=>{w=G.open?G:null},0)}},[()=>J?typeof J==="function"?J():J:null,()=>Z?typeof Z==="function"?Z():Z:null]),$html("ul",{tabindex:"-1",class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"},[()=>{return(typeof Y==="function"?Y():Y||[]).map((G)=>$html("li",{},[$html("a",{class:G.class||"",onclick:(q)=>{if(G.onclick)G.onclick(q);let L=q.currentTarget.closest("details");if(L){if(L.open=!1,w===L)w=null}}},[G.icon?$html("span",{},G.icon):null,$html("span",{},G.label)])]))}])])};var SM={};z(SM,{Fab:()=>jM});var jM=(W)=>{let{class:X,icon:Z,label:J,actions:Y=[],position:Q="bottom-6 right-6",...K}=W;return M("div",{...K,class:P(`fab absolute ${Q} flex flex-col-reverse items-end gap-3 z-[100]`,X)},[M("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[Z?V(Z):null,!Z&&J?J:null]),..._(Y).map((G)=>M("div",{class:"flex items-center gap-3 transition-all duration-300"},[G.label?M("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},G.label):null,M("button",{type:"button",class:`btn btn-circle shadow-lg ${G.class||""}`,onclick:(q)=>{q.stopPropagation(),G.onclick?.(q)}},[G.icon?V(G.icon):G.text||""])]))])};var NM={};z(NM,{Fieldset:()=>EM});var EM=(W,X)=>{let{class:Z,legend:J,...Y}=W;return M("fieldset",{...Y,class:P("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",Z)},[()=>{let Q=_(J);return Q?M("legend",{class:"fieldset-legend font-bold"},[Q]):null},X])};var IM={};z(IM,{Fileinput:()=>OM});var OM=(W)=>{let{class:X,tooltip:Z,max:J=2,accept:Y="*",onSelect:Q,...K}=W,G=U([]),q=U(!1),L=U(null),B=J*1024*1024,A=(C)=>{let R=Array.from(C);if(L(null),R.find((N)=>N.size>B)){L(`Máx ${J}MB`);return}G([...G(),...R]),Q?.(G())},D=(C)=>{let R=G().filter((H,N)=>N!==C);G(R),Q?.(R)};return M("fieldset",{...K,class:P("fieldset w-full p-0",X)},[M("div",{class:()=>`w-full ${Z?"tooltip tooltip-top before:z-50 after:z-50":""}`,"data-tip":Z},[M("label",{class:()=>` +(()=>{var{defineProperty:JM,getOwnPropertyNames:UJ,getOwnPropertyDescriptor:HJ}=Object,VJ=Object.prototype.hasOwnProperty;var TJ=new WeakMap,SJ=(Z)=>{var K=TJ.get(Z),G;if(K)return K;if(K=JM({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function")UJ(Z).map((J)=>!VJ.call(K,J)&&JM(K,J,{get:()=>Z[J],enumerable:!(G=HJ(Z,J))||G.enumerable}));return TJ.set(Z,K),K};var U=(Z,K)=>{for(var G in K)JM(Z,G,{get:K[G],enumerable:!0,configurable:!0,set:(J)=>K[G]=()=>J})};var xJ={};U(xJ,{val:()=>q,ui:()=>_,tt:()=>k,getIcon:()=>V,Tooltip:()=>AJ,Toast:()=>BJ,Timeline:()=>QJ,Tabs:()=>KJ,Table:()=>XJ,Swap:()=>WJ,Stat:()=>MJ,Stack:()=>tM,Select:()=>nM,Rating:()=>aM,Range:()=>iM,Radio:()=>cM,Navbar:()=>dM,Modal:()=>mM,Menu:()=>gM,List:()=>vM,Label:()=>yM,Input:()=>m,Indicator:()=>wM,Fileinput:()=>xM,Fieldset:()=>jM,Fab:()=>NM,Dropdown:()=>SM,Drawer:()=>HM,Datepicker:()=>FM,Colorpicker:()=>RM,Checkbox:()=>CM,Button:()=>u,Badge:()=>_M,Autocomplete:()=>qM,Alert:()=>QM,Accordion:()=>KM});var j=null,$=null,p=new Set,i=!1,WM=new WeakMap,EJ=()=>{if(i)return;i=!0;while(p.size>0){let Z=Array.from(p).sort((K,G)=>(K.depth||0)-(G.depth||0));p.clear();for(let K of Z)if(!K._deleted)K()}i=!1},CJ=(Z)=>{if(j&&!j._deleted)Z.add(j),j._deps.add(Z)},ZM=(Z)=>{for(let K of Z){if(K===j||K._deleted)continue;if(K._isComputed){if(K.markDirty(),K._subs)ZM(K._subs)}else p.add(K)}if(!i)queueMicrotask(EJ)},XM=(Z)=>{if(Z._cleanups)Z._cleanups.forEach((K)=>K()),Z._cleanups.clear();Z.childNodes?.forEach(XM)},r=(Z)=>{let K=new Set,G=$,J=document.createElement("div");J.style.display="contents",$={cleanups:K};try{let Y=Z({onCleanup:(X)=>K.add(X)}),L=(X)=>{if(!X)return;if(X._isRuntime)K.add(X.destroy),J.appendChild(X.container);else if(Array.isArray(X))X.forEach(L);else J.appendChild(X instanceof Node?X:document.createTextNode(String(X)))};L(Y)}finally{$=G}return{_isRuntime:!0,container:J,destroy:()=>{K.forEach((Y)=>Y()),XM(J),J.remove()}}},H=(Z,K=null)=>{if(typeof Z==="function"){let Y=new Set,L,X=!0,W=()=>{if(W._deleted)return;W._deps.forEach((B)=>B.delete(W)),W._deps.clear();let Q=j;j=W;try{let B=Z();if(!Object.is(L,B)||X)L=B,X=!1,ZM(Y)}finally{j=Q}};if(W._deps=new Set,W._isComputed=!0,W._subs=Y,W._deleted=!1,W.markDirty=()=>X=!0,W.stop=()=>{W._deleted=!0,W._deps.forEach((Q)=>Q.delete(W)),Y.clear()},$)$.cleanups.add(W.stop);return()=>{if(X)W();return CJ(Y),L}}let G=Z;if(K)try{let Y=localStorage.getItem(K);if(Y!==null)G=JSON.parse(Y)}catch(Y){console.warn("SigPro: LocalStorage locked",Y)}let J=new Set;return(...Y)=>{if(Y.length){let L=typeof Y[0]==="function"?Y[0](G):Y[0];if(!Object.is(G,L)){if(G=L,K)localStorage.setItem(K,JSON.stringify(G));ZM(J)}}return CJ(J),G}},w=(Z,K)=>{let G=Array.isArray(Z),J=G?K:Z,Y=G?Z:null;if(typeof J!=="function")return()=>{};let L=$,X=()=>{if(X._deleted)return;X._deps.forEach((B)=>B.delete(X)),X._deps.clear(),X._cleanups.forEach((B)=>B()),X._cleanups.clear();let W=j,Q=$;j=X,$={cleanups:X._cleanups},X.depth=W?W.depth+1:0;try{if(G)j=null,J(),j=X,Y.forEach((B)=>typeof B==="function"&&B());else J()}finally{j=W,$=Q}};if(X._deps=new Set,X._cleanups=new Set,X._deleted=!1,X.stop=()=>{if(X._deleted)return;if(X._deleted=!0,p.delete(X),X._deps.forEach((W)=>W.delete(X)),X._cleanups.forEach((W)=>W()),L)L.cleanups.delete(X.stop)},L)L.cleanups.add(X.stop);return X(),X.stop},M=(Z,K={},G=[])=>{if(K instanceof Node||Array.isArray(K)||typeof K!=="object")G=K,K={};let J=document.createElement(Z),Y=(W,Q)=>(W==="src"||W==="href")&&String(Q).toLowerCase().includes("javascript:")?"#":Q;J._cleanups=new Set;let L=["disabled","checked","required","readonly","selected","multiple","autofocus"];for(let[W,Q]of Object.entries(K)){if(W==="ref"){typeof Q==="function"?Q(J):Q.current=J;continue}let B=typeof Q==="function";if(["INPUT","TEXTAREA","SELECT"].includes(J.tagName)&&(W==="value"||W==="checked")&&B){J._cleanups.add(w(()=>{let A=Q();if(J[W]!==A)J[W]=A}));let P=W==="checked"?"change":"input",R=(A)=>Q(A.target[W]);J.addEventListener(P,R),J._cleanups.add(()=>J.removeEventListener(P,R))}else if(W.startsWith("on")){let P=W.slice(2).toLowerCase().split(".")[0],R=(A)=>Q(A);J.addEventListener(P,R),J._cleanups.add(()=>J.removeEventListener(P,R))}else if(B)J._cleanups.add(w(()=>{let P=Y(W,Q());if(W==="class")J.className=P||"";else if(L.includes(W))if(P)J.setAttribute(W,""),J[W]=!0;else J.removeAttribute(W),J[W]=!1;else P==null?J.removeAttribute(W):J.setAttribute(W,P)}));else if(L.includes(W))if(Q)J.setAttribute(W,""),J[W]=!0;else J.removeAttribute(W),J[W]=!1;else J.setAttribute(W,Y(W,Q))}let X=(W)=>{if(Array.isArray(W))return W.forEach(X);if(W instanceof Node)J.appendChild(W);else if(typeof W==="function"){let Q=document.createTextNode("");J.appendChild(Q);let B=[];J._cleanups.add(w(()=>{let z=W(),T=(Array.isArray(z)?z:[z]).map((P)=>P?._isRuntime?P.container:P instanceof Node?P:document.createTextNode(P??""));B.forEach((P)=>{XM?.(P),P.remove()}),T.forEach((P)=>Q.parentNode?.insertBefore(P,Q)),B=T}))}else J.appendChild(document.createTextNode(W??""))};return X(G),J},N=(Z,K,G=null)=>{let J=document.createTextNode(""),Y=M("div",{style:"display:contents"},[J]),L=null,X=null;return w(()=>{let W=!!(typeof Z==="function"?Z():Z);if(W!==X){if(X=W,L)L.destroy();let Q=W?K:G;if(Q)L=r(()=>typeof Q==="function"?Q():Q),Y.insertBefore(L.container,J)}}),Y};N.not=(Z,K,G)=>N(()=>!(typeof Z==="function"?Z():Z),K,G);var O=(Z,K,G,J="div",Y={style:"display:contents"})=>{let L=document.createTextNode(""),X=M(J,Y,[L]),W=new Map;return w(()=>{let Q=(typeof Z==="function"?Z():Z)||[],B=new Map,z=[];for(let P=0;PK(R,P));else W.delete(A);B.set(A,D),z.push(A)}W.forEach((P)=>{P.destroy(),P.container.remove()});let T=L;for(let P=z.length-1;P>=0;P--){let R=B.get(z[P]);if(R.container.nextSibling!==T)X.insertBefore(R.container,T);T=R.container}W=B}),X},h=(Z)=>{let K=H(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>K(window.location.hash.replace(/^#/,"")||"/"));let G=M("div",{class:"router-outlet"}),J=null;return w([K],async()=>{let Y=K(),L=Z.find((X)=>{let W=X.path.split("/").filter(Boolean),Q=Y.split("/").filter(Boolean);return W.length===Q.length&&W.every((B,z)=>B.startsWith(":")||B===Q[z])})||Z.find((X)=>X.path==="*");if(L){let X=L.component;if(typeof X==="function"&&X.toString().includes("import"))X=(await X()).default||await X();let W={};if(L.path.split("/").filter(Boolean).forEach((Q,B)=>{if(Q.startsWith(":"))W[Q.slice(1)]=Y.split("/").filter(Boolean)[B]}),J)J.destroy();if(h.params)h.params(W);J=r(()=>{try{return typeof X==="function"?X(W):X}catch(Q){return M("div",{class:"p-4 text-error"},"Error loading view")}}),G.appendChild(J.container)}}),G};h.params=H({});h.to=(Z)=>window.location.hash=Z.replace(/^#?\/?/,"#/");h.back=()=>window.history.back();h.path=()=>window.location.hash.replace(/^#/,"")||"/";var GM=(Z,K)=>{let G=typeof K==="string"?document.querySelector(K):K;if(!G)return;if(WM.has(G))WM.get(G).destroy();let J=r(typeof Z==="function"?Z:()=>Z);return G.replaceChildren(J.container),WM.set(G,J),J},NJ={$:H,$watch:w,$html:M,$if:N,$for:O,$router:h,$mount:GM};if(typeof window<"u")((K)=>{Object.keys(K).forEach((J)=>{window[J]=K[J]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((J)=>{let Y=J.charAt(0).toUpperCase()+J.slice(1);if(!(Y in window))window[Y]=(L,X)=>M(J,L,X)}),window.SigPro=Object.freeze(K)})(NJ);var l={};U(l,{default:()=>IJ,Tooltip:()=>AJ,Toast:()=>BJ,Timeline:()=>QJ,Tabs:()=>KJ,Table:()=>XJ,Swap:()=>WJ,Stat:()=>MJ,Stack:()=>tM,Select:()=>nM,Rating:()=>aM,Range:()=>iM,Radio:()=>cM,Navbar:()=>dM,Modal:()=>mM,Menu:()=>gM,List:()=>vM,Label:()=>yM,Input:()=>m,Indicator:()=>wM,Fileinput:()=>xM,Fieldset:()=>jM,Fab:()=>NM,Dropdown:()=>SM,Drawer:()=>HM,Datepicker:()=>FM,Colorpicker:()=>RM,Checkbox:()=>CM,Button:()=>u,Badge:()=>_M,Autocomplete:()=>qM,Alert:()=>QM,Accordion:()=>KM});var YM={};U(YM,{Accordion:()=>KM});var a={};U(a,{val:()=>q,ui:()=>_,getIcon:()=>V});var q=(Z)=>typeof Z==="function"?Z():Z,_=(Z,K)=>typeof K==="function"?()=>`${Z} ${K()||""}`.trim():`${Z} ${K||""}`.trim(),V=(Z)=>{if(!Z)return null;if(typeof Z==="function")return M("span",{class:"mr-1"},Z());if(typeof Z==="object")return M("span",{class:"mr-1"},Z);if(typeof Z==="string"){let K=Z.trim().split(/\s+/),G=K[K.length-1]==="right",J=G?K.slice(0,-1).join(" "):Z,Y=G?"ml-1":"mr-1";if(J&&!J.startsWith("icon-[")&&!J.includes("--"))return M("span",{class:Y},J);return M("span",{class:`${J} ${Y}`.trim()})}return null};var KM=(Z,K)=>{let{class:G,title:J,name:Y,open:L,...X}=Z;return M("div",{...X,class:_("collapse collapse-arrow bg-base-200 mb-2",G)},[M("input",{type:Y?"radio":"checkbox",name:Y,checked:q(L)}),M("div",{class:"collapse-title text-xl font-medium"},J),M("div",{class:"collapse-content"},K)])};var LM={};U(LM,{Alert:()=>QM});var QM=(Z,K)=>{let{class:G,actions:J,type:Y="info",soft:L=!0,...X}=Z,W={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"},z=[`alert-${Y}`,L?"alert-soft":"",G].filter(Boolean).join(" "),T=K||Z.message;return M("div",{...X,role:"alert",class:_("alert",z)},()=>[V(W[Y]),M("div",{class:"flex-1"},[M("span",{},[typeof T==="function"?T():T])]),J?M("div",{class:"flex-none"},[typeof J==="function"?J():J]):null].filter(Boolean))};var AM={};U(AM,{Autocomplete:()=>qM});var OJ={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"}},jJ=H("es");var k=(Z)=>()=>OJ[jJ()][Z]||Z;var BM={};U(BM,{Input:()=>m});var m=(Z)=>{let{class:K,value:G,type:J="text",icon:Y,oninput:L,placeholder:X,disabled:W,size:Q,validate:B,...z}=Z,T=J==="password",P=H(!1),R=H(null),A={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]"},D=Y?V(Y):A[J]?V(A[J]):null,E=()=>V(P()?"icon-[lucide--eye-off]":"icon-[lucide--eye]"),d=D?"pl-10":"",n=T?"pr-10":"",c=()=>{if(K?.includes("input-xs"))return"btn-xs";if(K?.includes("input-sm"))return"btn-sm";if(K?.includes("input-lg"))return"btn-lg";return"btn-md"},o=(S)=>{let I=S.target.value;if(B){let b=B(I);R(b||null)}L?.(S)},v=()=>R()&&R()!=="",F=M("input",{...z,type:()=>T?P()?"text":"password":J,placeholder:X||" ",class:()=>{let S=`input w-full ${d} ${n}`;if(K)S+=` ${K}`;if(v())S+=" input-error";return S.trim()},value:G,oninput:o,disabled:()=>q(W),"aria-invalid":()=>v()?"true":"false"});return M("div",{class:"relative w-full"},()=>[F,D?M("div",{class:"absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60"},D):null,T?M("button",{type:"button",class:_("absolute right-3 inset-y-0 flex items-center","btn btn-ghost btn-circle opacity-50 hover:opacity-100",c()),onclick:(S)=>{S.preventDefault(),P(!P())}},()=>E()):null,M("div",{class:"text-error text-xs mt-1 px-3 absolute -bottom-5 left-0"},()=>v()?R():null)])};var qM=(Z)=>{let{class:K,items:G=[],value:J,onSelect:Y,label:L,placeholder:X,...W}=Z,Q=H(q(J)||""),B=H(!1),z=H(-1),T=H(()=>{let A=Q().toLowerCase(),D=q(G)||[];return A?D.filter((E)=>(typeof E==="string"?E:E.label).toLowerCase().includes(A)):D}),P=(A)=>{let D=typeof A==="string"?A:A.value,E=typeof A==="string"?A:A.label;if(Q(E),typeof J==="function")J(D);Y?.(A),B(!1),z(-1)},R=(A)=>{let D=T();if(A.key==="ArrowDown")A.preventDefault(),B(!0),z(Math.min(z()+1,D.length-1));else if(A.key==="ArrowUp")A.preventDefault(),z(Math.max(z()-1,0));else if(A.key==="Enter"&&z()>=0)A.preventDefault(),P(D[z()]);else if(A.key==="Escape")B(!1)};return M("div",{class:"relative w-full"},[m({label:L,class:K,placeholder:X||k("search")(),value:Q,onfocus:()=>B(!0),onblur:()=>setTimeout(()=>B(!1),150),onkeydown:R,oninput:(A)=>{let D=A.target.value;if(Q(D),typeof J==="function")J(D);B(!0),z(-1)},...W}),M("ul",{class:"absolute 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:()=>B()&&T().length?"display:block":"display:none"},[O(T,(A,D)=>M("li",{},[M("a",{class:()=>`block w-full ${z()===D?"active bg-primary text-primary-content":""}`,onclick:()=>P(A),onmouseenter:()=>z(D)},typeof A==="string"?A:A.label)]),(A,D)=>(typeof A==="string"?A:A.value)+D),()=>T().length?null:M("li",{class:"p-2 text-center opacity-50"},k("nodata")())])])};var PM={};U(PM,{Badge:()=>_M});var _M=(Z,K)=>{let{class:G,...J}=Z;return M("span",{...J,class:_("badge",G)},K)};var TM={};U(TM,{Button:()=>u});var u=(Z,K)=>{let{class:G,loading:J,icon:Y,...L}=Z,X=V(Y);return M("button",{...L,class:_("btn",G),disabled:()=>q(J)||q(Z.disabled)},()=>[q(J)&&M("span",{class:"loading loading-spinner"}),X,K].filter(Boolean))};var zM={};U(zM,{Checkbox:()=>CM});var CM=(Z)=>{let{class:K,value:G,tooltip:J,toggle:Y,label:L,...X}=Z,W=M("input",{...X,type:"checkbox",class:()=>_(q(Y)?"toggle":"checkbox",K),checked:G}),Q=M("label",{class:"label cursor-pointer justify-start gap-3"},[W,L?M("span",{class:"label-text"},L):null]);return J?M("div",{class:"tooltip","data-tip":J},Q):Q};var DM={};U(DM,{Colorpicker:()=>RM});var RM=(Z)=>{let{class:K,value:G,label:J,...Y}=Z,L=H(!1),X=["#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"],W=()=>q(G)||"#000000";return M("div",{class:_("relative w-fit",K)},[M("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:(Q)=>{Q.stopPropagation(),L(!L())},...Y},[M("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${W()}`}),J?M("span",{class:"opacity-80"},J):null]),N(L,()=>M("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:(Q)=>Q.stopPropagation()},[M("div",{class:"grid grid-cols-8 gap-1"},X.map((Q)=>M("button",{type:"button",style:`background-color: ${Q}`,class:()=>{return`size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 + ${W().toLowerCase()===Q.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""}`},onclick:()=>{if(typeof G==="function")G(Q);L(!1)}})))])),N(L,()=>M("div",{class:"fixed inset-0 z-[100]",onclick:()=>L(!1)}))])};var UM={};U(UM,{Datepicker:()=>FM});var FM=(Z)=>{let{class:K,value:G,range:J,label:Y,placeholder:L,hour:X=!1,...W}=Z,Q=H(!1),B=H(new Date),z=H(null),T=H(0),P=H(0),R=()=>q(J)===!0,A=new Date,D=`${A.getFullYear()}-${String(A.getMonth()+1).padStart(2,"0")}-${String(A.getDate()).padStart(2,"0")}`,E=(C)=>{let F=C.getFullYear(),S=String(C.getMonth()+1).padStart(2,"0"),I=String(C.getDate()).padStart(2,"0");return`${F}-${S}-${I}`},d=(C)=>{let F=E(C),S=q(G);if(R())if(!S?.start||S.start&&S.end){if(typeof G==="function")G({start:F,end:null,...X&&{startHour:T()}})}else{let I=S.start;if(typeof G==="function"){let b=F{let C=q(G);if(!C)return"";if(typeof C==="string"){if(X&&C.includes("T"))return C.replace("T"," ");return C}if(C.start&&C.end){let F=X&&C.startHour?`${C.start} ${String(C.startHour).padStart(2,"0")}:00`:C.start,S=X&&C.endHour?`${C.end} ${String(C.endHour).padStart(2,"0")}:00`:C.end;return`${F} - ${S}`}if(C.start)return`${X&&C.startHour?`${C.start} ${String(C.startHour).padStart(2,"0")}:00`:C.start}...`;return""}),c=(C)=>{let F=B();B(new Date(F.getFullYear(),F.getMonth()+C,1))},o=(C)=>{let F=B();B(new Date(F.getFullYear()+C,F.getMonth(),1))},v=({value:C,onChange:F})=>{return M("div",{class:"flex-1"},[M("div",{class:"flex gap-2 items-center"},[M("input",{type:"range",min:0,max:23,value:C,class:"range range-xs flex-1",oninput:(S)=>{let I=parseInt(S.target.value);F(I)}}),M("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(q(C)).padStart(2,"0")+":00")])])};return M("div",{class:_("relative w-full",K)},[m({label:Y,placeholder:L||(R()?"Seleccionar rango...":"Seleccionar fecha..."),value:n,readonly:!0,icon:V("icon-[lucide--calendar]"),onclick:(C)=>{C.stopPropagation(),Q(!Q())},...W}),N(Q,()=>M("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:(C)=>C.stopPropagation()},[M("div",{class:"flex justify-between items-center mb-4 gap-1"},[M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>o(-1)},V("icon-[lucide--chevrons-left]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>c(-1)},V("icon-[lucide--chevron-left]"))]),M("span",{class:"font-bold uppercase flex-1 text-center"},[()=>B().toLocaleString("es-ES",{month:"short",year:"numeric"})]),M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>c(1)},V("icon-[lucide--chevron-right]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>o(1)},V("icon-[lucide--chevrons-right]"))])]),M("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>z(null)},[...["L","M","X","J","V","S","D"].map((C)=>M("div",{class:"text-[10px] opacity-40 font-bold text-center"},C)),()=>{let C=B(),F=C.getFullYear(),S=C.getMonth(),I=new Date(F,S,1).getDay(),b=I===0?6:I-1,RJ=new Date(F,S+1,0).getDate(),s=[];for(let g=0;g{let y=q(G),t=z(),DJ=typeof y==="string"?y.split("T")[0]===x:y?.start===x,FJ=y?.end===x,e=!1;if(R()&&y?.start){let MM=y.start;if(!y.end&&t)e=x>MM&&x<=t||x=t;else if(y.end)e=x>MM&&x{if(R())z(x)},onclick:()=>d(PJ)},[g.toString()]))}return s}]),X?M("div",{class:"mt-3 pt-2 border-t border-base-300"},[R()?M("div",{class:"flex gap-4"},[v({value:T,onChange:(C)=>{T(C);let F=q(G);if(F?.start)G({...F,startHour:C})}}),v({value:P,onChange:(C)=>{P(C);let F=q(G);if(F?.end)G({...F,endHour:C})}})]):v({value:T,onChange:(C)=>{T(C);let F=q(G);if(F&&typeof F==="string"&&F.includes("-"))G(F.split("T")[0]+"T"+String(C).padStart(2,"0")+":00:00")}})]):null])),N(Q,()=>M("div",{class:"fixed inset-0 z-[90]",onclick:()=>Q(!1)}))])};var VM={};U(VM,{Drawer:()=>HM});var HM=(Z,K)=>{let{class:G,id:J,open:Y,side:L,content:X,...W}=Z,Q=J||`drawer-${Math.random().toString(36).slice(2,9)}`;return M("div",{...W,class:_("drawer",G)},[M("input",{id:Q,type:"checkbox",class:"drawer-toggle",checked:()=>typeof Y==="function"?Y():Y,onchange:(B)=>{if(typeof Y==="function")Y(B.target.checked)}}),M("div",{class:"drawer-content"},[typeof X==="function"?X():X]),M("div",{class:"drawer-side"},[M("label",{for:Q,class:"drawer-overlay",onclick:()=>{if(typeof Y==="function")Y(!1)}}),M("div",{class:"min-h-full bg-base-200 w-80"},[typeof L==="function"?L():L])])])};var EM={};U(EM,{Dropdown:()=>SM});var f=null;if(typeof window<"u"&&!window.__dropdownHandlerRegistered)window.addEventListener("click",(Z)=>{if(f&&!f.contains(Z.target))f.open=!1,f=null}),window.__dropdownHandlerRegistered=!0;var SM=(Z)=>{let{class:K,label:G,icon:J,items:Y,...L}=Z;return $html("details",{...L,class:_("dropdown",K)},[$html("summary",{class:"btn m-1 flex items-center gap-2 list-none cursor-pointer",style:"display: inline-flex;",onclick:(X)=>{let W=X.currentTarget.closest("details");if(f&&f!==W)f.open=!1;setTimeout(()=>{f=W.open?W:null},0)}},[()=>J?typeof J==="function"?J():J:null,()=>G?typeof G==="function"?G():G:null]),$html("ul",{tabindex:"-1",class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"},[()=>{return(typeof Y==="function"?Y():Y||[]).map((W)=>$html("li",{},[$html("a",{class:W.class||"",onclick:(Q)=>{if(W.onclick)W.onclick(Q);let B=Q.currentTarget.closest("details");if(B){if(B.open=!1,f===B)f=null}}},[W.icon?$html("span",{},W.icon):null,$html("span",{},W.label)])]))}])])};var OM={};U(OM,{Fab:()=>NM});var NM=(Z)=>{let{class:K,icon:G,label:J,actions:Y=[],position:L="bottom-6 right-6",...X}=Z;return M("div",{...X,class:_(`fab absolute ${L} flex flex-col-reverse items-end gap-3 z-[100]`,K)},[M("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[G?V(G):null,!G&&J?J:null]),...q(Y).map((W)=>M("div",{class:"flex items-center gap-3 transition-all duration-300"},[W.label?M("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},W.label):null,M("button",{type:"button",class:`btn btn-circle shadow-lg ${W.class||""}`,onclick:(Q)=>{Q.stopPropagation(),W.onclick?.(Q)}},[W.icon?V(W.icon):W.text||""])]))])};var IM={};U(IM,{Fieldset:()=>jM});var jM=(Z,K)=>{let{class:G,legend:J,...Y}=Z;return M("fieldset",{...Y,class:_("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",G)},[()=>{let L=q(J);return L?M("legend",{class:"fieldset-legend font-bold"},[L]):null},K])};var kM={};U(kM,{Fileinput:()=>xM});var xM=(Z)=>{let{class:K,tooltip:G,max:J=2,accept:Y="*",onSelect:L,...X}=Z,W=H([]),Q=H(!1),B=H(null),z=J*1024*1024,T=(R)=>{let A=Array.from(R);if(B(null),A.find((E)=>E.size>z)){B(`Máx ${J}MB`);return}W([...W(),...A]),L?.(W())},P=(R)=>{let A=W().filter((D,E)=>E!==R);W(A),L?.(A)};return M("fieldset",{...X,class:_("fieldset w-full p-0",K)},[M("div",{class:()=>`w-full ${G?"tooltip tooltip-top before:z-50 after:z-50":""}`,"data-tip":G},[M("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 - ${q()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"} - `,ondragover:(C)=>{C.preventDefault(),q(!0)},ondragleave:()=>q(!1),ondrop:(C)=>{C.preventDefault(),q(!1),A(C.dataTransfer.files)}},[M("div",{class:"flex items-center gap-3 w-full"},[V("icon-[lucide--upload]"),M("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),M("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${J}MB`)]),M("input",{type:"file",multiple:!0,accept:Y,class:"hidden",onchange:(C)=>A(C.target.files)})])]),()=>L()?M("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},L()):null,E(()=>G().length>0,()=>M("ul",{class:"mt-2 space-y-1"},[j(G,(C,R)=>M("li",{class:"flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300"},[M("div",{class:"flex items-center gap-2 truncate"},[M("span",{class:"opacity-50"},"\uD83D\uDCC4"),M("span",{class:"truncate font-medium max-w-[200px]"},C.name),M("span",{class:"text-[9px] opacity-40"},`(${(C.size/1024).toFixed(0)} KB)`)]),M("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:(H)=>{H.preventDefault(),H.stopPropagation(),D(R)}},[V("icon-[lucide--x]")])]),(C)=>C.name+C.lastModified)]))])};var kM={};z(kM,{Indicator:()=>xM});var xM=(W,X)=>{let{value:Z,class:J,...Y}=W;return M("div",{...Y,class:"indicator"},()=>[Z?M("span",{class:P("indicator-item badge",J)},()=>typeof Z==="function"?Z():Z):null,X].filter(Boolean))};var fM={};z(fM,{Label:()=>wM});var wM=(W)=>{let{children:X,value:Z,floating:J=!1,error:Y,required:Q,class:K,...G}=W;if(J)return M("label",{class:P("floating-label w-full",K),...G},()=>[Z?M("span",{},Z):null,X,Y?M("span",{class:"text-error text-xs"},_(Y)):null]);return M("label",{class:P("input w-full",K),...G},()=>[Z?M("span",{class:"label"},Z):null,X,Y?M("span",{class:"text-error text-xs"},_(Y)):null])};var $M={};z($M,{List:()=>yM});var yM=(W)=>{let{class:X,items:Z,header:J,render:Y,keyFn:Q=(q,L)=>L,...K}=W,G=j(Z,(q,L)=>M("li",{class:"list-row"},[Y(q,L)]),Q);return M("ul",{...K,class:P("list bg-base-100 rounded-box shadow-md",X)},J?[E(J,()=>M("li",{class:"p-4 pb-2 text-xs opacity-60"},[_(J)])),G]:G)};var bM={};z(bM,{Menu:()=>vM});var vM=(W)=>{let{class:X,items:Z,...J}=W,Y=(Q)=>j(()=>Q||[],(K)=>M("li",{},[K.children?M("details",{open:K.open},[M("summary",{},[K.icon&&M("span",{class:"mr-2"},K.icon),K.label]),M("ul",{},Y(K.children))]):M("a",{class:()=>_(K.active)?"active":"",onclick:K.onclick},[K.icon&&M("span",{class:"mr-2"},K.icon),K.label])]),(K,G)=>K.label||G);return M("ul",{...J,class:P("menu bg-base-200 rounded-box",X)},Y(Z))};var hM={};z(hM,{Modal:()=>gM});var gM=(W,X)=>{let{class:Z,title:J,buttons:Y,open:Q,...K}=W,G=null,q=()=>{let B=typeof Q==="function"?Q():Q;if(!G)return;if(B){if(!G.open)G.showModal()}else if(G.open)G.close()};$(()=>q());let L=()=>{if(typeof Q==="function")Q(!1)};return M("dialog",{...K,ref:(B)=>{if(G=B,B)q()},class:P("modal",Z),onclose:L,oncancel:L},[M("div",{class:"modal-box"},[J?M("h3",{class:"text-lg font-bold mb-4"},()=>typeof J==="function"?J():J):null,M("div",{class:"py-2"},[typeof X==="function"?X():X]),M("div",{class:"modal-action"},[M("form",{method:"dialog",class:"flex gap-2"},[...(Array.isArray(Y)?Y:[Y]).filter(Boolean),h({type:"submit"},x("close")())])])]),M("form",{method:"dialog",class:"modal-backdrop"},[M("button",{},"close")])])};var uM={};z(uM,{Navbar:()=>mM});var mM=(W,X)=>{let{class:Z,...J}=W;return M("div",{...J,class:P("navbar bg-base-100 shadow-sm px-4",Z)},X)};var pM={};z(pM,{Radio:()=>dM});var dM=(W)=>{let{class:X,label:Z,tooltip:J,value:Y,inputValue:Q,name:K,...G}=W,q=M("input",{...G,type:"radio",name:K,class:P("radio",X),checked:()=>_(Y)===Q,onclick:()=>{if(typeof Y==="function")Y(Q)}});if(!Z&&!J)return q;let L=M("label",{class:"label cursor-pointer justify-start gap-3"},[q,Z?M("span",{class:"label-text"},Z):null]);return J?M("div",{class:"tooltip","data-tip":J},L):L};var oM={};z(oM,{Range:()=>cM});var cM=(W)=>{let{class:X,label:Z,tooltip:J,value:Y,...Q}=W,K=M("input",{...Q,type:"range",class:P("range",X),value:Y,disabled:()=>_(W.disabled)});if(!Z&&!J)return K;let G=M("div",{class:"flex flex-col gap-2"},[Z?M("span",{class:"label-text"},Z):null,K]);return J?M("div",{class:"tooltip","data-tip":J},G):G};var rM={};z(rM,{Rating:()=>iM});var iM=(W)=>{let{class:X,value:Z,count:J=5,mask:Y="mask-star",readonly:Q=!1,onchange:K,...G}=W,q=`rating-${Math.random().toString(36).slice(2,7)}`;return M("div",{...G,class:()=>P(`rating ${_(Q)?"pointer-events-none":""}`,X)},Array.from({length:_(J)},(L,B)=>{let A=B+1;return M("input",{type:"radio",name:q,class:`mask ${Y}`,checked:()=>Math.round(_(Z))===A,onchange:()=>{if(!_(Q)){if(typeof K==="function")K(A);else if(typeof Z==="function")Z(A)}}})}))};var sM={};z(sM,{Select:()=>aM});var aM=(W)=>{let{class:X,label:Z,items:J,value:Y,...Q}=W,K=M("select",{...Q,class:P("select select-bordered w-full",X),value:Y},j(()=>_(J)||[],(G)=>M("option",{value:G.value,$selected:()=>String(_(Y))===String(G.value)},G.label),(G)=>G.value));if(!Z)return K;return M("label",{class:"fieldset-label flex flex-col gap-1"},[M("span",{},Z),K])};var nM={};z(nM,{Stack:()=>lM});var lM=(W,X)=>{let{class:Z,...J}=W;return M("div",{...J,class:P("stack",Z)},X)};var eM={};z(eM,{Stat:()=>tM});var tM=(W)=>{let{class:X,icon:Z,label:J,value:Y,desc:Q,...K}=W;return M("div",{...K,class:P("stat",X)},[Z&&M("div",{class:"stat-figure text-secondary"},Z),J&&M("div",{class:"stat-title"},J),M("div",{class:"stat-value"},()=>_(Y)??Y),Q&&M("div",{class:"stat-desc"},Q)])};var JJ={};z(JJ,{Swap:()=>MJ});var MJ=(W)=>{let{class:X,value:Z,on:J,off:Y,...Q}=W;return M("label",{...Q,class:P("swap",X)},[M("input",{type:"checkbox",checked:()=>_(Z),onclick:(K)=>{if(typeof Z==="function")Z(K.target.checked)}}),M("div",{class:"swap-on"},J),M("div",{class:"swap-off"},Y)])};var WJ={};z(WJ,{Table:()=>KJ});var KJ=(W)=>{let{class:X,items:Z=[],columns:J=[],keyFn:Y,zebra:Q=!1,pinRows:K=!1,empty:G=x("nodata")(),...q}=W;return M("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[M("table",{...q,class:()=>{let B=_(Q)?"table-zebra":"",A=_(K)?"table-pin-rows":"";return P("table",X,B,A)}},[M("thead",{},[M("tr",{},J.map((B)=>M("th",{class:B.class||""},B.label)))]),M("tbody",{},[j(Z,(B,A)=>{return M("tr",{class:"hover"},J.map((D)=>{let C=()=>{if(D.render)return D.render(B,A);let R=B[D.key];return _(R)};return M("td",{class:D.class||""},[C])}))},Y||((B,A)=>B.id||A)),E(()=>_(Z).length===0,()=>M("tr",{},[M("td",{colspan:J.length,class:"text-center p-10 opacity-50"},[_(G)])]))]),E(()=>J.some((B)=>B.footer),()=>M("tfoot",{},[M("tr",{},J.map((B)=>M("th",{},B.footer||"")))]))])])};var XJ={};z(XJ,{Tabs:()=>ZJ});var ZJ=(W)=>{let{items:X,class:Z,...J}=W,Y=typeof X==="function"?X:()=>X||[],Q=`tabs-${Math.random().toString(36).slice(2,9)}`,K=()=>{let B=Y().findIndex((A)=>_(A.active)===!0);return B===-1?0:B},G=U(K),q=()=>{let L=K();if(L!==G())G(L)};return $watch(()=>q()),M("div",{...J,class:P("tabs",Z||"tabs-box")},[j(Y,(L,B)=>{let A=()=>G()===B;return[M("input",{type:"radio",name:Q,class:"tab","aria-label":(()=>{let C=typeof L.label==="function"?L.label():L.label;return typeof C==="string"?C:`Tab ${B+1}`})(),checked:A,disabled:()=>_(L.disabled),onchange:(C)=>{if(C.target.checked&&!_(L.disabled)){if(L.onclick)L.onclick();if(typeof L.active==="function")L.active(!0);G(B)}}}),M("div",{class:"tab-content bg-base-100 border-base-300 p-6",style:()=>A()?"display: block":"display: none"},[typeof L.content==="function"?L.content():L.content])]},(L,B)=>B)])};var YJ={};z(YJ,{Timeline:()=>GJ});var GJ=(W)=>{let{class:X,items:Z=[],vertical:J=!0,compact:Y=!1,...Q}=W,K={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"},G=typeof Z==="function"?Z:()=>Z||[];return M("ul",{...Q,class:()=>P(`timeline ${_(J)?"timeline-vertical":"timeline-horizontal"} ${_(Y)?"timeline-compact":""}`,X)},[j(G,(q,L)=>{let B=L===0,A=L===G().length-1,D=q.type||"success",C=(R)=>typeof R==="function"?R():R;return M("li",{class:"flex-1"},[!B?M("hr",{class:()=>q.completed?"bg-primary":""}):null,M("div",{class:"timeline-start"},()=>C(q.title)),M("div",{class:"timeline-middle"},()=>[q.icon?V(q.icon):V(K[D]||K.success)]),M("div",{class:"timeline-end timeline-box shadow-sm"},()=>C(q.detail)),!A?M("hr",{class:()=>q.completed?"bg-primary":""}):null])},(q,L)=>q.id||L)])};var LJ={};z(LJ,{Toast:()=>QJ});var QJ=(W,X="alert-success",Z=3500)=>{let J=document.getElementById("sigpro-toast-container");if(!J)J=M("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(J);let Y=M("div",{style:"display: contents"});J.appendChild(Y);let Q,K=()=>{clearTimeout(Q);let L=Y.firstElementChild;if(L&&!L.classList.contains("opacity-0"))L.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{if(q.destroy(),Y.remove(),!J.hasChildNodes())J.remove()},300);else q.destroy(),Y.remove()},q=WM(()=>{let L=V("icon-[lucide--x]"),B=M("div",{class:`alert alert-soft ${X} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[M("span",{},[typeof W==="function"?W():W]),h({class:"btn-xs btn-circle btn-ghost",onclick:K},L)]);return requestAnimationFrame(()=>B.classList.remove("translate-x-10","opacity-0")),B},Y);if(Z>0)Q=setTimeout(K,Z);return K};var BJ={};z(BJ,{Tooltip:()=>qJ});var qJ=(W,X)=>M("div",{...W,class:()=>P("tooltip",W.ui,W.class),"data-tip":W.tip},X);var RJ={...XM,...YM,...qM,...AM,..._M,...TM,...RM,...FM,...UM,...HM,...SM,...NM,...IM,...kM,...QM,...fM,...$M,...bM,...hM,...uM,...pM,...oM,...rM,...sM,...nM,...eM,...JJ,...WJ,...XJ,...YJ,...LJ,...BJ},IJ={...RJ,install:(W=window)=>{Object.entries(RJ).forEach(([X,Z])=>{W[X]=Z}),console.log("\uD83D\uDE80 SigproUI")}};if(typeof window<"u")Object.entries(i).forEach(([W,X])=>{window[W]=X}),window.Utils=o,window.tt=x,window.SigProUI={...i,Utils:o,tt:x},console.log("\uD83C\uDFA8 SigProUI ready");})(); + ${Q()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"} + `,ondragover:(R)=>{R.preventDefault(),Q(!0)},ondragleave:()=>Q(!1),ondrop:(R)=>{R.preventDefault(),Q(!1),T(R.dataTransfer.files)}},[M("div",{class:"flex items-center gap-3 w-full"},[V("icon-[lucide--upload]"),M("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),M("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${J}MB`)]),M("input",{type:"file",multiple:!0,accept:Y,class:"hidden",onchange:(R)=>T(R.target.files)})])]),()=>B()?M("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},B()):null,N(()=>W().length>0,()=>M("ul",{class:"mt-2 space-y-1"},[O(W,(R,A)=>M("li",{class:"flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300"},[M("div",{class:"flex items-center gap-2 truncate"},[M("span",{class:"opacity-50"},"\uD83D\uDCC4"),M("span",{class:"truncate font-medium max-w-[200px]"},R.name),M("span",{class:"text-[9px] opacity-40"},`(${(R.size/1024).toFixed(0)} KB)`)]),M("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:(D)=>{D.preventDefault(),D.stopPropagation(),P(A)}},[V("icon-[lucide--x]")])]),(R)=>R.name+R.lastModified)]))])};var fM={};U(fM,{Indicator:()=>wM});var wM=(Z,K)=>{let{value:G,class:J,...Y}=Z;return M("div",{...Y,class:"indicator"},()=>[G?M("span",{class:_("indicator-item badge",J)},()=>typeof G==="function"?G():G):null,K].filter(Boolean))};var $M={};U($M,{Label:()=>yM});var yM=(Z)=>{let{children:K,value:G,floating:J=!1,error:Y,required:L,class:X,...W}=Z;if(J)return M("label",{class:_("floating-label w-full",X),...W},()=>[G?M("span",{},G):null,K,Y?M("span",{class:"text-error text-xs"},q(Y)):null]);return M("label",{class:_("input w-full",X),...W},()=>[G?M("span",{class:"label"},G):null,K,Y?M("span",{class:"text-error text-xs"},q(Y)):null])};var bM={};U(bM,{List:()=>vM});var vM=(Z)=>{let{class:K,items:G,header:J,render:Y,keyFn:L=(Q,B)=>Q.id??B,...X}=Z,W=O(G,(Q,B)=>M("li",{class:"list-row"},[Y(Q,B)]),L);return M("ul",{...X,class:_("list bg-base-100 rounded-box shadow-md",K)},J?[N(J,()=>M("li",{class:"p-4 pb-2 text-xs opacity-60"},[q(J)])),W]:W)};var hM={};U(hM,{Menu:()=>gM});var gM=(Z)=>{let{class:K,items:G,...J}=Z,Y=(L)=>O(()=>L||[],(X)=>M("li",{},[X.children?M("details",{open:X.open},[M("summary",{},[X.icon&&M("span",{class:"mr-2"},X.icon),X.label]),M("ul",{},Y(X.children))]):M("a",{class:()=>q(X.active)?"active":"",onclick:X.onclick},[X.icon&&M("span",{class:"mr-2"},X.icon),X.label])]),(X,W)=>X.label||W);return M("ul",{...J,class:_("menu bg-base-200 rounded-box",K)},Y(G))};var uM={};U(uM,{Modal:()=>mM});var mM=(Z,K)=>{let{class:G,title:J,buttons:Y,open:L,...X}=Z,W=null,Q=()=>{let z=typeof L==="function"?L():L;if(!W)return;if(z){if(!W.open)W.showModal()}else if(W.open)W.close()};w(()=>Q());let B=()=>{if(typeof L==="function")L(!1)};return M("dialog",{...X,ref:(z)=>{if(W=z,z)Q()},class:_("modal",G),onclose:B,oncancel:B},[M("div",{class:"modal-box"},[J?M("h3",{class:"text-lg font-bold mb-4"},()=>typeof J==="function"?J():J):null,M("div",{class:"py-2"},[typeof K==="function"?K():K]),M("div",{class:"modal-action"},[M("form",{method:"dialog",class:"flex gap-2"},[...(Array.isArray(Y)?Y:[Y]).filter(Boolean),u({type:"submit"},k("close")())])])]),M("form",{method:"dialog",class:"modal-backdrop"},[M("button",{},"close")])])};var pM={};U(pM,{Navbar:()=>dM});var dM=(Z,K)=>{let{class:G,...J}=Z;return M("div",{...J,class:_("navbar bg-base-100 shadow-sm px-4",G)},K)};var oM={};U(oM,{Radio:()=>cM});var cM=(Z)=>{let{class:K,label:G,tooltip:J,value:Y,inputValue:L,name:X,...W}=Z,Q=M("input",{...W,type:"radio",name:X,class:_("radio",K),checked:()=>q(Y)===L,onclick:()=>{if(typeof Y==="function")Y(L)}});if(!G&&!J)return Q;let B=M("label",{class:"label cursor-pointer justify-start gap-3"},[Q,G?M("span",{class:"label-text"},G):null]);return J?M("div",{class:"tooltip","data-tip":J},B):B};var rM={};U(rM,{Range:()=>iM});var iM=(Z)=>{let{class:K,label:G,tooltip:J,value:Y,...L}=Z,X=M("input",{...L,type:"range",class:_("range",K),value:Y,disabled:()=>q(Z.disabled)});if(!G&&!J)return X;let W=M("div",{class:"flex flex-col gap-2"},[G?M("span",{class:"label-text"},G):null,X]);return J?M("div",{class:"tooltip","data-tip":J},W):W};var lM={};U(lM,{Rating:()=>aM});var aM=(Z)=>{let{class:K,value:G,count:J=5,mask:Y="mask-star",readonly:L=!1,onchange:X,...W}=Z,Q=`rating-${Math.random().toString(36).slice(2,7)}`;return M("div",{...W,class:()=>_(`rating ${q(L)?"pointer-events-none":""}`,K)},Array.from({length:q(J)},(B,z)=>{let T=z+1;return M("input",{type:"radio",name:Q,class:`mask ${Y}`,checked:()=>Math.round(q(G))===T,onchange:()=>{if(!q(L)){if(typeof X==="function")X(T);else if(typeof G==="function")G(T)}}})}))};var sM={};U(sM,{Select:()=>nM});var nM=(Z)=>{let{class:K,label:G,items:J,value:Y,...L}=Z,X=M("select",{...L,class:_("select select-bordered w-full",K),value:Y},O(()=>q(J)||[],(W)=>M("option",{value:W.value,$selected:()=>String(q(Y))===String(W.value)},W.label),(W)=>W.value));if(!G)return X;return M("label",{class:"fieldset-label flex flex-col gap-1"},[M("span",{},G),X])};var eM={};U(eM,{Stack:()=>tM});var tM=(Z,K)=>{let{class:G,...J}=Z;return M("div",{...J,class:_("stack",G)},K)};var JJ={};U(JJ,{Stat:()=>MJ});var MJ=(Z)=>{let{class:K,icon:G,label:J,value:Y,desc:L,...X}=Z;return M("div",{...X,class:_("stat",K)},[G&&M("div",{class:"stat-figure text-secondary"},G),J&&M("div",{class:"stat-title"},J),M("div",{class:"stat-value"},()=>q(Y)??Y),L&&M("div",{class:"stat-desc"},L)])};var ZJ={};U(ZJ,{Swap:()=>WJ});var WJ=(Z)=>{let{class:K,value:G,on:J,off:Y,...L}=Z;return M("label",{...L,class:_("swap",K)},[M("input",{type:"checkbox",checked:()=>q(G),onclick:(X)=>{if(typeof G==="function")G(X.target.checked)}}),M("div",{class:"swap-on"},J),M("div",{class:"swap-off"},Y)])};var GJ={};U(GJ,{Table:()=>XJ});var XJ=(Z)=>{let{class:K,items:G=[],columns:J=[],keyFn:Y,zebra:L=!1,pinRows:X=!1,empty:W=k("nodata")(),...Q}=Z,B=()=>{let T=q(L)?"table-zebra":"",P=q(X)?"table-pin-rows":"";return _("table",K,T,P)},z=Y||((T,P)=>T.id||P);return M("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[M("table",{...Q,class:B},[M("thead",{},[M("tr",{},J.map((T)=>M("th",{class:T.class||""},T.label)))]),M("tbody",{},[O(G,(T,P)=>{let R=()=>{let A=q(G),D=z(T,P);return A.find((E,d)=>z(E,d)===D)||T};return M("tr",{class:"hover"},J.map((A)=>{let D=()=>{let E=R();if(A.render)return A.render(E,P);return q(E[A.key])};return M("td",{class:A.class||""},[D])}))},z),N(()=>q(G).length===0,()=>M("tr",{},[M("td",{colspan:J.length,class:"text-center p-10 opacity-50"},[q(W)])]))])])])};var YJ={};U(YJ,{Tabs:()=>KJ});var KJ=(Z)=>{let{items:K,class:G,...J}=Z,Y=typeof K==="function"?K:()=>K||[],L=H(0);return $watch(()=>{let X=Y().findIndex((W)=>q(W.active)===!0);if(X!==-1&&X!==L())L(X)}),M("div",{...J,class:"w-full"},[M("div",{role:"tablist",class:_("tabs",G||"tabs-box")},()=>{return Y().map((W,Q)=>{let B=()=>L()===Q,z=M("button",{role:"tab",class:()=>_("tab",B()?"tab-active":""),onclick:(T)=>{if(T.preventDefault(),!q(W.disabled)){if(W.onclick)W.onclick();L(Q)}}});return $watch(()=>{let T=q(W.label);if(T instanceof Node)z.replaceChildren(T);else z.textContent=String(T)}),z})}),M("div",{class:"tab-panels"},()=>{return Y().map((X,W)=>{let Q=()=>L()===W;return M("div",{role:"tabpanel",class:"tab-content bg-base-100 border-base-300 p-6",style:()=>Q()?"display: block":"display: none"},[()=>typeof X.content==="function"?X.content():X.content])})})])};var LJ={};U(LJ,{Timeline:()=>QJ});var QJ=(Z)=>{let{class:K,items:G=[],vertical:J=!0,compact:Y=!1,...L}=Z,X={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"};return M("ul",{...L,class:()=>_(`timeline ${q(J)?"timeline-vertical":"timeline-horizontal"} ${q(Y)?"timeline-compact":""}`,K)},()=>{let W=(typeof G==="function"?G():G)||[];return W.map((Q,B)=>{let z=B===0,T=B===W.length-1,P=Q.type||"success",R=()=>q(Q.completed),A=()=>B>0&&q(W[B-1].completed),D=(E)=>typeof E==="function"?E():E;return M("li",{class:"flex-1"},[!z?M("hr",{class:()=>A()?"bg-primary":""}):null,M("div",{class:"timeline-start"},[()=>D(Q.title)]),M("div",{class:"timeline-middle"},[()=>Q.icon?V(Q.icon):V(X[P]||X.success)]),M("div",{class:"timeline-end timeline-box shadow-sm"},[()=>D(Q.detail)]),!T?M("hr",{class:()=>R()?"bg-primary":""}):null])})})};var qJ={};U(qJ,{Toast:()=>BJ});var BJ=(Z,K="alert-success",G=3500)=>{let J=document.getElementById("sigpro-toast-container");if(!J)J=M("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(J);let Y=M("div",{style:"display: contents"});J.appendChild(Y);let L,X=()=>{clearTimeout(L);let B=Y.firstElementChild;if(B&&!B.classList.contains("opacity-0"))B.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{if(Q.destroy(),Y.remove(),!J.hasChildNodes())J.remove()},300);else Q.destroy(),Y.remove()},Q=GM(()=>{let B=V("icon-[lucide--x]"),z=M("div",{class:`alert alert-soft ${K} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[M("span",{},[typeof Z==="function"?Z():Z]),u({class:"btn-xs btn-circle btn-ghost",onclick:X},B)]);return requestAnimationFrame(()=>z.classList.remove("translate-x-10","opacity-0")),z},Y);if(G>0)L=setTimeout(X,G);return X};var _J={};U(_J,{Tooltip:()=>AJ});var AJ=(Z,K)=>M("div",{...Z,class:()=>_("tooltip",Z.ui,Z.class),"data-tip":Z.tip},K);var zJ={...YM,...LM,...AM,...PM,...TM,...zM,...DM,...UM,...VM,...EM,...OM,...IM,...kM,...fM,...BM,...$M,...bM,...hM,...uM,...pM,...oM,...rM,...lM,...sM,...eM,...JJ,...ZJ,...GJ,...YJ,...LJ,...qJ,..._J},IJ={...zJ,install:(Z=window)=>{Object.entries(zJ).forEach(([K,G])=>{Z[K]=G}),console.log("\uD83D\uDE80 SigproUI")}};if(typeof window<"u")Object.entries(l).forEach(([Z,K])=>{window[Z]=K}),window.Utils=a,window.tt=k,window.SigProUI={...l,Utils:a,tt:k},console.log("\uD83C\uDFA8 SigProUI ready");})(); diff --git a/docs/README.md b/docs/README.md index 9424430..f5909ca 100644 --- a/docs/README.md +++ b/docs/README.md @@ -8,7 +8,7 @@

SigPro UI beta (W.I.P.)

Reactive Design System for SigPro
-
"Atomic components for high-performance interfaces. Zero-boilerplate, pure DaisyUI v5 elegance."
+
"Atomic components for high-performance interfaces. Zero-boilerplate, pure reactivity."
View Components @@ -25,26 +25,26 @@
-

TAILWIND V4

-

Built on the latest CSS engine. Lightning fast styles with zero legacy overhead.

+

SIGPRO NATIVE

+

Direct integration with SigPro signals. No wrappers, no context, just pure atomic reactivity.

-

DAISYUI V5

-

Semantic, beautiful and accessible. Professional components out of the box.

+

ZERO CONFIG

+

Import and build immediately. Designed for developers who hate configuration files.

-

NATIVE REACTION

-

Direct integration with SigPro signals. No wrappers, no context, just speed.

+

REACTIVE BY DESIGN

+

Every component is a high-order function optimized for SigPro's fine-grained updates.

READY-TO-GO

-

Import and build. Designed for developers who hate configuration files.

+

60+ atomic components. Semantic, accessible, and production-ready.

@@ -54,13 +54,13 @@ SigPro-UI isn't just a library; it's a **Functional Design System**. -It eliminates the gap between your data (Signals) and your layout (DaisyUI). Each component is a high-order function optimized for the SigPro core, ensuring that your UI only updates where it matters. +It eliminates the gap between your data (Signals) and your UI components. Each component is a high-order function optimized for the SigPro core, ensuring that your interface only updates where it matters. | Requirement | Value | Why? | | :--- | :--- | :--- | | **Engine** | **SigPro** | Atomic reactivity without V-DOM. | -| **Styling** | **Tailwind CSS v4** | Pure CSS performance. | -| **Components** | **daisyUI v5** | Semantic and clean layouts. | +| **Components** | **SigPro-UI** | 60+ semantic, reactive components. | +| **Styling** | **daisyUI v5** | Beautiful, accessible, themeable. | | **Learning Curve** | **Zero** | If you know JS and HTML, you know SigPro-UI. | ### Semantic Functionalism @@ -73,43 +73,43 @@ Modal({ title: "Precision Engineering" }, () => Div({ class: "space-y-4" }, [ - P("SigPro-UI leverages Tailwind v4 for instant styling."), + P("SigPro-UI provides instant reactivity out of the box."), Button({ class: "btn-primary", onclick: () => isVisible(false) }, "Confirm") ]) ) -```` +``` ------ +--- ## Technical Stack Requirements To achieve the performance promised by SigPro-UI, your environment must be equipped with: -### 1\. SigPro Core +### 1. SigPro Core The atomic heart. SigPro-UI requires the SigPro runtime (`$`, `$watch`, `$html`, etc.) to be present in the global scope or provided as a module. -### 2\. Tailwind CSS v4 Engine - -SigPro-UI uses the modern `@theme` and utility engine of Tailwind v4. It is designed to work with the ultra-fast compiler of the new generation. - -### 3\. daisyUI v5 +### 2. daisyUI v5 The visual DNA. All components are mapped to daisyUI v5 semantic classes, providing access to dozens of themes and accessible UI patterns without writing a single line of custom CSS. ------ +### 3. Modern Browser + +SigPro-UI uses modern Web APIs and requires no polyfills for evergreen browsers. + +---
-

Design at Runtime.

+

Reactive at Runtime.

- Combine the best of three worlds: SigPro for logic, - Tailwind v4 for speed, and daisyUI v5 for beauty. - Build interfaces that feel as fast as they look. + Combine the best of both worlds: SigPro for logic and + daisyUI v5 for beauty. Build interfaces that feel as fast as they look, + with components that react instantly to your data changes.

diff --git a/docs/_sidebar.md b/docs/_sidebar.md index 6a4ddec..a4177ab 100644 --- a/docs/_sidebar.md +++ b/docs/_sidebar.md @@ -42,9 +42,4 @@ * [Fieldset](components/fieldset.md) * [Menu](components/menu.md) * [Navbar](components/navbar.md) - * [Tabs](components/tabs.md) - -* **Advanced** - * [Reactivity Guide](advanced/reactivity.md) - * [i18n Guide](advanced/i18n.md) - * [Theming](advanced/theming.md) \ No newline at end of file + * [Tabs](components/tabs.md) \ No newline at end of file diff --git a/docs/components/indicator.md b/docs/components/indicator.md index 2ef06cf..bac6190 100644 --- a/docs/components/indicator.md +++ b/docs/components/indicator.md @@ -171,7 +171,7 @@ const CartDemo = () => { ), Span({ class: 'text-lg font-bold' }, () => `Total: $${total()}`) ]), - cart().length === 0 + () => cart().length === 0 ? Div({ class: 'alert alert-soft text-center' }, 'Cart is empty') : Div({ class: 'flex flex-col gap-2' }, cart().map(item => Div({ class: 'flex justify-between items-center p-2 bg-base-200 rounded-lg' }, [ @@ -187,6 +187,7 @@ const CartDemo = () => { )) ]); }; + $mount(CartDemo, '#demo-cart'); ``` @@ -235,7 +236,7 @@ const InboxDemo = () => { } }, 'Mark all read') ]), - Div({ class: 'flex flex-col gap-2' }, messages().map(msg => + Div({ class: 'flex flex-col gap-2' }, () => messages().map(msg => Div({ class: `p-3 rounded-lg cursor-pointer transition-all ${msg.read ? 'bg-base-200 opacity-60' : 'bg-primary/10 border-l-4 border-primary'}`, onclick: () => markAsRead(msg.id) @@ -247,6 +248,7 @@ const InboxDemo = () => { )) ]); }; + $mount(InboxDemo, '#demo-inbox'); ``` diff --git a/docs/components/input.md b/docs/components/input.md index 9ad6979..7e3d1ff 100644 --- a/docs/components/input.md +++ b/docs/components/input.md @@ -125,20 +125,22 @@ $mount(TooltipDemo, '#demo-tooltip'); ```javascript const ErrorDemo = () => { const email = $(''); - const isValid = $(true); - const validate = (value) => { - const valid = value.includes('@') && value.includes('.'); - isValid(valid); - email(value); - }; - - return Input({ - type: 'email', - value: email, - error: () => !isValid() && email() ? 'Invalid email address' : '', - oninput: (e) => validate(e.target.value) - }); + return Div({ class: 'w-full max-w-md' }, [ + Input({ + type: 'email', + value: email, + placeholder: 'Enter your email', + icon: 'icon-[lucide--mail]', + validate: (value) => { + if (!value) return ''; + if (!value.includes('@')) return 'Email must contain @'; + if (!value.includes('.')) return 'Email must contain .'; + return ''; + }, + oninput: (e) => email(e.target.value) + }) + ]); }; $mount(ErrorDemo, '#demo-error'); ``` diff --git a/docs/components/list.md b/docs/components/list.md index 99ea1b8..17f102b 100644 --- a/docs/components/list.md +++ b/docs/components/list.md @@ -8,23 +8,23 @@ List component with custom item rendering, headers, and reactive data binding. ## Props -| Prop | Type | Default | Description | -| :--- | :--- | :--- | :--- | -| `items` | `Array \| Signal` | `[]` | Data array to display | -| `header` | `string \| VNode \| Signal` | `-` | Optional header content | -| `render` | `function(item, index)` | Required | Custom render function for each item | -| `keyFn` | `function(item, index)` | `(item, idx) => idx` | Unique key function for items | -| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | +| Prop | Type | Default | Description | +| :------- | :-------------------------- | :------------------- | :------------------------------------------ | +| `items` | `Array \| Signal` | `[]` | Data array to display | +| `header` | `string \| VNode \| Signal` | `-` | Optional header content | +| `render` | `function(item, index)` | Required | Custom render function for each item | +| `keyFn` | `function(item, index)` | `(item, idx) => idx` | Unique key function for items | +| `class` | `string` | `''` | Additional CSS classes (DaisyUI + Tailwind) | ## Styling List supports all **daisyUI List classes**: -| Category | Keywords | Description | -| :--- | :--- | :--- | -| Base | `list` | Base list styling | -| Variant | `list-row` | Row styling for list items | -| Background | `bg-base-100` | Background color | +| Category | Keywords | Description | +| :--------- | :------------ | :------------------------- | +| Base | `list` | Base list styling | +| Variant | `list-row` | Row styling for list items | +| Background | `bg-base-100` | Background color | > For further details, check the [daisyUI List Documentation](https://daisyui.com/components/list) – Full reference for CSS classes. @@ -41,16 +41,17 @@ List supports all **daisyUI List classes**: ```javascript const BasicDemo = () => { - const items = ['Apple', 'Banana', 'Orange', 'Grape', 'Mango']; - + const items = ["Apple", "Banana", "Orange", "Grape", "Mango"]; + return List({ items: items, - render: (item) => Div({ class: 'p-3 hover:bg-base-200 transition-colors' }, [ - Span({ class: 'font-medium' }, item) - ]) + render: (item) => + Div({ class: "p-3 hover:bg-base-200 transition-colors" }, [ + Span({ class: "font-medium" }, item), + ]), }); }; -$mount(BasicDemo, '#demo-basic'); +$mount(BasicDemo, "#demo-basic"); ``` ### With Header @@ -65,22 +66,31 @@ $mount(BasicDemo, '#demo-basic'); ```javascript const HeaderDemo = () => { const users = [ - { name: 'John Doe', email: 'john@example.com', status: 'active' }, - { name: 'Jane Smith', email: 'jane@example.com', status: 'inactive' }, - { name: 'Bob Johnson', email: 'bob@example.com', status: 'active' } + { name: "John Doe", email: "john@example.com", status: "active" }, + { name: "Jane Smith", email: "jane@example.com", status: "inactive" }, + { name: "Bob Johnson", email: "bob@example.com", status: "active" }, ]; - + return List({ items: users, - header: Div({ class: 'p-3 bg-primary/10 font-bold border-b border-base-300' }, 'Active Users'), - render: (user) => Div({ class: 'p-3 border-b border-base-300 hover:bg-base-200' }, [ - Div({ class: 'font-medium' }, user.name), - Div({ class: 'text-sm opacity-70' }, user.email), - Span({ class: `badge badge-sm ${user.status === 'active' ? 'badge-success' : 'badge-ghost'} mt-1` }, user.status) - ]) + header: Div( + { class: "p-3 bg-primary/10 font-bold border-b border-base-300" }, + "Active Users", + ), + render: (user) => + Div({ class: "p-3 border-b border-base-300 hover:bg-base-200" }, [ + Div({ class: "font-medium" }, user.name), + Div({ class: "text-sm opacity-70" }, user.email), + Span( + { + class: `badge badge-sm ${user.status === "active" ? "badge-success" : "badge-ghost"} mt-1`, + }, + user.status, + ), + ]), }); }; -$mount(HeaderDemo, '#demo-header'); +$mount(HeaderDemo, "#demo-header"); ``` ### With Icons @@ -95,25 +105,36 @@ $mount(HeaderDemo, '#demo-header'); ```javascript const IconsDemo = () => { const settings = [ - { icon: '🔊', label: 'Sound', description: 'Adjust volume and notifications' }, - { icon: '🌙', label: 'Display', description: 'Brightness and dark mode' }, - { icon: '🔒', label: 'Privacy', description: 'Security settings' }, - { icon: '🌐', label: 'Network', description: 'WiFi and connections' } + { + icon: "🔊", + label: "Sound", + description: "Adjust volume and notifications", + }, + { icon: "🌙", label: "Display", description: "Brightness and dark mode" }, + { icon: "🔒", label: "Privacy", description: "Security settings" }, + { icon: "🌐", label: "Network", description: "WiFi and connections" }, ]; - + return List({ items: settings, - render: (item) => Div({ class: 'flex gap-3 p-3 hover:bg-base-200 transition-colors cursor-pointer' }, [ - Div({ class: 'text-2xl' }, item.icon), - Div({ class: 'flex-1' }, [ - Div({ class: 'font-medium' }, item.label), - Div({ class: 'text-sm opacity-60' }, item.description) - ]), - Span({ class: 'opacity-40' }, '→') - ]) + render: (item) => + Div( + { + class: + "flex gap-3 p-3 hover:bg-base-200 transition-colors cursor-pointer", + }, + [ + Div({ class: "text-2xl" }, item.icon), + Div({ class: "flex-1" }, [ + Div({ class: "font-medium" }, item.label), + Div({ class: "text-sm opacity-60" }, item.description), + ]), + Span({ class: "opacity-40" }, "→"), + ], + ), }); }; -$mount(IconsDemo, '#demo-icons'); +$mount(IconsDemo, "#demo-icons"); ``` ### With Badges @@ -128,24 +149,52 @@ $mount(IconsDemo, '#demo-icons'); ```javascript const BadgesDemo = () => { const notifications = [ - { id: 1, message: 'New comment on your post', time: '5 min ago', unread: true }, - { id: 2, message: 'Your order has been shipped', time: '1 hour ago', unread: true }, - { id: 3, message: 'Welcome to the platform!', time: '2 days ago', unread: false }, - { id: 4, message: 'Weekly digest available', time: '3 days ago', unread: false } + { + id: 1, + message: "New comment on your post", + time: "5 min ago", + unread: true, + }, + { + id: 2, + message: "Your order has been shipped", + time: "1 hour ago", + unread: true, + }, + { + id: 3, + message: "Welcome to the platform!", + time: "2 days ago", + unread: false, + }, + { + id: 4, + message: "Weekly digest available", + time: "3 days ago", + unread: false, + }, ]; - + return List({ items: notifications, - render: (item) => Div({ class: `flex justify-between items-center p-3 border-b border-base-300 hover:bg-base-200 ${item.unread ? 'bg-primary/5' : ''}` }, [ - Div({ class: 'flex-1' }, [ - Div({ class: 'font-medium' }, item.message), - Div({ class: 'text-xs opacity-50' }, item.time) - ]), - item.unread ? Span({ class: 'badge badge-primary badge-sm' }, 'New') : null - ]) + render: (item) => + Div( + { + class: `flex justify-between items-center p-3 border-b border-base-300 hover:bg-base-200 ${item.unread ? "bg-primary/5" : ""}`, + }, + [ + Div({ class: "flex-1" }, [ + Div({ class: "font-medium" }, item.message), + Div({ class: "text-xs opacity-50" }, item.time), + ]), + item.unread + ? Span({ class: "badge badge-primary badge-sm" }, "New") + : null, + ], + ), }); }; -$mount(BadgesDemo, '#demo-badges'); +$mount(BadgesDemo, "#demo-badges"); ``` ### Interactive List @@ -161,38 +210,49 @@ $mount(BadgesDemo, '#demo-badges'); const InteractiveDemo = () => { const selected = $(null); const items = [ - { id: 1, name: 'Project Alpha', status: 'In Progress' }, - { id: 2, name: 'Project Beta', status: 'Planning' }, - { id: 3, name: 'Project Gamma', status: 'Completed' }, - { id: 4, name: 'Project Delta', status: 'Review' } + { id: 1, name: "Project Alpha", status: "In Progress" }, + { id: 2, name: "Project Beta", status: "Planning" }, + { id: 3, name: "Project Gamma", status: "Completed" }, + { id: 4, name: "Project Delta", status: "Review" }, ]; - + const statusColors = { - 'In Progress': 'badge-warning', - 'Planning': 'badge-info', - 'Completed': 'badge-success', - 'Review': 'badge-accent' + "In Progress": "badge-warning", + Planning: "badge-info", + Completed: "badge-success", + Review: "badge-accent", }; - - return Div({ class: 'flex flex-col gap-4' }, [ + + return Div({ class: "flex flex-col gap-4" }, [ List({ items: items, - render: (item) => Div({ - class: `p-3 cursor-pointer transition-all hover:bg-base-200 ${selected() === item.id ? 'bg-primary/10 border-l-4 border-primary' : 'border-l-4 border-transparent'}`, - onclick: () => selected(item.id) - }, [ - Div({ class: 'flex justify-between items-center' }, [ - Div({ class: 'font-medium' }, item.name), - Span({ class: `badge ${statusColors[item.status]}` }, item.status) - ]) - ]) + render: (item) => + Div( + { + class: `p-3 cursor-pointer transition-all hover:bg-base-200 ${selected() === item.id ? "bg-primary/10 border-l-4 border-primary" : "border-l-4 border-transparent"}`, + onclick: () => selected(item.id), + }, + [ + Div({ class: "flex justify-between items-center" }, [ + Div({ class: "font-medium" }, item.name), + Span( + { class: `badge ${statusColors[item.status]}` }, + item.status, + ), + ]), + ], + ), }), - () => selected() - ? Div({ class: 'alert alert-info' }, `Selected: ${items.find(i => i.id === selected()).name}`) - : Div({ class: 'alert alert-soft' }, 'Select a project to see details') + () => + selected() + ? Div( + { class: "alert alert-info" }, + `Selected: ${items.find((i) => i.id === selected()).name}`, + ) + : Div({ class: "alert alert-soft" }, "Select a project to see details"), ]); }; -$mount(InteractiveDemo, '#demo-interactive'); +$mount(InteractiveDemo, "#demo-interactive"); ``` ### Reactive List (Todo App) @@ -223,9 +283,7 @@ const ReactiveDemo = () => { }; const toggleTodo = (id) => { - todos(todos().map(t => - t.id === id ? { ...t, done: !t.done } : t - )); + todos(todos().map(t => t.id === id ? { ...t, done: !t.done } : t)); }; const deleteTodo = (id) => { @@ -233,13 +291,12 @@ const ReactiveDemo = () => { }; const pendingCount = () => todos().filter(t => !t.done).length; - + $watch(()=> console.log(pendingCount())); return Div({ class: 'flex flex-col gap-4' }, [ Div({ class: 'flex gap-2' }, [ Input({ placeholder: 'Add new task...', value: newTodo, - class: 'flex-1', oninput: (e) => newTodo(e.target.value), onkeypress: (e) => e.key === 'Enter' && addTodo() }), @@ -247,24 +304,32 @@ const ReactiveDemo = () => { ]), List({ items: todos, - render: (todo) => Div({ class: `flex items-center gap-3 p-2 border-b border-base-300 hover:bg-base-200 ${todo.done ? 'opacity-60' : ''}` }, [ - Checkbox({ - value: todo.done, - onclick: () => toggleTodo(todo.id) - }), - Span({ - class: `flex-1 ${todo.done ? 'line-through' : ''}`, - onclick: () => toggleTodo(todo.id) - }, todo.text), - Button({ - class: 'btn btn-ghost btn-xs btn-circle', - onclick: () => deleteTodo(todo.id) - }, '✕') - ]) + render: (item) => { + // Esta función busca siempre el estado actual del item dentro del signal + const it = () => todos().find(t => t.id === item.id) || item; + + return Div({ + class: () => `flex items-center gap-3 p-2 border-b border-base-300 ${it().done ? 'opacity-60' : ''}` + }, [ + Checkbox({ + value: () => it().done, + onclick: () => toggleTodo(item.id) + }), + Span({ + class: () => `flex-1 ${it().done ? 'line-through' : ''}`, + onclick: () => toggleTodo(item.id) + }, () => it().text), + Button({ + class: 'btn btn-ghost btn-xs btn-circle', + onclick: () => deleteTodo(item.id) + }, '✕') + ]); + } }), Div({ class: 'text-sm opacity-70 mt-2' }, () => `${pendingCount()} tasks remaining`) ]); }; + $mount(ReactiveDemo, '#demo-reactive'); ``` @@ -280,27 +345,45 @@ $mount(ReactiveDemo, '#demo-reactive'); ```javascript const AvatarDemo = () => { const contacts = [ - { name: 'Alice Johnson', role: 'Developer', avatar: 'A', online: true }, - { name: 'Bob Smith', role: 'Designer', avatar: 'B', online: false }, - { name: 'Charlie Brown', role: 'Manager', avatar: 'C', online: true }, - { name: 'Diana Prince', role: 'QA Engineer', avatar: 'D', online: false } + { name: "Alice Johnson", role: "Developer", avatar: "A", online: true }, + { name: "Bob Smith", role: "Designer", avatar: "B", online: false }, + { name: "Charlie Brown", role: "Manager", avatar: "C", online: true }, + { name: "Diana Prince", role: "QA Engineer", avatar: "D", online: false }, ]; - + return List({ items: contacts, - render: (contact) => Div({ class: 'flex gap-3 p-3 hover:bg-base-200 transition-colors' }, [ - Div({ class: `avatar ${contact.online ? 'online' : 'offline'}`, style: 'width: 48px' }, [ - Div({ class: 'rounded-full bg-primary text-primary-content flex items-center justify-center w-12 h-12 font-bold' }, contact.avatar) + render: (contact) => + Div({ class: "flex gap-3 p-3 hover:bg-base-200 transition-colors" }, [ + Div( + { + class: `avatar ${contact.online ? "online" : "offline"}`, + style: "width: 48px", + }, + [ + Div( + { + class: + "rounded-full bg-primary text-primary-content flex items-center justify-center w-12 h-12 font-bold", + }, + contact.avatar, + ), + ], + ), + Div({ class: "flex-1" }, [ + Div({ class: "font-medium" }, contact.name), + Div({ class: "text-sm opacity-60" }, contact.role), + ]), + Div( + { + class: `badge badge-sm ${contact.online ? "badge-success" : "badge-ghost"}`, + }, + contact.online ? "Online" : "Offline", + ), ]), - Div({ class: 'flex-1' }, [ - Div({ class: 'font-medium' }, contact.name), - Div({ class: 'text-sm opacity-60' }, contact.role) - ]), - Div({ class: `badge badge-sm ${contact.online ? 'badge-success' : 'badge-ghost'}` }, contact.online ? 'Online' : 'Offline') - ]) }); }; -$mount(AvatarDemo, '#demo-avatar'); +$mount(AvatarDemo, "#demo-avatar"); ``` ### All Variants @@ -314,29 +397,29 @@ $mount(AvatarDemo, '#demo-avatar'); ```javascript const VariantsDemo = () => { - const items = ['Item 1', 'Item 2', 'Item 3']; - - return Div({ class: 'flex flex-col gap-6' }, [ - Div({ class: 'text-sm font-bold' }, 'Default List'), + const items = ["Item 1", "Item 2", "Item 3"]; + + return Div({ class: "flex flex-col gap-6" }, [ + Div({ class: "text-sm font-bold" }, "Default List"), List({ items: items, - render: (item) => Div({ class: 'p-2' }, item) + render: (item) => Div({ class: "p-2" }, item), }), - - Div({ class: 'text-sm font-bold mt-2' }, 'With Shadow'), + + Div({ class: "text-sm font-bold mt-2" }, "With Shadow"), List({ items: items, - render: (item) => Div({ class: 'p-2' }, item), - class: 'shadow-lg' + render: (item) => Div({ class: "p-2" }, item), + class: "shadow-lg", }), - - Div({ class: 'text-sm font-bold mt-2' }, 'Rounded Corners'), + + Div({ class: "text-sm font-bold mt-2" }, "Rounded Corners"), List({ items: items, - render: (item) => Div({ class: 'p-2' }, item), - class: 'rounded-box overflow-hidden' - }) + render: (item) => Div({ class: "p-2" }, item), + class: "rounded-box overflow-hidden", + }), ]); }; -$mount(VariantsDemo, '#demo-variants'); -``` \ No newline at end of file +$mount(VariantsDemo, "#demo-variants"); +``` diff --git a/docs/components/stat.md b/docs/components/stat.md index ed3f1f0..3153785 100644 --- a/docs/components/stat.md +++ b/docs/components/stat.md @@ -140,41 +140,6 @@ const ReactiveDemo = () => { $mount(ReactiveDemo, '#demo-reactive'); ``` -### With Trend Indicators - -
-
-

Live Demo

- -
-
- -```javascript -const TrendsDemo = () => { - return Div({ class: 'grid grid-cols-1 md:grid-cols-3 gap-4' }, [ - Stat({ - label: 'Weekly Sales', - value: '$12,345', - desc: Div({ class: 'text-success' }, '↗︎ 15% increase'), - icon: Span({ class: 'text-2xl' }, '📈') - }), - Stat({ - label: 'Bounce Rate', - value: '42%', - desc: Div({ class: 'text-error' }, '↘︎ 3% from last week'), - icon: Span({ class: 'text-2xl' }, '📉') - }), - Stat({ - label: 'Avg. Session', - value: '4m 32s', - desc: Div({ class: 'text-warning' }, '↗︎ 12 seconds'), - icon: Span({ class: 'text-2xl' }, '⏱️') - }) - ]); -}; -$mount(TrendsDemo, '#demo-trends'); -``` - ### Multiple Stats in Row
diff --git a/docs/components/tooltip.md b/docs/components/tooltip.md index 4acfa4e..3ce97f2 100644 --- a/docs/components/tooltip.md +++ b/docs/components/tooltip.md @@ -294,27 +294,22 @@ $mount(ColorsDemo, '#demo-colors'); const AllPositionsDemo = () => { return Div({ class: 'grid grid-cols-3 gap-4 justify-items-center' }, [ Div({ class: 'col-start-2' }, [ - Tooltip({ tip: 'Top tooltip', class: 'tooltip-top' }, [ + Tooltip({ tip: 'Top tooltip', ui: 'tooltip-top' }, [ Button({ class: 'btn btn-sm w-24' }, 'Top') ]) ]), Div({ class: 'col-start-1 row-start-2' }, [ - Tooltip({ tip: 'Left tooltip', class: 'tooltip-left' }, [ + Tooltip({ tip: 'Left tooltip', ui: 'tooltip-left' }, [ Button({ class: 'btn btn-sm w-24' }, 'Left') ]) ]), - Div({ class: 'col-start-2 row-start-2' }, [ - Tooltip({ tip: 'Center tooltip', class: 'tooltip' }, [ - Button({ class: 'btn btn-sm w-24' }, 'Center') - ]) - ]), Div({ class: 'col-start-3 row-start-2' }, [ - Tooltip({ tip: 'Right tooltip', class: 'tooltip-right' }, [ + Tooltip({ tip: 'Right tooltip', ui: 'tooltip-right' }, [ Button({ class: 'btn btn-sm w-24' }, 'Right') ]) ]), Div({ class: 'col-start-2 row-start-3' }, [ - Tooltip({ tip: 'Bottom tooltip', class: 'tooltip-bottom' }, [ + Tooltip({ tip: 'Bottom tooltip', ui: 'tooltip-bottom' }, [ Button({ class: 'btn btn-sm w-24' }, 'Bottom') ]) ]) diff --git a/docs/install.md b/docs/install.md index 07c4f25..db58cd1 100644 --- a/docs/install.md +++ b/docs/install.md @@ -6,7 +6,7 @@ Follow these steps to integrate **SigPro-UI** into your project. !> **📘 Core Concepts** -**Note:** SigPro-UI now includes SigPro core internally. You no longer need to install SigPro separately. +**Note:** SigPro-UI now includes SigPro core internally. No need to install SigPro separately. SigProUI is built on top of the [SigPro](https://natxocc.github.io/sigpro/#/) reactive core. To learn how to create signals, manage reactivity, and structure your application logic, check out the [SigPro documentation](https://natxocc.github.io/sigpro/#/). It covers everything you need to build reactive applications with signals, computed values, and effects. --- @@ -135,7 +135,6 @@ When you install SigProUI, you get: - And 30+ more components! ### Utilities -- `Utils` - Helper functions (ui, val) - `tt()` - i18n translation function ## Language Support @@ -143,7 +142,7 @@ When you install SigProUI, you get: SigProUI includes built-in i18n with Spanish and English: ```javascript -import { tt } from 'sigpro-ui'; +import { tt, Locale } from 'sigpro-ui'; // Change locale (default is 'es') Locale('en'); diff --git a/docs/quick.md b/docs/quick.md index eaa44fb..1777d4c 100644 --- a/docs/quick.md +++ b/docs/quick.md @@ -1,6 +1,5 @@ # SigPro-UI Quick Reference -**Version:** daisyUI v5 + Tailwind v4 Plugin **Status:** Active / WIP @@ -8,9 +7,7 @@ ```javascript import "sigpro-ui"; - -// Injects all components into window and sets default language -Locale('en'); // 'es' or 'en' +import "sigpro-ui/css"; // All components (Button, Input, Table, Toast, etc.) are now globally available. ``` @@ -22,7 +19,7 @@ Locale('en'); // 'es' or 'en' | Component | Purpose | Basic Example | | :--- | :--- | :--- | | **Button** | Styled button with DaisyUI | `Button({ class: "btn-primary" }, "Submit")` | -| **Input** | Reactive text field with floating label | `Input({ label: "Name", value: $name })` | +| **Input** | Reactive text field with validation | `Input({ value: $name, validate: (v) => !v ? "Required" : "" })` | | **Select** | Dropdown selection menu | `Select({ options: ["Admin", "User"], value: $role })` | | **Checkbox** | Binary toggle (boolean) | `Checkbox({ label: "Active", checked: $isActive })` | | **Table** | Data grid with column rendering | `Table({ items: $data, columns: [...] })` | @@ -40,7 +37,7 @@ Locale('en'); // 'es' or 'en' | Component | Description | Example | | :--- | :--- | :--- | -| **Input** | Text input with floating label, validation, password toggle | `Input({ label: "Email", type: "email", value: $email })` | +| **Input** | Text input with floating label, validation, password toggle | `Input({ label: "Email", type: "email", value: $email, validate: validateEmail })` | | **Select** | Dropdown selector | `Select({ label: "Role", options: ["Admin", "User"], value: $role })` | | **Autocomplete** | Searchable dropdown with filtering | `Autocomplete({ label: "Country", options: countryList, value: $country })` | | **Datepicker** | Date picker (single or range mode) | `Datepicker({ label: "Date", value: $date, range: false })` | @@ -53,6 +50,36 @@ Locale('en'); // 'es' or 'en' --- +## Input Validation + +The `Input` component supports real-time validation via the `validate` prop: + +```javascript +const email = $(''); + +Input({ + type: 'email', + value: email, + placeholder: 'Enter your email', + icon: 'icon-[lucide--mail]', + validate: (value) => { + if (!value) return ''; + if (!value.includes('@')) return 'Email must contain @'; + if (!value.includes('.')) return 'Email must contain .'; + return ''; + }, + oninput: (e) => email(e.target.value) +}) +``` + +**How it works:** +- Returns `''` or `null` → no error +- Returns a string → shows error message and adds `input-error` class +- Validates on every keystroke +- No external state needed for error messages + +--- + ## Data Display | Component | Description | Example | @@ -63,7 +90,7 @@ Locale('en'); // 'es' or 'en' | **Stat** | Statistical data blocks (KPIs) | `Stat({ label: "Total", value: "1.2k", desc: "Monthly" })` | | **Timeline** | Vertical/horizontal timeline | `Timeline({ items: [{ title: "Step 1", detail: "Completed" }] })` | | **Stack** | Stacked elements | `Stack({}, [Card1, Card2, Card3])` | -| **Indicator** | Badge on corner of element | `Indicator({ badge: "3" }, Button(...))` | +| **Indicator** | Badge on corner of element | `Indicator({ value: () => count() }, Button(...))` | --- @@ -74,7 +101,7 @@ Locale('en'); // 'es' or 'en' | **Alert** | Inline contextual notification | `Alert({ type: "success" }, "Changes saved!")` | | **Modal** | Dialog overlay | `Modal({ open: $isOpen, title: "Confirm" }, "Are you sure?")` | | **Toast** | Floating notification (auto-stacking) | `Toast("Action completed", "alert-info", 3000)` | -| **Tooltip** | Hover tooltip wrapper | `Tooltip({ tip: "Help text" }, Button(...))` | +| **Tooltip** | Hover tooltip wrapper | `Tooltip({ tip: "Help text", ui: "tooltip-top" }, Button(...))` | --- @@ -97,7 +124,7 @@ Locale('en'); // 'es' or 'en' | Component | Description | Example | | :--- | :--- | :--- | | **Fab** | Floating Action Button with actions | `Fab({ icon: "+", actions: [{ label: "Add", onclick: add }] })` | -| **Indicator** | Badge indicator wrapper | `Indicator({ badge: "99+" }, Button(...))` | +| **Indicator** | Badge indicator wrapper | `Indicator({ value: () => unread() }, Button(...))` | --- @@ -138,15 +165,16 @@ const closeText = tt("close"); // "Close" or "Cerrar" ```javascript const name = $(""); -const error = $(null); Input({ value: name, - error: error, - oninput: (e) => { - name(e.target.value); - error(e.target.value.length < 3 ? "Name too short" : null); - } + placeholder: "Name", + validate: (value) => { + if (!value) return "Name is required"; + if (value.length < 3) return "Name too short"; + return ""; + }, + oninput: (e) => name(e.target.value) }) ``` @@ -186,14 +214,14 @@ Modal({ | Component | Key Props | | :--- | :--- | -| `Button` | `class`, `disabled`, `loading`, `badge`, `tooltip`, `icon` | -| `Input` | `label`, `value`, `error`, `type`, `placeholder`, `disabled`, `tip` | +| `Button` | `class`, `disabled`, `loading`, `icon` | +| `Input` | `value`, `validate`, `type`, `placeholder`, `icon`, `disabled` | | `Select` | `label`, `options`, `value`, `disabled` | | `Modal` | `open`, `title`, `buttons` | | `Table` | `items`, `columns`, `zebra`, `pinRows`, `empty` | | `Alert` | `type` (info/success/warning/error), `soft`, `actions` | | `Toast` | `message`, `type`, `duration` | -| `Loading` | `show` | | `Datepicker` | `value`, `range`, `label`, `placeholder` | | `Autocomplete` | `options`, `value`, `onSelect`, `label` | - +| `Indicator` | `value` (function that returns number/string) | +| `Tooltip` | `tip`, `ui` (tooltip-top/bottom/left/right) | diff --git a/docs/sigpro-ui.min.js b/docs/sigpro-ui.min.js index 70fd10d..aaa0514 100644 --- a/docs/sigpro-ui.min.js +++ b/docs/sigpro-ui.min.js @@ -1,7 +1,7 @@ -(()=>{var{defineProperty:e,getOwnPropertyNames:UJ,getOwnPropertyDescriptor:VJ}=Object,HJ=Object.prototype.hasOwnProperty;var TJ=new WeakMap,jJ=(W)=>{var X=TJ.get(W),Z;if(X)return X;if(X=e({},"__esModule",{value:!0}),W&&typeof W==="object"||typeof W==="function")UJ(W).map((J)=>!HJ.call(X,J)&&e(X,J,{get:()=>W[J],enumerable:!(Z=VJ(W,J))||Z.enumerable}));return TJ.set(W,X),X};var z=(W,X)=>{for(var Z in X)e(W,Z,{get:X[Z],enumerable:!0,configurable:!0,set:(J)=>X[Z]=()=>J})};var xJ={};z(xJ,{val:()=>_,ui:()=>P,tt:()=>x,getIcon:()=>V,Tooltip:()=>qJ,Toast:()=>QJ,Timeline:()=>GJ,Tabs:()=>ZJ,Table:()=>KJ,Swap:()=>MJ,Stat:()=>tM,Stack:()=>lM,Select:()=>aM,Rating:()=>iM,Range:()=>cM,Radio:()=>dM,Navbar:()=>mM,Modal:()=>gM,Menu:()=>vM,List:()=>yM,Label:()=>wM,Input:()=>g,Indicator:()=>xM,Fileinput:()=>OM,Fieldset:()=>EM,Fab:()=>jM,Dropdown:()=>VM,Drawer:()=>DM,Datepicker:()=>zM,Colorpicker:()=>CM,Checkbox:()=>PM,Button:()=>h,Badge:()=>BM,Autocomplete:()=>LM,Alert:()=>GM,Accordion:()=>ZM});var O=null,y=null,d=new Set,p=!1,MM=new WeakMap,SJ=()=>{if(p)return;p=!0;while(d.size>0){let W=Array.from(d).sort((X,Z)=>(X.depth||0)-(Z.depth||0));d.clear();for(let X of W)if(!X._deleted)X()}p=!1},CJ=(W)=>{if(O&&!O._deleted)W.add(O),O._deps.add(W)},JM=(W)=>{for(let X of W){if(X===O||X._deleted)continue;if(X._isComputed){if(X.markDirty(),X._subs)JM(X._subs)}else d.add(X)}if(!p)queueMicrotask(SJ)},KM=(W)=>{if(W._cleanups)W._cleanups.forEach((X)=>X()),W._cleanups.clear();W.childNodes?.forEach(KM)},c=(W)=>{let X=new Set,Z=y,J=document.createElement("div");J.style.display="contents",y={cleanups:X};try{let Y=W({onCleanup:(K)=>X.add(K)}),Q=(K)=>{if(!K)return;if(K._isRuntime)X.add(K.destroy),J.appendChild(K.container);else if(Array.isArray(K))K.forEach(Q);else J.appendChild(K instanceof Node?K:document.createTextNode(String(K)))};Q(Y)}finally{y=Z}return{_isRuntime:!0,container:J,destroy:()=>{X.forEach((Y)=>Y()),KM(J),J.remove()}}},U=(W,X=null)=>{if(typeof W==="function"){let Y=new Set,Q,K=!0,G=()=>{if(G._deleted)return;G._deps.forEach((L)=>L.delete(G)),G._deps.clear();let q=O;O=G;try{let L=W();if(!Object.is(Q,L)||K)Q=L,K=!1,JM(Y)}finally{O=q}};if(G._deps=new Set,G._isComputed=!0,G._subs=Y,G._deleted=!1,G.markDirty=()=>K=!0,G.stop=()=>{G._deleted=!0,G._deps.forEach((q)=>q.delete(G)),Y.clear()},y)y.cleanups.add(G.stop);return()=>{if(K)G();return CJ(Y),Q}}let Z=W;if(X)try{let Y=localStorage.getItem(X);if(Y!==null)Z=JSON.parse(Y)}catch(Y){console.warn("SigPro: LocalStorage locked",Y)}let J=new Set;return(...Y)=>{if(Y.length){let Q=typeof Y[0]==="function"?Y[0](Z):Y[0];if(!Object.is(Z,Q)){if(Z=Q,X)localStorage.setItem(X,JSON.stringify(Z));JM(J)}}return CJ(J),Z}},$=(W,X)=>{let Z=Array.isArray(W),J=Z?X:W,Y=Z?W:null;if(typeof J!=="function")return()=>{};let Q=y,K=()=>{if(K._deleted)return;K._deps.forEach((L)=>L.delete(K)),K._deps.clear(),K._cleanups.forEach((L)=>L()),K._cleanups.clear();let G=O,q=y;O=K,y={cleanups:K._cleanups},K.depth=G?G.depth+1:0;try{if(Z)O=null,J(),O=K,Y.forEach((L)=>typeof L==="function"&&L());else J()}finally{O=G,y=q}};if(K._deps=new Set,K._cleanups=new Set,K._deleted=!1,K.stop=()=>{if(K._deleted)return;if(K._deleted=!0,d.delete(K),K._deps.forEach((G)=>G.delete(K)),K._cleanups.forEach((G)=>G()),Q)Q.cleanups.delete(K.stop)},Q)Q.cleanups.add(K.stop);return K(),K.stop},M=(W,X={},Z=[])=>{if(X instanceof Node||Array.isArray(X)||typeof X!=="object")Z=X,X={};let J=document.createElement(W),Y=(K,G)=>(K==="src"||K==="href")&&String(G).toLowerCase().includes("javascript:")?"#":G;J._cleanups=new Set;for(let[K,G]of Object.entries(X)){if(K==="ref"){typeof G==="function"?G(J):G.current=J;continue}let q=typeof G==="function";if(["INPUT","TEXTAREA","SELECT"].includes(J.tagName)&&(K==="value"||K==="checked")&&q){J._cleanups.add($(()=>{let C=G();if(J[K]!==C)J[K]=C}));let A=K==="checked"?"change":"input",D=(C)=>G(C.target[K]);J.addEventListener(A,D),J._cleanups.add(()=>J.removeEventListener(A,D))}else if(K.startsWith("on")){let A=K.slice(2).toLowerCase().split(".")[0],D=(C)=>G(C);J.addEventListener(A,D),J._cleanups.add(()=>J.removeEventListener(A,D))}else if(q)J._cleanups.add($(()=>{let A=Y(K,G());if(K==="class")J.className=A||"";else A==null?J.removeAttribute(K):J.setAttribute(K,A)}));else J.setAttribute(K,Y(K,G))}let Q=(K)=>{if(Array.isArray(K))return K.forEach(Q);if(typeof K==="function"){let G=document.createTextNode("");J.appendChild(G);let q=[];J._cleanups.add($(()=>{let L=K(),B=(Array.isArray(L)?L:[L]).map((A)=>A?._isRuntime?A.container:A instanceof Node?A:document.createTextNode(A??""));q.forEach((A)=>{KM(A),A.remove()}),B.forEach((A)=>G.parentNode?.insertBefore(A,G)),q=B}))}else J.appendChild(K instanceof Node?K:document.createTextNode(K??""))};return Q(Z),J},E=(W,X,Z=null)=>{let J=document.createTextNode(""),Y=M("div",{style:"display:contents"},[J]),Q=null,K=null;return $(()=>{let G=!!(typeof W==="function"?W():W);if(G!==K){if(K=G,Q)Q.destroy();let q=G?X:Z;if(q)Q=c(()=>typeof q==="function"?q():q),Y.insertBefore(Q.container,J)}}),Y};E.not=(W,X,Z)=>E(()=>!(typeof W==="function"?W():W),X,Z);var j=(W,X,Z)=>{let J=document.createTextNode(""),Y=M("div",{style:"display:contents"},[J]),Q=new Map;return $(()=>{let K=(typeof W==="function"?W():W)||[],G=new Map,q=[];for(let B=0;BX(A,B));else Q.delete(D);G.set(D,C),q.push(D)}Q.forEach((B)=>{B.destroy(),B.container.remove()});let L=J;for(let B=q.length-1;B>=0;B--){let A=G.get(q[B]);if(A.container.nextSibling!==L)Y.insertBefore(A.container,L);L=A.container}Q=G}),Y},b=(W)=>{let X=U(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>X(window.location.hash.replace(/^#/,"")||"/"));let Z=M("div",{class:"router-outlet"}),J=null;return $([X],async()=>{let Y=X(),Q=W.find((K)=>{let G=K.path.split("/").filter(Boolean),q=Y.split("/").filter(Boolean);return G.length===q.length&&G.every((L,B)=>L.startsWith(":")||L===q[B])})||W.find((K)=>K.path==="*");if(Q){let K=Q.component;if(typeof K==="function"&&K.toString().includes("import"))K=(await K()).default||await K();let G={};if(Q.path.split("/").filter(Boolean).forEach((q,L)=>{if(q.startsWith(":"))G[q.slice(1)]=Y.split("/").filter(Boolean)[L]}),J)J.destroy();if(b.params)b.params(G);J=c(()=>{try{return typeof K==="function"?K(G):K}catch(q){return M("div",{class:"p-4 text-error"},"Error loading view")}}),Z.appendChild(J.container)}}),Z};b.params=U({});b.to=(W)=>window.location.hash=W.replace(/^#?\/?/,"#/");b.back=()=>window.history.back();b.path=()=>window.location.hash.replace(/^#/,"")||"/";var WM=(W,X)=>{let Z=typeof X==="string"?document.querySelector(X):X;if(!Z)return;if(MM.has(Z))MM.get(Z).destroy();let J=c(typeof W==="function"?W:()=>W);return Z.replaceChildren(J.container),MM.set(Z,J),J},EJ={$:U,$watch:$,$html:M,$if:E,$for:j,$router:b,$mount:WM};if(typeof window<"u")((X)=>{Object.keys(X).forEach((J)=>{window[J]=X[J]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((J)=>{let Y=J.charAt(0).toUpperCase()+J.slice(1);if(!(Y in window))window[Y]=(Q,K)=>M(J,Q,K)}),window.SigPro=Object.freeze(X)})(EJ);var i={};z(i,{default:()=>IJ,Tooltip:()=>qJ,Toast:()=>QJ,Timeline:()=>GJ,Tabs:()=>ZJ,Table:()=>KJ,Swap:()=>MJ,Stat:()=>tM,Stack:()=>lM,Select:()=>aM,Rating:()=>iM,Range:()=>cM,Radio:()=>dM,Navbar:()=>mM,Modal:()=>gM,Menu:()=>vM,List:()=>yM,Label:()=>wM,Input:()=>g,Indicator:()=>xM,Fileinput:()=>OM,Fieldset:()=>EM,Fab:()=>jM,Dropdown:()=>VM,Drawer:()=>DM,Datepicker:()=>zM,Colorpicker:()=>CM,Checkbox:()=>PM,Button:()=>h,Badge:()=>BM,Autocomplete:()=>LM,Alert:()=>GM,Accordion:()=>ZM});var XM={};z(XM,{Accordion:()=>ZM});var o={};z(o,{val:()=>_,ui:()=>P,getIcon:()=>V});var _=(W)=>typeof W==="function"?W():W,P=(W,X)=>typeof X==="function"?()=>`${W} ${X()||""}`.trim():`${W} ${X||""}`.trim(),V=(W)=>{if(!W)return null;if(typeof W==="function")return M("span",{class:"mr-1"},W());if(typeof W==="object")return M("span",{class:"mr-1"},W);if(typeof W==="string"){let X=W.trim().split(/\s+/),Z=X[X.length-1]==="right",J=Z?X.slice(0,-1).join(" "):W,Y=Z?"ml-1":"mr-1";if(J&&!J.startsWith("icon-[")&&!J.includes("--"))return M("span",{class:Y},J);return M("span",{class:`${J} ${Y}`.trim()})}return null};var ZM=(W,X)=>{let{class:Z,title:J,name:Y,open:Q,...K}=W;return M("div",{...K,class:P("collapse collapse-arrow bg-base-200 mb-2",Z)},[M("input",{type:Y?"radio":"checkbox",name:Y,checked:_(Q)}),M("div",{class:"collapse-title text-xl font-medium"},J),M("div",{class:"collapse-content"},X)])};var YM={};z(YM,{Alert:()=>GM});var GM=(W,X)=>{let{class:Z,actions:J,type:Y="info",soft:Q=!0,...K}=W,G={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"},B=[`alert-${Y}`,Q?"alert-soft":"",Z].filter(Boolean).join(" "),A=X||W.message;return M("div",{...K,role:"alert",class:P("alert",B)},()=>[V(G[Y]),M("div",{class:"flex-1"},[M("span",{},[typeof A==="function"?A():A])]),J?M("div",{class:"flex-none"},[typeof J==="function"?J():J]):null].filter(Boolean))};var qM={};z(qM,{Autocomplete:()=>LM});var NJ={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"}},OJ=U("es");var x=(W)=>()=>NJ[OJ()][W]||W;var QM={};z(QM,{Input:()=>g});var g=(W)=>{let{class:X,value:Z,type:J="text",icon:Y,oninput:Q,placeholder:K,disabled:G,size:q,...L}=W,B=J==="password",A=U(!1),D={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]"},C=Y?V(Y):D[J]?V(D[J]):null,R=()=>V(A()?"icon-[lucide--eye-off]":"icon-[lucide--eye]"),H=C?"pl-10":"",N=B?"pr-10":"",r=()=>{if(X?.includes("input-xs"))return"btn-xs";if(X?.includes("input-sm"))return"btn-sm";if(X?.includes("input-lg"))return"btn-lg";return"btn-md"};return M("div",{class:"relative w-full"},()=>[M("input",{...L,type:()=>B?A()?"text":"password":J,placeholder:K||" ",class:P("input w-full",`${H} ${N} ${X||""}`.trim()),value:Z,oninput:(m)=>Q?.(m),disabled:()=>_(G)}),C?M("div",{class:"absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60"},C):null,B?M("button",{type:"button",class:P("absolute right-3 inset-y-0 flex items-center","btn btn-ghost btn-circle opacity-50 hover:opacity-100",r()),onclick:(m)=>{m.preventDefault(),A(!A())}},()=>R()):null])};var LM=(W)=>{let{class:X,items:Z=[],value:J,onSelect:Y,label:Q,placeholder:K,...G}=W,q=U(_(J)||""),L=U(!1),B=U(-1),A=U(()=>{let R=q().toLowerCase(),H=_(Z)||[];return R?H.filter((N)=>(typeof N==="string"?N:N.label).toLowerCase().includes(R)):H}),D=(R)=>{let H=typeof R==="string"?R:R.value,N=typeof R==="string"?R:R.label;if(q(N),typeof J==="function")J(H);Y?.(R),L(!1),B(-1)},C=(R)=>{let H=A();if(R.key==="ArrowDown")R.preventDefault(),L(!0),B(Math.min(B()+1,H.length-1));else if(R.key==="ArrowUp")R.preventDefault(),B(Math.max(B()-1,0));else if(R.key==="Enter"&&B()>=0)R.preventDefault(),D(H[B()]);else if(R.key==="Escape")L(!1)};return M("div",{class:"relative w-full"},[g({label:Q,class:X,placeholder:K||x("search")(),value:q,onfocus:()=>L(!0),onblur:()=>setTimeout(()=>L(!1),150),onkeydown:C,oninput:(R)=>{let H=R.target.value;if(q(H),typeof J==="function")J(H);L(!0),B(-1)},...G}),M("ul",{class:"absolute 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:()=>L()&&A().length?"display:block":"display:none"},[j(A,(R,H)=>M("li",{},[M("a",{class:()=>`block w-full ${B()===H?"active bg-primary text-primary-content":""}`,onclick:()=>D(R),onmouseenter:()=>B(H)},typeof R==="string"?R:R.label)]),(R,H)=>(typeof R==="string"?R:R.value)+H),()=>A().length?null:M("li",{class:"p-2 text-center opacity-50"},x("nodata")())])])};var AM={};z(AM,{Badge:()=>BM});var BM=(W,X)=>{let{class:Z,...J}=W;return M("span",{...J,class:P("badge",Z)},X)};var _M={};z(_M,{Button:()=>h});var h=(W,X)=>{let{class:Z,loading:J,icon:Y,...Q}=W,K=V(Y);return M("button",{...Q,class:P("btn",Z),disabled:()=>_(J)||_(W.disabled)},()=>[_(J)&&M("span",{class:"loading loading-spinner"}),K,X].filter(Boolean))};var TM={};z(TM,{Checkbox:()=>PM});var PM=(W)=>{let{class:X,value:Z,tooltip:J,toggle:Y,label:Q,...K}=W,G=M("input",{...K,type:"checkbox",class:()=>P(_(Y)?"toggle":"checkbox",X),checked:Z}),q=M("label",{class:"label cursor-pointer justify-start gap-3"},[G,Q?M("span",{class:"label-text"},Q):null]);return J?M("div",{class:"tooltip","data-tip":J},q):q};var RM={};z(RM,{Colorpicker:()=>CM});var CM=(W)=>{let{class:X,value:Z,label:J,...Y}=W,Q=U(!1),K=["#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"],G=()=>_(Z)||"#000000";return M("div",{class:P("relative w-fit",X)},[M("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:(q)=>{q.stopPropagation(),Q(!Q())},...Y},[M("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${G()}`}),J?M("span",{class:"opacity-80"},J):null]),E(Q,()=>M("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:(q)=>q.stopPropagation()},[M("div",{class:"grid grid-cols-8 gap-1"},K.map((q)=>M("button",{type:"button",style:`background-color: ${q}`,class:()=>{return`size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 - ${G().toLowerCase()===q.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""}`},onclick:()=>{if(typeof Z==="function")Z(q);Q(!1)}})))])),E(Q,()=>M("div",{class:"fixed inset-0 z-[100]",onclick:()=>Q(!1)}))])};var FM={};z(FM,{Datepicker:()=>zM});var zM=(W)=>{let{class:X,value:Z,range:J,label:Y,placeholder:Q,hour:K=!1,...G}=W,q=U(!1),L=U(new Date),B=U(null),A=U(0),D=U(0),C=()=>_(J)===!0,R=new Date,H=`${R.getFullYear()}-${String(R.getMonth()+1).padStart(2,"0")}-${String(R.getDate()).padStart(2,"0")}`,N=(T)=>{let F=T.getFullYear(),S=String(T.getMonth()+1).padStart(2,"0"),k=String(T.getDate()).padStart(2,"0");return`${F}-${S}-${k}`},r=(T)=>{let F=N(T),S=_(Z);if(C())if(!S?.start||S.start&&S.end){if(typeof Z==="function")Z({start:F,end:null,...K&&{startHour:A()}})}else{let k=S.start;if(typeof Z==="function"){let u=F{let T=_(Z);if(!T)return"";if(typeof T==="string"){if(K&&T.includes("T"))return T.replace("T"," ");return T}if(T.start&&T.end){let F=K&&T.startHour?`${T.start} ${String(T.startHour).padStart(2,"0")}:00`:T.start,S=K&&T.endHour?`${T.end} ${String(T.endHour).padStart(2,"0")}:00`:T.end;return`${F} - ${S}`}if(T.start)return`${K&&T.startHour?`${T.start} ${String(T.startHour).padStart(2,"0")}:00`:T.start}...`;return""}),AJ=(T)=>{let F=L();L(new Date(F.getFullYear(),F.getMonth()+T,1))},_J=(T)=>{let F=L();L(new Date(F.getFullYear()+T,F.getMonth(),1))},a=({value:T,onChange:F})=>{return M("div",{class:"flex-1"},[M("div",{class:"flex gap-2 items-center"},[M("input",{type:"range",min:0,max:23,value:T,class:"range range-xs flex-1",oninput:(S)=>{let k=parseInt(S.target.value);F(k)}}),M("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(_(T)).padStart(2,"0")+":00")])])};return M("div",{class:P("relative w-full",X)},[g({label:Y,placeholder:Q||(C()?"Seleccionar rango...":"Seleccionar fecha..."),value:m,readonly:!0,icon:V("icon-[lucide--calendar]"),onclick:(T)=>{T.stopPropagation(),q(!q())},...G}),E(q,()=>M("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:(T)=>T.stopPropagation()},[M("div",{class:"flex justify-between items-center mb-4 gap-1"},[M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>_J(-1)},V("icon-[lucide--chevrons-left]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>AJ(-1)},V("icon-[lucide--chevron-left]"))]),M("span",{class:"font-bold uppercase flex-1 text-center"},[()=>L().toLocaleString("es-ES",{month:"short",year:"numeric"})]),M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>AJ(1)},V("icon-[lucide--chevron-right]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>_J(1)},V("icon-[lucide--chevrons-right]"))])]),M("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>B(null)},[...["L","M","X","J","V","S","D"].map((T)=>M("div",{class:"text-[10px] opacity-40 font-bold text-center"},T)),()=>{let T=L(),F=T.getFullYear(),S=T.getMonth(),k=new Date(F,S,1).getDay(),u=k===0?6:k-1,zJ=new Date(F,S+1,0).getDate(),s=[];for(let v=0;v{let f=_(Z),l=B(),FJ=typeof f==="string"?f.split("T")[0]===I:f?.start===I,DJ=f?.end===I,n=!1;if(C()&&f?.start){let t=f.start;if(!f.end&&l)n=I>t&&I<=l||I=l;else if(f.end)n=I>t&&I{if(C())B(I)},onclick:()=>r(PJ)},[v.toString()]))}return s}]),K?M("div",{class:"mt-3 pt-2 border-t border-base-300"},[C()?M("div",{class:"flex gap-4"},[a({value:A,onChange:(T)=>{A(T);let F=_(Z);if(F?.start)Z({...F,startHour:T})}}),a({value:D,onChange:(T)=>{D(T);let F=_(Z);if(F?.end)Z({...F,endHour:T})}})]):a({value:A,onChange:(T)=>{A(T);let F=_(Z);if(F&&typeof F==="string"&&F.includes("-"))Z(F.split("T")[0]+"T"+String(T).padStart(2,"0")+":00:00")}})]):null])),E(q,()=>M("div",{class:"fixed inset-0 z-[90]",onclick:()=>q(!1)}))])};var UM={};z(UM,{Drawer:()=>DM});var DM=(W,X)=>{let{class:Z,id:J,open:Y,side:Q,content:K,...G}=W,q=J||`drawer-${Math.random().toString(36).slice(2,9)}`;return M("div",{...G,class:P("drawer",Z)},[M("input",{id:q,type:"checkbox",class:"drawer-toggle",checked:()=>typeof Y==="function"?Y():Y,onchange:(L)=>{if(typeof Y==="function")Y(L.target.checked)}}),M("div",{class:"drawer-content"},[typeof K==="function"?K():K]),M("div",{class:"drawer-side"},[M("label",{for:q,class:"drawer-overlay",onclick:()=>{if(typeof Y==="function")Y(!1)}}),M("div",{class:"min-h-full bg-base-200 w-80"},[typeof Q==="function"?Q():Q])])])};var HM={};z(HM,{Dropdown:()=>VM});var w=null;if(typeof window<"u"&&!window.__dropdownHandlerRegistered)window.addEventListener("click",(W)=>{if(w&&!w.contains(W.target))w.open=!1,w=null}),window.__dropdownHandlerRegistered=!0;var VM=(W)=>{let{class:X,label:Z,icon:J,items:Y,...Q}=W;return $html("details",{...Q,class:P("dropdown",X)},[$html("summary",{class:"btn m-1 flex items-center gap-2 list-none cursor-pointer",style:"display: inline-flex;",onclick:(K)=>{let G=K.currentTarget.closest("details");if(w&&w!==G)w.open=!1;setTimeout(()=>{w=G.open?G:null},0)}},[()=>J?typeof J==="function"?J():J:null,()=>Z?typeof Z==="function"?Z():Z:null]),$html("ul",{tabindex:"-1",class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"},[()=>{return(typeof Y==="function"?Y():Y||[]).map((G)=>$html("li",{},[$html("a",{class:G.class||"",onclick:(q)=>{if(G.onclick)G.onclick(q);let L=q.currentTarget.closest("details");if(L){if(L.open=!1,w===L)w=null}}},[G.icon?$html("span",{},G.icon):null,$html("span",{},G.label)])]))}])])};var SM={};z(SM,{Fab:()=>jM});var jM=(W)=>{let{class:X,icon:Z,label:J,actions:Y=[],position:Q="bottom-6 right-6",...K}=W;return M("div",{...K,class:P(`fab absolute ${Q} flex flex-col-reverse items-end gap-3 z-[100]`,X)},[M("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[Z?V(Z):null,!Z&&J?J:null]),..._(Y).map((G)=>M("div",{class:"flex items-center gap-3 transition-all duration-300"},[G.label?M("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},G.label):null,M("button",{type:"button",class:`btn btn-circle shadow-lg ${G.class||""}`,onclick:(q)=>{q.stopPropagation(),G.onclick?.(q)}},[G.icon?V(G.icon):G.text||""])]))])};var NM={};z(NM,{Fieldset:()=>EM});var EM=(W,X)=>{let{class:Z,legend:J,...Y}=W;return M("fieldset",{...Y,class:P("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",Z)},[()=>{let Q=_(J);return Q?M("legend",{class:"fieldset-legend font-bold"},[Q]):null},X])};var IM={};z(IM,{Fileinput:()=>OM});var OM=(W)=>{let{class:X,tooltip:Z,max:J=2,accept:Y="*",onSelect:Q,...K}=W,G=U([]),q=U(!1),L=U(null),B=J*1024*1024,A=(C)=>{let R=Array.from(C);if(L(null),R.find((N)=>N.size>B)){L(`Máx ${J}MB`);return}G([...G(),...R]),Q?.(G())},D=(C)=>{let R=G().filter((H,N)=>N!==C);G(R),Q?.(R)};return M("fieldset",{...K,class:P("fieldset w-full p-0",X)},[M("div",{class:()=>`w-full ${Z?"tooltip tooltip-top before:z-50 after:z-50":""}`,"data-tip":Z},[M("label",{class:()=>` +(()=>{var{defineProperty:JM,getOwnPropertyNames:UJ,getOwnPropertyDescriptor:HJ}=Object,VJ=Object.prototype.hasOwnProperty;var TJ=new WeakMap,SJ=(Z)=>{var K=TJ.get(Z),G;if(K)return K;if(K=JM({},"__esModule",{value:!0}),Z&&typeof Z==="object"||typeof Z==="function")UJ(Z).map((J)=>!VJ.call(K,J)&&JM(K,J,{get:()=>Z[J],enumerable:!(G=HJ(Z,J))||G.enumerable}));return TJ.set(Z,K),K};var U=(Z,K)=>{for(var G in K)JM(Z,G,{get:K[G],enumerable:!0,configurable:!0,set:(J)=>K[G]=()=>J})};var xJ={};U(xJ,{val:()=>q,ui:()=>_,tt:()=>k,getIcon:()=>V,Tooltip:()=>AJ,Toast:()=>BJ,Timeline:()=>QJ,Tabs:()=>KJ,Table:()=>XJ,Swap:()=>WJ,Stat:()=>MJ,Stack:()=>tM,Select:()=>nM,Rating:()=>aM,Range:()=>iM,Radio:()=>cM,Navbar:()=>dM,Modal:()=>mM,Menu:()=>gM,List:()=>vM,Label:()=>yM,Input:()=>m,Indicator:()=>wM,Fileinput:()=>xM,Fieldset:()=>jM,Fab:()=>NM,Dropdown:()=>SM,Drawer:()=>HM,Datepicker:()=>FM,Colorpicker:()=>RM,Checkbox:()=>CM,Button:()=>u,Badge:()=>_M,Autocomplete:()=>qM,Alert:()=>QM,Accordion:()=>KM});var j=null,$=null,p=new Set,i=!1,WM=new WeakMap,EJ=()=>{if(i)return;i=!0;while(p.size>0){let Z=Array.from(p).sort((K,G)=>(K.depth||0)-(G.depth||0));p.clear();for(let K of Z)if(!K._deleted)K()}i=!1},CJ=(Z)=>{if(j&&!j._deleted)Z.add(j),j._deps.add(Z)},ZM=(Z)=>{for(let K of Z){if(K===j||K._deleted)continue;if(K._isComputed){if(K.markDirty(),K._subs)ZM(K._subs)}else p.add(K)}if(!i)queueMicrotask(EJ)},XM=(Z)=>{if(Z._cleanups)Z._cleanups.forEach((K)=>K()),Z._cleanups.clear();Z.childNodes?.forEach(XM)},r=(Z)=>{let K=new Set,G=$,J=document.createElement("div");J.style.display="contents",$={cleanups:K};try{let Y=Z({onCleanup:(X)=>K.add(X)}),L=(X)=>{if(!X)return;if(X._isRuntime)K.add(X.destroy),J.appendChild(X.container);else if(Array.isArray(X))X.forEach(L);else J.appendChild(X instanceof Node?X:document.createTextNode(String(X)))};L(Y)}finally{$=G}return{_isRuntime:!0,container:J,destroy:()=>{K.forEach((Y)=>Y()),XM(J),J.remove()}}},H=(Z,K=null)=>{if(typeof Z==="function"){let Y=new Set,L,X=!0,W=()=>{if(W._deleted)return;W._deps.forEach((B)=>B.delete(W)),W._deps.clear();let Q=j;j=W;try{let B=Z();if(!Object.is(L,B)||X)L=B,X=!1,ZM(Y)}finally{j=Q}};if(W._deps=new Set,W._isComputed=!0,W._subs=Y,W._deleted=!1,W.markDirty=()=>X=!0,W.stop=()=>{W._deleted=!0,W._deps.forEach((Q)=>Q.delete(W)),Y.clear()},$)$.cleanups.add(W.stop);return()=>{if(X)W();return CJ(Y),L}}let G=Z;if(K)try{let Y=localStorage.getItem(K);if(Y!==null)G=JSON.parse(Y)}catch(Y){console.warn("SigPro: LocalStorage locked",Y)}let J=new Set;return(...Y)=>{if(Y.length){let L=typeof Y[0]==="function"?Y[0](G):Y[0];if(!Object.is(G,L)){if(G=L,K)localStorage.setItem(K,JSON.stringify(G));ZM(J)}}return CJ(J),G}},w=(Z,K)=>{let G=Array.isArray(Z),J=G?K:Z,Y=G?Z:null;if(typeof J!=="function")return()=>{};let L=$,X=()=>{if(X._deleted)return;X._deps.forEach((B)=>B.delete(X)),X._deps.clear(),X._cleanups.forEach((B)=>B()),X._cleanups.clear();let W=j,Q=$;j=X,$={cleanups:X._cleanups},X.depth=W?W.depth+1:0;try{if(G)j=null,J(),j=X,Y.forEach((B)=>typeof B==="function"&&B());else J()}finally{j=W,$=Q}};if(X._deps=new Set,X._cleanups=new Set,X._deleted=!1,X.stop=()=>{if(X._deleted)return;if(X._deleted=!0,p.delete(X),X._deps.forEach((W)=>W.delete(X)),X._cleanups.forEach((W)=>W()),L)L.cleanups.delete(X.stop)},L)L.cleanups.add(X.stop);return X(),X.stop},M=(Z,K={},G=[])=>{if(K instanceof Node||Array.isArray(K)||typeof K!=="object")G=K,K={};let J=document.createElement(Z),Y=(W,Q)=>(W==="src"||W==="href")&&String(Q).toLowerCase().includes("javascript:")?"#":Q;J._cleanups=new Set;let L=["disabled","checked","required","readonly","selected","multiple","autofocus"];for(let[W,Q]of Object.entries(K)){if(W==="ref"){typeof Q==="function"?Q(J):Q.current=J;continue}let B=typeof Q==="function";if(["INPUT","TEXTAREA","SELECT"].includes(J.tagName)&&(W==="value"||W==="checked")&&B){J._cleanups.add(w(()=>{let A=Q();if(J[W]!==A)J[W]=A}));let P=W==="checked"?"change":"input",R=(A)=>Q(A.target[W]);J.addEventListener(P,R),J._cleanups.add(()=>J.removeEventListener(P,R))}else if(W.startsWith("on")){let P=W.slice(2).toLowerCase().split(".")[0],R=(A)=>Q(A);J.addEventListener(P,R),J._cleanups.add(()=>J.removeEventListener(P,R))}else if(B)J._cleanups.add(w(()=>{let P=Y(W,Q());if(W==="class")J.className=P||"";else if(L.includes(W))if(P)J.setAttribute(W,""),J[W]=!0;else J.removeAttribute(W),J[W]=!1;else P==null?J.removeAttribute(W):J.setAttribute(W,P)}));else if(L.includes(W))if(Q)J.setAttribute(W,""),J[W]=!0;else J.removeAttribute(W),J[W]=!1;else J.setAttribute(W,Y(W,Q))}let X=(W)=>{if(Array.isArray(W))return W.forEach(X);if(W instanceof Node)J.appendChild(W);else if(typeof W==="function"){let Q=document.createTextNode("");J.appendChild(Q);let B=[];J._cleanups.add(w(()=>{let z=W(),T=(Array.isArray(z)?z:[z]).map((P)=>P?._isRuntime?P.container:P instanceof Node?P:document.createTextNode(P??""));B.forEach((P)=>{XM?.(P),P.remove()}),T.forEach((P)=>Q.parentNode?.insertBefore(P,Q)),B=T}))}else J.appendChild(document.createTextNode(W??""))};return X(G),J},N=(Z,K,G=null)=>{let J=document.createTextNode(""),Y=M("div",{style:"display:contents"},[J]),L=null,X=null;return w(()=>{let W=!!(typeof Z==="function"?Z():Z);if(W!==X){if(X=W,L)L.destroy();let Q=W?K:G;if(Q)L=r(()=>typeof Q==="function"?Q():Q),Y.insertBefore(L.container,J)}}),Y};N.not=(Z,K,G)=>N(()=>!(typeof Z==="function"?Z():Z),K,G);var O=(Z,K,G,J="div",Y={style:"display:contents"})=>{let L=document.createTextNode(""),X=M(J,Y,[L]),W=new Map;return w(()=>{let Q=(typeof Z==="function"?Z():Z)||[],B=new Map,z=[];for(let P=0;PK(R,P));else W.delete(A);B.set(A,D),z.push(A)}W.forEach((P)=>{P.destroy(),P.container.remove()});let T=L;for(let P=z.length-1;P>=0;P--){let R=B.get(z[P]);if(R.container.nextSibling!==T)X.insertBefore(R.container,T);T=R.container}W=B}),X},h=(Z)=>{let K=H(window.location.hash.replace(/^#/,"")||"/");window.addEventListener("hashchange",()=>K(window.location.hash.replace(/^#/,"")||"/"));let G=M("div",{class:"router-outlet"}),J=null;return w([K],async()=>{let Y=K(),L=Z.find((X)=>{let W=X.path.split("/").filter(Boolean),Q=Y.split("/").filter(Boolean);return W.length===Q.length&&W.every((B,z)=>B.startsWith(":")||B===Q[z])})||Z.find((X)=>X.path==="*");if(L){let X=L.component;if(typeof X==="function"&&X.toString().includes("import"))X=(await X()).default||await X();let W={};if(L.path.split("/").filter(Boolean).forEach((Q,B)=>{if(Q.startsWith(":"))W[Q.slice(1)]=Y.split("/").filter(Boolean)[B]}),J)J.destroy();if(h.params)h.params(W);J=r(()=>{try{return typeof X==="function"?X(W):X}catch(Q){return M("div",{class:"p-4 text-error"},"Error loading view")}}),G.appendChild(J.container)}}),G};h.params=H({});h.to=(Z)=>window.location.hash=Z.replace(/^#?\/?/,"#/");h.back=()=>window.history.back();h.path=()=>window.location.hash.replace(/^#/,"")||"/";var GM=(Z,K)=>{let G=typeof K==="string"?document.querySelector(K):K;if(!G)return;if(WM.has(G))WM.get(G).destroy();let J=r(typeof Z==="function"?Z:()=>Z);return G.replaceChildren(J.container),WM.set(G,J),J},NJ={$:H,$watch:w,$html:M,$if:N,$for:O,$router:h,$mount:GM};if(typeof window<"u")((K)=>{Object.keys(K).forEach((J)=>{window[J]=K[J]}),"div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter".split(/\s+/).forEach((J)=>{let Y=J.charAt(0).toUpperCase()+J.slice(1);if(!(Y in window))window[Y]=(L,X)=>M(J,L,X)}),window.SigPro=Object.freeze(K)})(NJ);var l={};U(l,{default:()=>IJ,Tooltip:()=>AJ,Toast:()=>BJ,Timeline:()=>QJ,Tabs:()=>KJ,Table:()=>XJ,Swap:()=>WJ,Stat:()=>MJ,Stack:()=>tM,Select:()=>nM,Rating:()=>aM,Range:()=>iM,Radio:()=>cM,Navbar:()=>dM,Modal:()=>mM,Menu:()=>gM,List:()=>vM,Label:()=>yM,Input:()=>m,Indicator:()=>wM,Fileinput:()=>xM,Fieldset:()=>jM,Fab:()=>NM,Dropdown:()=>SM,Drawer:()=>HM,Datepicker:()=>FM,Colorpicker:()=>RM,Checkbox:()=>CM,Button:()=>u,Badge:()=>_M,Autocomplete:()=>qM,Alert:()=>QM,Accordion:()=>KM});var YM={};U(YM,{Accordion:()=>KM});var a={};U(a,{val:()=>q,ui:()=>_,getIcon:()=>V});var q=(Z)=>typeof Z==="function"?Z():Z,_=(Z,K)=>typeof K==="function"?()=>`${Z} ${K()||""}`.trim():`${Z} ${K||""}`.trim(),V=(Z)=>{if(!Z)return null;if(typeof Z==="function")return M("span",{class:"mr-1"},Z());if(typeof Z==="object")return M("span",{class:"mr-1"},Z);if(typeof Z==="string"){let K=Z.trim().split(/\s+/),G=K[K.length-1]==="right",J=G?K.slice(0,-1).join(" "):Z,Y=G?"ml-1":"mr-1";if(J&&!J.startsWith("icon-[")&&!J.includes("--"))return M("span",{class:Y},J);return M("span",{class:`${J} ${Y}`.trim()})}return null};var KM=(Z,K)=>{let{class:G,title:J,name:Y,open:L,...X}=Z;return M("div",{...X,class:_("collapse collapse-arrow bg-base-200 mb-2",G)},[M("input",{type:Y?"radio":"checkbox",name:Y,checked:q(L)}),M("div",{class:"collapse-title text-xl font-medium"},J),M("div",{class:"collapse-content"},K)])};var LM={};U(LM,{Alert:()=>QM});var QM=(Z,K)=>{let{class:G,actions:J,type:Y="info",soft:L=!0,...X}=Z,W={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"},z=[`alert-${Y}`,L?"alert-soft":"",G].filter(Boolean).join(" "),T=K||Z.message;return M("div",{...X,role:"alert",class:_("alert",z)},()=>[V(W[Y]),M("div",{class:"flex-1"},[M("span",{},[typeof T==="function"?T():T])]),J?M("div",{class:"flex-none"},[typeof J==="function"?J():J]):null].filter(Boolean))};var AM={};U(AM,{Autocomplete:()=>qM});var OJ={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"}},jJ=H("es");var k=(Z)=>()=>OJ[jJ()][Z]||Z;var BM={};U(BM,{Input:()=>m});var m=(Z)=>{let{class:K,value:G,type:J="text",icon:Y,oninput:L,placeholder:X,disabled:W,size:Q,validate:B,...z}=Z,T=J==="password",P=H(!1),R=H(null),A={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]"},D=Y?V(Y):A[J]?V(A[J]):null,E=()=>V(P()?"icon-[lucide--eye-off]":"icon-[lucide--eye]"),d=D?"pl-10":"",n=T?"pr-10":"",c=()=>{if(K?.includes("input-xs"))return"btn-xs";if(K?.includes("input-sm"))return"btn-sm";if(K?.includes("input-lg"))return"btn-lg";return"btn-md"},o=(S)=>{let I=S.target.value;if(B){let b=B(I);R(b||null)}L?.(S)},v=()=>R()&&R()!=="",F=M("input",{...z,type:()=>T?P()?"text":"password":J,placeholder:X||" ",class:()=>{let S=`input w-full ${d} ${n}`;if(K)S+=` ${K}`;if(v())S+=" input-error";return S.trim()},value:G,oninput:o,disabled:()=>q(W),"aria-invalid":()=>v()?"true":"false"});return M("div",{class:"relative w-full"},()=>[F,D?M("div",{class:"absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60"},D):null,T?M("button",{type:"button",class:_("absolute right-3 inset-y-0 flex items-center","btn btn-ghost btn-circle opacity-50 hover:opacity-100",c()),onclick:(S)=>{S.preventDefault(),P(!P())}},()=>E()):null,M("div",{class:"text-error text-xs mt-1 px-3 absolute -bottom-5 left-0"},()=>v()?R():null)])};var qM=(Z)=>{let{class:K,items:G=[],value:J,onSelect:Y,label:L,placeholder:X,...W}=Z,Q=H(q(J)||""),B=H(!1),z=H(-1),T=H(()=>{let A=Q().toLowerCase(),D=q(G)||[];return A?D.filter((E)=>(typeof E==="string"?E:E.label).toLowerCase().includes(A)):D}),P=(A)=>{let D=typeof A==="string"?A:A.value,E=typeof A==="string"?A:A.label;if(Q(E),typeof J==="function")J(D);Y?.(A),B(!1),z(-1)},R=(A)=>{let D=T();if(A.key==="ArrowDown")A.preventDefault(),B(!0),z(Math.min(z()+1,D.length-1));else if(A.key==="ArrowUp")A.preventDefault(),z(Math.max(z()-1,0));else if(A.key==="Enter"&&z()>=0)A.preventDefault(),P(D[z()]);else if(A.key==="Escape")B(!1)};return M("div",{class:"relative w-full"},[m({label:L,class:K,placeholder:X||k("search")(),value:Q,onfocus:()=>B(!0),onblur:()=>setTimeout(()=>B(!1),150),onkeydown:R,oninput:(A)=>{let D=A.target.value;if(Q(D),typeof J==="function")J(D);B(!0),z(-1)},...W}),M("ul",{class:"absolute 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:()=>B()&&T().length?"display:block":"display:none"},[O(T,(A,D)=>M("li",{},[M("a",{class:()=>`block w-full ${z()===D?"active bg-primary text-primary-content":""}`,onclick:()=>P(A),onmouseenter:()=>z(D)},typeof A==="string"?A:A.label)]),(A,D)=>(typeof A==="string"?A:A.value)+D),()=>T().length?null:M("li",{class:"p-2 text-center opacity-50"},k("nodata")())])])};var PM={};U(PM,{Badge:()=>_M});var _M=(Z,K)=>{let{class:G,...J}=Z;return M("span",{...J,class:_("badge",G)},K)};var TM={};U(TM,{Button:()=>u});var u=(Z,K)=>{let{class:G,loading:J,icon:Y,...L}=Z,X=V(Y);return M("button",{...L,class:_("btn",G),disabled:()=>q(J)||q(Z.disabled)},()=>[q(J)&&M("span",{class:"loading loading-spinner"}),X,K].filter(Boolean))};var zM={};U(zM,{Checkbox:()=>CM});var CM=(Z)=>{let{class:K,value:G,tooltip:J,toggle:Y,label:L,...X}=Z,W=M("input",{...X,type:"checkbox",class:()=>_(q(Y)?"toggle":"checkbox",K),checked:G}),Q=M("label",{class:"label cursor-pointer justify-start gap-3"},[W,L?M("span",{class:"label-text"},L):null]);return J?M("div",{class:"tooltip","data-tip":J},Q):Q};var DM={};U(DM,{Colorpicker:()=>RM});var RM=(Z)=>{let{class:K,value:G,label:J,...Y}=Z,L=H(!1),X=["#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"],W=()=>q(G)||"#000000";return M("div",{class:_("relative w-fit",K)},[M("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:(Q)=>{Q.stopPropagation(),L(!L())},...Y},[M("div",{class:"size-5 rounded-sm shadow-inner border border-black/10 shrink-0",style:()=>`background-color: ${W()}`}),J?M("span",{class:"opacity-80"},J):null]),N(L,()=>M("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:(Q)=>Q.stopPropagation()},[M("div",{class:"grid grid-cols-8 gap-1"},X.map((Q)=>M("button",{type:"button",style:`background-color: ${Q}`,class:()=>{return`size-6 rounded-sm cursor-pointer transition-all hover:scale-125 hover:z-10 active:scale-95 outline-none border border-black/5 + ${W().toLowerCase()===Q.toLowerCase()?"ring-2 ring-offset-1 ring-primary z-10 scale-110":""}`},onclick:()=>{if(typeof G==="function")G(Q);L(!1)}})))])),N(L,()=>M("div",{class:"fixed inset-0 z-[100]",onclick:()=>L(!1)}))])};var UM={};U(UM,{Datepicker:()=>FM});var FM=(Z)=>{let{class:K,value:G,range:J,label:Y,placeholder:L,hour:X=!1,...W}=Z,Q=H(!1),B=H(new Date),z=H(null),T=H(0),P=H(0),R=()=>q(J)===!0,A=new Date,D=`${A.getFullYear()}-${String(A.getMonth()+1).padStart(2,"0")}-${String(A.getDate()).padStart(2,"0")}`,E=(C)=>{let F=C.getFullYear(),S=String(C.getMonth()+1).padStart(2,"0"),I=String(C.getDate()).padStart(2,"0");return`${F}-${S}-${I}`},d=(C)=>{let F=E(C),S=q(G);if(R())if(!S?.start||S.start&&S.end){if(typeof G==="function")G({start:F,end:null,...X&&{startHour:T()}})}else{let I=S.start;if(typeof G==="function"){let b=F{let C=q(G);if(!C)return"";if(typeof C==="string"){if(X&&C.includes("T"))return C.replace("T"," ");return C}if(C.start&&C.end){let F=X&&C.startHour?`${C.start} ${String(C.startHour).padStart(2,"0")}:00`:C.start,S=X&&C.endHour?`${C.end} ${String(C.endHour).padStart(2,"0")}:00`:C.end;return`${F} - ${S}`}if(C.start)return`${X&&C.startHour?`${C.start} ${String(C.startHour).padStart(2,"0")}:00`:C.start}...`;return""}),c=(C)=>{let F=B();B(new Date(F.getFullYear(),F.getMonth()+C,1))},o=(C)=>{let F=B();B(new Date(F.getFullYear()+C,F.getMonth(),1))},v=({value:C,onChange:F})=>{return M("div",{class:"flex-1"},[M("div",{class:"flex gap-2 items-center"},[M("input",{type:"range",min:0,max:23,value:C,class:"range range-xs flex-1",oninput:(S)=>{let I=parseInt(S.target.value);F(I)}}),M("span",{class:"text-sm font-mono min-w-[48px] text-center"},()=>String(q(C)).padStart(2,"0")+":00")])])};return M("div",{class:_("relative w-full",K)},[m({label:Y,placeholder:L||(R()?"Seleccionar rango...":"Seleccionar fecha..."),value:n,readonly:!0,icon:V("icon-[lucide--calendar]"),onclick:(C)=>{C.stopPropagation(),Q(!Q())},...W}),N(Q,()=>M("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:(C)=>C.stopPropagation()},[M("div",{class:"flex justify-between items-center mb-4 gap-1"},[M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>o(-1)},V("icon-[lucide--chevrons-left]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>c(-1)},V("icon-[lucide--chevron-left]"))]),M("span",{class:"font-bold uppercase flex-1 text-center"},[()=>B().toLocaleString("es-ES",{month:"short",year:"numeric"})]),M("div",{class:"flex gap-0.5"},[M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>c(1)},V("icon-[lucide--chevron-right]")),M("button",{type:"button",class:"btn btn-ghost btn-xs px-1",onclick:()=>o(1)},V("icon-[lucide--chevrons-right]"))])]),M("div",{class:"grid grid-cols-7 gap-1",onmouseleave:()=>z(null)},[...["L","M","X","J","V","S","D"].map((C)=>M("div",{class:"text-[10px] opacity-40 font-bold text-center"},C)),()=>{let C=B(),F=C.getFullYear(),S=C.getMonth(),I=new Date(F,S,1).getDay(),b=I===0?6:I-1,RJ=new Date(F,S+1,0).getDate(),s=[];for(let g=0;g{let y=q(G),t=z(),DJ=typeof y==="string"?y.split("T")[0]===x:y?.start===x,FJ=y?.end===x,e=!1;if(R()&&y?.start){let MM=y.start;if(!y.end&&t)e=x>MM&&x<=t||x=t;else if(y.end)e=x>MM&&x{if(R())z(x)},onclick:()=>d(PJ)},[g.toString()]))}return s}]),X?M("div",{class:"mt-3 pt-2 border-t border-base-300"},[R()?M("div",{class:"flex gap-4"},[v({value:T,onChange:(C)=>{T(C);let F=q(G);if(F?.start)G({...F,startHour:C})}}),v({value:P,onChange:(C)=>{P(C);let F=q(G);if(F?.end)G({...F,endHour:C})}})]):v({value:T,onChange:(C)=>{T(C);let F=q(G);if(F&&typeof F==="string"&&F.includes("-"))G(F.split("T")[0]+"T"+String(C).padStart(2,"0")+":00:00")}})]):null])),N(Q,()=>M("div",{class:"fixed inset-0 z-[90]",onclick:()=>Q(!1)}))])};var VM={};U(VM,{Drawer:()=>HM});var HM=(Z,K)=>{let{class:G,id:J,open:Y,side:L,content:X,...W}=Z,Q=J||`drawer-${Math.random().toString(36).slice(2,9)}`;return M("div",{...W,class:_("drawer",G)},[M("input",{id:Q,type:"checkbox",class:"drawer-toggle",checked:()=>typeof Y==="function"?Y():Y,onchange:(B)=>{if(typeof Y==="function")Y(B.target.checked)}}),M("div",{class:"drawer-content"},[typeof X==="function"?X():X]),M("div",{class:"drawer-side"},[M("label",{for:Q,class:"drawer-overlay",onclick:()=>{if(typeof Y==="function")Y(!1)}}),M("div",{class:"min-h-full bg-base-200 w-80"},[typeof L==="function"?L():L])])])};var EM={};U(EM,{Dropdown:()=>SM});var f=null;if(typeof window<"u"&&!window.__dropdownHandlerRegistered)window.addEventListener("click",(Z)=>{if(f&&!f.contains(Z.target))f.open=!1,f=null}),window.__dropdownHandlerRegistered=!0;var SM=(Z)=>{let{class:K,label:G,icon:J,items:Y,...L}=Z;return $html("details",{...L,class:_("dropdown",K)},[$html("summary",{class:"btn m-1 flex items-center gap-2 list-none cursor-pointer",style:"display: inline-flex;",onclick:(X)=>{let W=X.currentTarget.closest("details");if(f&&f!==W)f.open=!1;setTimeout(()=>{f=W.open?W:null},0)}},[()=>J?typeof J==="function"?J():J:null,()=>G?typeof G==="function"?G():G:null]),$html("ul",{tabindex:"-1",class:"dropdown-content z-[50] menu p-2 shadow bg-base-100 rounded-box w-52 border border-base-300"},[()=>{return(typeof Y==="function"?Y():Y||[]).map((W)=>$html("li",{},[$html("a",{class:W.class||"",onclick:(Q)=>{if(W.onclick)W.onclick(Q);let B=Q.currentTarget.closest("details");if(B){if(B.open=!1,f===B)f=null}}},[W.icon?$html("span",{},W.icon):null,$html("span",{},W.label)])]))}])])};var OM={};U(OM,{Fab:()=>NM});var NM=(Z)=>{let{class:K,icon:G,label:J,actions:Y=[],position:L="bottom-6 right-6",...X}=Z;return M("div",{...X,class:_(`fab absolute ${L} flex flex-col-reverse items-end gap-3 z-[100]`,K)},[M("div",{tabindex:0,role:"button",class:"btn btn-lg btn-circle btn-primary shadow-2xl"},[G?V(G):null,!G&&J?J:null]),...q(Y).map((W)=>M("div",{class:"flex items-center gap-3 transition-all duration-300"},[W.label?M("span",{class:"badge badge-ghost shadow-sm whitespace-nowrap"},W.label):null,M("button",{type:"button",class:`btn btn-circle shadow-lg ${W.class||""}`,onclick:(Q)=>{Q.stopPropagation(),W.onclick?.(Q)}},[W.icon?V(W.icon):W.text||""])]))])};var IM={};U(IM,{Fieldset:()=>jM});var jM=(Z,K)=>{let{class:G,legend:J,...Y}=Z;return M("fieldset",{...Y,class:_("fieldset bg-base-200 border border-base-300 p-4 rounded-lg",G)},[()=>{let L=q(J);return L?M("legend",{class:"fieldset-legend font-bold"},[L]):null},K])};var kM={};U(kM,{Fileinput:()=>xM});var xM=(Z)=>{let{class:K,tooltip:G,max:J=2,accept:Y="*",onSelect:L,...X}=Z,W=H([]),Q=H(!1),B=H(null),z=J*1024*1024,T=(R)=>{let A=Array.from(R);if(B(null),A.find((E)=>E.size>z)){B(`Máx ${J}MB`);return}W([...W(),...A]),L?.(W())},P=(R)=>{let A=W().filter((D,E)=>E!==R);W(A),L?.(A)};return M("fieldset",{...X,class:_("fieldset w-full p-0",K)},[M("div",{class:()=>`w-full ${G?"tooltip tooltip-top before:z-50 after:z-50":""}`,"data-tip":G},[M("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 - ${q()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"} - `,ondragover:(C)=>{C.preventDefault(),q(!0)},ondragleave:()=>q(!1),ondrop:(C)=>{C.preventDefault(),q(!1),A(C.dataTransfer.files)}},[M("div",{class:"flex items-center gap-3 w-full"},[V("icon-[lucide--upload]"),M("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),M("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${J}MB`)]),M("input",{type:"file",multiple:!0,accept:Y,class:"hidden",onchange:(C)=>A(C.target.files)})])]),()=>L()?M("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},L()):null,E(()=>G().length>0,()=>M("ul",{class:"mt-2 space-y-1"},[j(G,(C,R)=>M("li",{class:"flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300"},[M("div",{class:"flex items-center gap-2 truncate"},[M("span",{class:"opacity-50"},"\uD83D\uDCC4"),M("span",{class:"truncate font-medium max-w-[200px]"},C.name),M("span",{class:"text-[9px] opacity-40"},`(${(C.size/1024).toFixed(0)} KB)`)]),M("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:(H)=>{H.preventDefault(),H.stopPropagation(),D(R)}},[V("icon-[lucide--x]")])]),(C)=>C.name+C.lastModified)]))])};var kM={};z(kM,{Indicator:()=>xM});var xM=(W,X)=>{let{value:Z,class:J,...Y}=W;return M("div",{...Y,class:"indicator"},()=>[Z?M("span",{class:P("indicator-item badge",J)},()=>typeof Z==="function"?Z():Z):null,X].filter(Boolean))};var fM={};z(fM,{Label:()=>wM});var wM=(W)=>{let{children:X,value:Z,floating:J=!1,error:Y,required:Q,class:K,...G}=W;if(J)return M("label",{class:P("floating-label w-full",K),...G},()=>[Z?M("span",{},Z):null,X,Y?M("span",{class:"text-error text-xs"},_(Y)):null]);return M("label",{class:P("input w-full",K),...G},()=>[Z?M("span",{class:"label"},Z):null,X,Y?M("span",{class:"text-error text-xs"},_(Y)):null])};var $M={};z($M,{List:()=>yM});var yM=(W)=>{let{class:X,items:Z,header:J,render:Y,keyFn:Q=(q,L)=>L,...K}=W,G=j(Z,(q,L)=>M("li",{class:"list-row"},[Y(q,L)]),Q);return M("ul",{...K,class:P("list bg-base-100 rounded-box shadow-md",X)},J?[E(J,()=>M("li",{class:"p-4 pb-2 text-xs opacity-60"},[_(J)])),G]:G)};var bM={};z(bM,{Menu:()=>vM});var vM=(W)=>{let{class:X,items:Z,...J}=W,Y=(Q)=>j(()=>Q||[],(K)=>M("li",{},[K.children?M("details",{open:K.open},[M("summary",{},[K.icon&&M("span",{class:"mr-2"},K.icon),K.label]),M("ul",{},Y(K.children))]):M("a",{class:()=>_(K.active)?"active":"",onclick:K.onclick},[K.icon&&M("span",{class:"mr-2"},K.icon),K.label])]),(K,G)=>K.label||G);return M("ul",{...J,class:P("menu bg-base-200 rounded-box",X)},Y(Z))};var hM={};z(hM,{Modal:()=>gM});var gM=(W,X)=>{let{class:Z,title:J,buttons:Y,open:Q,...K}=W,G=null,q=()=>{let B=typeof Q==="function"?Q():Q;if(!G)return;if(B){if(!G.open)G.showModal()}else if(G.open)G.close()};$(()=>q());let L=()=>{if(typeof Q==="function")Q(!1)};return M("dialog",{...K,ref:(B)=>{if(G=B,B)q()},class:P("modal",Z),onclose:L,oncancel:L},[M("div",{class:"modal-box"},[J?M("h3",{class:"text-lg font-bold mb-4"},()=>typeof J==="function"?J():J):null,M("div",{class:"py-2"},[typeof X==="function"?X():X]),M("div",{class:"modal-action"},[M("form",{method:"dialog",class:"flex gap-2"},[...(Array.isArray(Y)?Y:[Y]).filter(Boolean),h({type:"submit"},x("close")())])])]),M("form",{method:"dialog",class:"modal-backdrop"},[M("button",{},"close")])])};var uM={};z(uM,{Navbar:()=>mM});var mM=(W,X)=>{let{class:Z,...J}=W;return M("div",{...J,class:P("navbar bg-base-100 shadow-sm px-4",Z)},X)};var pM={};z(pM,{Radio:()=>dM});var dM=(W)=>{let{class:X,label:Z,tooltip:J,value:Y,inputValue:Q,name:K,...G}=W,q=M("input",{...G,type:"radio",name:K,class:P("radio",X),checked:()=>_(Y)===Q,onclick:()=>{if(typeof Y==="function")Y(Q)}});if(!Z&&!J)return q;let L=M("label",{class:"label cursor-pointer justify-start gap-3"},[q,Z?M("span",{class:"label-text"},Z):null]);return J?M("div",{class:"tooltip","data-tip":J},L):L};var oM={};z(oM,{Range:()=>cM});var cM=(W)=>{let{class:X,label:Z,tooltip:J,value:Y,...Q}=W,K=M("input",{...Q,type:"range",class:P("range",X),value:Y,disabled:()=>_(W.disabled)});if(!Z&&!J)return K;let G=M("div",{class:"flex flex-col gap-2"},[Z?M("span",{class:"label-text"},Z):null,K]);return J?M("div",{class:"tooltip","data-tip":J},G):G};var rM={};z(rM,{Rating:()=>iM});var iM=(W)=>{let{class:X,value:Z,count:J=5,mask:Y="mask-star",readonly:Q=!1,onchange:K,...G}=W,q=`rating-${Math.random().toString(36).slice(2,7)}`;return M("div",{...G,class:()=>P(`rating ${_(Q)?"pointer-events-none":""}`,X)},Array.from({length:_(J)},(L,B)=>{let A=B+1;return M("input",{type:"radio",name:q,class:`mask ${Y}`,checked:()=>Math.round(_(Z))===A,onchange:()=>{if(!_(Q)){if(typeof K==="function")K(A);else if(typeof Z==="function")Z(A)}}})}))};var sM={};z(sM,{Select:()=>aM});var aM=(W)=>{let{class:X,label:Z,items:J,value:Y,...Q}=W,K=M("select",{...Q,class:P("select select-bordered w-full",X),value:Y},j(()=>_(J)||[],(G)=>M("option",{value:G.value,$selected:()=>String(_(Y))===String(G.value)},G.label),(G)=>G.value));if(!Z)return K;return M("label",{class:"fieldset-label flex flex-col gap-1"},[M("span",{},Z),K])};var nM={};z(nM,{Stack:()=>lM});var lM=(W,X)=>{let{class:Z,...J}=W;return M("div",{...J,class:P("stack",Z)},X)};var eM={};z(eM,{Stat:()=>tM});var tM=(W)=>{let{class:X,icon:Z,label:J,value:Y,desc:Q,...K}=W;return M("div",{...K,class:P("stat",X)},[Z&&M("div",{class:"stat-figure text-secondary"},Z),J&&M("div",{class:"stat-title"},J),M("div",{class:"stat-value"},()=>_(Y)??Y),Q&&M("div",{class:"stat-desc"},Q)])};var JJ={};z(JJ,{Swap:()=>MJ});var MJ=(W)=>{let{class:X,value:Z,on:J,off:Y,...Q}=W;return M("label",{...Q,class:P("swap",X)},[M("input",{type:"checkbox",checked:()=>_(Z),onclick:(K)=>{if(typeof Z==="function")Z(K.target.checked)}}),M("div",{class:"swap-on"},J),M("div",{class:"swap-off"},Y)])};var WJ={};z(WJ,{Table:()=>KJ});var KJ=(W)=>{let{class:X,items:Z=[],columns:J=[],keyFn:Y,zebra:Q=!1,pinRows:K=!1,empty:G=x("nodata")(),...q}=W;return M("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[M("table",{...q,class:()=>{let B=_(Q)?"table-zebra":"",A=_(K)?"table-pin-rows":"";return P("table",X,B,A)}},[M("thead",{},[M("tr",{},J.map((B)=>M("th",{class:B.class||""},B.label)))]),M("tbody",{},[j(Z,(B,A)=>{return M("tr",{class:"hover"},J.map((D)=>{let C=()=>{if(D.render)return D.render(B,A);let R=B[D.key];return _(R)};return M("td",{class:D.class||""},[C])}))},Y||((B,A)=>B.id||A)),E(()=>_(Z).length===0,()=>M("tr",{},[M("td",{colspan:J.length,class:"text-center p-10 opacity-50"},[_(G)])]))]),E(()=>J.some((B)=>B.footer),()=>M("tfoot",{},[M("tr",{},J.map((B)=>M("th",{},B.footer||"")))]))])])};var XJ={};z(XJ,{Tabs:()=>ZJ});var ZJ=(W)=>{let{items:X,class:Z,...J}=W,Y=typeof X==="function"?X:()=>X||[],Q=`tabs-${Math.random().toString(36).slice(2,9)}`,K=()=>{let B=Y().findIndex((A)=>_(A.active)===!0);return B===-1?0:B},G=U(K),q=()=>{let L=K();if(L!==G())G(L)};return $watch(()=>q()),M("div",{...J,class:P("tabs",Z||"tabs-box")},[j(Y,(L,B)=>{let A=()=>G()===B;return[M("input",{type:"radio",name:Q,class:"tab","aria-label":(()=>{let C=typeof L.label==="function"?L.label():L.label;return typeof C==="string"?C:`Tab ${B+1}`})(),checked:A,disabled:()=>_(L.disabled),onchange:(C)=>{if(C.target.checked&&!_(L.disabled)){if(L.onclick)L.onclick();if(typeof L.active==="function")L.active(!0);G(B)}}}),M("div",{class:"tab-content bg-base-100 border-base-300 p-6",style:()=>A()?"display: block":"display: none"},[typeof L.content==="function"?L.content():L.content])]},(L,B)=>B)])};var YJ={};z(YJ,{Timeline:()=>GJ});var GJ=(W)=>{let{class:X,items:Z=[],vertical:J=!0,compact:Y=!1,...Q}=W,K={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"},G=typeof Z==="function"?Z:()=>Z||[];return M("ul",{...Q,class:()=>P(`timeline ${_(J)?"timeline-vertical":"timeline-horizontal"} ${_(Y)?"timeline-compact":""}`,X)},[j(G,(q,L)=>{let B=L===0,A=L===G().length-1,D=q.type||"success",C=(R)=>typeof R==="function"?R():R;return M("li",{class:"flex-1"},[!B?M("hr",{class:()=>q.completed?"bg-primary":""}):null,M("div",{class:"timeline-start"},()=>C(q.title)),M("div",{class:"timeline-middle"},()=>[q.icon?V(q.icon):V(K[D]||K.success)]),M("div",{class:"timeline-end timeline-box shadow-sm"},()=>C(q.detail)),!A?M("hr",{class:()=>q.completed?"bg-primary":""}):null])},(q,L)=>q.id||L)])};var LJ={};z(LJ,{Toast:()=>QJ});var QJ=(W,X="alert-success",Z=3500)=>{let J=document.getElementById("sigpro-toast-container");if(!J)J=M("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(J);let Y=M("div",{style:"display: contents"});J.appendChild(Y);let Q,K=()=>{clearTimeout(Q);let L=Y.firstElementChild;if(L&&!L.classList.contains("opacity-0"))L.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{if(q.destroy(),Y.remove(),!J.hasChildNodes())J.remove()},300);else q.destroy(),Y.remove()},q=WM(()=>{let L=V("icon-[lucide--x]"),B=M("div",{class:`alert alert-soft ${X} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[M("span",{},[typeof W==="function"?W():W]),h({class:"btn-xs btn-circle btn-ghost",onclick:K},L)]);return requestAnimationFrame(()=>B.classList.remove("translate-x-10","opacity-0")),B},Y);if(Z>0)Q=setTimeout(K,Z);return K};var BJ={};z(BJ,{Tooltip:()=>qJ});var qJ=(W,X)=>M("div",{...W,class:()=>P("tooltip",W.ui,W.class),"data-tip":W.tip},X);var RJ={...XM,...YM,...qM,...AM,..._M,...TM,...RM,...FM,...UM,...HM,...SM,...NM,...IM,...kM,...QM,...fM,...$M,...bM,...hM,...uM,...pM,...oM,...rM,...sM,...nM,...eM,...JJ,...WJ,...XJ,...YJ,...LJ,...BJ},IJ={...RJ,install:(W=window)=>{Object.entries(RJ).forEach(([X,Z])=>{W[X]=Z}),console.log("\uD83D\uDE80 SigproUI")}};if(typeof window<"u")Object.entries(i).forEach(([W,X])=>{window[W]=X}),window.Utils=o,window.tt=x,window.SigProUI={...i,Utils:o,tt:x},console.log("\uD83C\uDFA8 SigProUI ready");})(); + ${Q()?"border-primary bg-primary/10":"border-base-content/20 bg-base-100 hover:bg-base-200"} + `,ondragover:(R)=>{R.preventDefault(),Q(!0)},ondragleave:()=>Q(!1),ondrop:(R)=>{R.preventDefault(),Q(!1),T(R.dataTransfer.files)}},[M("div",{class:"flex items-center gap-3 w-full"},[V("icon-[lucide--upload]"),M("span",{class:"text-sm opacity-70 truncate grow text-left"},"Arrastra o selecciona archivos..."),M("span",{class:"text-[10px] opacity-40 shrink-0"},`Máx ${J}MB`)]),M("input",{type:"file",multiple:!0,accept:Y,class:"hidden",onchange:(R)=>T(R.target.files)})])]),()=>B()?M("span",{class:"text-[10px] text-error mt-1 px-1 font-medium"},B()):null,N(()=>W().length>0,()=>M("ul",{class:"mt-2 space-y-1"},[O(W,(R,A)=>M("li",{class:"flex items-center justify-between p-1.5 pl-3 text-xs bg-base-200/50 rounded-md border border-base-300"},[M("div",{class:"flex items-center gap-2 truncate"},[M("span",{class:"opacity-50"},"\uD83D\uDCC4"),M("span",{class:"truncate font-medium max-w-[200px]"},R.name),M("span",{class:"text-[9px] opacity-40"},`(${(R.size/1024).toFixed(0)} KB)`)]),M("button",{type:"button",class:"btn btn-ghost btn-xs btn-circle",onclick:(D)=>{D.preventDefault(),D.stopPropagation(),P(A)}},[V("icon-[lucide--x]")])]),(R)=>R.name+R.lastModified)]))])};var fM={};U(fM,{Indicator:()=>wM});var wM=(Z,K)=>{let{value:G,class:J,...Y}=Z;return M("div",{...Y,class:"indicator"},()=>[G?M("span",{class:_("indicator-item badge",J)},()=>typeof G==="function"?G():G):null,K].filter(Boolean))};var $M={};U($M,{Label:()=>yM});var yM=(Z)=>{let{children:K,value:G,floating:J=!1,error:Y,required:L,class:X,...W}=Z;if(J)return M("label",{class:_("floating-label w-full",X),...W},()=>[G?M("span",{},G):null,K,Y?M("span",{class:"text-error text-xs"},q(Y)):null]);return M("label",{class:_("input w-full",X),...W},()=>[G?M("span",{class:"label"},G):null,K,Y?M("span",{class:"text-error text-xs"},q(Y)):null])};var bM={};U(bM,{List:()=>vM});var vM=(Z)=>{let{class:K,items:G,header:J,render:Y,keyFn:L=(Q,B)=>Q.id??B,...X}=Z,W=O(G,(Q,B)=>M("li",{class:"list-row"},[Y(Q,B)]),L);return M("ul",{...X,class:_("list bg-base-100 rounded-box shadow-md",K)},J?[N(J,()=>M("li",{class:"p-4 pb-2 text-xs opacity-60"},[q(J)])),W]:W)};var hM={};U(hM,{Menu:()=>gM});var gM=(Z)=>{let{class:K,items:G,...J}=Z,Y=(L)=>O(()=>L||[],(X)=>M("li",{},[X.children?M("details",{open:X.open},[M("summary",{},[X.icon&&M("span",{class:"mr-2"},X.icon),X.label]),M("ul",{},Y(X.children))]):M("a",{class:()=>q(X.active)?"active":"",onclick:X.onclick},[X.icon&&M("span",{class:"mr-2"},X.icon),X.label])]),(X,W)=>X.label||W);return M("ul",{...J,class:_("menu bg-base-200 rounded-box",K)},Y(G))};var uM={};U(uM,{Modal:()=>mM});var mM=(Z,K)=>{let{class:G,title:J,buttons:Y,open:L,...X}=Z,W=null,Q=()=>{let z=typeof L==="function"?L():L;if(!W)return;if(z){if(!W.open)W.showModal()}else if(W.open)W.close()};w(()=>Q());let B=()=>{if(typeof L==="function")L(!1)};return M("dialog",{...X,ref:(z)=>{if(W=z,z)Q()},class:_("modal",G),onclose:B,oncancel:B},[M("div",{class:"modal-box"},[J?M("h3",{class:"text-lg font-bold mb-4"},()=>typeof J==="function"?J():J):null,M("div",{class:"py-2"},[typeof K==="function"?K():K]),M("div",{class:"modal-action"},[M("form",{method:"dialog",class:"flex gap-2"},[...(Array.isArray(Y)?Y:[Y]).filter(Boolean),u({type:"submit"},k("close")())])])]),M("form",{method:"dialog",class:"modal-backdrop"},[M("button",{},"close")])])};var pM={};U(pM,{Navbar:()=>dM});var dM=(Z,K)=>{let{class:G,...J}=Z;return M("div",{...J,class:_("navbar bg-base-100 shadow-sm px-4",G)},K)};var oM={};U(oM,{Radio:()=>cM});var cM=(Z)=>{let{class:K,label:G,tooltip:J,value:Y,inputValue:L,name:X,...W}=Z,Q=M("input",{...W,type:"radio",name:X,class:_("radio",K),checked:()=>q(Y)===L,onclick:()=>{if(typeof Y==="function")Y(L)}});if(!G&&!J)return Q;let B=M("label",{class:"label cursor-pointer justify-start gap-3"},[Q,G?M("span",{class:"label-text"},G):null]);return J?M("div",{class:"tooltip","data-tip":J},B):B};var rM={};U(rM,{Range:()=>iM});var iM=(Z)=>{let{class:K,label:G,tooltip:J,value:Y,...L}=Z,X=M("input",{...L,type:"range",class:_("range",K),value:Y,disabled:()=>q(Z.disabled)});if(!G&&!J)return X;let W=M("div",{class:"flex flex-col gap-2"},[G?M("span",{class:"label-text"},G):null,X]);return J?M("div",{class:"tooltip","data-tip":J},W):W};var lM={};U(lM,{Rating:()=>aM});var aM=(Z)=>{let{class:K,value:G,count:J=5,mask:Y="mask-star",readonly:L=!1,onchange:X,...W}=Z,Q=`rating-${Math.random().toString(36).slice(2,7)}`;return M("div",{...W,class:()=>_(`rating ${q(L)?"pointer-events-none":""}`,K)},Array.from({length:q(J)},(B,z)=>{let T=z+1;return M("input",{type:"radio",name:Q,class:`mask ${Y}`,checked:()=>Math.round(q(G))===T,onchange:()=>{if(!q(L)){if(typeof X==="function")X(T);else if(typeof G==="function")G(T)}}})}))};var sM={};U(sM,{Select:()=>nM});var nM=(Z)=>{let{class:K,label:G,items:J,value:Y,...L}=Z,X=M("select",{...L,class:_("select select-bordered w-full",K),value:Y},O(()=>q(J)||[],(W)=>M("option",{value:W.value,$selected:()=>String(q(Y))===String(W.value)},W.label),(W)=>W.value));if(!G)return X;return M("label",{class:"fieldset-label flex flex-col gap-1"},[M("span",{},G),X])};var eM={};U(eM,{Stack:()=>tM});var tM=(Z,K)=>{let{class:G,...J}=Z;return M("div",{...J,class:_("stack",G)},K)};var JJ={};U(JJ,{Stat:()=>MJ});var MJ=(Z)=>{let{class:K,icon:G,label:J,value:Y,desc:L,...X}=Z;return M("div",{...X,class:_("stat",K)},[G&&M("div",{class:"stat-figure text-secondary"},G),J&&M("div",{class:"stat-title"},J),M("div",{class:"stat-value"},()=>q(Y)??Y),L&&M("div",{class:"stat-desc"},L)])};var ZJ={};U(ZJ,{Swap:()=>WJ});var WJ=(Z)=>{let{class:K,value:G,on:J,off:Y,...L}=Z;return M("label",{...L,class:_("swap",K)},[M("input",{type:"checkbox",checked:()=>q(G),onclick:(X)=>{if(typeof G==="function")G(X.target.checked)}}),M("div",{class:"swap-on"},J),M("div",{class:"swap-off"},Y)])};var GJ={};U(GJ,{Table:()=>XJ});var XJ=(Z)=>{let{class:K,items:G=[],columns:J=[],keyFn:Y,zebra:L=!1,pinRows:X=!1,empty:W=k("nodata")(),...Q}=Z,B=()=>{let T=q(L)?"table-zebra":"",P=q(X)?"table-pin-rows":"";return _("table",K,T,P)},z=Y||((T,P)=>T.id||P);return M("div",{class:"overflow-x-auto w-full bg-base-100 rounded-box border border-base-300"},[M("table",{...Q,class:B},[M("thead",{},[M("tr",{},J.map((T)=>M("th",{class:T.class||""},T.label)))]),M("tbody",{},[O(G,(T,P)=>{let R=()=>{let A=q(G),D=z(T,P);return A.find((E,d)=>z(E,d)===D)||T};return M("tr",{class:"hover"},J.map((A)=>{let D=()=>{let E=R();if(A.render)return A.render(E,P);return q(E[A.key])};return M("td",{class:A.class||""},[D])}))},z),N(()=>q(G).length===0,()=>M("tr",{},[M("td",{colspan:J.length,class:"text-center p-10 opacity-50"},[q(W)])]))])])])};var YJ={};U(YJ,{Tabs:()=>KJ});var KJ=(Z)=>{let{items:K,class:G,...J}=Z,Y=typeof K==="function"?K:()=>K||[],L=H(0);return $watch(()=>{let X=Y().findIndex((W)=>q(W.active)===!0);if(X!==-1&&X!==L())L(X)}),M("div",{...J,class:"w-full"},[M("div",{role:"tablist",class:_("tabs",G||"tabs-box")},()=>{return Y().map((W,Q)=>{let B=()=>L()===Q,z=M("button",{role:"tab",class:()=>_("tab",B()?"tab-active":""),onclick:(T)=>{if(T.preventDefault(),!q(W.disabled)){if(W.onclick)W.onclick();L(Q)}}});return $watch(()=>{let T=q(W.label);if(T instanceof Node)z.replaceChildren(T);else z.textContent=String(T)}),z})}),M("div",{class:"tab-panels"},()=>{return Y().map((X,W)=>{let Q=()=>L()===W;return M("div",{role:"tabpanel",class:"tab-content bg-base-100 border-base-300 p-6",style:()=>Q()?"display: block":"display: none"},[()=>typeof X.content==="function"?X.content():X.content])})})])};var LJ={};U(LJ,{Timeline:()=>QJ});var QJ=(Z)=>{let{class:K,items:G=[],vertical:J=!0,compact:Y=!1,...L}=Z,X={info:"icon-[lucide--info]",success:"icon-[lucide--check-circle]",warning:"icon-[lucide--alert-triangle]",error:"icon-[lucide--alert-circle]"};return M("ul",{...L,class:()=>_(`timeline ${q(J)?"timeline-vertical":"timeline-horizontal"} ${q(Y)?"timeline-compact":""}`,K)},()=>{let W=(typeof G==="function"?G():G)||[];return W.map((Q,B)=>{let z=B===0,T=B===W.length-1,P=Q.type||"success",R=()=>q(Q.completed),A=()=>B>0&&q(W[B-1].completed),D=(E)=>typeof E==="function"?E():E;return M("li",{class:"flex-1"},[!z?M("hr",{class:()=>A()?"bg-primary":""}):null,M("div",{class:"timeline-start"},[()=>D(Q.title)]),M("div",{class:"timeline-middle"},[()=>Q.icon?V(Q.icon):V(X[P]||X.success)]),M("div",{class:"timeline-end timeline-box shadow-sm"},[()=>D(Q.detail)]),!T?M("hr",{class:()=>R()?"bg-primary":""}):null])})})};var qJ={};U(qJ,{Toast:()=>BJ});var BJ=(Z,K="alert-success",G=3500)=>{let J=document.getElementById("sigpro-toast-container");if(!J)J=M("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(J);let Y=M("div",{style:"display: contents"});J.appendChild(Y);let L,X=()=>{clearTimeout(L);let B=Y.firstElementChild;if(B&&!B.classList.contains("opacity-0"))B.classList.add("translate-x-full","opacity-0"),setTimeout(()=>{if(Q.destroy(),Y.remove(),!J.hasChildNodes())J.remove()},300);else Q.destroy(),Y.remove()},Q=GM(()=>{let B=V("icon-[lucide--x]"),z=M("div",{class:`alert alert-soft ${K} shadow-lg transition-all duration-300 translate-x-10 opacity-0 pointer-events-auto`},[M("span",{},[typeof Z==="function"?Z():Z]),u({class:"btn-xs btn-circle btn-ghost",onclick:X},B)]);return requestAnimationFrame(()=>z.classList.remove("translate-x-10","opacity-0")),z},Y);if(G>0)L=setTimeout(X,G);return X};var _J={};U(_J,{Tooltip:()=>AJ});var AJ=(Z,K)=>M("div",{...Z,class:()=>_("tooltip",Z.ui,Z.class),"data-tip":Z.tip},K);var zJ={...YM,...LM,...AM,...PM,...TM,...zM,...DM,...UM,...VM,...EM,...OM,...IM,...kM,...fM,...BM,...$M,...bM,...hM,...uM,...pM,...oM,...rM,...lM,...sM,...eM,...JJ,...ZJ,...GJ,...YJ,...LJ,...qJ,..._J},IJ={...zJ,install:(Z=window)=>{Object.entries(zJ).forEach(([K,G])=>{Z[K]=G}),console.log("\uD83D\uDE80 SigproUI")}};if(typeof window<"u")Object.entries(l).forEach(([Z,K])=>{window[Z]=K}),window.Utils=a,window.tt=k,window.SigProUI={...l,Utils:a,tt:k},console.log("\uD83C\uDFA8 SigProUI ready");})(); diff --git a/index.js b/index.js index 9eae459..03ed591 100644 --- a/index.js +++ b/index.js @@ -1,5 +1,5 @@ // index.js -import 'sigpro'; +import './src/sigpro.js'; // import './src/css/sigpro.css'; // No importes CSS en JS import * as Components from './src/components/index.js'; // import * as Icons from './src/core/icons.js'; // ELIMINAR diff --git a/package.json b/package.json index a848ea5..cc89db1 100644 --- a/package.json +++ b/package.json @@ -1,12 +1,15 @@ { "name": "sigpro-ui", "version": "1.1.0", - "type": "module", - "license": "MIT", "main": "./index.js", "module": "./index.js", - "unpkg": "./dist/sigpro-ui.min.js", - "jsdelivr": "./dist/sigpro-ui.min.js", + "devDependencies": { + "@iconify/json": "^2.2.458", + "@iconify/tailwind4": "^1.2.3", + "@tailwindcss/cli": "^4.0.0", + "daisyui": "^5.5.19", + "tailwindcss": "^4.2.2" + }, "exports": { ".": { "import": "./index.js", @@ -24,6 +27,8 @@ "README.md", "LICENSE" ], + "jsdelivr": "./dist/sigpro-ui.min.js", + "license": "MIT", "scripts": { "build:cssmin": "./node_modules/.bin/tailwindcss -i ./src/css/sigpro.css -o ./css/sigpro.min.css --content './src/**/*.js' --minify", "build:css": "./node_modules/.bin/tailwindcss -i ./src/css/sigpro.css -o ./css/sigpro.css --content './src/**/*.js'", @@ -34,14 +39,6 @@ "prepublishOnly": "bun run build", "docs": "bun x serve docs" }, - "dependencies": { - "sigpro": "^1.1.18" - }, - "devDependencies": { - "@iconify/json": "^2.2.458", - "@iconify/tailwind4": "^1.2.3", - "@tailwindcss/cli": "^4.0.0", - "daisyui": "^5.5.19", - "tailwindcss": "^4.2.2" - } + "type": "module", + "unpkg": "./dist/sigpro-ui.min.js" } \ No newline at end of file diff --git a/src/components/Accordion.js b/src/components/Accordion.js index b57ace2..5b8a7bc 100644 --- a/src/components/Accordion.js +++ b/src/components/Accordion.js @@ -1,5 +1,5 @@ // components/Accordion.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui, val } from "../core/utils.js"; /** diff --git a/src/components/Alert.js b/src/components/Alert.js index f24833d..25302bc 100644 --- a/src/components/Alert.js +++ b/src/components/Alert.js @@ -1,5 +1,5 @@ // components/Alert.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui, getIcon } from "../core/utils.js"; /** diff --git a/src/components/Autocomplete.js b/src/components/Autocomplete.js index 89f0313..b485c65 100644 --- a/src/components/Autocomplete.js +++ b/src/components/Autocomplete.js @@ -1,5 +1,5 @@ // components/Autocomplete.js -import { $, $html, $for } from "sigpro"; +import { $, $html, $for } from "../sigpro.js"; import { val } from "../core/utils.js"; import { tt } from "../core/i18n.js"; import { Input } from "./Input.js"; diff --git a/src/components/Badge.js b/src/components/Badge.js index b61f910..31c3c3d 100644 --- a/src/components/Badge.js +++ b/src/components/Badge.js @@ -1,5 +1,5 @@ // components/Badge.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/components/Button.js b/src/components/Button.js index 926006d..c5a6dbb 100644 --- a/src/components/Button.js +++ b/src/components/Button.js @@ -1,5 +1,5 @@ // components/Button.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui, val, getIcon } from "../core/utils.js"; /** diff --git a/src/components/Checkbox.js b/src/components/Checkbox.js index d964c88..a8f8340 100644 --- a/src/components/Checkbox.js +++ b/src/components/Checkbox.js @@ -1,5 +1,5 @@ // components/Checkbox.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Colorpicker.js b/src/components/Colorpicker.js index 6f11552..795e2bb 100644 --- a/src/components/Colorpicker.js +++ b/src/components/Colorpicker.js @@ -1,5 +1,5 @@ // components/Colorpicker.js -import { $, $html, $if } from "sigpro"; +import { $, $html, $if } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Datepicker.js b/src/components/Datepicker.js index 02f7bd2..ce00bc9 100644 --- a/src/components/Datepicker.js +++ b/src/components/Datepicker.js @@ -1,5 +1,5 @@ // components/Datepicker.js -import { $, $html, $if } from "sigpro"; +import { $, $html, $if } from "../sigpro.js"; import { val, ui, getIcon } from "../core/utils.js"; import { Input } from "./Input.js"; diff --git a/src/components/Drawer.js b/src/components/Drawer.js index 50d253e..202cc86 100644 --- a/src/components/Drawer.js +++ b/src/components/Drawer.js @@ -1,5 +1,5 @@ // components/Drawer.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/components/Dropdown.js b/src/components/Dropdown.js index 1f4bde2..288f81a 100644 --- a/src/components/Dropdown.js +++ b/src/components/Dropdown.js @@ -1,5 +1,5 @@ // components/Dropdown.js -// import { $html, $for, $watch } from "sigpro"; +// import { $html, $for, $watch } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/components/Fab.js b/src/components/Fab.js index 3d97dc7..b061067 100644 --- a/src/components/Fab.js +++ b/src/components/Fab.js @@ -1,5 +1,5 @@ // components/Fab.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui, getIcon } from "../core/utils.js"; /** diff --git a/src/components/Fieldset.js b/src/components/Fieldset.js index f75ab10..58a20fc 100644 --- a/src/components/Fieldset.js +++ b/src/components/Fieldset.js @@ -1,5 +1,5 @@ // components/Fieldset.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Fileinput.js b/src/components/Fileinput.js index 70cb41e..e3616a7 100644 --- a/src/components/Fileinput.js +++ b/src/components/Fileinput.js @@ -1,5 +1,5 @@ // components/Fileinput.js -import { $, $html, $if, $for } from "sigpro"; +import { $, $html, $if, $for } from "../sigpro.js"; import { ui, getIcon } from "../core/utils.js"; /** diff --git a/src/components/Indicator.js b/src/components/Indicator.js index 3730825..f99a091 100644 --- a/src/components/Indicator.js +++ b/src/components/Indicator.js @@ -1,5 +1,5 @@ // components/Indicator.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/components/Input.js b/src/components/Input.js index c30bf50..3bddf62 100644 --- a/src/components/Input.js +++ b/src/components/Input.js @@ -1,5 +1,5 @@ // components/Input.js -import { $, $html } from "sigpro"; +import { $, $html, $watch } from "../sigpro.js"; import { val, ui, getIcon } from "../core/utils.js"; /** @@ -20,12 +20,14 @@ export const Input = (props) => { oninput, placeholder, disabled, - size, // para poder pasar el tamaño también al botón + size, + validate, ...rest } = props; const isPassword = type === "password"; const visible = $(false); + const errorMsg = $(null); const iconMap = { text: "icon-[lucide--text]", @@ -39,7 +41,6 @@ export const Input = (props) => { }; 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" : ""; @@ -52,25 +53,43 @@ export const Input = (props) => { 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 = $html("input", { + ...rest, + type: () => (isPassword ? (visible() ? "text" : "password") : type), + placeholder: placeholder || " ", + class: inputClasses, + value: value, + oninput: handleInput, + disabled: () => val(disabled), + "aria-invalid": () => hasError() ? "true" : "false", + }); + return $html( "div", { class: "relative w-full" }, () => [ - // Input - $html("input", { - ...rest, - type: () => (isPassword ? (visible() ? "text" : "password") : type), - placeholder: placeholder || " ", - class: ui('input w-full', `${paddingLeft} ${paddingRight} ${className || ''}`.trim()), - value: value, - oninput: (e) => oninput?.(e), - disabled: () => val(disabled), - }), - + inputElement, leftIcon ? $html("div", { class: "absolute left-3 inset-y-0 flex items-center pointer-events-none text-base-content/60", }, leftIcon) : null, - isPassword ? $html("button", { type: "button", class: ui( @@ -83,6 +102,9 @@ export const Input = (props) => { visible(!visible()); } }, () => getPasswordIcon()) : null, + $html("div", { + class: "text-error text-xs mt-1 px-3 absolute -bottom-5 left-0", + }, () => hasError() ? errorMsg() : null), ] ); }; \ No newline at end of file diff --git a/src/components/Label.js b/src/components/Label.js index ac65b85..8904386 100644 --- a/src/components/Label.js +++ b/src/components/Label.js @@ -1,5 +1,5 @@ // components/Label.js -import { $, $html } from "sigpro"; +import { $, $html } from "../sigpro.js"; import { ui, val } from "../core/utils.js"; /** diff --git a/src/components/List.js b/src/components/List.js index 6b77b2b..a06c7a6 100644 --- a/src/components/List.js +++ b/src/components/List.js @@ -1,5 +1,5 @@ // components/List.js -import { $html, $if, $for } from "sigpro"; +import { $html, $if, $for } from "../sigpro.js"; import { ui, val } from "../core/utils.js"; /** @@ -12,7 +12,7 @@ import { ui, val } from "../core/utils.js"; * - flex, items-center, gap-2 */ export const List = (props) => { - const { class: className, items, header, render, keyFn = (item, index) => index, ...rest } = props; + const { class: className, items, header, render, keyFn = (item, index) => item.id ?? index, ...rest } = props; const listItems = $for( items, @@ -20,12 +20,8 @@ export const List = (props) => { keyFn ); - return $html( - "ul", - { - ...rest, - class: ui('list bg-base-100 rounded-box shadow-md', className), - }, - header ? [$if(header, () => $html("li", { class: "p-4 pb-2 text-xs opacity-60" }, [val(header)])), listItems] : listItems - ); + return $html("ul", { + ...rest, + class: ui('list bg-base-100 rounded-box shadow-md', className), + }, header ? [$if(header, () => $html("li", { class: "p-4 pb-2 text-xs opacity-60" }, [val(header)])), listItems] : listItems); }; \ No newline at end of file diff --git a/src/components/Menu.js b/src/components/Menu.js index f9ca00d..a36fdb5 100644 --- a/src/components/Menu.js +++ b/src/components/Menu.js @@ -1,5 +1,5 @@ // components/Menu.js -import { $html, $for } from "sigpro"; +import { $html, $for } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Modal.js b/src/components/Modal.js index e85fb9b..47c1be7 100644 --- a/src/components/Modal.js +++ b/src/components/Modal.js @@ -1,5 +1,5 @@ // components/Modal.js -import { $html, $watch } from "sigpro"; +import { $html, $watch } from "../sigpro.js"; import { ui } from "../core/utils.js"; import { tt } from "../core/i18n.js"; import { Button } from "./Button.js"; diff --git a/src/components/Navbar.js b/src/components/Navbar.js index fdead7e..e1711d5 100644 --- a/src/components/Navbar.js +++ b/src/components/Navbar.js @@ -1,5 +1,5 @@ // components/Navbar.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/components/Radio.js b/src/components/Radio.js index 4ecde0f..10dfa96 100644 --- a/src/components/Radio.js +++ b/src/components/Radio.js @@ -1,5 +1,5 @@ // components/Radio.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Range.js b/src/components/Range.js index 4d1c507..ca31f66 100644 --- a/src/components/Range.js +++ b/src/components/Range.js @@ -1,5 +1,5 @@ // components/Range.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Rating.js b/src/components/Rating.js index 2ea8107..63fc7c9 100644 --- a/src/components/Rating.js +++ b/src/components/Rating.js @@ -1,5 +1,5 @@ // components/Rating.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Select.js b/src/components/Select.js index 287094a..52f5966 100644 --- a/src/components/Select.js +++ b/src/components/Select.js @@ -1,5 +1,5 @@ // components/Select.js -import { $html, $for } from "sigpro"; +import { $html, $for } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Stack.js b/src/components/Stack.js index 85c485a..553bfef 100644 --- a/src/components/Stack.js +++ b/src/components/Stack.js @@ -1,5 +1,5 @@ // components/Stack.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/components/Stat.js b/src/components/Stat.js index 3614ec4..da10e0e 100644 --- a/src/components/Stat.js +++ b/src/components/Stat.js @@ -1,5 +1,5 @@ // components/Stat.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** diff --git a/src/components/Swap.js b/src/components/Swap.js index fc740d9..a26f1c6 100644 --- a/src/components/Swap.js +++ b/src/components/Swap.js @@ -1,5 +1,5 @@ // components/Swap.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui, val } from "../core/utils.js"; /** diff --git a/src/components/Table.js b/src/components/Table.js index c1d2a4c..72f5acd 100644 --- a/src/components/Table.js +++ b/src/components/Table.js @@ -1,5 +1,5 @@ // components/Table.js -import { $html, $for, $if } from "sigpro"; +import { $html, $for, $if } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; import { tt } from "../core/i18n.js"; @@ -22,6 +22,8 @@ export const Table = (props) => { return ui('table', className, zebraClass, pinRowsClass); }; + const getInternalKeyFn = keyFn || ((item, idx) => item.id || idx); + return $html("div", { class: "overflow-x-auto w-full bg-base-100 rounded-box border border-base-300" }, [ $html("table", { ...rest, class: tableClass }, [ $html("thead", {}, [ @@ -31,17 +33,24 @@ export const Table = (props) => { ]), $html("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 $html("tr", { class: "hover" }, columns.map(col => { const cellContent = () => { - if (col.render) return col.render(item, index); - const value = item[col.key]; - return val(value); + const latestItem = it(); + if (col.render) return col.render(latestItem, index); + return val(latestItem[col.key]); }; return $html("td", { class: col.class || "" }, [cellContent]); }) ); - }, keyFn || ((item, idx) => item.id || idx)), + }, getInternalKeyFn), $if(() => val(items).length === 0, () => $html("tr", {}, [ @@ -50,14 +59,7 @@ export const Table = (props) => { ]) ]) ) - ]), - $if(() => columns.some(c => c.footer), () => - $html("tfoot", {}, [ - $html("tr", {}, - columns.map(col => $html("th", {}, col.footer || "")) - ) - ]) - ) + ]) ]) ]); }; \ No newline at end of file diff --git a/src/components/Tabs.js b/src/components/Tabs.js index 7c22888..c613af6 100644 --- a/src/components/Tabs.js +++ b/src/components/Tabs.js @@ -1,5 +1,5 @@ // components/Tabs.js -import { $, $html, $for } from "sigpro"; +import { $, $html, $for } from "../sigpro.js"; import { val, ui } from "../core/utils.js"; /** @@ -13,58 +13,63 @@ import { val, ui } from "../core/utils.js"; export const Tabs = (props) => { const { items, class: className, ...rest } = props; const itemsSignal = typeof items === "function" ? items : () => items || []; - const name = `tabs-${Math.random().toString(36).slice(2, 9)}`; + const activeIndex = $(0); - // Encontrar el índice activo - const getActiveIndex = () => { - const arr = itemsSignal(); - const idx = arr.findIndex(it => val(it.active) === true); - return idx === -1 ? 0 : idx; - }; + $watch(() => { + const idx = itemsSignal().findIndex(it => val(it.active) === true); + if (idx !== -1 && idx !== activeIndex()) activeIndex(idx); + }); - const activeIndex = $(getActiveIndex); - - const updateActiveIndex = () => { - const newIndex = getActiveIndex(); - if (newIndex !== activeIndex()) activeIndex(newIndex); - }; - - $watch(() => updateActiveIndex()); - - return $html("div", { - ...rest, - class: ui('tabs', className || 'tabs-box') - }, [ - $for(itemsSignal, (it, idx) => { - const isChecked = () => activeIndex() === idx; - const getLabelText = () => { - const label = typeof it.label === "function" ? it.label() : it.label; - return typeof label === "string" ? label : `Tab ${idx + 1}`; - }; - - return [ - $html("input", { - type: "radio", - name: name, - class: "tab", - "aria-label": getLabelText(), - checked: isChecked, // ← función reactiva, no string hardcodeado - disabled: () => val(it.disabled), - onchange: (e) => { - if (e.target.checked && !val(it.disabled)) { + return $html("div", { ...rest, class: "w-full" }, [ + // 1. Tab List: Aplanamos los botones para que sean hijos directos + $html("div", { + role: "tablist", + class: ui('tabs', className || 'tabs-box') + }, () => { + const list = itemsSignal(); + return list.map((it, idx) => { + const isSelected = () => activeIndex() === idx; + + const tab = $html("button", { + role: "tab", + class: () => ui("tab", isSelected() ? "tab-active" : ""), + onclick: (e) => { + e.preventDefault(); + if (!val(it.disabled)) { if (it.onclick) it.onclick(); - if (typeof it.active === "function") it.active(true); activeIndex(idx); } } - }), - $html("div", { + }); + + // Mantenemos el watch para el label por si es dinámico + $watch(() => { + const content = val(it.label); + if (content instanceof Node) { + tab.replaceChildren(content); + } else { + tab.textContent = String(content); + } + }); + + return tab; + }); + }), + + // 2. Tab Content: Aquí el display:contents no molesta tanto, + // pero lo aplanamos por consistencia + $html("div", { class: "tab-panels" }, () => { + return itemsSignal().map((it, idx) => { + const isVisible = () => activeIndex() === idx; + + return $html("div", { + role: "tabpanel", class: "tab-content bg-base-100 border-base-300 p-6", - style: () => isChecked() ? "display: block" : "display: none" + style: () => isVisible() ? "display: block" : "display: none" }, [ - typeof it.content === "function" ? it.content() : it.content - ]) - ]; - }, (it, idx) => idx) + () => typeof it.content === "function" ? it.content() : it.content + ]); + }); + }) ]); }; \ No newline at end of file diff --git a/src/components/Timeline.js b/src/components/Timeline.js index d6e77e9..2b761b6 100644 --- a/src/components/Timeline.js +++ b/src/components/Timeline.js @@ -1,5 +1,5 @@ // components/Timeline.js -import { $html, $for } from "sigpro"; +import { $html, $for } from "../sigpro.js"; import { val, ui, getIcon } from "../core/utils.js"; /** @@ -21,38 +21,39 @@ export const Timeline = (props) => { error: "icon-[lucide--alert-circle]", }; - const itemsSource = typeof items === "function" ? items : () => items || []; - return $html( "ul", { ...rest, class: () => ui( - `timeline ${val(vertical) ? "timeline-vertical" : "timeline-horizontal"} ${val(compact) ? "timeline-compact" : ""}`, className), - }, - [ - $for( - itemsSource, - (item, i) => { - const isFirst = i === 0; - const isLast = i === itemsSource().length - 1; - const itemType = item.type || "success"; - const renderSlot = (content) => (typeof content === "function" ? content() : content); - - return $html("li", { class: "flex-1" }, [ - !isFirst ? $html("hr", { class: () => item.completed ? "bg-primary" : "" }) : null, - $html("div", { class: "timeline-start" }, () => renderSlot(item.title)), - $html("div", { class: "timeline-middle" }, () => [ - item.icon - ? getIcon(item.icon) - : getIcon(iconMap[itemType] || iconMap.success) - ]), - $html("div", { class: "timeline-end timeline-box shadow-sm" }, () => renderSlot(item.detail)), - !isLast ? $html("hr", { class: () => item.completed ? "bg-primary" : "" }) : null, - ]); - }, - (item, i) => item.id || i, + `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); + // Nueva lógica: La línea de entrada se pinta si el ANTERIOR estaba completado + const prevCompleted = () => i > 0 && val(list[i - 1].completed); + + const renderSlot = (content) => (typeof content === "function" ? content() : content); + + return $html("li", { class: "flex-1" }, [ + !isFirst ? $html("hr", { class: () => prevCompleted() ? "bg-primary" : "" }) : null, + $html("div", { class: "timeline-start" }, [() => renderSlot(item.title)]), + $html("div", { class: "timeline-middle" }, [ + () => item.icon ? getIcon(item.icon) : getIcon(iconMap[itemType] || iconMap.success) + ]), + $html("div", { class: "timeline-end timeline-box shadow-sm" }, [() => renderSlot(item.detail)]), + !isLast ? $html("hr", { class: () => isCompleted() ? "bg-primary" : "" }) : null, + ]); + }); + } ); }; \ No newline at end of file diff --git a/src/components/Toast.js b/src/components/Toast.js index 729b006..7f9e93f 100644 --- a/src/components/Toast.js +++ b/src/components/Toast.js @@ -1,5 +1,5 @@ // components/Toast.js -import { $html, $mount } from "sigpro"; +import { $html, $mount } from "../sigpro.js"; import { getIcon } from "../core/utils.js"; import { Button } from "./Button.js"; diff --git a/src/components/Tooltip.js b/src/components/Tooltip.js index 2b6c5ff..8820139 100644 --- a/src/components/Tooltip.js +++ b/src/components/Tooltip.js @@ -1,5 +1,5 @@ // components/Tooltip.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; import { ui } from "../core/utils.js"; /** diff --git a/src/core/i18n.js b/src/core/i18n.js index dfe1b3e..6cb31ab 100644 --- a/src/core/i18n.js +++ b/src/core/i18n.js @@ -1,4 +1,4 @@ -import { $ } from "sigpro"; +import { $ } from "../sigpro.js"; export const i18n = { es: { diff --git a/src/core/utils.js b/src/core/utils.js index 1a70964..e1112ca 100644 --- a/src/core/utils.js +++ b/src/core/utils.js @@ -1,5 +1,5 @@ // core/utils.js -import { $html } from "sigpro"; +import { $html } from "../sigpro.js"; export const val = t => typeof t === "function" ? t() : t; diff --git a/src/sigpro.js b/src/sigpro.js new file mode 100644 index 0000000..ab75b98 --- /dev/null +++ b/src/sigpro.js @@ -0,0 +1,482 @@ +/** + * SigPro Core + */ +let activeEffect = null; +let currentOwner = null; +const effectQueue = new Set(); +let isFlushing = false; +const MOUNTED_NODES = new WeakMap(); + +/** flush */ +const flush = () => { + if (isFlushing) return; + isFlushing = true; + while (effectQueue.size > 0) { + const sorted = Array.from(effectQueue).sort((a, b) => (a.depth || 0) - (b.depth || 0)); + effectQueue.clear(); + for (const eff of sorted) if (!eff._deleted) eff(); + } + isFlushing = false; +}; + +/** track */ +const track = (subs) => { + if (activeEffect && !activeEffect._deleted) { + subs.add(activeEffect); + activeEffect._deps.add(subs); + } +}; + +/** trigger */ +const trigger = (subs) => { + for (const eff of subs) { + if (eff === activeEffect || eff._deleted) continue; + if (eff._isComputed) { + eff.markDirty(); + if (eff._subs) trigger(eff._subs); + } else { + effectQueue.add(eff); + } + } + if (!isFlushing) queueMicrotask(flush); +}; + +/** sweep */ +const sweep = (node) => { + if (node._cleanups) { + node._cleanups.forEach((f) => f()); + node._cleanups.clear(); + } + node.childNodes?.forEach(sweep); +}; + +/** _view */ +const _view = (fn) => { + const cleanups = new Set(); + const prev = currentOwner; + const container = document.createElement("div"); + container.style.display = "contents"; + currentOwner = { cleanups }; + try { + const res = fn({ onCleanup: (f) => cleanups.add(f) }); + const process = (n) => { + if (!n) return; + if (n._isRuntime) { + cleanups.add(n.destroy); + container.appendChild(n.container); + } else if (Array.isArray(n)) n.forEach(process); + else container.appendChild(n instanceof Node ? n : document.createTextNode(String(n))); + }; + process(res); + } finally { currentOwner = prev; } + return { + _isRuntime: true, + container, + destroy: () => { + cleanups.forEach((f) => f()); + sweep(container); + container.remove(); + }, + }; +}; + +/** + * Creates a reactive Signal or a Computed Value. + * @param {any|Function} initial - Initial value or a getter function for computed state. + * @param {string} [key] - Optional. Key for automatic persistence in localStorage. + * @returns {Function} Signal getter/setter. Use `sig()` to read and `sig(val)` to write. + * @example + * const count = $(0); // Simple signal + * const double = $(() => count() * 2); // Computed signal + * const name = $("John", "user-name"); // Persisted signal + */ + +const $ = (initial, key = null) => { + if (typeof initial === "function") { + const subs = new Set(); + let cached, dirty = true; + const effect = () => { + if (effect._deleted) return; + effect._deps.forEach((s) => s.delete(effect)); + effect._deps.clear(); + const prev = activeEffect; + activeEffect = effect; + try { + const val = initial(); + if (!Object.is(cached, val) || dirty) { + cached = val; + dirty = false; + trigger(subs); + } + } finally { activeEffect = prev; } + }; + effect._deps = new Set(); + effect._isComputed = true; + effect._subs = subs; + effect._deleted = false; + effect.markDirty = () => (dirty = true); + effect.stop = () => { + effect._deleted = true; + effect._deps.forEach((s) => s.delete(effect)); + subs.clear(); + }; + if (currentOwner) currentOwner.cleanups.add(effect.stop); + return () => { if (dirty) effect(); track(subs); return cached; }; + } + + let value = initial; + if (key) { + try { + const saved = localStorage.getItem(key); + if (saved !== null) value = JSON.parse(saved); + } catch (e) { + console.warn("SigPro: LocalStorage locked", e); + } + } + const subs = new Set(); + return (...args) => { + if (args.length) { + const next = typeof args[0] === "function" ? args[0](value) : args[0]; + if (!Object.is(value, next)) { + value = next; + if (key) localStorage.setItem(key, JSON.stringify(value)); + trigger(subs); + } + } + track(subs); + return value; + }; +}; + +/** +* Watches for signal changes and executes a side effect. +* Handles automatic cleanup of previous effects. +* @param {Function|Array} target - Function to execute or Array of signals for explicit dependency tracking. +* @param {Function} [fn] - If the first parameter is an Array, this is the callback function. +* @returns {Function} Function to manually stop the watcher. +* @example +* $watch(() => console.log("Count is:", count())); +* $watch([count], () => console.log("Only runs when count changes")); +*/ + +const $watch = (target, fn) => { + const isExplicit = Array.isArray(target); + const callback = isExplicit ? fn : target; + const depsInput = isExplicit ? target : null; + + if (typeof callback !== "function") return () => { }; + + const owner = currentOwner; + const runner = () => { + if (runner._deleted) return; + runner._deps.forEach((s) => s.delete(runner)); + runner._deps.clear(); + runner._cleanups.forEach((c) => c()); + runner._cleanups.clear(); + + const prevEffect = activeEffect; + const prevOwner = currentOwner; + activeEffect = runner; + currentOwner = { cleanups: runner._cleanups }; + runner.depth = prevEffect ? prevEffect.depth + 1 : 0; + + try { + if (isExplicit) { + activeEffect = null; + callback(); + activeEffect = runner; + depsInput.forEach(d => typeof d === "function" && d()); + } else { + callback(); + } + } finally { + activeEffect = prevEffect; + currentOwner = prevOwner; + } + }; + + runner._deps = new Set(); + runner._cleanups = new Set(); + runner._deleted = false; + runner.stop = () => { + if (runner._deleted) return; + runner._deleted = true; + effectQueue.delete(runner); + runner._deps.forEach((s) => s.delete(runner)); + runner._cleanups.forEach((c) => c()); + if (owner) owner.cleanups.delete(runner.stop); + }; + + if (owner) owner.cleanups.add(runner.stop); + runner(); + return runner.stop; +}; + +/** +* DOM element rendering engine with built-in reactivity. +* @param {string} tag - HTML tag name (e.g., 'div', 'span'). +* @param {Object} [props] - Attributes, events (onEvent), or two-way bindings (value, checked). +* @param {Array|any} [content] - Children: text, other nodes, or reactive signals. +* @returns {HTMLElement} The configured reactive DOM element. +*/ +const $html = (tag, props = {}, content = []) => { + if (props instanceof Node || Array.isArray(props) || typeof props !== "object") { + content = props; props = {}; + } + const el = document.createElement(tag), + _sanitize = (key, val) => (key === 'src' || key === 'href') && String(val).toLowerCase().includes('javascript:') ? '#' : val; + el._cleanups = new Set(); + + const boolAttrs = ["disabled", "checked", "required", "readonly", "selected", "multiple", "autofocus"]; + + for (let [key, val] of Object.entries(props)) { + if (key === "ref") { (typeof val === "function" ? val(el) : (val.current = el)); continue; } + const isSignal = typeof val === "function", + isInput = ["INPUT", "TEXTAREA", "SELECT"].includes(el.tagName), + isBindAttr = (key === "value" || key === "checked"); + + if (isInput && isBindAttr && isSignal) { + el._cleanups.add($watch(() => { const currentVal = val(); if (el[key] !== currentVal) el[key] = currentVal; })); + const eventName = key === "checked" ? "change" : "input", handler = (event) => val(event.target[key]); + el.addEventListener(eventName, handler); + el._cleanups.add(() => el.removeEventListener(eventName, handler)); + } else if (key.startsWith("on")) { + const eventName = key.slice(2).toLowerCase().split(".")[0], handler = (event) => val(event); + el.addEventListener(eventName, handler); + el._cleanups.add(() => el.removeEventListener(eventName, handler)); + } else if (isSignal) { + el._cleanups.add($watch(() => { + const currentVal = _sanitize(key, val()); + if (key === "class") { + el.className = currentVal || ""; + } else if (boolAttrs.includes(key)) { + if (currentVal) { + el.setAttribute(key, ""); + el[key] = true; + } else { + el.removeAttribute(key); + el[key] = false; + } + } else { + currentVal == null ? el.removeAttribute(key) : el.setAttribute(key, currentVal); + } + })); + } else { + if (boolAttrs.includes(key)) { + if (val) { + el.setAttribute(key, ""); + el[key] = true; + } else { + el.removeAttribute(key); + el[key] = false; + } + } else { + el.setAttribute(key, _sanitize(key, val)); + } + } + } + + const append = (child) => { + if (Array.isArray(child)) return child.forEach(append); + if (child instanceof Node) { + el.appendChild(child); + } else if (typeof child === "function") { + const marker = document.createTextNode(""); + el.appendChild(marker); + let nodes = []; + el._cleanups.add($watch(() => { + const res = child(), next = (Array.isArray(res) ? res : [res]).map((i) => + i?._isRuntime ? i.container : i instanceof Node ? i : document.createTextNode(i ?? "") + ); + nodes.forEach((n) => { sweep?.(n); n.remove(); }); + next.forEach((n) => marker.parentNode?.insertBefore(n, marker)); + nodes = next; + })); + } else el.appendChild(document.createTextNode(child ?? "")); + }; + append(content); + return el; +}; + +/** +* Conditional rendering component. +* @param {Function|boolean} condition - Reactive signal or boolean value. +* @param {Function|HTMLElement} thenVal - Content to show if true. +* @param {Function|HTMLElement} [otherwiseVal] - Content to show if false (optional). +* @returns {HTMLElement} A reactive container (display: contents). +*/ + +const $if = (condition, thenVal, otherwiseVal = null) => { + const marker = document.createTextNode(""); + const container = $html("div", { style: "display:contents" }, [marker]); + let current = null, last = null; + $watch(() => { + const state = !!(typeof condition === "function" ? condition() : condition); + if (state !== last) { + last = state; + if (current) current.destroy(); + const branch = state ? thenVal : otherwiseVal; + if (branch) { + current = _view(() => typeof branch === "function" ? branch() : branch); + container.insertBefore(current.container, marker); + } + } + }); + return container; +}; + +$if.not = (condition, thenVal, otherwiseVal) => $if(() => !(typeof condition === "function" ? condition() : condition), thenVal, otherwiseVal); + +/** +* Optimized reactive loop with key-based reconciliation. +* @param {Function|Array} source - Signal containing an Array of data. +* @param {Function} render - Function receiving (item, index) and returning a node. +* @param {Function} keyFn - Function to extract a unique key from the item. +* @returns {HTMLElement} A reactive container (display: contents). +*/ +const $for = (source, render, keyFn, tag = "div", props = { style: "display:contents" }) => { + const marker = document.createTextNode(""); + const container = $html(tag, props, [marker]); + let cache = new Map(); + + $watch(() => { + const items = (typeof source === "function" ? source() : source) || []; + const newCache = new Map(); + const newOrder = []; + + for (let i = 0; i < items.length; i++) { + const item = items[i]; + const key = keyFn ? keyFn(item, i) : i; + + let run = cache.get(key); + if (!run) { + run = _view(() => render(item, i)); + } else { + cache.delete(key); + } + + newCache.set(key, run); + newOrder.push(key); + } + + cache.forEach(run => { + run.destroy(); + run.container.remove(); + }); + + let anchor = marker; + for (let i = newOrder.length - 1; i >= 0; i--) { + const run = newCache.get(newOrder[i]); + if (run.container.nextSibling !== anchor) { + container.insertBefore(run.container, anchor); + } + anchor = run.container; + } + + cache = newCache; + }); + + return container; +}; + +/** +* Hash-based (#) routing system. +* @param {Array<{path: string, component: Function}>} routes - Route definitions. +* @returns {HTMLElement} The router outlet container. +*/ +const $router = (routes) => { + const sPath = $(window.location.hash.replace(/^#/, "") || "/"); + window.addEventListener("hashchange", () => sPath(window.location.hash.replace(/^#/, "") || "/")); + const outlet = $html("div", { class: "router-outlet" }); + let current = null; + + $watch([sPath], async () => { + const path = sPath(); + const route = routes.find(r => { + const rp = r.path.split("/").filter(Boolean), pp = path.split("/").filter(Boolean); + return rp.length === pp.length && rp.every((p, i) => p.startsWith(":") || p === pp[i]); + }) || routes.find(r => r.path === "*"); + + if (route) { + let comp = route.component; + if (typeof comp === "function" && comp.toString().includes('import')) { + comp = (await comp()).default || (await comp()); + } + + const params = {}; + route.path.split("/").filter(Boolean).forEach((p, i) => { + if (p.startsWith(":")) params[p.slice(1)] = path.split("/").filter(Boolean)[i]; + }); + + if (current) current.destroy(); + if ($router.params) $router.params(params); + + current = _view(() => { + try { + return typeof comp === "function" ? comp(params) : comp; + } catch (e) { + return $html("div", { class: "p-4 text-error" }, "Error loading view"); + } + }); + outlet.appendChild(current.container); + } + }); + return outlet; +}; + +$router.params = $({}); +$router.to = (path) => (window.location.hash = path.replace(/^#?\/?/, "#/")); +$router.back = () => window.history.back(); +$router.path = () => window.location.hash.replace(/^#/, "") || "/"; + +/** + * Mounts a component or node into a DOM target element. + * It automatically handles the cleanup of any previously mounted SigPro instances + * in that target to prevent memory leaks and duplicate renders. + * * @param {Function|HTMLElement} component - The component function to render or a pre-built DOM node. + * @param {string|HTMLElement} target - A CSS selector string or a direct DOM element to mount into. + * @returns {Object|undefined} The view instance containing the `container` and `destroy` method, or undefined if target is not found. + * * @example + * // Mount using a component function + * $mount(() => Div({ class: "app" }, "Hello World"), "#root"); + * * // Mount using a direct element + * const myApp = Div("Hello"); + * $mount(myApp, document.getElementById("app")); + */ + +const $mount = (component, target) => { + const el = typeof target === "string" ? document.querySelector(target) : target; + if (!el) return; + if (MOUNTED_NODES.has(el)) MOUNTED_NODES.get(el).destroy(); + const instance = _view(typeof component === "function" ? component : () => component); + el.replaceChildren(instance.container); + MOUNTED_NODES.set(el, instance); + return instance; +}; + +/** GLOBAL CORE REGISTRY */ +const SigProCore = { $, $watch, $html, $if, $for, $router, $mount }; + +if (typeof window !== "undefined") { + const install = (registry) => { + Object.keys(registry).forEach(key => { + window[key] = registry[key]; + }); + + const tags = `div span p h1 h2 h3 h4 h5 h6 br hr section article aside nav main header footer address ul ol li dl dt dd a em strong small i b u mark time sub sup pre code blockquote details summary dialog form label input textarea select button option fieldset legend table thead tbody tfoot tr th td caption img video audio canvas svg iframe picture source progress meter`.split(/\s+/); + tags.forEach((tagName) => { + const helperName = tagName.charAt(0).toUpperCase() + tagName.slice(1); + if (!(helperName in window)) { + window[helperName] = (props, content) => $html(tagName, props, content); + } + }); + + window.SigPro = Object.freeze(registry); + }; + + install(SigProCore); +} + +export { $, $watch, $html, $if, $for, $router, $mount }; + +export default SigProCore; \ No newline at end of file