cx 26.0.11 → 26.0.13

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 (366) 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/ui/selection/KeySelection.d.ts +0 -8
  120. package/build/ui/selection/Selection.d.ts +9 -3
  121. package/build/util/Console.d.ts +1 -0
  122. package/build/util/Console.js +7 -3
  123. package/build/util/Format.spec.d.ts +1 -0
  124. package/build/util/Format.spec.js +58 -0
  125. package/build/util/TraversalStack.spec.d.ts +1 -0
  126. package/build/util/TraversalStack.spec.js +43 -0
  127. package/build/util/date/upperBoundCheck.spec.d.ts +1 -0
  128. package/build/util/date/upperBoundCheck.spec.js +22 -0
  129. package/build/util/getSearchQueryPredicate.spec.d.ts +1 -0
  130. package/build/util/getSearchQueryPredicate.spec.js +33 -0
  131. package/build/util/isValidIdentifierName.spec.d.ts +1 -0
  132. package/build/util/isValidIdentifierName.spec.js +28 -0
  133. package/build/util/routeAppend.spec.d.ts +1 -0
  134. package/build/util/routeAppend.spec.js +14 -0
  135. package/build/widgets/AccessorBindings.spec.d.ts +1 -0
  136. package/build/widgets/AccessorBindings.spec.js +40 -0
  137. package/build/widgets/Button.d.ts +3 -6
  138. package/build/widgets/Button.js +1 -1
  139. package/build/widgets/DocumentTitle.d.ts +2 -0
  140. package/build/widgets/Heading.d.ts +2 -2
  141. package/build/widgets/HtmlElement.d.ts +33 -8
  142. package/build/widgets/HtmlElement.js +7 -9
  143. package/build/widgets/HtmlElement.spec.d.ts +1 -0
  144. package/build/widgets/HtmlElement.spec.js +38 -0
  145. package/build/widgets/Icon.d.ts +3 -13
  146. package/build/widgets/List.d.ts +4 -0
  147. package/build/widgets/ReactElementWrapper.d.ts +29 -0
  148. package/build/widgets/ReactElementWrapper.js +59 -0
  149. package/build/widgets/drag-drop/DragSource.d.ts +3 -3
  150. package/build/widgets/drag-drop/DragSource.js +2 -3
  151. package/build/widgets/drag-drop/DropZone.d.ts +3 -3
  152. package/build/widgets/drag-drop/DropZone.js +2 -3
  153. package/build/widgets/form/Checkbox.d.ts +2 -0
  154. package/build/widgets/form/ColorField.d.ts +2 -0
  155. package/build/widgets/form/DateTimeField.d.ts +2 -0
  156. package/build/widgets/form/Field.d.ts +0 -2
  157. package/build/widgets/form/LabeledContainer.d.ts +9 -8
  158. package/build/widgets/form/LabeledContainer.js +9 -9
  159. package/build/widgets/form/LookupField.d.ts +57 -9
  160. package/build/widgets/form/MonthField.d.ts +2 -0
  161. package/build/widgets/form/NumberField.d.ts +2 -0
  162. package/build/widgets/form/Radio.d.ts +2 -0
  163. package/build/widgets/form/Select.d.ts +2 -0
  164. package/build/widgets/form/Slider.d.ts +3 -0
  165. package/build/widgets/form/Switch.d.ts +2 -0
  166. package/build/widgets/form/TextField.d.ts +34 -0
  167. package/build/widgets/form/TimeList.d.ts +16 -1
  168. package/build/widgets/form/TimeList.js +34 -62
  169. package/build/widgets/form/UploadButton.d.ts +34 -2
  170. package/build/widgets/form/UploadButton.js +3 -1
  171. package/build/widgets/form/ValidationGroup.spec.d.ts +1 -0
  172. package/build/widgets/form/ValidationGroup.spec.js +62 -0
  173. package/build/widgets/form/Validator.d.ts +33 -2
  174. package/build/widgets/form/Validator.js +3 -0
  175. package/build/widgets/grid/Grid.d.ts +9 -9
  176. package/build/widgets/grid/TreeNode.d.ts +6 -0
  177. package/build/widgets/index.d.ts +1 -0
  178. package/build/widgets/index.js +1 -0
  179. package/build/widgets/nav/MenuItem.d.ts +3 -2
  180. package/build/widgets/nav/Route.spec.d.ts +1 -0
  181. package/build/widgets/nav/Route.spec.js +15 -0
  182. package/build/widgets/nav/Scroller.d.ts +4 -6
  183. package/build/widgets/nav/Scroller.js +6 -3
  184. package/build/widgets/nav/Tab.d.ts +2 -2
  185. package/build/widgets/overlay/ContextMenu.d.ts +3 -3
  186. package/build/widgets/overlay/Overlay.d.ts +2 -1
  187. package/build/widgets/overlay/Overlay.js +1 -1
  188. package/build.js +133 -133
  189. package/dist/data.js +2 -2
  190. package/dist/jsx-runtime.js +6 -1
  191. package/dist/manifest.d.ts +1443 -0
  192. package/dist/manifest.js +852 -804
  193. package/dist/ui.js +91 -5
  194. package/dist/util.js +3 -0
  195. package/dist/widgets.js +520 -161
  196. package/package.json +46 -20
  197. package/src/charts/Chart.ts +108 -108
  198. package/src/charts/ScatterGraph.tsx +6 -6
  199. package/src/data/ArrayElementView.ts +90 -90
  200. package/src/data/AugmentedViewBase.ts +88 -88
  201. package/src/data/Binding.ts +104 -104
  202. package/src/data/ExposedRecordView.ts +95 -95
  203. package/src/data/ExposedValueView.ts +89 -89
  204. package/src/data/Expression.spec.ts +229 -229
  205. package/src/data/Expression.ts +233 -233
  206. package/src/data/Grouper.spec.ts +57 -57
  207. package/src/data/Grouper.ts +158 -158
  208. package/src/data/NestedDataView.ts +43 -43
  209. package/src/data/ReadOnlyDataView.ts +39 -39
  210. package/src/data/Ref.ts +104 -104
  211. package/src/data/Selector.ts +10 -10
  212. package/src/data/Store.ts +52 -52
  213. package/src/data/StoreProxy.ts +19 -19
  214. package/src/data/StoreRef.ts +66 -66
  215. package/src/data/StringTemplate.spec.ts +132 -132
  216. package/src/data/StringTemplate.ts +93 -93
  217. package/src/data/StructuredSelector.spec.ts +113 -113
  218. package/src/data/StructuredSelector.ts +146 -146
  219. package/src/data/SubscribableView.ts +63 -63
  220. package/src/data/ZoomIntoPropertyView.spec.ts +64 -64
  221. package/src/data/ZoomIntoPropertyView.ts +45 -45
  222. package/src/data/computable.spec.ts +87 -62
  223. package/src/data/computable.ts +3 -6
  224. package/src/data/createAccessorModelProxy.spec.tsx +102 -1
  225. package/src/data/createAccessorModelProxy.ts +9 -3
  226. package/src/data/createStructuredSelector.ts +62 -62
  227. package/src/data/getAccessor.spec.ts +11 -11
  228. package/src/data/getAccessor.ts +74 -74
  229. package/src/data/getSelector.spec.ts +43 -43
  230. package/src/data/getSelector.ts +66 -66
  231. package/src/data/ops/filter.spec.ts +35 -35
  232. package/src/data/ops/filter.ts +9 -9
  233. package/src/data/ops/findTreeNode.ts +1 -5
  234. package/src/data/ops/findTreePath.ts +1 -1
  235. package/src/data/ops/merge.ts +13 -13
  236. package/src/data/ops/removeTreeNodes.spec.ts +37 -37
  237. package/src/data/ops/removeTreeNodes.ts +2 -2
  238. package/src/data/ops/updateArray.spec.ts +69 -69
  239. package/src/data/ops/updateArray.ts +31 -31
  240. package/src/data/ops/updateTree.ts +1 -1
  241. package/src/data/test-types.ts +7 -7
  242. package/src/hooks/resolveCallback.spec.tsx +30 -7
  243. package/src/hooks/useTrigger.ts +26 -26
  244. package/src/index.scss +6 -6
  245. package/src/jsx-dev-runtime.ts +4 -4
  246. package/src/jsx-runtime.spec.tsx +402 -0
  247. package/src/jsx-runtime.ts +26 -22
  248. package/src/svg/BoundedObject.ts +101 -101
  249. package/src/svg/util/Rect.ts +105 -105
  250. package/src/ui/CSSHelper.ts +17 -17
  251. package/src/ui/ContentResolver.spec.tsx +172 -19
  252. package/src/ui/ContentResolver.ts +16 -8
  253. package/src/ui/Controller.ts +15 -2
  254. package/src/ui/Culture.ts +159 -159
  255. package/src/ui/DataProxy.ts +55 -55
  256. package/src/ui/FocusManager.ts +171 -171
  257. package/src/ui/Instance.ts +866 -868
  258. package/src/ui/Prop.ts +140 -112
  259. package/src/ui/RenderingContext.ts +99 -99
  260. package/src/ui/Repeater.ts +3 -12
  261. package/src/ui/Rescope.ts +49 -49
  262. package/src/ui/StructuredInstanceDataAccessor.ts +32 -32
  263. package/src/ui/Text.ts +21 -2
  264. package/src/ui/VDOM.ts +34 -34
  265. package/src/ui/adapter/ArrayAdapter.spec.ts +55 -55
  266. package/src/ui/adapter/ArrayAdapter.ts +4 -1
  267. package/src/ui/adapter/TreeAdapter.spec.ts +76 -76
  268. package/src/ui/adapter/TreeAdapter.ts +185 -185
  269. package/src/ui/app/History.ts +133 -133
  270. package/src/ui/app/Url.spec.ts +50 -50
  271. package/src/ui/app/startHotAppLoop.ts +41 -41
  272. package/src/ui/createFunctionalComponent.spec.tsx +53 -0
  273. package/src/ui/createFunctionalComponent.ts +86 -65
  274. package/src/ui/expr.ts +4 -1
  275. package/src/ui/exprHelpers.spec.ts +379 -0
  276. package/src/ui/exprHelpers.ts +78 -0
  277. package/src/ui/index.ts +47 -46
  278. package/src/ui/layout/Content.ts +30 -30
  279. package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +1 -1
  280. package/src/ui/layout/FirstVisibleChildLayout.ts +60 -60
  281. package/src/ui/selection/KeySelection.ts +0 -12
  282. package/src/ui/selection/PropertySelection.ts +87 -87
  283. package/src/ui/selection/Selection.ts +13 -3
  284. package/src/util/Console.ts +13 -11
  285. package/src/util/Format.ts +267 -267
  286. package/src/util/addEventListenerWithOptions.ts +41 -41
  287. package/src/util/browserSupportsPassiveEventHandlers.ts +20 -20
  288. package/src/util/color/rgbToHsl.ts +35 -35
  289. package/src/util/getActiveElement.ts +4 -4
  290. package/src/util/hasKey.ts +18 -18
  291. package/src/util/index.ts +55 -55
  292. package/src/util/innerTextTrim.ts +10 -10
  293. package/src/util/isArray.ts +3 -3
  294. package/src/util/isDataRecord.ts +5 -5
  295. package/src/util/isDefined.ts +3 -3
  296. package/src/util/isString.ts +3 -3
  297. package/src/widgets/AccessorBindings.spec.tsx +26 -0
  298. package/src/widgets/Button.tsx +5 -17
  299. package/src/widgets/DocumentTitle.ts +95 -92
  300. package/src/widgets/Heading.ts +2 -2
  301. package/src/widgets/HtmlElement.spec.helpers.tsx +108 -0
  302. package/src/widgets/HtmlElement.spec.tsx +20 -12
  303. package/src/widgets/HtmlElement.tsx +82 -24
  304. package/src/widgets/Icon.ts +3 -17
  305. package/src/widgets/List.tsx +6 -0
  306. package/src/widgets/ReactElementWrapper.spec.tsx +452 -0
  307. package/src/widgets/ReactElementWrapper.tsx +108 -0
  308. package/src/widgets/Sandbox.ts +103 -103
  309. package/src/widgets/autoFocus.ts +9 -9
  310. package/src/widgets/cx.ts +63 -63
  311. package/src/widgets/drag-drop/DragSource.tsx +3 -4
  312. package/src/widgets/drag-drop/DropZone.tsx +3 -4
  313. package/src/widgets/form/Checkbox.tsx +3 -0
  314. package/src/widgets/form/ColorField.tsx +3 -0
  315. package/src/widgets/form/DateTimeField.tsx +5 -0
  316. package/src/widgets/form/Field.tsx +0 -3
  317. package/src/widgets/form/Label.tsx +1 -0
  318. package/src/widgets/form/LabeledContainer.ts +22 -26
  319. package/src/widgets/form/LookupField.spec.tsx +93 -0
  320. package/src/widgets/form/LookupField.tsx +104 -9
  321. package/src/widgets/form/MonthField.tsx +5 -0
  322. package/src/widgets/form/NumberField.tsx +3 -0
  323. package/src/widgets/form/Radio.tsx +5 -0
  324. package/src/widgets/form/Select.tsx +5 -0
  325. package/src/widgets/form/Slider.tsx +4 -0
  326. package/src/widgets/form/Switch.tsx +3 -0
  327. package/src/widgets/form/TextField.tsx +62 -0
  328. package/src/widgets/form/TimeList.tsx +84 -73
  329. package/src/widgets/form/UploadButton.tsx +53 -2
  330. package/src/widgets/form/Validator.ts +40 -3
  331. package/src/widgets/grid/Grid.tsx +9 -12
  332. package/src/widgets/grid/GridCell.ts +143 -143
  333. package/src/widgets/grid/TreeNode.tsx +9 -0
  334. package/src/widgets/icons/calendar.tsx +17 -17
  335. package/src/widgets/icons/check.tsx +13 -13
  336. package/src/widgets/icons/clear.tsx +15 -15
  337. package/src/widgets/icons/close.tsx +20 -20
  338. package/src/widgets/icons/cx.tsx +38 -38
  339. package/src/widgets/icons/drop-down.tsx +15 -15
  340. package/src/widgets/icons/file.tsx +13 -13
  341. package/src/widgets/icons/folder-open.tsx +15 -15
  342. package/src/widgets/icons/folder.tsx +13 -13
  343. package/src/widgets/icons/forward.tsx +22 -22
  344. package/src/widgets/icons/loading.tsx +24 -24
  345. package/src/widgets/icons/menu.tsx +17 -17
  346. package/src/widgets/icons/pixel-picker.tsx +18 -18
  347. package/src/widgets/icons/search.tsx +13 -13
  348. package/src/widgets/icons/sort-asc.tsx +14 -14
  349. package/src/widgets/icons/square.tsx +18 -18
  350. package/src/widgets/index.ts +1 -0
  351. package/src/widgets/nav/MenuItem.tsx +3 -2
  352. package/src/widgets/nav/Route.ts +142 -142
  353. package/src/widgets/nav/Scroller.tsx +8 -9
  354. package/src/widgets/nav/Tab.ts +2 -2
  355. package/src/widgets/overlay/ContextMenu.ts +42 -42
  356. package/src/widgets/overlay/Dropdown.tsx +762 -762
  357. package/src/widgets/overlay/MsgBox.tsx +141 -141
  358. package/src/widgets/overlay/Overlay.tsx +5 -4
  359. package/src/widgets/overlay/Toast.ts +111 -111
  360. package/src/widgets/overlay/Window.tsx +299 -299
  361. package/src/widgets/overlay/alerts.ts +46 -46
  362. package/src/widgets/overlay/captureMouse.ts +195 -195
  363. package/src/widgets/overlay/createHotPromiseWindowFactory.ts +72 -72
  364. package/src/widgets/overlay/index.d.ts +11 -11
  365. package/src/widgets/overlay/index.ts +11 -11
  366. package/src/widgets/overlay/tooltip-ops.ts +173 -173
