cx 26.0.12 → 26.0.14

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 (365) hide show
  1. package/build/charts/ScatterGraph.d.ts +4 -4
  2. package/build/charts/ScatterGraph.js +2 -2
  3. package/build/data/ArrayElementView.spec.d.ts +1 -0
  4. package/build/data/ArrayElementView.spec.js +81 -0
  5. package/build/data/Binding.spec.d.ts +1 -0
  6. package/build/data/Binding.spec.js +61 -0
  7. package/build/data/Expression.spec.d.ts +1 -0
  8. package/build/data/Expression.spec.js +196 -0
  9. package/build/data/Grouper.spec.d.ts +1 -0
  10. package/build/data/Grouper.spec.js +48 -0
  11. package/build/data/Ref.spec.d.ts +1 -0
  12. package/build/data/Ref.spec.js +72 -0
  13. package/build/data/Selector.d.ts +1 -1
  14. package/build/data/Store.spec.d.ts +1 -0
  15. package/build/data/Store.spec.js +19 -0
  16. package/build/data/StoreRef.spec.d.ts +1 -0
  17. package/build/data/StoreRef.spec.js +22 -0
  18. package/build/data/StringTemplate.spec.d.ts +1 -0
  19. package/build/data/StringTemplate.spec.js +112 -0
  20. package/build/data/StructuredSelector.spec.d.ts +1 -0
  21. package/build/data/StructuredSelector.spec.js +102 -0
  22. package/build/data/View.spec.d.ts +1 -0
  23. package/build/data/View.spec.js +44 -0
  24. package/build/data/ZoomIntoPropertyView.spec.d.ts +1 -0
  25. package/build/data/ZoomIntoPropertyView.spec.js +54 -0
  26. package/build/data/comparer.spec.d.ts +1 -0
  27. package/build/data/comparer.spec.js +50 -0
  28. package/build/data/computable.d.ts +3 -6
  29. package/build/data/computable.spec.d.ts +1 -0
  30. package/build/data/computable.spec.js +56 -0
  31. package/build/data/createAccessorModelProxy.d.ts +5 -3
  32. package/build/data/createAccessorModelProxy.spec.d.ts +1 -0
  33. package/build/data/createAccessorModelProxy.spec.js +30 -0
  34. package/build/data/createStructuredSelector.spec.d.ts +1 -0
  35. package/build/data/createStructuredSelector.spec.js +42 -0
  36. package/build/data/diff/diffs.spec.d.ts +1 -0
  37. package/build/data/diff/diffs.spec.js +45 -0
  38. package/build/data/getAccessor.spec.d.ts +1 -0
  39. package/build/data/getAccessor.spec.js +10 -0
  40. package/build/data/getSelector.spec.d.ts +1 -0
  41. package/build/data/getSelector.spec.js +36 -0
  42. package/build/data/ops/append.spec.d.ts +1 -0
  43. package/build/data/ops/append.spec.js +24 -0
  44. package/build/data/ops/filter.spec.d.ts +1 -0
  45. package/build/data/ops/filter.spec.js +25 -0
  46. package/build/data/ops/findTreeNode.d.ts +1 -1
  47. package/build/data/ops/findTreeNode.js +1 -1
  48. package/build/data/ops/findTreeNode.spec.d.ts +1 -0
  49. package/build/data/ops/findTreeNode.spec.js +20 -0
  50. package/build/data/ops/findTreePath.d.ts +1 -1
  51. package/build/data/ops/merge.spec.d.ts +1 -0
  52. package/build/data/ops/merge.spec.js +23 -0
  53. package/build/data/ops/removeTreeNodes.d.ts +1 -1
  54. package/build/data/ops/removeTreeNodes.js +1 -1
  55. package/build/data/ops/removeTreeNodes.spec.d.ts +1 -0
  56. package/build/data/ops/removeTreeNodes.spec.js +35 -0
  57. package/build/data/ops/updateArray.spec.d.ts +1 -0
  58. package/build/data/ops/updateArray.spec.js +33 -0
  59. package/build/data/ops/updateTree.d.ts +1 -1
  60. package/build/data/ops/updateTree.spec.d.ts +1 -0
  61. package/build/data/ops/updateTree.spec.js +44 -0
  62. package/build/hooks/invokeCallback.spec.d.ts +1 -0
  63. package/build/hooks/invokeCallback.spec.js +44 -0
  64. package/build/hooks/resolveCallback.spec.d.ts +1 -0
  65. package/build/hooks/resolveCallback.spec.js +35 -0
  66. package/build/hooks/store.spec.d.ts +1 -0
  67. package/build/hooks/store.spec.js +48 -0
  68. package/build/hooks/useTrigger.spec.d.ts +1 -0
  69. package/build/hooks/useTrigger.spec.js +59 -0
  70. package/build/jsx-runtime.d.ts +10 -10
  71. package/build/jsx-runtime.js +6 -0
  72. package/build/svg/util/Rect.d.ts +1 -1
  73. package/build/ui/ContentResolver.d.ts +16 -6
  74. package/build/ui/Controller.d.ts +7 -0
  75. package/build/ui/Controller.js +2 -1
  76. package/build/ui/Controller.spec.d.ts +1 -0
  77. package/build/ui/Controller.spec.js +247 -0
  78. package/build/ui/Cx.spec.d.ts +1 -0
  79. package/build/ui/Cx.spec.js +153 -0
  80. package/build/ui/DataProxy.spec.d.ts +1 -0
  81. package/build/ui/DataProxy.spec.js +208 -0
  82. package/build/ui/Instance.d.ts +1 -1
  83. package/build/ui/Instance.js +10 -10
  84. package/build/ui/IsolatedScope.spec.d.ts +1 -0
  85. package/build/ui/IsolatedScope.spec.js +42 -0
  86. package/build/ui/Prop.d.ts +12 -1
  87. package/build/ui/PureContainer.spec.d.ts +1 -0
  88. package/build/ui/PureContainer.spec.js +149 -0
  89. package/build/ui/Repeater.d.ts +3 -3
  90. package/build/ui/Repeater.spec.d.ts +1 -0
  91. package/build/ui/Repeater.spec.js +109 -0
  92. package/build/ui/Rescope.spec.d.ts +1 -0
  93. package/build/ui/Rescope.spec.js +134 -0
  94. package/build/ui/Restate.spec.d.ts +1 -0
  95. package/build/ui/Restate.spec.js +257 -0
  96. package/build/ui/Text.d.ts +14 -2
  97. package/build/ui/Text.js +3 -0
  98. package/build/ui/adapter/ArrayAdapter.js +4 -1
  99. package/build/ui/adapter/ArrayAdapter.spec.d.ts +1 -0
  100. package/build/ui/adapter/ArrayAdapter.spec.js +44 -0
  101. package/build/ui/adapter/TreeAdapter.spec.d.ts +1 -0
  102. package/build/ui/adapter/TreeAdapter.spec.js +71 -0
  103. package/build/ui/app/Url.spec.d.ts +1 -0
  104. package/build/ui/app/Url.spec.js +43 -0
  105. package/build/ui/app/startHotAppLoop.js +1 -1
  106. package/build/ui/createFunctionalComponent.d.ts +14 -1
  107. package/build/ui/createFunctionalComponent.js +7 -4
  108. package/build/ui/createFunctionalComponent.spec.d.ts +1 -0
  109. package/build/ui/createFunctionalComponent.spec.js +272 -0
  110. package/build/ui/expr.d.ts +3 -1
  111. package/build/ui/exprHelpers.d.ts +32 -0
  112. package/build/ui/exprHelpers.js +61 -0
  113. package/build/ui/index.d.ts +1 -0
  114. package/build/ui/index.js +1 -0
  115. package/build/ui/layout/ContentPlaceholder.spec.d.ts +1 -0
  116. package/build/ui/layout/ContentPlaceholder.spec.js +333 -0
  117. package/build/ui/layout/FirstVisibleChildLayout.spec.d.ts +1 -0
  118. package/build/ui/layout/FirstVisibleChildLayout.spec.js +101 -0
  119. package/build/util/Console.d.ts +1 -0
  120. package/build/util/Console.js +7 -3
  121. package/build/util/Format.spec.d.ts +1 -0
  122. package/build/util/Format.spec.js +58 -0
  123. package/build/util/TraversalStack.spec.d.ts +1 -0
  124. package/build/util/TraversalStack.spec.js +43 -0
  125. package/build/util/date/upperBoundCheck.spec.d.ts +1 -0
  126. package/build/util/date/upperBoundCheck.spec.js +22 -0
  127. package/build/util/getSearchQueryPredicate.spec.d.ts +1 -0
  128. package/build/util/getSearchQueryPredicate.spec.js +33 -0
  129. package/build/util/isValidIdentifierName.spec.d.ts +1 -0
  130. package/build/util/isValidIdentifierName.spec.js +28 -0
  131. package/build/util/routeAppend.spec.d.ts +1 -0
  132. package/build/util/routeAppend.spec.js +14 -0
  133. package/build/widgets/AccessorBindings.spec.d.ts +1 -0
  134. package/build/widgets/AccessorBindings.spec.js +40 -0
  135. package/build/widgets/Button.d.ts +3 -6
  136. package/build/widgets/Button.js +1 -1
  137. package/build/widgets/DocumentTitle.d.ts +2 -0
  138. package/build/widgets/Heading.d.ts +2 -2
  139. package/build/widgets/HtmlElement.d.ts +31 -8
  140. package/build/widgets/HtmlElement.js +7 -9
  141. package/build/widgets/HtmlElement.spec.d.ts +1 -0
  142. package/build/widgets/HtmlElement.spec.js +38 -0
  143. package/build/widgets/Icon.d.ts +3 -13
  144. package/build/widgets/List.d.ts +4 -0
  145. package/build/widgets/ReactElementWrapper.d.ts +29 -0
  146. package/build/widgets/ReactElementWrapper.js +59 -0
  147. package/build/widgets/drag-drop/DragSource.d.ts +3 -3
  148. package/build/widgets/drag-drop/DragSource.js +2 -3
  149. package/build/widgets/drag-drop/DropZone.d.ts +3 -3
  150. package/build/widgets/drag-drop/DropZone.js +2 -3
  151. package/build/widgets/form/Checkbox.d.ts +2 -0
  152. package/build/widgets/form/ColorField.d.ts +2 -0
  153. package/build/widgets/form/DateTimeField.d.ts +2 -0
  154. package/build/widgets/form/Field.d.ts +0 -2
  155. package/build/widgets/form/LabeledContainer.d.ts +9 -8
  156. package/build/widgets/form/LabeledContainer.js +9 -9
  157. package/build/widgets/form/LookupField.d.ts +57 -9
  158. package/build/widgets/form/MonthField.d.ts +2 -0
  159. package/build/widgets/form/NumberField.d.ts +2 -0
  160. package/build/widgets/form/Radio.d.ts +2 -0
  161. package/build/widgets/form/Select.d.ts +2 -0
  162. package/build/widgets/form/Slider.d.ts +3 -0
  163. package/build/widgets/form/Switch.d.ts +2 -0
  164. package/build/widgets/form/TextField.d.ts +34 -0
  165. package/build/widgets/form/TimeList.d.ts +16 -1
  166. package/build/widgets/form/TimeList.js +34 -62
  167. package/build/widgets/form/UploadButton.d.ts +34 -2
  168. package/build/widgets/form/UploadButton.js +3 -1
  169. package/build/widgets/form/ValidationGroup.spec.d.ts +1 -0
  170. package/build/widgets/form/ValidationGroup.spec.js +62 -0
  171. package/build/widgets/form/Validator.d.ts +33 -2
  172. package/build/widgets/form/Validator.js +3 -0
  173. package/build/widgets/grid/Grid.d.ts +9 -9
  174. package/build/widgets/grid/TreeNode.d.ts +6 -0
  175. package/build/widgets/index.d.ts +1 -0
  176. package/build/widgets/index.js +1 -0
  177. package/build/widgets/nav/MenuItem.d.ts +3 -2
  178. package/build/widgets/nav/Route.spec.d.ts +1 -0
  179. package/build/widgets/nav/Route.spec.js +15 -0
  180. package/build/widgets/nav/Scroller.d.ts +4 -6
  181. package/build/widgets/nav/Scroller.js +6 -3
  182. package/build/widgets/nav/Tab.d.ts +2 -2
  183. package/build/widgets/overlay/ContextMenu.d.ts +3 -3
  184. package/build/widgets/overlay/Overlay.d.ts +2 -1
  185. package/build/widgets/overlay/Overlay.js +1 -1
  186. package/build/widgets/overlay/createHotPromiseWindowFactory.js +0 -1
  187. package/build.js +133 -133
  188. package/dist/data.js +2 -2
  189. package/dist/jsx-runtime.js +6 -1
  190. package/dist/manifest.d.ts +1443 -0
  191. package/dist/manifest.js +761 -713
  192. package/dist/ui.js +91 -5
  193. package/dist/util.js +3 -0
  194. package/dist/widgets.js +520 -162
  195. package/package.json +46 -20
  196. package/src/charts/Chart.ts +108 -108
  197. package/src/charts/ScatterGraph.tsx +6 -6
  198. package/src/data/ArrayElementView.ts +90 -90
  199. package/src/data/AugmentedViewBase.ts +88 -88
  200. package/src/data/Binding.ts +104 -104
  201. package/src/data/ExposedRecordView.ts +95 -95
  202. package/src/data/ExposedValueView.ts +89 -89
  203. package/src/data/Expression.spec.ts +229 -229
  204. package/src/data/Expression.ts +233 -233
  205. package/src/data/Grouper.spec.ts +57 -57
  206. package/src/data/Grouper.ts +158 -158
  207. package/src/data/NestedDataView.ts +43 -43
  208. package/src/data/ReadOnlyDataView.ts +39 -39
  209. package/src/data/Ref.ts +104 -104
  210. package/src/data/Selector.ts +10 -10
  211. package/src/data/Store.ts +52 -52
  212. package/src/data/StoreProxy.ts +19 -19
  213. package/src/data/StoreRef.ts +66 -66
  214. package/src/data/StringTemplate.spec.ts +132 -132
  215. package/src/data/StringTemplate.ts +93 -93
  216. package/src/data/StructuredSelector.spec.ts +113 -113
  217. package/src/data/StructuredSelector.ts +146 -146
  218. package/src/data/SubscribableView.ts +63 -63
  219. package/src/data/ZoomIntoPropertyView.spec.ts +64 -64
  220. package/src/data/ZoomIntoPropertyView.ts +45 -45
  221. package/src/data/computable.spec.ts +87 -62
  222. package/src/data/computable.ts +3 -6
  223. package/src/data/createAccessorModelProxy.spec.tsx +102 -1
  224. package/src/data/createAccessorModelProxy.ts +9 -3
  225. package/src/data/createStructuredSelector.ts +62 -62
  226. package/src/data/getAccessor.spec.ts +11 -11
  227. package/src/data/getAccessor.ts +74 -74
  228. package/src/data/getSelector.spec.ts +43 -43
  229. package/src/data/getSelector.ts +66 -66
  230. package/src/data/ops/filter.spec.ts +35 -35
  231. package/src/data/ops/filter.ts +9 -9
  232. package/src/data/ops/findTreeNode.ts +1 -5
  233. package/src/data/ops/findTreePath.ts +1 -1
  234. package/src/data/ops/merge.ts +13 -13
  235. package/src/data/ops/removeTreeNodes.spec.ts +37 -37
  236. package/src/data/ops/removeTreeNodes.ts +2 -2
  237. package/src/data/ops/updateArray.spec.ts +69 -69
  238. package/src/data/ops/updateArray.ts +31 -31
  239. package/src/data/ops/updateTree.ts +1 -1
  240. package/src/data/test-types.ts +7 -7
  241. package/src/hooks/resolveCallback.spec.tsx +30 -7
  242. package/src/hooks/useTrigger.ts +26 -26
  243. package/src/index.scss +6 -6
  244. package/src/jsx-dev-runtime.ts +4 -4
  245. package/src/jsx-runtime.spec.tsx +431 -0
  246. package/src/jsx-runtime.ts +26 -22
  247. package/src/svg/BoundedObject.ts +101 -101
  248. package/src/svg/util/Rect.ts +105 -105
  249. package/src/ui/CSSHelper.ts +17 -17
  250. package/src/ui/ContentResolver.spec.tsx +172 -19
  251. package/src/ui/ContentResolver.ts +16 -8
  252. package/src/ui/Controller.ts +15 -2
  253. package/src/ui/Culture.ts +159 -159
  254. package/src/ui/DataProxy.ts +55 -55
  255. package/src/ui/FocusManager.ts +171 -171
  256. package/src/ui/Instance.ts +866 -868
  257. package/src/ui/Prop.ts +140 -112
  258. package/src/ui/RenderingContext.ts +99 -99
  259. package/src/ui/Repeater.ts +3 -12
  260. package/src/ui/Rescope.ts +49 -49
  261. package/src/ui/StructuredInstanceDataAccessor.ts +32 -32
  262. package/src/ui/Text.ts +21 -2
  263. package/src/ui/VDOM.ts +34 -34
  264. package/src/ui/adapter/ArrayAdapter.spec.ts +55 -55
  265. package/src/ui/adapter/ArrayAdapter.ts +4 -1
  266. package/src/ui/adapter/TreeAdapter.spec.ts +76 -76
  267. package/src/ui/adapter/TreeAdapter.ts +185 -185
  268. package/src/ui/app/History.ts +133 -133
  269. package/src/ui/app/Url.spec.ts +50 -50
  270. package/src/ui/app/startHotAppLoop.ts +41 -41
  271. package/src/ui/createFunctionalComponent.spec.tsx +53 -0
  272. package/src/ui/createFunctionalComponent.ts +86 -65
  273. package/src/ui/expr.ts +4 -1
  274. package/src/ui/exprHelpers.spec.ts +379 -0
  275. package/src/ui/exprHelpers.ts +78 -0
  276. package/src/ui/index.ts +47 -46
  277. package/src/ui/layout/Content.ts +30 -30
  278. package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +1 -1
  279. package/src/ui/layout/FirstVisibleChildLayout.ts +60 -60
  280. package/src/ui/selection/KeySelection.ts +153 -153
  281. package/src/ui/selection/Selection.ts +128 -128
  282. package/src/util/Console.ts +13 -11
  283. package/src/util/Format.spec.ts +41 -41
  284. package/src/util/Format.ts +267 -267
  285. package/src/util/addEventListenerWithOptions.ts +41 -41
  286. package/src/util/browserSupportsPassiveEventHandlers.ts +20 -20
  287. package/src/util/color/rgbToHsl.ts +35 -35
  288. package/src/util/getActiveElement.ts +4 -4
  289. package/src/util/hasKey.ts +18 -18
  290. package/src/util/index.ts +55 -55
  291. package/src/util/innerTextTrim.ts +10 -10
  292. package/src/util/isArray.ts +3 -3
  293. package/src/util/isDataRecord.ts +5 -5
  294. package/src/util/isDefined.ts +3 -3
  295. package/src/util/isString.ts +3 -3
  296. package/src/widgets/AccessorBindings.spec.tsx +26 -0
  297. package/src/widgets/Button.tsx +5 -17
  298. package/src/widgets/DocumentTitle.ts +95 -92
  299. package/src/widgets/Heading.ts +2 -2
  300. package/src/widgets/HtmlElement.spec.helpers.tsx +108 -0
  301. package/src/widgets/HtmlElement.spec.tsx +20 -12
  302. package/src/widgets/HtmlElement.tsx +77 -23
  303. package/src/widgets/Icon.ts +3 -17
  304. package/src/widgets/List.tsx +6 -0
  305. package/src/widgets/ReactElementWrapper.spec.tsx +452 -0
  306. package/src/widgets/ReactElementWrapper.tsx +108 -0
  307. package/src/widgets/Sandbox.ts +103 -103
  308. package/src/widgets/autoFocus.ts +9 -9
  309. package/src/widgets/cx.ts +63 -63
  310. package/src/widgets/drag-drop/DragSource.tsx +3 -4
  311. package/src/widgets/drag-drop/DropZone.tsx +3 -4
  312. package/src/widgets/form/Checkbox.tsx +3 -0
  313. package/src/widgets/form/ColorField.tsx +3 -0
  314. package/src/widgets/form/DateTimeField.tsx +5 -0
  315. package/src/widgets/form/Field.tsx +0 -3
  316. package/src/widgets/form/Label.tsx +1 -0
  317. package/src/widgets/form/LabeledContainer.ts +22 -26
  318. package/src/widgets/form/LookupField.spec.tsx +93 -0
  319. package/src/widgets/form/LookupField.tsx +104 -9
  320. package/src/widgets/form/MonthField.tsx +5 -0
  321. package/src/widgets/form/NumberField.tsx +3 -0
  322. package/src/widgets/form/Radio.tsx +5 -0
  323. package/src/widgets/form/Select.tsx +5 -0
  324. package/src/widgets/form/Slider.tsx +4 -0
  325. package/src/widgets/form/Switch.tsx +3 -0
  326. package/src/widgets/form/TextField.tsx +62 -0
  327. package/src/widgets/form/TimeList.tsx +84 -73
  328. package/src/widgets/form/UploadButton.tsx +53 -2
  329. package/src/widgets/form/Validator.ts +40 -3
  330. package/src/widgets/grid/Grid.tsx +9 -12
  331. package/src/widgets/grid/GridCell.ts +143 -143
  332. package/src/widgets/grid/TreeNode.tsx +9 -0
  333. package/src/widgets/icons/calendar.tsx +17 -17
  334. package/src/widgets/icons/check.tsx +13 -13
  335. package/src/widgets/icons/clear.tsx +15 -15
  336. package/src/widgets/icons/close.tsx +20 -20
  337. package/src/widgets/icons/cx.tsx +38 -38
  338. package/src/widgets/icons/drop-down.tsx +15 -15
  339. package/src/widgets/icons/file.tsx +13 -13
  340. package/src/widgets/icons/folder-open.tsx +15 -15
  341. package/src/widgets/icons/folder.tsx +13 -13
  342. package/src/widgets/icons/forward.tsx +22 -22
  343. package/src/widgets/icons/loading.tsx +24 -24
  344. package/src/widgets/icons/menu.tsx +17 -17
  345. package/src/widgets/icons/pixel-picker.tsx +18 -18
  346. package/src/widgets/icons/search.tsx +13 -13
  347. package/src/widgets/icons/sort-asc.tsx +14 -14
  348. package/src/widgets/icons/square.tsx +18 -18
  349. package/src/widgets/index.ts +1 -0
  350. package/src/widgets/nav/MenuItem.tsx +3 -2
  351. package/src/widgets/nav/Route.ts +142 -142
  352. package/src/widgets/nav/Scroller.tsx +8 -9
  353. package/src/widgets/nav/Tab.ts +2 -2
  354. package/src/widgets/overlay/ContextMenu.ts +42 -42
  355. package/src/widgets/overlay/Dropdown.tsx +762 -762
  356. package/src/widgets/overlay/MsgBox.tsx +141 -141
  357. package/src/widgets/overlay/Overlay.tsx +5 -4
  358. package/src/widgets/overlay/Toast.ts +111 -111
  359. package/src/widgets/overlay/Window.tsx +299 -299
  360. package/src/widgets/overlay/alerts.ts +46 -46
  361. package/src/widgets/overlay/captureMouse.ts +195 -195
  362. package/src/widgets/overlay/createHotPromiseWindowFactory.ts +0 -1
  363. package/src/widgets/overlay/index.d.ts +11 -11
  364. package/src/widgets/overlay/index.ts +11 -11
  365. package/src/widgets/overlay/tooltip-ops.ts +173 -173
