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
@@ -102,6 +102,89 @@ HideIf(condition, content)
102
102
  ShowIf(condition.check(val => !val), content)
103
103
  ```
104
104
 
105
+ ## ShowWhen - Observable Value Matching
106
+
107
+ `ShowWhen` is a specialized conditional function that shows content when an Observable matches a specific value. It's particularly useful for state machines and enum-based conditions.
108
+
109
+ ### Basic Usage
110
+ ```javascript
111
+ const status = Observable('idle');
112
+
113
+ // Show content when status equals 'loading'
114
+ const loadingIndicator = ShowWhen(status, 'loading',
115
+ Div({ class: 'spinner' }, 'Loading...')
116
+ );
117
+
118
+ // Show content when status equals 'success'
119
+ const successMessage = ShowWhen(status, 'success',
120
+ Div({ class: 'success' }, '✅ Success!')
121
+ );
122
+ ```
123
+
124
+ ### Two Syntax Options
125
+
126
+ **Option 1: Three arguments (Observable, value, content)**
127
+ ```javascript
128
+ const theme = Observable('light');
129
+
130
+ ShowWhen(theme, 'dark',
131
+ Div({ class: 'dark-mode-indicator' }, '🌙 Dark Mode')
132
+ );
133
+ ```
134
+
135
+ **Option 2: Two arguments (ObservableWhen result, content)**
136
+ ```javascript
137
+ const theme = Observable('light');
138
+ const isDark = theme.when('dark'); // Returns ObservableWhen
139
+
140
+ ShowWhen(isDark,
141
+ Div({ class: 'dark-mode-indicator' }, '🌙 Dark Mode')
142
+ );
143
+ ```
144
+
145
+ ### Practical Example: Status-Based UI
146
+ ```javascript
147
+ const connectionStatus = Observable('disconnected');
148
+
149
+ const StatusIndicator = Div({ class: 'status-bar' }, [
150
+ ShowWhen(connectionStatus, 'connecting',
151
+ Span({ class: 'status connecting' }, '🔄 Connecting...')
152
+ ),
153
+ ShowWhen(connectionStatus, 'connected',
154
+ Span({ class: 'status connected' }, '✅ Connected')
155
+ ),
156
+ ShowWhen(connectionStatus, 'disconnected',
157
+ Span({ class: 'status disconnected' }, '❌ Disconnected')
158
+ ),
159
+ ShowWhen(connectionStatus, 'error',
160
+ Span({ class: 'status error' }, '⚠️ Connection Error')
161
+ )
162
+ ]);
163
+
164
+ // Update status
165
+ setTimeout(() => connectionStatus.set('connecting'), 1000);
166
+ setTimeout(() => connectionStatus.set('connected'), 3000);
167
+ ```
168
+
169
+ Both can handle multiple states, but they serve different purposes:
170
+ ```javascript
171
+ const phase = Observable('loading');
172
+
173
+ // ShowWhen: Multiple independent conditions
174
+ Div([
175
+ ShowWhen(phase, 'loading', LoadingSpinner()),
176
+ ShowWhen(phase, 'success', SuccessMessage()),
177
+ ShowWhen(phase, 'error', ErrorMessage())
178
+ ]);
179
+
180
+ // Match: Single content area that switches
181
+ Match(phase, {
182
+ loading: LoadingSpinner(),
183
+ success: SuccessMessage(),
184
+ error: ErrorMessage()
185
+ });
186
+ ```
187
+
105
188
  ## Switch - Binary Content Switching
106
189
 
107
190
  `Switch` efficiently toggles between exactly two pieces of content based on a boolean condition:
@@ -627,6 +710,13 @@ Now that you understand conditional rendering, explore these related topics:
627
710
  - **[Lifecycle Events](lifecycle-events.md)** - Lifecycle events
628
711
  - **[NDElement](native-document-element.md)** - Native Document Element
629
712
  - **[Extending NDElement](extending-native-document-element.md)** - Custom Methods Guide
713
+ - **[Advanced Components](advanced-components.md)** - Template caching and singleton views
630
714
  - **[Args Validation](validation.md)** - Function Argument Validation
631
715
  - **[Memory Management](memory-management.md)** - Memory management
632
- - **[Anchor](anchor.md)** - Anchor
716
+ - **[Anchor](anchor.md)** - Anchor
717
+
718
+ ## Utilities
719
+
720
+ - **[Cache](docs/utils/cache.md)** - Lazy initialization and singleton patterns
721
+ - **[NativeFetch](docs/utils/native-fetch.md)** - HTTP client with interceptors
722
+ - **[Filters](docs/utils/filters.md)** - Data filtering helpers
@@ -376,7 +376,7 @@ function Header() {
376
376
  const user = Store.use('user');
377
377
  const theme = Store.use('theme');
378
378
 
379
- return Div({ class: `theme-${theme}` }, [
379
+ return Div({ class: theme.check(t => `theme-${t}`) }, [
380
380
  ShowIf(user.check(u => u.isLoggedIn),
381
381
  Div(['Welcome, ', user.$value.name])
382
382
  )
@@ -512,6 +512,13 @@ Now that you understand NativeDocument's core concepts, explore these advanced t
512
512
  - **[Lifecycle Events](lifecycle-events.md)** - Lifecycle events
513
513
  - **[NDElement](native-document-element.md)** - Native Document Element
514
514
  - **[Extending NDElement](extending-native-document-element.md)** - Custom Methods Guide
515
+ - **[Advanced Components](advanced-components.md)** - Template caching and singleton views
515
516
  - **[Args Validation](validation.md)** - Function Argument Validation
516
517
  - **[Memory Management](memory-management.md)** - Memory management
517
- - **[Anchor](anchor.md)** - Anchor
518
+ - **[Anchor](anchor.md)** - Anchor
519
+
520
+ ## Utilities
521
+
522
+ - **[Cache](docs/utils/cache.md)** - Lazy initialization and singleton patterns
523
+ - **[NativeFetch](docs/utils/native-fetch.md)** - HTTP client with interceptors
524
+ - **[Filters](docs/utils/filters.md)** - Data filtering helpers
package/docs/elements.md CHANGED
@@ -66,7 +66,7 @@ const theme = Observable("dark");
66
66
  const greeting = Div({
67
67
  class: theme, // Updates when theme changes
68
68
  hidden: isVisible.check(val => !val) // Hide when isVisible is false
69
- }, `Hello ${userName}!`); // Reactive text content
69
+ }, ['Hello ', userName, '!']); // Reactive text content
70
70
 
71
71
  // Reactive styles
72
72
  const box = Div({
@@ -142,6 +142,63 @@ const form = Form()
142
142
  });
143
143
  ```
