This commit is contained in:
3
dist/sigpro-ui.css
vendored
3
dist/sigpro-ui.css
vendored
@@ -3396,9 +3396,6 @@
|
||||
.-mr-2 {
|
||||
margin-right: calc(var(--spacing) * -2);
|
||||
}
|
||||
.mr-1 {
|
||||
margin-right: calc(var(--spacing) * 1);
|
||||
}
|
||||
.fieldset-legend {
|
||||
@layer daisyui.l1.l2.l3 {
|
||||
margin-bottom: calc(0.25rem * -1);
|
||||
|
||||
349
dist/sigpro-ui.esm.js
vendored
349
dist/sigpro-ui.esm.js
vendored
@@ -16,6 +16,10 @@ var __export = (target, all) => {
|
||||
// sigpro-ui.js
|
||||
var exports_sigpro_ui = {};
|
||||
__export(exports_sigpro_ui, {
|
||||
tt: () => tt,
|
||||
i18n: () => i18n,
|
||||
hide: () => hide,
|
||||
currentLocale: () => currentLocale,
|
||||
Tooltip: () => Tooltip,
|
||||
Toggle: () => Toggle,
|
||||
Toast: () => Toast,
|
||||
@@ -46,6 +50,7 @@ __export(exports_sigpro_ui, {
|
||||
Navbar: () => Navbar,
|
||||
Modal: () => Modal,
|
||||
Menu: () => Menu,
|
||||
Locale: () => Locale,
|
||||
Loading: () => Loading,
|
||||
ListRows: () => ListRows,
|
||||
List: () => List,
|
||||
@@ -56,6 +61,7 @@ __export(exports_sigpro_ui, {
|
||||
Fileinput: () => Fileinput,
|
||||
Fieldset: () => Fieldset,
|
||||
Fab: () => Fab,
|
||||
Editor: () => Editor,
|
||||
DropdownContent: () => DropdownContent,
|
||||
DropdownButton: () => DropdownButton,
|
||||
Dropdown: () => Dropdown,
|
||||
@@ -92,23 +98,23 @@ __export(exports_sigpro_ui, {
|
||||
});
|
||||
|
||||
// node_modules/sigpro/dist/sigpro.esm.min.js
|
||||
var w = (e) => typeof e === "function";
|
||||
var B = (e) => e && typeof e === "object";
|
||||
var g = Array.isArray;
|
||||
var _ = (e) => typeof e === "function";
|
||||
var O = (e) => e && typeof e === "object";
|
||||
var b = Array.isArray;
|
||||
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 d = null;
|
||||
var _ = null;
|
||||
var N = false;
|
||||
var m = null;
|
||||
var v = false;
|
||||
var R = 0;
|
||||
var O = new Set;
|
||||
var T = new Set;
|
||||
var I = new WeakMap;
|
||||
var j = Symbol("iter");
|
||||
var k = new WeakMap;
|
||||
var k = Symbol("iter");
|
||||
var L = new WeakMap;
|
||||
var W = "http://www.w3.org/2000/svg";
|
||||
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 b = (e) => {
|
||||
var g = (e) => {
|
||||
if (!e || e._disposed)
|
||||
return;
|
||||
e._disposed = true;
|
||||
@@ -123,9 +129,9 @@ var b = (e) => {
|
||||
n._deps.forEach((r) => r.delete(n)), n._deps.clear();
|
||||
}
|
||||
};
|
||||
var v = (e) => {
|
||||
if (_)
|
||||
(_._cleanups ||= new Set).add(e);
|
||||
var S = (e) => {
|
||||
if (m)
|
||||
(m._cleanups ||= new Set).add(e);
|
||||
};
|
||||
var K = (e) => {
|
||||
let s = d;
|
||||
@@ -144,41 +150,41 @@ var x = (e, s = false) => {
|
||||
n._deps.forEach((i) => i.delete(n));
|
||||
if (n._cleanups)
|
||||
n._cleanups.forEach((i) => i()), n._cleanups.clear();
|
||||
let r = d, o = _;
|
||||
d = _ = n;
|
||||
let r = d, o = m;
|
||||
d = m = n;
|
||||
try {
|
||||
return n._result = e();
|
||||
} catch (i) {
|
||||
console.error("[SigPro]", i);
|
||||
} 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 = _, _)
|
||||
(_._children ||= new Set).add(n);
|
||||
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)
|
||||
(m._children ||= new Set).add(n);
|
||||
return n;
|
||||
};
|
||||
var $ = () => {
|
||||
if (N)
|
||||
if (v)
|
||||
return;
|
||||
N = true;
|
||||
let e = Array.from(O).sort((s, n) => s._depth - n._depth);
|
||||
O.clear();
|
||||
v = true;
|
||||
let e = Array.from(T).sort((s, n) => s._depth - n._depth);
|
||||
T.clear();
|
||||
for (let s of e)
|
||||
if (!s._disposed)
|
||||
s();
|
||||
N = false;
|
||||
v = false;
|
||||
};
|
||||
var z = (e) => {
|
||||
R++;
|
||||
try {
|
||||
return e();
|
||||
} 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)
|
||||
e.add(d), (d._deps ||= new Set).add(e);
|
||||
else if (s && e.size > 0) {
|
||||
@@ -188,17 +194,17 @@ var m = (e, s = false) => {
|
||||
continue;
|
||||
if (r._isComputed) {
|
||||
if (r._dirty = true, r._subs)
|
||||
m(r._subs, true);
|
||||
w(r._subs, true);
|
||||
} else
|
||||
O.add(r), n = true;
|
||||
T.add(r), n = true;
|
||||
}
|
||||
if (n && !N && R === 0)
|
||||
if (n && !v && R === 0)
|
||||
queueMicrotask($);
|
||||
}
|
||||
};
|
||||
var P = (e, s = null) => {
|
||||
let n = new Set;
|
||||
if (w(e)) {
|
||||
if (_(e)) {
|
||||
let r, o = () => {
|
||||
if (o._dirty) {
|
||||
let i = d;
|
||||
@@ -206,13 +212,13 @@ var P = (e, s = null) => {
|
||||
try {
|
||||
let t = e();
|
||||
if (!Object.is(r, t))
|
||||
r = t, m(n, true);
|
||||
r = t, w(n, true);
|
||||
} finally {
|
||||
d = i;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -222,18 +228,18 @@ var P = (e, s = null) => {
|
||||
} catch (r) {}
|
||||
return (...r) => {
|
||||
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 (e = o, s)
|
||||
localStorage.setItem(s, JSON.stringify(e));
|
||||
m(n, true);
|
||||
w(n, true);
|
||||
}
|
||||
}
|
||||
return m(n), e;
|
||||
return w(n), e;
|
||||
};
|
||||
};
|
||||
var D = (e) => {
|
||||
if (!B(e))
|
||||
if (!O(e))
|
||||
return e;
|
||||
let s = I.get(e);
|
||||
if (s)
|
||||
@@ -245,35 +251,35 @@ var D = (e) => {
|
||||
return t;
|
||||
}, o = new Proxy(e, { get(i, t, c) {
|
||||
if (typeof t !== "symbol")
|
||||
m(r(t));
|
||||
w(r(t));
|
||||
return D(Reflect.get(i, t, c));
|
||||
}, 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 (m(r(t), true), !a)
|
||||
m(r(j), true);
|
||||
if (w(r(t), true), !a)
|
||||
w(r(k), true);
|
||||
}
|
||||
return u;
|
||||
}, deleteProperty(i, t) {
|
||||
let c = Reflect.deleteProperty(i, t);
|
||||
if (c)
|
||||
m(r(t), true), m(r(j), true);
|
||||
w(r(t), true), w(r(k), true);
|
||||
return c;
|
||||
}, ownKeys(i) {
|
||||
return m(r(j)), Reflect.ownKeys(i);
|
||||
return w(r(k)), Reflect.ownKeys(i);
|
||||
} });
|
||||
return I.set(e, o), o;
|
||||
};
|
||||
var T = (e, s) => {
|
||||
var C = (e, s) => {
|
||||
if (s === undefined) {
|
||||
let r = x(e);
|
||||
return r(), () => b(r);
|
||||
return r(), () => g(r);
|
||||
}
|
||||
let n = x(() => {
|
||||
let r = Array.isArray(e) ? e.map((o) => o()) : e();
|
||||
K(() => s(r));
|
||||
});
|
||||
return n(), () => b(n);
|
||||
return n(), () => g(n);
|
||||
};
|
||||
var U = (e) => {
|
||||
if (!e)
|
||||
@@ -281,14 +287,14 @@ var U = (e) => {
|
||||
if (e._cleanups)
|
||||
e._cleanups.forEach((s) => s()), e._cleanups.clear();
|
||||
if (e._ownerEffect)
|
||||
b(e._ownerEffect);
|
||||
g(e._ownerEffect);
|
||||
if (e.childNodes)
|
||||
e.childNodes.forEach((s) => U(s));
|
||||
};
|
||||
var J = /^\s*(javascript|data|vbscript):/i;
|
||||
var Q = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
|
||||
var X = (e) => Q.has(e) || e.startsWith("on");
|
||||
var L = (e, s) => {
|
||||
var B = (e, s) => {
|
||||
if (s == null || s === false)
|
||||
return null;
|
||||
if (X(e)) {
|
||||
@@ -299,9 +305,9 @@ var L = (e, s) => {
|
||||
return s;
|
||||
};
|
||||
var A = (e, s = {}, n = []) => {
|
||||
if (s instanceof Node || g(s) || !B(s))
|
||||
if (s instanceof Node || b(s) || !O(s))
|
||||
n = s, s = {};
|
||||
if (w(e)) {
|
||||
if (_(e)) {
|
||||
let t = x(() => {
|
||||
let f = e(s, { children: n, emit: (u, ...h) => s[`on${u[0].toUpperCase()}${u.slice(1)}`]?.(...h) });
|
||||
return t._result = f, f;
|
||||
@@ -310,22 +316,22 @@ var A = (e, s = {}, n = []) => {
|
||||
let c = t._result;
|
||||
if (c == null)
|
||||
return null;
|
||||
let l = c instanceof Node || g(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => {
|
||||
if (B(f) && !f._isRuntime)
|
||||
let l = c instanceof Node || b(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => {
|
||||
if (O(f) && !f._isRuntime)
|
||||
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);
|
||||
o._cleanups = new Set;
|
||||
for (let t of Object.keys(s)) {
|
||||
let c = s[t];
|
||||
if (t === "ref") {
|
||||
w(c) ? c(o) : c.current = o;
|
||||
_(c) ? c(o) : c.current = o;
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
@@ -333,10 +339,10 @@ var A = (e, s = {}, n = []) => {
|
||||
let l = t.slice(2).toLowerCase();
|
||||
o.addEventListener(l, c);
|
||||
let a = () => o.removeEventListener(l, c);
|
||||
o._cleanups.add(a), v(a);
|
||||
} else if (w(c)) {
|
||||
o._cleanups.add(a), S(a);
|
||||
} else if (_(c)) {
|
||||
let l = x(() => {
|
||||
let a = L(t, c());
|
||||
let a = B(t, c());
|
||||
if (t === "class")
|
||||
o.className = a || "";
|
||||
else if (a == null)
|
||||
@@ -348,12 +354,12 @@ var A = (e, s = {}, n = []) => {
|
||||
else
|
||||
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";
|
||||
o.addEventListener(a, (f) => c(f.target[t]));
|
||||
}
|
||||
} else {
|
||||
let l = L(t, c);
|
||||
let l = B(t, c);
|
||||
if (l != null)
|
||||
if (t === "style" && typeof l === "string")
|
||||
o.setAttribute("style", l);
|
||||
@@ -364,13 +370,13 @@ var A = (e, s = {}, n = []) => {
|
||||
}
|
||||
}
|
||||
let i = (t) => {
|
||||
if (g(t))
|
||||
if (b(t))
|
||||
return t.forEach(i);
|
||||
if (w(t)) {
|
||||
if (_(t)) {
|
||||
let c = E.createTextNode("");
|
||||
o.appendChild(c);
|
||||
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) => {
|
||||
if (p._isRuntime)
|
||||
p.destroy();
|
||||
@@ -390,7 +396,7 @@ var A = (e, s = {}, n = []) => {
|
||||
}
|
||||
l = u;
|
||||
});
|
||||
a(), o._cleanups.add(() => b(a)), v(() => b(a));
|
||||
a(), o._cleanups.add(() => g(a)), S(() => g(a));
|
||||
} else {
|
||||
let c = V(t);
|
||||
if (o.appendChild(c), c._mounts)
|
||||
@@ -399,15 +405,15 @@ var A = (e, s = {}, n = []) => {
|
||||
};
|
||||
return i(n), o;
|
||||
};
|
||||
var C = (e) => {
|
||||
let s = new Set, n = _, r = d, o = E.createElement("div");
|
||||
o.style.display = "contents", o.setAttribute("role", "presentation"), _ = { _cleanups: s }, d = null;
|
||||
var j = (e) => {
|
||||
let s = new Set, n = m, r = d, o = E.createElement("div");
|
||||
o.style.display = "contents", o.setAttribute("role", "presentation"), m = { _cleanups: s }, d = null;
|
||||
let i = (t) => {
|
||||
if (!t)
|
||||
return;
|
||||
if (t._isRuntime)
|
||||
s.add(t.destroy), o.appendChild(t.container);
|
||||
else if (g(t))
|
||||
else if (b(t))
|
||||
t.forEach(i);
|
||||
else
|
||||
o.appendChild(t instanceof Node ? t : E.createTextNode(String(t == null ? "" : t)));
|
||||
@@ -415,7 +421,7 @@ var C = (e) => {
|
||||
try {
|
||||
i(e({ onCleanup: (t) => s.add(t) }));
|
||||
} finally {
|
||||
_ = n, d = r;
|
||||
m = n, d = r;
|
||||
}
|
||||
return { _isRuntime: true, container: o, destroy: () => {
|
||||
s.forEach((t) => t()), U(o), o.remove();
|
||||
@@ -423,22 +429,22 @@ var C = (e) => {
|
||||
};
|
||||
var F = (e, s, n = 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)
|
||||
i.destroy(), i = null;
|
||||
let c = t ? s : n;
|
||||
if (c)
|
||||
i = C(() => w(c) ? c() : c), o.insertBefore(i.container, r);
|
||||
}), v(() => i?.destroy()), o;
|
||||
i = j(() => _(c) ? c() : c), o.insertBefore(i.container, r);
|
||||
}), S(() => i?.destroy()), o;
|
||||
};
|
||||
var H = (e, s, n) => {
|
||||
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 || [];
|
||||
for (let u = 0;u < a.length; u++) {
|
||||
let h = a[u], p = n ? h?.[n] ?? u : h?.id ?? u, y = i.get(p);
|
||||
if (!y)
|
||||
y = C(() => s(h, u));
|
||||
y = j(() => s(h, u));
|
||||
else
|
||||
i.delete(p);
|
||||
c.set(p, y), l.push(y);
|
||||
@@ -454,11 +460,11 @@ var H = (e, s, n) => {
|
||||
i = c;
|
||||
}), o;
|
||||
};
|
||||
var S = (e) => {
|
||||
var N = (e) => {
|
||||
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;
|
||||
return T([n], () => {
|
||||
return C([n], () => {
|
||||
let t = n(), c = e.find((l) => {
|
||||
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]);
|
||||
@@ -469,38 +475,56 @@ var S = (e) => {
|
||||
c.path.split("/").filter(Boolean).forEach((a, f) => {
|
||||
if (a[0] === ":")
|
||||
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;
|
||||
};
|
||||
S.params = P({});
|
||||
S.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/");
|
||||
S.back = () => window.history.back();
|
||||
S.path = () => window.location.hash.replace(/^#/, "") || "/";
|
||||
N.params = P({});
|
||||
N.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/");
|
||||
N.back = () => window.history.back();
|
||||
N.path = () => window.location.hash.replace(/^#/, "") || "/";
|
||||
var Y = (e, s) => {
|
||||
let n = typeof s === "string" ? E.querySelector(s) : s;
|
||||
if (!n)
|
||||
return;
|
||||
if (k.has(n))
|
||||
k.get(n).destroy();
|
||||
let r = C(w(e) ? e : () => e);
|
||||
return n.replaceChildren(r.container), k.set(n, r), r;
|
||||
if (L.has(n))
|
||||
L.get(n).destroy();
|
||||
let r = j(_(e) ? e : () => e);
|
||||
return n.replaceChildren(r.container), L.set(n, r), r;
|
||||
};
|
||||
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);
|
||||
});
|
||||
|
||||
// sigpro-helpers.js
|
||||
var get = (val) => typeof val === "function" ? val() : val;
|
||||
// sigpro-ui.js
|
||||
var val = (val2) => typeof val2 === "function" ? val2() : val2;
|
||||
var getBy = (item, field = "label") => item && typeof item === "object" ? item[field] : item;
|
||||
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 ? get(items) : get(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 ? val(items) : val(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 hide = () => document.activeElement?.blur();
|
||||
|
||||
// sigpro-ui.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("en");
|
||||
var Locale = (t) => currentLocale(t);
|
||||
var tt = (t) => () => i18n[currentLocale()][t] || t;
|
||||
var Accordion = (p) => {
|
||||
const name = p.name || rand("acc");
|
||||
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 AvatarGroup = (p, c) => A("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c);
|
||||
var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) => {
|
||||
const query = P(get(value) || "");
|
||||
const query = P(val(value) || "");
|
||||
const filtered = P(() => filterBy(items, query()));
|
||||
const pick = (item) => {
|
||||
const display = getBy(item);
|
||||
const actual = typeof item === "string" ? item : item.value;
|
||||
query(display);
|
||||
if (isFn(value))
|
||||
if (_(value))
|
||||
value(actual);
|
||||
onselect?.(item);
|
||||
hide();
|
||||
@@ -534,7 +558,7 @@ var Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) =
|
||||
left: A("span", { class: "icon-[lucide--search]" }),
|
||||
oninput: (e) => {
|
||||
query(e.target.value);
|
||||
if (isFn(value))
|
||||
if (_(value))
|
||||
value(e.target.value);
|
||||
}
|
||||
})),
|
||||
@@ -560,8 +584,8 @@ var Calendar = (p) => {
|
||||
const now = new Date;
|
||||
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 rangeMode = () => get(p.range) === true;
|
||||
const current = () => get(p.value);
|
||||
const rangeMode = () => val(p.range) === true;
|
||||
const current = () => val(p.value);
|
||||
const selectDate = (date) => {
|
||||
const s = fmt(date);
|
||||
const v2 = current();
|
||||
@@ -592,7 +616,7 @@ var Calendar = (p) => {
|
||||
const HourSlider = ({ value: hVal, onChange: onH }) => A("div", { class: "flex-1" }, [
|
||||
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("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", {
|
||||
@@ -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 Checkbox = (p) => A("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) });
|
||||
var Colorpicker = (p) => {
|
||||
const current = () => get(p.value) || "#000000";
|
||||
const current = () => val(p.value) || "#000000";
|
||||
return Dropdown({}, [
|
||||
DropdownButton({ class: "btn" }, [
|
||||
A("div", { class: "size-5 rounded-sm", style: () => `background-color: ${current()}` }),
|
||||
@@ -672,13 +696,13 @@ var Colorpicker = (p) => {
|
||||
DropdownContent({ class: "p-0" }, ColorPalette({
|
||||
value: p.value,
|
||||
onchange: (c) => {
|
||||
isFn(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
_(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
}
|
||||
}))
|
||||
]);
|
||||
};
|
||||
var ColorPalette = (p) => {
|
||||
const current = () => get(p.value) || "#000000";
|
||||
const current = () => val(p.value) || "#000000";
|
||||
const palette = [
|
||||
"#000",
|
||||
"#1A1A1A",
|
||||
@@ -746,7 +770,7 @@ var ColorPalette = (p) => {
|
||||
"#fae8ff"
|
||||
];
|
||||
const pick = (c) => {
|
||||
isFn(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
_(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
hide();
|
||||
};
|
||||
return A("div", {
|
||||
@@ -765,9 +789,9 @@ var ColorPalette = (p) => {
|
||||
};
|
||||
var Datepicker = (p) => {
|
||||
const displayValue = P("");
|
||||
const rangeMode = () => get(p.range) === true;
|
||||
T(() => {
|
||||
const v2 = get(p.value);
|
||||
const rangeMode = () => val(p.range) === true;
|
||||
C(() => {
|
||||
const v2 = val(p.value);
|
||||
if (!v2)
|
||||
return displayValue("");
|
||||
let text = "";
|
||||
@@ -783,12 +807,12 @@ var Datepicker = (p) => {
|
||||
}
|
||||
displayValue(text);
|
||||
});
|
||||
const handleChange = (val) => {
|
||||
if (isFn(p.value))
|
||||
p.value(val);
|
||||
const handleChange = (val2) => {
|
||||
if (_(p.value))
|
||||
p.value(val2);
|
||||
else
|
||||
p.onChange?.(val);
|
||||
if (!rangeMode() || val?.end != null)
|
||||
p.onChange?.(val2);
|
||||
if (!rangeMode() || val2?.end != null)
|
||||
hide();
|
||||
};
|
||||
return Dropdown({ class: cls("w-full", p.class) }, [
|
||||
@@ -807,7 +831,7 @@ var Datepicker = (p) => {
|
||||
onmousedown: (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (isFn(p.value))
|
||||
if (_(p.value))
|
||||
p.value(null);
|
||||
else
|
||||
p.onChange?.(null);
|
||||
@@ -824,7 +848,7 @@ var Datepicker = (p) => {
|
||||
]);
|
||||
};
|
||||
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 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) });
|
||||
@@ -848,17 +872,17 @@ var Fileinput = (p) => {
|
||||
}
|
||||
const updated = [...files(), ...arr];
|
||||
files(updated);
|
||||
if (isFn(p.onselect))
|
||||
if (_(p.onselect))
|
||||
p.onselect(updated);
|
||||
else if (isFn(p.value))
|
||||
else if (_(p.value))
|
||||
p.value(updated);
|
||||
};
|
||||
const remove = (idx) => {
|
||||
const updated = files().filter((_2, i) => i !== idx);
|
||||
files(updated);
|
||||
if (isFn(p.onselect))
|
||||
if (_(p.onselect))
|
||||
p.onselect(updated);
|
||||
else if (isFn(p.value))
|
||||
else if (_(p.value))
|
||||
p.value(updated);
|
||||
};
|
||||
return A("div", { class: cls("fieldset w-full p-0", p.class) }, [
|
||||
@@ -913,7 +937,7 @@ var Input = (p) => {
|
||||
const showPassword = P(false);
|
||||
const isPassword = p.type === "password";
|
||||
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" : "" }, [
|
||||
float ? A("span", {}, label2) : null,
|
||||
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 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 Menu = (p) => {
|
||||
if (p.children !== undefined)
|
||||
@@ -940,7 +964,7 @@ var Menu = (p) => {
|
||||
const { items } = p;
|
||||
const render = (item) => item.children ? A("li", {}, A("details", { open: item.open || undefined }, [
|
||||
A("summary", {}, getBy(item)),
|
||||
A("ul", {}, H(() => get(item.children) || [], render))
|
||||
A("ul", {}, H(() => val(item.children) || [], render))
|
||||
])) : A("li", {}, A("a", {
|
||||
href: item.href,
|
||||
onclick: item.onclick ? (e) => {
|
||||
@@ -949,17 +973,17 @@ var Menu = (p) => {
|
||||
item.onclick(e);
|
||||
} : null
|
||||
}, 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) => {
|
||||
let dialogRef = null;
|
||||
T(() => {
|
||||
const isOpen = get(p.open);
|
||||
C(() => {
|
||||
const isOpen = val(p.open);
|
||||
if (!dialogRef)
|
||||
return;
|
||||
isOpen ? dialogRef.showModal() : dialogRef.hide();
|
||||
});
|
||||
const close = () => isFn(p.open) && p.open(false);
|
||||
const close = () => _(p.open) && p.open(false);
|
||||
return A("dialog", {
|
||||
...p,
|
||||
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 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 Range = (p) => A("input", { ...p, type: "range", class: cls("range", p.class) });
|
||||
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) => {
|
||||
if (c !== undefined)
|
||||
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 opts = () => {
|
||||
const raw = get(items) || [];
|
||||
const raw = val(items) || [];
|
||||
const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: "" }] : [];
|
||||
return [...ph, ...raw];
|
||||
};
|
||||
@@ -1001,12 +1025,12 @@ var Select = (p, c) => {
|
||||
!float && label2 ? A("span", { class: "label" }, label2) : null,
|
||||
left ?? null,
|
||||
A("select", {
|
||||
value: () => get(value),
|
||||
onchange: (e) => isFn(value) ? value(e.target.value) : rest.onchange?.(e)
|
||||
value: () => val(value),
|
||||
onchange: (e) => _(value) ? value(e.target.value) : rest.onchange?.(e)
|
||||
}, 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");
|
||||
return A("option", { value: val, disabled: item.disabled || undefined }, lab);
|
||||
return A("option", { value: val2, disabled: item.disabled || undefined }, lab);
|
||||
})),
|
||||
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 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 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 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 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 body = A("tbody", {}, () => {
|
||||
const list = get(items) || [];
|
||||
const list = val(items) || [];
|
||||
return list.map((it, idx) => A("tr", {}, columns.map((c) => {
|
||||
const v2 = c.render ? c.render(it, idx) : it[c.key];
|
||||
return A("td", { class: c.class }, v2);
|
||||
@@ -1046,16 +1070,16 @@ var Tabs = (p, c) => {
|
||||
return A("div", { ...rest2, class: cls("tabs", className2) }, c);
|
||||
}
|
||||
const { items, activeIndex, onClose, class: className, ...rest } = p;
|
||||
const get2 = (x2) => isFn(x2) ? x2() : x2;
|
||||
const closeH = onClose || (isFn(items) ? (idx, item) => {
|
||||
const arr = get2(items);
|
||||
const get = (x2) => _(x2) ? x2() : x2;
|
||||
const closeH = onClose || (_(items) ? (idx, item) => {
|
||||
const arr = val(items);
|
||||
const newArr = arr.filter((_2, i) => i !== idx);
|
||||
items(newArr);
|
||||
if (activeIndex() >= newArr.length)
|
||||
activeIndex(Math.max(0, newArr.length - 1));
|
||||
} : null);
|
||||
return A("div", { ...rest, class: cls("tabs", className) }, () => {
|
||||
const list = get2(items) || [];
|
||||
const list = val(items) || [];
|
||||
return list.flatMap((it, idx) => {
|
||||
const isActive = () => activeIndex() === idx;
|
||||
const button = A("button", {
|
||||
@@ -1078,7 +1102,7 @@ var Tabs = (p, c) => {
|
||||
const contentDiv = A("div", {
|
||||
class: "tab-content bg-base-100 border-base-300 p-6",
|
||||
style: () => `display: ${isActive() ? "block" : "none"};`
|
||||
}, isFn(it.content) ? it.content() : it.content);
|
||||
}, _(it.content) ? it.content() : it.content);
|
||||
return [button, contentDiv];
|
||||
});
|
||||
});
|
||||
@@ -1115,7 +1139,7 @@ var Toast = (message, type = "alert-success", duration = 3500) => {
|
||||
}, 300);
|
||||
};
|
||||
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;
|
||||
return A("div", {
|
||||
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 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) => {
|
||||
const { value, class: extraClass } = p;
|
||||
let editorRef = null;
|
||||
@@ -1178,19 +1196,19 @@ var Editor = (p) => {
|
||||
if (!editorRef)
|
||||
return;
|
||||
const html = editorRef.innerHTML;
|
||||
if (isFn(value))
|
||||
if (_(value))
|
||||
value(html);
|
||||
else
|
||||
p.onchange?.(html);
|
||||
triggerRefresh();
|
||||
};
|
||||
const exec = (cmd, val = null) => {
|
||||
const exec = (cmd, val2 = null) => {
|
||||
if (!editorRef)
|
||||
return;
|
||||
editorRef.focus();
|
||||
if (savedRange)
|
||||
restoreSelection();
|
||||
document.execCommand(cmd, false, val);
|
||||
document.execCommand(cmd, false, val2);
|
||||
savedRange = null;
|
||||
notify();
|
||||
};
|
||||
@@ -1219,7 +1237,7 @@ var Editor = (p) => {
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
const queryState = (cmd, val = null) => {
|
||||
const queryState = (cmd, val2 = null) => {
|
||||
refreshTick();
|
||||
if (!editorRef || isSource())
|
||||
return false;
|
||||
@@ -1227,7 +1245,7 @@ var Editor = (p) => {
|
||||
if (cmd === "formatBlock") {
|
||||
let node = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
||||
while (node && node !== editorRef) {
|
||||
if (node.nodeType === 1 && node.tagName === val)
|
||||
if (node.nodeType === 1 && node.tagName === val2)
|
||||
return true;
|
||||
node = node.parentNode;
|
||||
}
|
||||
@@ -1323,7 +1341,7 @@ var Editor = (p) => {
|
||||
ref: (el) => {
|
||||
if (!editorRef && el) {
|
||||
editorRef = el;
|
||||
el.innerHTML = get(value) || "";
|
||||
el.innerHTML = val(value) || "";
|
||||
document.execCommand("defaultParagraphSeparator", false, "br");
|
||||
el.addEventListener("click", (e) => {
|
||||
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
|
||||
var Components = {
|
||||
...exports_sigpro_ui,
|
||||
...exports_sigpro_editor
|
||||
};
|
||||
var Utils = {
|
||||
Locale,
|
||||
tt,
|
||||
hide,
|
||||
get
|
||||
};
|
||||
var Components = { ...exports_sigpro_ui };
|
||||
if (typeof window !== "undefined") {
|
||||
Object.entries({ ...Components, ...Utils }).forEach(([name, value]) => {
|
||||
Object.entries({ ...Components }).forEach(([name, value]) => {
|
||||
Object.defineProperty(window, name, {
|
||||
value,
|
||||
writable: false,
|
||||
@@ -1432,6 +1418,5 @@ if (typeof window !== "undefined") {
|
||||
});
|
||||
}
|
||||
export {
|
||||
Utils,
|
||||
Components
|
||||
};
|
||||
|
||||
4
dist/sigpro-ui.esm.min.js
vendored
4
dist/sigpro-ui.esm.min.js
vendored
File diff suppressed because one or more lines are too long
349
dist/sigpro-ui.js
vendored
349
dist/sigpro-ui.js
vendored
@@ -40,13 +40,16 @@
|
||||
// index.js
|
||||
var exports_sigpro_ui2 = {};
|
||||
__export(exports_sigpro_ui2, {
|
||||
Utils: () => Utils,
|
||||
Components: () => Components
|
||||
});
|
||||
|
||||
// sigpro-ui.js
|
||||
var exports_sigpro_ui = {};
|
||||
__export(exports_sigpro_ui, {
|
||||
tt: () => tt,
|
||||
i18n: () => i18n,
|
||||
hide: () => hide,
|
||||
currentLocale: () => currentLocale,
|
||||
Tooltip: () => Tooltip,
|
||||
Toggle: () => Toggle,
|
||||
Toast: () => Toast,
|
||||
@@ -77,6 +80,7 @@
|
||||
Navbar: () => Navbar,
|
||||
Modal: () => Modal,
|
||||
Menu: () => Menu,
|
||||
Locale: () => Locale,
|
||||
Loading: () => Loading,
|
||||
ListRows: () => ListRows,
|
||||
List: () => List,
|
||||
@@ -87,6 +91,7 @@
|
||||
Fileinput: () => Fileinput,
|
||||
Fieldset: () => Fieldset,
|
||||
Fab: () => Fab,
|
||||
Editor: () => Editor,
|
||||
DropdownContent: () => DropdownContent,
|
||||
DropdownButton: () => DropdownButton,
|
||||
Dropdown: () => Dropdown,
|
||||
@@ -123,23 +128,23 @@
|
||||
});
|
||||
|
||||
// node_modules/sigpro/dist/sigpro.esm.min.js
|
||||
var w = (e) => typeof e === "function";
|
||||
var B = (e) => e && typeof e === "object";
|
||||
var g = Array.isArray;
|
||||
var _ = (e) => typeof e === "function";
|
||||
var O = (e) => e && typeof e === "object";
|
||||
var b = Array.isArray;
|
||||
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 d = null;
|
||||
var _ = null;
|
||||
var N = false;
|
||||
var m = null;
|
||||
var v = false;
|
||||
var R = 0;
|
||||
var O = new Set;
|
||||
var T = new Set;
|
||||
var I = new WeakMap;
|
||||
var j = Symbol("iter");
|
||||
var k = new WeakMap;
|
||||
var k = Symbol("iter");
|
||||
var L = new WeakMap;
|
||||
var W = "http://www.w3.org/2000/svg";
|
||||
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 b = (e) => {
|
||||
var g = (e) => {
|
||||
if (!e || e._disposed)
|
||||
return;
|
||||
e._disposed = true;
|
||||
@@ -154,9 +159,9 @@
|
||||
n._deps.forEach((r) => r.delete(n)), n._deps.clear();
|
||||
}
|
||||
};
|
||||
var v = (e) => {
|
||||
if (_)
|
||||
(_._cleanups ||= new Set).add(e);
|
||||
var S = (e) => {
|
||||
if (m)
|
||||
(m._cleanups ||= new Set).add(e);
|
||||
};
|
||||
var K = (e) => {
|
||||
let s = d;
|
||||
@@ -175,41 +180,41 @@
|
||||
n._deps.forEach((i) => i.delete(n));
|
||||
if (n._cleanups)
|
||||
n._cleanups.forEach((i) => i()), n._cleanups.clear();
|
||||
let r = d, o = _;
|
||||
d = _ = n;
|
||||
let r = d, o = m;
|
||||
d = m = n;
|
||||
try {
|
||||
return n._result = e();
|
||||
} catch (i) {
|
||||
console.error("[SigPro]", i);
|
||||
} 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 = _, _)
|
||||
(_._children ||= new Set).add(n);
|
||||
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)
|
||||
(m._children ||= new Set).add(n);
|
||||
return n;
|
||||
};
|
||||
var $ = () => {
|
||||
if (N)
|
||||
if (v)
|
||||
return;
|
||||
N = true;
|
||||
let e = Array.from(O).sort((s, n) => s._depth - n._depth);
|
||||
O.clear();
|
||||
v = true;
|
||||
let e = Array.from(T).sort((s, n) => s._depth - n._depth);
|
||||
T.clear();
|
||||
for (let s of e)
|
||||
if (!s._disposed)
|
||||
s();
|
||||
N = false;
|
||||
v = false;
|
||||
};
|
||||
var z = (e) => {
|
||||
R++;
|
||||
try {
|
||||
return e();
|
||||
} 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)
|
||||
e.add(d), (d._deps ||= new Set).add(e);
|
||||
else if (s && e.size > 0) {
|
||||
@@ -219,17 +224,17 @@
|
||||
continue;
|
||||
if (r._isComputed) {
|
||||
if (r._dirty = true, r._subs)
|
||||
m(r._subs, true);
|
||||
w(r._subs, true);
|
||||
} else
|
||||
O.add(r), n = true;
|
||||
T.add(r), n = true;
|
||||
}
|
||||
if (n && !N && R === 0)
|
||||
if (n && !v && R === 0)
|
||||
queueMicrotask($);
|
||||
}
|
||||
};
|
||||
var P = (e, s = null) => {
|
||||
let n = new Set;
|
||||
if (w(e)) {
|
||||
if (_(e)) {
|
||||
let r, o = () => {
|
||||
if (o._dirty) {
|
||||
let i = d;
|
||||
@@ -237,13 +242,13 @@
|
||||
try {
|
||||
let t = e();
|
||||
if (!Object.is(r, t))
|
||||
r = t, m(n, true);
|
||||
r = t, w(n, true);
|
||||
} finally {
|
||||
d = i;
|
||||
}
|
||||
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;
|
||||
}
|
||||
@@ -253,18 +258,18 @@
|
||||
} catch (r) {}
|
||||
return (...r) => {
|
||||
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 (e = o, s)
|
||||
localStorage.setItem(s, JSON.stringify(e));
|
||||
m(n, true);
|
||||
w(n, true);
|
||||
}
|
||||
}
|
||||
return m(n), e;
|
||||
return w(n), e;
|
||||
};
|
||||
};
|
||||
var D = (e) => {
|
||||
if (!B(e))
|
||||
if (!O(e))
|
||||
return e;
|
||||
let s = I.get(e);
|
||||
if (s)
|
||||
@@ -276,35 +281,35 @@
|
||||
return t;
|
||||
}, o = new Proxy(e, { get(i, t, c) {
|
||||
if (typeof t !== "symbol")
|
||||
m(r(t));
|
||||
w(r(t));
|
||||
return D(Reflect.get(i, t, c));
|
||||
}, 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 (m(r(t), true), !a)
|
||||
m(r(j), true);
|
||||
if (w(r(t), true), !a)
|
||||
w(r(k), true);
|
||||
}
|
||||
return u;
|
||||
}, deleteProperty(i, t) {
|
||||
let c = Reflect.deleteProperty(i, t);
|
||||
if (c)
|
||||
m(r(t), true), m(r(j), true);
|
||||
w(r(t), true), w(r(k), true);
|
||||
return c;
|
||||
}, ownKeys(i) {
|
||||
return m(r(j)), Reflect.ownKeys(i);
|
||||
return w(r(k)), Reflect.ownKeys(i);
|
||||
} });
|
||||
return I.set(e, o), o;
|
||||
};
|
||||
var T = (e, s) => {
|
||||
var C = (e, s) => {
|
||||
if (s === undefined) {
|
||||
let r = x(e);
|
||||
return r(), () => b(r);
|
||||
return r(), () => g(r);
|
||||
}
|
||||
let n = x(() => {
|
||||
let r = Array.isArray(e) ? e.map((o) => o()) : e();
|
||||
K(() => s(r));
|
||||
});
|
||||
return n(), () => b(n);
|
||||
return n(), () => g(n);
|
||||
};
|
||||
var U = (e) => {
|
||||
if (!e)
|
||||
@@ -312,14 +317,14 @@
|
||||
if (e._cleanups)
|
||||
e._cleanups.forEach((s) => s()), e._cleanups.clear();
|
||||
if (e._ownerEffect)
|
||||
b(e._ownerEffect);
|
||||
g(e._ownerEffect);
|
||||
if (e.childNodes)
|
||||
e.childNodes.forEach((s) => U(s));
|
||||
};
|
||||
var J = /^\s*(javascript|data|vbscript):/i;
|
||||
var Q = new Set(["src", "href", "formaction", "action", "background", "code", "archive"]);
|
||||
var X = (e) => Q.has(e) || e.startsWith("on");
|
||||
var L = (e, s) => {
|
||||
var B = (e, s) => {
|
||||
if (s == null || s === false)
|
||||
return null;
|
||||
if (X(e)) {
|
||||
@@ -330,9 +335,9 @@
|
||||
return s;
|
||||
};
|
||||
var A = (e, s = {}, n = []) => {
|
||||
if (s instanceof Node || g(s) || !B(s))
|
||||
if (s instanceof Node || b(s) || !O(s))
|
||||
n = s, s = {};
|
||||
if (w(e)) {
|
||||
if (_(e)) {
|
||||
let t = x(() => {
|
||||
let f = e(s, { children: n, emit: (u, ...h) => s[`on${u[0].toUpperCase()}${u.slice(1)}`]?.(...h) });
|
||||
return t._result = f, f;
|
||||
@@ -341,22 +346,22 @@
|
||||
let c = t._result;
|
||||
if (c == null)
|
||||
return null;
|
||||
let l = c instanceof Node || g(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => {
|
||||
if (B(f) && !f._isRuntime)
|
||||
let l = c instanceof Node || b(c) && c.every((f) => f instanceof Node) ? c : E.createTextNode(String(c)), a = (f) => {
|
||||
if (O(f) && !f._isRuntime)
|
||||
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);
|
||||
o._cleanups = new Set;
|
||||
for (let t of Object.keys(s)) {
|
||||
let c = s[t];
|
||||
if (t === "ref") {
|
||||
w(c) ? c(o) : c.current = o;
|
||||
_(c) ? c(o) : c.current = o;
|
||||
continue;
|
||||
}
|
||||
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);
|
||||
continue;
|
||||
}
|
||||
@@ -364,10 +369,10 @@
|
||||
let l = t.slice(2).toLowerCase();
|
||||
o.addEventListener(l, c);
|
||||
let a = () => o.removeEventListener(l, c);
|
||||
o._cleanups.add(a), v(a);
|
||||
} else if (w(c)) {
|
||||
o._cleanups.add(a), S(a);
|
||||
} else if (_(c)) {
|
||||
let l = x(() => {
|
||||
let a = L(t, c());
|
||||
let a = B(t, c());
|
||||
if (t === "class")
|
||||
o.className = a || "";
|
||||
else if (a == null)
|
||||
@@ -379,12 +384,12 @@
|
||||
else
|
||||
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";
|
||||
o.addEventListener(a, (f) => c(f.target[t]));
|
||||
}
|
||||
} else {
|
||||
let l = L(t, c);
|
||||
let l = B(t, c);
|
||||
if (l != null)
|
||||
if (t === "style" && typeof l === "string")
|
||||
o.setAttribute("style", l);
|
||||
@@ -395,13 +400,13 @@
|
||||
}
|
||||
}
|
||||
let i = (t) => {
|
||||
if (g(t))
|
||||
if (b(t))
|
||||
return t.forEach(i);
|
||||
if (w(t)) {
|
||||
if (_(t)) {
|
||||
let c = E.createTextNode("");
|
||||
o.appendChild(c);
|
||||
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) => {
|
||||
if (p._isRuntime)
|
||||
p.destroy();
|
||||
@@ -421,7 +426,7 @@
|
||||
}
|
||||
l = u;
|
||||
});
|
||||
a(), o._cleanups.add(() => b(a)), v(() => b(a));
|
||||
a(), o._cleanups.add(() => g(a)), S(() => g(a));
|
||||
} else {
|
||||
let c = V(t);
|
||||
if (o.appendChild(c), c._mounts)
|
||||
@@ -430,15 +435,15 @@
|
||||
};
|
||||
return i(n), o;
|
||||
};
|
||||
var C = (e) => {
|
||||
let s = new Set, n = _, r = d, o = E.createElement("div");
|
||||
o.style.display = "contents", o.setAttribute("role", "presentation"), _ = { _cleanups: s }, d = null;
|
||||
var j = (e) => {
|
||||
let s = new Set, n = m, r = d, o = E.createElement("div");
|
||||
o.style.display = "contents", o.setAttribute("role", "presentation"), m = { _cleanups: s }, d = null;
|
||||
let i = (t) => {
|
||||
if (!t)
|
||||
return;
|
||||
if (t._isRuntime)
|
||||
s.add(t.destroy), o.appendChild(t.container);
|
||||
else if (g(t))
|
||||
else if (b(t))
|
||||
t.forEach(i);
|
||||
else
|
||||
o.appendChild(t instanceof Node ? t : E.createTextNode(String(t == null ? "" : t)));
|
||||
@@ -446,7 +451,7 @@
|
||||
try {
|
||||
i(e({ onCleanup: (t) => s.add(t) }));
|
||||
} finally {
|
||||
_ = n, d = r;
|
||||
m = n, d = r;
|
||||
}
|
||||
return { _isRuntime: true, container: o, destroy: () => {
|
||||
s.forEach((t) => t()), U(o), o.remove();
|
||||
@@ -454,22 +459,22 @@
|
||||
};
|
||||
var F = (e, s, n = 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)
|
||||
i.destroy(), i = null;
|
||||
let c = t ? s : n;
|
||||
if (c)
|
||||
i = C(() => w(c) ? c() : c), o.insertBefore(i.container, r);
|
||||
}), v(() => i?.destroy()), o;
|
||||
i = j(() => _(c) ? c() : c), o.insertBefore(i.container, r);
|
||||
}), S(() => i?.destroy()), o;
|
||||
};
|
||||
var H = (e, s, n) => {
|
||||
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 || [];
|
||||
for (let u = 0;u < a.length; u++) {
|
||||
let h = a[u], p = n ? h?.[n] ?? u : h?.id ?? u, y = i.get(p);
|
||||
if (!y)
|
||||
y = C(() => s(h, u));
|
||||
y = j(() => s(h, u));
|
||||
else
|
||||
i.delete(p);
|
||||
c.set(p, y), l.push(y);
|
||||
@@ -485,11 +490,11 @@
|
||||
i = c;
|
||||
}), o;
|
||||
};
|
||||
var S = (e) => {
|
||||
var N = (e) => {
|
||||
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;
|
||||
return T([n], () => {
|
||||
return C([n], () => {
|
||||
let t = n(), c = e.find((l) => {
|
||||
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]);
|
||||
@@ -500,38 +505,56 @@
|
||||
c.path.split("/").filter(Boolean).forEach((a, f) => {
|
||||
if (a[0] === ":")
|
||||
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;
|
||||
};
|
||||
S.params = P({});
|
||||
S.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/");
|
||||
S.back = () => window.history.back();
|
||||
S.path = () => window.location.hash.replace(/^#/, "") || "/";
|
||||
N.params = P({});
|
||||
N.to = (e) => window.location.hash = e.replace(/^#?\/?/, "#/");
|
||||
N.back = () => window.history.back();
|
||||
N.path = () => window.location.hash.replace(/^#/, "") || "/";
|
||||
var Y = (e, s) => {
|
||||
let n = typeof s === "string" ? E.querySelector(s) : s;
|
||||
if (!n)
|
||||
return;
|
||||
if (k.has(n))
|
||||
k.get(n).destroy();
|
||||
let r = C(w(e) ? e : () => e);
|
||||
return n.replaceChildren(r.container), k.set(n, r), r;
|
||||
if (L.has(n))
|
||||
L.get(n).destroy();
|
||||
let r = j(_(e) ? e : () => e);
|
||||
return n.replaceChildren(r.container), L.set(n, r), r;
|
||||
};
|
||||
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);
|
||||
});
|
||||
|
||||
// sigpro-helpers.js
|
||||
var get = (val) => typeof val === "function" ? val() : val;
|
||||
// sigpro-ui.js
|
||||
var val = (val2) => typeof val2 === "function" ? val2() : val2;
|
||||
var getBy = (item, field = "label") => item && typeof item === "object" ? item[field] : item;
|
||||
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 ? get(items) : get(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 ? val(items) : val(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 hide = () => document.activeElement?.blur();
|
||||
|
||||
// sigpro-ui.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("en");
|
||||
var Locale = (t) => currentLocale(t);
|
||||
var tt = (t) => () => i18n[currentLocale()][t] || t;
|
||||
var Accordion = (p) => {
|
||||
const name = p.name || rand("acc");
|
||||
return H(p.items, (it) => {
|
||||
@@ -546,13 +569,13 @@
|
||||
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 Autocomplete = ({ items, value, onselect, placeholder = "...", ...props }) => {
|
||||
const query = P(get(value) || "");
|
||||
const query = P(val(value) || "");
|
||||
const filtered = P(() => filterBy(items, query()));
|
||||
const pick = (item) => {
|
||||
const display = getBy(item);
|
||||
const actual = typeof item === "string" ? item : item.value;
|
||||
query(display);
|
||||
if (isFn(value))
|
||||
if (_(value))
|
||||
value(actual);
|
||||
onselect?.(item);
|
||||
hide();
|
||||
@@ -565,7 +588,7 @@
|
||||
left: A("span", { class: "icon-[lucide--search]" }),
|
||||
oninput: (e) => {
|
||||
query(e.target.value);
|
||||
if (isFn(value))
|
||||
if (_(value))
|
||||
value(e.target.value);
|
||||
}
|
||||
})),
|
||||
@@ -591,8 +614,8 @@
|
||||
const now = new Date;
|
||||
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 rangeMode = () => get(p.range) === true;
|
||||
const current = () => get(p.value);
|
||||
const rangeMode = () => val(p.range) === true;
|
||||
const current = () => val(p.value);
|
||||
const selectDate = (date) => {
|
||||
const s = fmt(date);
|
||||
const v2 = current();
|
||||
@@ -623,7 +646,7 @@
|
||||
const HourSlider = ({ value: hVal, onChange: onH }) => A("div", { class: "flex-1" }, [
|
||||
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("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", {
|
||||
@@ -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 Checkbox = (p) => A("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) });
|
||||
var Colorpicker = (p) => {
|
||||
const current = () => get(p.value) || "#000000";
|
||||
const current = () => val(p.value) || "#000000";
|
||||
return Dropdown({}, [
|
||||
DropdownButton({ class: "btn" }, [
|
||||
A("div", { class: "size-5 rounded-sm", style: () => `background-color: ${current()}` }),
|
||||
@@ -703,13 +726,13 @@
|
||||
DropdownContent({ class: "p-0" }, ColorPalette({
|
||||
value: p.value,
|
||||
onchange: (c) => {
|
||||
isFn(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
_(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
}
|
||||
}))
|
||||
]);
|
||||
};
|
||||
var ColorPalette = (p) => {
|
||||
const current = () => get(p.value) || "#000000";
|
||||
const current = () => val(p.value) || "#000000";
|
||||
const palette = [
|
||||
"#000",
|
||||
"#1A1A1A",
|
||||
@@ -777,7 +800,7 @@
|
||||
"#fae8ff"
|
||||
];
|
||||
const pick = (c) => {
|
||||
isFn(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
_(p.value) ? p.value(c) : p.onchange?.(c);
|
||||
hide();
|
||||
};
|
||||
return A("div", {
|
||||
@@ -796,9 +819,9 @@
|
||||
};
|
||||
var Datepicker = (p) => {
|
||||
const displayValue = P("");
|
||||
const rangeMode = () => get(p.range) === true;
|
||||
T(() => {
|
||||
const v2 = get(p.value);
|
||||
const rangeMode = () => val(p.range) === true;
|
||||
C(() => {
|
||||
const v2 = val(p.value);
|
||||
if (!v2)
|
||||
return displayValue("");
|
||||
let text = "";
|
||||
@@ -814,12 +837,12 @@
|
||||
}
|
||||
displayValue(text);
|
||||
});
|
||||
const handleChange = (val) => {
|
||||
if (isFn(p.value))
|
||||
p.value(val);
|
||||
const handleChange = (val2) => {
|
||||
if (_(p.value))
|
||||
p.value(val2);
|
||||
else
|
||||
p.onChange?.(val);
|
||||
if (!rangeMode() || val?.end != null)
|
||||
p.onChange?.(val2);
|
||||
if (!rangeMode() || val2?.end != null)
|
||||
hide();
|
||||
};
|
||||
return Dropdown({ class: cls("w-full", p.class) }, [
|
||||
@@ -838,7 +861,7 @@
|
||||
onmousedown: (e) => {
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
if (isFn(p.value))
|
||||
if (_(p.value))
|
||||
p.value(null);
|
||||
else
|
||||
p.onChange?.(null);
|
||||
@@ -855,7 +878,7 @@
|
||||
]);
|
||||
};
|
||||
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 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) });
|
||||
@@ -879,17 +902,17 @@
|
||||
}
|
||||
const updated = [...files(), ...arr];
|
||||
files(updated);
|
||||
if (isFn(p.onselect))
|
||||
if (_(p.onselect))
|
||||
p.onselect(updated);
|
||||
else if (isFn(p.value))
|
||||
else if (_(p.value))
|
||||
p.value(updated);
|
||||
};
|
||||
const remove = (idx) => {
|
||||
const updated = files().filter((_2, i) => i !== idx);
|
||||
files(updated);
|
||||
if (isFn(p.onselect))
|
||||
if (_(p.onselect))
|
||||
p.onselect(updated);
|
||||
else if (isFn(p.value))
|
||||
else if (_(p.value))
|
||||
p.value(updated);
|
||||
};
|
||||
return A("div", { class: cls("fieldset w-full p-0", p.class) }, [
|
||||
@@ -944,7 +967,7 @@
|
||||
const showPassword = P(false);
|
||||
const isPassword = p.type === "password";
|
||||
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" : "" }, [
|
||||
float ? A("span", {}, label2) : null,
|
||||
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 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 Menu = (p) => {
|
||||
if (p.children !== undefined)
|
||||
@@ -971,7 +994,7 @@
|
||||
const { items } = p;
|
||||
const render = (item) => item.children ? A("li", {}, A("details", { open: item.open || undefined }, [
|
||||
A("summary", {}, getBy(item)),
|
||||
A("ul", {}, H(() => get(item.children) || [], render))
|
||||
A("ul", {}, H(() => val(item.children) || [], render))
|
||||
])) : A("li", {}, A("a", {
|
||||
href: item.href,
|
||||
onclick: item.onclick ? (e) => {
|
||||
@@ -980,17 +1003,17 @@
|
||||
item.onclick(e);
|
||||
} : null
|
||||
}, 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) => {
|
||||
let dialogRef = null;
|
||||
T(() => {
|
||||
const isOpen = get(p.open);
|
||||
C(() => {
|
||||
const isOpen = val(p.open);
|
||||
if (!dialogRef)
|
||||
return;
|
||||
isOpen ? dialogRef.showModal() : dialogRef.hide();
|
||||
});
|
||||
const close = () => isFn(p.open) && p.open(false);
|
||||
const close = () => _(p.open) && p.open(false);
|
||||
return A("dialog", {
|
||||
...p,
|
||||
ref: (el) => dialogRef = el,
|
||||
@@ -1012,17 +1035,17 @@
|
||||
};
|
||||
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 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 Range = (p) => A("input", { ...p, type: "range", class: cls("range", p.class) });
|
||||
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) => {
|
||||
if (c !== undefined)
|
||||
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 opts = () => {
|
||||
const raw = get(items) || [];
|
||||
const raw = val(items) || [];
|
||||
const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: "" }] : [];
|
||||
return [...ph, ...raw];
|
||||
};
|
||||
@@ -1032,12 +1055,12 @@
|
||||
!float && label2 ? A("span", { class: "label" }, label2) : null,
|
||||
left ?? null,
|
||||
A("select", {
|
||||
value: () => get(value),
|
||||
onchange: (e) => isFn(value) ? value(e.target.value) : rest.onchange?.(e)
|
||||
value: () => val(value),
|
||||
onchange: (e) => _(value) ? value(e.target.value) : rest.onchange?.(e)
|
||||
}, 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");
|
||||
return A("option", { value: val, disabled: item.disabled || undefined }, lab);
|
||||
return A("option", { value: val2, disabled: item.disabled || undefined }, lab);
|
||||
})),
|
||||
right ?? null
|
||||
]),
|
||||
@@ -1056,14 +1079,14 @@
|
||||
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 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 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 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 body = A("tbody", {}, () => {
|
||||
const list = get(items) || [];
|
||||
const list = val(items) || [];
|
||||
return list.map((it, idx) => A("tr", {}, columns.map((c) => {
|
||||
const v2 = c.render ? c.render(it, idx) : it[c.key];
|
||||
return A("td", { class: c.class }, v2);
|
||||
@@ -1077,16 +1100,16 @@
|
||||
return A("div", { ...rest2, class: cls("tabs", className2) }, c);
|
||||
}
|
||||
const { items, activeIndex, onClose, class: className, ...rest } = p;
|
||||
const get2 = (x2) => isFn(x2) ? x2() : x2;
|
||||
const closeH = onClose || (isFn(items) ? (idx, item) => {
|
||||
const arr = get2(items);
|
||||
const get = (x2) => _(x2) ? x2() : x2;
|
||||
const closeH = onClose || (_(items) ? (idx, item) => {
|
||||
const arr = val(items);
|
||||
const newArr = arr.filter((_2, i) => i !== idx);
|
||||
items(newArr);
|
||||
if (activeIndex() >= newArr.length)
|
||||
activeIndex(Math.max(0, newArr.length - 1));
|
||||
} : null);
|
||||
return A("div", { ...rest, class: cls("tabs", className) }, () => {
|
||||
const list = get2(items) || [];
|
||||
const list = val(items) || [];
|
||||
return list.flatMap((it, idx) => {
|
||||
const isActive = () => activeIndex() === idx;
|
||||
const button = A("button", {
|
||||
@@ -1109,7 +1132,7 @@
|
||||
const contentDiv = A("div", {
|
||||
class: "tab-content bg-base-100 border-base-300 p-6",
|
||||
style: () => `display: ${isActive() ? "block" : "none"};`
|
||||
}, isFn(it.content) ? it.content() : it.content);
|
||||
}, _(it.content) ? it.content() : it.content);
|
||||
return [button, contentDiv];
|
||||
});
|
||||
});
|
||||
@@ -1146,7 +1169,7 @@
|
||||
}, 300);
|
||||
};
|
||||
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;
|
||||
return A("div", {
|
||||
class: () => {
|
||||
@@ -1172,12 +1195,6 @@
|
||||
};
|
||||
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);
|
||||
|
||||
// sigpro-editor.js
|
||||
var exports_sigpro_editor = {};
|
||||
__export(exports_sigpro_editor, {
|
||||
Editor: () => Editor
|
||||
});
|
||||
var Editor = (p) => {
|
||||
const { value, class: extraClass } = p;
|
||||
let editorRef = null;
|
||||
@@ -1209,19 +1226,19 @@
|
||||
if (!editorRef)
|
||||
return;
|
||||
const html = editorRef.innerHTML;
|
||||
if (isFn(value))
|
||||
if (_(value))
|
||||
value(html);
|
||||
else
|
||||
p.onchange?.(html);
|
||||
triggerRefresh();
|
||||
};
|
||||
const exec = (cmd, val = null) => {
|
||||
const exec = (cmd, val2 = null) => {
|
||||
if (!editorRef)
|
||||
return;
|
||||
editorRef.focus();
|
||||
if (savedRange)
|
||||
restoreSelection();
|
||||
document.execCommand(cmd, false, val);
|
||||
document.execCommand(cmd, false, val2);
|
||||
savedRange = null;
|
||||
notify();
|
||||
};
|
||||
@@ -1250,7 +1267,7 @@
|
||||
};
|
||||
reader.readAsDataURL(file);
|
||||
};
|
||||
const queryState = (cmd, val = null) => {
|
||||
const queryState = (cmd, val2 = null) => {
|
||||
refreshTick();
|
||||
if (!editorRef || isSource())
|
||||
return false;
|
||||
@@ -1258,7 +1275,7 @@
|
||||
if (cmd === "formatBlock") {
|
||||
let node = window.getSelection().getRangeAt(0).commonAncestorContainer;
|
||||
while (node && node !== editorRef) {
|
||||
if (node.nodeType === 1 && node.tagName === val)
|
||||
if (node.nodeType === 1 && node.tagName === val2)
|
||||
return true;
|
||||
node = node.parentNode;
|
||||
}
|
||||
@@ -1354,7 +1371,7 @@
|
||||
ref: (el) => {
|
||||
if (!editorRef && el) {
|
||||
editorRef = el;
|
||||
el.innerHTML = get(value) || "";
|
||||
el.innerHTML = val(value) || "";
|
||||
document.execCommand("defaultParagraphSeparator", false, "br");
|
||||
el.addEventListener("click", (e) => {
|
||||
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
|
||||
var Components = {
|
||||
...exports_sigpro_ui,
|
||||
...exports_sigpro_editor
|
||||
};
|
||||
var Utils = {
|
||||
Locale,
|
||||
tt,
|
||||
hide,
|
||||
get
|
||||
};
|
||||
var Components = { ...exports_sigpro_ui };
|
||||
if (typeof window !== "undefined") {
|
||||
Object.entries({ ...Components, ...Utils }).forEach(([name, value]) => {
|
||||
Object.entries({ ...Components }).forEach(([name, value]) => {
|
||||
Object.defineProperty(window, name, {
|
||||
value,
|
||||
writable: false,
|
||||
|
||||
2
dist/sigpro-ui.min.css
vendored
2
dist/sigpro-ui.min.css
vendored
File diff suppressed because one or more lines are too long
4
dist/sigpro-ui.min.js
vendored
4
dist/sigpro-ui.min.js
vendored
File diff suppressed because one or more lines are too long
@@ -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="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>
|
||||
<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 class="absolute top-0 left-1/2 -translate-x-1/2 w-full h-full -z-0 opacity-10 pointer-events-none">
|
||||
|
||||
2
docs/sigpro-ui.min.css
vendored
2
docs/sigpro-ui.min.css
vendored
File diff suppressed because one or more lines are too long
4
docs/sigpro-ui.min.js
vendored
4
docs/sigpro-ui.min.js
vendored
File diff suppressed because one or more lines are too long
938
index.d.ts
vendored
938
index.d.ts
vendored
@@ -1,465 +1,482 @@
|
||||
declare module 'sigpro-ui' {
|
||||
type Signal<T> = {
|
||||
(): T;
|
||||
(value: T | ((prev: T) => T)): void;
|
||||
};
|
||||
|
||||
type ComponentChild = Node | string | number | boolean | null | undefined;
|
||||
type ComponentChildren = ComponentChild | ComponentChild[] | (() => ComponentChild | ComponentChildren);
|
||||
|
||||
interface BaseProps {
|
||||
class?: string | (() => string);
|
||||
style?: string | (() => string);
|
||||
id?: string | (() => string);
|
||||
[key: string]: any;
|
||||
}
|
||||
|
||||
interface AccordionItem {
|
||||
title?: string | (() => string);
|
||||
content?: string | (() => string);
|
||||
open?: boolean;
|
||||
classTitle?: string;
|
||||
classContent?: string;
|
||||
}
|
||||
interface AccordionProps extends BaseProps {
|
||||
items: AccordionItem[] | (() => AccordionItem[]);
|
||||
name?: string;
|
||||
}
|
||||
function Accordion(props: AccordionProps): Node;
|
||||
|
||||
interface AlertProps extends BaseProps {}
|
||||
function Alert(props: AlertProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface AutocompleteProps extends BaseProps {
|
||||
items: (string | { label: string; value?: string })[] | (() => (string | { label: string; value?: string })[]);
|
||||
value?: Signal<string> | string;
|
||||
onselect?: (item: string | { label: string; value?: string }) => void;
|
||||
placeholder?: string;
|
||||
}
|
||||
function Autocomplete(props: AutocompleteProps): Node;
|
||||
|
||||
interface BadgeProps extends BaseProps {}
|
||||
function Badge(props: BadgeProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ButtonProps extends BaseProps {}
|
||||
function Button(props: ButtonProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DateRange {
|
||||
start: string;
|
||||
end: string | null;
|
||||
startHour?: number;
|
||||
endHour?: number;
|
||||
}
|
||||
interface CalendarProps extends BaseProps {
|
||||
value?: Signal<string | DateRange> | string | DateRange;
|
||||
range?: boolean | (() => boolean);
|
||||
hour?: boolean;
|
||||
onChange?: (value: string | DateRange | null) => void;
|
||||
onAccept?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
function Calendar(props: CalendarProps): Node;
|
||||
|
||||
interface CardProps extends BaseProps {}
|
||||
function Card(props: CardProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CardTitleProps extends BaseProps {}
|
||||
function CardTitle(props: CardTitleProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CardBodyProps extends BaseProps {}
|
||||
function CardBody(props: CardBodyProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CardActionsProps extends BaseProps {}
|
||||
function CardActions(props: CardActionsProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CarouselProps extends BaseProps {}
|
||||
function Carousel(props: CarouselProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CarouselItemProps extends BaseProps {}
|
||||
function CarouselItem(props: CarouselItemProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatProps extends BaseProps {}
|
||||
function Chat(props: ChatProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatBubbleProps extends BaseProps {}
|
||||
function ChatBubble(props: ChatBubbleProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatFooterProps extends BaseProps {}
|
||||
function ChatFooter(props: ChatFooterProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatHeaderProps extends BaseProps {}
|
||||
function ChatHeader(props: ChatHeaderProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatImageProps extends BaseProps {}
|
||||
function ChatImage(props: ChatImageProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CheckboxProps extends BaseProps {}
|
||||
function Checkbox(props: CheckboxProps): Node;
|
||||
|
||||
interface ColorpickerProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
label?: string | (() => string);
|
||||
onchange?: (color: string) => void;
|
||||
}
|
||||
function Colorpicker(props: ColorpickerProps): Node;
|
||||
|
||||
interface ColorPaletteProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
onchange?: (color: string) => void;
|
||||
}
|
||||
function ColorPalette(props: ColorPaletteProps): Node;
|
||||
|
||||
interface DatepickerProps extends BaseProps {
|
||||
value?: Signal<string | DateRange> | string | DateRange;
|
||||
range?: boolean | (() => boolean);
|
||||
hour?: boolean;
|
||||
placeholder?: string;
|
||||
onChange?: (value: string | DateRange | null) => void;
|
||||
onAccept?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
function Datepicker(props: DatepickerProps): Node;
|
||||
|
||||
interface DividerProps extends BaseProps {}
|
||||
function Divider(props: DividerProps): Node;
|
||||
|
||||
interface DrawerProps extends BaseProps {}
|
||||
function Drawer(props: DrawerProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DrawerToggleProps extends BaseProps {
|
||||
checked?: Signal<boolean> | boolean;
|
||||
}
|
||||
function DrawerToggle(props: DrawerToggleProps): Node;
|
||||
|
||||
interface DrawerContentProps extends BaseProps {}
|
||||
function DrawerContent(props: DrawerContentProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DrawerSideProps extends BaseProps {}
|
||||
function DrawerSide(props: DrawerSideProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DrawerOverlayProps extends BaseProps {
|
||||
for?: string;
|
||||
}
|
||||
function DrawerOverlay(props: DrawerOverlayProps): Node;
|
||||
|
||||
interface DropdownProps extends BaseProps {
|
||||
open?: Signal<boolean>;
|
||||
}
|
||||
function Dropdown(props: DropdownProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DropdownButtonProps extends BaseProps {}
|
||||
function DropdownButton(props: DropdownButtonProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DropdownContentProps extends BaseProps {}
|
||||
function DropdownContent(props: DropdownContentProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface FabProps extends BaseProps {
|
||||
icon?: string;
|
||||
}
|
||||
function Fab(props: FabProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface FieldsetProps extends BaseProps {
|
||||
label?: string | (() => string);
|
||||
}
|
||||
function Fieldset(props: FieldsetProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface FileinputProps extends BaseProps {
|
||||
max?: number;
|
||||
accept?: string;
|
||||
onselect?: (files: File[]) => void;
|
||||
value?: Signal<File[]>;
|
||||
}
|
||||
function Fileinput(props: FileinputProps): Node;
|
||||
|
||||
interface IconProps {
|
||||
class?: string;
|
||||
}
|
||||
function Icon(props: string | IconProps): Node;
|
||||
|
||||
interface IndicatorProps extends BaseProps {
|
||||
value?: string | number | (() => string | number);
|
||||
}
|
||||
function Indicator(props: IndicatorProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface InputProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
type?: string;
|
||||
placeholder?: string;
|
||||
label?: string | (() => string);
|
||||
float?: boolean;
|
||||
left?: ComponentChild;
|
||||
right?: ComponentChild;
|
||||
rule?: string;
|
||||
hint?: string | (() => string);
|
||||
}
|
||||
function Input(props: InputProps): Node;
|
||||
|
||||
interface KbdProps extends BaseProps {}
|
||||
function Kbd(props: KbdProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ListProps extends BaseProps {}
|
||||
function List(props: ListProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ListRowsProps extends BaseProps {
|
||||
items?: any[] | (() => any[]);
|
||||
render?: (item: any, index: number) => ComponentChild;
|
||||
}
|
||||
function ListRows(props: ListRowsProps): Node;
|
||||
|
||||
interface LoadingProps extends BaseProps {}
|
||||
function Loading(props: LoadingProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface MenuItem {
|
||||
label?: string | (() => string);
|
||||
href?: string;
|
||||
onclick?: (e: MouseEvent) => void;
|
||||
children?: MenuItem[] | (() => MenuItem[]);
|
||||
open?: boolean;
|
||||
}
|
||||
interface MenuProps extends BaseProps {
|
||||
items?: MenuItem[] | (() => MenuItem[]);
|
||||
children?: ComponentChildren;
|
||||
}
|
||||
function Menu(props: MenuProps): Node;
|
||||
|
||||
interface ModalProps extends BaseProps {
|
||||
open?: Signal<boolean> | boolean;
|
||||
title?: string | (() => string);
|
||||
actions?: ComponentChild;
|
||||
}
|
||||
function Modal(props: ModalProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface NavbarProps extends BaseProps {}
|
||||
function Navbar(props: NavbarProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ProgressProps extends BaseProps {
|
||||
value?: number | (() => number);
|
||||
max?: number;
|
||||
}
|
||||
function Progress(props: ProgressProps): Node;
|
||||
|
||||
interface RadialProps extends BaseProps {
|
||||
value?: number;
|
||||
}
|
||||
function Radial(props: RadialProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface RadioProps extends BaseProps {
|
||||
name?: string;
|
||||
checked?: boolean | (() => boolean);
|
||||
}
|
||||
function Radio(props: RadioProps): Node;
|
||||
|
||||
interface RangeProps extends BaseProps {
|
||||
value?: Signal<number> | number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
function Range(props: RangeProps): Node;
|
||||
|
||||
interface RatingProps extends BaseProps {}
|
||||
function Rating(props: RatingProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface RatingItemsProps extends BaseProps {
|
||||
count: number;
|
||||
name?: string;
|
||||
value?: Signal<number> | number;
|
||||
onchange?: (value: number) => void;
|
||||
}
|
||||
function RatingItems(props: RatingItemsProps): Node;
|
||||
|
||||
interface SelectOption {
|
||||
label?: string;
|
||||
value?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
interface SelectProps extends BaseProps {
|
||||
items?: SelectOption[] | (() => SelectOption[]);
|
||||
value?: Signal<string> | string;
|
||||
placeholder?: string;
|
||||
placeholderDisabled?: boolean;
|
||||
label?: string | (() => string);
|
||||
float?: boolean;
|
||||
left?: ComponentChild;
|
||||
right?: ComponentChild;
|
||||
hint?: string | (() => string);
|
||||
onchange?: (e: Event) => void;
|
||||
}
|
||||
function Select(props: SelectProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SkeletonProps extends BaseProps {}
|
||||
function Skeleton(props: SkeletonProps): Node;
|
||||
|
||||
interface SkeletonTextProps extends BaseProps {}
|
||||
function SkeletonText(props: SkeletonTextProps): Node;
|
||||
|
||||
interface StackProps extends BaseProps {}
|
||||
function Stack(props: StackProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface StatProps extends BaseProps {
|
||||
title?: string | (() => string);
|
||||
value?: string | number | (() => string | number);
|
||||
desc?: string | (() => string);
|
||||
}
|
||||
function Stat(props: StatProps): Node;
|
||||
|
||||
interface StatsProps extends BaseProps {}
|
||||
function Stats(props: StatsProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface StepsProps extends BaseProps {}
|
||||
function Steps(props: StepsProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface StepProps extends BaseProps {
|
||||
dataContent?: string;
|
||||
}
|
||||
function Step(props: StepProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SwapProps extends BaseProps {}
|
||||
function Swap(props: SwapProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SwapToggleProps extends BaseProps {
|
||||
value?: Signal<boolean> | boolean;
|
||||
}
|
||||
function SwapToggle(props: SwapToggleProps): Node;
|
||||
|
||||
interface SwapOnProps extends BaseProps {}
|
||||
function SwapOn(props: SwapOnProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SwapOffProps extends BaseProps {}
|
||||
function SwapOff(props: SwapOffProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface TableProps extends BaseProps {}
|
||||
function Table(props: TableProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface TableColumn {
|
||||
label?: string;
|
||||
key?: string;
|
||||
render?: (item: any, index: number) => ComponentChild;
|
||||
class?: string;
|
||||
}
|
||||
interface TableItemsProps extends BaseProps {
|
||||
items?: any[] | (() => any[]);
|
||||
columns?: TableColumn[];
|
||||
header?: boolean;
|
||||
}
|
||||
function TableItems(props: TableItemsProps): Node;
|
||||
|
||||
interface TabItem {
|
||||
label?: string | (() => string);
|
||||
content?: ComponentChild | (() => ComponentChild);
|
||||
class?: string;
|
||||
closable?: boolean;
|
||||
onclick?: (e: MouseEvent) => void;
|
||||
}
|
||||
interface TabsProps extends BaseProps {
|
||||
items?: TabItem[] | (() => TabItem[]);
|
||||
activeIndex?: Signal<number>;
|
||||
onClose?: (index: number, item: TabItem) => void;
|
||||
children?: ComponentChildren;
|
||||
}
|
||||
function Tabs(props: TabsProps): Node;
|
||||
|
||||
interface TextareaProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
placeholder?: string;
|
||||
}
|
||||
function Textarea(props: TextareaProps): Node;
|
||||
|
||||
interface TextrotateProps extends BaseProps {}
|
||||
function Textrotate(props: TextrotateProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface TimelineProps extends BaseProps {}
|
||||
function Timeline(props: TimelineProps, children?: ComponentChildren): Node;
|
||||
|
||||
type ToastType = 'alert-info' | 'alert-success' | 'alert-warning' | 'alert-error';
|
||||
function Toast(message: string | (() => string), type?: ToastType, duration?: number): () => void;
|
||||
|
||||
interface ToggleProps extends BaseProps {
|
||||
checked?: Signal<boolean> | boolean;
|
||||
}
|
||||
function Toggle(props: ToggleProps): Node;
|
||||
|
||||
interface TooltipProps extends BaseProps {
|
||||
tip: string | (() => string);
|
||||
}
|
||||
function Tooltip(props: TooltipProps, children?: ComponentChildren): Node;
|
||||
|
||||
const Components: {
|
||||
Accordion: typeof Accordion;
|
||||
Alert: typeof Alert;
|
||||
Autocomplete: typeof Autocomplete;
|
||||
Badge: typeof Badge;
|
||||
Button: typeof Button;
|
||||
Calendar: typeof Calendar;
|
||||
Card: typeof Card;
|
||||
CardTitle: typeof CardTitle;
|
||||
CardBody: typeof CardBody;
|
||||
CardActions: typeof CardActions;
|
||||
Carousel: typeof Carousel;
|
||||
CarouselItem: typeof CarouselItem;
|
||||
Chat: typeof Chat;
|
||||
ChatBubble: typeof ChatBubble;
|
||||
ChatFooter: typeof ChatFooter;
|
||||
ChatHeader: typeof ChatHeader;
|
||||
ChatImage: typeof ChatImage;
|
||||
Checkbox: typeof Checkbox;
|
||||
Colorpicker: typeof Colorpicker;
|
||||
ColorPalette: typeof ColorPalette;
|
||||
Datepicker: typeof Datepicker;
|
||||
Divider: typeof Divider;
|
||||
Drawer: typeof Drawer;
|
||||
DrawerToggle: typeof DrawerToggle;
|
||||
DrawerContent: typeof DrawerContent;
|
||||
DrawerSide: typeof DrawerSide;
|
||||
DrawerOverlay: typeof DrawerOverlay;
|
||||
Dropdown: typeof Dropdown;
|
||||
DropdownButton: typeof DropdownButton;
|
||||
DropdownContent: typeof DropdownContent;
|
||||
Fab: typeof Fab;
|
||||
Fieldset: typeof Fieldset;
|
||||
Fileinput: typeof Fileinput;
|
||||
Icon: typeof Icon;
|
||||
Indicator: typeof Indicator;
|
||||
Input: typeof Input;
|
||||
Kbd: typeof Kbd;
|
||||
List: typeof List;
|
||||
ListRows: typeof ListRows;
|
||||
Loading: typeof Loading;
|
||||
Menu: typeof Menu;
|
||||
Modal: typeof Modal;
|
||||
Navbar: typeof Navbar;
|
||||
Progress: typeof Progress;
|
||||
Radial: typeof Radial;
|
||||
Radio: typeof Radio;
|
||||
Range: typeof Range;
|
||||
Rating: typeof Rating;
|
||||
RatingItems: typeof RatingItems;
|
||||
Select: typeof Select;
|
||||
Skeleton: typeof Skeleton;
|
||||
SkeletonText: typeof SkeletonText;
|
||||
Stack: typeof Stack;
|
||||
Stat: typeof Stat;
|
||||
Stats: typeof Stats;
|
||||
Steps: typeof Steps;
|
||||
Step: typeof Step;
|
||||
Swap: typeof Swap;
|
||||
SwapToggle: typeof SwapToggle;
|
||||
SwapOn: typeof SwapOn;
|
||||
SwapOff: typeof SwapOff;
|
||||
Table: typeof Table;
|
||||
TableItems: typeof TableItems;
|
||||
Tabs: typeof Tabs;
|
||||
Textarea: typeof Textarea;
|
||||
Textrotate: typeof Textrotate;
|
||||
Timeline: typeof Timeline;
|
||||
Toast: typeof Toast;
|
||||
Toggle: typeof Toggle;
|
||||
Tooltip: typeof Tooltip;
|
||||
};
|
||||
|
||||
export { Components };
|
||||
export default Components;
|
||||
type Signal<T> = {
|
||||
(): T;
|
||||
(value: T | ((prev: T) => T)): void;
|
||||
};
|
||||
|
||||
type ComponentChild = Node | string | number | boolean | null | undefined;
|
||||
type ComponentChildren = ComponentChild | ComponentChild[] | (() => ComponentChild | ComponentChildren);
|
||||
|
||||
interface BaseProps {
|
||||
class?: string | (() => string);
|
||||
style?: string | (() => string);
|
||||
id?: string | (() => string);
|
||||
[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 {
|
||||
title?: string | (() => string);
|
||||
content?: string | (() => string);
|
||||
open?: boolean;
|
||||
classTitle?: string;
|
||||
classContent?: string;
|
||||
}
|
||||
interface AccordionProps extends BaseProps {
|
||||
items: AccordionItem[] | (() => AccordionItem[]);
|
||||
name?: string;
|
||||
}
|
||||
function Accordion(props: AccordionProps): Node;
|
||||
|
||||
interface AlertProps extends BaseProps { }
|
||||
function Alert(props: AlertProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface AutocompleteProps extends BaseProps {
|
||||
items: (string | { label: string; value?: string })[] | (() => (string | { label: string; value?: string })[]);
|
||||
value?: Signal<string> | string;
|
||||
onselect?: (item: string | { label: string; value?: string }) => void;
|
||||
placeholder?: string;
|
||||
}
|
||||
function Autocomplete(props: AutocompleteProps): Node;
|
||||
|
||||
interface BadgeProps extends BaseProps { }
|
||||
function Badge(props: BadgeProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ButtonProps extends BaseProps { }
|
||||
function Button(props: ButtonProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DateRange {
|
||||
start: string;
|
||||
end: string | null;
|
||||
startHour?: number;
|
||||
endHour?: number;
|
||||
}
|
||||
interface CalendarProps extends BaseProps {
|
||||
value?: Signal<string | DateRange> | string | DateRange;
|
||||
range?: boolean | (() => boolean);
|
||||
hour?: boolean;
|
||||
onChange?: (value: string | DateRange | null) => void;
|
||||
onAccept?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
function Calendar(props: CalendarProps): Node;
|
||||
|
||||
interface CardProps extends BaseProps { }
|
||||
function Card(props: CardProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CardTitleProps extends BaseProps { }
|
||||
function CardTitle(props: CardTitleProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CardBodyProps extends BaseProps { }
|
||||
function CardBody(props: CardBodyProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CardActionsProps extends BaseProps { }
|
||||
function CardActions(props: CardActionsProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CarouselProps extends BaseProps { }
|
||||
function Carousel(props: CarouselProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CarouselItemProps extends BaseProps { }
|
||||
function CarouselItem(props: CarouselItemProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatProps extends BaseProps { }
|
||||
function Chat(props: ChatProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatBubbleProps extends BaseProps { }
|
||||
function ChatBubble(props: ChatBubbleProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatFooterProps extends BaseProps { }
|
||||
function ChatFooter(props: ChatFooterProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatHeaderProps extends BaseProps { }
|
||||
function ChatHeader(props: ChatHeaderProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ChatImageProps extends BaseProps { }
|
||||
function ChatImage(props: ChatImageProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface CheckboxProps extends BaseProps { }
|
||||
function Checkbox(props: CheckboxProps): Node;
|
||||
|
||||
interface ColorpickerProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
label?: string | (() => string);
|
||||
onchange?: (color: string) => void;
|
||||
}
|
||||
function Colorpicker(props: ColorpickerProps): Node;
|
||||
|
||||
interface ColorPaletteProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
onchange?: (color: string) => void;
|
||||
}
|
||||
function ColorPalette(props: ColorPaletteProps): Node;
|
||||
|
||||
interface DatepickerProps extends BaseProps {
|
||||
value?: Signal<string | DateRange> | string | DateRange;
|
||||
range?: boolean | (() => boolean);
|
||||
hour?: boolean;
|
||||
placeholder?: string;
|
||||
onChange?: (value: string | DateRange | null) => void;
|
||||
onAccept?: () => void;
|
||||
onCancel?: () => void;
|
||||
}
|
||||
function Datepicker(props: DatepickerProps): Node;
|
||||
|
||||
interface DividerProps extends BaseProps { }
|
||||
function Divider(props: DividerProps): Node;
|
||||
|
||||
interface DrawerProps extends BaseProps { }
|
||||
function Drawer(props: DrawerProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DrawerToggleProps extends BaseProps {
|
||||
checked?: Signal<boolean> | boolean;
|
||||
}
|
||||
function DrawerToggle(props: DrawerToggleProps): Node;
|
||||
|
||||
interface DrawerContentProps extends BaseProps { }
|
||||
function DrawerContent(props: DrawerContentProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DrawerSideProps extends BaseProps { }
|
||||
function DrawerSide(props: DrawerSideProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DrawerOverlayProps extends BaseProps {
|
||||
for?: string;
|
||||
}
|
||||
function DrawerOverlay(props: DrawerOverlayProps): Node;
|
||||
|
||||
interface DropdownProps extends BaseProps {
|
||||
open?: Signal<boolean>;
|
||||
}
|
||||
function Dropdown(props: DropdownProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DropdownButtonProps extends BaseProps { }
|
||||
function DropdownButton(props: DropdownButtonProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface DropdownContentProps extends BaseProps { }
|
||||
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 {
|
||||
icon?: string;
|
||||
}
|
||||
function Fab(props: FabProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface FieldsetProps extends BaseProps {
|
||||
label?: string | (() => string);
|
||||
}
|
||||
function Fieldset(props: FieldsetProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface FileinputProps extends BaseProps {
|
||||
max?: number;
|
||||
accept?: string;
|
||||
onselect?: (files: File[]) => void;
|
||||
value?: Signal<File[]>;
|
||||
}
|
||||
function Fileinput(props: FileinputProps): Node;
|
||||
|
||||
interface IconProps {
|
||||
class?: string;
|
||||
}
|
||||
function Icon(props: string | IconProps): Node;
|
||||
|
||||
interface IndicatorProps extends BaseProps {
|
||||
value?: string | number | (() => string | number);
|
||||
}
|
||||
function Indicator(props: IndicatorProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface InputProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
type?: string;
|
||||
placeholder?: string;
|
||||
label?: string | (() => string);
|
||||
float?: boolean;
|
||||
left?: ComponentChild;
|
||||
right?: ComponentChild;
|
||||
rule?: string;
|
||||
hint?: string | (() => string);
|
||||
}
|
||||
function Input(props: InputProps): Node;
|
||||
|
||||
interface KbdProps extends BaseProps { }
|
||||
function Kbd(props: KbdProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ListProps extends BaseProps { }
|
||||
function List(props: ListProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ListRowsProps extends BaseProps {
|
||||
items?: any[] | (() => any[]);
|
||||
render?: (item: any, index: number) => ComponentChild;
|
||||
}
|
||||
function ListRows(props: ListRowsProps): Node;
|
||||
|
||||
interface LoadingProps extends BaseProps { }
|
||||
function Loading(props: LoadingProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface MenuItem {
|
||||
label?: string | (() => string);
|
||||
href?: string;
|
||||
onclick?: (e: MouseEvent) => void;
|
||||
children?: MenuItem[] | (() => MenuItem[]);
|
||||
open?: boolean;
|
||||
}
|
||||
interface MenuProps extends BaseProps {
|
||||
items?: MenuItem[] | (() => MenuItem[]);
|
||||
children?: ComponentChildren;
|
||||
}
|
||||
function Menu(props: MenuProps): Node;
|
||||
|
||||
interface ModalProps extends BaseProps {
|
||||
open?: Signal<boolean> | boolean;
|
||||
title?: string | (() => string);
|
||||
actions?: ComponentChild;
|
||||
}
|
||||
function Modal(props: ModalProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface NavbarProps extends BaseProps { }
|
||||
function Navbar(props: NavbarProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface ProgressProps extends BaseProps {
|
||||
value?: number | (() => number);
|
||||
max?: number;
|
||||
}
|
||||
function Progress(props: ProgressProps): Node;
|
||||
|
||||
interface RadialProps extends BaseProps {
|
||||
value?: Signal<number> | number;
|
||||
}
|
||||
function Radial(props: RadialProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface RadioProps extends BaseProps {
|
||||
name?: string;
|
||||
checked?: boolean | (() => boolean);
|
||||
}
|
||||
function Radio(props: RadioProps): Node;
|
||||
|
||||
interface RangeProps extends BaseProps {
|
||||
value?: Signal<number> | number;
|
||||
min?: number;
|
||||
max?: number;
|
||||
}
|
||||
function Range(props: RangeProps): Node;
|
||||
|
||||
interface RatingProps extends BaseProps { }
|
||||
function Rating(props: RatingProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface RatingItemsProps extends BaseProps {
|
||||
count: number;
|
||||
name?: string;
|
||||
value?: Signal<number> | number;
|
||||
onchange?: (value: number) => void;
|
||||
}
|
||||
function RatingItems(props: RatingItemsProps): Node;
|
||||
|
||||
interface SelectOption {
|
||||
label?: string;
|
||||
value?: string;
|
||||
disabled?: boolean;
|
||||
}
|
||||
interface SelectProps extends BaseProps {
|
||||
items?: SelectOption[] | (() => SelectOption[]);
|
||||
value?: Signal<string> | string;
|
||||
placeholder?: string;
|
||||
placeholderDisabled?: boolean;
|
||||
label?: string | (() => string);
|
||||
float?: boolean;
|
||||
left?: ComponentChild;
|
||||
right?: ComponentChild;
|
||||
hint?: string | (() => string);
|
||||
onchange?: (e: Event) => void;
|
||||
}
|
||||
function Select(props: SelectProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SkeletonProps extends BaseProps { }
|
||||
function Skeleton(props: SkeletonProps): Node;
|
||||
|
||||
interface SkeletonTextProps extends BaseProps { }
|
||||
function SkeletonText(props: SkeletonTextProps): Node;
|
||||
|
||||
interface StackProps extends BaseProps { }
|
||||
function Stack(props: StackProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface StatProps extends BaseProps {
|
||||
title?: string | (() => string);
|
||||
value?: string | number | (() => string | number);
|
||||
desc?: string | (() => string);
|
||||
}
|
||||
function Stat(props: StatProps): Node;
|
||||
|
||||
interface StatsProps extends BaseProps { }
|
||||
function Stats(props: StatsProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface StepsProps extends BaseProps { }
|
||||
function Steps(props: StepsProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface StepProps extends BaseProps {
|
||||
dataContent?: string;
|
||||
}
|
||||
function Step(props: StepProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SwapProps extends BaseProps { }
|
||||
function Swap(props: SwapProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SwapToggleProps extends BaseProps {
|
||||
value?: Signal<boolean> | boolean;
|
||||
}
|
||||
function SwapToggle(props: SwapToggleProps): Node;
|
||||
|
||||
interface SwapOnProps extends BaseProps { }
|
||||
function SwapOn(props: SwapOnProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface SwapOffProps extends BaseProps { }
|
||||
function SwapOff(props: SwapOffProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface TableProps extends BaseProps { }
|
||||
function Table(props: TableProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface TableColumn {
|
||||
label?: string;
|
||||
key?: string;
|
||||
render?: (item: any, index: number) => ComponentChild;
|
||||
class?: string;
|
||||
}
|
||||
interface TableItemsProps extends BaseProps {
|
||||
items?: any[] | (() => any[]);
|
||||
columns?: TableColumn[];
|
||||
header?: boolean;
|
||||
}
|
||||
function TableItems(props: TableItemsProps): Node;
|
||||
|
||||
interface TabItem {
|
||||
label?: string | (() => string);
|
||||
content?: ComponentChild | (() => ComponentChild);
|
||||
class?: string;
|
||||
closable?: boolean;
|
||||
onclick?: (e: MouseEvent) => void;
|
||||
}
|
||||
interface TabsProps extends BaseProps {
|
||||
items?: TabItem[] | (() => TabItem[]);
|
||||
activeIndex?: Signal<number>;
|
||||
onClose?: (index: number, item: TabItem) => void;
|
||||
children?: ComponentChildren;
|
||||
}
|
||||
function Tabs(props: TabsProps): Node;
|
||||
|
||||
interface TextareaProps extends BaseProps {
|
||||
value?: Signal<string> | string;
|
||||
placeholder?: string;
|
||||
}
|
||||
function Textarea(props: TextareaProps): Node;
|
||||
|
||||
interface TextrotateProps extends BaseProps { }
|
||||
function Textrotate(props: TextrotateProps, children?: ComponentChildren): Node;
|
||||
|
||||
interface TimelineProps extends BaseProps { }
|
||||
function Timeline(props: TimelineProps, children?: ComponentChildren): Node;
|
||||
|
||||
type ToastType = 'alert-info' | 'alert-success' | 'alert-warning' | 'alert-error';
|
||||
function Toast(message: string | (() => string), type?: ToastType, duration?: number): () => void;
|
||||
|
||||
interface ToggleProps extends BaseProps {
|
||||
checked?: Signal<boolean> | boolean;
|
||||
}
|
||||
function Toggle(props: ToggleProps): Node;
|
||||
|
||||
interface TooltipProps extends BaseProps {
|
||||
tip: string | (() => string);
|
||||
}
|
||||
function Tooltip(props: TooltipProps, children?: ComponentChildren): Node;
|
||||
|
||||
const Components: {
|
||||
Accordion: typeof Accordion;
|
||||
Alert: typeof Alert;
|
||||
Autocomplete: typeof Autocomplete;
|
||||
Badge: typeof Badge;
|
||||
Button: typeof Button;
|
||||
Calendar: typeof Calendar;
|
||||
Card: typeof Card;
|
||||
CardTitle: typeof CardTitle;
|
||||
CardBody: typeof CardBody;
|
||||
CardActions: typeof CardActions;
|
||||
Carousel: typeof Carousel;
|
||||
CarouselItem: typeof CarouselItem;
|
||||
Chat: typeof Chat;
|
||||
ChatBubble: typeof ChatBubble;
|
||||
ChatFooter: typeof ChatFooter;
|
||||
ChatHeader: typeof ChatHeader;
|
||||
ChatImage: typeof ChatImage;
|
||||
Checkbox: typeof Checkbox;
|
||||
Colorpicker: typeof Colorpicker;
|
||||
ColorPalette: typeof ColorPalette;
|
||||
Datepicker: typeof Datepicker;
|
||||
Divider: typeof Divider;
|
||||
Drawer: typeof Drawer;
|
||||
DrawerToggle: typeof DrawerToggle;
|
||||
DrawerContent: typeof DrawerContent;
|
||||
DrawerSide: typeof DrawerSide;
|
||||
DrawerOverlay: typeof DrawerOverlay;
|
||||
Dropdown: typeof Dropdown;
|
||||
DropdownButton: typeof DropdownButton;
|
||||
DropdownContent: typeof DropdownContent;
|
||||
Editor: typeof Editor;
|
||||
Fab: typeof Fab;
|
||||
Fieldset: typeof Fieldset;
|
||||
Fileinput: typeof Fileinput;
|
||||
Icon: typeof Icon;
|
||||
Indicator: typeof Indicator;
|
||||
Input: typeof Input;
|
||||
Kbd: typeof Kbd;
|
||||
List: typeof List;
|
||||
ListRows: typeof ListRows;
|
||||
Loading: typeof Loading;
|
||||
Menu: typeof Menu;
|
||||
Modal: typeof Modal;
|
||||
Navbar: typeof Navbar;
|
||||
Progress: typeof Progress;
|
||||
Radial: typeof Radial;
|
||||
Radio: typeof Radio;
|
||||
Range: typeof Range;
|
||||
Rating: typeof Rating;
|
||||
RatingItems: typeof RatingItems;
|
||||
Select: typeof Select;
|
||||
Skeleton: typeof Skeleton;
|
||||
SkeletonText: typeof SkeletonText;
|
||||
Stack: typeof Stack;
|
||||
Stat: typeof Stat;
|
||||
Stats: typeof Stats;
|
||||
Steps: typeof Steps;
|
||||
Step: typeof Step;
|
||||
Swap: typeof Swap;
|
||||
SwapToggle: typeof SwapToggle;
|
||||
SwapOn: typeof SwapOn;
|
||||
SwapOff: typeof SwapOff;
|
||||
Table: typeof Table;
|
||||
TableItems: typeof TableItems;
|
||||
Tabs: typeof Tabs;
|
||||
Textarea: typeof Textarea;
|
||||
Textrotate: typeof Textrotate;
|
||||
Timeline: typeof Timeline;
|
||||
Toast: typeof Toast;
|
||||
Toggle: typeof Toggle;
|
||||
Tooltip: typeof Tooltip;
|
||||
};
|
||||
|
||||
export { Components };
|
||||
export default Components;
|
||||
|
||||
|
||||
declare global {
|
||||
const Accordion: typeof import('sigpro-ui').Accordion;
|
||||
const Alert: typeof import('sigpro-ui').Alert;
|
||||
@@ -491,6 +508,7 @@ declare global {
|
||||
const Dropdown: typeof import('sigpro-ui').Dropdown;
|
||||
const DropdownButton: typeof import('sigpro-ui').DropdownButton;
|
||||
const DropdownContent: typeof import('sigpro-ui').DropdownContent;
|
||||
const Editor: typeof import('sigpro-ui').Editor;
|
||||
const Fab: typeof import('sigpro-ui').Fab;
|
||||
const Fieldset: typeof import('sigpro-ui').Fieldset;
|
||||
const Fileinput: typeof import('sigpro-ui').Fileinput;
|
||||
|
||||
14
index.js
14
index.js
@@ -1,20 +1,10 @@
|
||||
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 = {
|
||||
...All,
|
||||
...Editor,
|
||||
};
|
||||
|
||||
export const Utils = {
|
||||
Locale, tt, hide, get
|
||||
};
|
||||
export const Components = { ...All };
|
||||
|
||||
|
||||
if (typeof window !== 'undefined') {
|
||||
Object.entries({ ...Components, ...Utils }).forEach(([name, value]) => {
|
||||
Object.entries({ ...Components}).forEach(([name, value]) => {
|
||||
Object.defineProperty(window, name, {
|
||||
value,
|
||||
writable: false,
|
||||
|
||||
@@ -45,8 +45,8 @@
|
||||
"scripts": {
|
||||
"del": "bun pm cache rm && rm -f bun.lockb $$ rm -f bun.lock",
|
||||
"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:cssmin": "tailwindcss -i ./sigpro-css.css -o ./dist/sigpro-ui.min.css --content './src/**/*.js' --minify && 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-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: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",
|
||||
|
||||
201
sigpro-editor.js
201
sigpro-editor.js
@@ -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> `
|
||||
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> `
|
||||
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()}`)
|
||||
])
|
||||
])
|
||||
}
|
||||
@@ -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()
|
||||
@@ -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;
|
||||
342
sigpro-ui.js
342
sigpro-ui.js
@@ -1,7 +1,39 @@
|
||||
// All base components
|
||||
import { h, each, watch, when, mount, $ } from "sigpro";
|
||||
import { get, getBy, cls, isFn, filterBy, rand, hide } from "./sigpro-helpers.js"
|
||||
import { h, each, watch, when, mount, $, isFunc } from "sigpro";
|
||||
|
||||
// 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) => {
|
||||
const name = p.name || rand('acc')
|
||||
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 AvatarGroup = (p, c) => h("div", { ...p, class: cls("avatar-group -space-x-6", p.class) }, c);
|
||||
export const Autocomplete = ({ items, value, onselect, placeholder = '...', ...props }) => {
|
||||
const query = $(get(value) || '')
|
||||
const query = $(val(value) || '')
|
||||
const filtered = $(() => filterBy(items, query()))
|
||||
|
||||
const pick = (item) => {
|
||||
const display = getBy(item)
|
||||
const actual = typeof item === 'string' ? item : item.value
|
||||
query(display)
|
||||
if (isFn(value)) value(actual)
|
||||
if (isFunc(value)) value(actual)
|
||||
onselect?.(item)
|
||||
hide()
|
||||
}
|
||||
@@ -37,7 +69,7 @@ export const Autocomplete = ({ items, value, onselect, placeholder = '...', ...p
|
||||
left: h('span', { class: 'icon-[lucide--search]' }),
|
||||
oninput: (e) => {
|
||||
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 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 rangeMode = () => get(p.range) === true
|
||||
const current = () => get(p.value)
|
||||
const rangeMode = () => val(p.range) === true
|
||||
const current = () => val(p.value)
|
||||
const selectDate = (date) => {
|
||||
const s = fmt(date)
|
||||
const v = current()
|
||||
@@ -93,7 +125,7 @@ export const Calendar = (p) => {
|
||||
const HourSlider = ({ value: hVal, onChange: onH }) => h('div', { class: 'flex-1' }, [
|
||||
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('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', {
|
||||
@@ -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 Checkbox = (p) => h("input", { ...p, type: "checkbox", class: cls("checkbox", p.class) });
|
||||
export const Colorpicker = (p) => {
|
||||
const current = () => get(p.value) || '#000000'
|
||||
const current = () => val(p.value) || '#000000'
|
||||
return Dropdown({}, [
|
||||
DropdownButton({ class: 'btn' }, [
|
||||
h('div', { class: 'size-5 rounded-sm', style: () => `background-color: ${current()}` }),
|
||||
@@ -173,13 +205,13 @@ export const Colorpicker = (p) => {
|
||||
]),
|
||||
DropdownContent({ class: 'p-0' },
|
||||
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) => {
|
||||
const current = () => get(p.value) || '#000000'
|
||||
const current = () => val(p.value) || '#000000'
|
||||
const palette = [
|
||||
'#000', '#1A1A1A', '#333', '#4D4D4D', '#666', '#808080', '#B3B3B3', '#FFF',
|
||||
'#450a0a', '#7f1d1d', '#991b1b', '#b91c1c', '#dc2626', '#ef4444', '#f87171', '#fca5a5',
|
||||
@@ -191,7 +223,7 @@ export const ColorPalette = (p) => {
|
||||
'#2e1065', '#4c1d95', '#6d28d9', '#7c3aed', '#8b5cf6', '#a855f7', '#d946ef', '#fae8ff'
|
||||
]
|
||||
const pick = (c) => {
|
||||
isFn(p.value) ? p.value(c) : p.onchange?.(c)
|
||||
isFunc(p.value) ? p.value(c) : p.onchange?.(c)
|
||||
hide()
|
||||
}
|
||||
|
||||
@@ -211,10 +243,10 @@ export const ColorPalette = (p) => {
|
||||
}
|
||||
export const Datepicker = (p) => {
|
||||
const displayValue = $("")
|
||||
const rangeMode = () => get(p.range) === true
|
||||
const rangeMode = () => val(p.range) === true
|
||||
|
||||
watch(() => {
|
||||
const v = get(p.value)
|
||||
const v = val(p.value)
|
||||
if (!v) return displayValue("")
|
||||
let text = ""
|
||||
if (typeof v === "string") {
|
||||
@@ -231,7 +263,7 @@ export const Datepicker = (p) => {
|
||||
})
|
||||
|
||||
const handleChange = (val) => {
|
||||
if (isFn(p.value)) p.value(val)
|
||||
if (isFunc(p.value)) p.value(val)
|
||||
else p.onChange?.(val)
|
||||
if (!rangeMode() || val?.end != null) hide()
|
||||
}
|
||||
@@ -252,7 +284,7 @@ export const Datepicker = (p) => {
|
||||
onmousedown: (e) => {
|
||||
e.preventDefault()
|
||||
e.stopPropagation()
|
||||
if (isFn(p.value)) p.value(null)
|
||||
if (isFunc(p.value)) p.value(null)
|
||||
else p.onChange?.(null)
|
||||
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 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 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) })
|
||||
@@ -293,15 +325,15 @@ export const Fileinput = (p) => {
|
||||
}
|
||||
const updated = [...files(), ...arr]
|
||||
files(updated)
|
||||
if (isFn(p.onselect)) p.onselect(updated)
|
||||
else if (isFn(p.value)) p.value(updated)
|
||||
if (isFunc(p.onselect)) p.onselect(updated)
|
||||
else if (isFunc(p.value)) p.value(updated)
|
||||
}
|
||||
|
||||
const remove = (idx) => {
|
||||
const updated = files().filter((_, i) => i !== idx)
|
||||
files(updated)
|
||||
if (isFn(p.onselect)) p.onselect(updated)
|
||||
else if (isFn(p.value)) p.value(updated)
|
||||
if (isFunc(p.onselect)) p.onselect(updated)
|
||||
else if (isFunc(p.value)) p.value(updated)
|
||||
}
|
||||
return h('div', { class: cls('fieldset w-full p-0', p.class) }, [
|
||||
h('label', {
|
||||
@@ -354,7 +386,7 @@ export const Input = (p) => {
|
||||
const pattern = rule ?? null;
|
||||
|
||||
const inputType = () => isPassword
|
||||
? (get(showPassword) ? 'text' : 'password')
|
||||
? (val(showPassword) ? 'text' : 'password')
|
||||
: (p.type || 'search');
|
||||
|
||||
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 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 Menu = (p) => {
|
||||
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
|
||||
? h('li', {}, h('details', { open: item.open || undefined }, [
|
||||
h('summary', {}, getBy(item)),
|
||||
h('ul', {}, each(() => get(item.children) || [], render))
|
||||
h('ul', {}, each(() => val(item.children) || [], render))
|
||||
]))
|
||||
: h('li', {}, h('a', {
|
||||
href: item.href,
|
||||
onclick: item.onclick ? (e) => { if (!item.href) e.preventDefault(); item.onclick(e) } : null
|
||||
}, getBy(item)))
|
||||
return h('ul', { class: cls('menu', p.class) },
|
||||
each(() => get(items) || [], render)
|
||||
each(() => val(items) || [], render)
|
||||
)
|
||||
}
|
||||
export const Modal = (p) => {
|
||||
let dialogRef = null;
|
||||
|
||||
watch(() => {
|
||||
const isOpen = get(p.open);
|
||||
const isOpen = val(p.open);
|
||||
if (!dialogRef) return;
|
||||
isOpen ? dialogRef.showModal() : dialogRef.hide();
|
||||
});
|
||||
|
||||
const close = () => isFn(p.open) && p.open(false);
|
||||
const close = () => isFunc(p.open) && p.open(false);
|
||||
|
||||
return h("dialog", {
|
||||
...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 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 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 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) => {
|
||||
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 opts = () => {
|
||||
const raw = get(items) || []
|
||||
const raw = val(items) || []
|
||||
const ph = placeholder ? [{ disabled: placeholderDisabled, label: placeholder, value: '' }] : []
|
||||
return [...ph, ...raw]
|
||||
}
|
||||
@@ -448,8 +480,8 @@ export const Select = (p, c) => {
|
||||
(!float && label) ? h('span', { class: 'label' }, label) : null,
|
||||
left ?? null,
|
||||
h('select', {
|
||||
value: () => get(value),
|
||||
onchange: (e) => isFn(value) ? value(e.target.value) : rest.onchange?.(e)
|
||||
value: () => val(value),
|
||||
onchange: (e) => isFunc(value) ? value(e.target.value) : rest.onchange?.(e)
|
||||
},
|
||||
each(opts, (item) => {
|
||||
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 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 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 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 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 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 [head, body].filter(Boolean)
|
||||
@@ -492,16 +524,16 @@ export const Tabs = (p, c) => {
|
||||
return h('div', { ...rest, class: cls('tabs', className) }, c)
|
||||
}
|
||||
const { items, activeIndex, onClose, class: className, ...rest } = p
|
||||
const get = x => (isFn(x) ? x() : x)
|
||||
const closeH = onClose || (isFn(items) ? (idx, item) => {
|
||||
const arr = get(items)
|
||||
const get = x => (isFunc(x) ? x() : x)
|
||||
const closeH = onClose || (isFunc(items) ? (idx, item) => {
|
||||
const arr = val(items)
|
||||
const newArr = arr.filter((_, i) => i !== idx)
|
||||
items(newArr)
|
||||
if (activeIndex() >= newArr.length) activeIndex(Math.max(0, newArr.length - 1))
|
||||
} : null)
|
||||
|
||||
return h('div', { ...rest, class: cls('tabs', className) }, () => {
|
||||
const list = get(items) || []
|
||||
const list = val(items) || []
|
||||
return list.flatMap((it, idx) => {
|
||||
const isActive = () => activeIndex() === idx
|
||||
const button = h('button', {
|
||||
@@ -517,7 +549,7 @@ export const Tabs = (p, c) => {
|
||||
const contentDiv = h('div', {
|
||||
class: 'tab-content bg-base-100 border-base-300 p-6',
|
||||
style: () => `display: ${isActive() ? 'block' : 'none'};`
|
||||
}, isFn(it.content) ? it.content() : it.content)
|
||||
}, isFunc(it.content) ? it.content() : it.content)
|
||||
return [button, contentDiv]
|
||||
})
|
||||
})
|
||||
@@ -552,7 +584,7 @@ export const Toast = (message, type = "alert-success", duration = 3500) => {
|
||||
}, 300);
|
||||
};
|
||||
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;
|
||||
return h("div", {
|
||||
class: () => {
|
||||
@@ -574,4 +606,232 @@ export const Toast = (message, type = "alert-success", duration = 3500) => {
|
||||
return closeFn;
|
||||
};
|
||||
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> `
|
||||
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> `
|
||||
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()}`)
|
||||
])
|
||||
])
|
||||
}
|
||||
Reference in New Issue
Block a user