@@ -1,50 +1,50 @@
1
- import { Url } from "./Url";
2
- import Route from "route-parser";
3
- import assert from "assert";
4
- describe("Url", function () {
5
- describe(".unresolve", function () {
6
- it("preserves query parameters", function () {
7
- Url.absoluteBase = "https://cxjs.io/docs/";
8
- assert.equal("~/?state=1", Url.unresolve("https://cxjs.io/docs/?state=1"));
9
- });
10
-
11
- it("doesn't touch unresolved urls", function () {
12
- assert.equal("~/test", Url.unresolve("~/test"));
13
- });
14
- });
15
-
16
- describe(".getBaseFromScriptSrc", () => {
17
- it("ignores query strings", function () {
18
- assert.equal(Url.getBaseFromScriptSrc("/vendor.js?qs=1", "~/vendor.js"), "/");
19
- });
20
-
21
- it("allows wildcards", function () {
22
- assert.equal(Url.getBaseFromScriptSrc("/vendor.123.js?qs=1", "~/vendor.*.js"), "/");
23
- });
24
-
25
- it("works for an application folder", function () {
26
- assert.equal(Url.getBaseFromScriptSrc("/datasync/vendor.124c82.js", "~/vendor.*.js"), "/datasync/");
27
- });
28
- });
29
- });
30
-
31
- describe("Route", function () {
32
- it("matches query param", function () {
33
- let route = new Route("~/?state=:state");
34
- let result = route.match("~/?state=1");
35
- assert(result !== false);
36
- assert.equal(result.state, "1");
37
- });
38
-
39
- it("matches routes with extra query params", function () {
40
- let route = new Route("~/?state=:state");
41
- let result = route.match("~/?state=1&more=2");
42
- assert(result);
43
- });
44
-
45
- it.skip("matches query params in any order", function () {
46
- let route = new Route("~/?a=:a&b=:b");
47
- let result = route.match("~/?b=1&a=2");
48
- assert(result);
49
- });
50
- });
1
+ import { Url } from "./Url";
2
+ import Route from "route-parser";
3
+ import assert from "assert";
4
+ describe("Url", function () {
5
+ describe(".unresolve", function () {
6
+ it("preserves query parameters", function () {
7
+ Url.absoluteBase = "https://cxjs.io/docs/";
8
+ assert.equal("~/?state=1", Url.unresolve("https://cxjs.io/docs/?state=1"));
9
+ });
10
+
11
+ it("doesn't touch unresolved urls", function () {
12
+ assert.equal("~/test", Url.unresolve("~/test"));
13
+ });
14
+ });
15
+
16
+ describe(".getBaseFromScriptSrc", () => {
17
+ it("ignores query strings", function () {
18
+ assert.equal(Url.getBaseFromScriptSrc("/vendor.js?qs=1", "~/vendor.js"), "/");
19
+ });
20
+
21
+ it("allows wildcards", function () {
22
+ assert.equal(Url.getBaseFromScriptSrc("/vendor.123.js?qs=1", "~/vendor.*.js"), "/");
23
+ });
24
+
25
+ it("works for an application folder", function () {
26
+ assert.equal(Url.getBaseFromScriptSrc("/datasync/vendor.124c82.js", "~/vendor.*.js"), "/datasync/");
27
+ });
28
+ });
29
+ });
30
+
31
+ describe("Route", function () {
32
+ it("matches query param", function () {
33
+ let route = new Route("~/?state=:state");
34
+ let result = route.match("~/?state=1");
35
+ assert(result !== false);
36
+ assert.equal(result.state, "1");
37
+ });
38
+
39
+ it("matches routes with extra query params", function () {
40
+ let route = new Route("~/?state=:state");
41
+ let result = route.match("~/?state=1&more=2");
42
+ assert(result);
43
+ });
44
+
45
+ it.skip("matches query params in any order", function () {
46
+ let route = new Route("~/?a=:a&b=:b");
47
+ let result = route.match("~/?b=1&a=2");
48
+ assert(result);
49
+ });
50
+ });
@@ -1,41 +1,41 @@
1
- import { startAppLoop, StartAppLoopOptions } from "./startAppLoop";
2
- import { Widget, WidgetConfig } from "../Widget";
3
- import { Store } from "../../data/Store";
4
- import { Create } from "../../util/Component";
5
-
6
- export interface HotModule {
7
- hot?: {
8
- accept: () => void;
9
- dispose: (callback: (data: any) => void) => void;
10
- data?: any;
11
- };
12
- }
13
-
14
- export function startHotAppLoop(
15
- appModule: HotModule,
16
- element: HTMLElement,
17
- store: Store,
18
- widgets: Create<typeof Widget> | Create<typeof Widget>[],
19
- options: StartAppLoopOptions = {},
20
- ): () => void {
21
- let stop: (() => void) | undefined;
22
- //webpack (HMR)
23
- if (appModule.hot) {
24
- // accept itself
25
- appModule.hot.accept();
26
-
27
- // remember data on dispose
28
- appModule.hot.dispose(function (data: any) {
29
- data.state = store.getData();
30
- if (stop) stop();
31
- });
32
-
33
- //apply data on hot replace
34
- if (appModule.hot.data) store.load(appModule.hot.data.state);
35
- }
36
-
37
- Widget.resetCounter();
38
-
39
- //app loop
40
- return (stop = startAppLoop(element, store, widgets, options));
41
- }
1
+ import { startAppLoop, StartAppLoopOptions } from "./startAppLoop";
2
+ import { Widget, WidgetConfig } from "../Widget";
3
+ import { Store } from "../../data/Store";
4
+ import { Create } from "../../util/Component";
5
+
6
+ export interface HotModule {
7
+ hot?: {
8
+ accept: () => void;
9
+ dispose: (callback: (data: any) => void) => void;
10
+ data?: any;
11
+ };
12
+ }
13
+
14
+ export function startHotAppLoop(
15
+ appModule: HotModule,
16
+ element: HTMLElement,
17
+ store: Store,
18
+ widgets: Create<typeof Widget> | Create<typeof Widget>[],
19
+ options: StartAppLoopOptions = {},
20
+ ): () => void {
21
+ let stop: (() => void) | undefined;
22
+ //webpack (HMR)
23
+ if (appModule.hot) {
24
+ // accept itself
25
+ appModule.hot.accept();
26
+
27
+ // remember data on dispose
28
+ appModule.hot.dispose(function (data: any) {
29
+ data.state = store.getData();
30
+ if (stop) stop();
31
+ });
32
+
33
+ //apply data on hot replace
34
+ if (appModule.hot.data?.state) store.load(appModule.hot.data.state);
35
+ }
36
+
37
+ Widget.resetCounter();
38
+
39
+ //app loop
40
+ return (stop = startAppLoop(element, store, widgets, options));
41
+ }
@@ -12,6 +12,59 @@ import { Repeater } from "./Repeater";
12
12
  import { FirstVisibleChildLayout } from "./layout/FirstVisibleChildLayout";