144
144
 
145
+ ## Advanced Element Composition
146
+
147
+ ### Extending Elements with Custom Methods
148
+
149
+ Use `.nd.with()` to add custom methods to elements:
150
+ ```javascript
151
+ const customButton = Button("Click me")
152
+ .nd.with({
153
+ highlight() {
154
+ this.$element.style.backgroundColor = 'yellow';
155
+ return this;
156
+ },
157
+ resetStyle() {
158
+ this.$element.style.backgroundColor = '';
159
+ return this;
160
+ }
161
+ })
162
+ .highlight();
163
+
164
+ // Chain custom methods
165
+ customButton.resetStyle().highlight();
166
+ ```
167
+
168
+ ### Class and Style Accumulators
169
+
170
+ Build classes and styles programmatically:
171
+ ```javascript
172
+ import { classPropertyAccumulator, cssPropertyAccumulator } from 'native-document';
173
+
174
+ // Class accumulator
175
+ const classes = classPropertyAccumulator(['btn']);
176
+ classes.add('primary');
177
+ classes.add('large');
178
+
179
+ const button = Button({ class: classes.value() }, "Submit");
180
+ // Result: class="btn primary large"
181
+
182
+ // Or with object
183
+ const classObj = classPropertyAccumulator({ btn: true });
184
+ classObj.add('primary', true);
185
+ classObj.add('disabled', false);
186
+ console.log(classObj.value()); // { btn: true, primary: true, disabled: false }
187
+
188
+ // CSS accumulator
189
+ const styles = cssPropertyAccumulator({ color: 'red' });
190
+ styles.add('font-size', '16px');
191
+ styles.add('margin', '10px');
192
+
193
+ const element = Div({ style: styles.value() }, "Styled content");
194
+ // Result: style="color: red; font-size: 16px; margin: 10px"
195
+
196
+ // Or with array
197
+ const styleArr = cssPropertyAccumulator('color: red; font-size: 16px');
198
+ styleArr.add('margin', '10px');
199
+ console.log(styleArr.value()); // "color: red; font-size: 16px; margin: 10px;"
200
+ ```
201
+
145
202
  ## Form Elements and Two-Way Binding