@@ -0,0 +1,42 @@
1
+ import { jsx as _jsx } from "cx/jsx-runtime";
2
+ import { Store } from "../data/Store";
3
+ import { createTestRenderer } from "../util/test/createTestRenderer";
4
+ import assert from "assert";
5
+ import { IsolatedScope } from "./IsolatedScope";
6
+ import { bind } from "./bind";
7
+ describe("IsolatedScope", () => {
8
+ it("prevents multiple re-renders", () => {
9
+ let list = [];
10
+ let widget = (_jsx("cx", { children: _jsx(IsolatedScope, { data: {
11
+ value: { bind: 'value' }
12
+ }, children: _jsx("span", { text: bind("value"), onExplore: (context, { store }) => {
13
+ list.push(store.get("value"));
14
+ } }) }) }));
15
+ let store = new Store({
16
+ data: {
17
+ value: "bad",
18
+ },
19
+ });
20
+ const component = createTestRenderer(store, widget);
21
+ let tree = component.toJSON();
22
+ assert.deepEqual(list, ["bad"]);
23
+ assert.deepEqual(tree, {
24
+ type: "span",
25
+ props: {},
26
+ children: ["bad"],
27
+ });
28
+ //component should not re-render if unrelated data changes
29
+ store.set("dummy", "dummy");
30
+ tree = component.toJSON();
31
+ assert.deepEqual(list, ["bad"]);
32
+ //component should not re-render if unrelated data changes
33
+ store.set("value", "good");
34
+ tree = component.toJSON();
35
+ assert.deepEqual(list, ["bad", "good"]);
36
+ assert.deepEqual(tree, {
37
+ type: "span",
38
+ props: {},
39
+ children: ["good"],
40
+ });
41
+ });
42
+ });
@@ -45,9 +45,20 @@ export type ResolveProp<P> = P extends Selector<infer T> ? T : P extends Accesso
45
45
  * Utility type that resolves a structured prop object to its runtime value types.
