native-document 1.0.91 → 1.0.93

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 (68) hide show
  1. package/dist/native-document.components.min.js +1168 -138
  2. package/dist/native-document.dev.js +792 -217
  3. package/dist/native-document.dev.js.map +1 -1
  4. package/dist/native-document.devtools.min.js +1 -1
  5. package/dist/native-document.min.js +1 -1
  6. package/docs/advanced-components.md +814 -0
  7. package/docs/anchor.md +71 -11
  8. package/docs/cache.md +888 -0
  9. package/docs/conditional-rendering.md +91 -1
  10. package/docs/core-concepts.md +9 -2
  11. package/docs/elements.md +127 -2
  12. package/docs/extending-native-document-element.md +7 -1
  13. package/docs/filters.md +1216 -0
  14. package/docs/getting-started.md +12 -3
  15. package/docs/lifecycle-events.md +10 -2
  16. package/docs/list-rendering.md +453 -54
  17. package/docs/memory-management.md +9 -7
  18. package/docs/native-document-element.md +30 -9
  19. package/docs/native-fetch.md +744 -0
  20. package/docs/observables.md +135 -6
  21. package/docs/routing.md +7 -1
  22. package/docs/state-management.md +7 -1
  23. package/docs/validation.md +8 -1
  24. package/eslint.config.js +3 -3
  25. package/package.json +3 -2
  26. package/readme.md +53 -14
  27. package/src/components/$traits/HasItems.js +42 -1
  28. package/src/components/BaseComponent.js +4 -1
  29. package/src/components/accordion/Accordion.js +112 -8
  30. package/src/components/accordion/AccordionItem.js +93 -4
  31. package/src/components/alert/Alert.js +164 -4
  32. package/src/components/avatar/Avatar.js +236 -22
  33. package/src/components/menu/index.js +1 -2
  34. package/src/core/data/ObservableArray.js +120 -2
  35. package/src/core/data/ObservableChecker.js +50 -0
  36. package/src/core/data/ObservableItem.js +223 -80
  37. package/src/core/data/ObservableWhen.js +36 -6
  38. package/src/core/data/observable-helpers/array.js +12 -3
  39. package/src/core/data/observable-helpers/computed.js +17 -4
  40. package/src/core/data/observable-helpers/object.js +19 -3
  41. package/src/core/elements/control/for-each-array.js +21 -3
  42. package/src/core/elements/control/for-each.js +17 -5
  43. package/src/core/elements/control/show-if.js +31 -15
  44. package/src/core/elements/control/show-when.js +23 -0
  45. package/src/core/elements/control/switch.js +40 -10
  46. package/src/core/utils/cache.js +5 -0
  47. package/src/core/utils/memoize.js +25 -16
  48. package/src/core/utils/prototypes.js +3 -2
  49. package/src/core/wrappers/AttributesWrapper.js +1 -1
  50. package/src/core/wrappers/NDElement.js +41 -1
  51. package/src/core/wrappers/NdPrototype.js +4 -0
  52. package/src/core/wrappers/TemplateCloner.js +13 -10
  53. package/src/core/wrappers/prototypes/bind-class-extensions.js +1 -1
  54. package/src/core/wrappers/prototypes/nd-element-extensions.js +3 -0
  55. package/src/router/Route.js +9 -4
  56. package/src/router/Router.js +28 -9
  57. package/src/router/errors/RouterError.js +0 -1
  58. package/types/control-flow.d.ts +9 -6
  59. package/types/elements.d.ts +6 -3
  60. package/types/filters/index.d.ts +4 -0
  61. package/types/nd-element.d.ts +5 -238
  62. package/types/observable.d.ts +9 -3
  63. package/types/router.d.ts +5 -1
  64. package/types/template-cloner.ts +1 -0
  65. package/types/validator.ts +11 -1
  66. package/utils.d.ts +2 -1
  67. package/utils.js +4 -4
  68. package/src/core/utils/service.js +0 -6
