neo.mjs 10.0.0-beta.5 → 10.0.0-beta.6

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 (468) hide show
  1. package/.github/RELEASE_NOTES/v10.0.0-beta.5.md +70 -0
  2. package/.github/RELEASE_NOTES/v10.0.0-beta.6.md +48 -0
  3. package/.github/epic-functional-components.md +498 -0
  4. package/.github/ticket-asymmetric-vdom-updates.md +122 -0
  5. package/README.md +0 -3
  6. package/ServiceWorker.mjs +2 -2
  7. package/apps/colors/store/Colors.mjs +1 -0
  8. package/apps/colors/view/GridContainer.mjs +3 -0
  9. package/apps/colors/view/HeaderToolbar.mjs +2 -0
  10. package/apps/colors/view/Viewport.mjs +3 -0
  11. package/apps/covid/view/FooterContainer.mjs +3 -0
  12. package/apps/covid/view/GalleryContainer.mjs +2 -0
  13. package/apps/covid/view/GalleryContainerController.mjs +1 -0
  14. package/apps/covid/view/HeaderContainer.mjs +2 -0
  15. package/apps/covid/view/HelixContainer.mjs +2 -0
  16. package/apps/covid/view/HelixContainerController.mjs +1 -0
  17. package/apps/covid/view/MainContainer.mjs +3 -0
  18. package/apps/covid/view/TableContainer.mjs +3 -0
  19. package/apps/covid/view/TableContainerController.mjs +1 -0
  20. package/apps/covid/view/WorldMapContainer.mjs +2 -0
  21. package/apps/covid/view/country/Gallery.mjs +3 -0
  22. package/apps/covid/view/country/Helix.mjs +8 -0
  23. package/apps/covid/view/country/HistoricalDataTable.mjs +1 -0
  24. package/apps/covid/view/country/Table.mjs +2 -0
  25. package/apps/covid/view/mapboxGl/Component.mjs +1 -0
  26. package/apps/covid/view/mapboxGl/Container.mjs +2 -0
  27. package/apps/email/EPIC_PLAN.md +58 -0
  28. package/apps/email/neo-config.json +2 -2
  29. package/apps/email/store/Emails.mjs +11 -1
  30. package/apps/email/view/ComposeView.mjs +44 -0
  31. package/apps/email/view/MainView.mjs +89 -0
  32. package/apps/email/view/Viewport.mjs +4 -33
  33. package/apps/email/view/ViewportStateProvider.mjs +3 -3
  34. package/apps/form/store/SideNav.mjs +1 -0
  35. package/apps/form/view/FormContainer.mjs +1 -0
  36. package/apps/form/view/FormPageContainer.mjs +2 -0
  37. package/apps/form/view/SideNavList.mjs +1 -0
  38. package/apps/form/view/Viewport.mjs +3 -0
  39. package/apps/portal/childapps/preview/MainContainer.mjs +1 -0
  40. package/apps/portal/index.html +1 -1
  41. package/apps/portal/store/BlogPosts.mjs +2 -0
  42. package/apps/portal/store/Content.mjs +1 -0
  43. package/apps/portal/store/ContentSections.mjs +1 -0
  44. package/apps/portal/store/Examples.mjs +1 -0
  45. package/apps/portal/view/HeaderToolbar.mjs +1 -0
  46. package/apps/portal/view/Viewport.mjs +5 -0
  47. package/apps/portal/view/ViewportController.mjs +8 -2
  48. package/apps/portal/view/about/Container.mjs +2 -0
  49. package/apps/portal/view/about/MemberContainer.mjs +7 -0
  50. package/apps/portal/view/blog/Container.mjs +2 -0
  51. package/apps/portal/view/blog/List.mjs +2 -0
  52. package/apps/portal/view/examples/List.mjs +1 -0
  53. package/apps/portal/view/examples/TabContainer.mjs +4 -0
  54. package/apps/portal/view/home/ContentBox.mjs +3 -0
  55. package/apps/portal/view/home/FeatureSection.mjs +8 -0
  56. package/apps/portal/view/home/FooterContainer.mjs +4 -1
  57. package/apps/portal/view/home/MainContainer.mjs +2 -0
  58. package/apps/portal/view/home/parts/AfterMath.mjs +2 -0
  59. package/apps/portal/view/home/parts/BaseContainer.mjs +1 -0
  60. package/apps/portal/view/home/parts/Colors.mjs +4 -0
  61. package/apps/portal/view/home/parts/Features.mjs +2 -0
  62. package/apps/portal/view/home/parts/Helix.mjs +5 -0
  63. package/apps/portal/view/home/parts/How.mjs +4 -0
  64. package/apps/portal/view/home/parts/MainNeo.mjs +1 -0
  65. package/apps/portal/view/home/parts/References.mjs +2 -0
  66. package/apps/portal/view/learn/ContentComponent.mjs +11 -5
  67. package/apps/portal/view/learn/ContentTreeList.mjs +2 -0
  68. package/apps/portal/view/learn/CubeLayoutButton.mjs +1 -0
  69. package/apps/portal/view/learn/MainContainer.mjs +4 -0
  70. package/apps/portal/view/learn/PageContainer.mjs +2 -0
  71. package/apps/portal/view/learn/PageSectionsContainer.mjs +3 -0
  72. package/apps/portal/view/learn/PageSectionsList.mjs +1 -0
  73. package/apps/portal/view/services/Component.mjs +1 -0
  74. package/apps/realworld/api/Base.mjs +1 -0
  75. package/apps/realworld/view/HeaderComponent.mjs +4 -0
  76. package/apps/realworld/view/HomeComponent.mjs +7 -0
  77. package/apps/realworld/view/MainContainer.mjs +2 -0
  78. package/apps/realworld/view/MainContainerController.mjs +2 -0
  79. package/apps/realworld/view/article/CommentComponent.mjs +3 -0
  80. package/apps/realworld/view/article/Component.mjs +17 -10
  81. package/apps/realworld/view/article/CreateCommentComponent.mjs +2 -0
  82. package/apps/realworld/view/article/CreateComponent.mjs +5 -0
  83. package/apps/realworld/view/article/PreviewComponent.mjs +9 -0
  84. package/apps/realworld/view/article/TagListComponent.mjs +2 -0
  85. package/apps/realworld/view/user/ProfileComponent.mjs +7 -0
  86. package/apps/realworld/view/user/SettingsComponent.mjs +5 -0
  87. package/apps/realworld/view/user/SignUpComponent.mjs +3 -0
  88. package/apps/realworld2/api/Base.mjs +1 -0
  89. package/apps/realworld2/view/FooterComponent.mjs +1 -0
  90. package/apps/realworld2/view/HeaderToolbar.mjs +3 -0
  91. package/apps/realworld2/view/HomeContainer.mjs +1 -0
  92. package/apps/realworld2/view/MainContainer.mjs +2 -0
  93. package/apps/realworld2/view/MainContainerController.mjs +1 -0
  94. package/apps/realworld2/view/article/Helix.mjs +1 -0
  95. package/apps/realworld2/view/article/PreviewComponent.mjs +9 -0
  96. package/apps/realworld2/view/article/PreviewList.mjs +1 -0
  97. package/apps/realworld2/view/article/TagListComponent.mjs +2 -0
  98. package/apps/route/view/CenterContainer.mjs +1 -0
  99. package/apps/route/view/MainView.mjs +1 -0
  100. package/apps/sharedcovid/childapps/sharedcovidchart/MainContainer.mjs +1 -0
  101. package/apps/sharedcovid/childapps/sharedcovidgallery/MainContainer.mjs +1 -0
  102. package/apps/sharedcovid/childapps/sharedcovidhelix/MainContainer.mjs +1 -0
  103. package/apps/sharedcovid/childapps/sharedcovidmap/MainContainer.mjs +1 -0
  104. package/apps/sharedcovid/view/FooterContainer.mjs +3 -0
  105. package/apps/sharedcovid/view/GalleryContainer.mjs +2 -0
  106. package/apps/sharedcovid/view/GalleryContainerController.mjs +1 -0
  107. package/apps/sharedcovid/view/HeaderContainer.mjs +2 -0
  108. package/apps/sharedcovid/view/HelixContainer.mjs +2 -0
  109. package/apps/sharedcovid/view/HelixContainerController.mjs +1 -0
  110. package/apps/sharedcovid/view/MainContainer.mjs +3 -0
  111. package/apps/sharedcovid/view/TableContainer.mjs +3 -0
  112. package/apps/sharedcovid/view/TableContainerController.mjs +1 -0
  113. package/apps/sharedcovid/view/WorldMapContainer.mjs +2 -0
  114. package/apps/sharedcovid/view/country/Gallery.mjs +3 -0
  115. package/apps/sharedcovid/view/country/Helix.mjs +8 -0
  116. package/apps/sharedcovid/view/country/HistoricalDataTable.mjs +1 -0
  117. package/apps/sharedcovid/view/country/Table.mjs +2 -0
  118. package/apps/sharedcovid/view/mapboxGl/Component.mjs +1 -0
  119. package/apps/sharedcovid/view/mapboxGl/Container.mjs +2 -0
  120. package/apps/shareddialog/childapps/shareddialog2/view/MainContainer.mjs +2 -0
  121. package/apps/shareddialog/view/DemoDialog.mjs +2 -0
  122. package/apps/shareddialog/view/MainContainer.mjs +2 -0
  123. package/apps/shareddialog/view/MainContainerController.mjs +1 -0
  124. package/buildScripts/addReactiveTags.mjs +191 -0
  125. package/buildScripts/checkReactiveTags.mjs +160 -0
  126. package/docs/app/store/Api.mjs +1 -0
  127. package/docs/app/store/Examples.mjs +1 -0
  128. package/docs/app/view/ApiTreeList.mjs +1 -0
  129. package/docs/app/view/ContentTabContainer.mjs +2 -0
  130. package/docs/app/view/ExamplesTreeList.mjs +2 -0
  131. package/docs/app/view/HeaderContainer.mjs +3 -0
  132. package/docs/app/view/MainContainer.mjs +5 -0
  133. package/docs/app/view/classdetails/HeaderComponent.mjs +1 -0
  134. package/docs/app/view/classdetails/MainContainer.mjs +3 -0
  135. package/docs/app/view/classdetails/MembersList.mjs +5 -0
  136. package/docs/app/view/classdetails/SourceViewComponent.mjs +2 -0
  137. package/examples/ConfigurationViewport.mjs +14 -8
  138. package/examples/calendar/weekview/MainContainer.mjs +4 -0
  139. package/examples/component/coronaGallery/CountryGallery.mjs +2 -0
  140. package/examples/component/coronaGallery/CountryStore.mjs +1 -0
  141. package/examples/component/coronaGallery/Viewport.mjs +3 -0
  142. package/examples/component/coronaGallery/ViewportController.mjs +1 -0
  143. package/examples/component/coronaHelix/CountryHelix.mjs +7 -0
  144. package/examples/component/coronaHelix/MainContainer.mjs +1 -0
  145. package/examples/component/gallery/ImageStore.mjs +1 -0
  146. package/examples/component/helix/ImageStore.mjs +1 -0
  147. package/examples/component/helix/Viewport.mjs +3 -0
  148. package/examples/component/helix/ViewportController.mjs +1 -0
  149. package/examples/component/multiWindowCoronaGallery/childapp/Viewport.mjs +1 -0
  150. package/examples/component/multiWindowHelix/childapp/Viewport.mjs +1 -0
  151. package/examples/component/wrapper/googleMaps/MapComponent.mjs +2 -0
  152. package/examples/core/config/MainContainer.mjs +2 -0
  153. package/examples/dialog/DemoDialog.mjs +2 -0
  154. package/examples/dialog/MainContainer.mjs +1 -0
  155. package/examples/form/field/color/MainStore.mjs +1 -0
  156. package/examples/functional/defineComponent/Component.mjs +18 -0
  157. package/examples/functional/defineComponent/MainContainer.mjs +41 -0
  158. package/examples/functional/defineComponent/app.mjs +6 -0
  159. package/examples/functional/defineComponent/index.html +11 -0
  160. package/examples/functional/defineComponent/neo-config.json +6 -0
  161. package/examples/functional/hostComponent/Component.mjs +32 -0
  162. package/examples/functional/hostComponent/MainContainer.mjs +48 -0
  163. package/examples/functional/hostComponent/app.mjs +6 -0
  164. package/examples/functional/hostComponent/index.html +11 -0
  165. package/examples/functional/hostComponent/neo-config.json +6 -0
  166. package/examples/grid/animatedRowSorting/Viewport.mjs +1 -1
  167. package/examples/grid/bigData/ControlsContainer.mjs +3 -0
  168. package/examples/grid/bigData/GridContainer.mjs +4 -2
  169. package/examples/grid/bigData/MainContainer.mjs +2 -0
  170. package/examples/grid/bigData/MainModel.mjs +1 -0
  171. package/examples/grid/bigData/MainStore.mjs +3 -0
  172. package/examples/grid/cellEditing/MainContainer.mjs +1 -1
  173. package/examples/grid/container/MainContainer.mjs +1 -1
  174. package/examples/grid/covid/GridContainer.mjs +3 -0
  175. package/examples/grid/covid/MainContainer.mjs +2 -0
  176. package/examples/grid/covid/Store.mjs +1 -0
  177. package/examples/grid/nestedRecordFields/EditUserDialog.mjs +3 -0
  178. package/examples/grid/nestedRecordFields/Viewport.mjs +3 -1
  179. package/examples/list/animate/List.mjs +4 -0
  180. package/examples/list/animate/MainContainer.mjs +2 -0
  181. package/examples/list/circle/MainStore.mjs +1 -0
  182. package/examples/list/color/MainStore.mjs +1 -0
  183. package/examples/preloadingAssets/view/MainContainer.mjs +2 -0
  184. package/examples/stateProvider/advanced/MainContainer.mjs +1 -0
  185. package/examples/stateProvider/dialog/EditUserDialog.mjs +2 -0
  186. package/examples/stateProvider/dialog/MainContainer.mjs +1 -0
  187. package/examples/stateProvider/extendedClass/MainContainer.mjs +2 -0
  188. package/examples/stateProvider/inline/MainContainer.mjs +1 -0
  189. package/examples/stateProvider/inlineNoStateProvider/MainContainer.mjs +1 -0
  190. package/examples/stateProvider/inlineNoStateProvider/MainContainerController.mjs +2 -0
  191. package/examples/stateProvider/multiWindow/EditUserDialog.mjs +3 -0
  192. package/examples/stateProvider/multiWindow/MainContainer.mjs +1 -0
  193. package/examples/stateProvider/multiWindow/Viewport.mjs +1 -0
  194. package/examples/stateProvider/nestedData/MainContainer.mjs +1 -0
  195. package/examples/stateProvider/table/MainContainer.mjs +1 -0
  196. package/examples/table/covid/MainContainer.mjs +2 -0
  197. package/examples/table/covid/Store.mjs +1 -0
  198. package/examples/table/covid/TableContainer.mjs +3 -0
  199. package/examples/table/nestedRecordFields/EditUserDialog.mjs +3 -0
  200. package/examples/table/nestedRecordFields/Viewport.mjs +1 -0
  201. package/examples/todoList/version1/MainComponent.mjs +1 -1
  202. package/examples/toolbar/breadcrumb/view/MainContainer.mjs +2 -0
  203. package/examples/toolbar/paging/store/Users.mjs +1 -0
  204. package/examples/toolbar/paging/view/AddUserDialog.mjs +3 -0
  205. package/examples/toolbar/paging/view/MainContainer.mjs +3 -0
  206. package/examples/treeAccordion/MainContainer.mjs +2 -2
  207. package/examples/worker/task/MainContainer.mjs +1 -0
  208. package/learn/Glossary.md +1 -0
  209. package/learn/UsingTheseTopics.md +1 -0
  210. package/learn/benefits/ConfigSystem.md +2 -0
  211. package/learn/benefits/Effort.md +1 -0
  212. package/learn/benefits/Features.md +1 -0
  213. package/learn/benefits/FormsEngine.md +1 -0
  214. package/learn/benefits/FourEnvironments.md +2 -0
  215. package/learn/benefits/Introduction.md +2 -0
  216. package/learn/benefits/MultiWindow.md +3 -1
  217. package/learn/benefits/OffTheMainThread.md +2 -0
  218. package/learn/benefits/Quick.md +2 -0
  219. package/learn/benefits/RPCLayer.md +2 -0
  220. package/learn/benefits/Speed.md +2 -0
  221. package/learn/comparisons/NeoVsAngular.md +90 -0
  222. package/learn/comparisons/NeoVsExtJs.md +178 -0
  223. package/learn/comparisons/NeoVsNextJs.md +124 -0
  224. package/learn/comparisons/NeoVsReact.md +95 -0
  225. package/learn/comparisons/NeoVsSolid.md +78 -0
  226. package/learn/comparisons/NeoVsVue.md +92 -0
  227. package/learn/comparisons/Overview.md +46 -0
  228. package/learn/gettingstarted/ComponentModels.md +2 -0
  229. package/learn/gettingstarted/Config.md +2 -0
  230. package/learn/gettingstarted/DescribingTheUI.md +2 -0
  231. package/learn/gettingstarted/Events.md +2 -0
  232. package/learn/gettingstarted/Extending.md +2 -0
  233. package/learn/gettingstarted/References.md +2 -0
  234. package/learn/gettingstarted/Setup.md +3 -2
  235. package/learn/gettingstarted/Workspaces.md +2 -0
  236. package/learn/guides/datahandling/Collections.md +1 -0
  237. package/learn/guides/datahandling/Records.md +1 -0
  238. package/learn/guides/datahandling/StateProviders.md +130 -16
  239. package/learn/guides/datahandling/Tables.md +1 -1
  240. package/learn/guides/fundamentals/ConfigSystemDeepDive.md +1 -0
  241. package/learn/guides/fundamentals/DeclarativeComponentTreesVsImperativeVdom.md +2 -0
  242. package/learn/guides/fundamentals/DeclarativeVDOMWithEffects.md +10 -8
  243. package/learn/guides/fundamentals/ExtendingNeoClasses.md +1 -0
  244. package/learn/guides/fundamentals/InstanceLifecycle.md +3 -1
  245. package/learn/guides/fundamentals/MainThreadAddons.md +2 -0
  246. package/learn/guides/specificfeatures/Mixins.md +3 -1
  247. package/learn/guides/specificfeatures/MultiWindow.md +3 -1
  248. package/learn/guides/specificfeatures/PortalApp.md +2 -0
  249. package/learn/guides/uibuildingblocks/ComponentsAndContainers.md +2 -0
  250. package/learn/guides/uibuildingblocks/CustomComponents.md +2 -0
  251. package/learn/guides/uibuildingblocks/Layouts.md +2 -0
  252. package/learn/guides/uibuildingblocks/WorkingWithVDom.md +2 -0
  253. package/learn/guides/userinteraction/Forms.md +2 -0
  254. package/learn/guides/userinteraction/events/CustomEvents.md +2 -1
  255. package/learn/guides/userinteraction/events/DomEvents.md +2 -0
  256. package/learn/javascript/ClassFeatures.md +4 -3
  257. package/learn/javascript/Classes.md +10 -13
  258. package/learn/javascript/Overrides.md +10 -6
  259. package/learn/javascript/Super.md +12 -8
  260. package/learn/tree.json +71 -64
  261. package/learn/tutorials/Earthquakes.md +2 -0
  262. package/learn/tutorials/RSP.md +3 -1
  263. package/learn/tutorials/TodoList.md +103 -7
  264. package/package.json +6 -4
  265. package/resources/scss/src/apps/email/ComposeView.scss +16 -0
  266. package/resources/scss/src/apps/email/MainView.scss +5 -0
  267. package/resources/scss/src/apps/portal/learn/ContentComponent.scss +5 -4
  268. package/src/DefaultConfig.mjs +12 -2
  269. package/src/Main.mjs +1 -0
  270. package/src/Neo.mjs +217 -166
  271. package/src/Xhr.mjs +1 -0
  272. package/src/button/Base.mjs +13 -0
  273. package/src/button/Effect.mjs +16 -2
  274. package/src/button/Split.mjs +2 -0
  275. package/src/calendar/store/Calendars.mjs +1 -0
  276. package/src/calendar/store/Colors.mjs +1 -0
  277. package/src/calendar/store/Events.mjs +1 -0
  278. package/src/calendar/view/DayComponent.mjs +2 -0
  279. package/src/calendar/view/EditEventContainer.mjs +4 -1
  280. package/src/calendar/view/MainContainer.mjs +13 -0
  281. package/src/calendar/view/MainContainerStateProvider.mjs +14 -28
  282. package/src/calendar/view/SettingsContainer.mjs +1 -0
  283. package/src/calendar/view/YearComponent.mjs +16 -0
  284. package/src/calendar/view/calendars/ColorsList.mjs +2 -0
  285. package/src/calendar/view/calendars/Container.mjs +2 -0
  286. package/src/calendar/view/calendars/EditContainer.mjs +1 -0
  287. package/src/calendar/view/month/Component.mjs +11 -0
  288. package/src/calendar/view/settings/GeneralContainer.mjs +1 -0
  289. package/src/calendar/view/settings/MonthContainer.mjs +1 -0
  290. package/src/calendar/view/settings/WeekContainer.mjs +1 -0
  291. package/src/calendar/view/settings/YearContainer.mjs +1 -0
  292. package/src/calendar/view/week/Component.mjs +15 -1
  293. package/src/calendar/view/week/TimeAxisComponent.mjs +4 -0
  294. package/src/code/LivePreview.mjs +51 -23
  295. package/src/collection/Base.mjs +7 -10
  296. package/src/collection/Filter.mjs +6 -0
  297. package/src/collection/Sorter.mjs +3 -0
  298. package/src/component/Base.mjs +104 -771
  299. package/src/component/Canvas.mjs +1 -0
  300. package/src/component/Chip.mjs +4 -0
  301. package/src/component/Circle.mjs +14 -0
  302. package/src/component/Clock.mjs +4 -0
  303. package/src/component/DateSelector.mjs +12 -0
  304. package/src/component/Gallery.mjs +11 -0
  305. package/src/component/Helix.mjs +24 -0
  306. package/src/component/Label.mjs +1 -0
  307. package/src/component/Legend.mjs +3 -0
  308. package/src/component/MagicMoveText.mjs +4 -0
  309. package/src/component/Progress.mjs +3 -0
  310. package/src/component/Splitter.mjs +3 -0
  311. package/src/component/StatusBadge.mjs +6 -0
  312. package/src/component/Timer.mjs +4 -0
  313. package/src/component/Toast.mjs +6 -0
  314. package/src/component/Video.mjs +1 -0
  315. package/src/component/mwc/Button.mjs +7 -0
  316. package/src/component/mwc/TextField.mjs +9 -0
  317. package/src/component/wrapper/AmChart.mjs +2 -0
  318. package/src/component/wrapper/GoogleMaps.mjs +3 -0
  319. package/src/component/wrapper/MapboxGL.mjs +5 -0
  320. package/src/component/wrapper/MonacoEditor.mjs +12 -0
  321. package/src/container/Accordion.mjs +2 -0
  322. package/src/container/Base.mjs +7 -3
  323. package/src/container/Panel.mjs +1 -0
  324. package/src/container/Viewport.mjs +1 -0
  325. package/src/controller/Application.mjs +1 -0
  326. package/src/controller/Base.mjs +1 -0
  327. package/src/controller/Component.mjs +1 -0
  328. package/src/core/Base.mjs +55 -3
  329. package/src/core/Compare.mjs +4 -7
  330. package/src/core/Config.mjs +65 -52
  331. package/src/core/Effect.mjs +79 -13
  332. package/src/core/EffectBatchManager.mjs +18 -19
  333. package/src/core/EffectManager.mjs +25 -3
  334. package/src/core/IdGenerator.mjs +13 -44
  335. package/src/data/Model.mjs +2 -0
  336. package/src/data/Store.mjs +7 -0
  337. package/src/data/connection/WebSocket.mjs +2 -0
  338. package/src/date/DayViewComponent.mjs +2 -0
  339. package/src/date/SelectorContainer.mjs +14 -0
  340. package/src/dialog/Base.mjs +8 -0
  341. package/src/draggable/DragZone.mjs +5 -0
  342. package/src/draggable/tree/DragZone.mjs +1 -0
  343. package/src/filter/BooleanContainer.mjs +2 -0
  344. package/src/filter/NumberContainer.mjs +3 -0
  345. package/src/filter/ToggleOperatorsButton.mjs +2 -0
  346. package/src/form/Fieldset.mjs +6 -0
  347. package/src/form/field/Base.mjs +7 -0
  348. package/src/form/field/CheckBox.mjs +18 -0
  349. package/src/form/field/Chip.mjs +1 -0
  350. package/src/form/field/ComboBox.mjs +8 -0
  351. package/src/form/field/Country.mjs +1 -0
  352. package/src/form/field/Currency.mjs +2 -0
  353. package/src/form/field/Date.mjs +4 -0
  354. package/src/form/field/Display.mjs +1 -0
  355. package/src/form/field/Email.mjs +1 -0
  356. package/src/form/field/FileUpload.mjs +7 -0
  357. package/src/form/field/Hidden.mjs +1 -0
  358. package/src/form/field/Number.mjs +7 -0
  359. package/src/form/field/Password.mjs +1 -0
  360. package/src/form/field/Phone.mjs +3 -0
  361. package/src/form/field/Picker.mjs +2 -0
  362. package/src/form/field/Radio.mjs +1 -0
  363. package/src/form/field/Range.mjs +3 -0
  364. package/src/form/field/Search.mjs +2 -0
  365. package/src/form/field/Text.mjs +32 -0
  366. package/src/form/field/TextArea.mjs +7 -0
  367. package/src/form/field/Time.mjs +6 -0
  368. package/src/form/field/Url.mjs +3 -0
  369. package/src/form/field/ZipCode.mjs +2 -0
  370. package/src/form/field/trigger/Base.mjs +3 -0
  371. package/src/form/field/trigger/Clear.mjs +2 -0
  372. package/src/form/field/trigger/CopyToClipboard.mjs +2 -0
  373. package/src/form/field/trigger/Date.mjs +1 -0
  374. package/src/form/field/trigger/Picker.mjs +1 -0
  375. package/src/form/field/trigger/Search.mjs +1 -0
  376. package/src/form/field/trigger/SpinDown.mjs +2 -0
  377. package/src/form/field/trigger/SpinUp.mjs +1 -0
  378. package/src/form/field/trigger/Time.mjs +2 -0
  379. package/src/functional/_export.mjs +6 -0
  380. package/src/functional/component/Base.mjs +499 -0
  381. package/src/functional/defineComponent.mjs +102 -0
  382. package/src/functional/useConfig.mjs +52 -0
  383. package/src/functional/useEvent.mjs +43 -0
  384. package/src/grid/Body.mjs +20 -1
  385. package/src/grid/Container.mjs +50 -60
  386. package/src/grid/ScrollManager.mjs +2 -0
  387. package/src/grid/VerticalScrollbar.mjs +2 -0
  388. package/src/grid/column/Base.mjs +2 -0
  389. package/src/grid/header/Button.mjs +7 -0
  390. package/src/grid/header/Toolbar.mjs +6 -0
  391. package/src/grid/plugin/AnimateRows.mjs +2 -0
  392. package/src/layout/Base.mjs +3 -0
  393. package/src/layout/Card.mjs +1 -0
  394. package/src/layout/Cube.mjs +11 -1
  395. package/src/layout/Fit.mjs +1 -0
  396. package/src/layout/Flexbox.mjs +7 -0
  397. package/src/layout/Form.mjs +2 -0
  398. package/src/layout/Grid.mjs +1 -0
  399. package/src/layout/HBox.mjs +1 -0
  400. package/src/layout/VBox.mjs +1 -0
  401. package/src/list/Base.mjs +13 -0
  402. package/src/list/Chip.mjs +1 -0
  403. package/src/list/Circle.mjs +2 -0
  404. package/src/list/Color.mjs +1 -0
  405. package/src/list/plugin/Animate.mjs +2 -0
  406. package/src/main/DeltaUpdates.mjs +1 -0
  407. package/src/main/DomEvents.mjs +2 -0
  408. package/src/main/addon/CloneNode.mjs +1 -0
  409. package/src/main/addon/Cookie.mjs +1 -0
  410. package/src/main/addon/GoogleMaps.mjs +1 -0
  411. package/src/main/addon/LocalStorage.mjs +1 -0
  412. package/src/main/addon/MapboxGL.mjs +1 -0
  413. package/src/main/addon/Markdown.mjs +1 -0
  414. package/src/main/addon/Navigator.mjs +1 -0
  415. package/src/main/addon/Popover.mjs +1 -0
  416. package/src/main/addon/Stylesheet.mjs +1 -0
  417. package/src/main/addon/WindowPosition.mjs +1 -0
  418. package/src/manager/Component.mjs +0 -71
  419. package/src/manager/VDomUpdate.mjs +235 -0
  420. package/src/menu/List.mjs +6 -0
  421. package/src/menu/Model.mjs +1 -0
  422. package/src/menu/Panel.mjs +3 -0
  423. package/src/menu/Store.mjs +1 -0
  424. package/src/mixin/DomEvents.mjs +130 -0
  425. package/src/mixin/VdomLifecycle.mjs +667 -0
  426. package/src/plugin/Base.mjs +1 -0
  427. package/src/plugin/Resizable.mjs +2 -0
  428. package/src/selection/Model.mjs +15 -18
  429. package/src/selection/grid/BaseModel.mjs +1 -0
  430. package/src/sitemap/Component.mjs +1 -0
  431. package/src/state/Provider.mjs +98 -70
  432. package/src/state/createHierarchicalDataProxy.mjs +39 -25
  433. package/src/tab/Container.mjs +6 -0
  434. package/src/tab/Strip.mjs +1 -0
  435. package/src/tab/header/Button.mjs +2 -0
  436. package/src/tab/header/EffectButton.mjs +2 -0
  437. package/src/tab/header/Toolbar.mjs +1 -0
  438. package/src/table/Body.mjs +3 -0
  439. package/src/table/Container.mjs +10 -0
  440. package/src/table/header/Button.mjs +8 -0
  441. package/src/table/header/Toolbar.mjs +5 -0
  442. package/src/table/plugin/CellEditing.mjs +1 -0
  443. package/src/toolbar/Base.mjs +4 -0
  444. package/src/toolbar/Breadcrumb.mjs +3 -0
  445. package/src/toolbar/Paging.mjs +5 -0
  446. package/src/tooltip/Base.mjs +2 -0
  447. package/src/tree/List.mjs +3 -0
  448. package/src/util/HashHistory.mjs +1 -0
  449. package/src/util/KeyNavigation.mjs +2 -0
  450. package/src/util/Matrix.mjs +1 -0
  451. package/src/util/VDom.mjs +7 -1
  452. package/src/util/VNode.mjs +7 -1
  453. package/src/util/vdom/TreeBuilder.mjs +129 -0
  454. package/src/vdom/Helper.mjs +35 -23
  455. package/src/vdom/VNode.mjs +4 -6
  456. package/src/worker/App.mjs +1 -0
  457. package/src/worker/Base.mjs +2 -0
  458. package/src/worker/Manager.mjs +2 -0
  459. package/src/worker/ServiceBase.mjs +6 -1
  460. package/test/siesta/siesta.js +5 -2
  461. package/test/siesta/tests/VdomCalendar.mjs +13 -9
  462. package/test/siesta/tests/core/Effect.mjs +10 -14
  463. package/test/siesta/tests/core/EffectBatching.mjs +25 -37
  464. package/test/siesta/tests/state/ProviderNestedDataConfigs.mjs +255 -0
  465. package/test/siesta/tests/state/createHierarchicalDataProxy.mjs +42 -55
  466. package/test/siesta/tests/vdom/VdomAsymmetricUpdates.mjs +366 -0
  467. package/test/siesta/tests/vdom/VdomRealWorldUpdates.mjs +249 -0
  468. package/learn/javascript/NewNode.md +0 -31
