neo.mjs 10.1.0 → 10.2.0

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 (43) hide show
  1. package/.github/RELEASE_NOTES/v10.1.1.md +13 -0
  2. package/.github/RELEASE_NOTES/v10.2.0.md +34 -0
  3. package/ServiceWorker.mjs +2 -2
  4. package/apps/covid/view/country/Gallery.mjs +1 -1
  5. package/apps/covid/view/country/Helix.mjs +1 -1
  6. package/apps/covid/view/country/Table.mjs +27 -29
  7. package/apps/portal/index.html +1 -1
  8. package/apps/portal/resources/data/blog.json +12 -0
  9. package/apps/portal/view/home/FooterContainer.mjs +1 -1
  10. package/apps/sharedcovid/view/country/Gallery.mjs +1 -1
  11. package/apps/sharedcovid/view/country/Helix.mjs +1 -1
  12. package/apps/sharedcovid/view/country/Table.mjs +22 -22
  13. package/examples/grid/bigData/ControlsContainer.mjs +14 -0
  14. package/examples/stateProvider/inline/MainContainer.mjs +1 -1
  15. package/examples/stateProvider/twoWay/MainContainer.mjs +2 -2
  16. package/examples/treeAccordion/MainContainer.mjs +1 -1
  17. package/learn/blog/v10-deep-dive-functional-components.md +107 -97
  18. package/learn/blog/v10-deep-dive-reactivity.md +3 -3
  19. package/learn/blog/v10-deep-dive-state-provider.md +42 -137
  20. package/learn/blog/v10-deep-dive-vdom-revolution.md +35 -61
  21. package/learn/blog/v10-post1-love-story.md +3 -3
  22. package/learn/gettingstarted/DescribingTheUI.md +108 -33
  23. package/learn/guides/fundamentals/ConfigSystemDeepDive.md +118 -18
  24. package/learn/guides/fundamentals/InstanceLifecycle.md +121 -84
  25. package/learn/tree.json +1 -0
  26. package/learn/tutorials/CreatingAFunctionalButton.md +179 -0
  27. package/package.json +3 -3
  28. package/src/DefaultConfig.mjs +2 -2
  29. package/src/collection/Base.mjs +8 -3
  30. package/src/data/Store.mjs +8 -3
  31. package/src/date/SelectorContainer.mjs +2 -2
  32. package/src/form/field/Base.mjs +15 -1
  33. package/src/form/field/ComboBox.mjs +5 -15
  34. package/src/functional/component/Base.mjs +26 -0
  35. package/src/functional/util/html.mjs +75 -0
  36. package/src/state/Provider.mjs +7 -4
  37. package/src/tree/Accordion.mjs +1 -1
  38. package/test/siesta/siesta.js +8 -1
  39. package/test/siesta/tests/CollectionBase.mjs +46 -0
  40. package/test/siesta/tests/form/field/AfterSetValueSequence.mjs +106 -0
  41. package/test/siesta/tests/functional/HtmlTemplateComponent.mjs +92 -0
  42. package/test/siesta/tests/state/FeedbackLoop.mjs +159 -0
  43. package/test/siesta/tests/state/Provider.mjs +56 -0
@@ -186,6 +186,62 @@ StartTest(t => {
186
186
  component.destroy();
187
187
  });
188
188
 
189
+ t.it('Two-way binding should handle nested data properties', t => {
190
+ let userEffectRuns = 0;
191
+
192
+ const component = Neo.create(MockComponent, {
193
+ stateProvider: {
194
+ data: {
195
+ user: {
196
+ name: 'initial'
197
+ }
198
+ }
199
+ },
200
+ bind: {
201
+ testConfig: { key: 'user.name', twoWay: true },
202
+ // Add a separate binding to the parent object to test reactivity bubbling
203
+ userObject: 'user'
204
+ }
205
+ });
206
+ const provider = component.getStateProvider();
207
+
208
+ // Effect to monitor changes on the parent 'user' object
209
+ const userEffect = new Neo.core.Effect(() => {
210
+ userEffectRuns++;
211
+ return provider.getData('user');
212
+ });
213
+
214
+ t.is(userEffectRuns, 1, 'User effect should run once initially');
215
+ t.is(component.testConfig, 'initial', 'Component config should be initialized from nested state provider property');
216
+ t.is(provider.getData('user.name'), 'initial', 'State provider data should be correct initially');
217
+
218
+ // 1. Update component config => should update provider state
219
+ component.testConfig = 'updated from component';
220
+
221
+ t.is(provider.getData('user.name'), 'updated from component', 'Nested state provider data should update from component config change');
222
+ t.is(userEffectRuns, 2, 'User effect should run again after nested property change (bubbling)');
223
+
224
+ // 2. Update provider state => should update component config
225
+ provider.setData('user.name', 'updated from provider');
226
+
227
+ t.is(component.testConfig, 'updated from provider', 'Component config should update from nested state provider data change');
228
+ t.is(userEffectRuns, 3, 'User effect should run again after direct state change');
229
+
230
+ // 3. Verify the parent object reference has changed
231
+ const initialUserObject = component.userObject;
232
+ provider.setData('user.name', 'another update');
233
+ const newUserObject = component.userObject;
234
+
235
+ t.is(component.testConfig, 'another update', 'Component config updated again');
236
+ t.is(provider.getData('user.name'), 'another update', 'Provider data updated again');
237
+ t.is(userEffectRuns, 4, 'User effect should run again');
238
+ t.isNot(newUserObject, initialUserObject, 'Parent user object reference should change to trigger reactivity');
239
+ t.is(newUserObject.name, 'another update', 'New user object has the correct name property');
240
+
241
+ userEffect.destroy();
242
+ component.destroy();
243
+ });
244
+
189
245
  t.it('Formulas should calculate correctly and react to dependencies', t => {
190
246
  const component = Neo.create(MockComponent, {
191
247
  stateProvider: {