@alexgyver/component 2.0.0 → 2.0.2
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/Component.min.js +1 -1
- package/Component.min.js.gz +0 -0
- package/Component.pico.min.js +1 -1
- package/Component.pico.min.js.gz +0 -0
- package/Component.tiny.min.js +1 -1
- package/Component.tiny.min.js.gz +0 -0
- package/README.md +10 -14
- package/package.json +1 -1
- package/src/Component.js +2 -2
- package/src/EL.js +75 -55
- package/src/utils.js +1 -61
package/Component.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
|
|
1
|
+
class t{constructor(e,n={},s=!1){this.$root=t.make(e,{...n,ctx:this},s)}static make(s,a={},r=!1){s??=a.tag;let c="svg"==s||a.svg||r?document.createElementNS("http://www.w3.org/2000/svg",s??"svg"):document.createElement(s??"div");t.update(c,a);for(let n of e)Object.defineProperty(c,n,{value:(...e)=>t[n](c,...e)});return n.forEach(t=>{t in a&&(c["_"+t]=a[t].bind(c.ctx,{el:c,ctx:c.ctx}))}),c._onResize&&(c._ro=new ResizeObserver(t=>{for(const e of t)if(e.target===c)return void c._onResize()}),c._ro.observe(c)),c}static update(t,e){if(!h.node(t)||!h.obj(e))return t;t.ctx=e.ctx??e.context??t.ctx;for(let[n,s]of Object.entries(e))u(t,n,s);return t._onUpdate?.(),e.also?.call(t.ctx,{el:t,ctx:t.ctx}),t}static mount(t,e){t&&(null==e?t.parentNode?.removeChild(t):t.parentNode!==e&&(e.appendChild(t),a(t)))}static clear(e,n=!0){if(e)for(;e.firstChild;)n&&t.clear(e.firstChild,!0),t.remove(e.firstChild,!1)}static remove(e,s=!0){e&&(s&&t.clear(e,!0),t.release(e),t.unbind(e),e._ro?.disconnect(),e._onDestroy?.(),n.forEach(t=>e["_"+t]=null),e.parentNode?.removeChild(e))}static replace(e,n,s=!0){return e&&(e.parentNode?.replaceChild(n,e),a(n),n&&s&&(n.ctx=e.ctx)),t.remove(e),n}static release(t){t&&(Object.values(t._events??{}).forEach(({ev:e,fn:n,opts:s})=>t.removeEventListener(e,n,s)),t._events={})}static unbind(t){t&&(Object.values(t._unsub??{}).forEach(t=>t()),t._unsub={})}static makeShadow(e,n={},s=""){return e&&h.obj(n)?(h.node(e)||(e=document.createElement(e)),e.attachShadow({mode:"open"}),t.update(e.shadowRoot,{ctx:n.context??n.ctx,child:[{tag:"style",$:"style",text:s},n.child,n.children]}),delete n.child,delete n.children,t.update(e,n)):null}static setTemplate(e,n,s){t.templates.set(e,(...e)=>t.make(n,s(...e)))}static useTemplate(e,...n){const s=t.templates.get(e);return s?s(...n):null}static templates=new Map;static config=t.update}const e=["update","mount","clear","remove"],n=["onMount","onRender","onUpdate","onResize","onDestroy"],s=new Set(["tag","get","also","context","ctx","svg",...n]);function a(t,e=50){const n=()=>{t.isConnected&&(t._mounted||(t._mounted=!0,t._onMount?.()),t.clientWidth||t.clientHeight)?t._rendered||(t._rendered=!0,t._onRender?.()):e--&&requestAnimationFrame(n)};(t?._onMount||t?._onRender)&&n()}const r={children:"child",children_r:"child_r",text:"textContent",html:"innerHTML"},c={push(t,e){e.push(t)},$(t,e){t.ctx&&(t.ctx["$"+e]=t)},attrs(t,e){o("attrs",t,e,(e,n)=>t.setAttribute(e,n),e=>t.removeAttribute(e))},data(t,e){o("data",t,e,(e,n)=>t.dataset[e]=n,e=>delete t.dataset[e])},props(t,e){for(let n in e){let s=d(t,n,null,e[n]);t[n]=["min","max","step","selectedIndex"].includes(n)||"value"==n&&["number","range"].includes(t.type)?null==s||""===s||Number.isNaN(s)?"":+s:s??""}},transition(t,e){const{duration:n=300,easing:s="ease",delay:a=0,onEnd:r=null,...o}=e;t.style.transition=Object.keys(o).map(t=>`${t} ${n}ms ${s} ${a}ms`).join(", "),r&&c.events(t,{transitionend:{handler:r,once:!0}}),requestAnimationFrame(()=>c.style(t,o))},events(t,e){for(let n in e){let s=e[n],a={};if(h.obj(s)&&(a=s,s=s.handler,!s))continue;const r=e=>s.call(t.ctx,Object.assign(e,{el:t,ctx:t.ctx}));t._events||(t._events={});const c=t._events[n];c&&t.removeEventListener(n,c.fn,c.opts),t._events[n]={ev:n,fn:r,opts:a},t.addEventListener(n,r,a)}},events_r(e,n){t.release(e),c.events(e,n)},child(t,e){l(t,e)},child_r(e,n){t.clear(e),c.child(e,n)},style(t,e){i("style",t,e,e=>t.style.cssText+=e+";",(e,n)=>{e.startsWith("--")?t.style.setProperty(e,n):t.style[e]=n})},style_r(t,e){t.style.cssText="",c.style(t,e)},class(t,e){h.arr(e)&&(e=Object.fromEntries(e.filter(Boolean).map(t=>[t,!0]))),i("class",t,e,e=>e.split(/\s+/).forEach(e=>e&&t.classList.add(e)),(e,n)=>n?t.classList.add(e):t.classList.remove(e))},class_r(t,e){t.className="",c.class(t,e)},parent(e,n){t.mount(e,n)}};function o(t,e,n,s,a){for(let r in n){let c=d(e,t,r,n[r]);null==c?a(r):s(r,String(c))}}function i(t,e,n,s,a){if(h.str(n))s(n);else for(let s in n)"_raw"==s?c[t](e,n[s]):a(s,d(e,t,s,n[s]))}function l(e,n){n&&(h.str(n)?e.insertAdjacentHTML("beforeend",n):h.arr(n)?n.forEach(t=>l(e,t)):h.node(n)?t.mount(n,e):n instanceof t?t.mount(n.$root,e):h.obj(n)&&t.make(null,{ctx:e.ctx,...n,parent:e},e instanceof SVGElement))}function d(t,e,n,s){if(h.func(s))return s.call(t.ctx,{el:t,ctx:t.ctx});if(h.arr(s)&&h.state(s[0]))return s.map(s=>d(t,e,n,s))[0];if(h.state(s)){const a=(a,r)=>{r=s.map({el:t,ctx:t.ctx,name:a,value:r}),u(t,e,n?{[n]:r}:r),t._onUpdate?.()},r=[e,n,s.name].join(".");t._unsub||(t._unsub={});let c=t._unsub[r];return c&&c(),t._unsub[r]=s._state.subscribe(s.name,a),s.map({el:t,ctx:t.ctx,name:s.name,value:s._state[s.name]})}return s}function u(t,e,n){if(s.has(e))return;(e=r[e]??e).startsWith("on")?(n={[e.slice(2).toLowerCase()]:n},e="events"):n=d(t,e,null,n);const a=c[e];null!=n&&a?a(t,n):c.props(t,{[e]:n})}const h={func:t=>"function"==typeof t,str:t=>"string"==typeof t,arr:t=>Array.isArray(t),node:t=>t instanceof Node,obj:t=>null!==t&&"object"==typeof t,state:t=>t&&t._state};class m{static svg=(t={},e={})=>({tag:"svg",...e,attrs:t});static rect=(t,e,n,s,a,r,c={},o={})=>({tag:"rect",...o,attrs:{...c,x:t,y:e,width:n,height:s,rx:a,ry:r}});static circle=(t,e,n,s={},a={})=>({tag:"circle",...a,attrs:{...s,cx:t,cy:e,r:n}});static line=(t,e,n,s,a={},r={})=>({tag:"line",...r,attrs:{...a,x1:t,y1:e,x2:n,y2:s}});static polyline=(t,e={},n={})=>({tag:"polyline",...n,attrs:{...e,points:t}});static polygon=(t,e={},n={})=>({tag:"polygon",...n,attrs:{...e,points:t}});static path=(t,e={},n={})=>({tag:"path",...n,attrs:{...e,d:t}});static text=(t,e,n,s={},a={})=>({tag:"text",...a,text:t,attrs:{...s,x:e,y:n}});static make=(e,n)=>t.make(e,n,!0);static update=t.update;static config=t.update}function p(t,e=""){if(e||(e=_(t)),x.has(e))return;const n=document.createElement("style");return n.textContent=t,document.head.appendChild(n),x.set(e,n),n}function f(t,e=""){e||(e=_(t));const n=x.get(e);n&&(x.delete(e),n.remove())}function _(t){let e=5381;for(let n=0;n<t.length;n++)e=(e<<5)+e+t.charCodeAt(n),e|=0;return e.toString(36)}Object.getOwnPropertyNames(m).forEach(t=>m["make_"+t]=(...e)=>m.make(null,m[t](...e)));const x=new Map;class v{constructor(t={}){this._data={},this._subs=new Map,this.addStates(t)}addStates(t){for(const e in t)e in this||e in this._data||(this._data[e]=t[e],Object.defineProperty(this,e,{get:()=>this._data[e],set:t=>{if(Object.is(this._data[e],t))return;this._data[e]=t;const n=this._subs.get(e);n&&n.forEach(n=>n(e,t))}}))}hasState(t){return t in this._data}bind(t,e=t=>t.value){return{_state:this,name:t,map:e}}subscribe(t,e){return this._subs.has(t)||this._subs.set(t,new Set),this._subs.get(t).add(e),()=>this._subs.get(t).delete(e)}}function b(t){return new v(t)}export{t as EL,m as SVG,v as State,p as addCSS,f as removeCSS,b as useState};
|
package/Component.min.js.gz
CHANGED
|
Binary file
|
package/Component.pico.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class t{constructor(e,
|
|
1
|
+
class t{constructor(e,s={},n=!1){this.$root=t.make(e,{...s,ctx:this},n)}static make(e,s={},n=!1){e??=s.tag;let r="svg"==e||s.svg||n?document.createElementNS("http://www.w3.org/2000/svg",e??"svg"):document.createElement(e??"div");return t.update(r,s),r}static update(t,e){if(!i.node(t)||!i.obj(e))return t;t.ctx=e.ctx??e.context??t.ctx;for(let[s,n]of Object.entries(e))l(t,s,n);return e.also?.call(t.ctx,{el:t,ctx:t.ctx}),t}static mount(t,e){null==e?t?.parentNode?.removeChild(t):t?.parentNode!==e&&e.appendChild(t)}static clear(e,s=!0){if(e)for(;e.firstChild;)t.remove(e.firstChild,!1)}static remove(t,e=!0){t&&t.parentNode?.removeChild(t)}static config=t.update}const e=new Set(["tag","get","also","context","ctx","svg"]),s={children:"child",children_r:"child_r",text:"textContent",html:"innerHTML"},n={push(t,e){e.push(t)},$(t,e){t.ctx&&(t.ctx["$"+e]=t)},attrs(t,e){r("attrs",t,e,(e,s)=>t.setAttribute(e,s),e=>t.removeAttribute(e))},data(t,e){r("data",t,e,(e,s)=>t.dataset[e]=s,e=>delete t.dataset[e])},props(t,e){for(let s in e){let n=c(0,0,0,e[s]);t[s]=["min","max","step","selectedIndex"].includes(s)||"value"==s&&["number","range"].includes(t.type)?null==n||""===n||Number.isNaN(n)?"":+n:n??""}},transition(t,e){const{duration:s=300,easing:r="ease",delay:a=0,onEnd:o=null,...c}=e;t.style.transition=Object.keys(c).map(t=>`${t} ${s}ms ${r} ${a}ms`).join(", "),o&&n.events(t,{transitionend:{handler:o,once:!0}}),requestAnimationFrame(()=>n.style(t,c))},events(t,e){for(let s in e){let n=e[s],r={};if(i.obj(n)&&(r=n,n=n.handler,!n))continue;const a=e=>n.call(t.ctx,Object.assign(e,{el:t,ctx:t.ctx}));t.addEventListener(s,a,r)}},events_r(t,e){n.events(t,e)},child(t,e){o(t,e)},child_r(e,s){t.clear(e),n.child(e,s)},style(t,e){a("style",t,e,e=>t.style.cssText+=e+";",(e,s)=>{e.startsWith("--")?t.style.setProperty(e,s):t.style[e]=s})},style_r(t,e){t.style.cssText="",n.style(t,e)},class(t,e){i.arr(e)&&(e=Object.fromEntries(e.filter(Boolean).map(t=>[t,!0]))),a("class",t,e,e=>e.split(/\s+/).forEach(e=>e&&t.classList.add(e)),(e,s)=>s?t.classList.add(e):t.classList.remove(e))},class_r(t,e){t.className="",n.class(t,e)},parent(e,s){t.mount(e,s)}};function r(t,e,s,n,r){for(let t in s){let e=c(0,0,0,s[t]);null==e?r(t):n(t,String(e))}}function a(t,e,s,r,a){if(i.str(s))r(s);else for(let r in s)"_raw"==r?n[t](e,s[r]):a(r,c(0,0,0,s[r]))}function o(e,s){s&&(i.str(s)?e.insertAdjacentHTML("beforeend",s):i.arr(s)?s.forEach(t=>o(e,t)):i.node(s)?t.mount(s,e):s instanceof t?t.mount(s.$root,e):i.obj(s)&&t.make(null,{ctx:e.ctx,...s,parent:e},e instanceof SVGElement))}function c(t,e,s,n){return n}function l(t,r,a){if(e.has(r))return;(r=s[r]??r).startsWith("on")&&(a={[r.slice(2).toLowerCase()]:a},r="events");const o=n[r];null!=a&&o?o(t,a):n.props(t,{[r]:a})}const i={func:t=>"function"==typeof t,str:t=>"string"==typeof t,arr:t=>Array.isArray(t),node:t=>t instanceof Node,obj:t=>null!==t&&"object"==typeof t,state:t=>t&&t._state};export{t as EL};
|
package/Component.pico.min.js.gz
CHANGED
|
Binary file
|
package/Component.tiny.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
class t{constructor(e,
|
|
1
|
+
class t{constructor(e,s={},n=!1){this.$root=t.make(e,{...s,ctx:this},n)}static make(e,s={},n=!1){e??=s.tag;let a="svg"==e||s.svg||n?document.createElementNS("http://www.w3.org/2000/svg",e??"svg"):document.createElement(e??"div");return t.update(a,s),a}static update(t,e){if(!l.node(t)||!l.obj(e))return t;t.ctx=e.ctx??e.context??t.ctx;for(let[s,n]of Object.entries(e))i(t,s,n);return e.also?.call(t.ctx,{el:t,ctx:t.ctx}),t}static mount(t,e){null==e?t?.parentNode?.removeChild(t):t?.parentNode!==e&&e.appendChild(t)}static clear(e,s=!0){if(e)for(;e.firstChild;)t.remove(e.firstChild,!1)}static remove(t,e=!0){t&&t.parentNode?.removeChild(t)}static config=t.update}const e=new Set(["tag","get","also","context","ctx","svg"]),s={children:"child",children_r:"child_r",text:"textContent",html:"innerHTML"},n={push(t,e){e.push(t)},$(t,e){t.ctx&&(t.ctx["$"+e]=t)},attrs(t,e){a("attrs",t,e,(e,s)=>t.setAttribute(e,s),e=>t.removeAttribute(e))},data(t,e){a("data",t,e,(e,s)=>t.dataset[e]=s,e=>delete t.dataset[e])},props(t,e){for(let s in e){let n=o(0,0,0,e[s]);t[s]=["min","max","step","selectedIndex"].includes(s)||"value"==s&&["number","range"].includes(t.type)?null==n||""===n||Number.isNaN(n)?"":+n:n??""}},transition(t,e){const{duration:s=300,easing:a="ease",delay:r=0,onEnd:c=null,...o}=e;t.style.transition=Object.keys(o).map(t=>`${t} ${s}ms ${a} ${r}ms`).join(", "),c&&n.events(t,{transitionend:{handler:c,once:!0}}),requestAnimationFrame(()=>n.style(t,o))},events(t,e){for(let s in e){let n=e[s],a={};if(l.obj(n)&&(a=n,n=n.handler,!n))continue;const r=e=>n.call(t.ctx,Object.assign(e,{el:t,ctx:t.ctx}));t.addEventListener(s,r,a)}},events_r(t,e){n.events(t,e)},child(t,e){c(t,e)},child_r(e,s){t.clear(e),n.child(e,s)},style(t,e){r("style",t,e,e=>t.style.cssText+=e+";",(e,s)=>{e.startsWith("--")?t.style.setProperty(e,s):t.style[e]=s})},style_r(t,e){t.style.cssText="",n.style(t,e)},class(t,e){l.arr(e)&&(e=Object.fromEntries(e.filter(Boolean).map(t=>[t,!0]))),r("class",t,e,e=>e.split(/\s+/).forEach(e=>e&&t.classList.add(e)),(e,s)=>s?t.classList.add(e):t.classList.remove(e))},class_r(t,e){t.className="",n.class(t,e)},parent(e,s){t.mount(e,s)}};function a(t,e,s,n,a){for(let t in s){let e=o(0,0,0,s[t]);null==e?a(t):n(t,String(e))}}function r(t,e,s,a,r){if(l.str(s))a(s);else for(let a in s)"_raw"==a?n[t](e,s[a]):r(a,o(0,0,0,s[a]))}function c(e,s){s&&(l.str(s)?e.insertAdjacentHTML("beforeend",s):l.arr(s)?s.forEach(t=>c(e,t)):l.node(s)?t.mount(s,e):s instanceof t?t.mount(s.$root,e):l.obj(s)&&t.make(null,{ctx:e.ctx,...s,parent:e},e instanceof SVGElement))}function o(t,e,s,n){return n}function i(t,a,r){if(e.has(a))return;(a=s[a]??a).startsWith("on")&&(r={[a.slice(2).toLowerCase()]:r},a="events");const c=n[a];null!=r&&c?c(t,r):n.props(t,{[a]:r})}const l={func:t=>"function"==typeof t,str:t=>"string"==typeof t,arr:t=>Array.isArray(t),node:t=>t instanceof Node,obj:t=>null!==t&&"object"==typeof t,state:t=>t&&t._state};class d{static svg=(t={},e={})=>({tag:"svg",...e,attrs:t});static rect=(t,e,s,n,a,r,c={},o={})=>({tag:"rect",...o,attrs:{...c,x:t,y:e,width:s,height:n,rx:a,ry:r}});static circle=(t,e,s,n={},a={})=>({tag:"circle",...a,attrs:{...n,cx:t,cy:e,r:s}});static line=(t,e,s,n,a={},r={})=>({tag:"line",...r,attrs:{...a,x1:t,y1:e,x2:s,y2:n}});static polyline=(t,e={},s={})=>({tag:"polyline",...s,attrs:{...e,points:t}});static polygon=(t,e={},s={})=>({tag:"polygon",...s,attrs:{...e,points:t}});static path=(t,e={},s={})=>({tag:"path",...s,attrs:{...e,d:t}});static text=(t,e,s,n={},a={})=>({tag:"text",...a,text:t,attrs:{...n,x:e,y:s}});static make=(e,s)=>t.make(e,s,!0);static update=t.update;static config=t.update}function u(t,e=""){if(e||(e=f(t)),m.has(e))return;const s=document.createElement("style");return s.textContent=t,document.head.appendChild(s),m.set(e,s),s}function p(t,e=""){e||(e=f(t));const s=m.get(e);s&&(m.delete(e),s.remove())}function f(t){let e=5381;for(let s=0;s<t.length;s++)e=(e<<5)+e+t.charCodeAt(s),e|=0;return e.toString(36)}Object.getOwnPropertyNames(d).forEach(t=>d["make_"+t]=(...e)=>d.make(null,d[t](...e)));const m=new Map;export{t as EL,d as SVG,u as addCSS,p as removeCSS};
|
package/Component.tiny.min.js.gz
CHANGED
|
Binary file
|
package/README.md
CHANGED
|
@@ -33,6 +33,7 @@
|
|
|
33
33
|
|--------------|--------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------------------------------------|
|
|
34
34
|
| `parent` | `Node` | Монтировать созданный элемент в указанный |
|
|
35
35
|
| `tag` | `Строка` | HTML тег для child-объектов |
|
|
36
|
+
| `svg` | `Boolran` | Флаг SVG для child-объектов |
|
|
36
37
|
| `child` | `Конфиг\|Массив [Конфиг\|HTML\|Node\|Null\|Массив\|State]` | Создать детей и добавить к элементу. Без указания `tag` будет добавлен `div`. Null игнорируются |
|
|
37
38
|
| `child_r` | Как у `child` | Заменить детей |
|
|
38
39
|
| `props` | `Объект {name: Any\|Функция\|State}` | Добавить свойства как `el[name] = val` |
|
|
@@ -68,10 +69,11 @@
|
|
|
68
69
|
> Короткие имена параметров: `text` == `textContent`, `html` == `innerHTML`, `ctx` == `context`
|
|
69
70
|
|
|
70
71
|
> [!NOTE]
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
72
|
+
>- При обновлении `update` всё что указано как **добавить** - добавится, а **заменить** - заменит старое
|
|
73
|
+
>- Обработчики событий и `State`-бинды **не заменяют** старые, но корректно очищаются при уничтожении элемента
|
|
74
|
+
>- Обработчики жизненного цикла (onMount, onRender...) подключаются только при создании элемента, в update их обновить нельзя
|
|
75
|
+
>- Во все обработчики передаётся объект `{el, ctx}`, где el - сам элемент, ctx - его контекст. Также во все обработчики прокидывается контекст в `this` (если обработчик - function())
|
|
76
|
+
>- В обработчики событий элементов (click, input...) и onEnd анимаций добавляется сам `Event`, т.е. свойства `e.target` и прочие
|
|
75
77
|
|
|
76
78
|
### Функции
|
|
77
79
|
Статические методы EL:
|
|
@@ -83,11 +85,11 @@ EL.make(tag, cfg = {}, svg = false)
|
|
|
83
85
|
// Обновить элемент
|
|
84
86
|
EL.update(el, cfg);
|
|
85
87
|
|
|
86
|
-
// Подключить к
|
|
87
|
-
EL.mount(el, parent
|
|
88
|
+
// Подключить к родителю
|
|
89
|
+
EL.mount(el, parent);
|
|
88
90
|
|
|
89
91
|
// Заменить ребёнка old на нового el, old удалить, у el запустить монтаж с вызовом обработчиков. Вернёт el
|
|
90
|
-
EL.replace(old, el);
|
|
92
|
+
EL.replace(old, el, keepContext = true);
|
|
91
93
|
|
|
92
94
|
// Удалить всех детей
|
|
93
95
|
EL.clear(el, recursive = true);
|
|
@@ -144,7 +146,7 @@ module: {
|
|
|
144
146
|
`TINY` + `PICO`:
|
|
145
147
|
|
|
146
148
|
- Нет SVG
|
|
147
|
-
- Нет функций addCSS, removeCSS
|
|
149
|
+
- Нет функций addCSS, removeCSS
|
|
148
150
|
|
|
149
151
|
### State
|
|
150
152
|
```js
|
|
@@ -323,12 +325,6 @@ function addCSS(css, id = null);
|
|
|
323
325
|
|
|
324
326
|
// Удалить стили. Без ID будет вычислен хэш
|
|
325
327
|
function removeCSS(css, id = null);
|
|
326
|
-
|
|
327
|
-
// следить за обновлениями размера элемента
|
|
328
|
-
function watchResize(el, onResize);
|
|
329
|
-
|
|
330
|
-
// проверить статус подключения в DOM и рендера
|
|
331
|
-
function watchMount(el, waitRender = false);
|
|
332
328
|
```
|
|
333
329
|
|
|
334
330
|
## Примеры
|
package/package.json
CHANGED
package/src/Component.js
CHANGED
|
@@ -5,8 +5,8 @@ export { EL };
|
|
|
5
5
|
import { SVG } from "./SVG";
|
|
6
6
|
export { SVG };
|
|
7
7
|
|
|
8
|
-
import { addCSS, removeCSS
|
|
9
|
-
export { addCSS, removeCSS
|
|
8
|
+
import { addCSS, removeCSS } from "./utils";
|
|
9
|
+
export { addCSS, removeCSS };
|
|
10
10
|
/// #endif
|
|
11
11
|
|
|
12
12
|
/// #if !TINY_COMPONENT
|
package/src/EL.js
CHANGED
|
@@ -1,7 +1,3 @@
|
|
|
1
|
-
/// #if !TINY_COMPONENT
|
|
2
|
-
import { watchMount, watchResize } from "./utils";
|
|
3
|
-
/// #endif
|
|
4
|
-
|
|
5
1
|
export class EL {
|
|
6
2
|
// Создать элемент и поместить его в переменную $root
|
|
7
3
|
constructor(tag, cfg = {}, svg = false) {
|
|
@@ -14,7 +10,7 @@ export class EL {
|
|
|
14
10
|
static make(tag, cfg = {}, svg = false) {
|
|
15
11
|
tag ??= cfg.tag;
|
|
16
12
|
|
|
17
|
-
let el = (tag == 'svg' || svg)
|
|
13
|
+
let el = (tag == 'svg' || cfg.svg || svg)
|
|
18
14
|
? document.createElementNS("http://www.w3.org/2000/svg", tag ?? 'svg')
|
|
19
15
|
: document.createElement(tag ?? 'div');
|
|
20
16
|
|
|
@@ -22,14 +18,26 @@ export class EL {
|
|
|
22
18
|
|
|
23
19
|
/// #if !TINY_COMPONENT
|
|
24
20
|
for (let k of EL_METHODS) {
|
|
25
|
-
el
|
|
21
|
+
Object.defineProperty(el, k, {
|
|
22
|
+
value: (...a) => EL[k](el, ...a)
|
|
23
|
+
});
|
|
26
24
|
}
|
|
27
25
|
|
|
28
26
|
CALLBACKS.forEach(fn => {
|
|
29
27
|
if (fn in cfg) el['_' + fn] = cfg[fn].bind(el.ctx, { el, ctx: el.ctx });
|
|
30
28
|
});
|
|
31
29
|
|
|
32
|
-
if (el._onResize)
|
|
30
|
+
if (el._onResize) {
|
|
31
|
+
el._ro = new ResizeObserver(entries => {
|
|
32
|
+
for (const entry of entries) {
|
|
33
|
+
if (entry.target === el) {
|
|
34
|
+
el._onResize();
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
});
|
|
39
|
+
el._ro.observe(el);
|
|
40
|
+
}
|
|
33
41
|
/// #endif
|
|
34
42
|
|
|
35
43
|
return el;
|
|
@@ -46,31 +54,26 @@ export class EL {
|
|
|
46
54
|
for (let [param, val] of Object.entries(cfg)) _update(el, param, val);
|
|
47
55
|
|
|
48
56
|
/// #if !TINY_COMPONENT
|
|
49
|
-
|
|
57
|
+
el._onUpdate?.();
|
|
50
58
|
/// #endif
|
|
51
59
|
|
|
52
|
-
|
|
60
|
+
cfg.also?.call(el.ctx, { el, ctx: el.ctx });
|
|
53
61
|
|
|
54
62
|
return el;
|
|
55
63
|
}
|
|
56
64
|
|
|
57
65
|
//#region ## lifecycle
|
|
58
66
|
|
|
59
|
-
// Подключить к родителю, null -
|
|
60
|
-
static mount(el, parent
|
|
61
|
-
if (
|
|
67
|
+
// Подключить к родителю, null - отключить
|
|
68
|
+
static mount(el, parent) {
|
|
69
|
+
if (parent == null) {
|
|
70
|
+
el?.parentNode?.removeChild(el);
|
|
71
|
+
} else if (el?.parentNode !== parent) {
|
|
72
|
+
parent.appendChild(el);
|
|
62
73
|
/// #if !TINY_COMPONENT
|
|
63
|
-
|
|
64
|
-
if (el.parentNode) el.parentNode.removeChild(el);
|
|
65
|
-
} else {
|
|
66
|
-
/// #endif
|
|
67
|
-
if (el.parentNode !== parent) parent.appendChild(el);
|
|
68
|
-
/// #if !TINY_COMPONENT
|
|
69
|
-
if (tries) return watchMount(el, waitRender, tries);
|
|
70
|
-
}
|
|
74
|
+
_watchMount(el);
|
|
71
75
|
/// #endif
|
|
72
76
|
}
|
|
73
|
-
return Promise.resolve(el);
|
|
74
77
|
}
|
|
75
78
|
|
|
76
79
|
// Удалить всех детей
|
|
@@ -91,41 +94,34 @@ export class EL {
|
|
|
91
94
|
if (recursive) EL.clear(el, true);
|
|
92
95
|
EL.release(el);
|
|
93
96
|
EL.unbind(el);
|
|
94
|
-
|
|
97
|
+
el._ro?.disconnect();
|
|
98
|
+
el._onDestroy?.();
|
|
95
99
|
CALLBACKS.forEach(fn => el['_' + fn] = null);
|
|
96
100
|
/// #endif
|
|
97
|
-
|
|
101
|
+
el.parentNode?.removeChild(el); // remove
|
|
98
102
|
}
|
|
99
103
|
|
|
100
104
|
/// #if !TINY_COMPONENT
|
|
101
105
|
|
|
102
106
|
// Заменить ребёнка old на нового el, old удалить, у el запустить монтаж с вызовом обработчиков. Вернёт el
|
|
103
|
-
static replace(old, el, keepContext =
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
old.remove();
|
|
109
|
-
}
|
|
107
|
+
static replace(old, el, keepContext = true) {
|
|
108
|
+
old?.parentNode?.replaceChild(el, old);
|
|
109
|
+
_watchMount(el);
|
|
110
|
+
if (el && keepContext) el.ctx = old.ctx;
|
|
111
|
+
EL.remove(old);
|
|
110
112
|
return el;
|
|
111
113
|
}
|
|
112
114
|
|
|
113
115
|
// Отключить on-обработчики
|
|
114
116
|
static release(el) {
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
el._events = [];
|
|
118
|
-
}
|
|
117
|
+
Object.values(el?._events ?? {}).forEach(({ ev, fn, opts }) => el.removeEventListener(ev, fn, opts));
|
|
118
|
+
el?._events = {};
|
|
119
119
|
}
|
|
120
120
|
|
|
121
121
|
// Отключить state-бинды
|
|
122
122
|
static unbind(el) {
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
el._unsub = {};
|
|
126
|
-
// el._unsub.forEach(f => f());
|
|
127
|
-
// el._unsub = [];
|
|
128
|
-
}
|
|
123
|
+
Object.values(el?._unsub ?? {}).forEach(f => f());
|
|
124
|
+
el?._unsub = {};
|
|
129
125
|
}
|
|
130
126
|
|
|
131
127
|
/// #endif
|
|
@@ -182,12 +178,35 @@ const EL_METHODS = ['update', 'mount', 'clear', 'remove'];
|
|
|
182
178
|
const CALLBACKS = ['onMount', 'onRender', 'onUpdate', 'onResize', 'onDestroy'];
|
|
183
179
|
/// #endif
|
|
184
180
|
|
|
185
|
-
const SKIP_PARAM = new Set(['tag', 'get', 'also', 'context', 'ctx',
|
|
181
|
+
const SKIP_PARAM = new Set(['tag', 'get', 'also', 'context', 'ctx', 'svg',
|
|
186
182
|
/// #if !TINY_COMPONENT
|
|
187
183
|
...CALLBACKS
|
|
188
184
|
/// #endif
|
|
189
185
|
]);
|
|
190
186
|
|
|
187
|
+
/// #if !TINY_COMPONENT
|
|
188
|
+
function _watchMount(el, tries = 50) {
|
|
189
|
+
const check = () => {
|
|
190
|
+
if (el.isConnected) {
|
|
191
|
+
if (!el._mounted) {
|
|
192
|
+
el._mounted = true;
|
|
193
|
+
el._onMount?.();
|
|
194
|
+
}
|
|
195
|
+
|
|
196
|
+
if (el.clientWidth || el.clientHeight) {
|
|
197
|
+
if (!el._rendered) {
|
|
198
|
+
el._rendered = true;
|
|
199
|
+
el._onRender?.();
|
|
200
|
+
}
|
|
201
|
+
return;
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
if (tries--) requestAnimationFrame(check);
|
|
205
|
+
}
|
|
206
|
+
if (el?._onMount || el?._onRender) check();
|
|
207
|
+
}
|
|
208
|
+
/// #endif
|
|
209
|
+
|
|
191
210
|
const PARAM_ALIAS = {
|
|
192
211
|
children: 'child',
|
|
193
212
|
children_r: 'child_r',
|
|
@@ -222,28 +241,29 @@ const PARAM_UPD = {
|
|
|
222
241
|
const { duration = 300, easing = 'ease', delay = 0, onEnd = null, ...styles } = val;
|
|
223
242
|
el.style.transition = Object.keys(styles).map(st => `${st} ${duration}ms ${easing} ${delay}ms`).join(', ');
|
|
224
243
|
if (onEnd) {
|
|
225
|
-
PARAM_UPD.events(el, {
|
|
226
|
-
transitionend: { handler: onEnd, once: true }
|
|
227
|
-
});
|
|
244
|
+
PARAM_UPD.events(el, { transitionend: { handler: onEnd, once: true } });
|
|
228
245
|
}
|
|
229
246
|
requestAnimationFrame(() => PARAM_UPD.style(el, styles));
|
|
230
247
|
},
|
|
231
248
|
events(el, val) {
|
|
232
249
|
for (let ev in val) {
|
|
233
250
|
let h = val[ev];
|
|
234
|
-
let
|
|
251
|
+
let opts = {};
|
|
235
252
|
|
|
236
253
|
if (is.obj(h)) {
|
|
237
|
-
|
|
254
|
+
opts = h;
|
|
238
255
|
h = h.handler;
|
|
239
256
|
if (!h) continue;
|
|
240
257
|
}
|
|
241
258
|
|
|
242
259
|
const fn = (evt) => h.call(el.ctx, Object.assign(evt, { el, ctx: el.ctx }));
|
|
243
|
-
el.addEventListener(ev, fn, options);
|
|
244
260
|
/// #if !TINY_COMPONENT
|
|
245
|
-
(el._events
|
|
261
|
+
if (!el._events) el._events = {};
|
|
262
|
+
const old = el._events[ev];
|
|
263
|
+
if (old) el.removeEventListener(ev, old.fn, old.opts);
|
|
264
|
+
el._events[ev] = { ev, fn, opts };
|
|
246
265
|
/// #endif
|
|
266
|
+
el.addEventListener(ev, fn, opts);
|
|
247
267
|
}
|
|
248
268
|
},
|
|
249
269
|
events_r(el, val) {
|
|
@@ -257,13 +277,13 @@ const PARAM_UPD = {
|
|
|
257
277
|
},
|
|
258
278
|
child_r(el, val) {
|
|
259
279
|
EL.clear(el);
|
|
260
|
-
|
|
280
|
+
PARAM_UPD.child(el, val);
|
|
261
281
|
},
|
|
262
282
|
style(el, val) {
|
|
263
283
|
_applyObj('style', el, val,
|
|
264
284
|
r => el.style.cssText += r + ';',
|
|
265
285
|
(k, v) => {
|
|
266
|
-
|
|
286
|
+
k.startsWith('--') ? el.style.setProperty(k, v) : el.style[k] = v;
|
|
267
287
|
}
|
|
268
288
|
);
|
|
269
289
|
},
|
|
@@ -283,7 +303,7 @@ const PARAM_UPD = {
|
|
|
283
303
|
PARAM_UPD.class(el, val);
|
|
284
304
|
},
|
|
285
305
|
parent(el, val) {
|
|
286
|
-
EL.mount(el, val
|
|
306
|
+
EL.mount(el, val);
|
|
287
307
|
},
|
|
288
308
|
};
|
|
289
309
|
|
|
@@ -328,13 +348,13 @@ function _makeVal(el, param, sub, val) {
|
|
|
328
348
|
const fn = (name, value) => {
|
|
329
349
|
value = val.map({ el, ctx: el.ctx, name, value });
|
|
330
350
|
_update(el, param, sub ? { [sub]: value } : value);
|
|
331
|
-
|
|
351
|
+
el._onUpdate?.();
|
|
332
352
|
}
|
|
333
|
-
const key = param
|
|
353
|
+
const key = [param, sub, val.name].join('.');
|
|
334
354
|
if (!el._unsub) el._unsub = {};
|
|
335
|
-
|
|
355
|
+
let old = el._unsub[key];
|
|
356
|
+
if (old) old();
|
|
336
357
|
el._unsub[key] = val._state.subscribe(val.name, fn);
|
|
337
|
-
// (el._unsub ??= []).push(val._state.subscribe(val.name, fn));
|
|
338
358
|
return val.map({ el, ctx: el.ctx, name: val.name, value: val._state[val.name] });
|
|
339
359
|
}
|
|
340
360
|
/// #endif
|
package/src/utils.js
CHANGED
|
@@ -31,64 +31,4 @@ function _hash(str) {
|
|
|
31
31
|
return hash.toString(36);
|
|
32
32
|
}
|
|
33
33
|
|
|
34
|
-
const cssMap = new Map(); // hash: styleElement
|
|
35
|
-
|
|
36
|
-
//#region watch
|
|
37
|
-
|
|
38
|
-
// проверить статус подключения в DOM и рендера
|
|
39
|
-
export function watchMount(el, waitRender = false, tries = 100) {
|
|
40
|
-
return new Promise(res => {
|
|
41
|
-
let mounted, rendered;
|
|
42
|
-
const check = () => {
|
|
43
|
-
if (el.isConnected) {
|
|
44
|
-
if (!el._mounted) {
|
|
45
|
-
el._mounted = true;
|
|
46
|
-
if (el._onMount) el._onMount();
|
|
47
|
-
}
|
|
48
|
-
if (!mounted) {
|
|
49
|
-
mounted = true;
|
|
50
|
-
if (!waitRender) res(el);
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
if (el.clientWidth || el.clientHeight) {
|
|
54
|
-
if (!el._rendered) {
|
|
55
|
-
el._rendered = true;
|
|
56
|
-
if (el._onRender) el._onRender();
|
|
57
|
-
}
|
|
58
|
-
if (!rendered) {
|
|
59
|
-
rendered = true;
|
|
60
|
-
if (waitRender) res(el);
|
|
61
|
-
}
|
|
62
|
-
return;
|
|
63
|
-
}
|
|
64
|
-
}
|
|
65
|
-
if (tries--) {
|
|
66
|
-
requestAnimationFrame(check);
|
|
67
|
-
} else {
|
|
68
|
-
if ((waitRender && !rendered) || (!waitRender && !mounted)) res(null);
|
|
69
|
-
}
|
|
70
|
-
};
|
|
71
|
-
|
|
72
|
-
check();
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// следить за обновлениями размера элемента
|
|
77
|
-
export function watchResize(el, onResize) {
|
|
78
|
-
const ro = new ResizeObserver(entries => {
|
|
79
|
-
for (const entry of entries) {
|
|
80
|
-
if (entry.target === el) onResize(entry);
|
|
81
|
-
}
|
|
82
|
-
});
|
|
83
|
-
|
|
84
|
-
ro.observe(el);
|
|
85
|
-
|
|
86
|
-
const mo = new MutationObserver(() => {
|
|
87
|
-
if (!el.isConnected) {
|
|
88
|
-
ro.disconnect();
|
|
89
|
-
mo.disconnect();
|
|
90
|
-
}
|
|
91
|
-
});
|
|
92
|
-
|
|
93
|
-
mo.observe(document.body, { childList: true, subtree: true });
|
|
94
|
-
}
|
|
34
|
+
const cssMap = new Map(); // hash: styleElement
|