@alexgyver/component 1.4.1 → 1.5.0

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.js CHANGED
@@ -9,8 +9,19 @@ export class EL {
9
9
  * @param {Boolean} svg SVG
10
10
  */
11
11
  constructor(tag, data = {}, svg = false) {
12
- EL.context = this;
13
- this.$root = EL.make(tag, data, svg);
12
+ this.$root = EL.makeIn(this, tag, data, svg);
13
+ }
14
+ make(tag, data = {}, svg = false) {
15
+ return EL.makeIn(this, tag, data, svg);
16
+ }
17
+ makeArray(arr, svg = false) {
18
+ return EL.makeArrayIn(this, arr, svg);
19
+ }
20
+ config(el, data, svg = false) {
21
+ return EL.configIn(this, el, data, svg);
22
+ }
23
+ makeShadow(host, data = {}, sheet = null) {
24
+ return EL.makeShadowIn(this, host, data, sheet);
14
25
  }
15
26
 
16
27
  /**
@@ -22,13 +33,11 @@ export class EL {
22
33
  */
23
34
  static make(tag, data = {}, svg = false) {
24
35
  if (data instanceof Node) return data;
25
- if (!tag) tag = 'div';
26
36
  if (tag == 'svg') svg = true;
27
- return EL.config(svg ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag), data, svg);
37
+ return EL.config(svg ? document.createElementNS("http://www.w3.org/2000/svg", tag ?? 'svg') : document.createElement(tag ?? 'div'), data, svg);
28
38
  }
29
39
  static makeIn(ctx, tag, data = {}, svg = false) {
30
- data.context = ctx;
31
- return EL.make(tag, data, svg);
40
+ return EL.make(tag, { ...data, context: ctx }, svg);
32
41
  }
33
42
 
34
43
  /**
@@ -36,57 +45,47 @@ export class EL {
36
45
  * @param {Node | Array} el элемент или массив элементов
37
46
  * @param {object} data параметры
38
47
  * @param {Boolean} svg SVG
39
- * @returns {Node}
48
+ * @returns {Node | Array}
40
49
  */
