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
@@ -51,6 +51,14 @@ noMutationMethods.forEach((method) => {
51
51
  };
52
52
  });
53
53
 
54
+ /**
55
+ * Removes all items from the array and triggers an update.
56
+ *
57
+ * @returns {boolean} True if array was cleared, false if it was already empty
58
+ * @example
59
+ * const items = Observable.array([1, 2, 3]);
60
+ * items.clear(); // []
61
+ */
54
62
  ObservableArray.prototype.clear = function() {
55
63
  if(this.$currentValue.length === 0) {
56
64
  return;
@@ -60,19 +68,42 @@ ObservableArray.prototype.clear = function() {
60
68
  return true;
61
69
  };
62
70
 
71
+ /**
72
+ * Returns the element at the specified index in the array.
73
+ *
74
+ * @param {number} index - Zero-based index of the element to retrieve
75
+ * @returns {*} The element at the specified index
76
+ * @example
77
+ * const items = Observable.array(['a', 'b', 'c']);
78
+ * items.at(1); // 'b'
79
+ */
63
80
  ObservableArray.prototype.at = function(index) {
64
81
  return this.$currentValue[index];
65
82
  };
66
83
 
84
+
85
+ /**
86
+ * Merges multiple values into the array and triggers an update.
87
+ * Similar to push but with a different operation name.
88
+ *
89
+ * @param {Array} values - Array of values to merge
90
+ * @example
91
+ * const items = Observable.array([1, 2]);
92
+ * items.merge([3, 4]); // [1, 2, 3, 4]
93
+ */
67
94
  ObservableArray.prototype.merge = function(values) {
68
95
  this.$currentValue.push.apply(this.$currentValue, values);
69
96
  this.trigger({ action: 'merge', args: values });
70
97
  };
71
98
 
72
99
  /**
100
+ * Counts the number of elements that satisfy the provided condition.
73
101
  *
74
- * @param {Function} condition
75
- * @returns {number}
102
+ * @param {(value: *, index: number) => Boolean} condition - Function that tests each element (item, index) => boolean
103
+ * @returns {number} The count of elements that satisfy the condition
104
+ * @example
105
+ * const numbers = Observable.array([1, 2, 3, 4, 5]);
106
+ * numbers.count(n => n > 3); // 2
76
107
  */
77
108
  ObservableArray.prototype.count = function(condition) {
78
109
  let count = 0;
@@ -84,6 +115,16 @@ ObservableArray.prototype.count = function(condition) {
84
115
  return count;
85
116
  };
86
117
 
118
+ /**
119
+ * Swaps two elements at the specified indices and triggers an update.
120
+ *
121
+ * @param {number} indexA - Index of the first element
122
+ * @param {number} indexB - Index of the second element
123
+ * @returns {boolean} True if swap was successful, false if indices are out of bounds
124
+ * @example
125
+ * const items = Observable.array(['a', 'b', 'c']);
126
+ * items.swap(0, 2); // ['c', 'b', 'a']
127
+ */
87
128
  ObservableArray.prototype.swap = function(indexA, indexB) {
88
129
  const value = this.$currentValue;
89
130
  const length = value.length;
@@ -104,6 +145,15 @@ ObservableArray.prototype.swap = function(indexA, indexB) {
104
145
  return true;
105
146
  };
106
147
 
148
+ /**
149
+ * Removes the element at the specified index and triggers an update.
150
+ *
151
+ * @param {number} index - Index of the element to remove
152
+ * @returns {Array} Array containing the removed element, or empty array if index is invalid
153
+ * @example
154
+ * const items = Observable.array(['a', 'b', 'c']);
155
+ * items.remove(1); // ['b'] - Array is now ['a', 'c']
156
+ */
107
157
  ObservableArray.prototype.remove = function(index) {
108
158
  const deleted = this.$currentValue.splice(index, 1);
109
159
  if(deleted.length === 0) {
@@ -113,20 +163,60 @@ ObservableArray.prototype.remove = function(index) {
113
163
  return deleted;
114
164
  };
115
165
 
166
+ /**
167
+ * Removes the first occurrence of the specified item from the array.
168
+ *
169
+ * @param {*} item - The item to remove
170
+ * @returns {Array} Array containing the removed element, or empty array if item not found
171
+ * @example
172
+ * const items = Observable.array(['a', 'b', 'c']);
173
+ * items.removeItem('b'); // ['b'] - Array is now ['a', 'c']
174
+ */
116
175
  ObservableArray.prototype.removeItem = function(item) {
117
176
  const indexOfItem = this.$currentValue.indexOf(item);
177
+ if(indexOfItem === -1) {
178
+ return [];
179
+ }
118
180
  return this.remove(indexOfItem);
119
181
  };
120
182
 
183
+ /**
184
+ * Checks if the array is empty.
185
+ *
186
+ * @returns {boolean} True if array has no elements
187
+ * @example
188
+ * const items = Observable.array([]);
189
+ * items.isEmpty(); // true
190
+ */
121
191
  ObservableArray.prototype.isEmpty = function() {
122
192
  return this.$currentValue.length === 0;
123
193
  };
124
194
 
195
+ /**
196
+ * Triggers a populate operation with the current array, iteration count, and callback.
197
+ * Used internally for rendering optimizations.
198
+ *
199
+ * @param {number} iteration - Iteration count for rendering
200
+ * @param {Function} callback - Callback function for rendering items
201
+ */
125
202
  ObservableArray.prototype.populateAndRender = function(iteration, callback) {
126
203
  this.trigger({ action: 'populate', args: [this.$currentValue, iteration, callback] });
127
204
  };
128
205
 
129
206
 
207
+ /**
208
+ * Creates a filtered view of the array based on predicates.
209
+ * The filtered array updates automatically when source data or predicates change.
210
+ *
211
+ * @param {Object} predicates - Object mapping property names to filter conditions or functions
212
+ * @returns {ObservableArray} A new observable array containing filtered items
213
+ * @example
214
+ * const users = Observable.array([
215
+ * { name: 'John', age: 25 },
216
+ * { name: 'Jane', age: 30 }
217
+ * ]);
218
+ * const adults = users.where({ age: (val) => val >= 18 });
219
+ */
130
220
  ObservableArray.prototype.where = function(predicates) {
131
221
  const sourceArray = this;
132
222
  const observableDependencies = [sourceArray];
@@ -175,6 +265,20 @@ ObservableArray.prototype.where = function(predicates) {
175
265
  return viewArray;
176
266
  };
177
267
 
268
+ /**
269
+ * Creates a filtered view where at least one of the specified fields matches the filter.
270
+ *
271
+ * @param {Array<string>} fields - Array of field names to check
272
+ * @param {FilterResult} filter - Filter condition with callback and dependencies
273
+ * @returns {ObservableArray} A new observable array containing filtered items
274
+ * @example
275
+ * const products = Observable.array([
276
+ * { name: 'Apple', category: 'Fruit' },
277
+ * { name: 'Carrot', category: 'Vegetable' }
278
+ * ]);
279
+ * const searchTerm = Observable('App');
280
+ * const filtered = products.whereSome(['name', 'category'], match(searchTerm));
281
+ */
178
282
  ObservableArray.prototype.whereSome = function(fields, filter) {
179
283
  return this.where({
180
284
  _: {
@@ -184,6 +288,20 @@ ObservableArray.prototype.whereSome = function(fields, filter) {
184
288
  });
185
289
  };
186
290
 
291
+ /**
292
+ * Creates a filtered view where all specified fields match the filter.
293
+ *
294
+ * @param {Array<string>} fields - Array of field names to check
295
+ * @param {FilterResult} filter - Filter condition with callback and dependencies
296
+ * @returns {ObservableArray} A new observable array containing filtered items
297
+ * @example
298
+ * const items = Observable.array([
299
+ * { status: 'active', verified: true },
300
+ * { status: 'active', verified: false }
301
+ * ]);
302
+ * const activeFilter = equals('active');
303
+ * const filtered = items.whereEvery(['status', 'verified'], activeFilter);
304
+ */
187
305
  ObservableArray.prototype.whereEvery = function(fields, filter) {
188
306
  return this.where({
189
307
  _: {
@@ -12,6 +12,16 @@ export default function ObservableChecker($observable, $checker) {
12
12
 
13
13
  ObservableChecker.prototype.__$isObservableChecker = true;
14
14
 
15
+ /**
16
+ * Subscribes to changes in the checked/transformed value.
17
+ *
18
+ * @param {Function} callback - Function called with the transformed value when observable changes
19
+ * @returns {Function} Unsubscribe function
20
+ * @example
21
+ * const count = Observable(5);
22
+ * const doubled = count.check(n => n * 2);
23
+ * doubled.subscribe(value => console.log(value)); // Logs: 10
24
+ */
15
25
  ObservableChecker.prototype.subscribe = function(callback) {
16
26
  const unSubscribe = this.observable.subscribe((value) => {
17
27
  callback && callback(this.checker(value));
@@ -20,22 +30,62 @@ ObservableChecker.prototype.subscribe = function(callback) {
20
30
  return unSubscribe;
21
31
  };
22
32
 
33
+ /**
34
+ * Creates a new ObservableChecker by applying another transformation.
35
+ * Allows chaining transformations.
36
+ *
37
+ * @param {(value: *) => *} callback - Transformation function to apply to the current checked value
38
+ * @returns {ObservableChecker} New ObservableChecker with chained transformation
39
+ * @example
40
+ * const count = Observable(5);
41
+ * const result = count.check(n => n * 2).check(n => n + 1);
42
+ * result.val(); // 11
43
+ */
23
44
  ObservableChecker.prototype.check = function(callback) {
24
45
  return this.observable.check(() => callback(this.val()));
25
46
  }
26
47
 
48
+ /**
49
+ * Gets the current transformed/checked value.
50
+ *
51
+ * @returns {*} The result of applying the checker function to the observable's current value
52
+ * @example
53
+ * const count = Observable(5);
54
+ * const doubled = count.check(n => n * 2);
55
+ * doubled.val(); // 10
56
+ */
27
57
  ObservableChecker.prototype.val = function() {
28
58
  return this.checker && this.checker(this.observable.val());
29
59
  }
30
60
 
61
+ /**
62
+ * Sets the value of the underlying observable (not the transformed value).
63
+ *
64
+ * @param {*} value - New value for the underlying observable
65
+ * @example
66
+ * const count = Observable(5);
67
+ * const doubled = count.check(n => n * 2);
68
+ * doubled.set(10); // Sets count to 10, doubled.val() returns 20
69
+ */
31
70
  ObservableChecker.prototype.set = function(value) {
32
71
  return this.observable.set(value);
33
72
  };
34
73
 
74
+ /**
75
+ * Manually triggers the underlying observable to notify subscribers.
76
+ *
77
+ * @example
78
+ * const count = Observable(5);
79
+ * const doubled = count.check(n => n * 2);
80
+ * doubled.trigger(); // Notifies all subscribers
81
+ */
35
82
  ObservableChecker.prototype.trigger = function() {
36
83
  return this.observable.trigger();
37
84
  };
38
85
 
86
+ /**
87
+ * Cleans up the underlying observable and all its subscriptions.
88
+ */
39
89
  ObservableChecker.prototype.cleanup = function() {
40
90
  return this.observable.cleanup();
41
91
  };