Update TS
All checks were successful
Deploy Docs to Synology / deploy (push) Successful in 3s

This commit is contained in:
2026-04-29 23:23:08 +02:00
parent d2bf6aabfc
commit 7d2ad67513
17 changed files with 1126 additions and 1162 deletions

3
dist/sigpro-ui.css vendored
View File

@@ -3396,9 +3396,6 @@
.-mr-2 { .-mr-2 {
margin-right: calc(var(--spacing) * -2); margin-right: calc(var(--spacing) * -2);
} }
.mr-1 {
margin-right: calc(var(--spacing) * 1);
}
.fieldset-legend { .fieldset-legend {
@layer daisyui.l1.l2.l3 { @layer daisyui.l1.l2.l3 {
margin-bottom: calc(0.25rem * -1); margin-bottom: calc(0.25rem * -1);

349
dist/sigpro-ui.esm.js vendored
View File

@@ -16,6 +16,10 @@ var __export = (target, all) => {
// sigpro-ui.js // sigpro-ui.js
var exports_sigpro_ui = {}; var exports_sigpro_ui = {};
__export(exports_sigpro_ui, { __export(exports_sigpro_ui, {
tt: () => tt,
i18n: () => i18n,
hide: () => hide,
currentLocale: () => currentLocale,
Tooltip: () => Tooltip, Tooltip: () => Tooltip,
Toggle: () => Toggle, Toggle: () => Toggle,
Toast: () => Toast, Toast: () => Toast,
@@ -46,6 +50,7 @@ __export(exports_sigpro_ui, {
Navbar: () => Navbar, Navbar: () => Navbar,
Modal: () => Modal, Modal: () => Modal,
Menu: () => Menu, Menu: () => Menu,
Locale: () => Locale,
Loading: () => Loading, Loading: () => Loading,
ListRows: () => ListRows, ListRows: () => ListRows,
List: () => List, List: () => List,
@@ -56,6 +61,7 @@ __export(exports_sigpro_ui, {
Fileinput: () => Fileinput, Fileinput: () => Fileinput,
Fieldset: () => Fieldset, Fieldset: () => Fieldset,
Fab: () => Fab, Fab: () => Fab,
Editor: () => Editor,
DropdownContent: () => DropdownContent, DropdownContent: () => DropdownContent,
DropdownButton: () => DropdownButton, DropdownButton: () => DropdownButton,
Dropdown: () => Dropdown, Dropdown: () => Dropdown,
@@ -92,23 +98,23 @@ __export(exports_sigpro_ui, {
}); });
// node_modules/sigpro/dist/sigpro.esm.min.js // node_modules/sigpro/dist/sigpro.esm.min.js
var w = (e) => typeof e === "function"; var _ = (e) => typeof e === "function";
var B = (e) => e && typeof e === "object"; var O = (e) => e && typeof e === "object";
var g = Array.isArray; var b = Array.isArray;
var E = typeof document < "u" ? document : null; var E = typeof document < "u" ? document : null;
var V = (e) => e?._isRuntime ? e.container : e instanceof Node ? e : E.createTextNode(e == null ? "" : String(e)); var V = (e) => e?._isRuntime ? e.container : e instanceof Node ? e : E.createTextNode(e == null ? "" : String(e));
var d = null; var d = null;
var _ = null; var m = null;
var N = false; var v = false;
var R = 0; var R = 0;
var O = new Set; var T = new Set;
var I = new WeakMap; var I = new WeakMap;
var j = Symbol("iter"); var k = Symbol("iter");
var k = new WeakMap; var L = new WeakMap;
var W = "http://www.w3.org/2000/svg"; var W = "http://www.w3.org/2000/svg";
var M = "http://www.w3.org/1999/xlink"; var M = "http://www.w3.org/1999/xlink";
var q = new Set("svg,path,circle,rect,line,polyline,polygon,g,defs,text,textPath,tspan,use,symbol,image,marker,ellipse".split(",")); var q = new Set("svg,path,circle,rect,line,polyline,polygon,g,defs,text,textPath,tspan,use,symbol,image,marker,ellipse".split(","));
var b = (e) => { var g = (e) => {
if (!e || e._disposed) if (!e || e._disposed)
return; return;
e._disposed = true; e._disposed = true;
@@ -123,9 +129,9 @@ var b = (e) => {
n._deps.forEach((r) => r.delete(n)), n._deps.clear(); n._deps.forEach((r) => r.delete(n)), n._deps.clear();
} }
}; };
var v = (e) => { var S = (e) => {
if (_) if (m)
(_._cleanups ||= new Set).add(e); (m._cleanups ||= new Set).add(e);
}; };
var K = (e) => { var K = (e) => {
let s = d; let s = d;
@@ -144,41 +150,41 @@ var x = (e, s = false) => {
n._deps.forEach((i) => i.delete(n)); n._deps.forEach((i) => i.delete(n));
if (n._cleanups) if (n._cleanups)
n._cleanups.forEach((i) => i()), n._cleanups.clear(); n._cleanups.forEach((i) => i()), n._cleanups.clear();
let r = d, o = _; let r = d, o = m;
d = _ = n; d = m = n;
try { try {
return n._result = e(); return n._result = e();
} catch (i) { } catch (i) {
console.error("[SigPro]", i); console.error("[SigPro]", i);
} finally { } finally {
d = r, _ = o; d = r, m = o;
} }
}; };
if (n._deps = n._cleanups = n._children = null, n._disposed = false, n._isComputed = s, n._depth = d ? d._depth + 1 : 0, n._mounts = [], n._parent = _, _) if (n._deps = n._cleanups = n._children = null, n._disposed = false, n._isComputed = s, n._depth = d ? d._depth + 1 : 0, n._mounts = [], n._parent = m, m)
(_._children ||= new Set).add(n); (m._children ||= new Set).add(n);
return n; return n;
}; };
var $ = () => { var $ = () => {
if (N) if (v)
return; return;
N = true; v = true;
let e = Array.from(O).sort((s, n) => s._depth - n._depth); let e = Array.from(T).sort((s, n) => s._depth - n._depth);
O.clear(); T.clear();
for (let s of e) for (let s of e)
if (!s._disposed) if (!s._disposed)
s(); s();
N = false; v = false;
}; };
var z = (e) => { var z = (e) => {
R++; R++;
try { try {
return e(); return e();
} finally { } finally {
if (R--, R === 0 && O.size > 0 && !N) if (R--, R === 0 && T.size > 0 && !v)
$(); $();
} }
}; };
var m = (e, s = false) => { var w = (e, s = false) => {
if (!s && d && !d._disposed) if (!s && d && !d._disposed)
e.add(d), (d._deps ||= new Set).add(e); e.add(d), (d._deps ||= new Set).add(e);
else if (s && e.size > 0) { else if (s && e.size > 0) {
@@ -188,17 +194,17 @@ var m = (e, s = false) => {
continue; continue;
if (r._isComputed) { if (r._isComputed) {
if (r._dirty = true, r._subs) if (r._dirty = true, r._subs)
m(r._subs, true); w(r._subs, true);
} else } else
O.add(r), n = true; T.add(r), n = true;
} }
if (n && !N && R === 0) if (n && !v && R === 0)
queueMicrotask($); queueMicrotask($);
} }
}; };
var P = (e, s = null) => { var P = (e, s = null) => {
let n = new Set; let n = new Set;
if (w(e)) { if (_(e)) {
let r, o = () => { let r, o = () => {
if (o._dirty) { if (o._dirty) {
let i = d; let i = d;
@@ -206,13 +212,13 @@ var P = (e, s = null) => {
try { try {
let t = e(); let t = e();
if (!Object.is(r, t)) if (!Object.is(r, t))
r = t, m(n, true); r = t, w(n, true);
} finally { } finally {
d = i; d = i;
} }
o._dirty = false; o._dirty = false;
} }
return m(n), r; return w(n), r;
}; };
return o._isComputed = true, o._subs = n, o._dirty = true, o._deps = null, o._disposed = false, o; return o._isComputed = true, o._subs = n, o._dirty = true, o._deps = null, o._disposed = false, o;
} }
@@ -222,18 +228,18 @@ var P = (e, s = null) => {
} catch (r) {} } catch (r) {}
return (...r) => { return (...r) => {
if (r.length) { if (r.length) {
let o = w(r[0]) ? r[0](e) : r[0]; let o = _(r[0]) ? r[0](e) : r[0];
if (!Object.is(e, o)) { if (!Object.is(e, o)) {
if (e = o, s) if (e = o, s)
localStorage.setItem(s, JSON.stringify(e)); localStorage.setItem(s, JSON.stringify(e));
m(n, true); w(n, true);
} }
} }
return m(n), e; return w(n), e;
}; };
}; };
var D = (e) => { var D = (e) => {
if (!B(e)) if (!O(e))
return e; return e;
let s = I.get(e); let s = I.get(e);
if (s) if (s)
@@ -245,35 +251,35 @@ var D = (e) => {
return t; return t;
}, o = new Proxy(e, { get(i, t, c) { }, o = new Proxy(e, { get(i, t, c) {
if (typeof t !== "symbol") if (typeof t !== "symbol")
m(r(t)); w(r(t));
return D(Reflect.get(i, t, c)); return D(Reflect.get(i, t, c));
}, set(i, t, c, l) { }, set(i, t, c, l) {
let a = Reflect.has(i, t), f = Reflect.get(i, t, l), u = Reflect.set(i, t, c, l); let a = Reflect.has(i, t), f = Reflect.get(i, t, l), u = Reflect.set(i, t, c, l);
if (u && !Object.is(f, c)) { if (u && !Object.is(f, c)) {
if (m(r(t), true), !a) if (w(r(t), true), !a)
m(r(j), true); w(r(k), true);
} }
return u; return u;
}, deleteProperty(i, t) { }, deleteProperty(i, t) {
let c = Reflect.deleteProperty(i, t); let c = Reflect.deleteProperty(i, t);
if (c) if (c)
m(r(t), true), m(r(j), true); w(r(t), true), w(r(k), true);
return c; return c;
}, ownKeys(i) { }, ownKeys(i) {
return m(r(j)), Reflect.ownKeys(i); return w(r(k)), Reflect.ownKeys(i);
} }); } });
return I.set(e, o), o; return I.set(e, o), o;
}; };
var T = (e, s) => { var C = (e, s) => {
if (s === undefined) { if (s === undefined) {
let r = x(e); let r = x(e);
return r(), () => b(r); return r(), () => g(r);
} }
let n = x(() => { let n = x(() => {
let r = Array.isArray(e) ? e.map((o) => o()) : e(); let r = Array.isArray(e) ? e.map((o) => o()) : e();
K(() => s(r)); K(() => s(r));
}); });
return n(), () => b(n); return n(), () => g(n);
}; };
var U = (e) => { var U = (e) => {
if (!e) if (!e)
@@ -281,14 +287,14 @@ var U = (e) => {
if (e._cleanups) if (e._cleanups)
e._cleanups.forEach((s) => s()), e._cleanups.clear(); e._cleanups.forEach((s) => s()), e._cleanups.clear();
if (e._ownerEffect) if (e._ownerEffect)
b(e._ownerEffect); g(e._ownerEffect);
if (e.childNodes) if (e.childNodes)
e.childNodes.forEach((s) => U(s)); e.childNodes.forEach((s) => U(s));
}; };
var J = /^\s*(javascript|data|vbscript):/i; var J = /^\s*(javascript|data|vbscript):/i;
var Q = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]); var Q = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
var X = (e) => Q.has(e) || e.startsWith("on"); var X = (e) => Q.has(e) || e.startsWith("on");
var L = (e, s) => { var B = (e, s) => {
if (s == null || s === false) if (s == null || s === false)
return null; return null;
if (X(e)) { if (X(e)) {
@@ -299,9 +305,9 @@ var L = (e, s) => {
return s; return s;
}; };
var A = (e, s = {}, n = []) => { var A = (e, s = {}, n = []) => {
if (s instanceof Node || g(s) || !B(s)) if (s instanceof Node || b(s) || !O(s))
n = s, s = {}; n = s, s = {};
if (w(e)) { if (_(e)) {
let t = x(() => { let t = x(() => {
let f = e(s, { children: n, emit: (u, ...h) => s[`on${u[0].toUpperCase()}${u.slice(1)}`]?.(...h) }); let f = e(s, { children: n, emit: (u, ...h) => s[`on${u[0].toUpperCase()}${u.slice(1)}`]?.(...h) });
return t._result = f, f; return t._result = f, f;
@@ -310,22 +316,22 @@ var A = (e, s = {}, n = []) => {
let c = t._result; let c = t._result;
if (c == null) if (c == null)
return null; return null;
let l = c instanceof Node || g(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => { let l = c instanceof Node || b(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => {
if (B(f) && !f._isRuntime) if (O(f) && !f._isRuntime)
f._mounts = t._mounts || [], f._cleanups = t._cleanups || new Set, f._ownerEffect = t; f._mounts = t._mounts || [], f._cleanups = t._cleanups || new Set, f._ownerEffect = t;
}; };
return g(l) ? l.forEach(a) : a(l), l; return b(l) ? l.forEach(a) : a(l), l;
} }
let r = q.has(e), o = r ? E.createElementNS(W, e) : E.createElement(e); let r = q.has(e), o = r ? E.createElementNS(W, e) : E.createElement(e);
o._cleanups = new Set; o._cleanups = new Set;
for (let t of Object.keys(s)) { for (let t of Object.keys(s)) {
let c = s[t]; let c = s[t];
if (t === "ref") { if (t === "ref") {
w(c) ? c(o) : c.current = o; _(c) ? c(o) : c.current = o;
continue; continue;
} }
if (r && t.startsWith("xlink:")) { if (r && t.startsWith("xlink:")) {
let l = L(t.slice(6), c); let l = B(t.slice(6), c);
l == null ? o.removeAttributeNS(M, t.slice(6)) : o.setAttributeNS(M, t.slice(6), l); l == null ? o.removeAttributeNS(M, t.slice(6)) : o.setAttributeNS(M, t.slice(6), l);
continue; continue;
} }
@@ -333,10 +339,10 @@ var A = (e, s = {}, n = []) => {
let l = t.slice(2).toLowerCase(); let l = t.slice(2).toLowerCase();
o.addEventListener(l, c); o.addEventListener(l, c);
let a = () => o.removeEventListener(l, c); let a = () => o.removeEventListener(l, c);
o._cleanups.add(a), v(a); o._cleanups.add(a), S(a);
} else if (w(c)) { } else if (_(c)) {
let l = x(() => { let l = x(() => {
let a = L(t, c()); let a = B(t, c());
if (t === "class") if (t === "class")
o.className = a || ""; o.className = a || "";
else if (a == null) else if (a == null)
@@ -348,12 +354,12 @@ var A = (e, s = {}, n = []) => {
else else
o.setAttribute(t, a === true ? "" : a); o.setAttribute(t, a === true ? "" : a);
}); });
if (l(), o._cleanups.add(() => b(l)), v(() => b(l)), /^(INPUT|TEXTAREA|SELECT)$/.test(o.tagName) && (t === "value" || t === "checked")) { if (l(), o._cleanups.add(() => g(l)), S(() => g(l)), /^(INPUT|TEXTAREA|SELECT)$/.test(o.tagName) && (t === "value" || t === "checked")) {
let a = t === "checked" ? "change" : "input"; let a = t === "checked" ? "change" : "input";
o.addEventListener(a, (f) => c(f.target[t])); o.addEventListener(a, (f) => c(f.target[t]));
} }
} else { } else {
let l = L(t, c); let l = B(t, c);
if (l != null) if (l != null)
if (t === "style" && typeof l === "string") if (t === "style" && typeof l === "string")
o.setAttribute("style", l); o.setAttribute("style", l);
@@ -364,13 +370,13 @@ var A = (e, s = {}, n = []) => {
} }
} }
let i = (t) => { let i = (t) => {
if (g(t)) if (b(t))
return t.forEach(i); return t.forEach(i);
if (w(t)) { if (_(t)) {
let c = E.createTextNode(""); let c = E.createTextNode("");
o.appendChild(c); o.appendChild(c);
let l = [], a = x(() => { let l = [], a = x(() => {
let f = t(), u = (g(f) ? f : [f]).map(V); let f = t(), u = (b(f) ? f : [f]).map(V);
l.forEach((p) => { l.forEach((p) => {
if (p._isRuntime) if (p._isRuntime)
p.destroy(); p.destroy();
@@ -390,7 +396,7 @@ var A = (e, s = {}, n = []) => {
} }
l = u; l = u;
}); });
a(), o._cleanups.add(() => b(a)), v(() => b(a)); a(), o._cleanups.add(() => g(a)), S(() => g(a));
} else { } else {
let c = V(t); let c = V(t);
if (o.appendChild(c), c._mounts) if (o.appendChild(c), c._mounts)
@@ -399,15 +405,15 @@ var A = (e, s = {}, n = []) => {
}; };
return i(n), o; return i(n), o;
}; };
var C = (e) => { var j = (e) => {
let s = new Set, n = _, r = d, o = E.createElement("div"); let s = new Set, n = m, r = d, o = E.createElement("div");
o.style.display = "contents", o.setAttribute("role", "presentation"), _ = { _cleanups: s }, d = null; o.style.display = "contents", o.setAttribute("role", "presentation"), m = { _cleanups: s }, d = null;
let i = (t) => { let i = (t) => {
if (!t) if (!t)
return; return;
if (t._isRuntime) if (t._isRuntime)
s.add(t.destroy), o.appendChild(t.container); s.add(t.destroy), o.appendChild(t.container);
else if (g(t)) else if (b(t))
t.forEach(i); t.forEach(i);
else else
o.appendChild(t instanceof Node ? t : E.createTextNode(String(t == null ? "" : t))); o.appendChild(t instanceof Node ? t : E.createTextNode(String(t == null ? "" : t)));
@@ -415,7 +421,7 @@ var C = (e) => {
try { try {
i(e({ onCleanup: (t) => s.add(t) })); i(e({ onCleanup: (t) => s.add(t) }));
} finally { } finally {
_ = n, d = r; m = n, d = r;
} }
return { _isRuntime: true, container: o, destroy: () => { return { _isRuntime: true, container: o, destroy: () => {
s.forEach((t) => t()), U(o), o.remove(); s.forEach((t) => t()), U(o), o.remove();
@@ -423,22 +429,22 @@ var C = (e) => {
}; };
var F = (e, s, n = null) => { var F = (e, s, n = null) => {
let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = null; let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = null;
return T(() => !!(w(e) ? e() : e), (t) => { return C(() => !!(_(e) ? e() : e), (t) => {
if (i) if (i)
i.destroy(), i = null; i.destroy(), i = null;
let c = t ? s : n; let c = t ? s : n;
if (c) if (c)
i = C(() => w(c) ? c() : c), o.insertBefore(i.container, r); i = j(() => _(c) ? c() : c), o.insertBefore(i.container, r);
}), v(() => i?.destroy()), o; }), S(() => i?.destroy()), o;
}; };
var H = (e, s, n) => { var H = (e, s, n) => {
let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = new Map; let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = new Map;
return T(() => (w(e) ? e() : e) || [], (t) => { return C(() => (_(e) ? e() : e) || [], (t) => {
let c = new Map, l = [], a = t || []; let c = new Map, l = [], a = t || [];
for (let u = 0;u < a.length; u++) { for (let u = 0;u < a.length; u++) {
let h = a[u], p = n ? h?.[n] ?? u : h?.id ?? u, y = i.get(p); let h = a[u], p = n ? h?.[n] ?? u : h?.id ?? u, y = i.get(p);
if (!y) if (!y)
y = C(() => s(h, u)); y = j(() => s(h, u));
else else
i.delete(p); i.delete(p);
c.set(p, y), l.push(y); c.set(p, y), l.push(y);
@@ -454,11 +460,11 @@ var H = (e, s, n) => {
i = c; i = c;
}), o; }), o;
}; };
var S = (e) => { var N = (e) => {
let s = () => window.location.hash.slice(1) || "/", n = P(s()), r = () => n(s()); let s = () => window.location.hash.slice(1) || "/", n = P(s()), r = () => n(s());
window.addEventListener("hashchange", r), v(() => window.removeEventListener("hashchange", r)); window.addEventListener("hashchange", r), S(() => window.removeEventListener("hashchange", r));
let o = A("div", { class: "router-hook" }), i = null; let o = A("div", { class: "router-hook" }), i = null;
return T([n], () => { return C([n], () => {
let t = n(), c = e.find((l) => { let t = n(), c = e.find((l) => {
let a = l.path.split("/").filter(Boolean), f = t.split("/").filter(Boolean); let a = l.path.split("/").filter(Boolean), f = t.split("/").filter(Boolean);
return a.length === f.length && a.every((u, h) => u[0] === ":" || u === f[h]); return a.length === f.length && a.every((u, h) => u[0] === ":" || u === f[h]);
@@ -469,38 +475,56 @@ var S = (e) => {
c.path.split("/").filter(Boolean).forEach((a, f) => { c.path.split("/").filter(Boolean).forEach((a, f) => {
if (a[0] === ":") if (a[0] === ":")
l[a.slice(1)] = t.split("/").filter(Boolean)[f]; l[a.slice(1)] = t.split("/").filter(Boolean)[f];
}), S.params(l), i = C(() => w(c.component) ? c.component(l) : c.component), o.replaceChildren(i.container); }), N.params(l), i = j(() => _(c.component) ? c.component(l) : c.component), o.replaceChildren(i.container);
} }
}), o; }), o;
}; };
S.params = P({}); N.params = P({});
S.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/"); N.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/");
S.back = () => window.history.back(); N.back = () => window.history.back();
S.path = () => window.location.hash.replace(/^#/, "") || "/"; N.path = () => window.location.hash.replace(/^#/, "") || "/";
var Y = (e, s) => { var Y = (e, s) => {
let n = typeof s === "string" ? E.querySelector(s) : s; let n = typeof s === "string" ? E.querySelector(s) : s;
if (!n) if (!n)
return; return;
if (k.has(n)) if (L.has(n))
k.get(n).destroy(); L.get(n).destroy();
let r = C(w(e) ? e : () => e); let r = j(_(e) ? e : () => e);
return n.replaceChildren(r.container), k.set(n, r), r; return n.replaceChildren(r.container), L.set(n, r), r;
}; };
if (typeof window < "u") if (typeof window < "u")
Object.assign(window, { $: P, $$: D, watch: T, h: A, when: F, each: H, router: S, mount: Y, batch: z }), "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video".split(" ").forEach((e) => { Object.assign(window, { $: P, $$: D, watch: C, h: A, when: F, each: H, router: N, mount: Y, batch: z, onUnmount: S, isArr: b, isFunc: _, isObj: O }), "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video".split(" ").forEach((e) => {
window[e] = (s, n) => A(e, s, n); window[e] = (s, n) => A(e, s, n);
}); });
// sigpro-helpers.js // sigpro-ui.js
var get = (val) => typeof val === "function" ? val() : val; var val = (val2) => typeof val2 === "function" ? val2() : val2;
var getBy = (item, field = "label") => item && typeof item === "object" ? item[field] : item; var getBy = (item, field = "label") => item && typeof item === "object" ? item[field] : item;
var cls = (...classes) => classes.filter(Boolean).join(" ").trim(); var cls = (...classes) => classes.filter(Boolean).join(" ").trim();
var isFn = (f) => typeof f === "function"; var filterBy = (items, query, field = "label", q2 = String(query).toLowerCase()) => !query ? val(items) : val(items).filter((item) => String(item && typeof item === "object" ? item[field] : item).toLowerCase().includes(q2));
var filterBy = (items, query, field = "label", q2 = String(query).toLowerCase()) => !query ? get(items) : get(items).filter((item) => String(item && typeof item === "object" ? item[field] : item).toLowerCase().includes(q2));
var rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`; var rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`;
var hide = () => document.activeElement?.blur(); var hide = () => document.activeElement?.blur();
var i18n = {
// sigpro-ui.js es: {
close: "Cerrar",
confirm: "Confirmar",
cancel: "Cancelar",
search: "Buscar...",
loading: "Cargando...",
nodata: "Sin datos"
},
en: {
close: "Close",
confirm: "Confirm",
cancel: "Cancel",
search: "Search...",
loading: "Loading...",
nodata: "No data"
}
};
var currentLocale = P("en");
var Locale = (t) => currentLocale(t);
var tt = (t) => () => i18n[currentLocale()][t] || t;
var Accordion = (p) => { var Accordion = (p) => {
const name = p.name || rand("acc"); const name = p.name || rand("acc");
return H(p.items, (it) => { return H(p.items, (it) => {
@@ -515,13 +539,13 @@ var Alert = (p, c) => A("div", { ...p, class: cls("alert", p.class) }, c);
var Avatar = (p, c) => A("div", { class: "avatar" }, A("div", { class: p.class }, c)); var Avatar = (p, c) => A("div", { class: "avatar" }, A("div", { class: p.class }, c));
var AvatarGroup = (p, c) => A("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c); var AvatarGroup = (p, c) => A("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c);
var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) => { var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) => {
const query = P(get(value) || ""); const query = P(val(value) || "");
const filtered = P(() => filterBy(items, query())); const filtered = P(() => filterBy(items, query()));
const pick = (item) => { const pick = (item) => {
const display = getBy(item); const display = getBy(item);
const actual = typeof item === "string" ? item : item.value; const actual = typeof item === "string" ? item : item.value;
query(display); query(display);
if (isFn(value)) if (_(value))
value(actual); value(actual);
onselect?.(item); onselect?.(item);
hide(); hide();
@@ -534,7 +558,7 @@ var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) =
left: A("span", { class: "icon-[lucide--search]" }), left: A("span", { class: "icon-[lucide--search]" }),
oninput: (e) => { oninput: (e) => {
query(e.target.value); query(e.target.value);
if (isFn(value)) if (_(value))
value(e.target.value); value(e.target.value);
} }
})), })),
@@ -560,8 +584,8 @@ var Calendar = (p) => {
const now = new Date; const now = new Date;
const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`; const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
const fmt = (d2) => `${d2.getFullYear()}-${String(d2.getMonth() + 1).padStart(2, "0")}-${String(d2.getDate()).padStart(2, "0")}`; const fmt = (d2) => `${d2.getFullYear()}-${String(d2.getMonth() + 1).padStart(2, "0")}-${String(d2.getDate()).padStart(2, "0")}`;
const rangeMode = () => get(p.range) === true; const rangeMode = () => val(p.range) === true;
const current = () => get(p.value); const current = () => val(p.value);
const selectDate = (date) => { const selectDate = (date) => {
const s = fmt(date); const s = fmt(date);
const v2 = current(); const v2 = current();
@@ -592,7 +616,7 @@ var Calendar = (p) => {
const HourSlider = ({ value: hVal, onChange: onH }) => A("div", { class: "flex-1" }, [ const HourSlider = ({ value: hVal, onChange: onH }) => A("div", { class: "flex-1" }, [
A("div", { class: "flex gap-2 items-center" }, [ A("div", { class: "flex gap-2 items-center" }, [
A("input", { type: "range", min: 0, max: 23, value: hVal, class: "range range-xs flex-1", oninput: (e) => onH(+e.target.value) }), A("input", { type: "range", min: 0, max: 23, value: hVal, class: "range range-xs flex-1", oninput: (e) => onH(+e.target.value) }),
A("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(get(hVal)).padStart(2, "0") + ":00") A("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(val(hVal)).padStart(2, "0") + ":00")
]) ])
]); ]);
return A("div", { return A("div", {
@@ -663,7 +687,7 @@ var ChatHeader = (p, c) => A("div", { ...p, class: cls("chat-header", p.class) }
var ChatImage = (p, c) => A("div", { ...p, class: cls("chat-image avatar", p.class) }, A("div", { class: "w-10 rounded-full" }, typeof c === "string" ? A("img", { src: c, alt: "avatar" }) : c)); var ChatImage = (p, c) => A("div", { ...p, class: cls("chat-image avatar", p.class) }, A("div", { class: "w-10 rounded-full" }, typeof c === "string" ? A("img", { src: c, alt: "avatar" }) : c));
var Checkbox = (p) => A("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) }); var Checkbox = (p) => A("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) });
var Colorpicker = (p) => { var Colorpicker = (p) => {
const current = () => get(p.value) || "#000000"; const current = () => val(p.value) || "#000000";
return Dropdown({}, [ return Dropdown({}, [
DropdownButton({ class: "btn" }, [ DropdownButton({ class: "btn" }, [
A("div", { class: "size-5 rounded-sm", style: () => `background-color: ${current()}` }), A("div", { class: "size-5 rounded-sm", style: () => `background-color: ${current()}` }),
@@ -672,13 +696,13 @@ var Colorpicker = (p) => {
DropdownContent({ class: "p-0" }, ColorPalette({ DropdownContent({ class: "p-0" }, ColorPalette({
value: p.value, value: p.value,
onchange: (c) => { onchange: (c) => {
isFn(p.value) ? p.value(c) : p.onchange?.(c); _(p.value) ? p.value(c) : p.onchange?.(c);
} }
})) }))
]); ]);
}; };
var ColorPalette = (p) => { var ColorPalette = (p) => {
const current = () => get(p.value) || "#000000"; const current = () => val(p.value) || "#000000";
const palette = [ const palette = [
"#000", "#000",
"#1A1A1A", "#1A1A1A",
@@ -746,7 +770,7 @@ var ColorPalette = (p) => {
"#fae8ff" "#fae8ff"
]; ];
const pick = (c) => { const pick = (c) => {
isFn(p.value) ? p.value(c) : p.onchange?.(c); _(p.value) ? p.value(c) : p.onchange?.(c);
hide(); hide();
}; };
return A("div", { return A("div", {
@@ -765,9 +789,9 @@ var ColorPalette = (p) => {
}; };
var Datepicker = (p) => { var Datepicker = (p) => {
const displayValue = P(""); const displayValue = P("");
const rangeMode = () => get(p.range) === true; const rangeMode = () => val(p.range) === true;
T(() => { C(() => {
const v2 = get(p.value); const v2 = val(p.value);
if (!v2) if (!v2)
return displayValue(""); return displayValue("");
let text = ""; let text = "";
@@ -783,12 +807,12 @@ var Datepicker = (p) => {
} }
displayValue(text); displayValue(text);
}); });
const handleChange = (val) => { const handleChange = (val2) => {
if (isFn(p.value)) if (_(p.value))
p.value(val); p.value(val2);
else else
p.onChange?.(val); p.onChange?.(val2);
if (!rangeMode() || val?.end != null) if (!rangeMode() || val2?.end != null)
hide(); hide();
}; };
return Dropdown({ class: cls("w-full", p.class) }, [ return Dropdown({ class: cls("w-full", p.class) }, [
@@ -807,7 +831,7 @@ var Datepicker = (p) => {
onmousedown: (e) => { onmousedown: (e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (isFn(p.value)) if (_(p.value))
p.value(null); p.value(null);
else else
p.onChange?.(null); p.onChange?.(null);
@@ -824,7 +848,7 @@ var Datepicker = (p) => {
]); ]);
}; };
var Drawer = (p, c) => div({ ...p, class: cls("drawer", p.class) }, c); var Drawer = (p, c) => div({ ...p, class: cls("drawer", p.class) }, c);
var DrawerToggle = (p) => input({ ...p, type: "checkbox", class: "drawer-toggle", checked: () => get(p.checked), onchange: (e) => isFn(p.checked) && p.checked(e.target.checked) }); var DrawerToggle = (p) => input({ ...p, type: "checkbox", class: "drawer-toggle", checked: () => val(p.checked), onchange: (e) => _(p.checked) && p.checked(e.target.checked) });
var DrawerContent = (p, c) => div({ ...p, class: cls("drawer-content", p.class) }, c); var DrawerContent = (p, c) => div({ ...p, class: cls("drawer-content", p.class) }, c);
var DrawerSide = (p, c) => div({ ...p, class: cls("drawer-side", p.class) }, c); var DrawerSide = (p, c) => div({ ...p, class: cls("drawer-side", p.class) }, c);
var DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls("drawer-overlay", p.class) }); var DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls("drawer-overlay", p.class) });
@@ -848,17 +872,17 @@ var Fileinput = (p) => {
} }
const updated = [...files(), ...arr]; const updated = [...files(), ...arr];
files(updated); files(updated);
if (isFn(p.onselect)) if (_(p.onselect))
p.onselect(updated); p.onselect(updated);
else if (isFn(p.value)) else if (_(p.value))
p.value(updated); p.value(updated);
}; };
const remove = (idx) => { const remove = (idx) => {
const updated = files().filter((_2, i) => i !== idx); const updated = files().filter((_2, i) => i !== idx);
files(updated); files(updated);
if (isFn(p.onselect)) if (_(p.onselect))
p.onselect(updated); p.onselect(updated);
else if (isFn(p.value)) else if (_(p.value))
p.value(updated); p.value(updated);
}; };
return A("div", { class: cls("fieldset w-full p-0", p.class) }, [ return A("div", { class: cls("fieldset w-full p-0", p.class) }, [
@@ -913,7 +937,7 @@ var Input = (p) => {
const showPassword = P(false); const showPassword = P(false);
const isPassword = p.type === "password"; const isPassword = p.type === "password";
const pattern = rule ?? null; const pattern = rule ?? null;
const inputType = () => isPassword ? get(showPassword) ? "text" : "password" : p.type || "search"; const inputType = () => isPassword ? val(showPassword) ? "text" : "password" : p.type || "search";
return A("label", { class: float ? "floating-label" : "" }, [ return A("label", { class: float ? "floating-label" : "" }, [
float ? A("span", {}, label2) : null, float ? A("span", {}, label2) : null,
A("label", { pattern, class: () => cls("input validator", p.class) }, [ A("label", { pattern, class: () => cls("input validator", p.class) }, [
@@ -932,7 +956,7 @@ var Input = (p) => {
}; };
var Kbd = (p, c) => A("kbd", { ...p, class: cls("kbd", p.class) }, c); var Kbd = (p, c) => A("kbd", { ...p, class: cls("kbd", p.class) }, c);
var List = (p, c) => A("ul", { ...p, class: cls("list", p.class) }, c); var List = (p, c) => A("ul", { ...p, class: cls("list", p.class) }, c);
var ListRows = (p) => () => (get(p.items) || []).map((item, idx) => A("li", { class: cls("list-row", p.class, item?.class) }, typeof p.render === "function" ? p.render(item, idx) : item)); var ListRows = (p) => () => (val(p.items) || []).map((item, idx) => A("li", { class: cls("list-row", p.class, item?.class) }, typeof p.render === "function" ? p.render(item, idx) : item));
var Loading = (p, c) => A("span", { ...p, class: cls("loading loading-spinner", p.class) }, c); var Loading = (p, c) => A("span", { ...p, class: cls("loading loading-spinner", p.class) }, c);
var Menu = (p) => { var Menu = (p) => {
if (p.children !== undefined) if (p.children !== undefined)
@@ -940,7 +964,7 @@ var Menu = (p) => {
const { items } = p; const { items } = p;
const render = (item) => item.children ? A("li", {}, A("details", { open: item.open || undefined }, [ const render = (item) => item.children ? A("li", {}, A("details", { open: item.open || undefined }, [
A("summary", {}, getBy(item)), A("summary", {}, getBy(item)),
A("ul", {}, H(() => get(item.children) || [], render)) A("ul", {}, H(() => val(item.children) || [], render))
])) : A("li", {}, A("a", { ])) : A("li", {}, A("a", {
href: item.href, href: item.href,
onclick: item.onclick ? (e) => { onclick: item.onclick ? (e) => {
@@ -949,17 +973,17 @@ var Menu = (p) => {
item.onclick(e); item.onclick(e);
} : null } : null
}, getBy(item))); }, getBy(item)));
return A("ul", { class: cls("menu", p.class) }, H(() => get(items) || [], render)); return A("ul", { class: cls("menu", p.class) }, H(() => val(items) || [], render));
}; };
var Modal = (p) => { var Modal = (p) => {
let dialogRef = null; let dialogRef = null;
T(() => { C(() => {
const isOpen = get(p.open); const isOpen = val(p.open);
if (!dialogRef) if (!dialogRef)
return; return;
isOpen ? dialogRef.showModal() : dialogRef.hide(); isOpen ? dialogRef.showModal() : dialogRef.hide();
}); });
const close = () => isFn(p.open) && p.open(false); const close = () => _(p.open) && p.open(false);
return A("dialog", { return A("dialog", {
...p, ...p,
ref: (el) => dialogRef = el, ref: (el) => dialogRef = el,
@@ -981,17 +1005,17 @@ var Modal = (p) => {
}; };
var Navbar = (p, c) => A("div", { ...p, class: cls("navbar", p.class) }, c); var Navbar = (p, c) => A("div", { ...p, class: cls("navbar", p.class) }, c);
var Progress = (p) => A("progress", { ...p, class: cls("progress", p.class) }); var Progress = (p) => A("progress", { ...p, class: cls("progress", p.class) });
var Radial = (p, c) => A("div", { class: cls("radial-progress", p.class), style: `--value:${get(p.value) ?? 0};`, role: "progressbar", "aria-valuenow": p.value }, c); var Radial = (p, c) => A("div", { class: cls("radial-progress", p.class), style: `--value:${val(p.value) ?? 0};`, role: "progressbar", "aria-valuenow": p.value }, c);
var Radio = (p) => A("input", { ...p, type: "radio", class: cls("radio", p.class) }); var Radio = (p) => A("input", { ...p, type: "radio", class: cls("radio", p.class) });
var Range = (p) => A("input", { ...p, type: "range", class: cls("range", p.class) }); var Range = (p) => A("input", { ...p, type: "range", class: cls("range", p.class) });
var Rating = (p, c) => A("div", { ...p, class: "rating" }, c); var Rating = (p, c) => A("div", { ...p, class: "rating" }, c);
var RatingItems = (p) => [...Array(p.count)].map((_2, i) => A("input", { class: cls("mask", p.class), name: p.name, type: "radio", checked: () => get(p.value) === i, onchange: () => isFn(p.value) ? p.value(i) : p.onchange?.(i) })); var RatingItems = (p) => [...Array(p.count)].map((_2, i) => A("input", { class: cls("mask", p.class), name: p.name, type: "radio", checked: () => val(p.value) === i, onchange: () => _(p.value) ? p.value(i) : p.onchange?.(i) }));
var Select = (p, c) => { var Select = (p, c) => {
if (c !== undefined) if (c !== undefined)
return A("select", { class: cls("select", p.class), ...p }, c); return A("select", { class: cls("select", p.class), ...p }, c);
const { label: label2, float, placeholder, placeholderDisabled = true, value, left, right, hint, items, keyFn, ...rest } = p; const { label: label2, float, placeholder, placeholderDisabled = true, value, left, right, hint, items, keyFn, ...rest } = p;
const opts = () => { const opts = () => {
const raw = get(items) || []; const raw = val(items) || [];
const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: "" }] : []; const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: "" }] : [];
return [...ph, ...raw]; return [...ph, ...raw];
}; };
@@ -1001,12 +1025,12 @@ var Select = (p, c) => {
!float && label2 ? A("span", { class: "label" }, label2) : null, !float && label2 ? A("span", { class: "label" }, label2) : null,
left ?? null, left ?? null,
A("select", { A("select", {
value: () => get(value), value: () => val(value),
onchange: (e) => isFn(value) ? value(e.target.value) : rest.onchange?.(e) onchange: (e) => _(value) ? value(e.target.value) : rest.onchange?.(e)
}, H(opts, (item) => { }, H(opts, (item) => {
const val = getBy(item, item.value !== undefined ? "value" : undefined); const val2 = getBy(item, item.value !== undefined ? "value" : undefined);
const lab = getBy(item, "label"); const lab = getBy(item, "label");
return A("option", { value: val, disabled: item.disabled || undefined }, lab); return A("option", { value: val2, disabled: item.disabled || undefined }, lab);
})), })),
right ?? null right ?? null
]), ]),
@@ -1025,14 +1049,14 @@ var Stat = (p) => A("div", { ...p, class: cls("stat", p.class) }, [
var Steps = (p, c) => A("ul", { ...p, class: cls("steps", p.class) }, c); var Steps = (p, c) => A("ul", { ...p, class: cls("steps", p.class) }, c);
var Step = (p, c) => A("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c); var Step = (p, c) => A("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c);
var Swap = (p, c) => A("label", { ...p, class: cls("swap", p.class) }, c); var Swap = (p, c) => A("label", { ...p, class: cls("swap", p.class) }, c);
var SwapToggle = (p) => A("input", { type: "checkbox", checked: () => get(p.value), onchange: (e) => isFn(p.value) && p.value(e.target.checked), class: p.class }); var SwapToggle = (p) => A("input", { type: "checkbox", checked: () => val(p.value), onchange: (e) => _(p.value) && p.value(e.target.checked), class: p.class });
var SwapOn = (p, c) => A("div", { ...p, class: cls("swap-on", p.class) }, c); var SwapOn = (p, c) => A("div", { ...p, class: cls("swap-on", p.class) }, c);
var SwapOff = (p, c) => A("div", { ...p, class: cls("swap-off", p.class) }, c); var SwapOff = (p, c) => A("div", { ...p, class: cls("swap-off", p.class) }, c);
var Table = (p, c) => A("table", { ...p, class: cls("table", p.class) }, c); var Table = (p, c) => A("table", { ...p, class: cls("table", p.class) }, c);
var TableItems = ({ items, columns = [], header = true }) => { var TableItems = ({ items, columns = [], header = true }) => {
const head = header !== false && columns.some((c) => c.label) ? A("thead", {}, A("tr", {}, columns.map((c) => A("th", { class: c.class }, c.label)))) : null; const head = header !== false && columns.some((c) => c.label) ? A("thead", {}, A("tr", {}, columns.map((c) => A("th", { class: c.class }, c.label)))) : null;
const body = A("tbody", {}, () => { const body = A("tbody", {}, () => {
const list = get(items) || []; const list = val(items) || [];
return list.map((it, idx) => A("tr", {}, columns.map((c) => { return list.map((it, idx) => A("tr", {}, columns.map((c) => {
const v2 = c.render ? c.render(it, idx) : it[c.key]; const v2 = c.render ? c.render(it, idx) : it[c.key];
return A("td", { class: c.class }, v2); return A("td", { class: c.class }, v2);
@@ -1046,16 +1070,16 @@ var Tabs = (p, c) => {
return A("div", { ...rest2, class: cls("tabs", className2) }, c); return A("div", { ...rest2, class: cls("tabs", className2) }, c);
} }
const { items, activeIndex, onClose, class: className, ...rest } = p; const { items, activeIndex, onClose, class: className, ...rest } = p;
const get2 = (x2) => isFn(x2) ? x2() : x2; const get = (x2) => _(x2) ? x2() : x2;
const closeH = onClose || (isFn(items) ? (idx, item) => { const closeH = onClose || (_(items) ? (idx, item) => {
const arr = get2(items); const arr = val(items);
const newArr = arr.filter((_2, i) => i !== idx); const newArr = arr.filter((_2, i) => i !== idx);
items(newArr); items(newArr);
if (activeIndex() >= newArr.length) if (activeIndex() >= newArr.length)
activeIndex(Math.max(0, newArr.length - 1)); activeIndex(Math.max(0, newArr.length - 1));
} : null); } : null);
return A("div", { ...rest, class: cls("tabs", className) }, () => { return A("div", { ...rest, class: cls("tabs", className) }, () => {
const list = get2(items) || []; const list = val(items) || [];
return list.flatMap((it, idx) => { return list.flatMap((it, idx) => {
const isActive = () => activeIndex() === idx; const isActive = () => activeIndex() === idx;
const button = A("button", { const button = A("button", {
@@ -1078,7 +1102,7 @@ var Tabs = (p, c) => {
const contentDiv = A("div", { const contentDiv = A("div", {
class: "tab-content bg-base-100 border-base-300 p-6", class: "tab-content bg-base-100 border-base-300 p-6",
style: () => `display: ${isActive() ? "block" : "none"};` style: () => `display: ${isActive() ? "block" : "none"};`
}, isFn(it.content) ? it.content() : it.content); }, _(it.content) ? it.content() : it.content);
return [button, contentDiv]; return [button, contentDiv];
}); });
}); });
@@ -1115,7 +1139,7 @@ var Toast = (message, type = "alert-success", duration = 3500) => {
}, 300); }, 300);
}; };
enterTimer = setTimeout(() => visible(true), 0); enterTimer = setTimeout(() => visible(true), 0);
const content = typeof message === "function" ? get(message) : message; const content = typeof message === "function" ? val(message) : message;
const msgNode = typeof content === "string" ? A("span", {}, content) : content; const msgNode = typeof content === "string" ? A("span", {}, content) : content;
return A("div", { return A("div", {
class: () => { class: () => {
@@ -1141,12 +1165,6 @@ var Toast = (message, type = "alert-success", duration = 3500) => {
}; };
var Toggle = (p) => A("input", { ...p, type: "checkbox", class: cls("toggle", p.class) }); var Toggle = (p) => A("input", { ...p, type: "checkbox", class: cls("toggle", p.class) });
var Tooltip = (p, c) => A("div", { ...p, class: cls("tooltip", p.class), "data-tip": p.tip }, c); var Tooltip = (p, c) => A("div", { ...p, class: cls("tooltip", p.class), "data-tip": p.tip }, c);
// sigpro-editor.js
var exports_sigpro_editor = {};
__export(exports_sigpro_editor, {
Editor: () => Editor
});
var Editor = (p) => { var Editor = (p) => {
const { value, class: extraClass } = p; const { value, class: extraClass } = p;
let editorRef = null; let editorRef = null;
@@ -1178,19 +1196,19 @@ var Editor = (p) => {
if (!editorRef) if (!editorRef)
return; return;
const html = editorRef.innerHTML; const html = editorRef.innerHTML;
if (isFn(value)) if (_(value))
value(html); value(html);
else else
p.onchange?.(html); p.onchange?.(html);
triggerRefresh(); triggerRefresh();
}; };
const exec = (cmd, val = null) => { const exec = (cmd, val2 = null) => {
if (!editorRef) if (!editorRef)
return; return;
editorRef.focus(); editorRef.focus();
if (savedRange) if (savedRange)
restoreSelection(); restoreSelection();
document.execCommand(cmd, false, val); document.execCommand(cmd, false, val2);
savedRange = null; savedRange = null;
notify(); notify();
}; };
@@ -1219,7 +1237,7 @@ var Editor = (p) => {
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
}; };
const queryState = (cmd, val = null) => { const queryState = (cmd, val2 = null) => {
refreshTick(); refreshTick();
if (!editorRef || isSource()) if (!editorRef || isSource())
return false; return false;
@@ -1227,7 +1245,7 @@ var Editor = (p) => {
if (cmd === "formatBlock") { if (cmd === "formatBlock") {
let node = window.getSelection().getRangeAt(0).commonAncestorContainer; let node = window.getSelection().getRangeAt(0).commonAncestorContainer;
while (node && node !== editorRef) { while (node && node !== editorRef) {
if (node.nodeType === 1 && node.tagName === val) if (node.nodeType === 1 && node.tagName === val2)
return true; return true;
node = node.parentNode; node = node.parentNode;
} }
@@ -1323,7 +1341,7 @@ var Editor = (p) => {
ref: (el) => { ref: (el) => {
if (!editorRef && el) { if (!editorRef && el) {
editorRef = el; editorRef = el;
el.innerHTML = get(value) || ""; el.innerHTML = val(value) || "";
document.execCommand("defaultParagraphSeparator", false, "br"); document.execCommand("defaultParagraphSeparator", false, "br");
el.addEventListener("click", (e) => { el.addEventListener("click", (e) => {
const container = e.target.closest(".resizable-img-container"); const container = e.target.closest(".resizable-img-container");
@@ -1387,42 +1405,10 @@ var Editor = (p) => {
]); ]);
}; };
// sigpro-locale.js
var i18n = {
es: {
close: "Cerrar",
confirm: "Confirmar",
cancel: "Cancelar",
search: "Buscar...",
loading: "Cargando...",
nodata: "Sin datos"
},
en: {
close: "Close",
confirm: "Confirm",
cancel: "Cancel",
search: "Search...",
loading: "Loading...",
nodata: "No data"
}
};
var currentLocale = P("es");
var Locale = (t) => currentLocale(t);
var tt = (t) => () => i18n[currentLocale()][t] || t;
// index.js // index.js
var Components = { var Components = { ...exports_sigpro_ui };
...exports_sigpro_ui,
...exports_sigpro_editor
};
var Utils = {
Locale,
tt,
hide,
get
};
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
Object.entries({ ...Components, ...Utils }).forEach(([name, value]) => { Object.entries({ ...Components }).forEach(([name, value]) => {
Object.defineProperty(window, name, { Object.defineProperty(window, name, {
value, value,
writable: false, writable: false,
@@ -1432,6 +1418,5 @@ if (typeof window !== "undefined") {
}); });
} }
export { export {
Utils,
Components Components
}; };

File diff suppressed because one or more lines are too long

349
dist/sigpro-ui.js vendored
View File

@@ -40,13 +40,16 @@
// index.js // index.js
var exports_sigpro_ui2 = {}; var exports_sigpro_ui2 = {};
__export(exports_sigpro_ui2, { __export(exports_sigpro_ui2, {
Utils: () => Utils,
Components: () => Components Components: () => Components
}); });
// sigpro-ui.js // sigpro-ui.js
var exports_sigpro_ui = {}; var exports_sigpro_ui = {};
__export(exports_sigpro_ui, { __export(exports_sigpro_ui, {
tt: () => tt,
i18n: () => i18n,
hide: () => hide,
currentLocale: () => currentLocale,
Tooltip: () => Tooltip, Tooltip: () => Tooltip,
Toggle: () => Toggle, Toggle: () => Toggle,
Toast: () => Toast, Toast: () => Toast,
@@ -77,6 +80,7 @@
Navbar: () => Navbar, Navbar: () => Navbar,
Modal: () => Modal, Modal: () => Modal,
Menu: () => Menu, Menu: () => Menu,
Locale: () => Locale,
Loading: () => Loading, Loading: () => Loading,
ListRows: () => ListRows, ListRows: () => ListRows,
List: () => List, List: () => List,
@@ -87,6 +91,7 @@
Fileinput: () => Fileinput, Fileinput: () => Fileinput,
Fieldset: () => Fieldset, Fieldset: () => Fieldset,
Fab: () => Fab, Fab: () => Fab,
Editor: () => Editor,
DropdownContent: () => DropdownContent, DropdownContent: () => DropdownContent,
DropdownButton: () => DropdownButton, DropdownButton: () => DropdownButton,
Dropdown: () => Dropdown, Dropdown: () => Dropdown,
@@ -123,23 +128,23 @@
}); });
// node_modules/sigpro/dist/sigpro.esm.min.js // node_modules/sigpro/dist/sigpro.esm.min.js
var w = (e) => typeof e === "function"; var _ = (e) => typeof e === "function";
var B = (e) => e && typeof e === "object"; var O = (e) => e && typeof e === "object";
var g = Array.isArray; var b = Array.isArray;
var E = typeof document < "u" ? document : null; var E = typeof document < "u" ? document : null;
var V = (e) => e?._isRuntime ? e.container : e instanceof Node ? e : E.createTextNode(e == null ? "" : String(e)); var V = (e) => e?._isRuntime ? e.container : e instanceof Node ? e : E.createTextNode(e == null ? "" : String(e));
var d = null; var d = null;
var _ = null; var m = null;
var N = false; var v = false;
var R = 0; var R = 0;
var O = new Set; var T = new Set;
var I = new WeakMap; var I = new WeakMap;
var j = Symbol("iter"); var k = Symbol("iter");
var k = new WeakMap; var L = new WeakMap;
var W = "http://www.w3.org/2000/svg"; var W = "http://www.w3.org/2000/svg";
var M = "http://www.w3.org/1999/xlink"; var M = "http://www.w3.org/1999/xlink";
var q = new Set("svg,path,circle,rect,line,polyline,polygon,g,defs,text,textPath,tspan,use,symbol,image,marker,ellipse".split(",")); var q = new Set("svg,path,circle,rect,line,polyline,polygon,g,defs,text,textPath,tspan,use,symbol,image,marker,ellipse".split(","));
var b = (e) => { var g = (e) => {
if (!e || e._disposed) if (!e || e._disposed)
return; return;
e._disposed = true; e._disposed = true;
@@ -154,9 +159,9 @@
n._deps.forEach((r) => r.delete(n)), n._deps.clear(); n._deps.forEach((r) => r.delete(n)), n._deps.clear();
} }
}; };
var v = (e) => { var S = (e) => {
if (_) if (m)
(_._cleanups ||= new Set).add(e); (m._cleanups ||= new Set).add(e);
}; };
var K = (e) => { var K = (e) => {
let s = d; let s = d;
@@ -175,41 +180,41 @@
n._deps.forEach((i) => i.delete(n)); n._deps.forEach((i) => i.delete(n));
if (n._cleanups) if (n._cleanups)
n._cleanups.forEach((i) => i()), n._cleanups.clear(); n._cleanups.forEach((i) => i()), n._cleanups.clear();
let r = d, o = _; let r = d, o = m;
d = _ = n; d = m = n;
try { try {
return n._result = e(); return n._result = e();
} catch (i) { } catch (i) {
console.error("[SigPro]", i); console.error("[SigPro]", i);
} finally { } finally {
d = r, _ = o; d = r, m = o;
} }
}; };
if (n._deps = n._cleanups = n._children = null, n._disposed = false, n._isComputed = s, n._depth = d ? d._depth + 1 : 0, n._mounts = [], n._parent = _, _) if (n._deps = n._cleanups = n._children = null, n._disposed = false, n._isComputed = s, n._depth = d ? d._depth + 1 : 0, n._mounts = [], n._parent = m, m)
(_._children ||= new Set).add(n); (m._children ||= new Set).add(n);
return n; return n;
}; };
var $ = () => { var $ = () => {
if (N) if (v)
return; return;
N = true; v = true;
let e = Array.from(O).sort((s, n) => s._depth - n._depth); let e = Array.from(T).sort((s, n) => s._depth - n._depth);
O.clear(); T.clear();
for (let s of e) for (let s of e)
if (!s._disposed) if (!s._disposed)
s(); s();
N = false; v = false;
}; };
var z = (e) => { var z = (e) => {
R++; R++;
try { try {
return e(); return e();
} finally { } finally {
if (R--, R === 0 && O.size > 0 && !N) if (R--, R === 0 && T.size > 0 && !v)
$(); $();
} }
}; };
var m = (e, s = false) => { var w = (e, s = false) => {
if (!s && d && !d._disposed) if (!s && d && !d._disposed)
e.add(d), (d._deps ||= new Set).add(e); e.add(d), (d._deps ||= new Set).add(e);
else if (s && e.size > 0) { else if (s && e.size > 0) {
@@ -219,17 +224,17 @@
continue; continue;
if (r._isComputed) { if (r._isComputed) {
if (r._dirty = true, r._subs) if (r._dirty = true, r._subs)
m(r._subs, true); w(r._subs, true);
} else } else
O.add(r), n = true; T.add(r), n = true;
} }
if (n && !N && R === 0) if (n && !v && R === 0)
queueMicrotask($); queueMicrotask($);
} }
}; };
var P = (e, s = null) => { var P = (e, s = null) => {
let n = new Set; let n = new Set;
if (w(e)) { if (_(e)) {
let r, o = () => { let r, o = () => {
if (o._dirty) { if (o._dirty) {
let i = d; let i = d;
@@ -237,13 +242,13 @@
try { try {
let t = e(); let t = e();
if (!Object.is(r, t)) if (!Object.is(r, t))
r = t, m(n, true); r = t, w(n, true);
} finally { } finally {
d = i; d = i;
} }
o._dirty = false; o._dirty = false;
} }
return m(n), r; return w(n), r;
}; };
return o._isComputed = true, o._subs = n, o._dirty = true, o._deps = null, o._disposed = false, o; return o._isComputed = true, o._subs = n, o._dirty = true, o._deps = null, o._disposed = false, o;
} }
@@ -253,18 +258,18 @@
} catch (r) {} } catch (r) {}
return (...r) => { return (...r) => {
if (r.length) { if (r.length) {
let o = w(r[0]) ? r[0](e) : r[0]; let o = _(r[0]) ? r[0](e) : r[0];
if (!Object.is(e, o)) { if (!Object.is(e, o)) {
if (e = o, s) if (e = o, s)
localStorage.setItem(s, JSON.stringify(e)); localStorage.setItem(s, JSON.stringify(e));
m(n, true); w(n, true);
} }
} }
return m(n), e; return w(n), e;
}; };
}; };
var D = (e) => { var D = (e) => {
if (!B(e)) if (!O(e))
return e; return e;
let s = I.get(e); let s = I.get(e);
if (s) if (s)
@@ -276,35 +281,35 @@
return t; return t;
}, o = new Proxy(e, { get(i, t, c) { }, o = new Proxy(e, { get(i, t, c) {
if (typeof t !== "symbol") if (typeof t !== "symbol")
m(r(t)); w(r(t));
return D(Reflect.get(i, t, c)); return D(Reflect.get(i, t, c));
}, set(i, t, c, l) { }, set(i, t, c, l) {
let a = Reflect.has(i, t), f = Reflect.get(i, t, l), u = Reflect.set(i, t, c, l); let a = Reflect.has(i, t), f = Reflect.get(i, t, l), u = Reflect.set(i, t, c, l);
if (u && !Object.is(f, c)) { if (u && !Object.is(f, c)) {
if (m(r(t), true), !a) if (w(r(t), true), !a)
m(r(j), true); w(r(k), true);
} }
return u; return u;
}, deleteProperty(i, t) { }, deleteProperty(i, t) {
let c = Reflect.deleteProperty(i, t); let c = Reflect.deleteProperty(i, t);
if (c) if (c)
m(r(t), true), m(r(j), true); w(r(t), true), w(r(k), true);
return c; return c;
}, ownKeys(i) { }, ownKeys(i) {
return m(r(j)), Reflect.ownKeys(i); return w(r(k)), Reflect.ownKeys(i);
} }); } });
return I.set(e, o), o; return I.set(e, o), o;
}; };
var T = (e, s) => { var C = (e, s) => {
if (s === undefined) { if (s === undefined) {
let r = x(e); let r = x(e);
return r(), () => b(r); return r(), () => g(r);
} }
let n = x(() => { let n = x(() => {
let r = Array.isArray(e) ? e.map((o) => o()) : e(); let r = Array.isArray(e) ? e.map((o) => o()) : e();
K(() => s(r)); K(() => s(r));
}); });
return n(), () => b(n); return n(), () => g(n);
}; };
var U = (e) => { var U = (e) => {
if (!e) if (!e)
@@ -312,14 +317,14 @@
if (e._cleanups) if (e._cleanups)
e._cleanups.forEach((s) => s()), e._cleanups.clear(); e._cleanups.forEach((s) => s()), e._cleanups.clear();
if (e._ownerEffect) if (e._ownerEffect)
b(e._ownerEffect); g(e._ownerEffect);
if (e.childNodes) if (e.childNodes)
e.childNodes.forEach((s) => U(s)); e.childNodes.forEach((s) => U(s));
}; };
var J = /^\s*(javascript|data|vbscript):/i; var J = /^\s*(javascript|data|vbscript):/i;
var Q = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]); var Q = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
var X = (e) => Q.has(e) || e.startsWith("on"); var X = (e) => Q.has(e) || e.startsWith("on");
var L = (e, s) => { var B = (e, s) => {
if (s == null || s === false) if (s == null || s === false)
return null; return null;
if (X(e)) { if (X(e)) {
@@ -330,9 +335,9 @@
return s; return s;
}; };
var A = (e, s = {}, n = []) => { var A = (e, s = {}, n = []) => {
if (s instanceof Node || g(s) || !B(s)) if (s instanceof Node || b(s) || !O(s))
n = s, s = {}; n = s, s = {};
if (w(e)) { if (_(e)) {
let t = x(() => { let t = x(() => {
let f = e(s, { children: n, emit: (u, ...h) => s[`on${u[0].toUpperCase()}${u.slice(1)}`]?.(...h) }); let f = e(s, { children: n, emit: (u, ...h) => s[`on${u[0].toUpperCase()}${u.slice(1)}`]?.(...h) });
return t._result = f, f; return t._result = f, f;
@@ -341,22 +346,22 @@
let c = t._result; let c = t._result;
if (c == null) if (c == null)
return null; return null;
let l = c instanceof Node || g(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => { let l = c instanceof Node || b(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => {
if (B(f) && !f._isRuntime) if (O(f) && !f._isRuntime)
f._mounts = t._mounts || [], f._cleanups = t._cleanups || new Set, f._ownerEffect = t; f._mounts = t._mounts || [], f._cleanups = t._cleanups || new Set, f._ownerEffect = t;
}; };
return g(l) ? l.forEach(a) : a(l), l; return b(l) ? l.forEach(a) : a(l), l;
} }
let r = q.has(e), o = r ? E.createElementNS(W, e) : E.createElement(e); let r = q.has(e), o = r ? E.createElementNS(W, e) : E.createElement(e);
o._cleanups = new Set; o._cleanups = new Set;
for (let t of Object.keys(s)) { for (let t of Object.keys(s)) {
let c = s[t]; let c = s[t];
if (t === "ref") { if (t === "ref") {
w(c) ? c(o) : c.current = o; _(c) ? c(o) : c.current = o;
continue; continue;
} }
if (r && t.startsWith("xlink:")) { if (r && t.startsWith("xlink:")) {
let l = L(t.slice(6), c); let l = B(t.slice(6), c);
l == null ? o.removeAttributeNS(M, t.slice(6)) : o.setAttributeNS(M, t.slice(6), l); l == null ? o.removeAttributeNS(M, t.slice(6)) : o.setAttributeNS(M, t.slice(6), l);
continue; continue;
} }
@@ -364,10 +369,10 @@
let l = t.slice(2).toLowerCase(); let l = t.slice(2).toLowerCase();
o.addEventListener(l, c); o.addEventListener(l, c);
let a = () => o.removeEventListener(l, c); let a = () => o.removeEventListener(l, c);
o._cleanups.add(a), v(a); o._cleanups.add(a), S(a);
} else if (w(c)) { } else if (_(c)) {
let l = x(() => { let l = x(() => {
let a = L(t, c()); let a = B(t, c());
if (t === "class") if (t === "class")
o.className = a || ""; o.className = a || "";
else if (a == null) else if (a == null)
@@ -379,12 +384,12 @@
else else
o.setAttribute(t, a === true ? "" : a); o.setAttribute(t, a === true ? "" : a);
}); });
if (l(), o._cleanups.add(() => b(l)), v(() => b(l)), /^(INPUT|TEXTAREA|SELECT)$/.test(o.tagName) && (t === "value" || t === "checked")) { if (l(), o._cleanups.add(() => g(l)), S(() => g(l)), /^(INPUT|TEXTAREA|SELECT)$/.test(o.tagName) && (t === "value" || t === "checked")) {
let a = t === "checked" ? "change" : "input"; let a = t === "checked" ? "change" : "input";
o.addEventListener(a, (f) => c(f.target[t])); o.addEventListener(a, (f) => c(f.target[t]));
} }
} else { } else {
let l = L(t, c); let l = B(t, c);
if (l != null) if (l != null)
if (t === "style" && typeof l === "string") if (t === "style" && typeof l === "string")
o.setAttribute("style", l); o.setAttribute("style", l);
@@ -395,13 +400,13 @@
} }
} }
let i = (t) => { let i = (t) => {
if (g(t)) if (b(t))
return t.forEach(i); return t.forEach(i);
if (w(t)) { if (_(t)) {
let c = E.createTextNode(""); let c = E.createTextNode("");
o.appendChild(c); o.appendChild(c);
let l = [], a = x(() => { let l = [], a = x(() => {
let f = t(), u = (g(f) ? f : [f]).map(V); let f = t(), u = (b(f) ? f : [f]).map(V);
l.forEach((p) => { l.forEach((p) => {
if (p._isRuntime) if (p._isRuntime)
p.destroy(); p.destroy();
@@ -421,7 +426,7 @@
} }
l = u; l = u;
}); });
a(), o._cleanups.add(() => b(a)), v(() => b(a)); a(), o._cleanups.add(() => g(a)), S(() => g(a));
} else { } else {
let c = V(t); let c = V(t);
if (o.appendChild(c), c._mounts) if (o.appendChild(c), c._mounts)
@@ -430,15 +435,15 @@
}; };
return i(n), o; return i(n), o;
}; };
var C = (e) => { var j = (e) => {
let s = new Set, n = _, r = d, o = E.createElement("div"); let s = new Set, n = m, r = d, o = E.createElement("div");
o.style.display = "contents", o.setAttribute("role", "presentation"), _ = { _cleanups: s }, d = null; o.style.display = "contents", o.setAttribute("role", "presentation"), m = { _cleanups: s }, d = null;
let i = (t) => { let i = (t) => {
if (!t) if (!t)
return; return;
if (t._isRuntime) if (t._isRuntime)
s.add(t.destroy), o.appendChild(t.container); s.add(t.destroy), o.appendChild(t.container);
else if (g(t)) else if (b(t))
t.forEach(i); t.forEach(i);
else else
o.appendChild(t instanceof Node ? t : E.createTextNode(String(t == null ? "" : t))); o.appendChild(t instanceof Node ? t : E.createTextNode(String(t == null ? "" : t)));
@@ -446,7 +451,7 @@
try { try {
i(e({ onCleanup: (t) => s.add(t) })); i(e({ onCleanup: (t) => s.add(t) }));
} finally { } finally {
_ = n, d = r; m = n, d = r;
} }
return { _isRuntime: true, container: o, destroy: () => { return { _isRuntime: true, container: o, destroy: () => {
s.forEach((t) => t()), U(o), o.remove(); s.forEach((t) => t()), U(o), o.remove();
@@ -454,22 +459,22 @@
}; };
var F = (e, s, n = null) => { var F = (e, s, n = null) => {
let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = null; let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = null;
return T(() => !!(w(e) ? e() : e), (t) => { return C(() => !!(_(e) ? e() : e), (t) => {
if (i) if (i)
i.destroy(), i = null; i.destroy(), i = null;
let c = t ? s : n; let c = t ? s : n;
if (c) if (c)
i = C(() => w(c) ? c() : c), o.insertBefore(i.container, r); i = j(() => _(c) ? c() : c), o.insertBefore(i.container, r);
}), v(() => i?.destroy()), o; }), S(() => i?.destroy()), o;
}; };
var H = (e, s, n) => { var H = (e, s, n) => {
let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = new Map; let r = E.createTextNode(""), o = A("div", { style: "display:contents" }, [r]), i = new Map;
return T(() => (w(e) ? e() : e) || [], (t) => { return C(() => (_(e) ? e() : e) || [], (t) => {
let c = new Map, l = [], a = t || []; let c = new Map, l = [], a = t || [];
for (let u = 0;u < a.length; u++) { for (let u = 0;u < a.length; u++) {
let h = a[u], p = n ? h?.[n] ?? u : h?.id ?? u, y = i.get(p); let h = a[u], p = n ? h?.[n] ?? u : h?.id ?? u, y = i.get(p);
if (!y) if (!y)
y = C(() => s(h, u)); y = j(() => s(h, u));
else else
i.delete(p); i.delete(p);
c.set(p, y), l.push(y); c.set(p, y), l.push(y);
@@ -485,11 +490,11 @@
i = c; i = c;
}), o; }), o;
}; };
var S = (e) => { var N = (e) => {
let s = () => window.location.hash.slice(1) || "/", n = P(s()), r = () => n(s()); let s = () => window.location.hash.slice(1) || "/", n = P(s()), r = () => n(s());
window.addEventListener("hashchange", r), v(() => window.removeEventListener("hashchange", r)); window.addEventListener("hashchange", r), S(() => window.removeEventListener("hashchange", r));
let o = A("div", { class: "router-hook" }), i = null; let o = A("div", { class: "router-hook" }), i = null;
return T([n], () => { return C([n], () => {
let t = n(), c = e.find((l) => { let t = n(), c = e.find((l) => {
let a = l.path.split("/").filter(Boolean), f = t.split("/").filter(Boolean); let a = l.path.split("/").filter(Boolean), f = t.split("/").filter(Boolean);
return a.length === f.length && a.every((u, h) => u[0] === ":" || u === f[h]); return a.length === f.length && a.every((u, h) => u[0] === ":" || u === f[h]);
@@ -500,38 +505,56 @@
c.path.split("/").filter(Boolean).forEach((a, f) => { c.path.split("/").filter(Boolean).forEach((a, f) => {
if (a[0] === ":") if (a[0] === ":")
l[a.slice(1)] = t.split("/").filter(Boolean)[f]; l[a.slice(1)] = t.split("/").filter(Boolean)[f];
}), S.params(l), i = C(() => w(c.component) ? c.component(l) : c.component), o.replaceChildren(i.container); }), N.params(l), i = j(() => _(c.component) ? c.component(l) : c.component), o.replaceChildren(i.container);
} }
}), o; }), o;
}; };
S.params = P({}); N.params = P({});
S.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/"); N.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/");
S.back = () => window.history.back(); N.back = () => window.history.back();
S.path = () => window.location.hash.replace(/^#/, "") || "/"; N.path = () => window.location.hash.replace(/^#/, "") || "/";
var Y = (e, s) => { var Y = (e, s) => {
let n = typeof s === "string" ? E.querySelector(s) : s; let n = typeof s === "string" ? E.querySelector(s) : s;
if (!n) if (!n)
return; return;
if (k.has(n)) if (L.has(n))
k.get(n).destroy(); L.get(n).destroy();
let r = C(w(e) ? e : () => e); let r = j(_(e) ? e : () => e);
return n.replaceChildren(r.container), k.set(n, r), r; return n.replaceChildren(r.container), L.set(n, r), r;
}; };
if (typeof window < "u") if (typeof window < "u")
Object.assign(window, { $: P, $$: D, watch: T, h: A, when: F, each: H, router: S, mount: Y, batch: z }), "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video".split(" ").forEach((e) => { Object.assign(window, { $: P, $$: D, watch: C, h: A, when: F, each: H, router: N, mount: Y, batch: z, onUnmount: S, isArr: b, isFunc: _, isObj: O }), "a abbr article aside audio b blockquote br button canvas caption cite code col colgroup datalist dd del details dfn dialog div dl dt em embed fieldset figcaption figure footer form h1 h2 h3 h4 h5 h6 header hr i iframe img input ins kbd label legend li main mark meter nav object ol optgroup option output p picture pre progress section select slot small source span strong sub summary sup svg table tbody td template textarea tfoot th thead time tr u ul video".split(" ").forEach((e) => {
window[e] = (s, n) => A(e, s, n); window[e] = (s, n) => A(e, s, n);
}); });
// sigpro-helpers.js // sigpro-ui.js
var get = (val) => typeof val === "function" ? val() : val; var val = (val2) => typeof val2 === "function" ? val2() : val2;
var getBy = (item, field = "label") => item && typeof item === "object" ? item[field] : item; var getBy = (item, field = "label") => item && typeof item === "object" ? item[field] : item;
var cls = (...classes) => classes.filter(Boolean).join(" ").trim(); var cls = (...classes) => classes.filter(Boolean).join(" ").trim();
var isFn = (f) => typeof f === "function"; var filterBy = (items, query, field = "label", q2 = String(query).toLowerCase()) => !query ? val(items) : val(items).filter((item) => String(item && typeof item === "object" ? item[field] : item).toLowerCase().includes(q2));
var filterBy = (items, query, field = "label", q2 = String(query).toLowerCase()) => !query ? get(items) : get(items).filter((item) => String(item && typeof item === "object" ? item[field] : item).toLowerCase().includes(q2));
var rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`; var rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`;
var hide = () => document.activeElement?.blur(); var hide = () => document.activeElement?.blur();
var i18n = {
// sigpro-ui.js es: {
close: "Cerrar",
confirm: "Confirmar",
cancel: "Cancelar",
search: "Buscar...",
loading: "Cargando...",
nodata: "Sin datos"
},
en: {
close: "Close",
confirm: "Confirm",
cancel: "Cancel",
search: "Search...",
loading: "Loading...",
nodata: "No data"
}
};
var currentLocale = P("en");
var Locale = (t) => currentLocale(t);
var tt = (t) => () => i18n[currentLocale()][t] || t;
var Accordion = (p) => { var Accordion = (p) => {
const name = p.name || rand("acc"); const name = p.name || rand("acc");
return H(p.items, (it) => { return H(p.items, (it) => {
@@ -546,13 +569,13 @@
var Avatar = (p, c) => A("div", { class: "avatar" }, A("div", { class: p.class }, c)); var Avatar = (p, c) => A("div", { class: "avatar" }, A("div", { class: p.class }, c));
var AvatarGroup = (p, c) => A("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c); var AvatarGroup = (p, c) => A("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c);
var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) => { var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) => {
const query = P(get(value) || ""); const query = P(val(value) || "");
const filtered = P(() => filterBy(items, query())); const filtered = P(() => filterBy(items, query()));
const pick = (item) => { const pick = (item) => {
const display = getBy(item); const display = getBy(item);
const actual = typeof item === "string" ? item : item.value; const actual = typeof item === "string" ? item : item.value;
query(display); query(display);
if (isFn(value)) if (_(value))
value(actual); value(actual);
onselect?.(item); onselect?.(item);
hide(); hide();
@@ -565,7 +588,7 @@
left: A("span", { class: "icon-[lucide--search]" }), left: A("span", { class: "icon-[lucide--search]" }),
oninput: (e) => { oninput: (e) => {
query(e.target.value); query(e.target.value);
if (isFn(value)) if (_(value))
value(e.target.value); value(e.target.value);
} }
})), })),
@@ -591,8 +614,8 @@
const now = new Date; const now = new Date;
const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`; const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, "0")}-${String(now.getDate()).padStart(2, "0")}`;
const fmt = (d2) => `${d2.getFullYear()}-${String(d2.getMonth() + 1).padStart(2, "0")}-${String(d2.getDate()).padStart(2, "0")}`; const fmt = (d2) => `${d2.getFullYear()}-${String(d2.getMonth() + 1).padStart(2, "0")}-${String(d2.getDate()).padStart(2, "0")}`;
const rangeMode = () => get(p.range) === true; const rangeMode = () => val(p.range) === true;
const current = () => get(p.value); const current = () => val(p.value);
const selectDate = (date) => { const selectDate = (date) => {
const s = fmt(date); const s = fmt(date);
const v2 = current(); const v2 = current();
@@ -623,7 +646,7 @@
const HourSlider = ({ value: hVal, onChange: onH }) => A("div", { class: "flex-1" }, [ const HourSlider = ({ value: hVal, onChange: onH }) => A("div", { class: "flex-1" }, [
A("div", { class: "flex gap-2 items-center" }, [ A("div", { class: "flex gap-2 items-center" }, [
A("input", { type: "range", min: 0, max: 23, value: hVal, class: "range range-xs flex-1", oninput: (e) => onH(+e.target.value) }), A("input", { type: "range", min: 0, max: 23, value: hVal, class: "range range-xs flex-1", oninput: (e) => onH(+e.target.value) }),
A("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(get(hVal)).padStart(2, "0") + ":00") A("span", { class: "text-sm font-mono min-w-[48px] text-center" }, () => String(val(hVal)).padStart(2, "0") + ":00")
]) ])
]); ]);
return A("div", { return A("div", {
@@ -694,7 +717,7 @@
var ChatImage = (p, c) => A("div", { ...p, class: cls("chat-image avatar", p.class) }, A("div", { class: "w-10 rounded-full" }, typeof c === "string" ? A("img", { src: c, alt: "avatar" }) : c)); var ChatImage = (p, c) => A("div", { ...p, class: cls("chat-image avatar", p.class) }, A("div", { class: "w-10 rounded-full" }, typeof c === "string" ? A("img", { src: c, alt: "avatar" }) : c));
var Checkbox = (p) => A("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) }); var Checkbox = (p) => A("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) });
var Colorpicker = (p) => { var Colorpicker = (p) => {
const current = () => get(p.value) || "#000000"; const current = () => val(p.value) || "#000000";
return Dropdown({}, [ return Dropdown({}, [
DropdownButton({ class: "btn" }, [ DropdownButton({ class: "btn" }, [
A("div", { class: "size-5 rounded-sm", style: () => `background-color: ${current()}` }), A("div", { class: "size-5 rounded-sm", style: () => `background-color: ${current()}` }),
@@ -703,13 +726,13 @@
DropdownContent({ class: "p-0" }, ColorPalette({ DropdownContent({ class: "p-0" }, ColorPalette({
value: p.value, value: p.value,
onchange: (c) => { onchange: (c) => {
isFn(p.value) ? p.value(c) : p.onchange?.(c); _(p.value) ? p.value(c) : p.onchange?.(c);
} }
})) }))
]); ]);
}; };
var ColorPalette = (p) => { var ColorPalette = (p) => {
const current = () => get(p.value) || "#000000"; const current = () => val(p.value) || "#000000";
const palette = [ const palette = [
"#000", "#000",
"#1A1A1A", "#1A1A1A",
@@ -777,7 +800,7 @@
"#fae8ff" "#fae8ff"
]; ];
const pick = (c) => { const pick = (c) => {
isFn(p.value) ? p.value(c) : p.onchange?.(c); _(p.value) ? p.value(c) : p.onchange?.(c);
hide(); hide();
}; };
return A("div", { return A("div", {
@@ -796,9 +819,9 @@
}; };
var Datepicker = (p) => { var Datepicker = (p) => {
const displayValue = P(""); const displayValue = P("");
const rangeMode = () => get(p.range) === true; const rangeMode = () => val(p.range) === true;
T(() => { C(() => {
const v2 = get(p.value); const v2 = val(p.value);
if (!v2) if (!v2)
return displayValue(""); return displayValue("");
let text = ""; let text = "";
@@ -814,12 +837,12 @@
} }
displayValue(text); displayValue(text);
}); });
const handleChange = (val) => { const handleChange = (val2) => {
if (isFn(p.value)) if (_(p.value))
p.value(val); p.value(val2);
else else
p.onChange?.(val); p.onChange?.(val2);
if (!rangeMode() || val?.end != null) if (!rangeMode() || val2?.end != null)
hide(); hide();
}; };
return Dropdown({ class: cls("w-full", p.class) }, [ return Dropdown({ class: cls("w-full", p.class) }, [
@@ -838,7 +861,7 @@
onmousedown: (e) => { onmousedown: (e) => {
e.preventDefault(); e.preventDefault();
e.stopPropagation(); e.stopPropagation();
if (isFn(p.value)) if (_(p.value))
p.value(null); p.value(null);
else else
p.onChange?.(null); p.onChange?.(null);
@@ -855,7 +878,7 @@
]); ]);
}; };
var Drawer = (p, c) => div({ ...p, class: cls("drawer", p.class) }, c); var Drawer = (p, c) => div({ ...p, class: cls("drawer", p.class) }, c);
var DrawerToggle = (p) => input({ ...p, type: "checkbox", class: "drawer-toggle", checked: () => get(p.checked), onchange: (e) => isFn(p.checked) && p.checked(e.target.checked) }); var DrawerToggle = (p) => input({ ...p, type: "checkbox", class: "drawer-toggle", checked: () => val(p.checked), onchange: (e) => _(p.checked) && p.checked(e.target.checked) });
var DrawerContent = (p, c) => div({ ...p, class: cls("drawer-content", p.class) }, c); var DrawerContent = (p, c) => div({ ...p, class: cls("drawer-content", p.class) }, c);
var DrawerSide = (p, c) => div({ ...p, class: cls("drawer-side", p.class) }, c); var DrawerSide = (p, c) => div({ ...p, class: cls("drawer-side", p.class) }, c);
var DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls("drawer-overlay", p.class) }); var DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls("drawer-overlay", p.class) });
@@ -879,17 +902,17 @@
} }
const updated = [...files(), ...arr]; const updated = [...files(), ...arr];
files(updated); files(updated);
if (isFn(p.onselect)) if (_(p.onselect))
p.onselect(updated); p.onselect(updated);
else if (isFn(p.value)) else if (_(p.value))
p.value(updated); p.value(updated);
}; };
const remove = (idx) => { const remove = (idx) => {
const updated = files().filter((_2, i) => i !== idx); const updated = files().filter((_2, i) => i !== idx);
files(updated); files(updated);
if (isFn(p.onselect)) if (_(p.onselect))
p.onselect(updated); p.onselect(updated);
else if (isFn(p.value)) else if (_(p.value))
p.value(updated); p.value(updated);
}; };
return A("div", { class: cls("fieldset w-full p-0", p.class) }, [ return A("div", { class: cls("fieldset w-full p-0", p.class) }, [
@@ -944,7 +967,7 @@
const showPassword = P(false); const showPassword = P(false);
const isPassword = p.type === "password"; const isPassword = p.type === "password";
const pattern = rule ?? null; const pattern = rule ?? null;
const inputType = () => isPassword ? get(showPassword) ? "text" : "password" : p.type || "search"; const inputType = () => isPassword ? val(showPassword) ? "text" : "password" : p.type || "search";
return A("label", { class: float ? "floating-label" : "" }, [ return A("label", { class: float ? "floating-label" : "" }, [
float ? A("span", {}, label2) : null, float ? A("span", {}, label2) : null,
A("label", { pattern, class: () => cls("input validator", p.class) }, [ A("label", { pattern, class: () => cls("input validator", p.class) }, [
@@ -963,7 +986,7 @@
}; };
var Kbd = (p, c) => A("kbd", { ...p, class: cls("kbd", p.class) }, c); var Kbd = (p, c) => A("kbd", { ...p, class: cls("kbd", p.class) }, c);
var List = (p, c) => A("ul", { ...p, class: cls("list", p.class) }, c); var List = (p, c) => A("ul", { ...p, class: cls("list", p.class) }, c);
var ListRows = (p) => () => (get(p.items) || []).map((item, idx) => A("li", { class: cls("list-row", p.class, item?.class) }, typeof p.render === "function" ? p.render(item, idx) : item)); var ListRows = (p) => () => (val(p.items) || []).map((item, idx) => A("li", { class: cls("list-row", p.class, item?.class) }, typeof p.render === "function" ? p.render(item, idx) : item));
var Loading = (p, c) => A("span", { ...p, class: cls("loading loading-spinner", p.class) }, c); var Loading = (p, c) => A("span", { ...p, class: cls("loading loading-spinner", p.class) }, c);
var Menu = (p) => { var Menu = (p) => {
if (p.children !== undefined) if (p.children !== undefined)
@@ -971,7 +994,7 @@
const { items } = p; const { items } = p;
const render = (item) => item.children ? A("li", {}, A("details", { open: item.open || undefined }, [ const render = (item) => item.children ? A("li", {}, A("details", { open: item.open || undefined }, [
A("summary", {}, getBy(item)), A("summary", {}, getBy(item)),
A("ul", {}, H(() => get(item.children) || [], render)) A("ul", {}, H(() => val(item.children) || [], render))
])) : A("li", {}, A("a", { ])) : A("li", {}, A("a", {
href: item.href, href: item.href,
onclick: item.onclick ? (e) => { onclick: item.onclick ? (e) => {
@@ -980,17 +1003,17 @@
item.onclick(e); item.onclick(e);
} : null } : null
}, getBy(item))); }, getBy(item)));
return A("ul", { class: cls("menu", p.class) }, H(() => get(items) || [], render)); return A("ul", { class: cls("menu", p.class) }, H(() => val(items) || [], render));
}; };
var Modal = (p) => { var Modal = (p) => {
let dialogRef = null; let dialogRef = null;
T(() => { C(() => {
const isOpen = get(p.open); const isOpen = val(p.open);
if (!dialogRef) if (!dialogRef)
return; return;
isOpen ? dialogRef.showModal() : dialogRef.hide(); isOpen ? dialogRef.showModal() : dialogRef.hide();
}); });
const close = () => isFn(p.open) && p.open(false); const close = () => _(p.open) && p.open(false);
return A("dialog", { return A("dialog", {
...p, ...p,
ref: (el) => dialogRef = el, ref: (el) => dialogRef = el,
@@ -1012,17 +1035,17 @@
}; };
var Navbar = (p, c) => A("div", { ...p, class: cls("navbar", p.class) }, c); var Navbar = (p, c) => A("div", { ...p, class: cls("navbar", p.class) }, c);
var Progress = (p) => A("progress", { ...p, class: cls("progress", p.class) }); var Progress = (p) => A("progress", { ...p, class: cls("progress", p.class) });
var Radial = (p, c) => A("div", { class: cls("radial-progress", p.class), style: `--value:${get(p.value) ?? 0};`, role: "progressbar", "aria-valuenow": p.value }, c); var Radial = (p, c) => A("div", { class: cls("radial-progress", p.class), style: `--value:${val(p.value) ?? 0};`, role: "progressbar", "aria-valuenow": p.value }, c);
var Radio = (p) => A("input", { ...p, type: "radio", class: cls("radio", p.class) }); var Radio = (p) => A("input", { ...p, type: "radio", class: cls("radio", p.class) });
var Range = (p) => A("input", { ...p, type: "range", class: cls("range", p.class) }); var Range = (p) => A("input", { ...p, type: "range", class: cls("range", p.class) });
var Rating = (p, c) => A("div", { ...p, class: "rating" }, c); var Rating = (p, c) => A("div", { ...p, class: "rating" }, c);
var RatingItems = (p) => [...Array(p.count)].map((_2, i) => A("input", { class: cls("mask", p.class), name: p.name, type: "radio", checked: () => get(p.value) === i, onchange: () => isFn(p.value) ? p.value(i) : p.onchange?.(i) })); var RatingItems = (p) => [...Array(p.count)].map((_2, i) => A("input", { class: cls("mask", p.class), name: p.name, type: "radio", checked: () => val(p.value) === i, onchange: () => _(p.value) ? p.value(i) : p.onchange?.(i) }));
var Select = (p, c) => { var Select = (p, c) => {
if (c !== undefined) if (c !== undefined)
return A("select", { class: cls("select", p.class), ...p }, c); return A("select", { class: cls("select", p.class), ...p }, c);
const { label: label2, float, placeholder, placeholderDisabled = true, value, left, right, hint, items, keyFn, ...rest } = p; const { label: label2, float, placeholder, placeholderDisabled = true, value, left, right, hint, items, keyFn, ...rest } = p;
const opts = () => { const opts = () => {
const raw = get(items) || []; const raw = val(items) || [];
const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: "" }] : []; const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: "" }] : [];
return [...ph, ...raw]; return [...ph, ...raw];
}; };
@@ -1032,12 +1055,12 @@
!float && label2 ? A("span", { class: "label" }, label2) : null, !float && label2 ? A("span", { class: "label" }, label2) : null,
left ?? null, left ?? null,
A("select", { A("select", {
value: () => get(value), value: () => val(value),
onchange: (e) => isFn(value) ? value(e.target.value) : rest.onchange?.(e) onchange: (e) => _(value) ? value(e.target.value) : rest.onchange?.(e)
}, H(opts, (item) => { }, H(opts, (item) => {
const val = getBy(item, item.value !== undefined ? "value" : undefined); const val2 = getBy(item, item.value !== undefined ? "value" : undefined);
const lab = getBy(item, "label"); const lab = getBy(item, "label");
return A("option", { value: val, disabled: item.disabled || undefined }, lab); return A("option", { value: val2, disabled: item.disabled || undefined }, lab);
})), })),
right ?? null right ?? null
]), ]),
@@ -1056,14 +1079,14 @@
var Steps = (p, c) => A("ul", { ...p, class: cls("steps", p.class) }, c); var Steps = (p, c) => A("ul", { ...p, class: cls("steps", p.class) }, c);
var Step = (p, c) => A("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c); var Step = (p, c) => A("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c);
var Swap = (p, c) => A("label", { ...p, class: cls("swap", p.class) }, c); var Swap = (p, c) => A("label", { ...p, class: cls("swap", p.class) }, c);
var SwapToggle = (p) => A("input", { type: "checkbox", checked: () => get(p.value), onchange: (e) => isFn(p.value) && p.value(e.target.checked), class: p.class }); var SwapToggle = (p) => A("input", { type: "checkbox", checked: () => val(p.value), onchange: (e) => _(p.value) && p.value(e.target.checked), class: p.class });
var SwapOn = (p, c) => A("div", { ...p, class: cls("swap-on", p.class) }, c); var SwapOn = (p, c) => A("div", { ...p, class: cls("swap-on", p.class) }, c);
var SwapOff = (p, c) => A("div", { ...p, class: cls("swap-off", p.class) }, c); var SwapOff = (p, c) => A("div", { ...p, class: cls("swap-off", p.class) }, c);
var Table = (p, c) => A("table", { ...p, class: cls("table", p.class) }, c); var Table = (p, c) => A("table", { ...p, class: cls("table", p.class) }, c);
var TableItems = ({ items, columns = [], header = true }) => { var TableItems = ({ items, columns = [], header = true }) => {
const head = header !== false && columns.some((c) => c.label) ? A("thead", {}, A("tr", {}, columns.map((c) => A("th", { class: c.class }, c.label)))) : null; const head = header !== false && columns.some((c) => c.label) ? A("thead", {}, A("tr", {}, columns.map((c) => A("th", { class: c.class }, c.label)))) : null;
const body = A("tbody", {}, () => { const body = A("tbody", {}, () => {
const list = get(items) || []; const list = val(items) || [];
return list.map((it, idx) => A("tr", {}, columns.map((c) => { return list.map((it, idx) => A("tr", {}, columns.map((c) => {
const v2 = c.render ? c.render(it, idx) : it[c.key]; const v2 = c.render ? c.render(it, idx) : it[c.key];
return A("td", { class: c.class }, v2); return A("td", { class: c.class }, v2);
@@ -1077,16 +1100,16 @@
return A("div", { ...rest2, class: cls("tabs", className2) }, c); return A("div", { ...rest2, class: cls("tabs", className2) }, c);
} }
const { items, activeIndex, onClose, class: className, ...rest } = p; const { items, activeIndex, onClose, class: className, ...rest } = p;
const get2 = (x2) => isFn(x2) ? x2() : x2; const get = (x2) => _(x2) ? x2() : x2;
const closeH = onClose || (isFn(items) ? (idx, item) => { const closeH = onClose || (_(items) ? (idx, item) => {
const arr = get2(items); const arr = val(items);
const newArr = arr.filter((_2, i) => i !== idx); const newArr = arr.filter((_2, i) => i !== idx);
items(newArr); items(newArr);
if (activeIndex() >= newArr.length) if (activeIndex() >= newArr.length)
activeIndex(Math.max(0, newArr.length - 1)); activeIndex(Math.max(0, newArr.length - 1));
} : null); } : null);
return A("div", { ...rest, class: cls("tabs", className) }, () => { return A("div", { ...rest, class: cls("tabs", className) }, () => {
const list = get2(items) || []; const list = val(items) || [];
return list.flatMap((it, idx) => { return list.flatMap((it, idx) => {
const isActive = () => activeIndex() === idx; const isActive = () => activeIndex() === idx;
const button = A("button", { const button = A("button", {
@@ -1109,7 +1132,7 @@
const contentDiv = A("div", { const contentDiv = A("div", {
class: "tab-content bg-base-100 border-base-300 p-6", class: "tab-content bg-base-100 border-base-300 p-6",
style: () => `display: ${isActive() ? "block" : "none"};` style: () => `display: ${isActive() ? "block" : "none"};`
}, isFn(it.content) ? it.content() : it.content); }, _(it.content) ? it.content() : it.content);
return [button, contentDiv]; return [button, contentDiv];
}); });
}); });
@@ -1146,7 +1169,7 @@
}, 300); }, 300);
}; };
enterTimer = setTimeout(() => visible(true), 0); enterTimer = setTimeout(() => visible(true), 0);
const content = typeof message === "function" ? get(message) : message; const content = typeof message === "function" ? val(message) : message;
const msgNode = typeof content === "string" ? A("span", {}, content) : content; const msgNode = typeof content === "string" ? A("span", {}, content) : content;
return A("div", { return A("div", {
class: () => { class: () => {
@@ -1172,12 +1195,6 @@
}; };
var Toggle = (p) => A("input", { ...p, type: "checkbox", class: cls("toggle", p.class) }); var Toggle = (p) => A("input", { ...p, type: "checkbox", class: cls("toggle", p.class) });
var Tooltip = (p, c) => A("div", { ...p, class: cls("tooltip", p.class), "data-tip": p.tip }, c); var Tooltip = (p, c) => A("div", { ...p, class: cls("tooltip", p.class), "data-tip": p.tip }, c);
// sigpro-editor.js
var exports_sigpro_editor = {};
__export(exports_sigpro_editor, {
Editor: () => Editor
});
var Editor = (p) => { var Editor = (p) => {
const { value, class: extraClass } = p; const { value, class: extraClass } = p;
let editorRef = null; let editorRef = null;
@@ -1209,19 +1226,19 @@
if (!editorRef) if (!editorRef)
return; return;
const html = editorRef.innerHTML; const html = editorRef.innerHTML;
if (isFn(value)) if (_(value))
value(html); value(html);
else else
p.onchange?.(html); p.onchange?.(html);
triggerRefresh(); triggerRefresh();
}; };
const exec = (cmd, val = null) => { const exec = (cmd, val2 = null) => {
if (!editorRef) if (!editorRef)
return; return;
editorRef.focus(); editorRef.focus();
if (savedRange) if (savedRange)
restoreSelection(); restoreSelection();
document.execCommand(cmd, false, val); document.execCommand(cmd, false, val2);
savedRange = null; savedRange = null;
notify(); notify();
}; };
@@ -1250,7 +1267,7 @@
}; };
reader.readAsDataURL(file); reader.readAsDataURL(file);
}; };
const queryState = (cmd, val = null) => { const queryState = (cmd, val2 = null) => {
refreshTick(); refreshTick();
if (!editorRef || isSource()) if (!editorRef || isSource())
return false; return false;
@@ -1258,7 +1275,7 @@
if (cmd === "formatBlock") { if (cmd === "formatBlock") {
let node = window.getSelection().getRangeAt(0).commonAncestorContainer; let node = window.getSelection().getRangeAt(0).commonAncestorContainer;
while (node && node !== editorRef) { while (node && node !== editorRef) {
if (node.nodeType === 1 && node.tagName === val) if (node.nodeType === 1 && node.tagName === val2)
return true; return true;
node = node.parentNode; node = node.parentNode;
} }
@@ -1354,7 +1371,7 @@
ref: (el) => { ref: (el) => {
if (!editorRef && el) { if (!editorRef && el) {
editorRef = el; editorRef = el;
el.innerHTML = get(value) || ""; el.innerHTML = val(value) || "";
document.execCommand("defaultParagraphSeparator", false, "br"); document.execCommand("defaultParagraphSeparator", false, "br");
el.addEventListener("click", (e) => { el.addEventListener("click", (e) => {
const container = e.target.closest(".resizable-img-container"); const container = e.target.closest(".resizable-img-container");
@@ -1418,42 +1435,10 @@
]); ]);
}; };
// sigpro-locale.js
var i18n = {
es: {
close: "Cerrar",
confirm: "Confirmar",
cancel: "Cancelar",
search: "Buscar...",
loading: "Cargando...",
nodata: "Sin datos"
},
en: {
close: "Close",
confirm: "Confirm",
cancel: "Cancel",
search: "Search...",
loading: "Loading...",
nodata: "No data"
}
};
var currentLocale = P("es");
var Locale = (t) => currentLocale(t);
var tt = (t) => () => i18n[currentLocale()][t] || t;
// index.js // index.js
var Components = { var Components = { ...exports_sigpro_ui };
...exports_sigpro_ui,
...exports_sigpro_editor
};
var Utils = {
Locale,
tt,
hide,
get
};
if (typeof window !== "undefined") { if (typeof window !== "undefined") {
Object.entries({ ...Components, ...Utils }).forEach(([name, value]) => { Object.entries({ ...Components }).forEach(([name, value]) => {
Object.defineProperty(window, name, { Object.defineProperty(window, name, {
value, value,
writable: false, writable: false,

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@@ -11,7 +11,7 @@
<div class="text-xl text-base-content/60 max-w-3xl mx-auto mb-10 leading-relaxed italic text-balance font-light !text-center w-full">"Atomic components for high-performance interfaces. Zero-boilerplate, pure reactivity."</div> <div class="text-xl text-base-content/60 max-w-3xl mx-auto mb-10 leading-relaxed italic text-balance font-light !text-center w-full">"Atomic components for high-performance interfaces. Zero-boilerplate, pure reactivity."</div>
<div class="flex flex-wrap justify-center gap-4 w-full"> <div class="flex flex-wrap justify-center gap-4 w-full">
<a href="#/install" class="btn btn-secondary btn-lg shadow-xl shadow-secondary/20 group px-10 border-none text-secondary-content">View Components <span class="group-hover:translate-x-1 transition-transform inline-block">→</span></a> <a href="#/install" class="btn btn-secondary btn-lg shadow-xl shadow-secondary/20 group px-10 border-none text-secondary-content">View Components <span class="group-hover:translate-x-1 transition-transform inline-block">→</span></a>
<button onclick="window.open('https://github.com/natxocc/sigpro-ui')" class="btn btn-outline btn-lg border-base-300 hover:bg-base-300 hover:text-base-content">GitHub</button> <button onclick="window.open('https://git.natxocc.com/natxocc/sigpro-ui')" class="btn btn-outline btn-lg border-base-300 hover:bg-base-300 hover:text-base-content">Gitea</button>
</div> </div>
</div> </div>
<div class="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-0 opacity-10 pointer-events-none"> <div class="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-0 opacity-10 pointer-events-none">

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

24
index.d.ts vendored
View File

@@ -1,4 +1,3 @@
declare module 'sigpro-ui' {
type Signal<T> = { type Signal<T> = {
(): T; (): T;
(value: T | ((prev: T) => T)): void; (value: T | ((prev: T) => T)): void;
@@ -14,6 +13,17 @@ declare module 'sigpro-ui' {
[key: string]: any; [key: string]: any;
} }
// ---------- helpers ----------
const hide: () => void;
const i18n: {
es: Record<string, string>;
en: Record<string, string>;
};
const currentLocale: Signal<string>;
const Locale: (locale: string) => void;
const tt: (key: string) => () => string;
// ---------- components ----------
interface AccordionItem { interface AccordionItem {
title?: string | (() => string); title?: string | (() => string);
content?: string | (() => string); content?: string | (() => string);
@@ -153,6 +163,12 @@ declare module 'sigpro-ui' {
interface DropdownContentProps extends BaseProps { } interface DropdownContentProps extends BaseProps { }
function DropdownContent(props: DropdownContentProps, children?: ComponentChildren): Node; function DropdownContent(props: DropdownContentProps, children?: ComponentChildren): Node;
interface EditorProps extends BaseProps {
value?: Signal<string> | string;
onchange?: (value: string) => void;
}
function Editor(props: EditorProps): Node;
interface FabProps extends BaseProps { interface FabProps extends BaseProps {
icon?: string; icon?: string;
} }
@@ -239,7 +255,7 @@ declare module 'sigpro-ui' {
function Progress(props: ProgressProps): Node; function Progress(props: ProgressProps): Node;
interface RadialProps extends BaseProps { interface RadialProps extends BaseProps {
value?: number; value?: Signal<number> | number;
} }
function Radial(props: RadialProps, children?: ComponentChildren): Node; function Radial(props: RadialProps, children?: ComponentChildren): Node;
@@ -414,6 +430,7 @@ declare module 'sigpro-ui' {
Dropdown: typeof Dropdown; Dropdown: typeof Dropdown;
DropdownButton: typeof DropdownButton; DropdownButton: typeof DropdownButton;
DropdownContent: typeof DropdownContent; DropdownContent: typeof DropdownContent;
Editor: typeof Editor;
Fab: typeof Fab; Fab: typeof Fab;
Fieldset: typeof Fieldset; Fieldset: typeof Fieldset;
Fileinput: typeof Fileinput; Fileinput: typeof Fileinput;
@@ -458,7 +475,7 @@ declare module 'sigpro-ui' {
export { Components }; export { Components };
export default Components; export default Components;
}
declare global { declare global {
const Accordion: typeof import('sigpro-ui').Accordion; const Accordion: typeof import('sigpro-ui').Accordion;
@@ -491,6 +508,7 @@ declare global {
const Dropdown: typeof import('sigpro-ui').Dropdown; const Dropdown: typeof import('sigpro-ui').Dropdown;
const DropdownButton: typeof import('sigpro-ui').DropdownButton; const DropdownButton: typeof import('sigpro-ui').DropdownButton;
const DropdownContent: typeof import('sigpro-ui').DropdownContent; const DropdownContent: typeof import('sigpro-ui').DropdownContent;
const Editor: typeof import('sigpro-ui').Editor;
const Fab: typeof import('sigpro-ui').Fab; const Fab: typeof import('sigpro-ui').Fab;
const Fieldset: typeof import('sigpro-ui').Fieldset; const Fieldset: typeof import('sigpro-ui').Fieldset;
const Fileinput: typeof import('sigpro-ui').Fileinput; const Fileinput: typeof import('sigpro-ui').Fileinput;

View File

@@ -1,20 +1,10 @@
import * as All from './sigpro-ui.js'; import * as All from './sigpro-ui.js';
import * as Editor from './sigpro-editor.js';
import { Locale, tt } from './sigpro-locale.js';
import { hide, get } from './sigpro-helpers.js';
export const Components = { export const Components = { ...All };
...All,
...Editor,
};
export const Utils = {
Locale, tt, hide, get
};
if (typeof window !== 'undefined') { if (typeof window !== 'undefined') {
Object.entries({ ...Components, ...Utils }).forEach(([name, value]) => { Object.entries({ ...Components}).forEach(([name, value]) => {
Object.defineProperty(window, name, { Object.defineProperty(window, name, {
value, value,
writable: false, writable: false,

View File

@@ -45,8 +45,8 @@
"scripts": { "scripts": {
"del": "bun pm cache rm && rm -f bun.lockb $$ rm -f bun.lock", "del": "bun pm cache rm && rm -f bun.lockb $$ rm -f bun.lock",
"clean": "rm -rf ./dist ./css/*.css ./docs/*.js ./docs/*.css", "clean": "rm -rf ./dist ./css/*.css ./docs/*.js ./docs/*.css",
"build:css": "tailwindcss -i ./sigpro-css.css -o ./dist/sigpro-ui.css --content './src/**/*.js' && du -h ./dist/sigpro-ui.css", "build:css": "tailwindcss -i ./sigpro-ui.css -o ./dist/sigpro-ui.css --content './src/**/*.js' && du -h ./dist/sigpro-ui.css",
"build:cssmin": "tailwindcss -i ./sigpro-css.css -o ./dist/sigpro-ui.min.css --content './src/**/*.js' --minify && du -h ./dist/sigpro-ui.css", "build:cssmin": "tailwindcss -i ./sigpro-ui.css -o ./dist/sigpro-ui.min.css --content './src/**/*.js' --minify && du -h ./dist/sigpro-ui.css",
"build:js": "bun run build:js:iife && bun run build:js:esm", "build:js": "bun run build:js:iife && bun run build:js:esm",
"build:js:iife": "bun build ./index.js --bundle --outfile=./dist/sigpro-ui.js --format=iife --global-name=SigProUI", "build:js:iife": "bun build ./index.js --bundle --outfile=./dist/sigpro-ui.js --format=iife --global-name=SigProUI",
"build:js:iife:min": "bun build ./index.js --bundle --outfile=./dist/sigpro-ui.min.js --format=iife --global-name=SigProUI --minify", "build:js:iife:min": "bun build ./index.js --bundle --outfile=./dist/sigpro-ui.min.js --format=iife --global-name=SigProUI --minify",

View File

@@ -1,201 +0,0 @@
import { h, $ } from "sigpro"
import { get, cls, isFn } from "./sigpro-helpers.js"
export const Editor = (p) => {
const { value, class: extraClass } = p
let editorRef = null
let savedRange = null
const isSource = $(false)
const source = $("")
const count = $(0)
const refreshTick = $(0)
const showEmojis = $(false)
const emojis = ["😀", "😊", "😉", "🧐", "😮", "🤔", "😅", "😂", "😍", "😘", "🥰", "👍", "👎", "👌", "🤝", "🤞", "👋", "👏", "🙌", "🙏", "💪", "☝️", "👇", "👈", "👉", "🖕", "✅", "⚠️", "🚀", "📢", "✉️", "❤️"]
const saveSelection = () => {
const sel = window.getSelection()
if (sel.getRangeAt && sel.rangeCount) savedRange = sel.getRangeAt(0)
}
const restoreSelection = () => {
if (savedRange) {
const sel = window.getSelection()
sel.removeAllRanges()
sel.addRange(savedRange)
}
}
const triggerRefresh = () => {
refreshTick(refreshTick() + 1)
if (editorRef) count(editorRef.innerText.length)
}
const notify = () => {
if (!editorRef) return
const html = editorRef.innerHTML
if (isFn(value)) value(html)
else p.onchange?.(html)
triggerRefresh()
}
const exec = (cmd, val = null) => {
if (!editorRef) return
editorRef.focus()
if (savedRange) restoreSelection()
document.execCommand(cmd, false, val)
savedRange = null
notify()
}
const openLightbox = (src) => {
const overlay = document.createElement('div')
overlay.style = `position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.9);z-index:9999;display:flex;align-items:center;justify-content:center;cursor:zoom-out;`
const img = document.createElement('img')
img.src = src
img.style = `max-width:95%;max-height:95%;box-shadow:0 0 30px rgba(0,0,0,0.5);border-radius:4px;`
overlay.onclick = () => document.body.removeChild(overlay)
overlay.appendChild(img)
document.body.appendChild(overlay)
}
const handleUpload = (file) => {
if (!file) return
const reader = new FileReader()
reader.onload = (re) => {
if (file.type.startsWith('image/')) {
const imgHtml = `<div style="display:inline-block; resize:both; overflow:hidden; vertical-align:bottom; line-height:0; width:200px; height:auto; border:1px dashed #ccc; padding:2px; cursor:pointer;" class="resizable-img-container"><img src="${re.target.result}" style="width:100%; height:100%; object-fit:contain; pointer-events:none;"></div>&nbsp;`
exec("insertHTML", imgHtml)
} else {
const linkHtml = `<a href="${re.target.result}" download="${file.name}" contenteditable="false" style="display:inline-flex; align-items:center; gap:5px; padding:4px 8px; border:1px solid #ccc; border-radius:4px; background:#f9f9f9; text-decoration:none; color:#333; font-size:12px; margin:2px; cursor:pointer;"><span class="icon-[lucide--paperclip] w-3 h-3"></span>${file.name}</a>&nbsp;`
exec("insertHTML", linkHtml)
}
}
reader.readAsDataURL(file)
}
const queryState = (cmd, val = null) => {
refreshTick(); if (!editorRef || isSource()) return false
try {
if (cmd === 'formatBlock') {
let node = window.getSelection().getRangeAt(0).commonAncestorContainer
while (node && node !== editorRef) {
if (node.nodeType === 1 && node.tagName === val) return true
node = node.parentNode
}
return false
}
return document.queryCommandState(cmd)
} catch (e) { return false }
}
const toolbar = h("div", { class: "flex flex-wrap items-center gap-1 p-2 border-b border-base-300 bg-base-200 sticky top-0 z-20" }, [
h("div", { class: "flex flex-wrap gap-1 flex-1 items-center" }, [
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('bold') ? 'btn-active bg-primary/20' : ''}`, onclick: () => exec("bold") }, h("span", { class: "icon-[lucide--bold]" })),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('italic') ? 'btn-active bg-primary/20' : ''}`, onclick: () => exec("italic") }, h("span", { class: "icon-[lucide--italic]" })),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('underline') ? 'btn-active bg-primary/20' : ''}`, onclick: () => exec("underline") }, h("span", { class: "icon-[lucide--underline]" })),
h("input", { type: "color", class: "w-5 h-5 p-0 border-0 bg-transparent cursor-pointer", oninput: (e) => exec("foreColor", e.target.value) }),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", {
type: "button",
class: "btn btn-ghost btn-xs",
onclick: () => exec("justifyLeft")
}, h("span", { class: "icon-[lucide--align-left]" })),
h("button", {
type: "button",
class: "btn btn-ghost btn-xs",
onclick: () => exec("justifyCenter")
}, h("span", { class: "icon-[lucide--align-center]" })),
h("button", {
type: "button",
class: "btn btn-ghost btn-xs",
onclick: () => exec("justifyRight")
}, h("span", { class: "icon-[lucide--align-right]" })),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("insertUnorderedList") }, h("span", { class: "icon-[lucide--list]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("insertOrderedList") }, h("span", { class: "icon-[lucide--list-ordered]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("outdent") }, h("span", { class: "icon-[lucide--indent-decrease]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("indent") }, h("span", { class: "icon-[lucide--indent-increase]" })),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('formatBlock', 'BLOCKQUOTE') ? 'btn-active' : ''}`, onclick: () => exec("formatBlock", queryState('formatBlock', 'BLOCKQUOTE') ? 'P' : 'BLOCKQUOTE') }, h("span", { class: "icon-[lucide--quote]" })),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => { const url = window.prompt('URL:'); if (url) exec("createLink", url) } }, h("span", { class: "icon-[lucide--link]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => { const input = document.createElement('input'); input.type = 'file'; input.onchange = (e) => handleUpload(e.target.files[0]); input.click(); } }, h("span", { class: "icon-[lucide--paperclip]" })),
h("div", { class: "relative" }, [
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: (e) => { e.stopPropagation(); saveSelection(); showEmojis(!showEmojis()); } }, h("span", { class: "icon-[lucide--smile]" })),
h("div", { class: "absolute top-full left-0 mt-1 p-2 bg-base-100 border border-base-300 shadow-xl rounded-box w-52 z-50 flex flex-wrap gap-1", style: () => showEmojis() ? "display:flex" : "display:none" }, emojis.map(emo => h("span", { class: "cursor-pointer hover:bg-base-200 p-1 rounded text-lg", onclick: (e) => { e.stopPropagation(); exec("insertText", emo); showEmojis(false); } }, emo)))
]),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("undo") }, h("span", { class: "icon-[lucide--undo-2]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("redo") }, h("span", { class: "icon-[lucide--redo-2]" })),
]),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${isSource() ? 'btn-active' : ''}`, onclick: () => { if (!isSource()) source(editorRef?.innerHTML || ""); else if (editorRef) { editorRef.innerHTML = source(); notify(); }; isSource(!isSource()) } }, h("span", { class: "icon-[lucide--code-2]" }))
])
if (typeof document !== 'undefined' && !document.getElementById('editor-styles')) {
const style = document.createElement('style')
style.id = 'editor-styles'
style.textContent = `
[contenteditable="true"] div,
[contenteditable="true"] p {
margin: 0;
padding: 0;
}
`
document.head.appendChild(style)
}
return h("div", { class: cls("border border-base-300 rounded-box bg-base-100 overflow-hidden shadow-sm flex flex-col", extraClass) }, [
toolbar,
h("div", { class: "relative flex-1 flex flex-col", onclick: () => showEmojis(false) }, [
h("div", {
ref: el => {
if (!editorRef && el) {
editorRef = el; el.innerHTML = get(value) || "";
document.execCommand("defaultParagraphSeparator", false, "br");
el.addEventListener('click', (e) => {
const container = e.target.closest('.resizable-img-container');
if (container) { const img = container.querySelector('img'); if (img) openLightbox(img.src); }
});
}
},
style: () => `min-height:22rem;${isSource() ? 'display:none' : ''}`,
class: "p-4 outline-none text-base-content leading-relaxed [&>div]:m-0 [&>p]:m-0 [&>div]:min-h-[1em] [&_.resizable-img-container]:hover:border-primary [&_blockquote]:border-l-4 [&_blockquote]:border-base-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_ul]:list-disc [&_ul]:pl-8 [&_ol]:list-decimal [&_ol]:pl-8",
contenteditable: "true",
oninput: notify,
onkeydown: (e) => { if (e.key === 'Tab') { e.preventDefault(); exec("indent"); } },
onkeyup: () => { triggerRefresh(); saveSelection(); },
onclick: (e) => { triggerRefresh(); saveSelection(); e.stopPropagation(); },
onmouseup: () => { notify(); saveSelection(); },
onpaste: (e) => {
e.preventDefault();
const text = e.clipboardData.getData('text/plain');
exec('insertText', text);
},
ondragover: (e) => e.preventDefault(),
ondrop: (e) => { e.preventDefault(); handleUpload(e.dataTransfer.files[0]) }
}),
h("textarea", {
class: "w-full flex-1 min-h-[22rem] p-4 outline-none font-mono text-sm bg-base-200 border-0",
style: () => isSource() ? '' : 'display:none',
value: source,
oninput: (e) => { source(e.target.value); if (editorRef) editorRef.innerHTML = e.target.value; p.onchange?.(e.target.value); }
})
]),
h("div", { class: "px-3 py-1 border-t border-base-300 bg-base-100/50 text-[10px] text-right text-base-content/60 italic" }, [
h("span", () => `${count()}`)
])
])
}

View File

@@ -1,8 +0,0 @@
// Helpers
export const get = val => typeof val === "function" ? val() : val;
export const getBy = (item, field = 'label') => (item && typeof item === 'object') ? item[field] : item;
export const cls = (...classes) => classes.filter(Boolean).join(' ').trim();
export const isFn = f => typeof f === "function";
export const filterBy = (items, query, field = 'label', q = String(query).toLowerCase()) => !query ? get(items) : get(items).filter(item => String(item && typeof item === 'object' ? item[field] : item).toLowerCase().includes(q));
export const rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`
export const hide = () => document.activeElement?.blur()

View File

@@ -1,62 +0,0 @@
// core/utils.js
import { $, h } from "sigpro";
export const val = t => typeof t === "function" ? t() : t;
export const ui = (baseClass, additionalClassOrFn) =>
typeof additionalClassOrFn === "function"
? () => `${baseClass} ${additionalClassOrFn() || ""}`.trim()
: `${baseClass} ${additionalClassOrFn || ""}`.trim();
export const getIcon = (icon) => {
if (!icon) return null;
if (typeof icon === 'function') {
return h("span", { class: "mr-1" }, icon());
}
if (typeof icon === 'object') {
return h("span", { class: "mr-1" }, icon);
}
if (typeof icon === 'string') {
const parts = icon.trim().split(/\s+/);
const hasRight = parts[parts.length - 1] === 'right';
const iconClass = hasRight ? parts.slice(0, -1).join(' ') : icon;
const spacing = hasRight ? 'ml-1' : 'mr-1';
if (iconClass && !iconClass.startsWith('icon-[') && !iconClass.includes('--')) {
return h("span", { class: spacing }, iconClass);
}
return h("span", { class: `${iconClass} ${spacing}`.trim() });
}
return null;
};
export const i18n = {
es: {
close: "Cerrar",
confirm: "Confirmar",
cancel: "Cancelar",
search: "Buscar...",
loading: "Cargando...",
nodata: "Sin datos"
},
en: {
close: "Close",
confirm: "Confirm",
cancel: "Cancel",
search: "Search...",
loading: "Loading...",
nodata: "No data"
}
};
export const currentLocale = $("es");
// Export design
export const Locale = t => currentLocale(t);
export const tt = t => () => i18n[currentLocale()][t] || t;

View File

@@ -1,7 +1,39 @@
// All base components // All base components
import { h, each, watch, when, mount, $ } from "sigpro"; import { h, each, watch, when, mount, $, isFunc } from "sigpro";
import { get, getBy, cls, isFn, filterBy, rand, hide } from "./sigpro-helpers.js"
// Helpers
const val = val => typeof val === "function" ? val() : val;
const getBy = (item, field = 'label') => (item && typeof item === 'object') ? item[field] : item;
const cls = (...classes) => classes.filter(Boolean).join(' ').trim();
const filterBy = (items, query, field = 'label', q = String(query).toLowerCase()) => !query ? val(items) : val(items).filter(item => String(item && typeof item === 'object' ? item[field] : item).toLowerCase().includes(q));
const rand = (r) => `${r}-${Math.random().toString(36).slice(2, 9)}`
export const hide = () => document.activeElement?.blur()
// Locales
export const i18n = {
es: {
close: "Cerrar",
confirm: "Confirmar",
cancel: "Cancelar",
search: "Buscar...",
loading: "Cargando...",
nodata: "Sin datos"
},
en: {
close: "Close",
confirm: "Confirm",
cancel: "Cancel",
search: "Search...",
loading: "Loading...",
nodata: "No data"
}
};
export const currentLocale = $("en");
export const Locale = t => currentLocale(t);
export const tt = t => () => i18n[currentLocale()][t] || t;
// Components
export const Accordion = (p) => { export const Accordion = (p) => {
const name = p.name || rand('acc') const name = p.name || rand('acc')
return each(p.items, (it) => { return each(p.items, (it) => {
@@ -16,14 +48,14 @@ export const Alert = (p, c) => h("div", { ...p, class: cls("alert", p.class) },
export const Avatar = (p, c) => h("div", { class: "avatar" }, h('div', { class: p.class }, c)); export const Avatar = (p, c) => h("div", { class: "avatar" }, h('div', { class: p.class }, c));
export const AvatarGroup = (p, c) => h("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c); export const AvatarGroup = (p, c) => h("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c);
export const Autocomplete = ({ items, value, onselect, placeholder = '...', ...props }) => { export const Autocomplete = ({ items, value, onselect, placeholder = '...', ...props }) => {
const query = $(get(value) || '') const query = $(val(value) || '')
const filtered = $(() => filterBy(items, query())) const filtered = $(() => filterBy(items, query()))
const pick = (item) => { const pick = (item) => {
const display = getBy(item) const display = getBy(item)
const actual = typeof item === 'string' ? item : item.value const actual = typeof item === 'string' ? item : item.value
query(display) query(display)
if (isFn(value)) value(actual) if (isFunc(value)) value(actual)
onselect?.(item) onselect?.(item)
hide() hide()
} }
@@ -37,7 +69,7 @@ export const Autocomplete = ({ items, value, onselect, placeholder = '...', ...p
left: h('span', { class: 'icon-[lucide--search]' }), left: h('span', { class: 'icon-[lucide--search]' }),
oninput: (e) => { oninput: (e) => {
query(e.target.value) query(e.target.value)
if (isFn(value)) value(e.target.value) if (isFunc(value)) value(e.target.value)
} }
}) })
), ),
@@ -70,8 +102,8 @@ export const Calendar = (p) => {
const now = new Date() const now = new Date()
const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}` const todayStr = `${now.getFullYear()}-${String(now.getMonth() + 1).padStart(2, '0')}-${String(now.getDate()).padStart(2, '0')}`
const fmt = d => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}` const fmt = d => `${d.getFullYear()}-${String(d.getMonth() + 1).padStart(2, '0')}-${String(d.getDate()).padStart(2, '0')}`
const rangeMode = () => get(p.range) === true const rangeMode = () => val(p.range) === true
const current = () => get(p.value) const current = () => val(p.value)
const selectDate = (date) => { const selectDate = (date) => {
const s = fmt(date) const s = fmt(date)
const v = current() const v = current()
@@ -93,7 +125,7 @@ export const Calendar = (p) => {
const HourSlider = ({ value: hVal, onChange: onH }) => h('div', { class: 'flex-1' }, [ const HourSlider = ({ value: hVal, onChange: onH }) => h('div', { class: 'flex-1' }, [
h('div', { class: 'flex gap-2 items-center' }, [ h('div', { class: 'flex gap-2 items-center' }, [
h('input', { type: 'range', min: 0, max: 23, value: hVal, class: 'range range-xs flex-1', oninput: e => onH(+e.target.value) }), h('input', { type: 'range', min: 0, max: 23, value: hVal, class: 'range range-xs flex-1', oninput: e => onH(+e.target.value) }),
h('span', { class: 'text-sm font-mono min-w-[48px] text-center' }, () => String(get(hVal)).padStart(2, '0') + ':00') h('span', { class: 'text-sm font-mono min-w-[48px] text-center' }, () => String(val(hVal)).padStart(2, '0') + ':00')
]) ])
]) ])
return h('div', { return h('div', {
@@ -165,7 +197,7 @@ export const ChatHeader = (p, c) => h("div", { ...p, class: cls("chat-header", p
export const ChatImage = (p, c) => h("div", { ...p, class: cls("chat-image avatar", p.class) }, h("div", { class: "w-10 rounded-full" }, typeof c === "string" ? h("img", { src: c, alt: "avatar" }) : c)); export const ChatImage = (p, c) => h("div", { ...p, class: cls("chat-image avatar", p.class) }, h("div", { class: "w-10 rounded-full" }, typeof c === "string" ? h("img", { src: c, alt: "avatar" }) : c));
export const Checkbox = (p) => h("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) }); export const Checkbox = (p) => h("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) });
export const Colorpicker = (p) => { export const Colorpicker = (p) => {
const current = () => get(p.value) || '#000000' const current = () => val(p.value) || '#000000'
return Dropdown({}, [ return Dropdown({}, [
DropdownButton({ class: 'btn' }, [ DropdownButton({ class: 'btn' }, [
h('div', { class: 'size-5 rounded-sm', style: () => `background-color: ${current()}` }), h('div', { class: 'size-5 rounded-sm', style: () => `background-color: ${current()}` }),
@@ -173,13 +205,13 @@ export const Colorpicker = (p) => {
]), ]),
DropdownContent({ class: 'p-0' }, DropdownContent({ class: 'p-0' },
ColorPalette({ ColorPalette({
value: p.value, onchange: (c) => { isFn(p.value) ? p.value(c) : p.onchange?.(c) } value: p.value, onchange: (c) => { isFunc(p.value) ? p.value(c) : p.onchange?.(c) }
}) })
) )
]) ])
} }
export const ColorPalette = (p) => { export const ColorPalette = (p) => {
const current = () => get(p.value) || '#000000' const current = () => val(p.value) || '#000000'
const palette = [ const palette = [
'#000', '#1A1A1A', '#333', '#4D4D4D', '#666', '#808080', '#B3B3B3', '#FFF', '#000', '#1A1A1A', '#333', '#4D4D4D', '#666', '#808080', '#B3B3B3', '#FFF',
'#450a0a', '#7f1d1d', '#991b1b', '#b91c1c', '#dc2626', '#ef4444', '#f87171', '#fca5a5', '#450a0a', '#7f1d1d', '#991b1b', '#b91c1c', '#dc2626', '#ef4444', '#f87171', '#fca5a5',
@@ -191,7 +223,7 @@ export const ColorPalette = (p) => {
'#2e1065', '#4c1d95', '#6d28d9', '#7c3aed', '#8b5cf6', '#a855f7', '#d946ef', '#fae8ff' '#2e1065', '#4c1d95', '#6d28d9', '#7c3aed', '#8b5cf6', '#a855f7', '#d946ef', '#fae8ff'
] ]
const pick = (c) => { const pick = (c) => {
isFn(p.value) ? p.value(c) : p.onchange?.(c) isFunc(p.value) ? p.value(c) : p.onchange?.(c)
hide() hide()
} }
@@ -211,10 +243,10 @@ export const ColorPalette = (p) => {
} }
export const Datepicker = (p) => { export const Datepicker = (p) => {
const displayValue = $("") const displayValue = $("")
const rangeMode = () => get(p.range) === true const rangeMode = () => val(p.range) === true
watch(() => { watch(() => {
const v = get(p.value) const v = val(p.value)
if (!v) return displayValue("") if (!v) return displayValue("")
let text = "" let text = ""
if (typeof v === "string") { if (typeof v === "string") {
@@ -231,7 +263,7 @@ export const Datepicker = (p) => {
}) })
const handleChange = (val) => { const handleChange = (val) => {
if (isFn(p.value)) p.value(val) if (isFunc(p.value)) p.value(val)
else p.onChange?.(val) else p.onChange?.(val)
if (!rangeMode() || val?.end != null) hide() if (!rangeMode() || val?.end != null) hide()
} }
@@ -252,7 +284,7 @@ export const Datepicker = (p) => {
onmousedown: (e) => { onmousedown: (e) => {
e.preventDefault() e.preventDefault()
e.stopPropagation() e.stopPropagation()
if (isFn(p.value)) p.value(null) if (isFunc(p.value)) p.value(null)
else p.onChange?.(null) else p.onChange?.(null)
displayValue("") // Forzar limpieza visual inmediata displayValue("") // Forzar limpieza visual inmediata
} }
@@ -269,7 +301,7 @@ export const Datepicker = (p) => {
]) ])
} }
export const Drawer = (p, c) => div({ ...p, class: cls('drawer', p.class) }, c) export const Drawer = (p, c) => div({ ...p, class: cls('drawer', p.class) }, c)
export const DrawerToggle = (p) => input({ ...p, type: 'checkbox', class: 'drawer-toggle', checked: () => get(p.checked), onchange: (e) => isFn(p.checked) && p.checked(e.target.checked) }) export const DrawerToggle = (p) => input({ ...p, type: 'checkbox', class: 'drawer-toggle', checked: () => val(p.checked), onchange: (e) => isFunc(p.checked) && p.checked(e.target.checked) })
export const DrawerContent = (p, c) => div({ ...p, class: cls('drawer-content', p.class) }, c) export const DrawerContent = (p, c) => div({ ...p, class: cls('drawer-content', p.class) }, c)
export const DrawerSide = (p, c) => div({ ...p, class: cls('drawer-side', p.class) }, c) export const DrawerSide = (p, c) => div({ ...p, class: cls('drawer-side', p.class) }, c)
export const DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls('drawer-overlay', p.class) }) export const DrawerOverlay = (p) => label({ ...p, for: p.for, class: cls('drawer-overlay', p.class) })
@@ -293,15 +325,15 @@ export const Fileinput = (p) => {
} }
const updated = [...files(), ...arr] const updated = [...files(), ...arr]
files(updated) files(updated)
if (isFn(p.onselect)) p.onselect(updated) if (isFunc(p.onselect)) p.onselect(updated)
else if (isFn(p.value)) p.value(updated) else if (isFunc(p.value)) p.value(updated)
} }
const remove = (idx) => { const remove = (idx) => {
const updated = files().filter((_, i) => i !== idx) const updated = files().filter((_, i) => i !== idx)
files(updated) files(updated)
if (isFn(p.onselect)) p.onselect(updated) if (isFunc(p.onselect)) p.onselect(updated)
else if (isFn(p.value)) p.value(updated) else if (isFunc(p.value)) p.value(updated)
} }
return h('div', { class: cls('fieldset w-full p-0', p.class) }, [ return h('div', { class: cls('fieldset w-full p-0', p.class) }, [
h('label', { h('label', {
@@ -354,7 +386,7 @@ export const Input = (p) => {
const pattern = rule ?? null; const pattern = rule ?? null;
const inputType = () => isPassword const inputType = () => isPassword
? (get(showPassword) ? 'text' : 'password') ? (val(showPassword) ? 'text' : 'password')
: (p.type || 'search'); : (p.type || 'search');
return h("label", { class: float ? 'floating-label' : '' }, [ return h("label", { class: float ? 'floating-label' : '' }, [
@@ -376,7 +408,7 @@ export const Input = (p) => {
}; };
export const Kbd = (p, c) => h("kbd", { ...p, class: cls("kbd", p.class) }, c); export const Kbd = (p, c) => h("kbd", { ...p, class: cls("kbd", p.class) }, c);
export const List = (p, c) => h('ul', { ...p, class: cls('list', p.class) }, c) export const List = (p, c) => h('ul', { ...p, class: cls('list', p.class) }, c)
export const ListRows = (p) => () => (get(p.items) || []).map((item, idx) => h('li', { class: cls('list-row', p.class, item?.class) }, typeof p.render === 'function' ? p.render(item, idx) : item)) export const ListRows = (p) => () => (val(p.items) || []).map((item, idx) => h('li', { class: cls('list-row', p.class, item?.class) }, typeof p.render === 'function' ? p.render(item, idx) : item))
export const Loading = (p, c) => h("span", { ...p, class: cls("loading loading-spinner", p.class) }, c); export const Loading = (p, c) => h("span", { ...p, class: cls("loading loading-spinner", p.class) }, c);
export const Menu = (p) => { export const Menu = (p) => {
if (p.children !== undefined) return h('ul', { class: cls('menu', p.class), ...p }, p.children) if (p.children !== undefined) return h('ul', { class: cls('menu', p.class), ...p }, p.children)
@@ -384,26 +416,26 @@ export const Menu = (p) => {
const render = (item) => item.children const render = (item) => item.children
? h('li', {}, h('details', { open: item.open || undefined }, [ ? h('li', {}, h('details', { open: item.open || undefined }, [
h('summary', {}, getBy(item)), h('summary', {}, getBy(item)),
h('ul', {}, each(() => get(item.children) || [], render)) h('ul', {}, each(() => val(item.children) || [], render))
])) ]))
: h('li', {}, h('a', { : h('li', {}, h('a', {
href: item.href, href: item.href,
onclick: item.onclick ? (e) => { if (!item.href) e.preventDefault(); item.onclick(e) } : null onclick: item.onclick ? (e) => { if (!item.href) e.preventDefault(); item.onclick(e) } : null
}, getBy(item))) }, getBy(item)))
return h('ul', { class: cls('menu', p.class) }, return h('ul', { class: cls('menu', p.class) },
each(() => get(items) || [], render) each(() => val(items) || [], render)
) )
} }
export const Modal = (p) => { export const Modal = (p) => {
let dialogRef = null; let dialogRef = null;
watch(() => { watch(() => {
const isOpen = get(p.open); const isOpen = val(p.open);
if (!dialogRef) return; if (!dialogRef) return;
isOpen ? dialogRef.showModal() : dialogRef.hide(); isOpen ? dialogRef.showModal() : dialogRef.hide();
}); });
const close = () => isFn(p.open) && p.open(false); const close = () => isFunc(p.open) && p.open(false);
return h("dialog", { return h("dialog", {
...p, ...p,
@@ -426,18 +458,18 @@ export const Modal = (p) => {
}; };
export const Navbar = (p, c) => h("div", { ...p, class: cls("navbar", p.class) }, c); export const Navbar = (p, c) => h("div", { ...p, class: cls("navbar", p.class) }, c);
export const Progress = (p) => h("progress", { ...p, class: cls("progress", p.class) }); export const Progress = (p) => h("progress", { ...p, class: cls("progress", p.class) });
export const Radial = (p, c) => h("div", { class: cls("radial-progress", p.class,), style: `--value:${get(p.value) ?? 0};`, role: "progressbar", "aria-valuenow": p.value }, c) export const Radial = (p, c) => h("div", { class: cls("radial-progress", p.class,), style: `--value:${val(p.value) ?? 0};`, role: "progressbar", "aria-valuenow": p.value }, c)
export const Radio = (p) => h("input", { ...p, type: "radio", class: cls("radio", p.class) }); export const Radio = (p) => h("input", { ...p, type: "radio", class: cls("radio", p.class) });
export const Range = (p) => h("input", { ...p, type: "range", class: cls("range", p.class) }); export const Range = (p) => h("input", { ...p, type: "range", class: cls("range", p.class) });
export const Rating = (p, c) => h('div', { ...p, class: "rating" }, c); export const Rating = (p, c) => h('div', { ...p, class: "rating" }, c);
export const RatingItems = (p) => [...Array(p.count)].map((_, i) => h('input', { class: cls('mask', p.class), name: p.name, type: 'radio', checked: () => get(p.value) === i, onchange: () => isFn(p.value) ? p.value(i) : p.onchange?.(i) })) export const RatingItems = (p) => [...Array(p.count)].map((_, i) => h('input', { class: cls('mask', p.class), name: p.name, type: 'radio', checked: () => val(p.value) === i, onchange: () => isFunc(p.value) ? p.value(i) : p.onchange?.(i) }))
export const Select = (p, c) => { export const Select = (p, c) => {
if (c !== undefined) return h('select', { class: cls('select', p.class), ...p }, c) if (c !== undefined) return h('select', { class: cls('select', p.class), ...p }, c)
const { label, float, placeholder, placeholderDisabled = true, value, left, right, hint, items, keyFn, ...rest } = p const { label, float, placeholder, placeholderDisabled = true, value, left, right, hint, items, keyFn, ...rest } = p
const opts = () => { const opts = () => {
const raw = get(items) || [] const raw = val(items) || []
const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: '' }] : [] const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: '' }] : []
return [...ph, ...raw] return [...ph, ...raw]
} }
@@ -448,8 +480,8 @@ export const Select = (p, c) => {
(!float && label) ? h('span', { class: 'label' }, label) : null, (!float && label) ? h('span', { class: 'label' }, label) : null,
left ?? null, left ?? null,
h('select', { h('select', {
value: () => get(value), value: () => val(value),
onchange: (e) => isFn(value) ? value(e.target.value) : rest.onchange?.(e) onchange: (e) => isFunc(value) ? value(e.target.value) : rest.onchange?.(e)
}, },
each(opts, (item) => { each(opts, (item) => {
const val = getBy(item, item.value !== undefined ? 'value' : undefined) const val = getBy(item, item.value !== undefined ? 'value' : undefined)
@@ -474,14 +506,14 @@ export const Stat = (p) => h('div', { ...p, class: cls('stat', p.class) }, [
export const Steps = (p, c) => h("ul", { ...p, class: cls("steps", p.class) }, c); export const Steps = (p, c) => h("ul", { ...p, class: cls("steps", p.class) }, c);
export const Step = (p, c) => h("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c); export const Step = (p, c) => h("li", { ...p, class: cls("step", p.class), "data-content": p.dataContent }, c);
export const Swap = (p, c) => h('label', { ...p, class: cls('swap', p.class) }, c) export const Swap = (p, c) => h('label', { ...p, class: cls('swap', p.class) }, c)
export const SwapToggle = (p) => h('input', { type: 'checkbox', checked: () => get(p.value), onchange: (e) => isFn(p.value) && p.value(e.target.checked), class: p.class }) export const SwapToggle = (p) => h('input', { type: 'checkbox', checked: () => val(p.value), onchange: (e) => isFunc(p.value) && p.value(e.target.checked), class: p.class })
export const SwapOn = (p, c) => h('div', { ...p, class: cls('swap-on', p.class) }, c) export const SwapOn = (p, c) => h('div', { ...p, class: cls('swap-on', p.class) }, c)
export const SwapOff = (p, c) => h('div', { ...p, class: cls('swap-off', p.class) }, c) export const SwapOff = (p, c) => h('div', { ...p, class: cls('swap-off', p.class) }, c)
export const Table = (p, c) => h('table', { ...p, class: cls('table', p.class) }, c) export const Table = (p, c) => h('table', { ...p, class: cls('table', p.class) }, c)
export const TableItems = ({ items, columns = [], header = true }) => { export const TableItems = ({ items, columns = [], header = true }) => {
const head = header !== false && columns.some(c => c.label) ? h('thead', {}, h('tr', {}, columns.map(c => h('th', { class: c.class }, c.label)))) : null const head = header !== false && columns.some(c => c.label) ? h('thead', {}, h('tr', {}, columns.map(c => h('th', { class: c.class }, c.label)))) : null
const body = h('tbody', {}, () => { const body = h('tbody', {}, () => {
const list = get(items) || [] const list = val(items) || []
return list.map((it, idx) => h('tr', {}, columns.map(c => { const v = c.render ? c.render(it, idx) : it[c.key]; return h('td', { class: c.class }, v) }))) return list.map((it, idx) => h('tr', {}, columns.map(c => { const v = c.render ? c.render(it, idx) : it[c.key]; return h('td', { class: c.class }, v) })))
}) })
return [head, body].filter(Boolean) return [head, body].filter(Boolean)
@@ -492,16 +524,16 @@ export const Tabs = (p, c) => {
return h('div', { ...rest, class: cls('tabs', className) }, c) return h('div', { ...rest, class: cls('tabs', className) }, c)
} }
const { items, activeIndex, onClose, class: className, ...rest } = p const { items, activeIndex, onClose, class: className, ...rest } = p
const get = x => (isFn(x) ? x() : x) const get = x => (isFunc(x) ? x() : x)
const closeH = onClose || (isFn(items) ? (idx, item) => { const closeH = onClose || (isFunc(items) ? (idx, item) => {
const arr = get(items) const arr = val(items)
const newArr = arr.filter((_, i) => i !== idx) const newArr = arr.filter((_, i) => i !== idx)
items(newArr) items(newArr)
if (activeIndex() >= newArr.length) activeIndex(Math.max(0, newArr.length - 1)) if (activeIndex() >= newArr.length) activeIndex(Math.max(0, newArr.length - 1))
} : null) } : null)
return h('div', { ...rest, class: cls('tabs', className) }, () => { return h('div', { ...rest, class: cls('tabs', className) }, () => {
const list = get(items) || [] const list = val(items) || []
return list.flatMap((it, idx) => { return list.flatMap((it, idx) => {
const isActive = () => activeIndex() === idx const isActive = () => activeIndex() === idx
const button = h('button', { const button = h('button', {
@@ -517,7 +549,7 @@ export const Tabs = (p, c) => {
const contentDiv = h('div', { const contentDiv = h('div', {
class: 'tab-content bg-base-100 border-base-300 p-6', class: 'tab-content bg-base-100 border-base-300 p-6',
style: () => `display: ${isActive() ? 'block' : 'none'};` style: () => `display: ${isActive() ? 'block' : 'none'};`
}, isFn(it.content) ? it.content() : it.content) }, isFunc(it.content) ? it.content() : it.content)
return [button, contentDiv] return [button, contentDiv]
}) })
}) })
@@ -552,7 +584,7 @@ export const Toast = (message, type = "alert-success", duration = 3500) => {
}, 300); }, 300);
}; };
enterTimer = setTimeout(() => visible(true), 0); enterTimer = setTimeout(() => visible(true), 0);
const content = typeof message === 'function' ? get(message) : message; const content = typeof message === 'function' ? val(message) : message;
const msgNode = typeof content === 'string' ? h("span", {}, content) : content; const msgNode = typeof content === 'string' ? h("span", {}, content) : content;
return h("div", { return h("div", {
class: () => { class: () => {
@@ -575,3 +607,231 @@ export const Toast = (message, type = "alert-success", duration = 3500) => {
}; };
export const Toggle = (p) => h("input", { ...p, type: "checkbox", class: cls("toggle", p.class) }); export const Toggle = (p) => h("input", { ...p, type: "checkbox", class: cls("toggle", p.class) });
export const Tooltip = (p, c) => h("div", { ...p, class: cls("tooltip", p.class), "data-tip": p.tip }, c); export const Tooltip = (p, c) => h("div", { ...p, class: cls("tooltip", p.class), "data-tip": p.tip }, c);
// Editor
export const Editor = (p) => {
const { value, class: extraClass } = p
let editorRef = null
let savedRange = null
const isSource = $(false)
const source = $("")
const count = $(0)
const refreshTick = $(0)
const showEmojis = $(false)
const emojis = ["😀", "😊", "😉", "🧐", "😮", "🤔", "😅", "😂", "😍", "😘", "🥰", "👍", "👎", "👌", "🤝", "🤞", "👋", "👏", "🙌", "🙏", "💪", "☝️", "👇", "👈", "👉", "🖕", "✅", "⚠️", "🚀", "📢", "✉️", "❤️"]
const saveSelection = () => {
const sel = window.getSelection()
if (sel.getRangeAt && sel.rangeCount) savedRange = sel.getRangeAt(0)
}
const restoreSelection = () => {
if (savedRange) {
const sel = window.getSelection()
sel.removeAllRanges()
sel.addRange(savedRange)
}
}
const triggerRefresh = () => {
refreshTick(refreshTick() + 1)
if (editorRef) count(editorRef.innerText.length)
}
const notify = () => {
if (!editorRef) return
const html = editorRef.innerHTML
if (isFunc(value)) value(html)
else p.onchange?.(html)
triggerRefresh()
}
const exec = (cmd, val = null) => {
if (!editorRef) return
editorRef.focus()
if (savedRange) restoreSelection()
document.execCommand(cmd, false, val)
savedRange = null
notify()
}
const openLightbox = (src) => {
const overlay = document.createElement('div')
overlay.style = `position:fixed;top:0;left:0;width:100%;height:100%;background:rgba(0,0,0,0.9);z-index:9999;display:flex;align-items:center;justify-content:center;cursor:zoom-out;`
const img = document.createElement('img')
img.src = src
img.style = `max-width:95%;max-height:95%;box-shadow:0 0 30px rgba(0,0,0,0.5);border-radius:4px;`
overlay.onclick = () => document.body.removeChild(overlay)
overlay.appendChild(img)
document.body.appendChild(overlay)
}
const handleUpload = (file) => {
if (!file) return
const reader = new FileReader()
reader.onload = (re) => {
if (file.type.startsWith('image/')) {
const imgHtml = `<div style="display:inline-block; resize:both; overflow:hidden; vertical-align:bottom; line-height:0; width:200px; height:auto; border:1px dashed #ccc; padding:2px; cursor:pointer;" class="resizable-img-container"><img src="${re.target.result}" style="width:100%; height:100%; object-fit:contain; pointer-events:none;"></div>&nbsp;`
exec("insertHTML", imgHtml)
} else {
const linkHtml = `<a href="${re.target.result}" download="${file.name}" contenteditable="false" style="display:inline-flex; align-items:center; gap:5px; padding:4px 8px; border:1px solid #ccc; border-radius:4px; background:#f9f9f9; text-decoration:none; color:#333; font-size:12px; margin:2px; cursor:pointer;"><span class="icon-[lucide--paperclip] w-3 h-3"></span>${file.name}</a>&nbsp;`
exec("insertHTML", linkHtml)
}
}
reader.readAsDataURL(file)
}
const queryState = (cmd, val = null) => {
refreshTick(); if (!editorRef || isSource()) return false
try {
if (cmd === 'formatBlock') {
let node = window.getSelection().getRangeAt(0).commonAncestorContainer
while (node && node !== editorRef) {
if (node.nodeType === 1 && node.tagName === val) return true
node = node.parentNode
}
return false
}
return document.queryCommandState(cmd)
} catch (e) { return false }
}
const toolbar = h("div", { class: "flex flex-wrap items-center gap-1 p-2 border-b border-base-300 bg-base-200 sticky top-0 z-20" }, [
h("div", { class: "flex flex-wrap gap-1 flex-1 items-center" }, [
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('bold') ? 'btn-active bg-primary/20' : ''}`, onclick: () => exec("bold") }, h("span", { class: "icon-[lucide--bold]" })),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('italic') ? 'btn-active bg-primary/20' : ''}`, onclick: () => exec("italic") }, h("span", { class: "icon-[lucide--italic]" })),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('underline') ? 'btn-active bg-primary/20' : ''}`, onclick: () => exec("underline") }, h("span", { class: "icon-[lucide--underline]" })),
h("input", { type: "color", class: "w-5 h-5 p-0 border-0 bg-transparent cursor-pointer", oninput: (e) => exec("foreColor", e.target.value) }),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", {
type: "button",
class: "btn btn-ghost btn-xs",
onclick: () => exec("justifyLeft")
}, h("span", { class: "icon-[lucide--align-left]" })),
h("button", {
type: "button",
class: "btn btn-ghost btn-xs",
onclick: () => exec("justifyCenter")
}, h("span", { class: "icon-[lucide--align-center]" })),
h("button", {
type: "button",
class: "btn btn-ghost btn-xs",
onclick: () => exec("justifyRight")
}, h("span", { class: "icon-[lucide--align-right]" })),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("insertUnorderedList") }, h("span", { class: "icon-[lucide--list]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("insertOrderedList") }, h("span", { class: "icon-[lucide--list-ordered]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("outdent") }, h("span", { class: "icon-[lucide--indent-decrease]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("indent") }, h("span", { class: "icon-[lucide--indent-increase]" })),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${queryState('formatBlock', 'BLOCKQUOTE') ? 'btn-active' : ''}`, onclick: () => exec("formatBlock", queryState('formatBlock', 'BLOCKQUOTE') ? 'P' : 'BLOCKQUOTE') }, h("span", { class: "icon-[lucide--quote]" })),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => { const url = window.prompt('URL:'); if (url) exec("createLink", url) } }, h("span", { class: "icon-[lucide--link]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => { const input = document.createElement('input'); input.type = 'file'; input.onchange = (e) => handleUpload(e.target.files[0]); input.click(); } }, h("span", { class: "icon-[lucide--paperclip]" })),
h("div", { class: "relative" }, [
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: (e) => { e.stopPropagation(); saveSelection(); showEmojis(!showEmojis()); } }, h("span", { class: "icon-[lucide--smile]" })),
h("div", { class: "absolute top-full left-0 mt-1 p-2 bg-base-100 border border-base-300 shadow-xl rounded-box w-52 z-50 flex flex-wrap gap-1", style: () => showEmojis() ? "display:flex" : "display:none" }, emojis.map(emo => h("span", { class: "cursor-pointer hover:bg-base-200 p-1 rounded text-lg", onclick: (e) => { e.stopPropagation(); exec("insertText", emo); showEmojis(false); } }, emo)))
]),
h("span", { class: "w-px h-5 bg-base-300 mx-1" }),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("undo") }, h("span", { class: "icon-[lucide--undo-2]" })),
h("button", { type: "button", class: "btn btn-ghost btn-xs", onclick: () => exec("redo") }, h("span", { class: "icon-[lucide--redo-2]" })),
]),
h("button", { type: "button", class: () => `btn btn-ghost btn-xs ${isSource() ? 'btn-active' : ''}`, onclick: () => { if (!isSource()) source(editorRef?.innerHTML || ""); else if (editorRef) { editorRef.innerHTML = source(); notify(); }; isSource(!isSource()) } }, h("span", { class: "icon-[lucide--code-2]" }))
])
if (typeof document !== 'undefined' && !document.getElementById('editor-styles')) {
const style = document.createElement('style')
style.id = 'editor-styles'
style.textContent = `
[contenteditable="true"] div,
[contenteditable="true"] p {
margin: 0;
padding: 0;
}
`
document.head.appendChild(style)
}
return h("div", { class: cls("border border-base-300 rounded-box bg-base-100 overflow-hidden shadow-sm flex flex-col", extraClass) }, [
toolbar,
h("div", { class: "relative flex-1 flex flex-col", onclick: () => showEmojis(false) }, [
h("div", {
ref: el => {
if (!editorRef && el) {
editorRef = el; el.innerHTML = val(value) || "";
document.execCommand("defaultParagraphSeparator", false, "br");
el.addEventListener('click', (e) => {
const container = e.target.closest('.resizable-img-container');
if (container) { const img = container.querySelector('img'); if (img) openLightbox(img.src); }
});
}
},
style: () => `min-height:22rem;${isSource() ? 'display:none' : ''}`,
class: "p-4 outline-none text-base-content leading-relaxed [&>div]:m-0 [&>p]:m-0 [&>div]:min-h-[1em] [&_.resizable-img-container]:hover:border-primary [&_blockquote]:border-l-4 [&_blockquote]:border-base-300 [&_blockquote]:pl-4 [&_blockquote]:italic [&_ul]:list-disc [&_ul]:pl-8 [&_ol]:list-decimal [&_ol]:pl-8",
contenteditable: "true",
oninput: notify,
onkeydown: (e) => { if (e.key === 'Tab') { e.preventDefault(); exec("indent"); } },
onkeyup: () => { triggerRefresh(); saveSelection(); },
onclick: (e) => { triggerRefresh(); saveSelection(); e.stopPropagation(); },
onmouseup: () => { notify(); saveSelection(); },
onpaste: (e) => {
e.preventDefault();
const text = e.clipboardData.getData('text/plain');
exec('insertText', text);
},
ondragover: (e) => e.preventDefault(),
ondrop: (e) => { e.preventDefault(); handleUpload(e.dataTransfer.files[0]) }
}),
h("textarea", {
class: "w-full flex-1 min-h-[22rem] p-4 outline-none font-mono text-sm bg-base-200 border-0",
style: () => isSource() ? '' : 'display:none',
value: source,
oninput: (e) => { source(e.target.value); if (editorRef) editorRef.innerHTML = e.target.value; p.onchange?.(e.target.value); }
})
]),
h("div", { class: "px-3 py-1 border-t border-base-300 bg-base-100/50 text-[10px] text-right text-base-content/60 italic" }, [
h("span", () => `${count()}`)
])
])
}