@cntwg/html-ctrls-lists 0.0.32 → 0.0.33

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.
@@ -1,4 +1,4 @@
1
- // [v0.1.088-20260505]
1
+ // [v0.2.091-20260510]
2
2
 
3
3
  // === module init block ===
4
4
 
@@ -8,19 +8,17 @@ const {
8
8
  } = require('@ygracs/bsfoc-lib-js');
9
9
 
10
10
  const {
11
- TItemsListEx,
12
- } = require('@ygracs/lists-lib-js');
13
-
14
- const {
15
- isHTMLElement, isSelectedHTMLElement, isHiddenHTMLElement,
11
+ isHTMLElement,
16
12
  showHTMLElement, hideHTMLElement,
17
13
  selectHTMLElement, unselectHTMLElement,
18
- markHTMLElementAsCurrent, unmarkCurrentHTMLElement,
19
- readAsAttrValue, valueToClassList,
20
14
  eventHelper, // [!] not oficialy exported yet
21
15
  CSS_CLASS_STRING,
22
16
  } = require('@cntwg/html-helper');
23
17
 
18
+ const {
19
+ THtmlItemsListContainer,
20
+ } = require('./list-cont');
21
+
24
22
  const {
25
23
  THtmlStubItemsSet,
26
24
  // * import types definitions *
@@ -37,529 +35,24 @@ const {
37
35
  CSS_CLASS_DISABLED,
38
36
  } = CSS_CLASS_STRING;
39
37
 
40
- /**
41
- * @typedef {Object} ISearchListElementResultOnFail
42
- * @property {number} index - element index
43
- * @property {null} item - found element
44
- */
45
-
46
- /**
47
- * @typedef {Object} ISearchListElementResultOnSuccess
48
- * @property {number} index - element index
49
- * @property {any} item - found element
50
- */
51
-
52
- /**
53
- * @typedef {ISearchListElementResultOnFail|ISearchListElementResultOnSuccess} ISearchListElementResult
54
- */
55
-
56
- /**
57
- * Searches an element in a list by a given attributes of that element.
58
- * @function srchListElementByAttr
59
- * @param {TItemsListEx} list
60
- * @param {string} name - target attribute name
61
- * @param {string} [value=""] - target attribute value
62
- * @returns {ISearchListElementResult}
63
- * @inner
64
- */
65
- function srchListElementByAttr(list, name, value = '') {
66
- const _value = readAsAttrValue(value);
67
- let item = null;
68
- let index = -1;
69
- let count = list.count;
70
- let isACCEPTED = false;
71
- if (count > 0 && name !== '' && _value !== null) {
72
- const acceptAnyVal = _value === '';
73
- for (let i = 0; i < count; i++) {
74
- item = list.getItem(i);
75
- if (
76
- isHTMLElement(item)
77
- && item.hasAttribute(name)
78
- && (acceptAnyVal || item.getAttribute(name) === value)
79
- ) {
80
- index = i;
81
- isACCEPTED = true;
82
- break;
83
- };
84
- };
85
- };
86
- return isACCEPTED ? { index, item } : { index, item: null };
87
- };
88
-
89
38
  // === module main block ===
90
39
 
91
40
  const ILC_SMODE_DEF = 0;
92
41
  const ILC_SMODE_SHFT = 1;
93
42
  const ILC_SMODE_CTRL = 2;
94
43
 
95
- /**
96
- * An options set for `THtmlItemsListContainer`-class
97
- * @typedef {Object} OPT_hlconsett
98
- * @property {boolean} [autoHideNewItems=false] - indicates whether to hide
99
- * a new element
100
- * @property {boolean} [markCurrentItem=false] - indicates whether to mark
101
- * a current element
102
- * @property {(string|string[])} [itemBaseClassID] - contains a base class
103
- * attributes applayed to each a newly added list member
104
- */
105
-
106
- /**
107
- * @classdesc This class implements an interfaco for a list container
108
- */
109
- class THtmlItemsListContainer {
110
- /** @type {?HTMLElement} */
111
- #_host;
112
- /** @type {TItemsListEx} */
113
- #_items;
114
- /**
115
- * A container settings
116
- * @typedef {Object} THtmlItemsListContainerConfig
117
- * @property {boolean} autoHideNewItems - indicates whether to hide a new element
118
- * @property {boolean} markCurrentItem - indicates whether to mark a new element
119
- * as a current
120
- * @property {string[]} itemBaseClassID - contains a base class attributes
121
- * applayed to each a newly added list member
122
- */
123
- /** @type {THtmlItemsListContainerConfig} */
124
- #_config;
125
- /**
126
- * A container status
127
- * @typedef {Object} statILCont
128
- * @property {number} curIndex
129
- * @property {?HTMLElement} curItem
130
- * @inner
131
- */
132
- /** @type {statILCont} */
133
- #_status;
134
-
135
- /**
136
- * Creates an instance of a list container
137
- * @param {?HTMLElement} host - host element
138
- * @param {OPT_hlconsett} [opt] - options
139
- */
140
- constructor(host, opt) {
141
- // check host
142
- this.#_host = isHTMLElement(host) ? host : null;
143
- // init items container
144
- const _items = new TItemsListEx();
145
- this.#_items = _items;
146
- // load options
147
- /** @type {OPT_hlconsett} */
148
- const _options = isPlainObject(opt) ? opt : {};
149
- let {
150
- autoHideNewItems,
151
- markCurrentItem,
152
- itemBaseClassID,
153
- } = _options;
154
- if (typeof autoHideNewItems !== 'boolean') {
155
- autoHideNewItems = false;
156
- // // TODO: next line planned to be removed
157
- _options.autoHideNewItems = autoHideNewItems;
158
- };
159
- if (typeof markCurrentItem !== 'boolean') {
160
- markCurrentItem = false;
161
- // // TODO: next line planned to be removed
162
- _options.markCurrentItem = markCurrentItem;
163
- };
164
- itemBaseClassID = valueToClassList(itemBaseClassID, true);
165
- // // TODO: next line planned to be removed
166
- _options.itemBaseClassID = itemBaseClassID;
167
- // init status
168
- /** @type {statILCont} */
169
- const _status = {
170
- curIndex: _items.curIndex,
171
- curItem: _items.curItem,
172
- };
173
- this.#_status = _status;
174
- // save options
175
- this.#_config = {
176
- autoHideNewItems,
177
- markCurrentItem,
178
- itemBaseClassID,
179
- };
180
- }
181
-
182
- [Symbol.iterator]() {
183
- let index = 0;
184
- return {
185
- next: () => {
186
- if (index < this.count) {
187
- return { done: false, value: this.getItem(index++) };
188
- } else {
189
- return { done: true, value: undefined };
190
- };
191
- },
192
- return() {
193
- return { done: true, value: undefined };
194
- },
195
- };
196
- }
197
-
198
- /**
199
- * Contains a Qty of an elements
200
- * @type {number}
201
- * @readonly
202
- */
203
- get count() {
204
- return this.#_items.count;
205
- }
206
-
207
- /**
208
- * Contains an index of the current element
209
- * @type {number}
210
- * @readonly
211
- */
212
- get curIndex() {
213
- return this.#_items.curIndex;
214
- }
215
-
216
- /**
217
- * Returns a minimum value of an index
218
- * @type {number}
219
- * @readonly
220
- */
221
- get minIndex() {
222
- return this.#_items.minIndex;
223
- }
224
-
225
- /**
226
- * Returns a maximum value of an index
227
- * @type {number}
228
- * @readonly
229
- */
230
- get maxIndex() {
231
- return this.#_items.maxIndex;
232
- }
233
-
234
- /**
235
- * Returns a value of a previous index
236
- * @type {number}
237
- * @readonly
238
- */
239
- get prevIndex() {
240
- return this.#_items.prevIndex;
241
- }
242
-
243
- /**
244
- * Returns a value of a next index
245
- * @type {number}
246
- * @readonly
247
- */
248
- get nextIndex() {
249
- return this.#_items.nextIndex;
250
- }
251
-
252
- /**
253
- * Returns an element in the current index
254
- * @type {?HTMLElement}
255
- * @readonly
256
- */
257
- get curItem() {
258
- const item = this.#_items.curItem;
259
- return isHTMLElement(item) ? item : null;
260
- }
261
-
262
- /**
263
- * Clears an instance content.
264
- * @returns {void}
265
- */
266
- clear() {
267
- this.#_items.clear();
268
- const _status = this.#_status;
269
- _status.curIndex = this.curIndex;
270
- _status.curItem = this.curItem;
271
- const _host = this.#_host;
272
- if (_host) _host.innerHTML = '';
273
- }
274
-
275
- /**
276
- * Checks if an instance contains no items.
277
- * @returns {boolean}
278
- */
279
- isEmpty() {
280
- return this.#_items.isEmpty();
281
- }
282
-
283
- /**
284
- * Checks if an instance contains any items.
285
- * @returns {boolean}
286
- */
287
- isNotEmpty() {
288
- return this.#_items.isNotEmpty();
289
- }
290
-
291
- /**
292
- * Checks if a given value is a valid index and
293
- * it fits an index range within an instance.
294
- * @param {number|string} value - index value
295
- * @returns {boolean}
296
- * @deprecated
297
- * @todo \[since v0.0.31] deprecated. Use
298
- * {@link THtmlItemsListContainer.checkIndex} instead
299
- */
300
- chkIndex(value) {
301
- return this.#_items.checkIndex(value);
302
- }
303
-
304
- /**
305
- * Checks if a given value is a valid index and
306
- * it fits an index range within an instance.
307
- * @since 0.0.31
308
- * @param {number|string} value - index value
309
- * @returns {boolean}
310
- */
311
- checkIndex(value) {
312
- return this.#_items.checkIndex(value);
313
- }
314
-
315
- /**
316
- * Checks if a given value is a valid index and
317
- * it fits an index range within an instance.
318
- * @param {number|string} value - value to check
319
- * @param {boolean} [opt=false] - defines a type of result
320
- * @returns {boolean|number}
321
- * @deprecated
322
- * @todo \[since v0.0.31] deprecated. Use
323
- * {@link THtmlItemsListContainer.checkIndex} or
324
- * {@link THtmlItemsListContainer.tryIndex} instead
325
- */
326
- chkIndexEx(value, opt) {
327
- return opt ? this.#_items.tryIndex(value) : this.#_items.checkIndex(value);
328
- }
329
-
330
- /**
331
- * Returns an index in case a given value is a valid index value and not exceeds
332
- * an index range within the list. If failed a `-1` returned
333
- * @since 0.0.31
334
- * @param {any} value - value to evaluate
335
- * @returns {number}
336
- */
337
- tryIndex(value) {
338
- return this.#_items.tryIndex(value);
339
- }
340
-
341
- /**
342
- * Returns an index of a given element.
343
- * @param {HTMLElement} item - element to search
344
- * @returns {number}
345
- * @todo add 2nd param
346
- * @see TItemsListEx.srchIndex
347
- */
348
- srchIndex(item) {
349
- return isHTMLElement(item) ? this.#_items.srchIndex(item) : -1;
350
- }
351
-
352
- /**
353
- * Returns an index of an element wich has an attribute
354
- * with a given name and value.
355
- * @param {string} name - attribute name
356
- * @param {any} [value=""] - attribute value
357
- * @returns {number}
358
- */
359
- srchIndexByAttr(name, value = '') {
360
- const _name = typeof name === 'string' ? name.trim() : '';
361
- const { index } = srchListElementByAttr(this.#_items, _name, value);
362
- return index;
363
- };
364
-
365
- /**
366
- * Returns an index of an element wich has a given ID.
367
- * @param {string} value - element ID
368
- * @returns {number}
369
- */
370
- srchIndexByID(value) {
371
- const { index } = srchListElementByAttr(this.#_items, 'id', value);
372
- return index;
373
- };
374
-
375
- /**
376
- * Sets a current index.
377
- * @param {number|string} index - element index
378
- * @returns {boolean}
379
- */
380
- setCurIndex(index) {
381
- const isSUCCEED = this.#_items.setIndex(index);
382
- if (isSUCCEED) {
383
- const markCurrentItem = this.#_config.markCurrentItem;
384
- const _status = this.#_status;
385
- if (markCurrentItem && _status.curIndex !== -1) {
386
- unmarkCurrentHTMLElement(_status.curItem);
387
- };
388
- const item = this.getItem(index);
389
- _status.curIndex = Number(index);
390
- _status.curItem = item;
391
- if (markCurrentItem) markHTMLElementAsCurrent(item);
392
- };
393
- return isSUCCEED;
394
- }
395
-
396
- /**
397
- * Resets a current index.
398
- * @returns {void}
399
- */
400
- rstCurIndex() {
401
- const _status = this.#_status;
402
- if (this.#_config.markCurrentItem && _status.curIndex !== -1) {
403
- unmarkCurrentHTMLElement(_status.curItem);
404
- };
405
- this.#_items.rstIndex();
406
- _status.curIndex = this.#_items.curIndex;
407
- _status.curItem = this.curItem;
408
- }
409
-
410
- /**
411
- * Returns an item addressed by a given index.
412
- * @param {number|string} index - element index
413
- * @returns {?HTMLElement}
414
- */
415
- getItem(index) {
416
- const item = this.#_items.getItem(index);
417
- return isHTMLElement(item) ? item : null;
418
- }
419
-
420
- /**
421
- * Returns an item wich has an attribute with a given name and value.
422
- * @param {string} name - attribute name
423
- * @param {any} [value=""] - attribute value
424
- * @returns {?HTMLElement}
425
- */
426
- getItemByAttr(name, value = '') {
427
- const _name = typeof name === 'string' ? name.trim() : '';
428
- const { item } = srchListElementByAttr(this.#_items, _name, value);
429
- return item;
430
- }
431
-
432
- /**
433
- * Returns an item wich has a given ID.
434
- * @param {string} value - element ID
435
- * @returns {?HTMLElement}
436
- */
437
- getItemByID(value) {
438
- const { item } = srchListElementByAttr(this.#_items, 'id', value);
439
- return item;
440
- }
441
-
442
- /**
443
- * Adds an item to an instance.
444
- * @param {HTMLElement} item - some element
445
- * @param {boolean} [opt=false] - indicates whether to correct a current index
446
- * @returns {number}
447
- */
448
- addItem(item, opt) {
449
- const forceCI = typeof opt === 'boolean' ? opt : false;
450
- const index = (
451
- isHTMLElement(item)
452
- ? this.#_items.addItemEx(item, false)
453
- : -1
454
- );
455
- const isSUCCEED = index !== -1;
456
- if (isSUCCEED) {
457
- const { autoHideNewItems, itemBaseClassID } = this.#_config;
458
- if (autoHideNewItems) hideHTMLElement(item);
459
- if (itemBaseClassID.length > 0) item.classList.add(...itemBaseClassID);
460
- if (forceCI) this.setCurIndex(index);
461
- const _host = this.#_host;
462
- if (_host) _host.append(item);
463
- };
464
- return isSUCCEED ? index : -1;
465
- }
466
-
467
- /**
468
- * Deletes an item from an instance.
469
- * @param {number|string} index - element index
470
- * @param {any} [opt]
471
- * @param {boolean} [optEx=true]
472
- * @returns {boolean}
473
- */
474
- delItem(index, opt, optEx) {
475
- const _items = this.#_items;
476
- const item = _items.delItemEx(index, opt);
477
- const isSUCCEED = item !== undefined;
478
- if (isSUCCEED) {
479
- if (this.#_host && isHTMLElement(item)) item.remove();
480
- const doProcEx = typeof optEx === 'boolean' ? optEx : true;
481
- if (doProcEx) {
482
- const index = _items.curIndex;
483
- if (index === -1) {
484
- this.rstCurIndex();
485
- } else {
486
- this.setCurIndex(index);
487
- };
488
- };
489
- };
490
- return isSUCCEED;
491
- }
492
-
493
- /**
494
- * Selects an item addressed by a given index.
495
- * @param {number|string} index - element index
496
- * @param {boolean} [opt=false] - indicates whether to correct a current index
497
- * @returns {boolean}
498
- */
499
- selectItem(index, opt) {
500
- const forceCI = typeof opt === 'boolean' ? opt : false;
501
- const isSUCCEED = selectHTMLElement(this.#_items.getItem(index));
502
- if (isSUCCEED && forceCI) this.setCurIndex(index);
503
- return isSUCCEED;
504
- }
505
-
506
- /**
507
- * Unselects an item addressed by a given index.
508
- * @param {number|string} index - element index
509
- * @returns {boolean}
510
- */
511
- unselectItem(index) {
512
- return unselectHTMLElement(this.#_items.getItem(index));
513
- }
514
-
515
- /**
516
- * Hides an item addressed by a given index.
517
- * @param {number|string} index - element index
518
- * @returns {boolean}
519
- */
520
- hideItem(index) {
521
- return hideHTMLElement(this.#_items.getItem(index));
522
- }
523
-
524
- /**
525
- * Shows an item addressed by a given index.
526
- * @param {number|string} index - element index
527
- * @returns {boolean}
528
- */
529
- showItem(index) {
530
- return showHTMLElement(this.#_items.getItem(index));
531
- }
532
-
533
- /**
534
- * Checks whether an item is selected.
535
- * @param {number|string} index - element index
536
- * @returns {boolean}
537
- */
538
- isSelectedItem(index) {
539
- return isSelectedHTMLElement(this.#_items.getItem(index));
540
- }
541
-
542
- /**
543
- * Checks whether an item is hidden.
544
- * @param {number|string} index - element index
545
- * @returns {boolean}
546
- */
547
- isHiddenItem(index) {
548
- return isHiddenHTMLElement(this.#_items.getItem(index));
549
- }
550
-
551
- };
552
- module.exports.THtmlItemsListContainer = THtmlItemsListContainer;
553
-
44
+ // // NOTE: @extends ITHtmlItemsListContainerOptions
554
45
  /**
555
46
  * An options set for `THtmlItemsListController`-class
556
- * @typedef {Object} OPT_hlctlsett
47
+ * @typedef {Object} IHtmlItemsListControllerOptions
557
48
  * @property {boolean} [autoHideNewItems=false] - indicates whether to hide
558
49
  * a new element
559
50
  * @property {boolean} [markCurrentItem=false] - indicates whether to mark
560
51
  * a current element
561
52
  * @property {string|string[]} [itemBaseClassID] - contains a base class
562
53
  * attributes applayed to each a newly added list member
54
+ * @property {number|string} [targetScopeForEID] - \[since v0.0.33] indicates
55
+ * a target scope chosen to select an ID-attribute of the element
563
56
  * @property {boolean} [showStubsIfEmpty=false] - indicates whether to show
564
57
  * stubs if empty
565
58
  * @property {boolean} [allowGroupSelection=false] - indicates whether
@@ -568,6 +61,11 @@ module.exports.THtmlItemsListContainer = THtmlItemsListContainer;
568
61
  * of an element selection is allowed
569
62
  * @property {IStubItemsSetOptions} [stubs] - stub elements options
570
63
  */
64
+ /**
65
+ * A virtual constant meant for support jsdoc notation:
66
+ * @type {IHtmlItemsListControllerOptions}
67
+ */
68
+ module.exports.IHtmlItemsListControllerOptions = {};
571
69
 
572
70
  /**
573
71
  * @augments THtmlItemsListContainer
@@ -581,7 +79,7 @@ class THtmlItemsListController extends THtmlItemsListContainer {
581
79
  #_stubs;
582
80
  /** @type {Set<HTMLElement>} */
583
81
  #_selects;
584
- /** @property {OPT_hlctlsett} */
82
+ /** @property {IHtmlItemsListControllerOptions} */
585
83
  #_options;// = null;
586
84
  /**
587
85
  * A controler status
@@ -603,17 +101,15 @@ class THtmlItemsListController extends THtmlItemsListContainer {
603
101
  /**
604
102
  * Creates a new instance of the class.
605
103
  * @param {?HTMLElement} host - host element
606
- * @param {OPT_hlctlsett} [opt] - options
104
+ * @param {IHtmlItemsListControllerOptions} [opt] - options
607
105
  */
608
106
  constructor(host, opt) {
609
- // check host element
610
- const isHostEnabled = isHTMLElement(host);
611
- const _host = isHostEnabled ? host : null;
612
107
  // check options
613
- /** @type {OPT_hlctlsett} */
614
108
  const _options = isPlainObject(opt) ? opt : {};
615
109
  // call parent constructor
616
- super(_host, _options);
110
+ super(host, _options);
111
+ // check host
112
+ const _host = this.#_host = isHTMLElement(host) ? host : null;
617
113
  // load options
618
114
  let {
619
115
  //autoHideNewItems, // [*] processed by parent
@@ -625,17 +121,24 @@ class THtmlItemsListController extends THtmlItemsListContainer {
625
121
  stubs: stubsList,
626
122
  } = _options;
627
123
  if (typeof showStubsIfEmpty !== 'boolean') {
628
- _options.showStubsIfEmpty = showStubsIfEmpty = false;
124
+ showStubsIfEmpty = false;
125
+ // // TODO: next line planned to be removed
126
+ _options.showStubsIfEmpty = showStubsIfEmpty;
629
127
  };
630
128
  if (typeof allowGroupSelection !== 'boolean') {
631
- _options.allowGroupSelection = allowGroupSelection = false;
129
+ allowGroupSelection = false;
130
+ // // TODO: next line planned to be removed
131
+ _options.allowGroupSelection = allowGroupSelection;
632
132
  };
633
133
  if (typeof allowSelectionLocks !== 'boolean') {
634
- _options.allowSelectionLocks = allowSelectionLocks = false;
134
+ allowSelectionLocks = false;
135
+ // // TODO: next line planned to be removed
136
+ _options.allowSelectionLocks = allowSelectionLocks;
635
137
  };
636
138
  // save options
637
139
  this.#_options = _options;
638
140
  // init status flags set
141
+ const isHostEnabled = isHTMLElement(_host);
639
142
  /** @type {statILCtrl} */
640
143
  const _status = {
641
144
  isSelectionLocked: false,
@@ -646,8 +149,6 @@ class THtmlItemsListController extends THtmlItemsListContainer {
646
149
  execDelItemDI: -1,
647
150
  execDelItemCI: -1,
648
151
  }
649
- // bind ref to host
650
- this.#_host = _host;
651
152
  // init stub items set
652
153
  this.#_stubs = new THtmlStubItemsSet(_host, stubsList);
653
154
  // init index of selected items
@@ -709,6 +210,7 @@ class THtmlItemsListController extends THtmlItemsListContainer {
709
210
  //console.log(`CHECK: e => tag:[${curItem.tagName}]`);
710
211
  if (host) {
711
212
  // find an actual list element in case when some inner element was clicking
213
+ /** @type {?HTMLElement} */
712
214
  let tmpItem = curItem;
713
215
  while (tmpItem) {
714
216
  //console.log(`CHECK: e => target.tag:[${tmpItem.tagName}]`);
@@ -1007,7 +509,7 @@ class THtmlItemsListController extends THtmlItemsListContainer {
1007
509
  }
1008
510
 
1009
511
  /**
1010
- *
512
+ *
1011
513
  * @typedef {Object} OPT_selectStat
1012
514
  * @property {boolean} [ctrlKey=false]
1013
515
  * @property {boolean} [shiftKey=false]