46
46
  * Transforms { name: StringProp, count: NumberProp } to { name: string, count: number }
47
47
  */
48
- export type ResolveStructuredProp<S> = {
48
+ export type ResolveStructuredPropType<S> = {
49
49
  [K in keyof S]: ResolveProp<S[K]>;
50
50
  };
51
+ /**
52
+ * Resolves the runtime value type from either a Prop<T> or a StructuredProp.
53
+ * Use this for generic widgets like ContentResolver and Validator where the
54
+ * input can be either a single prop or a structured object.
55
+ *
56
+ * - For Prop<T> (Selector, AccessorChain, GetSet), resolves to T
57
+ * - For bindings (Bind, Tpl, Expr), resolves to any/string/any
58
+ * - For structured objects, recursively resolves each property via ResolveStructuredProp
59
+ * - For literal values, returns them as-is
60
+ */
61
+ export type ResolvePropType<P> = P extends Selector<infer T> ? T : P extends AccessorChain<infer T> ? T : P extends GetSet<infer T> ? T : P extends Bind ? any : P extends Tpl ? string : P extends Expr ? any : P extends object ? ResolveStructuredPropType<P> : P;
51
62
  /**
52
63
  * Generic structured prop type that provides type safety for params and their resolved values.
53
64
  * Use with ContentResolver and similar widgets to type the onResolve callback params.
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,149 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "cx/jsx-runtime";
2
+ import { Store } from "../data/Store";
3
+ import assert from "assert";
4
+ import { createTestRenderer } from "../util/test/createTestRenderer";
5
+ import { bind } from "./bind";
6
+ import { PureContainer } from "./PureContainer";
7
+ describe("PureContainer", () => {
8
+ it("renders static text children", () => {
9
+ let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { children: "Test" }) }) }));
10
+ let store = new Store();
11
+ const component = createTestRenderer(store, widget);
12
+ let tree = component.toJSON();
13
+ assert(tree && !Array.isArray(tree), "Expected single element");
14
+ assert.deepEqual(tree, {
15
+ type: "div",
16
+ props: {},
17
+ children: ["Test"],
18
+ });
19
+ });
20
+ it("renders multiple children", () => {
21
+ let widget = (_jsx("cx", { children: _jsxs(PureContainer, { children: [_jsx("div", { children: "First" }), _jsx("div", { children: "Second" }), _jsx("div", { children: "Third" })] }) }));
22
+ let store = new Store();
23
+ const component = createTestRenderer(store, widget);
24
+ let tree = component.toJSON();
25
+ assert(Array.isArray(tree), "Expected array of elements");
26
+ assert.equal(tree.length, 3);
27
+ assert.deepEqual(tree, [
28
+ {
29
+ type: "div",
30
+ props: {},
31
+ children: ["First"],
32
+ },
33
+ {
34
+ type: "div",
35
+ props: {},
36
+ children: ["Second"],
37
+ },
38
+ {
39
+ type: "div",
40
+ props: {},
41
+ children: ["Third"],
42
+ },
43
+ ]);
44
+ });
45
+ it("renders children with data bindings", () => {
46
+ let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { text: bind("message") }) }) }));
47
+ let store = new Store({
48
+ data: {
49
+ message: "Hello World",
50
+ },
51
+ });
52
+ const component = createTestRenderer(store, widget);
53
+ let tree = component.toJSON();
54
+ assert(tree && !Array.isArray(tree), "Expected single element");
55
+ assert.deepEqual(tree, {
56
+ type: "div",
57
+ props: {},
58
+ children: ["Hello World"],
59
+ });
60
+ });
61
+ it("renders nested containers", () => {
62
+ let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { children: _jsx(PureContainer, { children: _jsx("span", { children: "Nested" }) }) }) }) }));
63
+ let store = new Store();
64
+ const component = createTestRenderer(store, widget);
65
+ let tree = component.toJSON();
66
+ assert(tree && !Array.isArray(tree), "Expected single element");
67
+ assert.deepEqual(tree, {
68
+ type: "div",
69
+ props: {},
70
+ children: [
71
+ {
72
+ type: "span",
73
+ props: {},
74
+ children: ["Nested"],
75
+ },
76
+ ],
77
+ });
78
+ });
79
+ it("conditionally renders children based on visible binding", () => {
80
+ let widget = (_jsx("cx", { children: _jsxs(PureContainer, { children: [_jsx("div", { visible: bind("show"), text: "Visible" }), _jsx("div", { visible: false, text: "Hidden" })] }) }));
81
+ let store = new Store({
82
+ data: {
83
+ show: true,
84
+ },
85
+ });
86
+ const component = createTestRenderer(store, widget);
87
+ let tree = component.toJSON();
88
+ assert(tree && !Array.isArray(tree), "Expected single element");
89
+ assert.deepEqual(tree, {
90
+ type: "div",
91
+ props: {},
92
+ children: ["Visible"],
93
+ });
94
+ });
95
+ it("handles empty children", () => {
96
+ let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", {}) }) }));
97
+ let store = new Store();
98
+ const component = createTestRenderer(store, widget);
99
+ let tree = component.toJSON();
100
+ assert(tree && !Array.isArray(tree), "Expected single element");
101
+ assert.deepEqual(tree, {
102
+ type: "div",
103
+ props: {},
104
+ children: null,
105
+ });
106
+ });
107
+ it("renders children from items property", () => {
108
+ let widget = (_jsx("cx", { children: _jsx(PureContainer, { items: [_jsx("div", { children: "Item 1" }, "1"), _jsx("div", { children: "Item 2" }, "2")] }) }));
109
+ let store = new Store();
110
+ const component = createTestRenderer(store, widget);
111
+ let tree = component.toJSON();
112
+ assert(Array.isArray(tree), "Expected array of elements");
113
+ assert.equal(tree.length, 2);
114
+ assert.deepEqual(tree[0], {
115
+ type: "div",
116
+ props: {},
117
+ children: ["Item 1"],
118
+ });
119
+ assert.deepEqual(tree[1], {
120
+ type: "div",
121
+ props: {},
122
+ children: ["Item 2"],
123
+ });
124
+ });
125
+ it("updates children when store data changes", () => {
126
+ let widget = (_jsx("cx", { children: _jsx(PureContainer, { children: _jsx("div", { text: bind("count") }) }) }));
127
+ let store = new Store({
128
+ data: {
129
+ count: 0,
130
+ },
131
+ });
132
+ const component = createTestRenderer(store, widget);
133
+ let tree = component.toJSON();
134
+ assert.deepEqual(tree, {
135
+ type: "div",
136
+ props: {},
137
+ children: ["0"],
138
+ });
139
+ // Update the store
140
+ store.set("count", 5);
141
+ // Re-render
142
+ tree = component.toJSON();
143
+ assert.deepEqual(tree, {
144
+ type: "div",
145
+ props: {},
146
+ children: ["5"],
147
+ });
148
+ });
149
+ });
@@ -1,13 +1,13 @@
1
1
  import { ContainerBase, ContainerConfig } from "./Container";
2
2
  import { ArrayAdapter } from "./adapter/ArrayAdapter";
3
3
  import { RenderingContext } from "./RenderingContext";
4
- import { Prop, StringProp, StructuredProp, RecordAlias, SortersProp, CollatorOptions, SortDirection, DataRecord } from "./Prop";
4
+ import { Prop, StringProp, StructuredProp, RecordAlias, SortersProp, CollatorOptions, SortDirection } from "./Prop";
5
5
  import { Instance } from "./Instance";
6
6
  import { DataAdapter, DataAdapterRecord } from "./adapter/DataAdapter";
7
7
  import type { GroupAdapter } from "./adapter/GroupAdapter";
8
8
  import type { TreeAdapter } from "./adapter/TreeAdapter";
9
9
  import { Create } from "../util/Component";
10
- export interface RepeaterConfig<T = DataRecord> extends ContainerConfig {
10
+ export interface RepeaterConfig<T = any> extends ContainerConfig {
11
11
  /** An array of records to be displayed. */
12
12
  records?: Prop<T[]>;
13
13
  /** Alias used to expose the record in the child scope. Default is `$record`. */
@@ -47,7 +47,7 @@ export interface RepeaterConfig<T = DataRecord> extends ContainerConfig {
47
47
  /** Data adapter used to convert data in the list of records. Used for manipulation of records, e.g flattening the tree records. */
48
48
  dataAdapter?: Create<typeof DataAdapter> | Create<typeof ArrayAdapter> | Create<typeof TreeAdapter> | Create<typeof GroupAdapter>;
49
49
  }
50
- export declare class Repeater<Config extends RepeaterConfig = RepeaterConfig> extends ContainerBase<Config> {
50
+ export declare class Repeater<T = any> extends ContainerBase<RepeaterConfig<T>> {
51
51
  records?: any;
52
52
  recordsAccessor: any;
53
53
  recordAlias?: string;
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,109 @@
1
+ import { jsx as _jsx } from "cx/jsx-runtime";
2
+ import { Store } from "../data/Store";
3
+ import { Repeater } from "./Repeater";
4
+ import { bind } from "./bind";
5
+ import { createTestRenderer } from "../util/test/createTestRenderer";
6
+ import assert from "assert";
7
+ describe("Repeater", () => {
8
+ it("allows sorting", () => {
9
+ let data = [
10
+ {
11
+ value: "C",
12
+ },
13
+ {
14
+ value: "B",
15
+ },
16
+ {
17
+ value: "A",
18
+ },
19
+ ];
20
+ let widget = (_jsx("cx", { children: _jsx("div", { children: _jsx(Repeater, { records: data, sorters: [{ field: "value", direction: "ASC" }], recordAlias: "$item", children: _jsx("div", { text: bind("$item.value") }) }) }) }));
21
+ let store = new Store();
22
+ const component = createTestRenderer(store, widget);
23
+ let tree = component.toJSON();
24
+ assert.deepEqual(tree, {
25
+ type: "div",
26
+ props: {},
27
+ children: [
28
+ {
29
+ type: "div",
30
+ props: {},
31
+ children: ["A"],
32
+ },
33
+ {
34
+ type: "div",
35
+ props: {},
36
+ children: ["B"],
37
+ },
38
+ {
39
+ type: "div",
40
+ props: {},
41
+ children: ["C"],
42
+ },
43
+ ],
44
+ });
45
+ });
46
+ it("changes are properly updated", () => {
47
+ let divInstances = [];
48
+ let widget = (_jsx("cx", { children: _jsx("div", { children: _jsx(Repeater, { records: bind("data"), sorters: [{ field: "value", direction: "ASC" }], recordAlias: "$item", children: _jsx("div", { text: bind("$item.value"), onExplore: (context, instance) => {
49
+ divInstances.push(instance);
50
+ } }) }) }) }));
51
+ let store = new Store({
52
+ data: {
53
+ data: [
54
+ {
55
+ value: "C",
56
+ },
57
+ {
58
+ value: "B",
59
+ },
60
+ ],
61
+ },
62
+ });
63
+ const component = createTestRenderer(store, widget);
64
+ let tree = component.toJSON();
65
+ assert.deepEqual(tree, {
66
+ type: "div",
67
+ props: {},
68
+ children: [
69
+ {
70
+ type: "div",
71
+ props: {},
72
+ children: ["B"],
73
+ },
74
+ {
75
+ type: "div",
76
+ props: {},
77
+ children: ["C"],
78
+ },
79
+ ],
80
+ });
81
+ divInstances = [];
82
+ store.update("data", (data) => [{ value: "A" }, ...data]);
83
+ assert.deepEqual(component.toJSON(), {
84
+ type: "div",
85
+ props: {},
86
+ children: [
87
+ {
88
+ type: "div",
89
+ props: {},
90
+ children: ["A"],
91
+ },
92
+ {
93
+ type: "div",
94
+ props: {},
95
+ children: ["B"],
96
+ },
97
+ {
98
+ type: "div",
99
+ props: {},
100
+ children: ["C"],
101
+ },
102
+ ],
103
+ });
104
+ assert.equal(divInstances.length, 3);
105
+ assert.equal(divInstances[0].store.get("$item.value"), "A");
106
+ assert.equal(divInstances[1].store.get("$item.value"), "B");
107
+ assert.equal(divInstances[2].store.get("$item.value"), "C");
108
+ });
109
+ });
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,134 @@
1
+ import { jsx as _jsx, jsxs as _jsxs } from "cx/jsx-runtime";
2
+ import { Store } from "../data/Store";
3
+ import { Rescope } from "./Rescope";
4
+ import { bind } from "./bind";
5
+ import { createTestRenderer } from "../util/test/createTestRenderer";
6
+ import { Controller } from "./Controller";
7
+ import assert from "assert";
8
+ import { PureContainer } from "./PureContainer";
9
+ describe("Rescope", () => {
10
+ it("allows simple access to nested data", () => {
11
+ let store = new Store({
12
+ data: {
13
+ $page: {
14
+ data: {
15
+ name: "John",
16
+ },
17
+ },
18
+ },
19
+ });
20
+ let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", children: _jsx("div", { text: bind("name") }) }) }));
21
+ const component = createTestRenderer(store, widget);
22
+ let tree = component.toJSON();
23
+ assert.deepEqual(tree, {
24
+ type: "div",
25
+ props: {},
26
+ children: ["John"],
27
+ });
28
+ });
29
+ it("allows parent access through $root", () => {
30
+ let store = new Store({
31
+ data: {
32
+ layout: {
33
+ title: "Title",
34
+ },
35
+ $page: {
36
+ data: {
37
+ name: "John",
38
+ },
39
+ },
40
+ },
41
+ });
42
+ let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", children: _jsx("div", { text: bind("$root.layout.title") }) }) }));
43
+ const component = createTestRenderer(store, widget);
44
+ let tree = component.toJSON();
45
+ assert.deepEqual(tree, {
46
+ type: "div",
47
+ props: {},
48
+ children: ["Title"],
49
+ });
50
+ });
51
+ it("allows nested data access through data", () => {
52
+ let store = new Store({
53
+ data: {
54
+ layout: {
55
+ title: "Title",
56
+ },
57
+ },
58
+ });
59
+ let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page", data: { $title: { bind: "layout.title" } }, children: _jsx("div", { text: bind("$title") }) }) }));
60
+ const component = createTestRenderer(store, widget);
61
+ let tree = component.toJSON();
62
+ assert.deepEqual(tree, {
63
+ type: "div",
64
+ props: {},
65
+ children: ["Title"],
66
+ });
67
+ });
68
+ it("nested data mutations are correctly propagated to the parent store", () => {
69
+ let store = new Store({
70
+ data: {
71
+ item: {
72
+ value: 0,
73
+ },
74
+ },
75
+ });
76
+ let widget = (_jsxs("cx", { children: [_jsx(Rescope, { bind: "$page", data: { $value: { bind: "item.value" } }, children: _jsx(PureContainer, { controller: {
77
+ onInit() {
78
+ this.store.set("$value", 2);
79
+ },
80
+ } }) }), _jsx("div", { text: bind("item.value") })] }));
81
+ const component = createTestRenderer(store, widget);
82
+ let tree = component.toJSON();
83
+ assert.deepEqual(tree, {
84
+ type: "div",
85
+ props: {},
86
+ children: ["2"],
87
+ });
88
+ });
89
+ it("visible is calculated based on the inner scope", () => {
90
+ let store = new Store({
91
+ data: {
92
+ layout: {
93
+ title: "Title",
94
+ },
95
+ $page: {
96
+ data: {
97
+ visible: true,
98
+ name: "John",
99
+ },
100
+ },
101
+ },
102
+ });
103
+ let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", visible: bind("visible"), children: _jsx("div", { text: bind("name") }) }) }));
104
+ const component = createTestRenderer(store, widget);
105
+ let tree = component.toJSON();
106
+ assert.deepEqual(tree, {
107
+ type: "div",
108
+ props: {},
109
+ children: ["John"],
110
+ });
111
+ });
112
+ it("controllers see inner scope", () => {
113
+ let store = new Store({
114
+ data: {
115
+ $page: {
116
+ data: {
117
+ visible: true,
118
+ name: "John",
119
+ },
120
+ },
121
+ },
122
+ });
123
+ let testName = null;
124
+ class TestController extends Controller {
125
+ onInit() {
126
+ testName = this.store.get("name");
127
+ }
128
+ }
129
+ let widget = (_jsx("cx", { children: _jsx(Rescope, { bind: "$page.data", controller: TestController, children: _jsx("div", { text: bind("name") }) }) }));
130
+ const component = createTestRenderer(store, widget);
131
+ component.toJSON();
132
+ assert.equal(testName, "John");
133
+ });
134
+ });
@@ -0,0 +1 @@
1
+ export {};