@alexgyver/component 1.0.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.
Files changed (2) hide show
  1. package/component.js +116 -0
  2. package/package.json +20 -0
package/component.js ADDED
@@ -0,0 +1,116 @@
1
+ class Sheet {
2
+ /**
3
+ * @abstract Добавить стиль с уникальным id в head. ext - стиль можно будет удалить по id
4
+ */
5
+ static addStyle(style, id, ext = false) {
6
+ if (!style || !id) return;
7
+ if (typeof id === 'object') id = id.constructor.name;
8
+
9
+ if (!Sheet.#internal.has(id) && !Sheet.#external.has(id)) {
10
+ if (typeof style === 'object') {
11
+ let str = '';
12
+ let f = 0;
13
+ for (const v of style) {
14
+ if (f = !f) {
15
+ str += v;
16
+ } else {
17
+ str += '{';
18
+ for (const rule of v) str += rule + ';';
19
+ str += '}';
20
+ }
21
+ }
22
+ style = str;
23
+ }
24
+
25
+ if (ext) {
26
+ let sheet = document.createElement('style');
27
+ document.head.appendChild(sheet);
28
+ sheet.sheet.insertRule(style);
29
+ Sheet.#external.set(id, sheet);
30
+ } else {
31
+ if (!Sheet.#sheet) Sheet.#sheet = document.head.appendChild(document.createElement('style')).sheet;
32
+ Sheet.#sheet.insertRule(style);
33
+ Sheet.#internal.add(id);
34
+ }
35
+ }
36
+ }
37
+
38
+ /**
39
+ * @abstract Удалить ext стиль по его id
40
+ */
41
+ static removeStyle(id) {
42
+ if (Sheet.#external.has(id)) {
43
+ Sheet.#external.get(id).remove();
44
+ Sheet.#external.delete(id);
45
+ }
46
+ }
47
+
48
+ static #sheet;
49
+ static #internal = new Set();
50
+ static #external = new Map();
51
+ }
52
+
53
+ class Component {
54
+ /**
55
+ * @abstract Создать компонент и поместить его в переменную $root
56
+ * @param {string} tag html tag элемента
57
+ * @param {object} data параметры
58
+ * @param {string|array} style стили в виде css строки или [ 'class', ['color: red', 'padding: 0'], ... ]
59
+ * @param {string|this} id уникальный id стиля
60
+ * @param {boolean} ext внешний стиль - может быть удалён по id
61
+ */
62
+ constructor(tag, data = {}, style = null, id = null, ext = false) {
63
+ data.context = this;
64
+ this.$root = Component.make(tag, data, style, id, ext);
65
+ }
66
+
67
+ /*
68
+ context - контекст для параметра 'make' и вызовов 'also'
69
+ also - вызвать с текущим компонентом: { ... , also(el) { console.log('123'); }, }
70
+ makevar - создаёт переменную $name в указанном контексте
71
+ style - object: { padding: '0px', ... }
72
+ events - object
73
+ children - DOM, Component или параметры как object
74
+ */
75
+ /**
76
+ * @abstract Создать компонент и поместить его в переменную $root
77
+ * @param {string} tag html tag элемента
78
+ * @param {object} data параметры
79
+ * @param {string|array} style стили в виде css строки или [ 'class', ['color: red', 'padding: 0'], ... ]
80
+ * @param {string|this} id уникальный id стиля
81
+ * @param {boolean} ext внешний стиль - может быть удалён по id
82
+ */
83
+ static make(tag, data = {}, style = null, id = null, ext = false) {
84
+ Sheet.addStyle(style, id, ext);
85
+ if (!tag || typeof data !== 'object') return null;
86
+
87
+ const context = data.context;
88
+ const $el = document.createElement(tag);
89
+
90
+ for (const [key, value] of Object.entries(data)) {
91
+ switch (key) {
92
+ case 'context': case 'tag': continue;
93
+ case 'text': $el.textContent = value; break;
94
+ case 'html': $el.innerHTML = value; break;
95
+ case 'class': $el.className = value; break;
96
+ case 'also': if (context) value.call(context, $el); break;
97
+ case 'makevar': if (context) context['$' + value] = $el; break;
98
+ case 'style': for (const [skey, sval] of Object.entries(value)) $el.style[skey] = sval; break;
99
+ case 'events': for (const [ev, handler] of Object.entries(value)) $el.addEventListener(ev, handler.bind(context)); break;
100
+ case 'children':
101
+ for (const obj of value) {
102
+ if (obj instanceof Element || obj instanceof HTMLDocument) $el.appendChild(obj);
103
+ else if (obj instanceof Component) $el.appendChild(obj.$root);
104
+ else if (typeof obj === 'object') {
105
+ if (!obj.context) obj.context = context;
106
+ let comp = Component.make(obj.tag, obj);
107
+ if (comp) $el.appendChild(comp);
108
+ }
109
+ }
110
+ break;
111
+ default: $el[key] = value; break;
112
+ }
113
+ }
114
+ return $el;
115
+ }
116
+ }
package/package.json ADDED
@@ -0,0 +1,20 @@
1
+ {
2
+ "name": "@alexgyver/component",
3
+ "version": "1.0.0",
4
+ "description": "Simple HTML element builder",
5
+ "main": "component.js",
6
+ "type": "module",
7
+ "scripts": {
8
+ "test": "echo \"Error: no test specified\" && exit 1"
9
+ },
10
+ "repository": {
11
+ "type": "git",
12
+ "url": "git+https://github.com/GyverLibs/Component.js.git"
13
+ },
14
+ "author": "AlexGyver <alex@alexgyver.ru>",
15
+ "license": "MIT",
16
+ "bugs": {
17
+ "url": "https://github.com/GyverLibs/Component.js/issues"
18
+ },
19
+ "homepage": "https://github.com/GyverLibs/Component.js#readme"
20
+ }