ajo 0.1.12 → 0.1.13
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/html.cjs +1 -1
- package/dist/html.js +25 -23
- package/dist/index.cjs +1 -1
- package/dist/index.js +77 -73
- package/package.json +3 -3
- package/readme.md +65 -69
package/dist/html.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const{
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const{assign:p,entries:$,hasOwn:g}=Object,f=e=>typeof e!="string"&&typeof(e==null?void 0:e[Symbol.iterator])=="function",c=e=>[...y(e)].join(""),y=function*(e){for(e of d(e))if(typeof e=="string")yield m(e);else{const{nodeName:t,skip:o,children:i=""}=e;let n="";for(const[l,r]of $(e))v.has(l)||l.startsWith("set:")||r==null||r===!1||(n+=r===!0?`${n} ${l}`:`${n} ${l}="${m(String(r))}"`);k.has(t)?yield`<${t}${n}>`:o?yield`<${t}${n}></${t}>`:typeof i=="string"?yield`<${t}${n}>${i}</${t}>`:(yield`<${t}${n}>`,yield*y(i),yield`</${t}>`)}},d=function*(e,t={value:""},o=!0){for(e of f(e)?e:[e])if(!(e==null||typeof e=="boolean"))if(g(e,"nodeName")){const{value:i}=t,{nodeName:n}=e,l=typeof n;if(i&&(yield i,t.value=""),l==="function")if(delete e.nodeName,n.constructor.name==="GeneratorFunction"){const r={},s=p({},n.attrs);for(const a in e){const u=e[a];a.startsWith("attr:")?s[a.slice(5)]=u:r[a]=u}s.nodeName=n.is??"div",s.children=w(n,r),yield s}else delete e.nodeName,yield*d(n(e),t,!1);else l==="string"&&(yield e)}else f(e)?yield*d(e,t,!1):t.value+=e;o&&t.value&&(yield t.value)},k=new Set("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",")),v=new Set("nodeName,key,skip,memo,ref,children".split(",")),m=e=>e.replace(/[&<>"']/g,t=>`&#${t.charCodeAt(0)};`),w=(e,t)=>{let o,i;try{const n=e.call(o={$args:t,*[Symbol.iterator](){for(;;)yield t},refresh(){},next(){i=c(n.next().value)},throw(l){i=c(n.throw(l).value)},return(){n.return()}},t);o.next()}catch(n){o.throw(n)}finally{o.return()}return i};exports.html=y;exports.render=c;
|
package/dist/html.js
CHANGED
|
@@ -1,36 +1,38 @@
|
|
|
1
|
-
const {
|
|
2
|
-
for (e of
|
|
1
|
+
const { assign: p, entries: $, hasOwn: g } = Object, y = (e) => typeof e != "string" && typeof (e == null ? void 0 : e[Symbol.iterator]) == "function", f = (e) => [...m(e)].join(""), m = function* (e) {
|
|
2
|
+
for (e of c(e))
|
|
3
3
|
if (typeof e == "string")
|
|
4
4
|
yield u(e);
|
|
5
5
|
else {
|
|
6
|
-
const { nodeName: t, skip:
|
|
6
|
+
const { nodeName: t, skip: o, children: i = "" } = e;
|
|
7
7
|
let n = "";
|
|
8
|
-
for (const [l,
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
for (const [l, s] of $(e))
|
|
9
|
+
w.has(l) || l.startsWith("set:") || s == null || s === !1 || (n += s === !0 ? `${n} ${l}` : `${n} ${l}="${u(String(s))}"`);
|
|
10
|
+
k.has(t) ? yield `<${t}${n}>` : o ? yield `<${t}${n}></${t}>` : typeof i == "string" ? yield `<${t}${n}>${i}</${t}>` : (yield `<${t}${n}>`, yield* m(i), yield `</${t}>`);
|
|
11
11
|
}
|
|
12
|
-
},
|
|
12
|
+
}, c = function* (e, t = { value: "" }, o = !0) {
|
|
13
13
|
for (e of y(e) ? e : [e])
|
|
14
14
|
if (!(e == null || typeof e == "boolean"))
|
|
15
|
-
if (
|
|
15
|
+
if (g(e, "nodeName")) {
|
|
16
16
|
const { value: i } = t, { nodeName: n } = e, l = typeof n;
|
|
17
17
|
if (i && (yield i, t.value = ""), l === "function")
|
|
18
|
-
if (n.constructor.name === "GeneratorFunction") {
|
|
19
|
-
const
|
|
20
|
-
for (const
|
|
21
|
-
|
|
22
|
-
|
|
18
|
+
if (delete e.nodeName, n.constructor.name === "GeneratorFunction") {
|
|
19
|
+
const s = {}, r = p({}, n.attrs);
|
|
20
|
+
for (const a in e) {
|
|
21
|
+
const d = e[a];
|
|
22
|
+
a.startsWith("attr:") ? r[a.slice(5)] = d : s[a] = d;
|
|
23
|
+
}
|
|
24
|
+
r.nodeName = n.is ?? "div", r.children = v(n, s), yield r;
|
|
23
25
|
} else
|
|
24
|
-
delete e.nodeName, yield*
|
|
26
|
+
delete e.nodeName, yield* c(n(e), t, !1);
|
|
25
27
|
else
|
|
26
28
|
l === "string" && (yield e);
|
|
27
29
|
} else
|
|
28
|
-
y(e) ? yield*
|
|
29
|
-
|
|
30
|
-
},
|
|
31
|
-
let
|
|
30
|
+
y(e) ? yield* c(e, t, !1) : t.value += e;
|
|
31
|
+
o && t.value && (yield t.value);
|
|
32
|
+
}, k = new Set("area,base,br,col,command,embed,hr,img,input,keygen,link,meta,param,source,track,wbr".split(",")), w = new Set("nodeName,key,skip,memo,ref,children".split(",")), u = (e) => e.replace(/[&<>"']/g, (t) => `&#${t.charCodeAt(0)};`), v = (e, t) => {
|
|
33
|
+
let o, i;
|
|
32
34
|
try {
|
|
33
|
-
const n = e.call(
|
|
35
|
+
const n = e.call(o = {
|
|
34
36
|
$args: t,
|
|
35
37
|
*[Symbol.iterator]() {
|
|
36
38
|
for (; ; )
|
|
@@ -48,15 +50,15 @@ const { entries: m, hasOwn: $ } = Object, y = (e) => typeof e != "string" && typ
|
|
|
48
50
|
n.return();
|
|
49
51
|
}
|
|
50
52
|
}, t);
|
|
51
|
-
|
|
53
|
+
o.next();
|
|
52
54
|
} catch (n) {
|
|
53
|
-
|
|
55
|
+
o.throw(n);
|
|
54
56
|
} finally {
|
|
55
|
-
|
|
57
|
+
o.return();
|
|
56
58
|
}
|
|
57
59
|
return i;
|
|
58
60
|
};
|
|
59
61
|
export {
|
|
60
|
-
|
|
62
|
+
m as html,
|
|
61
63
|
f as render
|
|
62
64
|
};
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const b=({children:e})=>e,A=function(e,t){const{length:i}=arguments;return(t??(t=C(null))).nodeName=e,"children"in t||i<3||(t.children=i===3?arguments[2]:O.call(arguments,2)),t},y=(e,t)=>{let i=t.firstChild;for(e of p(e)){let n=i;if(typeof e=="string"){for(;n&&n.nodeType!=3;)n=n.nextSibling;n?n.data!=e&&(n.data=e):n=document.createTextNode(e)}else if(e instanceof Node)n=e;else{const{nodeName:o,key:a,skip:m,memo:r,ref:s,children:u}=e;for(;n&&!(n.localName===o&&(n.$key??(n.$key=a))==a);)n=n.nextSibling;if(n??(n=g(document.createElementNS(e.xmlns??o==="svg"?T:t.namespaceURI,o),{$key:a})),r==null||P(n.$memo,n.$memo=r)){const{$props:d}=n,w={};for(const c of h(g({},d,e))){if(q.has(c))continue;const f=w[c]=e[c];f!==(d==null?void 0:d[c])&&(c.startsWith("set:")?n[c.slice(4)]=f:f==null||f===!1?n.removeAttribute(c):n.setAttribute(c,f===!0?"":f))}n.$props=w,m||y(u,n),typeof s=="function"&&(n.$ref=s)(n)}}n===i?i=i.nextSibling:E(t,n,i)}for(;i;){const n=i.nextSibling;i.nodeType===1&&N(i),t.removeChild(i),i=n}},{isArray:$,prototype:{slice:O}}=Array,{create:C,keys:h,assign:g,hasOwn:F,setPrototypeOf:x,getPrototypeOf:v}=Object,T="http://www.w3.org/2000/svg",q=new Set("nodeName,key,skip,memo,ref,children".split(",")),S=e=>typeof e!="string"&&typeof(e==null?void 0:e[Symbol.iterator])=="function",P=(e,t)=>$(e)&&$(t)?e.some((i,n)=>i!==t[n]):e!==t,p=function*(e,t={value:""},i=!0){for(e of S(e)?e:[e])if(!(e==null||typeof e=="boolean"))if(F(e,"nodeName")){const{value:n}=t,{nodeName:o}=e,a=typeof o;if(n&&(yield n,t.value=""),a==="function")if(delete e.nodeName,o.constructor.name==="GeneratorFunction"){const m={},r=g({},o.attrs);for(const s of h(e)){const u=e[s];s.startsWith("attr:")&&(r[s.slice(5)]=u),s==="key"||s==="memo"?r[s]=u:m[s]=u}r.nodeName=o.is??"div",r.skip=!0,r.ref=j.bind(null,o,m),yield r}else yield*p(o(e),t,!1);else a==="string"&&(yield e)}else S(e)?yield*p(e,t,!1):t.value+=e;i&&t.value&&(yield t.value)},j=(e,t,i)=>{i&&(i.$gen??(i.$gen=(new I(i),e)),i.$ref=B.bind(null,i),i.$args=t,i.next())},B=(e,t)=>t??e.return(),E=(e,t,i)=>{if(t.contains(document.activeElement)){const n=t.nextSibling;for(;i&&i!=t;){const o=i.nextSibling;e.insertBefore(i,n),i=o}}else e.insertBefore(t,i)},N=e=>{for(const i of e.children)N(i);const{$ref:t}=e;typeof t=="function"&&t(null);for(const i of h(e))e[i]=null};class I{constructor(t){x(t,x(v(this),v(t)))}*[Symbol.iterator](){for(;;)yield this.$args??{}}refresh(){W(this)}next(){try{y((this.$it??(this.$it=this.$gen.call(this,this.$args??{}))).next().value,this),typeof this.$ref=="function"&&this.$ref(this)}catch(t){this.throw(t)}}throw(t){var i;for(let n=this;n;n=n.parentNode)if(typeof((i=n.$it)==null?void 0:i.throw)=="function")try{return y(n.$it.throw(t).value,n)}catch{}throw t}return(){var t;try{(t=this.$it)==null||t.return()}catch(i){this.throw(i)}finally{this.$it=null}}}let l,k;const W=e=>{(l??(l=new Set)).has(e)&&l.delete(e);for(const t of l){if(t.contains(e))return;e.contains(t)&&l.delete(t)}l.add(e),k??(k=requestAnimationFrame(z))},z=()=>{for(const e of l)e.isConnected&&e.next();l.clear(),k=null};exports.Fragment=b;exports.h=A;exports.render=y;
|
package/dist/index.js
CHANGED
|
@@ -1,96 +1,100 @@
|
|
|
1
|
-
const
|
|
2
|
-
const { length:
|
|
3
|
-
return (t ?? (t =
|
|
4
|
-
},
|
|
5
|
-
let
|
|
6
|
-
for (e of
|
|
7
|
-
let
|
|
1
|
+
const j = ({ children: e }) => e, z = function(e, t) {
|
|
2
|
+
const { length: i } = arguments;
|
|
3
|
+
return (t ?? (t = A(null))).nodeName = e, "children" in t || i < 3 || (t.children = i === 3 ? arguments[2] : b.call(arguments, 2)), t;
|
|
4
|
+
}, d = (e, t) => {
|
|
5
|
+
let i = t.firstChild;
|
|
6
|
+
for (e of p(e)) {
|
|
7
|
+
let n = i;
|
|
8
8
|
if (typeof e == "string") {
|
|
9
|
-
for (;
|
|
10
|
-
|
|
11
|
-
|
|
9
|
+
for (; n && n.nodeType != 3; )
|
|
10
|
+
n = n.nextSibling;
|
|
11
|
+
n ? n.data != e && (n.data = e) : n = document.createTextNode(e);
|
|
12
12
|
} else if (e instanceof Node)
|
|
13
|
-
|
|
13
|
+
n = e;
|
|
14
14
|
else {
|
|
15
|
-
const { nodeName: o, key:
|
|
16
|
-
for (;
|
|
17
|
-
|
|
18
|
-
if (
|
|
19
|
-
const { $props:
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
if (T.has(s))
|
|
15
|
+
const { nodeName: o, key: a, skip: m, memo: r, ref: s, children: u } = e;
|
|
16
|
+
for (; n && !(n.localName === o && (n.$key ?? (n.$key = a)) == a); )
|
|
17
|
+
n = n.nextSibling;
|
|
18
|
+
if (n ?? (n = g(document.createElementNS(e.xmlns ?? o === "svg" ? O : t.namespaceURI, o), { $key: a })), r == null || F(n.$memo, n.$memo = r)) {
|
|
19
|
+
const { $props: y } = n, $ = {};
|
|
20
|
+
for (const c of w(g({}, y, e))) {
|
|
21
|
+
if (q.has(c))
|
|
23
22
|
continue;
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
continue;
|
|
27
|
-
}
|
|
28
|
-
const l = g[s] = e[s];
|
|
29
|
-
l !== (f == null ? void 0 : f[s]) && (s.startsWith("set:") ? i[s.slice(4)] = l : l == null || l === !1 ? i.removeAttribute(s) : i.setAttribute(s, l === !0 ? "" : l));
|
|
23
|
+
const f = $[c] = e[c];
|
|
24
|
+
f !== (y == null ? void 0 : y[c]) && (c.startsWith("set:") ? n[c.slice(4)] = f : f == null || f === !1 ? n.removeAttribute(c) : n.setAttribute(c, f === !0 ? "" : f));
|
|
30
25
|
}
|
|
31
|
-
|
|
26
|
+
n.$props = $, m || d(u, n), typeof s == "function" && (n.$ref = s)(n);
|
|
32
27
|
}
|
|
33
28
|
}
|
|
34
|
-
|
|
29
|
+
n === i ? i = i.nextSibling : E(t, n, i);
|
|
35
30
|
}
|
|
36
|
-
for (;
|
|
37
|
-
const
|
|
38
|
-
|
|
31
|
+
for (; i; ) {
|
|
32
|
+
const n = i.nextSibling;
|
|
33
|
+
i.nodeType === 1 && k(i), t.removeChild(i), i = n;
|
|
39
34
|
}
|
|
40
|
-
},
|
|
41
|
-
for (e of
|
|
35
|
+
}, { isArray: h, prototype: { slice: b } } = Array, { create: A, keys: w, assign: g, hasOwn: C, setPrototypeOf: x, getPrototypeOf: v } = Object, O = "http://www.w3.org/2000/svg", q = new Set("nodeName,key,skip,memo,ref,children".split(",")), N = (e) => typeof e != "string" && typeof (e == null ? void 0 : e[Symbol.iterator]) == "function", F = (e, t) => h(e) && h(t) ? e.some((i, n) => i !== t[n]) : e !== t, p = function* (e, t = { value: "" }, i = !0) {
|
|
36
|
+
for (e of N(e) ? e : [e])
|
|
42
37
|
if (!(e == null || typeof e == "boolean"))
|
|
43
38
|
if (C(e, "nodeName")) {
|
|
44
|
-
const { value:
|
|
45
|
-
|
|
39
|
+
const { value: n } = t, { nodeName: o } = e, a = typeof o;
|
|
40
|
+
if (n && (yield n, t.value = ""), a === "function")
|
|
41
|
+
if (delete e.nodeName, o.constructor.name === "GeneratorFunction") {
|
|
42
|
+
const m = {}, r = g({}, o.attrs);
|
|
43
|
+
for (const s of w(e)) {
|
|
44
|
+
const u = e[s];
|
|
45
|
+
s.startsWith("attr:") && (r[s.slice(5)] = u), s === "key" || s === "memo" ? r[s] = u : m[s] = u;
|
|
46
|
+
}
|
|
47
|
+
r.nodeName = o.is ?? "div", r.skip = !0, r.ref = T.bind(null, o, m), yield r;
|
|
48
|
+
} else
|
|
49
|
+
yield* p(o(e), t, !1);
|
|
50
|
+
else
|
|
51
|
+
a === "string" && (yield e);
|
|
46
52
|
} else
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
},
|
|
50
|
-
|
|
51
|
-
},
|
|
52
|
-
n || e.return(), typeof t == "function" && t(n);
|
|
53
|
-
}, F = (e, t) => p(e) && p(t) ? e.some((n, i) => n !== t[i]) : e !== t, T = new Set("nodeName,key,skip,memo,ref,children".split(",")), B = (e, t, n) => {
|
|
53
|
+
N(e) ? yield* p(e, t, !1) : t.value += e;
|
|
54
|
+
i && t.value && (yield t.value);
|
|
55
|
+
}, T = (e, t, i) => {
|
|
56
|
+
i && (i.$gen ?? (i.$gen = (new I(i), e)), i.$ref = B.bind(null, i), i.$args = t, i.next());
|
|
57
|
+
}, B = (e, t) => t ?? e.return(), E = (e, t, i) => {
|
|
54
58
|
if (t.contains(document.activeElement)) {
|
|
55
|
-
const
|
|
56
|
-
for (;
|
|
57
|
-
const o =
|
|
58
|
-
e.insertBefore(
|
|
59
|
+
const n = t.nextSibling;
|
|
60
|
+
for (; i && i != t; ) {
|
|
61
|
+
const o = i.nextSibling;
|
|
62
|
+
e.insertBefore(i, n), i = o;
|
|
59
63
|
}
|
|
60
64
|
} else
|
|
61
|
-
e.insertBefore(t,
|
|
62
|
-
},
|
|
63
|
-
for (const
|
|
64
|
-
|
|
65
|
+
e.insertBefore(t, i);
|
|
66
|
+
}, k = (e) => {
|
|
67
|
+
for (const i of e.children)
|
|
68
|
+
k(i);
|
|
65
69
|
const { $ref: t } = e;
|
|
66
70
|
typeof t == "function" && t(null);
|
|
67
|
-
for (const
|
|
68
|
-
e[
|
|
71
|
+
for (const i of w(e))
|
|
72
|
+
e[i] = null;
|
|
69
73
|
};
|
|
70
|
-
class
|
|
74
|
+
class I {
|
|
71
75
|
constructor(t) {
|
|
72
|
-
|
|
76
|
+
x(t, x(v(this), v(t)));
|
|
73
77
|
}
|
|
74
78
|
*[Symbol.iterator]() {
|
|
75
79
|
for (; ; )
|
|
76
80
|
yield this.$args ?? {};
|
|
77
81
|
}
|
|
78
82
|
refresh() {
|
|
79
|
-
|
|
83
|
+
P(this);
|
|
80
84
|
}
|
|
81
85
|
next() {
|
|
82
86
|
try {
|
|
83
|
-
|
|
87
|
+
d((this.$it ?? (this.$it = this.$gen.call(this, this.$args ?? {}))).next().value, this), typeof this.$ref == "function" && this.$ref(this);
|
|
84
88
|
} catch (t) {
|
|
85
89
|
this.throw(t);
|
|
86
90
|
}
|
|
87
91
|
}
|
|
88
92
|
throw(t) {
|
|
89
|
-
var
|
|
90
|
-
for (let
|
|
91
|
-
if (typeof ((
|
|
93
|
+
var i;
|
|
94
|
+
for (let n = this; n; n = n.parentNode)
|
|
95
|
+
if (typeof ((i = n.$it) == null ? void 0 : i.throw) == "function")
|
|
92
96
|
try {
|
|
93
|
-
return
|
|
97
|
+
return d(n.$it.throw(t).value, n);
|
|
94
98
|
} catch {
|
|
95
99
|
}
|
|
96
100
|
throw t;
|
|
@@ -99,29 +103,29 @@ class E {
|
|
|
99
103
|
var t;
|
|
100
104
|
try {
|
|
101
105
|
(t = this.$it) == null || t.return();
|
|
102
|
-
} catch (
|
|
103
|
-
this.throw(
|
|
106
|
+
} catch (i) {
|
|
107
|
+
this.throw(i);
|
|
104
108
|
} finally {
|
|
105
109
|
this.$it = null;
|
|
106
110
|
}
|
|
107
111
|
}
|
|
108
112
|
}
|
|
109
|
-
let
|
|
110
|
-
const
|
|
111
|
-
(
|
|
112
|
-
for (const t of
|
|
113
|
+
let l, S;
|
|
114
|
+
const P = (e) => {
|
|
115
|
+
(l ?? (l = /* @__PURE__ */ new Set())).has(e) && l.delete(e);
|
|
116
|
+
for (const t of l) {
|
|
113
117
|
if (t.contains(e))
|
|
114
118
|
return;
|
|
115
|
-
e.contains(t) &&
|
|
119
|
+
e.contains(t) && l.delete(t);
|
|
116
120
|
}
|
|
117
|
-
|
|
118
|
-
},
|
|
119
|
-
for (const e of
|
|
121
|
+
l.add(e), S ?? (S = requestAnimationFrame(W));
|
|
122
|
+
}, W = () => {
|
|
123
|
+
for (const e of l)
|
|
120
124
|
e.isConnected && e.next();
|
|
121
|
-
|
|
125
|
+
l.clear(), S = null;
|
|
122
126
|
};
|
|
123
127
|
export {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
128
|
+
j as Fragment,
|
|
129
|
+
z as h,
|
|
130
|
+
d as render
|
|
127
131
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "ajo",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.13",
|
|
4
4
|
"description": "ajo is a JavaScript view library for building user interfaces",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"module": "./dist/index.js",
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
],
|
|
21
21
|
"devDependencies": {
|
|
22
22
|
"jsdom": "^23.0.1",
|
|
23
|
-
"vite": "^5.0.
|
|
24
|
-
"vitest": "^0.
|
|
23
|
+
"vite": "^5.0.10",
|
|
24
|
+
"vitest": "^1.0.4"
|
|
25
25
|
},
|
|
26
26
|
"keywords": [
|
|
27
27
|
"ui",
|
package/readme.md
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
|
|
16
16
|
# Ajo
|
|
17
17
|
|
|
18
|
-
Ajo is a
|
|
18
|
+
Ajo is a library designed for building dynamic UI components using JSX. Integrating ideas from Incremental DOM and Crank.js, Ajo offers a unique approach in the landscape of UI libraries.
|
|
19
19
|
|
|
20
20
|
Key features:
|
|
21
21
|
|
|
@@ -23,7 +23,7 @@ Key features:
|
|
|
23
23
|
- **Generator-Based State Management**: Leverages JavaScript Generators for managing component states and effects, offering developers a robust tool for controlling UI lifecycle events.
|
|
24
24
|
- **Minimalistic Rendering Approach**: Ajo’s rendering system is optimized for minimal overhead, enhancing the speed of DOM updates and overall application performance.
|
|
25
25
|
- **JSX Syntax for Intuitive Development**: Supports JSX, making it easy for developers familiar with React or similar libraries to adopt and use Ajo effectively.
|
|
26
|
-
- **Lifecycle Management for Components**: Provides a
|
|
26
|
+
- **Lifecycle Management for Components**: Provides a suite of lifecycle methods for stateful components, facilitating precise control over component behaviors during their lifecycle.
|
|
27
27
|
- **Flexibility and Lightweight Design**: Ajo is designed to be both adaptable for various use cases and lightweight, ensuring minimal impact on project size.
|
|
28
28
|
|
|
29
29
|
## Install
|
|
@@ -137,9 +137,6 @@ import { h } from 'ajo'
|
|
|
137
137
|
// Creating a simple virtual element
|
|
138
138
|
const myElement = h('div', { id: 'my-div' }, 'Hello World')
|
|
139
139
|
|
|
140
|
-
// or using JSX syntax
|
|
141
|
-
const myElementJSX = <div id="my-div">Hello World</div>
|
|
142
|
-
|
|
143
140
|
// Creating a virtual tree for a stateless component with children
|
|
144
141
|
const MyComponent = ({ class: className }) => h('div', { class: className },
|
|
145
142
|
h('h1', null, 'Header'),
|
|
@@ -147,26 +144,11 @@ const MyComponent = ({ class: className }) => h('div', { class: className },
|
|
|
147
144
|
h('p', null, 'Paragraph'),
|
|
148
145
|
)
|
|
149
146
|
|
|
150
|
-
// or using JSX syntax
|
|
151
|
-
const MyComponentJSX = ({ class: className }) => (
|
|
152
|
-
<div class={className}>
|
|
153
|
-
<h1>Header</h1>
|
|
154
|
-
Text Content
|
|
155
|
-
<p>Paragraph</p>
|
|
156
|
-
</div>
|
|
157
|
-
)
|
|
158
|
-
|
|
159
147
|
// Composing
|
|
160
148
|
const MyApp = () => h(MyComponent, { class: 'my-class' })
|
|
161
149
|
|
|
162
|
-
// or using JSX syntax
|
|
163
|
-
const MyAppJSX = () => <MyComponent class="my-class" />
|
|
164
|
-
|
|
165
150
|
// Render into a DOM element
|
|
166
151
|
render(h(MyApp), document.body)
|
|
167
|
-
|
|
168
|
-
// or using JSX syntax
|
|
169
|
-
render(<MyAppJSX />, document.body)
|
|
170
152
|
```
|
|
171
153
|
> You won't typically use the `h` function, it's automatically used when you write JSX code. The previous examples demonstrate how to use the `h` function directly if you need to.
|
|
172
154
|
|
|
@@ -183,6 +165,7 @@ In JSX, fragments are typically represented with empty tags (`<>...</>`), but th
|
|
|
183
165
|
//* @jsxFrag Fragment */
|
|
184
166
|
import { h, Fragment } from 'ajo'
|
|
185
167
|
|
|
168
|
+
// Using the h function
|
|
186
169
|
const MyComponent = () => {
|
|
187
170
|
return h(Fragment, null,
|
|
188
171
|
h('h1', null, 'Hello'),
|
|
@@ -201,16 +184,15 @@ const MyComponentJSX = () => (
|
|
|
201
184
|
|
|
202
185
|
### `set:`
|
|
203
186
|
|
|
204
|
-
The `set:` prefix in Ajo allows you to directly set properties on DOM elements from within your JSX. This is distinct from simply setting attributes, as it interacts with the properties of the DOM elements, much like how you would in plain JavaScript.
|
|
187
|
+
The `set:` prefix in Ajo allows you to directly set properties on DOM elements from within your JSX. This is distinct from simply setting attributes, as it interacts with the properties of the DOM elements, much like how you would in plain JavaScript. Ideal for situations where setting a DOM property is more appropriate or efficient than setting an HTML attribute.
|
|
205
188
|
|
|
206
189
|
#### Purpose:
|
|
207
190
|
|
|
208
|
-
-
|
|
191
|
+
- The `set:` prefix is used for directly setting properties on DOM elements. This is crucial for cases where you need to interact with the DOM API, or when a property does not have a direct attribute equivalent.
|
|
209
192
|
|
|
210
193
|
#### Usage:
|
|
211
194
|
|
|
212
|
-
-
|
|
213
|
-
- **JavaScript-centric DOM Interaction:** Ideal for situations where setting a DOM property is more appropriate or efficient than setting an HTML attribute.
|
|
195
|
+
- Use `set:` to assign various types of properties to DOM elements, including but not limited to event handlers. It can be used for properties like `textContent`, `scrollTop`, custom properties, and more.
|
|
214
196
|
|
|
215
197
|
#### Examples:
|
|
216
198
|
|
|
@@ -290,6 +272,7 @@ function* ChatComponent({ user = 'Anonymous', room }) { // Receive arguments ini
|
|
|
290
272
|
|
|
291
273
|
if (message) {
|
|
292
274
|
|
|
275
|
+
// Access current arguments values with 'this.$args'.
|
|
293
276
|
connection.send(JSON.stringify({ user: this.$args.user, message }))
|
|
294
277
|
|
|
295
278
|
message = ''
|
|
@@ -377,11 +360,58 @@ MyCustomRow.is = 'tr'
|
|
|
377
360
|
```
|
|
378
361
|
> This code will instruct Ajo to render a `<tr>` element instead of the default `<div>`. This capability is crucial for rendering and hydrating any type of HTML element when using stateful components.
|
|
379
362
|
|
|
380
|
-
|
|
363
|
+
### Wrapper Element Default Attributes
|
|
364
|
+
|
|
365
|
+
When a stateful component is rendered in Ajo, you can specify default attributes for all components instances of that type. This is useful for setting default attributes that are common to all instances of a component, such as `class` or `style`.
|
|
366
|
+
|
|
367
|
+
To specify default attributes for a component, set the `attrs` property on the Generator Function of your component. For example:
|
|
368
|
+
|
|
369
|
+
```javascript
|
|
370
|
+
function* MyComponent() {
|
|
371
|
+
// ...
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
MyComponent.attrs = { class: 'my-class' }
|
|
375
|
+
```
|
|
376
|
+
> This code will instruct Ajo to set the `class` attribute to `my-class` on all instances of `MyComponent`.
|
|
377
|
+
|
|
378
|
+
### `attr:`
|
|
379
|
+
|
|
380
|
+
- **Purpose:** The `attr:` prefix is used in Ajo to explicitly set attributes to the underlying DOM element of a stateful component.
|
|
381
|
+
This prefix distinguishes regular HTML attributes from component arguments, making it easier to identify and manage them.
|
|
382
|
+
|
|
383
|
+
- **Behavior:**
|
|
384
|
+
- When a stateful component is rendered in Ajo, any property on it that starts with `attr:` is treated as a regular HTML attribute and is applied to the component's underlying DOM element.
|
|
385
|
+
- This mechanism ensures that the arguments are clearly identified and separated from the HTML attributes.
|
|
386
|
+
|
|
387
|
+
- **Usage:**
|
|
388
|
+
- Use `attr:` prefixed attributes when you need to pass attributes to a component's underlying DOM element.
|
|
389
|
+
|
|
390
|
+
- **Example:**
|
|
391
|
+
```jsx
|
|
392
|
+
function* ParentComponent() {
|
|
393
|
+
|
|
394
|
+
const someData = { /* ... */ }
|
|
395
|
+
const handleEvent = () => { /* ... */ }
|
|
396
|
+
|
|
397
|
+
yield <ChildComponent
|
|
398
|
+
attr:class="my-class"
|
|
399
|
+
data={someData}
|
|
400
|
+
onEvent={handleEvent}
|
|
401
|
+
/>
|
|
402
|
+
}
|
|
403
|
+
|
|
404
|
+
function* ChildComponent({ data, onEvent }) {
|
|
405
|
+
// ...
|
|
406
|
+
}
|
|
407
|
+
```
|
|
408
|
+
> In this example, `ParentComponent` renders `ChildComponent`, passing `someData` and `handleEvent` as arguments. `attr:class` is a regular HTML attribute and is not passed to the component's generator function, it is applied to the DOM element associated with the component.
|
|
409
|
+
|
|
410
|
+
This `attr:` prefixed attribute system in Ajo enhances the clarity and readability of component composition. It makes the intent of passing DOM attributes more explicit, reducing confusion between function arguments and HTML attributes.
|
|
381
411
|
|
|
382
|
-
|
|
412
|
+
### SSR and Hydration
|
|
383
413
|
|
|
384
|
-
|
|
414
|
+
In the context of Server-Side Rendering (SSR), this features allows Ajo to gracefully hydrate existing SSR-generated DOM elements. Ajo can extend the functionality of built-in browser DOM elements without relying on Web Components or standards like Declarative Shadow DOM. It provides a streamlined, efficient method for enhancing and manipulating built-in elements, offering a more practical solution compared to the complexities of Web Components.
|
|
385
415
|
|
|
386
416
|
## Lifecycle methods
|
|
387
417
|
|
|
@@ -557,22 +587,22 @@ function* MultiStepForm({ initialData }) {
|
|
|
557
587
|
switch(currentStep) {
|
|
558
588
|
case 0:
|
|
559
589
|
yield <StepOne
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
590
|
+
data={formData}
|
|
591
|
+
onNext={handleNextStep}
|
|
592
|
+
onRestart={handleRestart}
|
|
563
593
|
/>
|
|
564
594
|
break
|
|
565
595
|
case 1:
|
|
566
596
|
yield <StepTwo
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
597
|
+
data={formData}
|
|
598
|
+
onNext={handleNextStep}
|
|
599
|
+
onRestart={handleRestart}
|
|
570
600
|
/>
|
|
571
601
|
break
|
|
572
602
|
default:
|
|
573
603
|
yield <FinalStep
|
|
574
|
-
|
|
575
|
-
|
|
604
|
+
data={formData}
|
|
605
|
+
onRestart={handleRestart}
|
|
576
606
|
/>
|
|
577
607
|
}
|
|
578
608
|
}
|
|
@@ -580,40 +610,6 @@ function* MultiStepForm({ initialData }) {
|
|
|
580
610
|
```
|
|
581
611
|
> In `handleRestart`, `this.return()` is first called to reset the generator function. This effectively ends the current execution of the component's generator function and prepares it to start from the beginning. Immediately after, `this.refresh()` is called to trigger a re-render of the component. This ensures that after the state is reset, the component's UI is also updated to reflect its initial state.
|
|
582
612
|
|
|
583
|
-
### `arg:`
|
|
584
|
-
|
|
585
|
-
- **Purpose:** The `arg:` prefix is used in Ajo to explicitly pass arguments to generator functions. This prefix distinguishes component arguments from regular HTML attributes and other special properties.
|
|
586
|
-
|
|
587
|
-
- **Behavior:**
|
|
588
|
-
- When a stateful component is rendered in Ajo, any property on it that starts with `arg:` is treated as an argument to be passed to the component's generator function.
|
|
589
|
-
- This mechanism ensures that the arguments are clearly identified and separated from other attributes or DOM properties.
|
|
590
|
-
|
|
591
|
-
- **Usage:**
|
|
592
|
-
- Use `arg:` prefixed attributes when you need to pass data or event handlers to a component's generator function.
|
|
593
|
-
- This approach is particularly useful in maintaining a clear separation between component-specific arguments and other attributes that might be used for styling or DOM manipulation.
|
|
594
|
-
|
|
595
|
-
- **Example:**
|
|
596
|
-
```jsx
|
|
597
|
-
function* ParentComponent() {
|
|
598
|
-
|
|
599
|
-
const someData = { /* ... */ }
|
|
600
|
-
const handleEvent = () => { /* ... */ }
|
|
601
|
-
|
|
602
|
-
yield <ChildComponent
|
|
603
|
-
class="my-class"
|
|
604
|
-
arg:data={someData}
|
|
605
|
-
arg:onEvent={handleEvent}
|
|
606
|
-
/>
|
|
607
|
-
}
|
|
608
|
-
|
|
609
|
-
function* ChildComponent({ data, onEvent }) {
|
|
610
|
-
// ...
|
|
611
|
-
}
|
|
612
|
-
```
|
|
613
|
-
> In this example, `ParentComponent` renders `ChildComponent`, passing `someData` and `handleEvent` as arguments using the `arg:` prefix. `class` is a regular HTML attribute and is not passed to the component's generator function, it is applied to the DOM element associated with the component.
|
|
614
|
-
|
|
615
|
-
This `arg:` prefixed attribute system in Ajo enhances the clarity and readability of component composition. It makes the intent of passing down arguments more explicit, reducing confusion between HTML attributes, and other special properties. This is especially beneficial in complex applications where components have multiple responsibilities and interact with both their children and the DOM.
|
|
616
|
-
|
|
617
613
|
## Server-Side Rendering (SSR)
|
|
618
614
|
|
|
619
615
|
Ajo supports Server-Side Rendering (SSR), enabling components to be rendered to HTML in server-side JavaScript environments. This feature enhances the capabilities of Ajo for projects requiring SEO-friendly pages and faster initial page loads.
|