146
203
 
147
204
  ```javascript
@@ -214,6 +271,34 @@ const widget = Div("Widget")
214
271
  unmounted: element => console.log("Widget unmounted")
215
272
  });
216
273
  ```
274
+ ## Manual DOM Manipulation
275
+
276
+ ### Unmounting Children
277
+
278
+ Remove all children from an element:
279
+ ```javascript
280
+ const container = Div([
281
+ P("Child 1"),
282
+ P("Child 2"),
283
+ P("Child 3")
284
+ ]);
285
+
286
+ // Remove all children
287
+ container.nd.unmountChildren();
288
+ // container is now empty but still in DOM
289
+ ```
290
+
291
+ ### Removing Elements
292
+
293
+ Remove an element from the DOM:
294
+ ```javascript
295
+ const element = Div("Content");
296
+ document.body.appendChild(element.nd.node());
297
+
298
+ // Remove from DOM
299
+ element.nd.remove();
300
+ // Element is detached from DOM
301
+ ```
217
302
 
218
303
  ## Element References
219
304
 
@@ -231,6 +316,37 @@ const app = Div([
231
316
  ]);
232
317
  ```
233
318
 
319
+ ## Shadow DOM
320
+
321
+ NativeDocument supports Shadow DOM for encapsulated components:
322
+ ```javascript
323
+ // Open shadow DOM (inspectable)
324
+ const widget = Div("Widget content")
325
+ .nd.openShadow(`
326
+ :host {
327
+ display: block;
328
+ padding: 20px;
329
+ background: #f0f0f0;
330
+ }
331
+ p { color: blue; }
332
+
333
+ `);
334
+
335
+ // Closed shadow DOM (private)
336
+ const privateWidget = Div("Private content")
337
+ .nd.closedShadow(`
338
+ p { color: red; }
339
+
340
+ `);
341
+
342
+ // Manual shadow DOM with mode
343
+ const customWidget = Div("Custom")
344
+ .nd.shadow('open', `
345
+ /* Scoped styles */
346
+
347
+ `);
348
+ ```
349
+
234
350
  ## Practical Example: Simple Button with Event
235
351
 
236
352
  ```javascript
@@ -281,6 +397,8 @@ const validateForm = () => {
281
397
 
282
398
  Observable.update(errors, newErrors);
283
399
 
400
+ errors.set(newErrors);
401
+
284
402
  return Object.values(newErrors).every(error => error === "");
285
403
  };
286
404
 
@@ -382,6 +500,13 @@ Now that you understand NativeDocument's elements, explore these advanced topics
382
500
  - **[Lifecycle Events](lifecycle-events.md)** - Lifecycle events
383
501
  - **[NDElement](native-document-element.md)** - Native Document Element
384
502
  - **[Extending NDElement](extending-native-document-element.md)** - Custom Methods Guide
503
+ - **[Advanced Components](advanced-components.md)** - Template caching and singleton views
385
504
  - **[Args Validation](validation.md)** - Function Argument Validation
386
505
  - **[Memory Management](memory-management.md)** - Memory management
387
- - **[Anchor](anchor.md)** - Anchor
506
+ - **[Anchor](anchor.md)** - Anchor
507
+
508
+ ## Utilities
509
+
510
+ - **[Cache](docs/utils/cache.md)** - Lazy initialization and singleton patterns
511
+ - **[NativeFetch](docs/utils/native-fetch.md)** - HTTP client with interceptors
512
+ - **[Filters](docs/utils/filters.md)** - Data filtering helpers
@@ -265,4 +265,10 @@ Explore these related topics to build complete applications:
265
265
 
266
266
  - **[Args Validation](validation.md)** - Function Argument Validation
267
267
  - **[Memory Management](memory-management.md)** - Memory management
268
- - **[Anchor](anchor.md)** - Anchor
268
+ - **[Anchor](anchor.md)** - Anchor
269
+
270
+ ## Utilities
271
+
272
+ - **[Cache](docs/utils/cache.md)** - Lazy initialization and singleton patterns
273
+ - **[NativeFetch](docs/utils/native-fetch.md)** - HTTP client with interceptors
274
+ - **[Filters](docs/utils/filters.md)** - Data filtering helpers