@alexgyver/component 1.3.10 → 1.4.1

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
@@ -3,7 +3,7 @@ export class EL {
3
3
  static context;
4
4
 
5
5
  /**
6
- * Создать компонент и поместить его в переменную $root
6
+ * Создать элемент и поместить его в переменную $root
7
7
  * @param {string} tag html tag элемента
8
8
  * @param {object} data параметры
9
9
  * @param {Boolean} svg SVG
@@ -14,35 +14,22 @@ export class EL {
14
14
  }
15
15
 
16
16
  /**
17
- * Создать компонент
17
+ * Создать элемент
18
18
  * @param {string} tag html tag элемента
19
19
  * @param {object} data параметры
20
20
  * @param {Boolean} svg SVG
21
21
  * @returns {Node}
22
- * @params
23
- * tag {string} - тег html элемента. Если 'svg' - включится режим SVG на детей
24
- * context {object} - контекст для параметра 'var' и вызовов, прокидывается в детей. Если указан явно как null - прерывает проброс
25
- * parent - {Element} добавляет компонент к указанному элементу
26
- * text {string} - добавить в textContent
27
- * html {string} - добавить в innerHTML
28
- * class {string | Array} - добавить в className
29
- * style {string | object} - объект в виде { padding: '0px', ... } или строка css стилей
30
- * push {array} - добавить к указанному массиву
31
- * var | $ {string} - создаёт переменную $имя в указанном контексте
32
- * events {object} - добавляет addEventListener'ы {event: e => {}}
33
- * children/children_r - массив {DOM, EL, object, html string}. _r - заменить имеющиеся. Без тега tag будет div
34
- * child/child_r - {DOM, EL, object, html string}. _r - заменить имеющиеся. Без тега tag будет div
35
- * attrs {object} - добавить аттрибуты (через setAttribute)
36
- * props {object} - добавить свойства (как el[prop])
37
- * also {function} - вызвать с текущим компонентом: also(el) { console.log(el); }
38
- * всё остальное будет добавлено как property
39
22
  */
40
23
  static make(tag, data = {}, svg = false) {
41
- if (!tag || typeof data !== 'object') return null;
42
24
  if (data instanceof Node) return data;
25
+ if (!tag) tag = 'div';
43
26
  if (tag == 'svg') svg = true;
44
27
  return EL.config(svg ? document.createElementNS("http://www.w3.org/2000/svg", tag) : document.createElement(tag), data, svg);
45
28
  }
29
+ static makeIn(ctx, tag, data = {}, svg = false) {
30
+ data.context = ctx;
31
+ return EL.make(tag, data, svg);
32
+ }
46
33
 
47
34
  /**
48
35
  * Настроить элемент
@@ -56,67 +43,155 @@ export class EL {
56
43
  el.forEach(e => EL.config(e, data, svg));
57
44
  return null;
58
45
  }
59
- if (!(el instanceof Node) || (typeof data !== 'object')) return el;
46
+ if (!(el instanceof Node) || (typeof data !== 'object')) {
47
+ return el;
48
+ }
60
49
 
61
50
  let ctx = data.context;
62
- EL.context = (ctx === null) ? null : (ctx ? ctx : EL.context);
63
- ctx = EL.context;
64
-
65
- let addChild = (obj) => {
66
- if (!obj) return;
67
- if (obj instanceof Node) el.appendChild(obj);
68
- else if (obj instanceof EL) el.appendChild(obj.$root);
69
- else if (typeof obj === 'string') el.innerHTML += obj;
70
- else if (typeof obj === 'object') {
71
- let cmp = EL.make(obj.tag ?? 'div', obj, svg || obj.tag == 'svg');
72
- if (cmp) el.appendChild(cmp);
51
+ if (ctx === undefined) ctx = EL.context;
52
+ else EL.context = ctx;
53
+
54
+ const addChild = (obj) => {
55
+ if (obj) {
56
+ if (obj instanceof Node) el.appendChild(obj);
57
+ else if (obj instanceof EL) el.appendChild(obj.$root);
58
+ 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
+ }
73
63
  }
74
64
  }
75
65
 
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
+ }
79
+
76
80
  for (const [key, val] of Object.entries(data)) {
77
81
  switch (key) {
78
- case 'text': el.textContent = (val == null) ? '' : (val + ''); continue;
79
- case 'html': el.innerHTML = (val == null) ? '' : (val + ''); continue;
82
+ case 'text': el.textContent = (val == null) ? '' : String(val); continue; // == - null + undef
83
+ case 'html': el.innerHTML = (val == null) ? '' : String(val); continue;
80
84
  case 'tag':
81
85
  case 'context':
82
86
  case 'get':
83
87
  case 'also':
88
+ case 'onConfig':
89
+ case 'onMount':
84
90
  continue;
85
91
  }
86
- if (!val) continue;
92
+
93
+ if (val === undefined || val === null) continue;
94
+
87
95
  switch (key) {
88
- case 'class': (Array.isArray(val) ? val : val.split(' ')).map(c => c && el.classList.add(c)); break;
89
- case 'push': val.push(el); break;
90
- case '$': case 'var': if (ctx) ctx['$' + val] = el; break;
91
- case 'events': for (let ev in val) el.addEventListener(ev, val[ev].bind(ctx)); break;
92
- case 'parent': val.appendChild(el); break;
93
- case 'attrs': for (let attr in val) el.setAttribute(attr, val[attr]); break;
94
- case 'props': for (let prop in val) el[prop] = val[prop]; break;
95
- case 'child_r': EL.clear(el); // fall
96
- case 'child': addChild(val); break;
97
- case 'children_r': EL.clear(el); // fall
98
- case 'children': for (let obj of val) addChild(obj); break;
96
+ case 'push':
97
+ val.push(el);
98
+ break;
99
+
100
+ case '$':
101
+ case 'var':
102
+ if (ctx) ctx['$' + val] = el;
103
+ break;
104
+
105
+ case 'events':
106
+ for (let ev in val) el.addEventListener(ev, ctx ? val[ev].bind(ctx) : val[ev]);
107
+ break;
108
+
109
+ case 'click':
110
+ case 'change':
111
+ case 'input':
112
+ case 'mousewheel':
113
+ el.addEventListener(key, ctx ? val.bind(ctx) : val);
114
+ break;
115
+
116
+ case 'parent':
117
+ val.appendChild(el);
118
+ break;
119
+
120
+ case 'attrs':
121
+ for (let attr in val) el.setAttribute(attr, val[attr]);
122
+ break;
123
+
124
+ case 'props':
125
+ for (let prop in val) el[prop] = val[prop];
126
+ break;
127
+
128
+ case 'data':
129
+ for (let key in val) el.dataset[key] = val[key];
130
+ break;
131
+
132
+ case 'child_r':
133
+ EL.clear(el);
134
+ // fall
135
+ case 'child':
136
+ addChild(val);
137
+ break;
138
+
139
+ case 'children_r':
140
+ EL.clear(el);
141
+ // fall
142
+ case 'children':
143
+ for (let obj of val) addChild(obj);
144
+ break;
145
+
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
+ case 'style_r':
153
+ el.style.cssText = '';
154
+ // fall
99
155
  case 'style':
100
- if (typeof val === 'string') el.style.cssText += val + ';';
101
- else for (let st in val) if (val[st]) el.style[st] = val[st];
156
+ if (typeof val === 'string') {
157
+ el.style.cssText += val + ';';
158
+ } else for (let st in val) {
159
+ if (val[st]) el.style[st] = val[st];
160
+ }
161
+ break;
162
+
163
+ case 'class_r':
164
+ el.className = '';
165
+ // fall
166
+ case 'class':
167
+ getClasses(val).forEach(c => c && el.classList.add(c));
168
+ break;
169
+
170
+ default: el[key] = val;
102
171
  break;
103
- default: el[key] = val; break;
104
172
  }
105
173
  }
106
- if (data.also && ctx) data.also.call(ctx, el);
174
+
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);
107
178
  return el;
108
179
  }
180
+ static configIn(ctx, el, data, svg = false) {
181
+ data.context = ctx;
182
+ return EL.config(el, data, svg);
183
+ }
109
184
 
110
185
  /**
111
186
  * Удалить все child ноды
112
187
  * @param {HTMLElement} el
113
188
  */
114
189
  static clear(el) {
115
- while (el.firstChild) el.removeChild(el.lastChild);
190
+ while (el.firstChild) el.removeChild(el.firstChild);
116
191
  }
117
192
 
118
193
  /**
119
- * Создать массив компонентов из массива объектов конфигурации
194
+ * Создать массив элементов из массива объектов конфигурации
120
195
  * @param {array} arr массив объектов конфигурации
121
196
  * @param {Boolean} svg SVG
122
197
  * @returns {array} of Elements
@@ -127,7 +202,7 @@ export class EL {
127
202
  }
128
203
 
129
204
  /**
130
- * Создать теневой компонент от указанного tag, дети подключатся к нему в shadowRoot
205
+ * Создать теневой элемент от указанного tag, дети подключатся к нему в shadowRoot
131
206
  * @param {string|Node} host html tag теневого элемента или Node
132
207
  * @param {object} data параметры внешнего элемента
133
208
  * @param {string} sheet css стили
@@ -160,6 +235,25 @@ export class EL {
160
235
  // legacy
161
236
  export const Component = EL;
162
237
 
238
+ //#region State
239
+ export class State {
240
+ constructor(init = {}) {
241
+ this.data = init;
242
+ this.subs = new Set();
243
+ }
244
+ set(key, value) {
245
+ this.data[key] = value;
246
+ this.subs.forEach(fn => fn(this.data));
247
+ }
248
+ get(key) {
249
+ return this.data[key];
250
+ }
251
+ subscribe(fn) {
252
+ this.subs.add(fn);
253
+ return () => this.subs.delete(fn);
254
+ }
255
+ }
256
+
163
257
  //#region SVG
164
258
  export class SVG {
165
259
  static make = (tag, data) => EL.make(tag, data, true);
@@ -224,7 +318,7 @@ export class Sheet {
224
318
  //#region StyledComponent
225
319
  export class StyledComponent extends EL {
226
320
  /**
227
- * Создать компонент и поместить его в переменную $root
321
+ * Создать элемент и поместить его в переменную $root
228
322
  * @param {string} tag html tag элемента
229
323
  * @param {object} data параметры
230
324
  * @param {string|array} style стили в виде css строки
@@ -237,7 +331,7 @@ export class StyledComponent extends EL {
237
331
  }
238
332
 
239
333
  /**
240
- * Создать компонент
334
+ * Создать элемент
241
335
  * @param {string} tag html tag элемента
242
336
  * @param {object} data параметры
243
337
  * @param {string|array} style стили в виде css строки
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:()=>o,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 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,o]of Object.entries(t)){switch(c){case"text":e.textContent=null==o?"":o+"";continue;case"html":e.innerHTML=null==o?"":o+"";continue;case"tag":case"context":case"get":case"also":continue}if(o)switch(c){case"class":(Array.isArray(o)?o:o.split(" ")).map(t=>t&&e.classList.add(t));break;case"push":o.push(e);break;case"$":case"var":n&&(n["$"+o]=e);break;case"events":for(let t in o)e.addEventListener(t,o[t].bind(n));break;case"parent":o.appendChild(e);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"child_r":a.clear(e);case"child":s(o);break;case"children_r":a.clear(e);case"children":for(let e of o)s(e);break;case"style":if("string"==typeof o)e.style.cssText+=o+";";else for(let t in o)o[t]&&(e.style[t]=o[t]);break;default:e[c]=o}}return t.also&&n&&t.also.call(n,e),e}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,o,r={},l={})=>n._make("rect",{...r,x:e,y:t,width:a,height:c,rx:s,ry:o},l);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={},o={})=>n._make("line",{...s,x1:e,y1:t,x2:a,y2:c},o);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 o 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,o=!1){return s.addStyle(c,n,o),a.make(e,t)}}const r=t.uA,l=t.EL,i=t.t4,d=t.cj,h=t.LV;export{r as Component,l as EL,i as SVG,d as Sheet,h as StyledComponent};
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};
package/README.md CHANGED
@@ -4,7 +4,36 @@
4
4
  > npm i @alexgyver/component
5
5
 
6
6
  ## Дока
7
- ### Component
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
26
+ - `style`, `style_r` - стили. Принимает:
27
+ - Строки CSS стилей
28
+ - Объект вида `{styleName: value}`
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
35
+ - Другие значения будут добавлены как свойства
36
+
8
37
  ```js
9
38
  /**
10
39
  * Создать компонент и поместить его в переменную $root
@@ -18,22 +47,6 @@ EL(tag, data = {}, svg = false);
18
47
  * @param {string} tag html tag элемента
19
48
  * @param {object} data параметры
20
49
  * @returns {Node}
21
- * tag {string} - тег html элемента. Если 'svg' - включится режим SVG на детей
22
- * context {object} - контекст для параметра 'var' и вызовов, прокидывается в детей. Если указан явно как null - прерывает проброс
23
- * parent - {Element} добавляет компонент к указанному элементу
24
- * text {string} - добавить в textContent
25
- * html {string} - добавить в innerHTML
26
- * class {string | Array} - добавить в className
27
- * style {string | object} - объект в виде { padding: '0px', ... } или строка css стилей
28
- * push {array} - добавить к указанному массиву
29
- * var | $ {string} - создаёт переменную $имя в указанном контексте
30
- * events {object} - добавляет addEventListener'ы {event: e => {}}
31
- * children/children_r - массив {DOM, EL, object, html string}. _r - заменить имеющиеся. Без тега tag будет div
32
- * child/child_r - {DOM, EL, object, html string}. _r - заменить имеющиеся. Без тега tag будет div
33
- * attrs {object} - добавить аттрибуты (через setAttribute)
34
- * props {object} - добавить свойства (как el[prop])
35
- * also {function} - вызвать с текущим компонентом: also(el) { console.log(el); }
36
- * всё остальное будет добавлено как property
37
50
  */
38
51
  EL.make(tag, data = {});
39
52
 
@@ -118,8 +131,9 @@ StyledComponent(tag, data = {}, style = null, id = null, ext = false);
118
131
  StyledComponent.make(tag, data = {}, style = null, id = null, ext = false);
119
132
  ```
120
133
 
121
- ## Пример
134
+ ## Примеры
122
135
  Создаст контейнер с двумя вложенными блоками текста и прикрепит к body
136
+
123
137
  ```js
124
138
  EL.make('div', {
125
139
  parent: document.body,
@@ -143,6 +157,46 @@ EL.make('div', {
143
157
  });
144
158
  ```
145
159
 
160
+ Простой элемент с текстом и классами
161
+
162
+ ```js
163
+ const box = new EL('div', {
164
+ text: 'Привет, мир!',
165
+ class: ['box', 'highlight'],
166
+ style: { padding: '10px', color: 'white', backgroundColor: 'blue' },
167
+ click() { console.log('Box кликнут!'); },
168
+ $: 'myBox' // создаёт ctx.$myBox
169
+ });
170
+
171
+ document.body.appendChild(box.$root);
172
+ console.log(box.$root); // сам DOM-элемент
173
+ console.log(EL.context.$myBox); // доступ через контекст
174
+ ```
175
+
176
+ Полная замена классов и стилей
177
+
178
+ ```js
179
+ EL.config(someElement, {
180
+ text: 'Обновлённый блок',
181
+ class_r: ['newClass', 'active'], // полностью заменяет классы
182
+ style_r: { color: 'red', fontWeight: 'bold' } // сброс и новые стили
183
+ });
184
+ ```
185
+
186
+ Вложенные дети и массив children
187
+
188
+ ```cpp
189
+ EL.make('div', {
190
+ parent: document.body,
191
+ class: 'parent',
192
+ children: [
193
+ { tag: 'p', text: 'Первый ребёнок', class: 'child' },
194
+ { tag: 'p', text: 'Второй ребёнок', class: ['child', 'second'] },
195
+ 'Просто текстовый узел'
196
+ ]
197
+ });
198
+ ```
199
+
146
200
  Гораздо интереснее использовать в классе и передавать контекст. Параметр `$` создаст переменную с элементом с указанным именем + префикс `$`:
147
201
 
148
202
  ```js
@@ -166,6 +220,25 @@ let btn = new Button('kek');
166
220
  btn.$button; // элемент кнопки
167
221
  ```
168
222
 
223
+ Использование контекста для $ и событий
224
+
225
+ ```js
226
+ class MyComponent extends EL {
227
+ constructor() {
228
+ super('div', {
229
+ class: 'comp',
230
+ $: 'root',
231
+ children: [
232
+ { tag: 'button', text: 'Нажми меня', click() { console.log(this.$root); } }
233
+ ]
234
+ });
235
+ }
236
+ }
237
+
238
+ const comp = new MyComponent();
239
+ document.body.appendChild(comp.$root);
240
+ ```
241
+
169
242
  Некоторые трюки
170
243
 
171
244
  ```js
@@ -194,3 +267,47 @@ EL.make('div', {
194
267
  class: ['some', 'class', foo && 'plus_me'], // добавить plus_me если foo - true
195
268
  });
196
269
  ```
270
+
271
+
272
+ Создание SVG
273
+
274
+ ```js
275
+ const svg = SVG.svg({ width: 200, height: 200 }, {
276
+ children: [
277
+ SVG.rect(10, 10, 50, 50, 5, 5, { fill: 'green' }),
278
+ SVG.circle(100, 100, 40, { fill: 'red' }),
279
+ SVG.line(0, 0, 200, 200, { stroke: 'blue', 'stroke-width': 2 })
280
+ ]
281
+ });
282
+ ```
283
+
284
+ Shadow DOM со стилями
285
+
286
+ ```js
287
+ const shadowHost = EL.makeShadow('div', {
288
+ child: { tag: 'p', text: 'Текст внутри Shadow DOM', class: 'shadow-text' }
289
+ }, `
290
+ .shadow-text { color: purple; font-weight: bold; }
291
+ `);
292
+
293
+ document.body.appendChild(shadowHost);
294
+ ```
295
+
296
+
297
+ Прочее
298
+
299
+ ```js
300
+ const state = new State({ count: 0 });
301
+
302
+ let d = EL.make('div', {
303
+ text: state.get('count'),
304
+ also: el => state.subscribe(d => el.textContent = d.count),
305
+ style: { width: '100px', height: '50px', background: 'red' },
306
+ animate: { width: '200px', background: 'blue', duration: 500 },
307
+ onConfig: el => console.log('update'),
308
+ onMount: el => console.log('mount'),
309
+ });
310
+
311
+ setInterval(() => state.set('count', state.get('count') + 1), 1000);
312
+ setTimeout(() => { document.body.appendChild(d) }, 2000);
313
+ ```
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@alexgyver/component",
3
- "version": "1.3.10",
3
+ "version": "1.4.1",
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.98.0",
18
+ "webpack": "^5.101.3",
19
19
  "webpack-cli": "^6.0.1"
20
20
  }
21
21
  }