41
50
  static config(el, data, svg = false) {
42
- if (Array.isArray(el)) {
43
- el.forEach(e => EL.config(e, data, svg));
44
- return null;
45
- }
46
51
  if (!(el instanceof Node) || (typeof data !== 'object')) {
47
52
  return el;
48
53
  }
54
+ if (Array.isArray(el)) {
55
+ return el.map(e => EL.config(e, data, svg));
56
+ }
49
57
 
50
- let ctx = data.context;
51
- if (ctx === undefined) ctx = EL.context;
52
- else EL.context = ctx;
58
+ const ctx = ('context' in data) ? (EL.context = data.context) : EL.context;
53
59
 
54
- const addChild = (obj) => {
60
+ const addChild = obj => {
55
61
  if (obj) {
56
62
  if (obj instanceof Node) el.appendChild(obj);
57
63
  else if (obj instanceof EL) el.appendChild(obj.$root);
58
64
  else if (typeof obj === 'string') el.insertAdjacentHTML('beforeend', obj);
59
- else if (typeof obj === 'object') {
60
- let cmp = EL.make(obj.tag, obj, svg || obj.tag == 'svg');
61
- if (cmp) el.appendChild(cmp);
62
- }
65
+ else if (typeof obj === 'object') EL.make(obj.tag, { ...obj, parent: el }, (svg || obj.tag == 'svg'));
63
66
  }
64
67
  }
65
68
 
66
- const getClasses = (cls) => {
67
- if (Array.isArray(cls)) return cls;
68
- if (typeof cls === 'string') return cls.split(/\s+/);
69
- if (typeof cls === 'object') return Object.keys(cls).filter(k => cls[k]);
70
- return [];
71
- }
72
-
73
- const mount = () => {
74
- if (el.isConnected) {
75
- el._mounted = true;
76
- data.onMount(el);
77
- } else requestAnimationFrame(mount);
78
- }
69
+ const call = fn => { if (fn) fn.call(ctx, el, ctx) }
79
70
 
80
71
  for (const [key, val] of Object.entries(data)) {
81
72
  switch (key) {
82
- case 'text': el.textContent = (val == null) ? '' : String(val); continue; // == - null + undef
83
- case 'html': el.innerHTML = (val == null) ? '' : String(val); continue;
73
+ case 'text':
74
+ el.textContent = (val == null) ? '' : String(val); // == - null + undef
75
+ continue;
76
+
77
+ case 'html':
78
+ el.innerHTML = (val == null) ? '' : String(val);
79
+ continue;
80
+
84
81
  case 'tag':
85
- case 'context':
86
82
  case 'get':
87
83
  case 'also':
88
- case 'onConfig':
84
+ case 'parent':
85
+ case 'context':
89
86
  case 'onMount':
87
+ case 'onUpdate':
88
+ case 'onDestroy':
90
89
  continue;
91
90
  }
92
91
 
@@ -103,18 +102,14 @@ export class EL {
103
102
  break;
104
103
 
105
104
  case 'events':
106
- for (let ev in val) el.addEventListener(ev, ctx ? val[ev].bind(ctx) : val[ev]);
105
+ for (let ev in val) el.addEventListener(ev, e => val[ev].call(ctx, e, el, ctx));
107
106
  break;
108
107
 
109
108
  case 'click':
110
- case 'change':
111
109
  case 'input':
110
+ case 'change':
112
111
  case 'mousewheel':
113
- el.addEventListener(key, ctx ? val.bind(ctx) : val);
114
- break;
115
-
116
- case 'parent':
117
- val.appendChild(el);
112
+ el.addEventListener(key, e => val.call(ctx, e, el, ctx));
118
113
  break;
119
114
 
120
115
  case 'attrs':
@@ -143,51 +138,93 @@ export class EL {
143
138
  for (let obj of val) addChild(obj);
144
139
  break;
145
140
 
146
- case 'animate': {
147
- const { duration = 300, easing = 'ease', ...styles } = val;
148
- el.style.transition = Object.keys(styles).map(st => `${st} ${duration}ms ${easing}`).join(', ');
149
- requestAnimationFrame(() => { for (let st in styles) el.style[st] = styles[st]; });
150
- } break;
151
-
152
141
  case 'style_r':
153
142
  el.style.cssText = '';
154
143
  // fall
155
144
  case 'style':
156
145
  if (typeof val === 'string') {
157
146
  el.style.cssText += val + ';';
158
- } else for (let st in val) {
159
- if (val[st]) el.style[st] = val[st];
147
+ } else {
148
+ for (let st in val) if (val[st]) el.style[st] = val[st];
160
149
  }
161
150
  break;
162
151
 
163
152
  case 'class_r':
164
153
  el.className = '';
165
154
  // fall
166
- case 'class':
167
- getClasses(val).forEach(c => c && el.classList.add(c));
168
- break;
155
+ case 'class': {
156
+ const getClasses = (cls) => {
157
+ if (Array.isArray(cls)) return Object.fromEntries(cls.filter(Boolean).map(c => [c, true]));
158
+ if (typeof cls === 'string') return getClasses(cls.split(/\s+/));
159
+ return cls;
160
+ }
161
+ for (const [cls, state] of Object.entries(getClasses(val))) {
162
+ state ? el.classList.add(cls) : el.classList.remove(cls);
163
+ }
164
+ } break;
165
+
166
+ case 'animate': {
167
+ const { duration = 300, easing = 'ease', onEnd = null, ...styles } = val;
168
+ el.style.transition = Object.keys(styles).map(st => `${st} ${duration}ms ${easing}`).join(', ');
169
+ requestAnimationFrame(() => { for (let st in styles) el.style[st] = styles[st]; });
170
+
171
+ const onEndHandler = () => {
172
+ el.removeEventListener('transitionend', onEndHandler);
173
+ call(onEnd);
174
+ };
175
+ el.addEventListener('transitionend', onEndHandler);
176
+ } break;
169
177
 
170
178
  default: el[key] = val;
171
179
  break;
172
180
  }
173
181
  }
174
182
 
175
- if (data.also) ctx ? data.also.call(ctx, el) : data.also(el);
176
- if (data.onMount && !el._mounted) mount();
177
- if (data.onConfig) data.onConfig(el);
183
+ if (data.parent) data.parent.appendChild(el);
184
+
185
+ let tries = 50;
186
+ const mount = () => {
187
+ if (!el._mounted) {
188
+ if (el.isConnected) {
189
+ el._mounted = true;
190
+ call(data.onMount);
191
+ } else if (--tries) {
192
+ requestAnimationFrame(mount);
193
+ }
194
+ }
195
+ }
196
+ mount();
197
+
198
+ if (data.onDestroy) el._onDestroy = data.onDestroy.bind(ctx, el, ctx);
199
+ if (data.onUpdate) el._onUpdate = data.onUpdate.bind(ctx, el, ctx);
200
+ if (el._onUpdate) el._onUpdate();
201
+ call(data.also);
202
+
178
203
  return el;
179
204
  }
180
205
  static configIn(ctx, el, data, svg = false) {
181
- data.context = ctx;
182
- return EL.config(el, data, svg);
206
+ return EL.config(el, { ...data, context: ctx }, svg);
183
207
  }
184
208
 
185
209
  /**
186
210
  * Удалить все child ноды
187
211
  * @param {HTMLElement} el
188
212
  */
189
- static clear(el) {
190
- while (el.firstChild) el.removeChild(el.firstChild);
213
+ static clear(el, recursive = true) {
214
+ while (el.firstChild) {
215
+ if (recursive) EL.clear(el.firstChild, true);
216
+ EL.remove(el.firstChild, false);
217
+ }
218
+ }
219
+
220
+ /**
221
+ * Удалить элемент
222
+ * @param {HTMLElement} el
223
+ */
224
+ static remove(el, recursive = true) {
225
+ if (recursive) EL.clear(el);
226
+ if (el._onDestroy) el._onDestroy();
227
+ el.remove();
191
228
  }
192
229
 
193
230
  /**
@@ -198,7 +235,10 @@ export class EL {
198
235
  */
199
236
  static makeArray(arr, svg = false) {
200
237
  if (!arr || !Array.isArray(arr)) return [];
201
- return arr.map(x => EL.make(x.tag, x, svg));
238
+ return arr.map(data => EL.make(data.tag, data, svg));
239
+ }
240
+ static makeArrayIn(ctx, arr, svg) {
241
+ return EL.makeArray(arr.map(data => ({ ...data, context: ctx })), svg);
202
242
  }
203
243
 
204
244
  /**
@@ -230,6 +270,9 @@ export class EL {
230
270
  EL.config($host, data);
231
271
  return $host;
232
272
  }
273
+ static makeShadowIn(ctx, host, data = {}, sheet = null) {
274
+ return EL.makeShadow(host, { ...data, context: ctx }, sheet);
275
+ }
233
276
  }
234
277
 
235
278
  // legacy
package/Component.min.js CHANGED
@@ -1 +1 @@
1
- var e={d:(t,a)=>{for(var c in a)e.o(a,c)&&!e.o(t,c)&&Object.defineProperty(t,c,{enumerable:!0,get:a[c]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{EL:()=>a,LV:()=>r,cj:()=>s,t4:()=>n,uA:()=>c});class a{static context;constructor(e,t={},c=!1){a.context=this,this.$root=a.make(e,t,c)}static make(e,t={},c=!1){return e&&"object"==typeof t?t instanceof Node?t:("svg"==e&&(c=!0),a.config(c?document.createElementNS("http://www.w3.org/2000/svg",e):document.createElement(e),t,c)):null}static makeIn(e,t,c={},n=!1){return c.context=e,a.make(t,c,n)}static config(e,t,c=!1){if(Array.isArray(e))return e.forEach(e=>a.config(e,t,c)),null;if(!(e instanceof Node)||"object"!=typeof t)return e;let n=t.context;a.context=null===n?null:n||a.context,n=a.context;let s=t=>{if(t)if(t instanceof Node)e.appendChild(t);else if(t instanceof a)e.appendChild(t.$root);else if("string"==typeof t)e.innerHTML+=t;else if("object"==typeof t){let n=a.make(t.tag??"div",t,c||"svg"==t.tag);n&&e.appendChild(n)}};for(const[c,r]of Object.entries(t)){switch(c){case"text":e.textContent=null==r?"":r+"";continue;case"html":e.innerHTML=null==r?"":r+"";continue;case"tag":case"context":case"get":case"also":continue}if(r)switch(c){case"class":(Array.isArray(r)?r:r.split(" ")).map(t=>t&&e.classList.add(t));break;case"push":r.push(e);break;case"$":case"var":n&&(n["$"+r]=e);break;case"events":for(let t in r)e.addEventListener(t,n?r[t].bind(n):r[t]);break;case"click":case"change":case"input":case"mousewheel":e.addEventListener(c,n?r.bind(n):r);break;case"parent":r.appendChild(e);break;case"attrs":for(let t in r)e.setAttribute(t,r[t]);break;case"props":for(let t in r)e[t]=r[t];break;case"child_r":a.clear(e);case"child":s(r);break;case"children_r":a.clear(e);case"children":for(let e of r)s(e);break;case"style_r":e.style.cssText="";case"style":if("string"==typeof r)e.style.cssText+=r+";";else for(let t in r)r[t]&&(e.style[t]=r[t]);break;default:e[c]=r}}return t.also&&n&&t.also.call(n,e),e}static configIn(e,t,c,n=!1){return c.context=e,a.config(t,c,n)}static clear(e){for(;e.firstChild;)e.removeChild(e.lastChild)}static makeArray(e,t=!1){return e&&Array.isArray(e)?e.map(e=>a.make(e.tag,e,t)):[]}static makeShadow(e,t={},c=null){if(!e||"object"!=typeof t)return null;let n=e instanceof Node?e:document.createElement(e);return n.attachShadow({mode:"open"}),a.config(n.shadowRoot,{context:t.context,children:[{tag:"style",textContent:c??""},t.child??{},...t.children??[]]}),delete t.children,delete t.child,a.config(n,t),n}}const c=a;class n{static make=(e,t)=>a.make(e,t,!0);static config=(e,t)=>a.config(e,t,!0);static makeArray=e=>a.makeArray(e,!0);static svg=(e={},t={})=>n._make("svg",e,t);static rect=(e,t,a,c,s,r,o={},i={})=>n._make("rect",{...o,x:e,y:t,width:a,height:c,rx:s,ry:r},i);static circle=(e,t,a,c={},s={})=>n._make("circle",{...c,cx:e,cy:t,r:a},s);static line=(e,t,a,c,s={},r={})=>n._make("line",{...s,x1:e,y1:t,x2:a,y2:c},r);static polyline=(e,t={},a={})=>n._make("polyline",{...t,points:e},a);static polygon=(e,t={},a={})=>n._make("polygon",{...t,points:e},a);static path=(e,t={},a={})=>n._make("path",{...t,d:e},a);static text=(e,t,a,c={},s={})=>n._make("text",{...c,x:t,y:a},{...s,text:e});static _make=(e,t={},a={})=>n.make(e,{attrs:{...t},...a})}class s{static addStyle(e,t,a=!1){if(e&&t&&("object"==typeof t&&(t=t.constructor.name),!s.#e.has(t)&&!s.#t.has(t)))if(a){let a=document.createElement("style");document.head.appendChild(a),a.textContent=e,s.#t.set(t,a)}else s.#a||(s.#a=document.head.appendChild(document.createElement("style"))),s.#a.textContent+=e+"\r\n",s.#e.add(t)}static removeStyle(e){"object"==typeof e&&(e=e.constructor.name),s.#t.has(e)&&(s.#t.get(e).remove(),s.#t.delete(e))}static#a=null;static#e=new Set;static#t=new Map}class r extends a{constructor(e,t={},a=null,c=null,n=!1){super(e,t),s.addStyle(a,c,n)}static make(e,t={},c=null,n=null,r=!1){return s.addStyle(c,n,r),a.make(e,t)}}const o=t.uA,i=t.EL,l=t.t4,d=t.cj,h=t.LV;export{o as Component,i as EL,l as SVG,d as Sheet,h as StyledComponent};
1
+ var e={d:(t,a)=>{for(var n in a)e.o(a,n)&&!e.o(t,n)&&Object.defineProperty(t,n,{enumerable:!0,get:a[n]})},o:(e,t)=>Object.prototype.hasOwnProperty.call(e,t)},t={};e.d(t,{EL:()=>a,LV:()=>o,Uw:()=>s,cj:()=>c,t4:()=>r,uA:()=>n});class a{static context;constructor(e,t={},n=!1){this.$root=a.makeIn(this,e,t,n)}make(e,t={},n=!1){return a.makeIn(this,e,t,n)}makeArray(e,t=!1){return a.makeArrayIn(this,e,t)}config(e,t,n=!1){return a.configIn(this,e,t,n)}makeShadow(e,t={},n=null){return a.makeShadowIn(this,e,t,n)}static make(e,t={},n=!1){return t instanceof Node?t:("svg"==e&&(n=!0),a.config(n?document.createElementNS("http://www.w3.org/2000/svg",e??"svg"):document.createElement(e??"div"),t,n))}static makeIn(e,t,n={},s=!1){return a.make(t,{...n,context:e},s)}static config(e,t,n=!1){if(!(e instanceof Node)||"object"!=typeof t)return e;if(Array.isArray(e))return e.map(e=>a.config(e,t,n));const s="context"in t?a.context=t.context:a.context,r=t=>{t&&(t instanceof Node?e.appendChild(t):t instanceof a?e.appendChild(t.$root):"string"==typeof t?e.insertAdjacentHTML("beforeend",t):"object"==typeof t&&a.make(t.tag,{...t,parent:e},n||"svg"==t.tag))},c=t=>{t&&t.call(s,e,s)};for(const[n,o]of Object.entries(t)){switch(n){case"text":e.textContent=null==o?"":String(o);continue;case"html":e.innerHTML=null==o?"":String(o);continue;case"tag":case"get":case"also":case"parent":case"context":case"onMount":case"onUpdate":case"onDestroy":continue}if(null!=o)switch(n){case"push":o.push(e);break;case"$":case"var":s&&(s["$"+o]=e);break;case"events":for(let t in o)e.addEventListener(t,a=>o[t].call(s,a,e,s));break;case"click":case"input":case"change":case"mousewheel":e.addEventListener(n,t=>o.call(s,t,e,s));break;case"attrs":for(let t in o)e.setAttribute(t,o[t]);break;case"props":for(let t in o)e[t]=o[t];break;case"data":for(let t in o)e.dataset[t]=o[t];break;case"child_r":a.clear(e);case"child":r(o);break;case"children_r":a.clear(e);case"children":for(let e of o)r(e);break;case"style_r":e.style.cssText="";case"style":if("string"==typeof o)e.style.cssText+=o+";";else for(let t in o)o[t]&&(e.style[t]=o[t]);break;case"class_r":e.className="";case"class":{const t=e=>Array.isArray(e)?Object.fromEntries(e.filter(Boolean).map(e=>[e,!0])):"string"==typeof e?t(e.split(/\s+/)):e;for(const[a,n]of Object.entries(t(o)))n?e.classList.add(a):e.classList.remove(a)}break;case"animate":{const{duration:t=300,easing:a="ease",onEnd:n=null,...s}=o;e.style.transition=Object.keys(s).map(e=>`${e} ${t}ms ${a}`).join(", "),requestAnimationFrame(()=>{for(let t in s)e.style[t]=s[t]});const r=()=>{e.removeEventListener("transitionend",r),c(n)};e.addEventListener("transitionend",r)}break;default:e[n]=o}}t.parent&&t.parent.appendChild(e);let o=50;const i=()=>{e._mounted||(e.isConnected?(e._mounted=!0,c(t.onMount)):--o&&requestAnimationFrame(i))};return i(),t.onDestroy&&(e._onDestroy=t.onDestroy.bind(s,e,s)),t.onUpdate&&(e._onUpdate=t.onUpdate.bind(s,e,s)),e._onUpdate&&e._onUpdate(),c(t.also),e}static configIn(e,t,n,s=!1){return a.config(t,{...n,context:e},s)}static clear(e,t=!0){for(;e.firstChild;)t&&a.clear(e.firstChild,!0),a.remove(e.firstChild,!1)}static remove(e,t=!0){t&&a.clear(e),e._onDestroy&&e._onDestroy(),e.remove()}static makeArray(e,t=!1){return e&&Array.isArray(e)?e.map(e=>a.make(e.tag,e,t)):[]}static makeArrayIn(e,t,n){return a.makeArray(t.map(t=>({...t,context:e})),n)}static makeShadow(e,t={},n=null){if(!e||"object"!=typeof t)return null;let s=e instanceof Node?e:document.createElement(e);return s.attachShadow({mode:"open"}),a.config(s.shadowRoot,{context:t.context,children:[{tag:"style",textContent:n??""},t.child??{},...t.children??[]]}),delete t.children,delete t.child,a.config(s,t),s}static makeShadowIn(e,t,n={},s=null){return a.makeShadow(t,{...n,context:e},s)}}const n=a;class s{constructor(e={}){this.data=e,this.subs=new Set}set(e,t){this.data[e]=t,this.subs.forEach(e=>e(this.data))}get(e){return this.data[e]}subscribe(e){return this.subs.add(e),()=>this.subs.delete(e)}}class r{static make=(e,t)=>a.make(e,t,!0);static config=(e,t)=>a.config(e,t,!0);static makeArray=e=>a.makeArray(e,!0);static svg=(e={},t={})=>r._make("svg",e,t);static rect=(e,t,a,n,s,c,o={},i={})=>r._make("rect",{...o,x:e,y:t,width:a,height:n,rx:s,ry:c},i);static circle=(e,t,a,n={},s={})=>r._make("circle",{...n,cx:e,cy:t,r:a},s);static line=(e,t,a,n,s={},c={})=>r._make("line",{...s,x1:e,y1:t,x2:a,y2:n},c);static polyline=(e,t={},a={})=>r._make("polyline",{...t,points:e},a);static polygon=(e,t={},a={})=>r._make("polygon",{...t,points:e},a);static path=(e,t={},a={})=>r._make("path",{...t,d:e},a);static text=(e,t,a,n={},s={})=>r._make("text",{...n,x:t,y:a},{...s,text:e});static _make=(e,t={},a={})=>r.make(e,{attrs:{...t},...a})}class c{static addStyle(e,t,a=!1){if(e&&t&&("object"==typeof t&&(t=t.constructor.name),!c.#e.has(t)&&!c.#t.has(t)))if(a){let a=document.createElement("style");document.head.appendChild(a),a.textContent=e,c.#t.set(t,a)}else c.#a||(c.#a=document.head.appendChild(document.createElement("style"))),c.#a.textContent+=e+"\r\n",c.#e.add(t)}static removeStyle(e){"object"==typeof e&&(e=e.constructor.name),c.#t.has(e)&&(c.#t.get(e).remove(),c.#t.delete(e))}static#a=null;static#e=new Set;static#t=new Map}class o extends a{constructor(e,t={},a=null,n=null,s=!1){super(e,t),c.addStyle(a,n,s)}static make(e,t={},n=null,s=null,r=!1){return c.addStyle(n,s,r),a.make(e,t)}}const i=t.uA,l=t.EL,d=t.t4,m=t.cj,u=t.Uw,h=t.LV;export{i as Component,l as EL,d as SVG,m as Sheet,u as State,h as StyledComponent};
package/README.md CHANGED
@@ -5,43 +5,54 @@
5
5
 
6
6
  ## Дока
7
7
  ### EL
8
- Параметры для конфига:
9
-
10
- - `context` - объект, в контексте которого будут созданы некоторые параметры
11
- - `$` - текст, добавляет созданный элемент в контекст с именем $значение
12
- - `events` - объект с событиями вида `{eventName: handlerFunc}`, привязываются к контексту, если указан
13
- - `click`, `change`, `input`, `mousewheel` - события, указывается обработчик. Короткая форма подключения этих событий
14
- - `also` - функция, будет вызвана с созданным элементом, в контексте, если он указан
15
- - `text` - текст, добавится в textContent, нулевые значения - очистить
16
- - `html` - текст, добавится в innerHTML, нулевые значения - очистить
17
- - `tag` - HTML тег (для child-объектов)
18
- - `push` - массив, добавляет созданный элемент в указанный массив
19
- - `parent` - Node элемент, к которому добавить созданный элемент как child
20
- - `attrs` - объект с аттрибутами для установки через setAttribute
21
- - `props` - объект со свойствами, будут добавлены просто как el[prop] = val
22
- - `data` - объект с датасетами вида `{name: value}`, будут добавлены как аттрибуты data-name = value
23
- - `child`, `child_r` - объект конфига, добавится как ребёнок к созданному элементу. Нужно указать tag, без указания будет div
24
- - `children`, `children_r` - массив объектов конфига, добавятся как дети к созданному элементу. Нужно указать tag, без указания будет div
25
- - `animate` - объект стилей `{styleName: value}`, может содержать параметры анимации duration и easing
8
+ Параметры для конфига `data`:
9
+
10
+ - `context` [объект] - привязывает контекст для других параметров (см ниже), пробрасывается в детей и не сбрасывается между вызовами make/config
11
+ - `$` [текст] - добавляет созданный элемент в context с именем `$значение`
12
+ - `events` [объект] - подключает события `{ eventName: handlerFunc(event, element, context) }`, в this тоже прокидывается context
13
+ - `click`, `change`, `input`, `mousewheel` [функция] - подключает эти события как `handlerFunc(event, element, context)`, в this тоже прокидывается context
14
+ - `also` [функция] - вызывает указанную функцию вида `handlerFunc(element, context)`, в this тоже прокидывается context
15
+ - `text` [текст] - добавится в textContent, nullish значения - очистить
16
+ - `html` [текст] - добавится в innerHTML, nullish значения - очистить
17
+ - `tag` [текст] - HTML тег для child-объектов
18
+ - `push` [массив] - добавляет созданный элемент в указанный массив
19
+ - `parent` [Node] - добавит к нему созданный элемент как child
20
+ - `attrs` [объект] - аттрибуты будут установлены через setAttribute
21
+ - `props` [объект] - свойства будут установлены как el[prop] = val
22
+ - `data` [объект] - датасеты будут добавлены как аттрибуты data-name = value
23
+ - `child`, `child_r` [объект] конфиг, добавится как ребёнок к созданному элементу. Без указания tag будет добавлен div. `_r` - заменить ребёнка
24
+ - `children`, `children_r` [массив] объектов конфига, добавятся как дети к созданному элементу. Без указания tag будет добавлен div. `_r` - заменить всех детей на новых
25
+ - `animate` [объект] - добавить CSS анимаций, может содержать параметры анимации `duration` и `easing`, обработчик окончания анимации `onEnd(element, context)`, в this тоже прокидывается context
26
26
  - `style`, `style_r` - стили. Принимает:
27
- - Строки CSS стилей
28
- - Объект вида `{styleName: value}`
27
+ - [Строка] CSS стилей
28
+ - [Объект] вида `{styleName: value}`
29
29
  - `class`, `class_r` - установка классов в classList, версия с `_r` - заменить классы. Принимает:
30
- - Строки вида `newClass active`
31
- - Массивы вида `['newClass', 'active']`, причём можно по условию: `['newClass', isActive && 'active']`
32
- - Объекты вида `{newClass: true, active: false}` - true значение добавляет класс
33
- - `onConfig` - функция, вызовется при настройке через функцию config
34
- - `onMount` - функция, вызовется при присоединении к DOM
30
+ - [Строку] вида `newClass active foo bar`
31
+ - [Массив] вида `['newClass', 'active']`, причём можно по условию: `['newClass', isActive && 'active']`
32
+ - [Объект] вида `{newClass: true, active: false}` - true значение добавляет класс, false не добавляет
33
+ - `onUpdate` [функция] вида `handlerFunc(element, context)`, вызовется при настройке через функцию config, в this тоже прокидывается context
34
+ - `onMount` [функция] вида `handlerFunc(element, context)`, вызовется при присоединении к DOM, в this тоже прокидывается context
35
+ - `onDestroy` [функция] вида `handlerFunc(element, context)`, вызовется при удалении через EL.remove(el) или EL.clear(el), в this тоже прокидывается context
35
36
  - Другие значения будут добавлены как свойства
36
37
 
38
+ #### Класс
37
39
  ```js
38
40
  /**
39
- * Создать компонент и поместить его в переменную $root
41
+ * Создать компонент и поместить его в переменную this.$root
40
42
  * @param {string} tag html tag элемента
41
43
  * @param {object} data параметры
42
44
  */
43
45
  EL(tag, data = {}, svg = false);
44
46
 
47
+ // аналоги с авто-this контекстом для вызова внутри класса
48
+ make(tag, data = {}, svg = false);
49
+ makeArray(arr, svg = false);
50
+ config(el, data, svg = false);
51
+ makeShadow(host, data = {}, sheet = null);
52
+ ```
53
+
54
+ #### Static
55
+ ```js
45
56
  /**
46
57
  * Создать компонент
47
58
  * @param {string} tag html tag элемента
@@ -49,15 +60,7 @@ EL(tag, data = {}, svg = false);
49
60
  * @returns {Node}
50
61
  */
51
62
  EL.make(tag, data = {});
52
-
53
- /**
54
- * Создать теневой компонент от указанного tag, дети подключатся к нему в shadowRoot
55
- * @param {string|Node} host html tag теневого элемента или Node
56
- * @param {object} data параметры внешнего элемента
57
- * @param {string} sheet css стили
58
- * @returns {Node} host
59
- */
60
- EL.makeShadow(host, data = {}, sheet = null);
63
+ EL.makeIn(ctx, tag, data = {}, svg = false);
61
64
 
62
65
  /**
63
66
  * Настроить элемент
@@ -66,6 +69,7 @@ EL.makeShadow(host, data = {}, sheet = null);
66
69
  * @returns {Node}
67
70
  */
68
71
  EL.config(el, data);
72
+ EL.configIn(ctx, el, data, svg = false);
69
73
 
70
74
  /**
71
75
  * Создать массив компонентов из массива объектов конфигурации
@@ -73,6 +77,29 @@ EL.config(el, data);
73
77
  * @returns {array} of Elements
74
78
  */
75
79
  EL.makeArray(arr);
80
+ EL.makeArrayIn(ctx, arr, svg);
81
+
82
+ /**
83
+ * Создать теневой компонент от указанного tag, дети подключатся к нему в shadowRoot
84
+ * @param {string|Node} host html tag теневого элемента или Node
85
+ * @param {object} data параметры внешнего элемента
86
+ * @param {string} sheet css стили
87
+ * @returns {Node} host
88
+ */
89
+ EL.makeShadow(host, data = {}, sheet = null);
90
+ EL.makeShadowIn(ctx, host, data = {}, sheet = null);
91
+
92
+ /**
93
+ * Удалить все child ноды
94
+ * @param {HTMLElement} el
95
+ */
96
+ EL.clear(el, recursive = true);
97
+
98
+ /**
99
+ * Удалить элемент
100
+ * @param {HTMLElement} el
101
+ */
102
+ EL.remove(el, recursive = true);
76
103
  ```
77
104
 
78
105
  ### SVG
@@ -304,7 +331,7 @@ let d = EL.make('div', {
304
331
  also: el => state.subscribe(d => el.textContent = d.count),
305
332
  style: { width: '100px', height: '50px', background: 'red' },
306
333
  animate: { width: '200px', background: 'blue', duration: 500 },
307
- onConfig: el => console.log('update'),
334
+ onUpdate: el => console.log('update'),
308
335
  onMount: el => console.log('mount'),
309
336
  });
310
337
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexgyver/component",
3
- "version": "1.4.1",
3
+ "version": "1.5.0",
4
4
  "description": "Simple HTML&SVG element builder",
5
5
  "main": "./Component.js",
6
6
  "module": "./Component.js",
@@ -15,7 +15,7 @@
15
15
  "author": "AlexGyver <alex@alexgyver.ru>",
16
16
  "license": "MIT",
17
17
  "devDependencies": {
18
- "webpack": "^5.101.3",
18
+ "webpack": "^5.105.0",
19
19
  "webpack-cli": "^6.0.1"
20
20
  }
21
21
  }
package/test/script.js CHANGED
@@ -1,4 +1,5 @@
1
- import { EL, Sheet, StyledComponent } from "https://gyverlibs.github.io/EL.js/EL.min.js";
1
+ // import { EL, Sheet, StyledComponent } from "https://gyverlibs.github.io/Component.js/Component.min.js";
2
+ import { EL, Sheet, StyledComponent } from "../Component.js";
2
3
 
3
4
  // кнопка наследует, стили добавляются отдельно
4
5
  class Button extends EL {
@@ -105,6 +106,29 @@ class ShadowComponent {
105
106
 
106
107
  document.addEventListener('kek', () => console.log('kek!'));
107
108
 
109
+ let context = { ctx: 'ctx' };
110
+
111
+ let d = EL.make('div', {
112
+ context: context,
113
+ parent: document.body,
114
+ text: 'test',
115
+ style: { width: '100px', height: '50px', background: 'red' },
116
+ animate: { width: '200px', background: 'blue', duration: 500, onEnd: function (el) { console.log('anim', this, el) } },
117
+ events: {
118
+ mouseleave: function (e, el) { console.log('leave', this, e, el) },
119
+ },
120
+ click: (e, el, ctx) => console.log('click', this, e, el, ctx),
121
+ also: function (el) { console.log('also', this, el) },
122
+ onUpdate: (el, ctx) => console.log('update', this, el, ctx),
123
+ onDestroy: (el, ctx) => console.log('destroy', this, el, ctx),
124
+ // onMount: el => console.log('mount', this),
125
+ onMount: function (el) { console.log('mount', this, el) },
126
+ });
127
+
128
+ // setTimeout(() => { document.body.appendChild(d) }, 2000);
129
+ setTimeout(() => { EL.config(d, { text: 123 }) }, 2000);
130
+ setTimeout(() => { EL.remove(d) }, 4000);
131
+
108
132
  document.addEventListener("DOMContentLoaded", () => {
109
133
  EL.make('h1', {
110
134
  text: 'Hello!',