@twobirds/microcomponents 0.0.4 → 0.0.6
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/MicroComponentProposal_draft.md +1 -1
- package/README.md +44 -26
- package/dist/microcomponents.d.ts +218 -2
- package/dist/microcomponents.d.ts.map +1 -1
- package/dist/microcomponents.js +237 -43
- package/dist/microcomponents.min.js +7 -6
- package/dist/microcomponents.ts +391 -201
- package/jsdoc.conf.json +19 -0
- package/microcomponents_usage.md +56 -24
- package/package.json +13 -2
- package/public/docs/assets/highlight.css +14 -14
- package/public/docs/assets/search.js +1 -1
- package/public/docs/classes/microcomponents.MC.html +179 -41
- package/public/docs/classes/microcomponents_es3.MC.html +12 -12
- package/public/docs/functions/microcomponents_es3.__isEmpty.html +1 -1
- package/public/docs/index.html +18 -16
- package/public/docs/interfaces/microcomponents.HTMLElementMc.html +2 -2
- package/public/docs/modules/microcomponents.html +1 -1
- package/public/jsdoc/es3/files.html +216 -0
- package/public/jsdoc/es3/index.html +210 -0
- package/public/jsdoc/es3/symbols/_global_.html +368 -0
- package/public/jsdoc/es3/symbols/src/build_microcomponents.es3.js.html +104 -0
- package/public/jsdoc/es5+/files.html +218 -0
- package/public/jsdoc/es5+/index.html +218 -0
- package/public/jsdoc/es5+/symbols/MC.html +621 -0
- package/public/jsdoc/es5+/symbols/_global_.html +720 -0
- package/public/jsdoc/es5+/symbols/microcomponents.MC.html +323 -0
- package/public/jsdoc/es5+/symbols/src/build_microcomponents.js.html +375 -0
- package/src/microcomponents.ts +391 -201
package/dist/microcomponents.js
CHANGED
|
@@ -1,18 +1,141 @@
|
|
|
1
1
|
'use strict';
|
|
2
|
-
|
|
2
|
+
/**
|
|
3
|
+
* @module microcomponenents
|
|
4
|
+
*/
|
|
5
|
+
/**
|
|
6
|
+
* A static flag to enable or disable debugging mode.
|
|
7
|
+
* @name debug
|
|
8
|
+
* @memberOf MC
|
|
9
|
+
* @static
|
|
10
|
+
* @type {boolean} A static flag to enable or disable debugging mode.
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Retrieves all top-level microcomponents from a target HTMLElement.
|
|
14
|
+
* @name siblings
|
|
15
|
+
* @memberOf MC
|
|
16
|
+
* @static
|
|
17
|
+
* @function
|
|
18
|
+
* @param {HTMLElement} target - The target DOM element.
|
|
19
|
+
* @param {string} [search] - The key of the specific microcomponent to find.
|
|
20
|
+
* @returns {Array<any>} An array of microcomponents or an empty array if none found.
|
|
21
|
+
* @example
|
|
22
|
+
* const siblings = MC.siblings(
|
|
23
|
+
* document.getElementById('myElement'),
|
|
24
|
+
* 'myComponent'
|
|
25
|
+
* );
|
|
26
|
+
*/
|
|
27
|
+
/**
|
|
28
|
+
* Adds a top level microcomponent to a target DOM node.
|
|
29
|
+
* @name add
|
|
30
|
+
* @memberOf MC
|
|
31
|
+
* @static
|
|
32
|
+
* @function
|
|
33
|
+
* @param {HTMLElement} target - The target DOM element.
|
|
34
|
+
* @param {string} key - The key to identify the microcomponent.
|
|
35
|
+
* @param {any} [element={}] - The microcomponent to add.
|
|
36
|
+
* @returns {any} The added microcomponent.
|
|
37
|
+
* @example
|
|
38
|
+
* const component = MC.add(
|
|
39
|
+
* document.getElementById('myElement'),
|
|
40
|
+
* 'myComponent',
|
|
41
|
+
* {}
|
|
42
|
+
* );
|
|
43
|
+
*/
|
|
44
|
+
/**
|
|
45
|
+
* Removes a top level microcomponent from the target DOM node.
|
|
46
|
+
* @name remove
|
|
47
|
+
* @memberOf MC
|
|
48
|
+
* @static
|
|
49
|
+
* @function
|
|
50
|
+
* @param {HTMLElement} target - The target DOM element.
|
|
51
|
+
* @param {string} key - The key identifying the microcomponent.
|
|
52
|
+
* @example
|
|
53
|
+
* MC.remove(
|
|
54
|
+
* document.getElementById('myElement'),
|
|
55
|
+
* 'myComponent'
|
|
56
|
+
* );
|
|
57
|
+
*/
|
|
58
|
+
/**
|
|
59
|
+
* Manages microcomponents (MCs) attached to DOM elements, allowing for the
|
|
60
|
+
* addition, removal, and traversal of microcomponents across siblings, parents,
|
|
61
|
+
* children, and descendants.
|
|
62
|
+
*
|
|
63
|
+
* This class provides an API for interacting with microcomponents on DOM elements.
|
|
64
|
+
* Public microcomponents are stored on the `_mc` attribute of the DOM element, while
|
|
65
|
+
* private microcomponents are managed internally.
|
|
66
|
+
*
|
|
67
|
+
* @example
|
|
68
|
+
* ```javascript
|
|
69
|
+
*
|
|
70
|
+
* // create the micro component class
|
|
71
|
+
* class MyMC extends MC{
|
|
72
|
+
*
|
|
73
|
+
* constructor( target ){
|
|
74
|
+
* super( target );
|
|
75
|
+
* this.target = target;
|
|
76
|
+
* }
|
|
77
|
+
* }
|
|
78
|
+
*
|
|
79
|
+
* const element = document.querySelector('div')
|
|
80
|
+
*
|
|
81
|
+
* // Add the top level microcomponent to the target element
|
|
82
|
+
* let mcc = MC.add(
|
|
83
|
+
* element,
|
|
84
|
+
* 'myMC',
|
|
85
|
+
* new MyMC( element )
|
|
86
|
+
* );
|
|
87
|
+
*
|
|
88
|
+
* // Add an inner (private) microcomponent to mcc
|
|
89
|
+
* let mcc.add(
|
|
90
|
+
* 'myInnerMC',
|
|
91
|
+
* new MyMC( element )
|
|
92
|
+
* );
|
|
93
|
+
*
|
|
94
|
+
* console.log( element._mc );
|
|
95
|
+
* // { 'myMC': { target: (element) } }
|
|
96
|
+
*
|
|
97
|
+
* console.log( element._mc.myMC );
|
|
98
|
+
* // { target: (element) }
|
|
99
|
+
*
|
|
100
|
+
* console.log( mcc.siblings() );
|
|
101
|
+
* // [ { target: (element) } ]
|
|
102
|
+
*
|
|
103
|
+
* ```
|
|
104
|
+
* @class
|
|
105
|
+
* @name MC
|
|
106
|
+
*/
|
|
107
|
+
class MC {
|
|
3
108
|
target;
|
|
4
109
|
privateMCs = {};
|
|
5
110
|
_mc = {};
|
|
6
111
|
static debug = false;
|
|
7
|
-
|
|
112
|
+
/**
|
|
113
|
+
* Constructs an MC instance with a target DOM element.
|
|
114
|
+
* @constructor
|
|
115
|
+
* @param {HTMLElement | { [key: string]: any }} - The target DOM element or any object.
|
|
116
|
+
*/
|
|
117
|
+
constructor(target = undefined) {
|
|
118
|
+
/**
|
|
119
|
+
* target is a DOM element or a parent MC
|
|
120
|
+
* @type {object}
|
|
121
|
+
* @public
|
|
122
|
+
*/
|
|
8
123
|
this.target = target;
|
|
124
|
+
/**
|
|
125
|
+
* The collection of private microcomponents.
|
|
126
|
+
* @private
|
|
127
|
+
* @type {Object.<string, any>}
|
|
128
|
+
*/
|
|
9
129
|
this.privateMCs = {};
|
|
10
|
-
if (MC
|
|
130
|
+
if (MC.debug) {
|
|
131
|
+
/**
|
|
132
|
+
* exposes private microcomponents in debug mode.
|
|
133
|
+
* @public
|
|
134
|
+
* @type {Object.<string, any>}
|
|
135
|
+
*/
|
|
11
136
|
this._mc = this.privateMCs;
|
|
12
137
|
}
|
|
13
|
-
;
|
|
14
138
|
}
|
|
15
|
-
// return all top-level micro components from an HTMLElement
|
|
16
139
|
static siblings(target, search) {
|
|
17
140
|
let t = target;
|
|
18
141
|
if (!t?._mc)
|
|
@@ -20,14 +143,11 @@ export class MC {
|
|
|
20
143
|
let mc = t._mc;
|
|
21
144
|
return search ? mc[search] ? [mc[search]] : [] : [...Object.entries(t._mc)];
|
|
22
145
|
}
|
|
23
|
-
// add a microcomponent to a target DOM node
|
|
24
146
|
static add(target, key, element = {}) {
|
|
25
147
|
const mc = target;
|
|
26
|
-
// create the _mc property if necessary
|
|
27
148
|
if (!mc._mc) {
|
|
28
149
|
mc._mc = new MC();
|
|
29
150
|
}
|
|
30
|
-
// add the element with the given property key to the _mc property object
|
|
31
151
|
if (key && !mc._mc[key]) {
|
|
32
152
|
mc._mc[key] = element;
|
|
33
153
|
if (target) {
|
|
@@ -36,31 +156,27 @@ export class MC {
|
|
|
36
156
|
}
|
|
37
157
|
return element;
|
|
38
158
|
}
|
|
39
|
-
// remove a micro component from the target DOM node
|
|
40
159
|
static remove(target, key) {
|
|
41
|
-
if (
|
|
42
|
-
!key
|
|
43
|
-
|| typeof key !== 'string'
|
|
44
|
-
|| !target
|
|
45
|
-
|| target instanceof HTMLElement === false) {
|
|
160
|
+
if (!key || typeof key !== 'string' || !target || !(target instanceof HTMLElement))
|
|
46
161
|
return;
|
|
47
|
-
}
|
|
48
|
-
;
|
|
49
162
|
const mc = target;
|
|
50
|
-
// delete the property from the HTMLElement _mc collection
|
|
51
163
|
if (mc._mc && mc._mc[key]) {
|
|
52
164
|
delete mc._mc[key];
|
|
53
165
|
}
|
|
54
|
-
// remove the _mc attribute if the DOM collection is empty
|
|
55
166
|
if (!Object.keys(mc._mc).length && target.hasAttribute('_mc')) {
|
|
56
167
|
target.removeAttribute('_mc');
|
|
57
168
|
}
|
|
58
|
-
return;
|
|
59
169
|
}
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
170
|
+
/**
|
|
171
|
+
* returns top level microcomponents from a list of HTMLElements.
|
|
172
|
+
* @name getMicroComponents
|
|
173
|
+
* @instance
|
|
174
|
+
* @function
|
|
175
|
+
* @private
|
|
176
|
+
* @param {Array<any>} elements - The elements to search for microcomponents.
|
|
177
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
178
|
+
* @returns {Array<any>} An array of microcomponents.
|
|
179
|
+
*/
|
|
64
180
|
getMicroComponents(elements, search) {
|
|
65
181
|
let mcValues = [];
|
|
66
182
|
elements.forEach(e => {
|
|
@@ -85,7 +201,17 @@ export class MC {
|
|
|
85
201
|
});
|
|
86
202
|
return mcValues;
|
|
87
203
|
}
|
|
88
|
-
|
|
204
|
+
/**
|
|
205
|
+
* returns ancestor MCs
|
|
206
|
+
* @name traverseNodes
|
|
207
|
+
* @instance
|
|
208
|
+
* @function
|
|
209
|
+
* @private
|
|
210
|
+
* @param {Node | null} node - The starting DOM node.
|
|
211
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
212
|
+
* @param {boolean} [firstonly=true] - If true, returns the first match only.
|
|
213
|
+
* @returns {Array<any>} An array of matching microcomponents.
|
|
214
|
+
*/
|
|
89
215
|
traverseNodes(node, search, firstonly = true) {
|
|
90
216
|
let mcValues = [];
|
|
91
217
|
while (node) {
|
|
@@ -103,31 +229,60 @@ export class MC {
|
|
|
103
229
|
}
|
|
104
230
|
return mcValues;
|
|
105
231
|
}
|
|
232
|
+
/**
|
|
233
|
+
* returns true if the element is an instance of HTMLElement.
|
|
234
|
+
* @instance
|
|
235
|
+
* @function
|
|
236
|
+
* @name isDOM
|
|
237
|
+
* @private
|
|
238
|
+
* @type {Function}
|
|
239
|
+
* @param {any} element - The element to check.
|
|
240
|
+
* @returns {boolean}
|
|
241
|
+
*/
|
|
106
242
|
isDOM(element) {
|
|
107
243
|
return element && element instanceof HTMLElement;
|
|
108
244
|
}
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
245
|
+
/**
|
|
246
|
+
* adds a microcomponent to the private collection.
|
|
247
|
+
* @name add
|
|
248
|
+
* @instance
|
|
249
|
+
* @function
|
|
250
|
+
* @param {string} [key] - The key to identify the microcomponent.
|
|
251
|
+
* @param {any} [element={}] - The microcomponent to add.
|
|
252
|
+
* @returns {any} The added microcomponent.
|
|
253
|
+
* @example
|
|
254
|
+
* const privateComp = this.add('privateComponent', {});
|
|
255
|
+
*/
|
|
113
256
|
add(key, element = {}) {
|
|
114
|
-
// add the element
|
|
115
257
|
if (key) {
|
|
116
|
-
this.privateMCs[key] = element;
|
|
258
|
+
this.privateMCs[key] = element;
|
|
117
259
|
}
|
|
118
260
|
return element;
|
|
119
261
|
}
|
|
120
|
-
|
|
262
|
+
/**
|
|
263
|
+
* removes a microcomponent from the private collection.
|
|
264
|
+
* @name remove
|
|
265
|
+
* @instance
|
|
266
|
+
* @function
|
|
267
|
+
* @param {string} [key] - The key to identify the microcomponent.
|
|
268
|
+
* @example
|
|
269
|
+
* this.remove('privateComponent');
|
|
270
|
+
*/
|
|
121
271
|
remove(key) {
|
|
122
|
-
// remove the component from the private collection
|
|
123
272
|
if (key in this.privateMCs) {
|
|
124
273
|
delete this.privateMCs[key];
|
|
125
274
|
}
|
|
126
275
|
}
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
276
|
+
/**
|
|
277
|
+
* removes a microcomponent from the private collection.
|
|
278
|
+
* @name siblings
|
|
279
|
+
* @instance
|
|
280
|
+
* @function
|
|
281
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
282
|
+
* @returns {Array<any>} An array of matching sibling microcomponents.
|
|
283
|
+
* @example
|
|
284
|
+
* const siblings = this.siblings('siblingComponent');
|
|
285
|
+
*/
|
|
131
286
|
siblings(search) {
|
|
132
287
|
if (this.target) {
|
|
133
288
|
if (this.target instanceof HTMLElement === true) {
|
|
@@ -140,34 +295,73 @@ export class MC {
|
|
|
140
295
|
}
|
|
141
296
|
return [];
|
|
142
297
|
}
|
|
143
|
-
|
|
298
|
+
/**
|
|
299
|
+
* retrieves the first ancestor DOM node with a matching microcomponent.
|
|
300
|
+
* @name parent
|
|
301
|
+
* @instance
|
|
302
|
+
* @function
|
|
303
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
304
|
+
* @returns {Array<any>} An array with the matching microcomponent.
|
|
305
|
+
* @example
|
|
306
|
+
* const parent = mcInstance.parent('parentComponent');
|
|
307
|
+
*/
|
|
308
|
+
/**
|
|
309
|
+
*/
|
|
144
310
|
parent(search) {
|
|
145
311
|
if (!this.isDOM(this.target))
|
|
146
312
|
return [];
|
|
147
313
|
return this.traverseNodes(this.target.parentNode, search, true);
|
|
148
314
|
}
|
|
149
|
-
|
|
315
|
+
/**
|
|
316
|
+
* retrieves the first ancestor DOM node with a matching microcomponent.
|
|
317
|
+
* @name parents
|
|
318
|
+
* @instance
|
|
319
|
+
* @function
|
|
320
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
321
|
+
* @returns {Array<any>} An array of matching ancestor microcomponents.
|
|
322
|
+
* @example
|
|
323
|
+
* const parents = mcInstance.parents('ancestorComponent');
|
|
324
|
+
*/
|
|
150
325
|
parents(search) {
|
|
151
326
|
if (!this.isDOM(this.target))
|
|
152
327
|
return [];
|
|
153
328
|
return this.traverseNodes(this.target.parentNode, search, false);
|
|
154
329
|
}
|
|
155
|
-
|
|
330
|
+
/**
|
|
331
|
+
* retrieves nearest child _mc DOM nodes, gets their matching microcomponents, and stops there.
|
|
332
|
+
* @name children
|
|
333
|
+
* @instance
|
|
334
|
+
* @function
|
|
335
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
336
|
+
* @returns {Array<any>} An array of matching child microcomponents.
|
|
337
|
+
* @example
|
|
338
|
+
* const children = mcInstance.children('childComponent');
|
|
339
|
+
*/
|
|
156
340
|
children(search) {
|
|
157
341
|
if (!this.isDOM(this.target))
|
|
158
342
|
return [];
|
|
159
343
|
const id = crypto.randomUUID();
|
|
160
344
|
this.target.setAttribute('temp-id', id);
|
|
161
345
|
const myDomElements = this.target.querySelectorAll(`*[_mc]:not([temp-id="${id}"] [_mc] [_mc])`);
|
|
162
|
-
const mcValues = this.getMicroComponents(
|
|
163
|
-
this.target.removeAttribute('temp-id');
|
|
346
|
+
const mcValues = this.getMicroComponents(Array.from(myDomElements), search);
|
|
164
347
|
return mcValues;
|
|
165
348
|
}
|
|
166
|
-
|
|
349
|
+
/**
|
|
350
|
+
* retrieves all decendant _mc DOM nodes and gets their matching microcomponents.
|
|
351
|
+
* @name children
|
|
352
|
+
* @instance
|
|
353
|
+
* @function
|
|
354
|
+
* @param {string} [search] - The key of the specific microcomponent.
|
|
355
|
+
* @returns {Array<any>} An array of matching descendant microcomponents.
|
|
356
|
+
* @example
|
|
357
|
+
* const descendants = mcInstance.descendants('descendantComponent');
|
|
358
|
+
*/
|
|
167
359
|
descendants(search) {
|
|
168
360
|
if (!this.isDOM(this.target))
|
|
169
361
|
return [];
|
|
170
362
|
const myDomElements = this.target.querySelectorAll('*[_mc]');
|
|
171
|
-
|
|
363
|
+
const mcValues = this.getMicroComponents(Array.from(myDomElements), search);
|
|
364
|
+
return mcValues;
|
|
172
365
|
}
|
|
173
366
|
}
|
|
367
|
+
export { MC };
|
|
@@ -1,12 +1,12 @@
|
|
|
1
|
-
'use strict';
|
|
1
|
+
'use strict';class MC{target;privateMCs={};_mc={};static debug=false;constructor(target=undefined){this.target=target;this.privateMCs={};if(MC.debug){this._mc=this.privateMCs;}}
|
|
2
2
|
static siblings(target,search){let t=target;if(!t?._mc)
|
|
3
3
|
return[];let mc=t._mc;return search?mc[search]?[mc[search]]:[]:[...Object.entries(t._mc)];}
|
|
4
4
|
static add(target,key,element={}){const mc=target;if(!mc._mc){mc._mc=new MC();}
|
|
5
5
|
if(key&&!mc._mc[key]){mc._mc[key]=element;if(target){target.setAttribute('_mc','');}}
|
|
6
6
|
return element;}
|
|
7
|
-
static remove(target,key){if(!key||typeof key!=='string'||!target
|
|
8
|
-
if(
|
|
9
|
-
|
|
7
|
+
static remove(target,key){if(!key||typeof key!=='string'||!target||!(target instanceof HTMLElement))
|
|
8
|
+
return;const mc=target;if(mc._mc&&mc._mc[key]){delete mc._mc[key];}
|
|
9
|
+
if(!Object.keys(mc._mc).length&&target.hasAttribute('_mc')){target.removeAttribute('_mc');}}
|
|
10
10
|
getMicroComponents(elements,search){let mcValues=[];elements.forEach(e=>{if(e){if(e instanceof HTMLElement){if(!search&&e._mc){mcValues=mcValues.concat(Object.values(e._mc));}
|
|
11
11
|
else if(search&&e._mc&&e._mc[search]){mcValues.push(e._mc[search]);}}
|
|
12
12
|
else if(e instanceof MC){if(!search){mcValues=mcValues.concat(Object.values(this.privateMCs));}
|
|
@@ -29,6 +29,7 @@ return[];return this.traverseNodes(this.target.parentNode,search,true);}
|
|
|
29
29
|
parents(search){if(!this.isDOM(this.target))
|
|
30
30
|
return[];return this.traverseNodes(this.target.parentNode,search,false);}
|
|
31
31
|
children(search){if(!this.isDOM(this.target))
|
|
32
|
-
return[];const id=crypto.randomUUID();this.target.setAttribute('temp-id',id);const myDomElements=this.target.querySelectorAll(`*[_mc]:not([temp-id="${id}"][_mc][_mc])`);const mcValues=this.getMicroComponents(
|
|
32
|
+
return[];const id=crypto.randomUUID();this.target.setAttribute('temp-id',id);const myDomElements=this.target.querySelectorAll(`*[_mc]:not([temp-id="${id}"][_mc][_mc])`);const mcValues=this.getMicroComponents(Array.from(myDomElements),search);return mcValues;}
|
|
33
33
|
descendants(search){if(!this.isDOM(this.target))
|
|
34
|
-
return[];const myDomElements=this.target.querySelectorAll('*[_mc]');
|
|
34
|
+
return[];const myDomElements=this.target.querySelectorAll('*[_mc]');const mcValues=this.getMicroComponents(Array.from(myDomElements),search);return mcValues;}}
|
|
35
|
+
export{MC};
|