@twobirds/microcomponents 0.0.4 → 0.0.7

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 (30) hide show
  1. package/MicroComponentProposal_draft.md +1 -1
  2. package/README.md +85 -36
  3. package/dist/microcomponents.d.ts +218 -2
  4. package/dist/microcomponents.d.ts.map +1 -1
  5. package/dist/microcomponents.js +237 -43
  6. package/dist/microcomponents.min.js +7 -6
  7. package/dist/microcomponents.ts +391 -201
  8. package/jsdoc.conf.json +19 -0
  9. package/microcomponents_functional_requirements.md +8 -0
  10. package/microcomponents_usage.md +56 -24
  11. package/package.json +13 -2
  12. package/public/docs/assets/highlight.css +14 -14
  13. package/public/docs/assets/search.js +1 -1
  14. package/public/docs/classes/microcomponents.MC.html +179 -41
  15. package/public/docs/classes/microcomponents_es3.MC.html +12 -12
  16. package/public/docs/functions/microcomponents_es3.__isEmpty.html +1 -1
  17. package/public/docs/index.html +18 -16
  18. package/public/docs/interfaces/microcomponents.HTMLElementMc.html +2 -2
  19. package/public/docs/modules/microcomponents.html +1 -1
  20. package/public/jsdoc/es3/files.html +216 -0
  21. package/public/jsdoc/es3/index.html +210 -0
  22. package/public/jsdoc/es3/symbols/_global_.html +368 -0
  23. package/public/jsdoc/es3/symbols/src/build_microcomponents.es3.js.html +104 -0
  24. package/public/jsdoc/es5+/files.html +218 -0
  25. package/public/jsdoc/es5+/index.html +218 -0
  26. package/public/jsdoc/es5+/symbols/MC.html +621 -0
  27. package/public/jsdoc/es5+/symbols/_global_.html +720 -0
  28. package/public/jsdoc/es5+/symbols/microcomponents.MC.html +323 -0
  29. package/public/jsdoc/es5+/symbols/src/build_microcomponents.js.html +375 -0
  30. package/src/microcomponents.ts +391 -201
@@ -1,18 +1,141 @@
1
1
  'use strict';
2
- export class MC {
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
+ * &nbsp;document.getElementById('myElement'),
24
+ * &nbsp;'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
+ * &nbsp;document.getElementById('myElement'),
40
+ * &nbsp;'myComponent',
41
+ * &nbsp;{}
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
+ * &nbsp;document.getElementById('myElement'),
55
+ * &nbsp;'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
+ * &nbsp;constructor( target ){
74
+ * &nbsp;&nbsp;super( target );
75
+ * &nbsp;&nbsp;this.target = target;
76
+ * &nbsp;}
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
+ * &nbsp;element,
84
+ * &nbsp;'myMC',
85
+ * &nbsp;new MyMC( element )
86
+ * );
87
+ *
88
+ * // Add an inner (private) microcomponent to mcc
89
+ * let mcc.add(
90
+ * &nbsp;'myInnerMC',
91
+ * &nbsp;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
- constructor(target = null) {
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?.debug) {
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 ( //silent fail
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
- helper methods
62
- */
63
- // get all microcomponents from a list of HTMLElements
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
- // get all ancestor DOM nodes up to the document
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
- Methods to handle private MCs
111
- */
112
- // add a microcomponent to the private microcomponent collection
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; // also the first element in the private MC collection
258
+ this.privateMCs[key] = element;
117
259
  }
118
260
  return element;
119
261
  }
120
- // remove a micro component from the private microcomponent collection
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
- selector methods, non-chainable
129
- */
130
- // all private collection members
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
- // first anchestor DOM node, all public MCs
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
- // all anchestor DOM nodes, beginning with the closest, all public MCs
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
- // nearest child DOM nodes, all puclic MCs
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([...myDomElements], search);
163
- this.target.removeAttribute('temp-id');
346
+ const mcValues = this.getMicroComponents(Array.from(myDomElements), search);
164
347
  return mcValues;
165
348
  }
166
- // all descendant DOM nodes, all puclic MCs
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
- return this.getMicroComponents([...myDomElements], search);
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';export class MC{target;privateMCs={};_mc={};static debug=false;constructor(target=null){this.target=target;this.privateMCs={};if(MC?.debug){this._mc=this.privateMCs;};}
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||target instanceof HTMLElement===false){return;};const mc=target;if(mc._mc&&mc._mc[key]){delete mc._mc[key];}
8
- if(!Object.keys(mc._mc).length&&target.hasAttribute('_mc')){target.removeAttribute('_mc');}
9
- return;}
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([...myDomElements],search);this.target.removeAttribute('temp-id');return mcValues;}
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]');return this.getMicroComponents([...myDomElements],search);}}
34
+ return[];const myDomElements=this.target.querySelectorAll('*[_mc]');const mcValues=this.getMicroComponents(Array.from(myDomElements),search);return mcValues;}}
35
+ export{MC};