@@ -1,6 +1,10 @@
1
1
  var NativeComponents = (function (exports) {
2
2
  'use strict';
3
3
 
4
+ /**
5
+ *
6
+ * @class
7
+ */
4
8
  function BaseComponent() {
5
9
 
6
10
  }
@@ -125,6 +129,17 @@ var NativeComponents = (function (exports) {
125
129
  };
126
130
  EventEmitter.prototype.emit = EventEmitter.prototype.trigger;
127
131
 
132
+ /**
133
+ * Valid children types that can be rendered in the DOM
134
+ * @typedef {HTMLElement|Text|DocumentFragment|string|Array<ValidChildren>} ValidChildren
135
+ */
136
+
137
+ /**
138
+ * Component for creating accordion interfaces with expandable/collapsible items
139
+ * @param {{ items?: Array<AccordionItem>, multiple?: boolean, variant?: string, renderContent?: (field: Accordion) => HTMLElement }} config
140
+ * @returns {Accordion}
141
+ * @class
142
+ */
128
143
  function Accordion(config = {}) {
129
144
  if (!(this instanceof Accordion)) {
130
145
  return new Accordion(config);
@@ -143,20 +158,47 @@ var NativeComponents = (function (exports) {
143
158
 
144
159
  Accordion.defaultTemplate = null;
145
160
 
146
- Accordion.use = function(template) {};
147
161
 
162
+ /**
163
+ * Sets the default template for all Accordion instances
164
+ * @param {{accordion: (accordion: Accordion) => ValidChildren}} template - Template object containing accordion factory function
165
+ */
166
+ Accordion.use = function(template) {
167
+ Accordion.defaultTemplate = template.accordion;
168
+ };
169
+
170
+ /**
171
+ * Adds an accordion item to the collection
172
+ * @param {AccordionItem} accordionItem - The accordion item to add
173
+ * @returns {Accordion}
174
+ */
148
175
  Accordion.prototype.item = function(accordionItem) {
149
176
  this.$description.items.push(accordionItem);
150
177
  return this;
151
178
  };
152
179
 
180
+ /**
181
+ * Sets the accordion items collection
182
+ * @param {Array<AccordionItem>} items - Array of accordion items
183
+ * @returns {Accordion}
184
+ */
153
185
  Accordion.prototype.items = function(items) {
154
186
  this.$description.items = items;
155
187
  return this;
156
188
  };
157
189
 
190
+ /**
191
+ * Alias for item method
192
+ * @param {AccordionItem} accordionItem - The accordion item to add
193
+ * @returns {Accordion}
194
+ */
158
195
  Accordion.prototype.addItem = Accordion.prototype.item;
159
196
 
197
+ /**
198
+ * Removes an item by its id
199
+ * @param {string} id - The id of the item to remove
200
+ * @returns {Accordion}
201
+ */
160
202
  Accordion.prototype.removeItemById = function(id) {
161
203
  if (this.$description.items) {
162
204
  this.$description.items = this.$description.items.filter(item => item.id !== id);
@@ -164,40 +206,77 @@ var NativeComponents = (function (exports) {
164
206
  return this;
165
207
  };
166
208
 
167
- Accordion.prototype.removeItem = function(item) {
209
+ /**
210
+ * Removes items matching the filter function
211
+ * @param {Function} filter - Filter function to determine which items to keep
212
+ * @returns {Accordion}
213
+ */
214
+ Accordion.prototype.remove = function(filter) {
168
215
  if (this.$description.items) {
169
- this.$description.items = this.$description.items.filter(item);
216
+ this.$description.items = this.$description.items.filter(filter);
170
217
  }
171
218
  return this;
172
219
  };
173
220
 
174
-
221
+ /**
222
+ * Enables or disables multiple items expansion
223
+ * @param {boolean} [enabled=true] - Whether multiple items can be expanded simultaneously
224
+ * @returns {Accordion}
225
+ */
175
226
  Accordion.prototype.multiple = function(enabled = true) {
176
227
  this.$description.multiple = enabled;
177
228
  return this;
178
229
  };
179
230
 
231
+ /**
232
+ * Sets the variant style for the accordion
233
+ * @param {string} name - The variant name
234
+ * @returns {Accordion}
235
+ */
180
236
  Accordion.prototype.variant = function(name) {
181
237
  this.$description.variant = name;
182
238
  return this;
183
239
  };
184
240
 
241
+ /**
242
+ * Sets the accordion variant to 'bordered'
243
+ * @returns {Accordion}
244
+ */
185
245
  Accordion.prototype.bordered = function() {
186
246
  return this.variant('bordered');
187
247
  };
188
248
 
249
+ /**
250
+ * Sets the accordion variant to 'separated'
251
+ * @returns {Accordion}
252
+ */
189
253
  Accordion.prototype.separated = function() {
190
254
  return this.variant('separated');
191
255
  };
192
256
 
257
+ /**
258
+ * Sets the accordion variant to 'flush'
259
+ * @returns {Accordion}
260
+ */
193
261
  Accordion.prototype.flush = function() {
194
262
  return this.variant('flush');
195
263
  };
196
264
 
265
+ /**
266
+ * Retrieves an accordion item by its key
267
+ * @param {string} key - The key of the item to retrieve
268
+ * @returns {AccordionItem|undefined}
269
+ */
197
270
  Accordion.prototype.getByKey = function(key) {
198
271
  return this.$description.items.find(item => item.key === key);
199
272
  };
200
273
 
274
+ /**
275
+ * Expands or collapses an accordion item by key
276
+ * @param {string} key - The key of the item
277
+ * @param {boolean} [state=true] - Whether to expand (true) or collapse (false)
278
+ * @returns {Accordion}
279
+ */
201
280
  Accordion.prototype.expanded = function(key, state = true) {
202
281
  const item = this.getByKey(key);
203
282
  if(item) {
@@ -210,35 +289,67 @@ var NativeComponents = (function (exports) {
210
289
  return this;
211
290
  };
212
291
 
292
+ /**
293
+ * Expands all accordion items
294
+ * @returns {Accordion}
295
+ */
213
296
  Accordion.prototype.expandAll = function() {
214
297
  this.$description.items.forEach(item => item.expanded(true));
215
298
  return this;
216
299
  };
217
300
 
301
+ /**
302
+ * Collapses all accordion items
303
+ * @returns {Accordion}
304
+ */
218
305
  Accordion.prototype.collapseAll = function() {
219
306
  this.$description.items.forEach(item => item.expanded(false));
220
307
  return this;
221
308
  };
222
309
 
310
+ /**
311
+ * Checks if an accordion item is expanded
312
+ * @param {string} key - The key of the item to check
313
+ * @returns {boolean|undefined}
314
+ */
223
315
  Accordion.prototype.isExpanded = function(key) {
224
316
  return this.getByKey(key)?.isExpanded?.();
225
317
  };
226
318
 
319
+ /**
320
+ * Registers a handler for the expand event
321
+ * @param {Function} handler - The event handler
322
+ * @returns {Accordion}
323
+ */
227
324
  Accordion.prototype.onExpand = function(handler) {
228
325
  this.on('expand', handler);
229
326
  return this;
230
327
  };
231
328
 
329
+ /**
330
+ * Registers a handler for the collapse event
331
+ * @param {Function} handler - The event handler
332
+ * @returns {Accordion}
333
+ */
232
334
  Accordion.prototype.onCollapse = function(handler) {
233
335
  this.on('collapse', handler);
234
336
  return this;
235
337
  };
236
338
 
339
+ /**
340
+ * Sets the content render function
341
+ * @param {Function} renderFn - Function to render content
342
+ * @returns {Accordion}
343
+ */
237
344
  Accordion.prototype.renderContent = function(renderFn) {
238
345
  this.$description.renderContent = renderFn;
239
346
  return this;
240
347
  };
241
348
 
349
+ /**
350
+ * Builds the accordion component
351
+ * @private
352
+ */
242
353
  Accordion.prototype.$build = function() {
243
354
  // TODO: Implementation
244
355
  // this.$description.items.forEach(item => {
@@ -252,10 +363,6 @@ var NativeComponents = (function (exports) {
252
363
  // });
253
364
  };
254
365
 
255
- Accordion.prototype.toNdElement = function() {
256
- return this.$build();
257
- };
258
-
259
366
  let DebugManager$1 = {};
260
367
  {
261
368
  DebugManager$1 = {
@@ -334,6 +441,16 @@ var NativeComponents = (function (exports) {
334
441
 
335
442
  ObservableChecker.prototype.__$isObservableChecker = true;
336
443
 
444
+ /**
445
+ * Subscribes to changes in the checked/transformed value.
446
+ *
447
+ * @param {Function} callback - Function called with the transformed value when observable changes
448
+ * @returns {Function} Unsubscribe function
449
+ * @example
450
+ * const count = Observable(5);
451
+ * const doubled = count.check(n => n * 2);
452
+ * doubled.subscribe(value => console.log(value)); // Logs: 10
453
+ */
337
454
  ObservableChecker.prototype.subscribe = function(callback) {
338
455
  const unSubscribe = this.observable.subscribe((value) => {
339
456
  callback && callback(this.checker(value));
@@ -342,26 +459,73 @@ var NativeComponents = (function (exports) {
342
459
  return unSubscribe;
343
460
  };
344
461
 
462
+ /**
463
+ * Creates a new ObservableChecker by applying another transformation.
464
+ * Allows chaining transformations.
465
+ *
466
+ * @param {(value: *) => *} callback - Transformation function to apply to the current checked value
467
+ * @returns {ObservableChecker} New ObservableChecker with chained transformation
468
+ * @example
469
+ * const count = Observable(5);
470
+ * const result = count.check(n => n * 2).check(n => n + 1);
471
+ * result.val(); // 11
472
+ */
345
473
  ObservableChecker.prototype.check = function(callback) {
346
474
  return this.observable.check(() => callback(this.val()));
347
475
  };
348
476
 
477
+ /**
478
+ * Gets the current transformed/checked value.
479
+ *
480
+ * @returns {*} The result of applying the checker function to the observable's current value
481
+ * @example
482
+ * const count = Observable(5);
483
+ * const doubled = count.check(n => n * 2);
484
+ * doubled.val(); // 10
485
+ */
349
486
  ObservableChecker.prototype.val = function() {
350
487
  return this.checker && this.checker(this.observable.val());
351
488
  };
352
489
 
490
+ /**
491
+ * Sets the value of the underlying observable (not the transformed value).
492
+ *
493
+ * @param {*} value - New value for the underlying observable
494
+ * @example
495
+ * const count = Observable(5);
496
+ * const doubled = count.check(n => n * 2);
497
+ * doubled.set(10); // Sets count to 10, doubled.val() returns 20
498
+ */
353
499
  ObservableChecker.prototype.set = function(value) {
354
500
  return this.observable.set(value);
355
501
  };
356
502
 
503
+ /**
504
+ * Manually triggers the underlying observable to notify subscribers.
505
+ *
506
+ * @example
507
+ * const count = Observable(5);
508
+ * const doubled = count.check(n => n * 2);
509
+ * doubled.trigger(); // Notifies all subscribers
510
+ */
357
511
  ObservableChecker.prototype.trigger = function() {
358
512
  return this.observable.trigger();
359
513
  };
360
514
 
515
+ /**
516
+ * Cleans up the underlying observable and all its subscriptions.
517
+ */
361
518
  ObservableChecker.prototype.cleanup = function() {
362
519
  return this.observable.cleanup();
363
520
  };
364
521
 
522
+ /**
523
+ * Creates an ObservableWhen that tracks whether an observable equals a specific value.
524
+ *
525
+ * @param {ObservableItem} observer - The observable to watch
526
+ * @param {*} value - The value to compare against
527
+ * @class ObservableWhen
528
+ */
365
529
  const ObservableWhen = function(observer, value) {
366
530
  this.$target = value;
367
531
  this.$observer = observer;
@@ -369,21 +533,44 @@ var NativeComponents = (function (exports) {
369
533
 
370
534
  ObservableWhen.prototype.__$isObservableWhen = true;
371
535
 
536
+ /**
537
+ * Subscribes to changes in the match status (true when observable equals target value).
538
+ *
539
+ * @param {Function} callback - Function called with boolean indicating if values match
540
+ * @returns {Function} Unsubscribe function
541
+ * @example
542
+ * const status = Observable('idle');
543
+ * const isLoading = status.when('loading');
544
+ * isLoading.subscribe(active => console.log('Loading:', active));
545
+ */
372
546
  ObservableWhen.prototype.subscribe = function(callback) {
373
547
  return this.$observer.on(this.$target, callback);
374
548
  };
375
549
 
550
+ /**
551
+ * Returns true if the observable's current value equals the target value.
552
+ *
553
+ * @returns {boolean} True if observable value matches target value
554
+ */
376
555
  ObservableWhen.prototype.val = function() {
377
556
  return this.$observer.$currentValue === this.$target;
378
557
  };
379
558
 
380
- ObservableWhen.prototype.isMath = function() {
381
- return this.$observer.$currentValue === this.$target;
382
- };
559
+ /**
560
+ * Returns true if the observable's current value equals the target value.
561
+ * Alias for val().
562
+ *
563
+ * @returns {boolean} True if observable value matches target value
564
+ */
565
+ ObservableWhen.prototype.isMatch = ObservableWhen.prototype.val;
383
566
 
384
- ObservableWhen.prototype.isActive = function() {
385
- return this.$observer.$currentValue === this.$target;
386
- };
567
+ /**
568
+ * Returns true if the observable's current value equals the target value.
569
+ * Alias for val().
570
+ *
571
+ * @returns {boolean} True if observable value matches target value
572
+ */
573
+ ObservableWhen.prototype.isActive = ObservableWhen.prototype.val;
387
574
 
388
575
  const invoke = function(fn, args, context) {
389
576
  if(context) {
@@ -472,7 +659,6 @@ var NativeComponents = (function (exports) {
472
659
 
473
660
  this.$previousValue = null;
474
661
  this.$currentValue = value;
475
- this.$isCleanedUp = false;
476
662
 
477
663
  this.$firstListener = null;
478
664
  this.$listeners = null;
@@ -499,16 +685,26 @@ var NativeComponents = (function (exports) {
499
685
  });
500
686
 
501
687
  ObservableItem.prototype.__$isObservable = true;
502
- const DEFAULT_OPERATIONS = {};
503
688
  const noneTrigger = function() {};
504
689
 
690
+ /**
691
+ * Intercepts and transforms values before they are set on the observable.
692
+ * The interceptor can modify the value or return undefined to use the original value.
693
+ *
694
+ * @param {(value) => any} callback - Interceptor function that receives (newValue, currentValue) and returns the transformed value or undefined
695
+ * @returns {ObservableItem} The observable instance for chaining
696
+ * @example
697
+ * const count = Observable(0);
698
+ * count.intercept((newVal, oldVal) => Math.max(0, newVal)); // Prevent negative values
699
+ */
505
700
  ObservableItem.prototype.intercept = function(callback) {
506
701
  this.$interceptor = callback;
702
+ this.set = this.$setWithInterceptor;
507
703
  return this;
508
704
  };
509
705
 
510
706
  ObservableItem.prototype.triggerFirstListener = function(operations) {
511
- this.$firstListener(this.$currentValue, this.$previousValue, operations || {});
707
+ this.$firstListener(this.$currentValue, this.$previousValue, operations);
512
708
  };
513
709
 
514
710
  ObservableItem.prototype.triggerListeners = function(operations) {
@@ -516,33 +712,12 @@ var NativeComponents = (function (exports) {
516
712
  const $previousValue = this.$previousValue;
517
713
  const $currentValue = this.$currentValue;
518
714
 
519
- operations = operations || DEFAULT_OPERATIONS;
520
715
  for(let i = 0, length = $listeners.length; i < length; i++) {
521
716
  $listeners[i]($currentValue, $previousValue, operations);
522
717
  }
523
718
  };
524
719
 
525
- const handleWatcherCallback = function(callbacks, value) {
526
- if(typeof callbacks === "function") {
527
- callbacks(value);
528
- return;
529
- }
530
- if (callbacks.set) {
531
- callbacks.set(value);
532
- return;
533
- }
534
- for(let i = 0, length = callbacks.length; i < length; i++) {
535
- const callback = callbacks[i];
536
- callback.set ? callback.set(value) : callback(value);
537
-
538
- }
539
- };
540
-
541
- ObservableItem.prototype.triggerWatchers = function() {
542
- if(!this.$watchers) {
543
- return;
544
- }
545
-
720
+ ObservableItem.prototype.triggerWatchers = function(operations) {
546
721
  const $watchers = this.$watchers;
547
722
  const $previousValue = this.$previousValue;
548
723
  const $currentValue = this.$currentValue;
@@ -550,20 +725,20 @@ var NativeComponents = (function (exports) {
550
725
  const $currentValueCallbacks = $watchers.get($currentValue);
551
726
  const $previousValueCallbacks = $watchers.get($previousValue);
552
727
  if($currentValueCallbacks) {
553
- handleWatcherCallback($currentValueCallbacks, true);
728
+ $currentValueCallbacks(true, $previousValue, operations);
554
729
  }
555
730
  if($previousValueCallbacks) {
556
- handleWatcherCallback($previousValueCallbacks, false);
731
+ $previousValueCallbacks(false, $currentValue, operations);
557
732
  }
558
733
  };
559
734
 
560
735
  ObservableItem.prototype.triggerAll = function(operations) {
561
- this.triggerWatchers();
736
+ this.triggerWatchers(operations);
562
737
  this.triggerListeners(operations);
563
738
  };
564
739
 
565
740
  ObservableItem.prototype.triggerWatchersAndFirstListener = function(operations) {
566
- this.triggerWatchers();
741
+ this.triggerWatchers(operations);
567
742
  this.triggerFirstListener(operations);
568
743
  };
569
744
 
@@ -591,21 +766,8 @@ var NativeComponents = (function (exports) {
591
766
  };
592
767
  ObservableItem.prototype.trigger = noneTrigger;
593
768
 
594
- /**
595
- * @param {*} data
596
- */
597
- ObservableItem.prototype.set = function(data) {
598
- let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
599
- newValue = Validator.isObservable(newValue) ? newValue.val() : newValue;
600
-
601
- if (this.$interceptor) {
602
- const result = this.$interceptor(newValue, this.$currentValue);
603
-
604
- if (result !== undefined) {
605
- newValue = result;
606
- }
607
- }
608
-
769
+ ObservableItem.prototype.$updateWithNewValue = function(newValue) {
770
+ newValue = newValue?.__$isObservable ? newValue.val() : newValue;
609
771
  if(this.$currentValue === newValue) {
610
772
  return;
611
773
  }
@@ -615,6 +777,30 @@ var NativeComponents = (function (exports) {
615
777
  this.$previousValue = null;
616
778
  };
617
779
 
780
+ /**
781
+ * @param {*} data
782
+ */
783
+ ObservableItem.prototype.$setWithInterceptor = function(data) {
784
+ let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
785
+ const result = this.$interceptor(newValue, this.$currentValue);
786
+
787
+ if (result !== undefined) {
788
+ newValue = result;
789
+ }
790
+
791
+ this.$updateWithNewValue(newValue);
792
+ };
793
+
794
+ /**
795
+ * @param {*} data
796
+ */
797
+ ObservableItem.prototype.$basicSet = function(data) {
798
+ let newValue = (typeof data === 'function') ? data(this.$currentValue) : data;
799
+ this.$updateWithNewValue(newValue);
800
+ };
801
+
802
+ ObservableItem.prototype.set = ObservableItem.prototype.$basicSet;
803
+
618
804
  ObservableItem.prototype.val = function() {
619
805
  return this.$currentValue;
620
806
  };
@@ -636,6 +822,16 @@ var NativeComponents = (function (exports) {
636
822
  this.trigger = noneTrigger;
637
823
  };
638
824
 
825
+ /**
826
+ * Registers a cleanup callback that will be executed when the observable is cleaned up.
827
+ * Useful for disposing resources, removing event listeners, or other cleanup tasks.
828
+ *
829
+ * @param {Function} callback - Cleanup function to execute on observable disposal
830
+ * @example
831
+ * const obs = Observable(0);
832
+ * obs.onCleanup(() => console.log('Cleaned up!'));
833
+ * obs.cleanup(); // Logs: "Cleaned up!"
834
+ */
639
835
  ObservableItem.prototype.onCleanup = function(callback) {
640
836
  this.$cleanupListeners = this.$cleanupListeners ?? [];
641
837
  this.$cleanupListeners.push(callback);
@@ -650,73 +846,114 @@ var NativeComponents = (function (exports) {
650
846
  }
651
847
  MemoryManager.unregister(this.$memoryId);
652
848
  this.disconnectAll();
653
- this.$isCleanedUp = true;
654
849
  delete this.$value;
655
850
  };
656
851
 
657
852
  /**
658
853
  *
659
854
  * @param {Function} callback
660
- * @param {any} target
661
855
  * @returns {(function(): void)}
662
856
  */
663
- ObservableItem.prototype.subscribe = function(callback, target = null) {
857
+ ObservableItem.prototype.subscribe = function(callback) {
664
858
  this.$listeners = this.$listeners ?? [];
665
- if (this.$isCleanedUp) {
666
- DebugManager.warn('Observable subscription', '⚠️ Attempted to subscribe to a cleaned up observable.');
667
- return () => {};
668
- }
669
- if (typeof callback !== 'function') {
670
- throw new NativeDocumentError('Callback must be a function');
671
- }
672
859
 
673
860
  this.$listeners.push(callback);
674
861
  this.assocTrigger();
675
- return () => {
676
- this.unsubscribe(callback);
677
- this.assocTrigger();
678
- };
679
862
  };
680
863
 
864
+ /**
865
+ * Watches for a specific value and executes callback when the observable equals that value.
866
+ * Creates a watcher that only triggers when the observable changes to the specified value.
867
+ *
868
+ * @param {*} value - The value to watch for
869
+ * @param {(value) => void|ObservableItem} callback - Callback function or observable to set when value matches
870
+ * @example
871
+ * const status = Observable('idle');
872
+ * status.on('loading', () => console.log('Started loading'));
873
+ * status.on('error', isError); // Set another observable
874
+ */
681
875
  ObservableItem.prototype.on = function(value, callback) {
682
876
  this.$watchers = this.$watchers ?? new Map();
683
877
 
684
878
  let watchValueList = this.$watchers.get(value);
685
879
 
880
+ if(callback.__$isObservable) {
881
+ callback = callback.set.bind(callback);
882
+ }
883
+
686
884
  if(!watchValueList) {
885
+ watchValueList = callback;
687
886
  this.$watchers.set(value, callback);
688
- } else if(!Validator.isArray(watchValueList)) {
887
+ } else if(!Validator.isArray(watchValueList.list)) {
689
888
  watchValueList = [watchValueList, callback];
690
- this.$watchers.set(value, watchValueList);
889
+ callback = (value) => {
890
+ for(let i = 0, length = watchValueList.length; i < length; i++) {
891
+ watchValueList[i](value);
892
+ }
893
+ };
894
+ callback.list = watchValueList;
895
+ this.$watchers.set(value, callback);
691
896
  } else {
692
- watchValueList.push(callback);
897
+ watchValueList.list.push(callback);
693
898
  }
694
899
 
695
900
  this.assocTrigger();
696
- return () => {
697
- const index = watchValueList.indexOf(callback);
698
- watchValueList?.splice(index, 1);
699
- if(watchValueList.size === 1) {
700
- this.$watchers.set(value, watchValueList[0]);
701
- }
702
- else if(watchValueList.size === 0) {
703
- this.$watchers?.delete(value);
704
- watchValueList = null;
705
- }
901
+ };
902
+
903
+ /**
904
+ * Removes a watcher for a specific value. If no callback is provided, removes all watchers for that value.
905
+ *
906
+ * @param {*} value - The value to stop watching
907
+ * @param {Function} [callback] - Specific callback to remove. If omitted, removes all watchers for this value
908
+ * @example
909
+ * const status = Observable('idle');
910
+ * const handler = () => console.log('Loading');
911
+ * status.on('loading', handler);
912
+ * status.off('loading', handler); // Remove specific handler
913
+ * status.off('loading'); // Remove all handlers for 'loading'
914
+ */
915
+ ObservableItem.prototype.off = function(value, callback) {
916
+ if(!this.$watchers) return;
917
+
918
+ const watchValueList = this.$watchers.get(value);
919
+ if(!watchValueList) return;
920
+
921
+ if(!callback || !Array.isArray(watchValueList.list)) {
922
+ this.$watchers?.delete(value);
706
923
  this.assocTrigger();
707
- };
924
+ return;
925
+ }
926
+ const index = watchValueList.indexOf(callback);
927
+ watchValueList?.splice(index, 1);
928
+ if(watchValueList.length === 1) {
929
+ this.$watchers.set(value, watchValueList[0]);
930
+ }
931
+ else if(watchValueList.length === 0) {
932
+ this.$watchers?.delete(value);
933
+ }
934
+ this.assocTrigger();
708
935
  };
709
936
 
937
+ /**
938
+ * Subscribes to the observable but automatically unsubscribes after the first time the predicate matches.
939
+ *
940
+ * @param {(value) => Boolean|any} predicate - Value to match or function that returns true when condition is met
941
+ * @param {(value) => void} callback - Callback to execute when predicate matches, receives the matched value
942
+ * @example
943
+ * const status = Observable('loading');
944
+ * status.once('ready', (val) => console.log('Ready!'));
945
+ * status.once(val => val === 'error', (val) => console.log('Error occurred'));
946
+ */
710
947
  ObservableItem.prototype.once = function(predicate, callback) {
711
948
  const fn = typeof predicate === 'function' ? predicate : (v) => v === predicate;
712
949
 
713
- const unsub = this.subscribe((val) => {
950
+ const handler = (val) => {
714
951
  if (fn(val)) {
715
- unsub();
952
+ this.unsubscribe(handler);
716
953
  callback(val);
717
954
  }
718
- });
719
- return unsub;
955
+ };
956
+ this.subscribe(handler);
720
957
  };
721
958
 
722
959
  /**
@@ -724,6 +961,7 @@ var NativeComponents = (function (exports) {
724
961
  * @param {Function} callback
725
962
  */
726
963
  ObservableItem.prototype.unsubscribe = function(callback) {
964
+ if(!this.$listeners) return;
727
965
  const index = this.$listeners.indexOf(callback);
728
966
  if (index > -1) {
729
967
  this.$listeners.splice(index, 1);
@@ -740,15 +978,50 @@ var NativeComponents = (function (exports) {
740
978
  return new ObservableChecker(this, callback)
741
979
  };
742
980
 
981
+ /**
982
+ * Gets a property value from the observable's current value.
983
+ * If the property is an observable, returns its value.
984
+ *
985
+ * @param {string|number} key - Property key to retrieve
986
+ * @returns {*} The value of the property, unwrapped if it's an observable
987
+ * @example
988
+ * const user = Observable({ name: 'John', age: Observable(25) });
989
+ * user.get('name'); // 'John'
990
+ * user.get('age'); // 25 (unwrapped from observable)
991
+ */
743
992
  ObservableItem.prototype.get = function(key) {
744
993
  const item = this.$currentValue[key];
745
994
  return Validator.isObservable(item) ? item.val() : item;
746
995
  };
747
996
 
997
+ /**
998
+ * Creates an ObservableWhen that represents whether the observable equals a specific value.
999
+ * Returns an object that can be subscribed to and will emit true/false.
1000
+ *
1001
+ * @param {*} value - The value to compare against
1002
+ * @returns {ObservableWhen} An ObservableWhen instance that tracks when the observable equals the value
1003
+ * @example
1004
+ * const status = Observable('idle');
1005
+ * const isLoading = status.when('loading');
1006
+ * isLoading.subscribe(active => console.log('Loading:', active));
1007
+ * status.set('loading'); // Logs: "Loading: true"
1008
+ */
748
1009
  ObservableItem.prototype.when = function(value) {
749
1010
  return new ObservableWhen(this, value);
750
1011
  };
751
1012
 
1013
+ /**
1014
+ * Compares the observable's current value with another value or observable.
1015
+ *
1016
+ * @param {*|ObservableItem} other - Value or observable to compare against
1017
+ * @returns {boolean} True if values are equal
1018
+ * @example
1019
+ * const a = Observable(5);
1020
+ * const b = Observable(5);
1021
+ * a.equals(5); // true
1022
+ * a.equals(b); // true
1023
+ * a.equals(10); // false
1024
+ */
752
1025
  ObservableItem.prototype.equals = function(other) {
753
1026
  if(Validator.isObservable(other)) {
754
1027
  return this.$currentValue === other.$currentValue;
@@ -756,14 +1029,41 @@ var NativeComponents = (function (exports) {
756
1029
  return this.$currentValue === other;
757
1030
  };
758
1031
 
1032
+ /**
1033
+ * Converts the observable's current value to a boolean.
1034
+ *
1035
+ * @returns {boolean} The boolean representation of the current value
1036
+ * @example
1037
+ * const count = Observable(0);
1038
+ * count.toBool(); // false
1039
+ * count.set(5);
1040
+ * count.toBool(); // true
1041
+ */
759
1042
  ObservableItem.prototype.toBool = function() {
760
1043
  return !!this.$currentValue;
761
1044
  };
762
1045
 
1046
+ /**
1047
+ * Toggles the boolean value of the observable (false becomes true, true becomes false).
1048
+ *
1049
+ * @example
1050
+ * const isOpen = Observable(false);
1051
+ * isOpen.toggle(); // Now true
1052
+ * isOpen.toggle(); // Now false
1053
+ */
763
1054
  ObservableItem.prototype.toggle = function() {
764
1055
  this.set(!this.$currentValue);
765
1056
  };
766
1057
 
1058
+ /**
1059
+ * Resets the observable to its initial value.
1060
+ * Only works if the observable was created with { reset: true } config.
1061
+ *
1062
+ * @example
1063
+ * const count = Observable(0, { reset: true });
1064
+ * count.set(10);
1065
+ * count.reset(); // Back to 0
1066
+ */
767
1067
  ObservableItem.prototype.reset = function() {
768
1068
  if(!this.configs?.reset) {
769
1069
  return;
@@ -776,11 +1076,25 @@ var NativeComponents = (function (exports) {
776
1076
  this.set(resetValue);
777
1077
  };
778
1078
 
779
-
1079
+ /**
1080
+ * Returns a string representation of the observable's current value.
1081
+ *
1082
+ * @returns {string} String representation of the current value
1083
+ */
780
1084
  ObservableItem.prototype.toString = function() {
781
1085
  return String(this.$currentValue);
782
1086
  };
783
1087
 
1088
+ /**
1089
+ * Returns the primitive value of the observable (its current value).
1090
+ * Called automatically in type coercion contexts.
1091
+ *
1092
+ * @returns {*} The current value of the observable
1093
+ */
1094
+ ObservableItem.prototype.valueOf = function() {
1095
+ return this.$currentValue;
1096
+ };
1097
+
784
1098
  const DocumentObserver = {
785
1099
  mounted: new WeakMap(),
786
1100
  mountedSupposedSize: 0,
@@ -981,12 +1295,35 @@ var NativeComponents = (function (exports) {
981
1295
  return this.shadow('closed', style);
982
1296
  };
983
1297
 
1298
+ /**
1299
+ * Attaches a template binding to the element by hydrating it with the specified method.
1300
+ *
1301
+ * @param {string} methodName - Name of the hydration method to call
1302
+ * @param {BindingHydrator} bindingHydrator - Template binding with $hydrate method
1303
+ * @returns {HTMLElement} The underlying HTML element
1304
+ * @example
1305
+ * const onClick = $binder.attach((event, data) => console.log(data));
1306
+ * element.nd.attach('onClick', onClick);
1307
+ */
984
1308
  NDElement.prototype.attach = function(methodName, bindingHydrator) {
985
1309
  bindingHydrator.$hydrate(this.$element, methodName);
986
1310
  return this.$element;
987
1311
  };
988
1312
 
989
-
1313
+ /**
1314
+ * Extends the current NDElement instance with custom methods.
1315
+ * Methods are bound to the instance and available for chaining.
1316
+ *
1317
+ * @param {Object} methods - Object containing method definitions
1318
+ * @returns {this} The NDElement instance with added methods for chaining
1319
+ * @example
1320
+ * element.nd.with({
1321
+ * highlight() {
1322
+ * this.$element.style.background = 'yellow';
1323
+ * return this;
1324
+ * }
1325
+ * }).highlight().onClick(() => console.log('Clicked'));
1326
+ */
990
1327
  NDElement.prototype.with = function(methods) {
991
1328
  if (!methods || typeof methods !== 'object') {
992
1329
  throw new NativeDocumentError('extend() requires an object of methods');
@@ -1006,6 +1343,23 @@ var NativeComponents = (function (exports) {
1006
1343
  return this;
1007
1344
  };
1008
1345
 
1346
+ /**
1347
+ * Extends the NDElement prototype with new methods available to all NDElement instances.
1348
+ * Use this to add global methods to all NDElements.
1349
+ *
1350
+ * @param {Object} methods - Object containing method definitions to add to prototype
1351
+ * @returns {typeof NDElement} The NDElement constructor
1352
+ * @throws {NativeDocumentError} If methods is not an object or contains non-function values
1353
+ * @example
1354
+ * NDElement.extend({
1355
+ * fadeIn() {
1356
+ * this.$element.style.opacity = '1';
1357
+ * return this;
1358
+ * }
1359
+ * });
1360
+ * // Now all NDElements have .fadeIn() method
1361
+ * Div().nd.fadeIn();
1362
+ */
1009
1363
  NDElement.extend = function(methods) {
1010
1364
  if (!methods || typeof methods !== 'object') {
1011
1365
  throw new NativeDocumentError('NDElement.extend() requires an object of methods');
@@ -1434,7 +1788,7 @@ var NativeComponents = (function (exports) {
1434
1788
  continue;
1435
1789
  }
1436
1790
  if(value.__$isObservableWhen) {
1437
- element.classes.toggle(className, value.isMath());
1791
+ element.classes.toggle(className, value.isActive());
1438
1792
  value.subscribe((shouldAdd) => element.classes.toggle(className, shouldAdd));
1439
1793
  continue;
1440
1794
  }
@@ -1578,6 +1932,8 @@ var NativeComponents = (function (exports) {
1578
1932
  return ElementCreator.createObservableNode(null, this);
1579
1933
  };
1580
1934
 
1935
+ ObservableChecker.prototype.toNdElement = ObservableItem.prototype.toNdElement;
1936
+
1581
1937
  NDElement.prototype.toNdElement = function () {
1582
1938
  return this.$element ?? this.$build?.() ?? this.build?.() ?? null;
1583
1939
  };
@@ -1907,6 +2263,10 @@ var NativeComponents = (function (exports) {
1907
2263
  _stop(this.$element, eventName, callback);
1908
2264
  return this;
1909
2265
  };
2266
+ NDElement.prototype['onPreventStop'+eventSourceName] = function(callback = null) {
2267
+ _preventStop(this.$element, eventName, callback);
2268
+ return this;
2269
+ };
1910
2270
  });
1911
2271
 
1912
2272
  EVENTS_WITH_PREVENT.forEach(eventSourceName => {
@@ -1940,6 +2300,16 @@ var NativeComponents = (function (exports) {
1940
2300
  return this;
1941
2301
  };
1942
2302
 
2303
+ const _preventStop = function(element, eventName, callback) {
2304
+ const handler = (event) => {
2305
+ event.stopPropagation();
2306
+ event.preventDefault();
2307
+ callback && callback.call(element, event);
2308
+ };
2309
+ element.addEventListener(eventName, handler);
2310
+ return this;
2311
+ };
2312
+
1943
2313
 
1944
2314
 
1945
2315
  // ----------------------------------------------------------------
@@ -2050,13 +2420,14 @@ var NativeComponents = (function (exports) {
2050
2420
  };
2051
2421
 
2052
2422
  Function.prototype.errorBoundary = function(callback) {
2053
- return (...args) => {
2423
+ const handler = (...args) => {
2054
2424
  try {
2055
2425
  return this.apply(this, args);
2056
2426
  } catch(e) {
2057
- return callback(e);
2427
+ return callback(e, {caller: handler, args: args });
2058
2428
  }
2059
2429
  };
2430
+ return handler;
2060
2431
  };
2061
2432
 
2062
2433
  String.prototype.use = function(args) {
@@ -2166,6 +2537,14 @@ var NativeComponents = (function (exports) {
2166
2537
  };
2167
2538
  });
2168
2539
 
2540
+ /**
2541
+ * Removes all items from the array and triggers an update.
2542
+ *
2543
+ * @returns {boolean} True if array was cleared, false if it was already empty
2544
+ * @example
2545
+ * const items = Observable.array([1, 2, 3]);
2546
+ * items.clear(); // []
2547
+ */
2169
2548
  ObservableArray.prototype.clear = function() {
2170
2549
  if(this.$currentValue.length === 0) {
2171
2550
  return;
@@ -2175,19 +2554,42 @@ var NativeComponents = (function (exports) {
2175
2554
  return true;
2176
2555
  };
2177
2556
 
2557
+ /**
2558
+ * Returns the element at the specified index in the array.
2559
+ *
2560
+ * @param {number} index - Zero-based index of the element to retrieve
2561
+ * @returns {*} The element at the specified index
2562
+ * @example
2563
+ * const items = Observable.array(['a', 'b', 'c']);
2564
+ * items.at(1); // 'b'
2565
+ */
2178
2566
  ObservableArray.prototype.at = function(index) {
2179
2567
  return this.$currentValue[index];
2180
2568
  };
2181
2569
 
2570
+
2571
+ /**
2572
+ * Merges multiple values into the array and triggers an update.
2573
+ * Similar to push but with a different operation name.
2574
+ *
2575
+ * @param {Array} values - Array of values to merge
2576
+ * @example
2577
+ * const items = Observable.array([1, 2]);
2578
+ * items.merge([3, 4]); // [1, 2, 3, 4]
2579
+ */
2182
2580
  ObservableArray.prototype.merge = function(values) {
2183
2581
  this.$currentValue.push.apply(this.$currentValue, values);
2184
2582
  this.trigger({ action: 'merge', args: values });
2185
2583
  };
2186
2584
 
2187
2585
  /**
2586
+ * Counts the number of elements that satisfy the provided condition.
2188
2587
  *
2189
- * @param {Function} condition
2190
- * @returns {number}
2588
+ * @param {(value: *, index: number) => Boolean} condition - Function that tests each element (item, index) => boolean
2589
+ * @returns {number} The count of elements that satisfy the condition
2590
+ * @example
2591
+ * const numbers = Observable.array([1, 2, 3, 4, 5]);
2592
+ * numbers.count(n => n > 3); // 2
2191
2593
  */
2192
2594
  ObservableArray.prototype.count = function(condition) {
2193
2595
  let count = 0;
@@ -2199,6 +2601,16 @@ var NativeComponents = (function (exports) {
2199
2601
  return count;
2200
2602
  };
2201
2603
 
2604
+ /**
2605
+ * Swaps two elements at the specified indices and triggers an update.
2606
+ *
2607
+ * @param {number} indexA - Index of the first element
2608
+ * @param {number} indexB - Index of the second element
2609
+ * @returns {boolean} True if swap was successful, false if indices are out of bounds
2610
+ * @example
2611
+ * const items = Observable.array(['a', 'b', 'c']);
2612
+ * items.swap(0, 2); // ['c', 'b', 'a']
2613
+ */
2202
2614
  ObservableArray.prototype.swap = function(indexA, indexB) {
2203
2615
  const value = this.$currentValue;
2204
2616
  const length = value.length;
@@ -2219,6 +2631,15 @@ var NativeComponents = (function (exports) {
2219
2631
  return true;
2220
2632
  };
2221
2633
 
2634
+ /**
2635
+ * Removes the element at the specified index and triggers an update.
2636
+ *
2637
+ * @param {number} index - Index of the element to remove
2638
+ * @returns {Array} Array containing the removed element, or empty array if index is invalid
2639
+ * @example
2640
+ * const items = Observable.array(['a', 'b', 'c']);
2641
+ * items.remove(1); // ['b'] - Array is now ['a', 'c']
2642
+ */
2222
2643
  ObservableArray.prototype.remove = function(index) {
2223
2644
  const deleted = this.$currentValue.splice(index, 1);
2224
2645
  if(deleted.length === 0) {
@@ -2228,20 +2649,60 @@ var NativeComponents = (function (exports) {
2228
2649
  return deleted;
2229
2650
  };
2230
2651
 
2652
+ /**
2653
+ * Removes the first occurrence of the specified item from the array.
2654
+ *
2655
+ * @param {*} item - The item to remove
2656
+ * @returns {Array} Array containing the removed element, or empty array if item not found
2657
+ * @example
2658
+ * const items = Observable.array(['a', 'b', 'c']);
2659
+ * items.removeItem('b'); // ['b'] - Array is now ['a', 'c']
2660
+ */
2231
2661
  ObservableArray.prototype.removeItem = function(item) {
2232
2662
  const indexOfItem = this.$currentValue.indexOf(item);
2663
+ if(indexOfItem === -1) {
2664
+ return [];
2665
+ }
2233
2666
  return this.remove(indexOfItem);
2234
2667
  };
2235
2668
 
2669
+ /**
2670
+ * Checks if the array is empty.
2671
+ *
2672
+ * @returns {boolean} True if array has no elements
2673
+ * @example
2674
+ * const items = Observable.array([]);
2675
+ * items.isEmpty(); // true
2676
+ */
2236
2677
  ObservableArray.prototype.isEmpty = function() {
2237
2678
  return this.$currentValue.length === 0;
2238
2679
  };
2239
2680
 
2681
+ /**
2682
+ * Triggers a populate operation with the current array, iteration count, and callback.
2683
+ * Used internally for rendering optimizations.
2684
+ *
2685
+ * @param {number} iteration - Iteration count for rendering
2686
+ * @param {Function} callback - Callback function for rendering items
2687
+ */
2240
2688
  ObservableArray.prototype.populateAndRender = function(iteration, callback) {
2241
2689
  this.trigger({ action: 'populate', args: [this.$currentValue, iteration, callback] });
2242
2690
  };
2243
2691
 
2244
2692
 
2693
+ /**
2694
+ * Creates a filtered view of the array based on predicates.
2695
+ * The filtered array updates automatically when source data or predicates change.
2696
+ *
2697
+ * @param {Object} predicates - Object mapping property names to filter conditions or functions
2698
+ * @returns {ObservableArray} A new observable array containing filtered items
2699
+ * @example
2700
+ * const users = Observable.array([
2701
+ * { name: 'John', age: 25 },
2702
+ * { name: 'Jane', age: 30 }
2703
+ * ]);
2704
+ * const adults = users.where({ age: (val) => val >= 18 });
2705
+ */
2245
2706
  ObservableArray.prototype.where = function(predicates) {
2246
2707
  const sourceArray = this;
2247
2708
  const observableDependencies = [sourceArray];
@@ -2290,6 +2751,20 @@ var NativeComponents = (function (exports) {
2290
2751
  return viewArray;
2291
2752
  };
2292
2753
 
2754
+ /**
2755
+ * Creates a filtered view where at least one of the specified fields matches the filter.
2756
+ *
2757
+ * @param {Array<string>} fields - Array of field names to check
2758
+ * @param {FilterResult} filter - Filter condition with callback and dependencies
2759
+ * @returns {ObservableArray} A new observable array containing filtered items
2760
+ * @example
2761
+ * const products = Observable.array([
2762
+ * { name: 'Apple', category: 'Fruit' },
2763
+ * { name: 'Carrot', category: 'Vegetable' }
2764
+ * ]);
2765
+ * const searchTerm = Observable('App');
2766
+ * const filtered = products.whereSome(['name', 'category'], match(searchTerm));
2767
+ */
2293
2768
  ObservableArray.prototype.whereSome = function(fields, filter) {
2294
2769
  return this.where({
2295
2770
  _: {
@@ -2299,6 +2774,20 @@ var NativeComponents = (function (exports) {
2299
2774
  });
2300
2775
  };
2301
2776
 
2777
+ /**
2778
+ * Creates a filtered view where all specified fields match the filter.
2779
+ *
2780
+ * @param {Array<string>} fields - Array of field names to check
2781
+ * @param {FilterResult} filter - Filter condition with callback and dependencies
2782
+ * @returns {ObservableArray} A new observable array containing filtered items
2783
+ * @example
2784
+ * const items = Observable.array([
2785
+ * { status: 'active', verified: true },
2786
+ * { status: 'active', verified: false }
2787
+ * ]);
2788
+ * const activeFilter = equals('active');
2789
+ * const filtered = items.whereEvery(['status', 'verified'], activeFilter);
2790
+ */
2302
2791
  ObservableArray.prototype.whereEvery = function(fields, filter) {
2303
2792
  return this.where({
2304
2793
  _: {
@@ -2309,10 +2798,19 @@ var NativeComponents = (function (exports) {
2309
2798
  };
2310
2799
 
2311
2800
  /**
2801
+ * Creates an observable array with reactive array methods.
2802
+ * All mutations trigger updates automatically.
2312
2803
  *
2313
- * @param {Array} target
2314
- * @param {{propagation: boolean, deep: boolean, reset: boolean}|null} configs
2315
- * @returns {ObservableArray}
2804
+ * @param {Array} [target=[]] - Initial array value
2805
+ * @param {Object|null} [configs=null] - Configuration options
2806
+ * // @param {boolean} [configs.propagation=true] - Whether to propagate changes to parent observables
2807
+ * // @param {boolean} [configs.deep=false] - Whether to make nested objects observable
2808
+ * @param {boolean} [configs.reset=false] - Whether to store initial value for reset()
2809
+ * @returns {ObservableArray} An observable array with reactive methods
2810
+ * @example
2811
+ * const items = Observable.array([1, 2, 3]);
2812
+ * items.push(4); // Triggers update
2813
+ * items.subscribe((arr) => console.log(arr));
2316
2814
  */
2317
2815
  Observable.array = function(target = [], configs = null) {
2318
2816
  return new ObservableArray(target, configs);
@@ -2377,10 +2875,26 @@ var NativeComponents = (function (exports) {
2377
2875
  };
2378
2876
 
2379
2877
  /**
2878
+ * Creates an observable proxy for an object where each property becomes an observable.
2879
+ * Properties can be accessed directly or via getter methods.
2380
2880
  *
2381
- * @param {Object} initialValue
2382
- * @param {{propagation: boolean, deep: boolean, reset: boolean}|null} configs
2383
- * @returns {Proxy}
2881
+ * @param {Object} initialValue - Initial object value
2882
+ * @param {Object|null} [configs=null] - Configuration options
2883
+ * // @param {boolean} [configs.propagation=true] - Whether changes propagate to parent
2884
+ * @param {boolean} [configs.deep=false] - Whether to make nested objects observable
2885
+ * @param {boolean} [configs.reset=false] - Whether to enable reset() method
2886
+ * @returns {ObservableProxy} A proxy where each property is an observable
2887
+ * @example
2888
+ * const user = Observable.init({
2889
+ * name: 'John',
2890
+ * age: 25,
2891
+ * address: { city: 'NYC' }
2892
+ * }, { deep: true });
2893
+ *
2894
+ * user.name.val(); // 'John'
2895
+ * user.name.set('Jane');
2896
+ * user.name = 'Jane X'
2897
+ * user.age.subscribe(val => console.log('Age:', val));
2384
2898
  */
2385
2899
  Observable.init = function(initialValue, configs = null) {
2386
2900
  const data = {};
@@ -2528,11 +3042,24 @@ var NativeComponents = (function (exports) {
2528
3042
  Observable.json = Observable.init;
2529
3043
 
2530
3044
  /**
3045
+ * Creates a computed observable that automatically updates when its dependencies change.
3046
+ * The callback is re-executed whenever any dependency observable changes.
2531
3047
  *
2532
- * @param {Function} callback
2533
- * @param {Array|Function} dependencies
2534
- * @returns {ObservableItem}
2535
- */
3048
+ * @param {Function} callback - Function that returns the computed value
3049
+ * @param {Array<ObservableItem|ObservableChecker|ObservableProxy>|Function} [dependencies=[]] - Array of observables to watch, or batch function
3050
+ * @returns {ObservableItem} A new observable that updates automatically
3051
+ * @example
3052
+ * const firstName = Observable('John');
3053
+ * const lastName = Observable('Doe');
3054
+ * const fullName = Observable.computed(
3055
+ * () => `${firstName.val()} ${lastName.val()}`,
3056
+ * [firstName, lastName]
3057
+ * );
3058
+ *
3059
+ * // With batch function
3060
+ * const batch = Observable.batch(() => { ... });
3061
+ * const computed = Observable.computed(() => { ... }, batch);
3062
+ */
2536
3063
  Observable.computed = function(callback, dependencies = []) {
2537
3064
  const initialValue = callback();
2538
3065
  const observable = new ObservableItem(initialValue);
@@ -2688,6 +3215,11 @@ var NativeComponents = (function (exports) {
2688
3215
 
2689
3216
  HtmlElementWrapper('');
2690
3217
 
3218
+ /**
3219
+ * Represents an individual item within an Accordion component
3220
+ * @param {{ id?: string|number, title?: string, icon?: string, collapsible?: boolean, content?: ValidChildren, renderHeader?: Function, renderContent?: Function, render?: Function, expanded?: Observable<boolean>, disabled?: boolean }} config - Configuration object
3221
+ * @class
3222
+ */
2691
3223
  function AccordionItem(config = {}) {
2692
3224
  if(!(this instanceof AccordionItem)){
2693
3225
  return new AccordionItem()
@@ -2710,42 +3242,81 @@ var NativeComponents = (function (exports) {
2710
3242
 
2711
3243
  BaseComponent.extends(AccordionItem);
2712
3244
 
3245
+ /**
3246
+ * Gets the id of the accordion item
3247
+ * @type {string}
3248
+ */
2713
3249
  Object.defineProperty(AccordionItem.prototype, 'id', {
2714
3250
  get() {
2715
3251
  this.$description.id;
2716
3252
  }
2717
3253
  });
2718
3254
 
3255
+ /**
3256
+ * Sets the identifier for the accordion item
3257
+ * @param {string|number} id - The unique identifier
3258
+ * @returns {AccordionItem}
3259
+ */
2719
3260
  AccordionItem.prototype.identifyBy = function(id) {
2720
3261
  this.$description.id = id;
2721
3262
  return this;
2722
3263
  };
2723
3264
 
3265
+ /**
3266
+ * Sets the content of the accordion item
3267
+ * @param {ValidChildren} content - The content to display
3268
+ * @returns {AccordionItem}
3269
+ */
2724
3270
  AccordionItem.prototype.content = function(content) {
2725
3271
  this.$description.content = content;
2726
3272
  return this;
2727
3273
  };
2728
3274
 
3275
+ /**
3276
+ * Sets the title of the accordion item
3277
+ * @param {ValidChildren} title
3278
+ * @returns {AccordionItem}
3279
+ */
2729
3280
  AccordionItem.prototype.title = function(title) {
2730
3281
  this.$description.title = title;
2731
3282
  return this;
2732
3283
  };
2733
3284
 
3285
+ /**
3286
+ * Sets the icon for the accordion item
3287
+ * @param {ValidChildren} icon - The icon identifier or element
3288
+ * @returns {AccordionItem}
3289
+ */
2734
3290
  AccordionItem.prototype.icon = function(icon) {
2735
3291
  this.$description.icon = icon;
2736
3292
  return this;
2737
3293
  };
2738
3294
 
3295
+ /**
3296
+ * Shows or hides the expansion indicator
3297
+ * @param {boolean} [show=true] - Whether to show the indicator
3298
+ * @returns {AccordionItem}
3299
+ */
2739
3300
  AccordionItem.prototype.showIndicator = function(show = true) {
2740
3301
  this.$description.showIndicator = show;
2741
3302
  return this;
2742
3303
  };
2743
3304
 
3305
+ /**
3306
+ * Sets whether the item can be collapsed
3307
+ * @param {boolean} [collapsible=true] - Whether the item is collapsible
3308
+ * @returns {AccordionItem}
3309
+ */
2744
3310
  AccordionItem.prototype.collapsible = function(collapsible = true) {
2745
3311
  this.$description.collapsible = collapsible;
2746
3312
  return this;
2747
3313
  };
2748
3314
 
3315
+ /**
3316
+ * Expands or collapses the accordion item
3317
+ * @param {boolean} [expanded=true] - Whether to expand the item
3318
+ * @returns {AccordionItem}
3319
+ */
2749
3320
  AccordionItem.prototype.expanded = function(expanded = true) {
2750
3321
  this.$description.expanded.set(expanded);
2751
3322
  if (this.$description.expanded.val()) {
@@ -2756,62 +3327,113 @@ var NativeComponents = (function (exports) {
2756
3327
  return this;
2757
3328
  };
2758
3329
 
3330
+ /**
3331
+ * Toggles the expanded state of the accordion item
3332
+ * @returns {AccordionItem}
3333
+ */
2759
3334
  AccordionItem.prototype.toggle = function() {
2760
3335
  return this.expanded(!this.$description.expanded.val());
2761
3336
  };
2762
3337
 
3338
+
3339
+ /**
3340
+ * Sets the disabled state of the accordion item
3341
+ * @param {boolean} [disabled=true] - Whether the item is disabled
3342
+ * @returns {AccordionItem}
3343
+ */
2763
3344
  AccordionItem.prototype.disabled = function(disabled = true) {
2764
3345
  this.$description.disabled = disabled;
2765
3346
  return this;
2766
3347
  };
2767
3348
 
3349
+ /**
3350
+ * Checks if the accordion item is currently expanded
3351
+ * @returns {boolean}
3352
+ */
2768
3353
  AccordionItem.prototype.isExpanded = function() {
2769
3354
  return this.$description.expanded.val();
2770
3355
  };
3356
+
3357
+ /**
3358
+ * Registers a handler for the expand event
3359
+ * @param {Function} handler - The event handler
3360
+ * @returns {AccordionItem}
3361
+ */
2771
3362
  AccordionItem.prototype.onExpand = function(handler) {
2772
3363
  this.on('expand', handler );
2773
3364
  return this;
2774
3365
  };
2775
3366
 
3367
+ /**
3368
+ * Registers a handler for the collapse event
3369
+ * @param {Function} handler - The event handler
3370
+ * @returns {AccordionItem}
3371
+ */
2776
3372
  AccordionItem.prototype.onCollapse = function(handler) {
2777
3373
  this.on('collapse', handler);
2778
3374
  return this;
2779
3375
  };
2780
3376
 
3377
+ /**
3378
+ * Sets the header render function
3379
+ * @param {Function} renderFn - Function to render the header
3380
+ * @returns {AccordionItem}
3381
+ */
2781
3382
  AccordionItem.prototype.renderHeader = function(renderFn) {
2782
3383
  this.$description.renderHeader = renderFn;
2783
3384
  return this;
2784
3385
  };
2785
3386
 
3387
+ /**
3388
+ * Sets the content render function
3389
+ * @param {Function} renderFn - Function to render the content
3390
+ * @returns {AccordionItem}
3391
+ */
2786
3392
  AccordionItem.prototype.renderContent = function(renderFn) {
2787
3393
  this.$description.renderContent = renderFn;
2788
3394
  };
2789
3395
 
3396
+ /**
3397
+ * Sets the indicator render function
3398
+ * @param {Function} renderFn - Function to render the indicator
3399
+ * @returns {AccordionItem}
3400
+ */
2790
3401
  AccordionItem.prototype.renderIndicator = function(renderFn) {
2791
3402
  this.$description.renderIndicator = renderFn;
2792
3403
  return this;
2793
3404
  };
2794
3405
 
3406
+ /**
3407
+ * Sets the render function for the entire item
3408
+ * @param {Function} renderFn - Function to render the item
3409
+ * @returns {AccordionItem}
3410
+ */
2795
3411
  AccordionItem.prototype.render = function(renderFn) {
2796
3412
  this.$description.render = renderFn;
2797
3413
  return this;
2798
3414
  };
2799
3415
 
3416
+ /**
3417
+ * Builds the accordion item component
3418
+ * @private
3419
+ */
2800
3420
  AccordionItem.prototype.$build = function() {
2801
3421
 
2802
3422
  };
2803
3423
 
2804
- AccordionItem.prototype.toNdElement = function() {
2805
-
2806
- };
2807
-
3424
+ /**
3425
+ * Component for displaying alert messages with various styles and variants
3426
+ * @param {ValidChildren} message - The alert message content
3427
+ * @param {{ title?: ValidChildren, content?: ValidChildren, outline?: boolean, style?: string, variant?: string, closable?: boolean, autoDismiss?: number, icon?: ValidChildren, showIcon?: boolean }} config - Configuration object
3428
+ * @class
3429
+ */
2808
3430
  function Alert(message, config = {}) {
2809
3431
  if(!(this instanceof Alert)) {
2810
3432
  return new Alert(message, config);
2811
3433
  }
2812
3434
  this.$description = {
2813
3435
  title: null,
2814
- content: null,
3436
+ content: message,
2815
3437
  outline: null,
2816
3438
  style: null,
2817
3439
  variant: 'info',
@@ -2828,139 +3450,299 @@ var NativeComponents = (function (exports) {
2828
3450
  Alert.defaultButtonsTemplate = null;
2829
3451
  Alert.defaultContentTemplate = null;
2830
3452
 
2831
- Alert.use = function(template) {};
3453
+ /**
3454
+ * Sets the default template for all Alert instances
3455
+ * @param {{alert: (alert: Alert) => ValidChildren, alertContent: (alert: Alert) => ValidChildren, alertButtons: (alert: Alert) => ValidChildren, alertTitle: (alert: Alert) => ValidChildren}} template - Template object containing alert factory function
3456
+ */
3457
+ Alert.use = function(template) {
3458
+ Alert.defaultTemplate = template.alert;
3459
+ Alert.defaultTitleTemplate = template.alertTitle;
3460
+ Alert.defaultButtonsTemplate = template.alertButtons;
3461
+ Alert.defaultContentTemplate = template.alertContent;
3462
+ };
2832
3463
 
2833
3464
  BaseComponent.extends(Alert, EventEmitter);
2834
3465
 
3466
+ /**
3467
+ * Sets the variant style for the alert
3468
+ * @param {string} variant - The variant name (info, success, warning, error, danger)
3469
+ * @returns {Alert}
3470
+ */
2835
3471
  Alert.prototype.variant = function(variant) {
2836
3472
  this.$description.variant = variant;
2837
3473
  return this;
2838
3474
  };
2839
3475
 
3476
+ /**
3477
+ * Sets the alert variant to 'info'
3478
+ * @returns {Alert}
3479
+ */
2840
3480
  Alert.prototype.info = function() {
2841
3481
  return this.variant('info');
2842
3482
  };
3483
+
3484
+ /**
3485
+ * Sets the alert variant to 'success'
3486
+ * @returns {Alert}
3487
+ */
2843
3488
  Alert.prototype.success = function() {
2844
3489
  return this.variant('success');
2845
3490
  };
3491
+
3492
+ /**
3493
+ * Sets the alert variant to 'warning'
3494
+ * @returns {Alert}
3495
+ */
2846
3496
  Alert.prototype.warning = function() {
2847
3497
  return this.variant('warning');
2848
3498
  };
3499
+
3500
+ /**
3501
+ * Sets the alert variant to 'error'
3502
+ * @returns {Alert}
3503
+ */
2849
3504
  Alert.prototype.error = function() {
2850
3505
  return this.variant('error');
2851
3506
  };
3507
+
3508
+ /**
3509
+ * Sets the alert variant to 'danger'
3510
+ * @returns {Alert}
3511
+ */
2852
3512
  Alert.prototype.danger = function() {
2853
3513
  return this.variant('danger');
2854
3514
  };
2855
3515
 
3516
+ /**
3517
+ * Sets the style type for the alert
3518
+ * @param {string} style - The style name (filled, bordered, outline)
3519
+ * @returns {Alert}
3520
+ */
2856
3521
  Alert.prototype.style = function(style) {
2857
3522
  this.$description.style = style;
2858
3523
  return this;
2859
3524
  };
3525
+
3526
+ /**
3527
+ * Sets the alert style to 'filled'
3528
+ * @returns {Alert}
3529
+ */
2860
3530
  Alert.prototype.filled = function() {
2861
3531
  return this.style('filled');
2862
3532
  };
3533
+
3534
+ /**
3535
+ * Sets the alert style to 'bordered'
3536
+ * @returns {Alert}
3537
+ */
2863
3538
  Alert.prototype.bordered = function() {
2864
3539
  return this.style('bordered');
2865
3540
  };
3541
+
3542
+ /**
3543
+ * Sets the alert style to 'outline'
3544
+ * @param {boolean} [outline=true] - Whether to use outline style
3545
+ * @returns {Alert}
3546
+ */
2866
3547
  Alert.prototype.outline = function(outline = true) {
2867
3548
  return this.style('outline');
2868
3549
  };
2869
3550
 
3551
+ /**
3552
+ * Sets the title of the alert
3553
+ * @param {ValidChildren} title - The title content
3554
+ * @returns {Alert}
3555
+ */
2870
3556
  Alert.prototype.title = function(title) {
2871
3557
  this.$description.title = title;
2872
3558
  return this;
2873
3559
  };
3560
+
3561
+ /**
3562
+ * Sets the content of the alert
3563
+ * @param {ValidChildren} content - The content to display
3564
+ * @returns {Alert}
3565
+ */
2874
3566
  Alert.prototype.content = function(content) {
2875
3567
  this.$description.content = content;
2876
3568
  return this;
2877
3569
  };
2878
3570
 
3571
+ /**
3572
+ * Sets the title render function
3573
+ * @param {Function} callback - Function to render the title
3574
+ * @returns {Alert}
3575
+ */
2879
3576
  Alert.prototype.renderTitle = function(callback) {
2880
3577
  this.$description.renderTitle = callback;
2881
3578
  return this;
2882
3579
  };
3580
+
3581
+ /**
3582
+ * Sets the content render function
3583
+ * @param {Function} callback - Function to render the content
3584
+ * @returns {Alert}
3585
+ */
2883
3586
  Alert.prototype.renderContent = function(callback) {
2884
3587
  this.$description.renderContent = callback;
2885
3588
  return this;
2886
3589
  };
3590
+
3591
+ /**
3592
+ * Clears all actions from the alert
3593
+ * @returns {Alert}
3594
+ */
2887
3595
  Alert.prototype.renderFooter = function(callback) {
2888
3596
  this.$description.renderFooter = callback;
2889
3597
  return this;
2890
3598
  };
2891
3599
 
3600
+ /**
3601
+ * Adds an action button to the alert
3602
+ * @param {string} label - The button label
3603
+ * @param {Function} handler - The click handler
3604
+ * @returns {Alert}
3605
+ */
2892
3606
  Alert.prototype.clearActions = function(label, handler) {
2893
3607
  this.$description.actions = [];
2894
3608
  return this;
2895
3609
  };
2896
3610
 
3611
+ /**
3612
+ * Adds an action button to the alert
3613
+ * @param {string} label - The button label
3614
+ * @param {Function} handler - The click handler
3615
+ * @returns {Alert}
3616
+ */
2897
3617
  Alert.prototype.action = function(label, handler) {
2898
3618
  this.$description.actions.push({label, handler});
2899
3619
  return this;
2900
3620
  };
2901
3621
 
3622
+ /**
3623
+ * Sets the layout function for the alert
3624
+ * @param {Function} layoutFn - Function to layout the alert
3625
+ * @returns {Alert}
3626
+ */
2902
3627
  Alert.prototype.layout = function(layoutFn) {
2903
3628
  this.$description.layout = layoutFn;
2904
3629
  return this;
2905
3630
  };
2906
3631
 
3632
+ /**
3633
+ * Sets the icon for the alert
3634
+ * @param {ValidChildren} icon - The icon to display
3635
+ * @returns {Alert}
3636
+ */
2907
3637
  Alert.prototype.icon = function(icon) {
2908
3638
  this.$description.icon = icon;
2909
3639
  return this;
2910
3640
  };
2911
3641
 
3642
+ /**
3643
+ * Shows or hides the icon
3644
+ * @param {boolean} [show=true] - Whether to show the icon
3645
+ * @returns {Alert}
3646
+ */
2912
3647
  Alert.prototype.showIcon = function(show = true) {
2913
3648
  this.$description.showIcon = show;
2914
3649
  };
2915
3650
 
3651
+ /**
3652
+ * Sets whether the alert can be closed
3653
+ * @param {boolean} [closable=true] - Whether the alert is closable
3654
+ * @returns {Alert}
3655
+ */
2916
3656
  Alert.prototype.closable = function(closable = true) {
2917
3657
  this.$description.closable = closable;
2918
3658
  return this;
2919
3659
  };
2920
3660
 
3661
+ /**
3662
+ * Sets whether the alert is dismissible (alias for closable)
3663
+ * @param {boolean} [dismissible=true] - Whether the alert is dismissible
3664
+ * @returns {Alert}
3665
+ */
2921
3666
  Alert.prototype.dismissible = function(dismissible = true) {
2922
3667
  return this.closable(dismissible);
2923
3668
  };
3669
+
3670
+ /**
3671
+ * Sets auto-dismiss delay for the alert
3672
+ * @param {number} delay - Delay in milliseconds before auto-dismissing
3673
+ * @returns {Alert}
3674
+ */
2924
3675
  Alert.prototype.autoDismiss = function(delay) {
2925
3676
  this.$description.autoDismiss = delay;
2926
3677
  return this;
2927
3678
  };
2928
3679
 
2929
-
2930
-
3680
+ /**
3681
+ * Closes the alert
3682
+ */
2931
3683
  Alert.prototype.close = function() {
2932
3684
 
2933
3685
  };
2934
3686
 
3687
+ /**
3688
+ * Shows the alert
3689
+ */
2935
3690
  Alert.prototype.show = function() {
2936
3691
 
2937
3692
  };
2938
3693
 
3694
+ /**
3695
+ * Hides the alert
3696
+ */
2939
3697
  Alert.prototype.hide = function() {
2940
3698
 
2941
3699
  };
2942
3700
 
3701
+ /**
3702
+ * Registers a handler for the close event
3703
+ * @param {(element: Alert) => void} handler - The event handler
3704
+ * @returns {Alert}
3705
+ */
2943
3706
  Alert.prototype.onClose = function(handler) {
2944
3707
  this.on('close', handler);
2945
3708
  return this;
2946
3709
  };
3710
+
3711
+ /**
3712
+ * Registers a handler for the show event
3713
+ * @param {(element: Alert) => void} handler - The event handler
3714
+ * @returns {Alert}
3715
+ */
2947
3716
  Alert.prototype.onShow = function(handler) {
2948
3717
  this.on('show', handler);
2949
3718
  return this;
2950
3719
  };
2951
3720
 
3721
+ /**
3722
+ * Sets the render function for the entire alert
3723
+ * @param {(alert: Alert, sections: {title: ValidChildren, content: ValidChildren, footer: ValidChildren, icon: ValidChildren}) => ValidChildren} renderFn - Function to render the alert
3724
+ * @returns {Alert}
3725
+ */
2952
3726
  Alert.prototype.render = function(renderFn) {
2953
3727
  this.$description.render = renderFn;
2954
3728
  return this;
2955
3729
  };
3730
+
2956
3731
  Alert.prototype.$build = function() {
2957
3732
 
2958
3733
  };
3734
+
2959
3735
  Alert.prototype.toNdElement = function() {};
2960
3736
 
3737
+ /**
3738
+ * Component for displaying user avatars with images, initials, or icons
3739
+ * @param {Observable<string>|string} source - The avatar source (image URL or observable)
3740
+ * @param {{ src?: Observable<string>|string, alt?: string, name?: string, initials?: string, icon?: ValidChildren, size?: string|number, shape?: string, variant?: string, color?: string, textColor?: string, status?: string, render?: Function }} config - Configuration object
3741
+ * @class
3742
+ */
2961
3743
  function Avatar(source, config = {}) {
2962
3744
  if (!(this instanceof Avatar)) {
2963
- return new Avatar(config);
3745
+ return new Avatar(source, config);
2964
3746
  }
2965
3747
 
2966
3748
  this.$description = {
@@ -2983,156 +3765,363 @@ var NativeComponents = (function (exports) {
2983
3765
  BaseComponent.extends(Avatar);
2984
3766
 
2985
3767
  Avatar.defaultTemplate = null;
2986
- Avatar.use = function(template) {};
2987
3768
 
3769
+ /**
3770
+ * Sets the default template for all Avatar instances
3771
+ * @param {{avatar: (avatar: Avatar) => ValidChildren}} template - Template object containing avatar factory function
3772
+ */
3773
+ Avatar.use = function(template) {
3774
+ Avatar.defaultTemplate = template.avatar;
3775
+ };
3776
+
3777
+ /**
3778
+ * Registers a handler for the error event
3779
+ * @param {(error: Error, avatar: Avatar) => void} handler - The event handler
3780
+ * @returns {Avatar}
3781
+ */
2988
3782
  Avatar.prototype.onError = function(handler) {};
2989
3783
 
3784
+ /**
3785
+ * Sets the source URL for the avatar image
3786
+ * @param {string} src - The image source URL
3787
+ * @returns {Avatar}
3788
+ */
2990
3789
  Avatar.prototype.src = function(src) {
2991
3790
  this.$description.src.set(src);
2992
3791
  return this;
2993
3792
  };
3793
+
3794
+ /**
3795
+ * Sets the alt text for the avatar image
3796
+ * @param {string} alt - The alt text
3797
+ * @returns {Avatar}
3798
+ */
2994
3799
  Avatar.prototype.alt = function(alt) {
2995
3800
  this.$description.alt = alt;
2996
3801
  return this;
2997
3802
  };
3803
+
3804
+ /**
3805
+ * Sets the name associated with the avatar
3806
+ * @param {string} name - The name
3807
+ * @returns {Avatar}
3808
+ */
2998
3809
  Avatar.prototype.name = function(name) {
2999
3810
  this.$description.name = name;
3000
3811
  return this;
3001
3812
  };
3813
+
3814
+ /**
3815
+ * Sets the initials to display
3816
+ * @param {string} initials - The initials text
3817
+ * @returns {Avatar}
3818
+ */
3002
3819
  Avatar.prototype.initials = function(initials) {
3003
3820
  this.$description.initials = initials;
3004
3821
  return this;
3005
3822
  };
3823
+
3824
+ /**
3825
+ * Sets the icon for the avatar
3826
+ * @param {ValidChildren} icon - The icon to display
3827
+ * @returns {Avatar}
3828
+ */
3006
3829
  Avatar.prototype.icon = function(icon) {
3007
3830
  this.$description.icon = icon;
3008
3831
  return this;
3009
3832
  };
3010
3833
 
3011
3834
  /**
3012
- * @param {string|int} size
3835
+ * Sets the size of the avatar
3836
+ * @param {string|number} size - The size value (preset name or custom value)
3013
3837
  * @returns {Avatar}
3014
3838
  */
3015
3839
  Avatar.prototype.size = function(size) {
3016
3840
  this.$description.size = size;
3017
3841
  return this;
3018
3842
  };
3843
+
3844
+ /**
3845
+ * Sets the avatar size to 'extra-small'
3846
+ * @returns {Avatar}
3847
+ */
3019
3848
  Avatar.prototype.extraSmall = function() {
3020
3849
  return this.size('extra-small');
3021
3850
  };
3851
+
3852
+ /**
3853
+ * Sets the avatar size to 'small'
3854
+ * @returns {Avatar}
3855
+ */
3022
3856
  Avatar.prototype.small = function() {
3023
3857
  return this.size('small');
3024
3858
  };
3859
+
3860
+ /**
3861
+ * Sets the avatar size to 'medium'
3862
+ * @returns {Avatar}
3863
+ */
3025
3864
  Avatar.prototype.medium = function() {
3026
3865
  return this.size('medium');
3027
3866
  };
3867
+
3868
+ /**
3869
+ * Sets the avatar size to 'large'
3870
+ * @returns {Avatar}
3871
+ */
3028
3872
  Avatar.prototype.large = function() {
3029
3873
  return this.size('large');
3030
3874
  };
3875
+
3876
+ /**
3877
+ * Sets the avatar size to 'extra-large'
3878
+ * @returns {Avatar}
3879
+ */
3031
3880
  Avatar.prototype.extraLarge = function() {
3032
3881
  return this.size('extra-large');
3033
3882
  };
3034
3883
 
3884
+ /**
3885
+ * Sets the shape of the avatar
3886
+ * @param {string} shape - The shape name (circle, square, rounded)
3887
+ * @returns {Avatar}
3888
+ */
3035
3889
  Avatar.prototype.shape = function(shape) {
3036
3890
  this.$description.shape = shape;
3037
3891
  return this;
3038
3892
  };
3893
+
3894
+ /**
3895
+ * Sets the avatar shape to 'circle'
3896
+ * @returns {Avatar}
3897
+ */
3039
3898
  Avatar.prototype.circle = function() {
3040
3899
  return this.shape('circle');
3041
3900
  };
3901
+
3902
+ /**
3903
+ * Sets the avatar shape to 'square'
3904
+ * @returns {Avatar}
3905
+ */
3042
3906
  Avatar.prototype.square = function() {
3043
3907
  return this.shape('square');
3044
3908
  };
3909
+
3910
+ /**
3911
+ * Sets the avatar shape to 'rounded'
3912
+ * @returns {Avatar}
3913
+ */
3045
3914
  Avatar.prototype.rounded = function() {
3046
3915
  return this.shape('rounded');
3047
3916
  };
3048
3917
 
3918
+ /**
3919
+ * Sets the variant style for the avatar
3920
+ * @param {string} variant - The variant name (primary, secondary, success, danger, warning, info)
3921
+ * @returns {Avatar}
3922
+ */
3049
3923
  Avatar.prototype.variant = function(variant) {
3050
3924
  this.$description.variant = variant;
3051
3925
  }; // 'primary' | 'secondary' | 'success' | etc.
3926
+
3927
+ /**
3928
+ * Sets the avatar variant to 'primary'
3929
+ * @returns {Avatar}
3930
+ */
3052
3931
  Avatar.prototype.primary = function() {
3053
3932
  return this.variant('primary');
3054
3933
  };
3934
+
3935
+ /**
3936
+ * Sets the avatar variant to 'secondary'
3937
+ * @returns {Avatar}
3938
+ */
3055
3939
  Avatar.prototype.secondary = function() {
3056
3940
  return this.variant('secondary');
3057
3941
  };
3942
+
3943
+ /**
3944
+ * Sets the avatar variant to 'success'
3945
+ * @returns {Avatar}
3946
+ */
3058
3947
  Avatar.prototype.success = function() {
3059
3948
  return this.variant('success');
3060
3949
  };
3950
+
3951
+ /**
3952
+ * Sets the avatar variant to 'danger'
3953
+ * @returns {Avatar}
3954
+ */
3061
3955
  Avatar.prototype.danger = function() {
3062
3956
  return this.variant('danger');
3063
3957
  };
3958
+
3959
+ /**
3960
+ * Sets the avatar variant to 'warning'
3961
+ * @returns {Avatar}
3962
+ */
3064
3963
  Avatar.prototype.warning = function() {
3065
3964
  return this.variant('warning');
3066
3965
  };
3966
+
3967
+ /**
3968
+ * Sets the avatar variant to 'info'
3969
+ * @returns {Avatar}
3970
+ */
3067
3971
  Avatar.prototype.info = function() {
3068
3972
  return this.variant('info');
3069
3973
  };
3974
+
3975
+ /**
3976
+ * Sets the background color of the avatar
3977
+ * @param {string} color - The color value
3978
+ * @returns {Avatar}
3979
+ */
3070
3980
  Avatar.prototype.color = function(color) {
3071
3981
  this.$description.color = color;
3072
3982
  return this;
3073
3983
  };
3984
+
3985
+ /**
3986
+ * Sets the text color of the avatar
3987
+ * @param {string} color - The color value
3988
+ * @returns {Avatar}
3989
+ */
3074
3990
  Avatar.prototype.textColor = function(color) {
3075
3991
  this.$description.textColor = color;
3076
3992
  return this;
3077
3993
  };
3078
3994
 
3995
+ /**
3996
+ * Sets the status indicator for the avatar
3997
+ * @param {string} status - The status value
3998
+ * @returns {Avatar}
3999
+ */
3079
4000
  Avatar.prototype.status = function(status) {
3080
4001
  this.$description.status = status;
3081
4002
  return this;
3082
4003
  };
4004
+
4005
+ /**
4006
+ * Sets the position of the status indicator
4007
+ * @param {string} position - The position (top-right, bottom-right, top-left, bottom-left)
4008
+ * @returns {Avatar}
4009
+ */
3083
4010
  Avatar.prototype.statusPosition = function(position) {
3084
4011
  this.$description.statusPosition = position;
3085
4012
  }; // 'top-right' | 'bottom-right' | etc.
3086
- Avatar.prototype.statusAtTopEnd = function() {
3087
- return this.statusPosition('top-end');
4013
+
4014
+ /**
4015
+ * Positions the status indicator at top-leading
4016
+ * @returns {Avatar}
4017
+ */
4018
+ Avatar.prototype.statusAtTopLeading = function() {
4019
+ return this.statusPosition('top-leading');
3088
4020
  };
3089
- Avatar.prototype.statusAtBottomEnd = function() {
3090
- return this.statusPosition('bottom-end');
4021
+
4022
+ /**
4023
+ * Positions the status indicator at bottom-leading
4024
+ * @returns {Avatar}
4025
+ */
4026
+ Avatar.prototype.statusAtBottomLeading = function() {
4027
+ return this.statusPosition('bottom-leading');
3091
4028
  };
3092
- Avatar.prototype.statusAtTopStart = function() {
3093
- return this.statusPosition('top-start');
4029
+
4030
+ /**
4031
+ * Positions the status indicator at top-trailing
4032
+ * @returns {Avatar}
4033
+ */
4034
+ Avatar.prototype.statusAtTopTrailing = function() {
4035
+ return this.statusPosition('top-trailing');
3094
4036
  };
3095
- Avatar.prototype.statusAtBottomStart = function() {
3096
- return this.statusPosition('bottom-start');
4037
+
4038
+ /**
4039
+ * Positions the status indicator at bottom-trailing
4040
+ * @returns {Avatar}
4041
+ */
4042
+ Avatar.prototype.statusAtBottomTrailing = function() {
4043
+ return this.statusPosition('bottom-trailing');
3097
4044
  };
3098
4045
 
4046
+ /**
4047
+ * Shows or hides the status indicator
4048
+ * @param {boolean} [show=true] - Whether to show the status
4049
+ * @returns {Avatar}
4050
+ */
3099
4051
  Avatar.prototype.showStatus = function(show = true) {
3100
4052
  this.$description.showStatus = show;
3101
4053
  return this;
3102
4054
  };
3103
4055
 
3104
- // Badge
4056
+ /**
4057
+ * Sets the badge content for the avatar
4058
+ * @param {ValidChildren} content - The badge content
4059
+ * @returns {Avatar}
4060
+ */
3105
4061
  Avatar.prototype.badge = function(content) {
3106
4062
  this.$description.badge = content;
3107
4063
  return this;
3108
4064
  };
4065
+
4066
+ /**
4067
+ * Sets the position of the badge
4068
+ * @param {string} position - The position (top-leading, bottom-leading, top-trailing, bottom-trailing)
4069
+ * @returns {Avatar}
4070
+ */
3109
4071
  Avatar.prototype.badgePosition = function(position) {
3110
4072
  this.$description.badgePosition = position;
3111
4073
  return this;
3112
4074
  };
3113
- Avatar.prototype.badgeAtTopEnd = function() {
3114
- return this.badgePosition('top-end');
3115
- };
3116
- Avatar.prototype.badgeAtBottomEnd = function() {
3117
- return this.badgePosition('bottom-end');
4075
+
4076
+ /**
4077
+ * Positions the badge at top-leading
4078
+ * @returns {Avatar}
4079
+ */
4080
+ Avatar.prototype.badgeAtTopLeading = function() {
4081
+ return this.badgePosition('top-leading');
3118
4082
  };
3119
- Avatar.prototype.badgeAtTopStart = function() {
3120
- return this.badgePosition('top-start');
4083
+
4084
+ /**
4085
+ * Positions the badge at bottom-leading
4086
+ * @returns {Avatar}
4087
+ */
4088
+ Avatar.prototype.badgeAtBottomLeading = function() {
4089
+ return this.badgePosition('bottom-leading');
3121
4090
  };
3122
- Avatar.prototype.badgeAtBottomStart = function() {
3123
- return this.badgePosition('bottom-start');
4091
+
4092
+ /**
4093
+ * Positions the badge at top-trailing
4094
+ * @returns {Avatar}
4095
+ */
4096
+ Avatar.prototype.badgeAtTopTrailing = function() {
4097
+ return this.badgePosition('top-trailing');
3124
4098
  };
3125
4099
 
4100
+ /**
4101
+ * Positions the badge at bottom-trailing
4102
+ * @returns {Avatar}
4103
+ */
4104
+ Avatar.prototype.badgeAtBottomTrailing = function() {
4105
+ return this.badgePosition('bottom-trailing');
4106
+ };
3126
4107
 
4108
+ /**
4109
+ * Sets the render function for the entire avatar
4110
+ * @param {(avatar: Avatar, sections: {image: ValidChildren, initials: ValidChildren, icon: ValidChildren, status: ValidChildren, badge: ValidChildren}) => ValidChildren} renderFn - Function to render the avatar
4111
+ * @returns {Avatar}
4112
+ */
3127
4113
  Avatar.prototype.render = function(renderFn) {
3128
4114
  this.$description.render = renderFn;
3129
4115
  return this;
3130
4116
  };
3131
4117
 
4118
+ /**
4119
+ * Builds the avatar component
4120
+ * @private
4121
+ */
3132
4122
  Avatar.prototype.$build = function() {
3133
4123
 
3134
4124
  };
3135
- Avatar.prototype.toNdElement = function() {};
3136
4125
 
3137
4126
  function Badge(config = {}) {
3138
4127
  if(!(this instanceof Badge)) {
@@ -3582,23 +4571,46 @@ var NativeComponents = (function (exports) {
3582
4571
  return this;
3583
4572
  };
3584
4573
 
4574
+ /**
4575
+ * Mixin for managing a collection of items with manipulation methods
4576
+ * @class
4577
+ */
3585
4578
  function HasItems() {}
3586
4579
 
4580
+ /**
4581
+ * Sets a dynamic observable array to store items
4582
+ * @param {ObservableArray?} [observableArray=null] - Observable array to use, or creates a new one if null
4583
+ * @returns {HasItems}
4584
+ */
3587
4585
  HasItems.prototype.dynamic = function(observableArray = null) {
3588
4586
  this.$description.items = observableArray || $$1.array([]);
3589
4587
  return this;
3590
4588
  };
3591
4589
 
4590
+ /**
4591
+ * Replaces all existing items with a new array of items
4592
+ * @param {Array} items - Array of new items
4593
+ * @returns {HasItems}
4594
+ */
3592
4595
  HasItems.prototype.items = function(items) {
3593
4596
  this.$description.items.splice(0, this.$description.items.length, ...items);
3594
4597
  return this;
3595
4598
  };
3596
4599
 
4600
+ /**
4601
+ * Adds an item to the collection
4602
+ * @param {*} item - The item to add
4603
+ * @returns {HasItems}
4604
+ */
3597
4605
  HasItems.prototype.item = function(item) {
3598
4606
  this.$description.items.push(item);
3599
4607
  return this;
3600
4608
  };
3601
4609
 
4610
+ /**
4611
+ * Clears all items from the collection
4612
+ * @returns {HasItems}
4613
+ */
3602
4614
  HasItems.prototype.clear = function() {
3603
4615
  const items = this.$description.items;
3604
4616
  if(Array.isArray(items)) {
@@ -3609,11 +4621,29 @@ var NativeComponents = (function (exports) {
3609
4621
  return this;
3610
4622
  };
3611
4623
 
4624
+ /**
4625
+ * Removes a specific item from the collection
4626
+ * @param {*} item - The item to remove
4627
+ * @returns {HasItems}
4628
+ */
3612
4629
  HasItems.prototype.removeItem = function(item) {
3613
- // TODO: implement this method
4630
+ const items = this.$description.items;
4631
+ if(Array.isArray(items)) {
4632
+ const index = items.indexOf(item);
4633
+ if(index > -1) {
4634
+ items.splice(index, 1);
4635
+ return this;
4636
+ }
4637
+ }
4638
+ items.removeItem(item);
3614
4639
  return this;
3615
4640
  };
3616
4641
 
4642
+ /**
4643
+ * Sets the render function for items
4644
+ * @param {(element: *) => ValidChildren} renderFn - Render function to apply
4645
+ * @returns {HasItems}
4646
+ */
3617
4647
  HasItems.prototype.render = function(renderFn) {
3618
4648
  this.$description.render = renderFn;
3619
4649
  return this;