13
13
  import { useStoreMethods } from "../hooks";
14
14
 
15
+ describe("createFunctionalComponent type safety", () => {
16
+ interface MyComponentProps {
17
+ title: string;
18
+ count: number;
19
+ optional?: boolean;
20
+ }
21
+
22
+ const TypedComponent = createFunctionalComponent<MyComponentProps>(({ title, count, optional }) => (
23
+ <cx>
24
+ <div text={title} />
25
+ <div text={String(count)} />
26
+ {optional && <div text="optional shown" />}
27
+ </cx>
28
+ ));
29
+
30
+ it("rejects non-existing properties", () => {
31
+ const widget = (
32
+ <cx>
33
+ <TypedComponent
34
+ title="Test"
35
+ count={5}
36
+ // @ts-expect-error - nonExisting does not exist on MyComponentProps
37
+ nonExisting="invalid"
38
+ />
39
+ </cx>
40
+ );
41
+ assert.ok(widget);
42
+ });
43
+
44
+ it("rejects wrong property type", () => {
45
+ const widget = (
46
+ <cx>
47
+ <TypedComponent
48
+ title="Test"
49
+ // @ts-expect-error - count should be number, not string
50
+ count="wrong"
51
+ />
52
+ </cx>
53
+ );
54
+ assert.ok(widget);
55
+ });
56
+
57
+ it("rejects missing required properties", () => {
58
+ const widget = (
59
+ <cx>
60
+ {/* @ts-expect-error - count is required but missing */}
61
+ <TypedComponent title="Test" />
62
+ </cx>
63
+ );
64
+ assert.ok(widget);
65
+ });
66
+ });
67
+
15
68
  describe("createFunctionalComponent", () => {
16
69
  it("allows spread", () => {
17
70
  const SuperDiv = createFunctionalComponent(({ ...props }) => {
@@ -1,65 +1,86 @@
1
- import { createComponentFactory, isComponentFactory } from "../util/Component";
2
- import { flattenProps } from "../ui/flattenProps";
3
- import { PureContainer } from "./PureContainer";
4
- import { UseParentLayout } from "./layout/UseParentLayout";
5
- import { isDefined } from "../util/isDefined";
6
-
7
- let currentInstance: any = null;
8
-
9
- class FunctionalComponent extends PureContainer {
10
- declare childrenFactory: (props: any) => any;
11
- declare props: any;
12
-
13
- initInstance(context: any, instance: any) {
14
- instance.store = instance.parentStore;
15
- this.clear();
16
- currentInstance = instance;
17
- this.add(this.childrenFactory(this.props));
18
- instance.content = this.layout ? this.layout.items : this.items;
19
- this.clear();
20
- currentInstance = null;
21
- }
22
-
23
- explore(context: any, instance: any) {
24
- if (this.layout) this.layout.items = instance.content;
25
- else this.items = instance.content;
26
- this.exploreItems(context, instance, instance.content);
27
- if (instance.computables) {
28
- instance.computables.forEach((cb: any) => cb(instance.store.getData()));
29
- }
30
- }
31
- }
32
-
33
- export function createFunctionalComponent(factory: any) {
34
- if (isComponentFactory(factory)) return factory;
35
-
36
- return createComponentFactory(factory, (props: any = {}) => {
37
- let innerProps = flattenProps(props);
38
- delete innerProps.visible;
39
- delete innerProps.if;
40
- delete innerProps.controller;
41
- delete innerProps.layout;
42
- delete innerProps.outerLayout;
43
- delete innerProps.putInto;
44
- delete innerProps.contentFor;
45
- delete innerProps.jsxAttributes;
46
- delete innerProps.$type;
47
- delete innerProps.vdomKey;
48
-
49
- return {
50
- type: FunctionalComponent,
51
- visible: isDefined(props.if) ? props.if : isDefined(props.visible) ? props.visible : true,
52
- layout: props.layout || UseParentLayout,
53
- controller: props.controller,
54
- outerLayout: props.outerLayout,
55
- putInto: props.contentFor || props.putInto,
56
- vdomKey: props.vdomKey,
57
- childrenFactory: factory,
58
- props: innerProps,
59
- };
60
- });
61
- }
62
-
63
- export function getCurrentInstance() {
64
- return currentInstance;
65
- }
1
+ import { flattenProps } from "../ui/flattenProps";
2
+ import { createComponentFactory, isComponentFactory } from "../util/Component";
3
+ import { isDefined } from "../util/isDefined";
4
+ import { ChildNode } from "./Container";
5
+ import { PureContainerBase, PureContainerConfig } from "./PureContainer";
6
+ import { UseParentLayout } from "./layout/UseParentLayout";
7
+
8
+ let currentInstance: any = null;
9
+
10
+ export interface FunctionalComponentConfig extends PureContainerConfig {
11
+ /** Factory function that creates children based on props. */
12
+ childrenFactory?: (props: any) => ChildNode | ChildNode[];
13
+
14
+ /** Props passed to the children factory. */
15
+ props?: any;
16
+ }
17
+
18
+ class FunctionalComponent extends PureContainerBase<FunctionalComponentConfig> {
19
+ declare childrenFactory: (props: any) => any;
20
+ declare props: any;
21
+
22
+ constructor(config?: FunctionalComponentConfig) {
23
+ super(config);
24
+ }
25
+
26
+ initInstance(context: any, instance: any) {
27
+ instance.store = instance.parentStore;
28
+ this.clear();
29
+ currentInstance = instance;
30
+ this.add(this.childrenFactory(this.props));
31
+ instance.content = this.layout ? this.layout.items : this.items;
32
+ this.clear();
33
+ currentInstance = null;
34
+ }
35
+
36
+ explore(context: any, instance: any) {
37
+ if (this.layout) this.layout.items = instance.content;
38
+ else this.items = instance.content;
39
+ this.exploreItems(context, instance, instance.content);
40
+ if (instance.computables) {
41
+ instance.computables.forEach((cb: any) => cb(instance.store.getData()));
42
+ }
43
+ }
44
+ }
45
+
46
+ /** Brand type to mark CxJS functional components */
47
+ export interface CxFunctionalComponent<Props = any> {
48
+ (props: Props & PureContainerConfig): any;
49
+ __cxFunctionalComponent: true;
50
+ }
51
+
52
+ export function createFunctionalComponent<Props = any>(
53
+ factory: (props: Props) => ChildNode | ChildNode[],
54
+ ): CxFunctionalComponent<Props> {
55
+ if (isComponentFactory(factory)) return factory as any;
56
+
57
+ return createComponentFactory(factory, (props: any = {}) => {
58
+ let innerProps = flattenProps(props);
59
+ delete innerProps.visible;
60
+ delete innerProps.if;
61
+ delete innerProps.controller;
62
+ delete innerProps.layout;
63
+ delete innerProps.outerLayout;
64
+ delete innerProps.putInto;
65
+ delete innerProps.contentFor;
66
+ delete innerProps.jsxAttributes;
67
+ delete innerProps.$type;
68
+ delete innerProps.vdomKey;
69
+
70
+ return {
71
+ type: FunctionalComponent,
72
+ visible: isDefined(props.if) ? props.if : isDefined(props.visible) ? props.visible : true,
73
+ layout: props.layout || UseParentLayout,
74
+ controller: props.controller,
75
+ outerLayout: props.outerLayout,
76
+ putInto: props.contentFor || props.putInto,
77
+ vdomKey: props.vdomKey,
78
+ childrenFactory: factory,
79
+ props: innerProps,
80
+ };
81
+ });
82
+ }
83
+
84
+ export function getCurrentInstance() {
85
+ return currentInstance;
86
+ }
package/src/ui/expr.ts CHANGED
@@ -4,6 +4,9 @@ import { AccessorChain } from "../data/createAccessorModelProxy";
4
4
  import { Selector } from "../data/Selector";
5
5
  import { Expr } from "./Prop";
6
6
 
7
+ // Helper type to infer value type from AccessorChain, handling `any` correctly
8
+ type InferAccessorValue<T> = 0 extends 1 & T ? any : T extends AccessorChain<infer V> ? V : never;
9
+
7
10
  export function expr(code: string): Expr;
8
11
  export function expr<V1, R>(arg1: AccessorChain<V1>, compute: (v1: V1) => R): Selector<R>;
9
12
  export function expr<V1, V2, R>(
@@ -25,7 +28,7 @@ export function expr<V1, V2, V3, V4, R>(
25
28
  compute: (v1: V1, v2: V2, v3: V3, v4: V4) => R,
26
29
  ): Selector<R>;
27
30
  export function expr<T extends AccessorChain<any>[], R>(
28
- ...args: [...accessors: T, compute: (...values: { [K in keyof T]: T[K] extends AccessorChain<infer V> ? V : never }) => R]
31
+ ...args: [...accessors: T, compute: (...values: { [K in keyof T]: InferAccessorValue<T[K]> }) => R]
29
32
  ): Selector<R>;
30
33
  export function expr(...args: any[]): any {
31
34
  let text = args[0];