@@ -1,10 +1,12 @@
1
- import Base from '../core/Base.mjs';
2
- import NeoArray from '../util/Array.mjs';
3
- import Observable from '../core/Observable.mjs';
1
+ import Base from '../core/Base.mjs';
2
+ import NeoArray from '../util/Array.mjs';
3
+ import Observable from '../core/Observable.mjs';
4
+ import {isDescriptor} from '../core/ConfigSymbols.mjs';
4
5
 
5
6
  /**
6
7
  * @class Neo.selection.Model
7
8
  * @extends Neo.core.Base
9
+ * @mixes Neo.core.Observable
8
10
  */
9
11
  class Model extends Base {
10
12
  /**
@@ -32,10 +34,17 @@ class Model extends Base {
32
34
  */
33
35
  cls: null,
34
36
  /**
35
- * @member {Array} items_=null
37
+ * @member {Array} items_
36
38
  * @protected
39
+ * @reactive
37
40
  */
38
- items_: null,
41
+ items_: {
42
+ [isDescriptor]: true,
43
+ clone : 'shallow',
44
+ cloneOnGet : 'none',
45
+ isEqual : () => false,
46
+ value : []
47
+ },
39
48
  /**
40
49
  * @member {String} selectedCls='selected'
41
50
  */
@@ -48,23 +57,11 @@ class Model extends Base {
48
57
  * Internally saves the view id, but the getter will return the matching instance
49
58
  * @member {Object} view_=null
50
59
  * @protected
60
+ * @reactive
51
61
  */
52
62
  view_: null
53
63
  }
54
64
 
55
- /**
56
- * Gets triggered before getting the value of the items config
57
- * @param {Array|null} value
58
- * @returns {Array}
59
- */
60
- beforeGetItems(value) {
61
- if (!value) {
62
- this._items = value = []
63
- }
64
-
65
- return value
66
- }
67
-
68
65
  /**
69
66
  * Gets triggered before getting the value of the view config
70
67
  * @param {String} value
@@ -53,6 +53,7 @@ class BaseModel extends Model {
53
53
  }
54
54
 
55
55
  me.fire('selectionChange', {
56
+ records : me.selectedRows.map(id => view.store.get(id)),
56
57
  selection: me.selectedRows
57
58
  })
58
59
  } else if (!silent) {
@@ -34,6 +34,7 @@ class Component extends Base {
34
34
  * Valid values: removeDom, visibility
35
35
  * Defines if the component items should use css visibility:'hidden' or vdom:removeDom
36
36
  * @member {String} hideMode_='removeDom'
37
+ * @reactive
37
38
  */
38
39
  itemHideMode_: 'removeDom',
39
40
  /*
@@ -2,6 +2,7 @@ import Base from '../core/Base.mjs';
2
2
  import ClassSystemUtil from '../util/ClassSystem.mjs';
3
3
  import Config from '../core/Config.mjs';
4
4
  import Effect from '../core/Effect.mjs';
5
+ import EffectBatchManager from '../core/EffectBatchManager.mjs';
5
6
  import Observable from '../core/Observable.mjs';
6
7
  import {createHierarchicalDataProxy} from './createHierarchicalDataProxy.mjs';
7
8
  import {isDescriptor} from '../core/ConfigSymbols.mjs';
@@ -12,6 +13,7 @@ const twoWayBindingSymbol = Symbol.for('twoWayBinding');
12
13
  * An optional component state provider for adding bindings to configs
13
14
  * @class Neo.state.Provider
14
15
  * @extends Neo.core.Base
16
+ * @mixes Neo.core.Observable
15
17
  */
16
18
  class Provider extends Base {
17
19
  /**
@@ -55,6 +57,7 @@ class Provider extends Base {
55
57
  * theme: 'dark'
56
58
  * }
57
59
  * }
60
+ * @reactive
58
61
  */
59
62
  data_: {
60
63
  [isDescriptor]: true,
@@ -79,10 +82,12 @@ class Provider extends Base {
79
82
  * // Accessing parent data (assuming a parent provider has a 'taxRate' property)
80
83
  * totalWithTax: (data) => data.total * (1 + data.taxRate)
81
84
  * }
85
+ * @reactive
82
86
  */
83
87
  formulas_: null,
84
88
  /**
85
89
  * @member {Neo.state.Provider|null} parent_=null
90
+ * @reactive
86
91
  */
87
92
  parent_: null,
88
93
  /**
@@ -104,6 +109,7 @@ class Provider extends Base {
104
109
  * autoLoad: true
105
110
  * }
106
111
  * }
112
+ * @reactive
107
113
  */
108
114
  stores_: null
109
115
  }
@@ -161,21 +167,16 @@ class Provider extends Base {
161
167
 
162
168
  if (value) {
163
169
  Object.entries(value).forEach(([formulaKey, formulaFn]) => {
164
- // Create a new Effect for each formula. The Effect's fn will re-run whenever its dependencies change.
170
+ // Create a new lazy Effect. It will not run until explicitly told to.
165
171
  const effect = new Effect({
166
172
  fn: () => {
167
173
  const
168
- hierarchicalData = me.getHierarchyData(), // Get the reactive data proxy
169
- result = formulaFn(hierarchicalData); // Execute the formula with the data
170
-
171
- // Assign the result back to the state provider's data.
172
- // This makes the formula's output available as a data property.
173
- if (isNaN(result)) {
174
- me.setData(formulaKey, null)
175
- } else {
176
- me.setData(formulaKey, result)
177
- }
178
- }
174
+ hierarchicalData = me.getHierarchyData(),
175
+ result = formulaFn(hierarchicalData);
176
+
177
+ me.setData(formulaKey, result);
178
+ },
179
+ lazy: true
179
180
  });
180
181
 
181
182
  me.#formulaEffects.set(formulaKey, effect)
@@ -223,24 +224,22 @@ class Provider extends Base {
223
224
  * @param {String} configKey The component config to bind (e.g., 'text').
224
225
  * @param {String|Function} formatter The function that computes the value.
225
226
  */
226
- createBinding(componentId, configKey, key, isTwoWay) {
227
+ createBinding(componentId, configKey, formatter) {
227
228
  const
228
229
  me = this,
229
- effect = new Effect({
230
- fn: () => {
230
+ effect = new Effect(() => {
231
231
  const component = Neo.get(componentId);
232
232
 
233
233
  if (component && !component.isDestroyed) {
234
234
  const
235
235
  hierarchicalData = me.getHierarchyData(),
236
- newValue = Neo.isFunction(key) ? key.call(me, hierarchicalData) : hierarchicalData[key];
236
+ newValue = Neo.isFunction(formatter) ? formatter.call(me, hierarchicalData) : hierarchicalData[formatter];
237
237
 
238
238
  component._skipTwoWayPush = configKey;
239
239
  component[configKey] = newValue;
240
240
  delete component._skipTwoWayPush
241
241
  }
242
- }
243
- });
242
+ });
244
243
 
245
244
  me.#bindingEffects.set(componentId, effect);
246
245
 
@@ -262,7 +261,8 @@ class Provider extends Base {
262
261
  * @param {Neo.component.Base} component The component instance whose bindings are to be created.
263
262
  */
264
263
  createBindings(component) {
265
- let hasTwoWayBinding = false;
264
+ let me = this,
265
+ hasTwoWayBinding = false;
266
266
 
267
267
  Object.entries(component.bind || {}).forEach(([configKey, value]) => {
268
268
  let key = value;
@@ -276,12 +276,12 @@ class Provider extends Base {
276
276
  }
277
277
 
278
278
  // Determine if it's a store binding or a data binding.
279
- if (this.isStoreValue(key)) {
279
+ if (me.isStoreValue(key)) {
280
280
  // For store bindings, resolve the store and assign it to the component config.
281
- this.resolveStore(component, configKey, key.substring(7)) // remove the "stores." prefix
281
+ me.resolveStore(component, configKey, key.substring(7)) // remove the "stores." prefix
282
282
  } else {
283
283
  // For data bindings, create an Effect to keep the component config in sync with the data.
284
- this.createBinding(component.id, configKey, key, value.twoWay)
284
+ me.createBinding(component.id, configKey, key, value.twoWay)
285
285
  }
286
286
  });
287
287
 
@@ -435,34 +435,40 @@ class Provider extends Base {
435
435
  * @returns {String[]}
436
436
  */
437
437
  getTopLevelDataKeys(path) {
438
- const keys = new Set();
439
- const pathPrefix = path ? `${path}.` : '';
438
+ const
439
+ keys = new Set(),
440
+ pathPrefix = path ? `${path}.` : '';
440
441
 
441
442
  for (const fullPath in this.#dataConfigs) {
442
443
  if (fullPath.startsWith(pathPrefix)) {
443
- const relativePath = fullPath.substring(pathPrefix.length);
444
- const topLevelKey = relativePath.split('.')[0];
444
+ const
445
+ relativePath = fullPath.substring(pathPrefix.length),
446
+ topLevelKey = relativePath.split('.')[0];
447
+
445
448
  if (topLevelKey) {
446
- keys.add(topLevelKey);
449
+ keys.add(topLevelKey)
447
450
  }
448
451
  }
449
452
  }
450
- return Array.from(keys);
453
+
454
+ return Array.from(keys)
451
455
  }
452
456
 
453
457
  /**
454
- * Internal method to avoid code redundancy.
455
- * Use setData() or setDataAtSameLevel() instead.
458
+ * This is the core method for setting data, providing a single entry point for all data modifications.
459
+ * It handles multiple scenarios:
460
+ * 1. **Object-based updates:** If `key` is an object, it recursively calls itself for each key-value pair.
461
+ * 2. **Data Records:** If `value` is a `Neo.data.Record`, it is treated as an atomic value and set directly.
462
+ * 3. **Bubbling Reactivity:** For a given key (e.g., 'user.name'), it sets the leaf value and then "bubbles up"
463
+ * the change, creating new parent objects (e.g., 'user') to ensure that effects depending on any part
464
+ * of the path are triggered.
456
465
  *
457
- * This method handles setting data properties, including nested paths and Neo.data.Record instances.
458
- * It determines the owning StateProvider in the hierarchy and delegates to #setConfigValue.
466
+ * All updates are batched by the public `setData` methods to ensure effects run only once.
467
+ * Use `setData()` or `setDataAtSameLevel()` instead of calling this method directly.
459
468
  *
460
- * Passing an originStateProvider param will try to set each key on the closest property match
461
- * inside the parent stateProvider chain => setData()
462
- * Not passing it will set all values on the stateProvider where the method gets called => setDataAtSameLevel()
463
- * @param {Object|String} key
464
- * @param {*} value
465
- * @param {Neo.state.Provider} [originStateProvider]
469
+ * @param {Object|String} key The property to set, or an object of key-value pairs.
470
+ * @param {*} value The new value.
471
+ * @param {Neo.state.Provider} [originStateProvider] The provider to start the search from for hierarchical updates.
466
472
  * @protected
467
473
  */
468
474
  internalSetData(key, value, originStateProvider) {
@@ -470,7 +476,7 @@ class Provider extends Base {
470
476
 
471
477
  // If the value is a Neo.data.Record, treat it as an atomic value
472
478
  // and set it directly without further recursive processing of its properties.
473
- if (Neo.isObject(value) && value.isRecord) {
479
+ if (Neo.isRecord(value)) {
474
480
  const
475
481
  ownerDetails = me.getOwnerOfDataProperty(key),
476
482
  targetProvider = ownerDetails ? ownerDetails.owner : (originStateProvider || me);
@@ -479,8 +485,6 @@ class Provider extends Base {
479
485
  return
480
486
  }
481
487
 
482
- // If the key is an object, iterate over its entries and recursively call internalSetData.
483
- // This handles setting multiple properties at once (e.g., setData({prop1: val1, prop2: val2})).
484
488
  if (Neo.isObject(key)) {
485
489
  Object.entries(key).forEach(([dataKey, dataValue]) => {
486
490
  me.internalSetData(dataKey, dataValue, originStateProvider)
@@ -488,33 +492,33 @@ class Provider extends Base {
488
492
  return
489
493
  }
490
494
 
491
- // Handle single key/value pairs, including nested paths (e.g., 'user.firstName').
492
495
  const
493
496
  ownerDetails = me.getOwnerOfDataProperty(key),
494
- targetProvider = ownerDetails ? ownerDetails.owner : (originStateProvider || me),
495
- pathParts = key.split('.');
496
-
497
- let currentPath = '',
498
- currentConfig = null,
499
- currentProvider = targetProvider;
500
-
501
- for (let i = 0; i < pathParts.length; i++) {
502
- const part = pathParts[i];
503
- currentPath = currentPath ? `${currentPath}.${part}` : part;
504
- currentConfig = currentProvider.getDataConfig(currentPath);
505
-
506
- if (i === pathParts.length - 1) { // Last part of the path
507
- // Set the value for the final property in the path.
508
- me.#setConfigValue(currentProvider, currentPath, value, null)
509
- } else { // Intermediate part of the path
510
- // Ensure intermediate paths exist as objects. If not, create them.
511
- // If an intermediate path exists but is not an object, overwrite it with an empty object.
512
- if (!currentConfig) {
513
- currentConfig = new Config({}); // Create an empty object config
514
- currentProvider.#dataConfigs[currentPath] = currentConfig
515
- } else if (!Neo.isObject(currentConfig.get())) {
516
- currentConfig.set({})
497
+ targetProvider = ownerDetails ? ownerDetails.owner : (originStateProvider || me);
498
+
499
+ me.#setConfigValue(targetProvider, key, value, null);
500
+
501
+ // Bubble up the change to parent configs to trigger their effects
502
+ let path = key,
503
+ latestValue = value;
504
+
505
+ while (path.includes('.')) {
506
+ const leafKey = path.split('.').pop();
507
+ path = path.substring(0, path.lastIndexOf('.'));
508
+
509
+ const parentConfig = targetProvider.getDataConfig(path);
510
+
511
+ if (parentConfig) {
512
+ const oldParentValue = parentConfig.get();
513
+ if (Neo.isObject(oldParentValue)) {
514
+ const newParentValue = { ...oldParentValue, [leafKey]: latestValue };
515
+ parentConfig.set(newParentValue);
516
+ latestValue = newParentValue;
517
+ } else {
518
+ break // Stop if parent is not an object
517
519
  }
520
+ } else {
521
+ break // Stop if parent config does not exist
518
522
  }
519
523
  }
520
524
  }
@@ -528,6 +532,18 @@ class Provider extends Base {
528
532
  return Neo.isString(value) && value.startsWith('stores.')
529
533
  }
530
534
 
535
+ /**
536
+ * Gets called after all constructors & configs are applied.
537
+ * @protected
538
+ */
539
+ onConstructed() {
540
+ super.onConstructed();
541
+
542
+ // After the provider is fully constructed and initial data is set,
543
+ // run the formula effects for the first time to compute their initial values.
544
+ this.#formulaEffects.forEach(effect => effect.run())
545
+ }
546
+
531
547
  /**
532
548
  * @param {String} key
533
549
  * @param {*} value
@@ -552,14 +568,14 @@ class Provider extends Base {
552
568
 
553
569
  // Ensure a Config instance exists for the current fullPath
554
570
  if (me.#dataConfigs[fullPath]) {
555
- me.#dataConfigs[fullPath].set(value);
571
+ me.#dataConfigs[fullPath].set(value)
556
572
  } else {
557
- me.#dataConfigs[fullPath] = new Config(value);
573
+ me.#dataConfigs[fullPath] = new Config(value)
558
574
  }
559
575
 
560
576
  // If the value is a plain object, recursively process its properties
561
577
  if (Neo.typeOf(value) === 'Object') {
562
- me.processDataObject(value, fullPath);
578
+ me.processDataObject(value, fullPath)
563
579
  }
564
580
  });
565
581
  }
@@ -608,21 +624,33 @@ class Provider extends Base {
608
624
  /**
609
625
  * The method will assign all values to the closest stateProvider where it finds an existing key.
610
626
  * In case no match is found inside the parent chain, a new data property will get generated.
627
+ *
628
+ * All updates within a single call are batched to ensure that reactive effects (bindings and formulas)
629
+ * are run only once.
630
+ *
611
631
  * @param {Object|String} key
612
632
  * @param {*} value
613
633
  */
614
634
  setData(key, value) {
615
- this.internalSetData(key, value, this)
635
+ EffectBatchManager.startBatch();
636
+ this.internalSetData(key, value, this);
637
+ EffectBatchManager.endBatch()
616
638
  }
617
639
 
618
640
  /**
619
641
  * Use this method instead of setData() in case you want to enforce
620
642
  * setting all keys on this instance instead of looking for matches inside parent stateProviders.
643
+ *
644
+ * All updates within a single call are batched to ensure that reactive effects (bindings and formulas)
645
+ * are run only once.
646
+ *
621
647
  * @param {Object|String} key
622
648
  * @param {*} value
623
649
  */
624
650
  setDataAtSameLevel(key, value) {
625
- this.internalSetData(key, value)
651
+ EffectBatchManager.startBatch();
652
+ this.internalSetData(key, value);
653
+ EffectBatchManager.endBatch()
626
654
  }
627
655
  }
628
656
 
@@ -22,7 +22,7 @@ function createNestedProxy(rootProvider, path) {
22
22
  // Handle internal properties that might be set directly on the proxy's target
23
23
  // or are expected by the environment (like Siesta's __REFADR__).
24
24
  if (typeof property === 'symbol' || property === '__REFADR__' || property === 'inspect' || property === 'then') {
25
- return Reflect.get(currentTarget, property);
25
+ return Reflect.get(currentTarget, property)
26
26
  }
27
27
 
28
28
  // Only allow string or number properties to proceed as data paths.
@@ -30,6 +30,20 @@ function createNestedProxy(rootProvider, path) {
30
30
  return undefined; // For other non-string/non-number properties, return undefined.
31
31
  }
32
32
 
33
+ // Special handling for the 'stores' property at the root level
34
+ if (path === '' && property === 'stores') {
35
+ return new Proxy({}, {
36
+ get(target, storeName) {
37
+ if (typeof storeName === 'symbol' || storeName === '__REFADR__') {
38
+ return Reflect.get(target, storeName)
39
+ }
40
+ // Delegate to the StateProvider's getStore method for hierarchical resolution
41
+ // Accessing store.count later will register the dependency via the Config system
42
+ return rootProvider.getStore(storeName)
43
+ }
44
+ })
45
+ }
46
+
33
47
  const fullPath = path ? `${path}.${property}` : property;
34
48
 
35
49
  // 1. Check if the full path corresponds to an actual data property.
@@ -41,17 +55,15 @@ function createNestedProxy(rootProvider, path) {
41
55
  config = owner.getDataConfig(propertyName);
42
56
 
43
57
  if (config) {
44
- const activeEffect = EffectManager.getActiveEffect();
45
- if (activeEffect) {
46
- activeEffect.addDependency(config);
47
- }
58
+ EffectManager.getActiveEffect()?.addDependency(config);
48
59
 
49
60
  const value = config.get();
50
61
  // If the value is an object, return a new proxy for it to ensure nested accesses are also proxied.
51
- if (Neo.typeOf(value) === 'Object') {
62
+ if (Neo.isObject(value)) {
52
63
  return createNestedProxy(rootProvider, fullPath)
53
64
  }
54
- return value;
65
+
66
+ return value
55
67
  }
56
68
  }
57
69
 
@@ -62,52 +74,54 @@ function createNestedProxy(rootProvider, path) {
62
74
  return createNestedProxy(rootProvider, fullPath)
63
75
  }
64
76
 
65
- // 3. If it's neither a data property nor a path to one, it doesn't exist in the state.
66
- return null
77
+ // 3. If it's neither a data property nor a path to one, it doesn't exist.
78
+ // Returning undefined ensures that chained accesses (e.g., data.nonexistent.property) fail gracefully.
67
79
  },
68
80
 
69
81
  set(currentTarget, property, value) {
70
82
  // Allow internal properties (like Symbols or specific strings) to be set directly on the target.
71
83
  if (typeof property === 'symbol' || property === '__REFADR__') {
72
- return Reflect.set(currentTarget, property, value);
84
+ return Reflect.set(currentTarget, property, value)
73
85
  }
74
86
 
75
- const fullPath = path ? `${path}.${property}` : property;
76
- const ownerDetails = rootProvider.getOwnerOfDataProperty(fullPath);
77
-
87
+ const
88
+ fullPath = path ? `${path}.${property}` : property,
89
+ ownerDetails = rootProvider.getOwnerOfDataProperty(fullPath);
78
90
  let targetProvider;
91
+
79
92
  if (ownerDetails) {
80
- targetProvider = ownerDetails.owner;
93
+ targetProvider = ownerDetails.owner
81
94
  } else {
82
95
  // If no owner is found, set it on the rootProvider (the one that created this proxy)
83
- targetProvider = rootProvider;
96
+ targetProvider = rootProvider
84
97
  }
85
98
 
86
99
  targetProvider.setData(fullPath, value);
87
- return true; // Indicate that the assignment was successful
100
+ return true // Indicate that the assignment was successful
88
101
  },
89
102
 
90
103
  ownKeys(currentTarget) {
91
- return rootProvider.getTopLevelDataKeys(path);
104
+ return rootProvider.getTopLevelDataKeys(path)
92
105
  },
93
106
 
94
107
  getOwnPropertyDescriptor(currentTarget, property) {
95
- const fullPath = path ? `${path}.${property}` : property;
96
- const ownerDetails = rootProvider.getOwnerOfDataProperty(fullPath);
108
+ const
109
+ fullPath = path ? `${path}.${property}` : property,
110
+ ownerDetails = rootProvider.getOwnerOfDataProperty(fullPath);
97
111
 
98
112
  if (ownerDetails) {
99
113
  const config = ownerDetails.owner.getDataConfig(ownerDetails.propertyName);
114
+
100
115
  if (config) {
101
116
  const value = config.get();
102
117
  return {
103
- value: Neo.isObject(value) ? createNestedProxy(rootProvider, fullPath) : value,
104
- writable: true,
105
- enumerable: true,
106
- configurable: true,
107
- };
118
+ value : Neo.isObject(value) ? createNestedProxy(rootProvider, fullPath) : value,
119
+ writable : true,
120
+ enumerable : true,
121
+ configurable: true
122
+ }
108
123
  }
109
124
  }
110
- return undefined; // Property not found
111
125
  }
112
126
  })
113
127
  }
@@ -32,6 +32,7 @@ class Container extends BaseContainer {
32
32
  /**
33
33
  * You can use null to not render any items initially
34
34
  * @member {Number|null} activeIndex_=0
35
+ * @reactive
35
36
  */
36
37
  activeIndex_: 0,
37
38
  /**
@@ -60,11 +61,13 @@ class Container extends BaseContainer {
60
61
  headerToolbar: null,
61
62
  /**
62
63
  * @member {Object|null} layout=null
64
+ * @reactive
63
65
  */
64
66
  layout: null,
65
67
  /**
66
68
  * True to not apply a background effect to the tab header container
67
69
  * @member {Boolean} plain_=true
70
+ * @reactive
68
71
  */
69
72
  plain_: true,
70
73
  /*
@@ -77,6 +80,7 @@ class Container extends BaseContainer {
77
80
  * true enables sorting tabs via drag&drop.
78
81
  * The config gets passed to the header toolbar
79
82
  * @member {Boolean} sortable_=false
83
+ * @reactive
80
84
  */
81
85
  sortable_: false,
82
86
  /**
@@ -96,6 +100,7 @@ class Container extends BaseContainer {
96
100
  * The position of the tab header toolbar.
97
101
  * Valid values are top, right, bottom, left.
98
102
  * @member {String} tabBarPosition_='top'
103
+ * @reactive
99
104
  */
100
105
  tabBarPosition_: 'top',
101
106
  /**
@@ -105,6 +110,7 @@ class Container extends BaseContainer {
105
110
  tabContainerCls: 'neo-tab-container',
106
111
  /**
107
112
  * @member {Boolean} useActiveTabIndicator_=true
113
+ * @reactive
108
114
  */
109
115
  useActiveTabIndicator_: true
110
116
  }
package/src/tab/Strip.mjs CHANGED
@@ -26,6 +26,7 @@ class Strip extends Component {
26
26
  tabContainerId: null,
27
27
  /**
28
28
  * @member {Boolean} useActiveTabIndicator_=true
29
+ * @reactive
29
30
  */
30
31
  useActiveTabIndicator_: true,
31
32
  /**
@@ -23,10 +23,12 @@ class Button extends BaseButton {
23
23
  /**
24
24
  * Specify a role tag attribute for the vdom root.
25
25
  * @member {String|null} role='tab'
26
+ * @reactive
26
27
  */
27
28
  role: 'tab',
28
29
  /**
29
30
  * @member {Boolean} useActiveTabIndicator_=true
31
+ * @reactive
30
32
  */
31
33
  useActiveTabIndicator_: true,
32
34
  /**
@@ -23,10 +23,12 @@ class EffectTabButton extends EffectButton {
23
23
  /**
24
24
  * Specify a role tag attribute for the vdom root.
25
25
  * @member {String|null} role='tab'
26
+ * @reactive
26
27
  */
27
28
  role: 'tab',
28
29
  /**
29
30
  * @member {Boolean} useActiveTabIndicator_=true
31
+ * @reactive
30
32
  */
31
33
  useActiveTabIndicator_: true
32
34
  }
@@ -22,6 +22,7 @@ class Toolbar extends BaseToolbar {
22
22
  baseCls: ['neo-tab-header-toolbar', 'neo-toolbar'],
23
23
  /**
24
24
  * @member {Boolean} useActiveTabIndicator_=true
25
+ * @reactive
25
26
  */
26
27
  useActiveTabIndicator_: true
27
28
  }
@@ -36,6 +36,7 @@ class TableBody extends Component {
36
36
  containerId: null,
37
37
  /**
38
38
  * @member {Boolean} highlightModifiedCells_=false
39
+ * @reactive
39
40
  */
40
41
  highlightModifiedCells_: false,
41
42
  /**
@@ -49,6 +50,7 @@ class TableBody extends Component {
49
50
  recordVnodeMap: {},
50
51
  /**
51
52
  * @member {Neo.selection.Model} selectionModel_=null
53
+ * @reactive
52
54
  */
53
55
  selectionModel_: null,
54
56
  /**
@@ -57,6 +59,7 @@ class TableBody extends Component {
57
59
  selectedRecordField: 'annotations.selected',
58
60
  /**
59
61
  * @member {Neo.data.Store|null} store_=null
62
+ * @reactive
60
63
  */
61
64
  store_: null,
62
65
  /**