cx 26.0.12 → 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 (363) 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.js +133 -133
  187. package/dist/data.js +2 -2
  188. package/dist/jsx-runtime.js +6 -1
  189. package/dist/manifest.d.ts +1443 -0
  190. package/dist/manifest.js +855 -807
  191. package/dist/ui.js +91 -5
  192. package/dist/util.js +3 -0
  193. package/dist/widgets.js +520 -161
  194. package/package.json +46 -20
  195. package/src/charts/Chart.ts +108 -108
  196. package/src/charts/ScatterGraph.tsx +6 -6
  197. package/src/data/ArrayElementView.ts +90 -90
  198. package/src/data/AugmentedViewBase.ts +88 -88
  199. package/src/data/Binding.ts +104 -104
  200. package/src/data/ExposedRecordView.ts +95 -95
  201. package/src/data/ExposedValueView.ts +89 -89
  202. package/src/data/Expression.spec.ts +229 -229
  203. package/src/data/Expression.ts +233 -233
  204. package/src/data/Grouper.spec.ts +57 -57
  205. package/src/data/Grouper.ts +158 -158
  206. package/src/data/NestedDataView.ts +43 -43
  207. package/src/data/ReadOnlyDataView.ts +39 -39
  208. package/src/data/Ref.ts +104 -104
  209. package/src/data/Selector.ts +10 -10
  210. package/src/data/Store.ts +52 -52
  211. package/src/data/StoreProxy.ts +19 -19
  212. package/src/data/StoreRef.ts +66 -66
  213. package/src/data/StringTemplate.spec.ts +132 -132
  214. package/src/data/StringTemplate.ts +93 -93
  215. package/src/data/StructuredSelector.spec.ts +113 -113
  216. package/src/data/StructuredSelector.ts +146 -146
  217. package/src/data/SubscribableView.ts +63 -63
  218. package/src/data/ZoomIntoPropertyView.spec.ts +64 -64
  219. package/src/data/ZoomIntoPropertyView.ts +45 -45
  220. package/src/data/computable.spec.ts +87 -62
  221. package/src/data/computable.ts +3 -6
  222. package/src/data/createAccessorModelProxy.spec.tsx +102 -1
  223. package/src/data/createAccessorModelProxy.ts +9 -3
  224. package/src/data/createStructuredSelector.ts +62 -62
  225. package/src/data/getAccessor.spec.ts +11 -11
  226. package/src/data/getAccessor.ts +74 -74
  227. package/src/data/getSelector.spec.ts +43 -43
  228. package/src/data/getSelector.ts +66 -66
  229. package/src/data/ops/filter.spec.ts +35 -35
  230. package/src/data/ops/filter.ts +9 -9
  231. package/src/data/ops/findTreeNode.ts +1 -5
  232. package/src/data/ops/findTreePath.ts +1 -1
  233. package/src/data/ops/merge.ts +13 -13
  234. package/src/data/ops/removeTreeNodes.spec.ts +37 -37
  235. package/src/data/ops/removeTreeNodes.ts +2 -2
  236. package/src/data/ops/updateArray.spec.ts +69 -69
  237. package/src/data/ops/updateArray.ts +31 -31
  238. package/src/data/ops/updateTree.ts +1 -1
  239. package/src/data/test-types.ts +7 -7
  240. package/src/hooks/resolveCallback.spec.tsx +30 -7
  241. package/src/hooks/useTrigger.ts +26 -26
  242. package/src/index.scss +6 -6
  243. package/src/jsx-dev-runtime.ts +4 -4
  244. package/src/jsx-runtime.spec.tsx +402 -0
  245. package/src/jsx-runtime.ts +26 -22
  246. package/src/svg/BoundedObject.ts +101 -101
  247. package/src/svg/util/Rect.ts +105 -105
  248. package/src/ui/CSSHelper.ts +17 -17
  249. package/src/ui/ContentResolver.spec.tsx +172 -19
  250. package/src/ui/ContentResolver.ts +16 -8
  251. package/src/ui/Controller.ts +15 -2
  252. package/src/ui/Culture.ts +159 -159
  253. package/src/ui/DataProxy.ts +55 -55
  254. package/src/ui/FocusManager.ts +171 -171
  255. package/src/ui/Instance.ts +866 -868
  256. package/src/ui/Prop.ts +140 -112
  257. package/src/ui/RenderingContext.ts +99 -99
  258. package/src/ui/Repeater.ts +3 -12
  259. package/src/ui/Rescope.ts +49 -49
  260. package/src/ui/StructuredInstanceDataAccessor.ts +32 -32
  261. package/src/ui/Text.ts +21 -2
  262. package/src/ui/VDOM.ts +34 -34
  263. package/src/ui/adapter/ArrayAdapter.spec.ts +55 -55
  264. package/src/ui/adapter/ArrayAdapter.ts +4 -1
  265. package/src/ui/adapter/TreeAdapter.spec.ts +76 -76
  266. package/src/ui/adapter/TreeAdapter.ts +185 -185
  267. package/src/ui/app/History.ts +133 -133
  268. package/src/ui/app/Url.spec.ts +50 -50
  269. package/src/ui/app/startHotAppLoop.ts +41 -41
  270. package/src/ui/createFunctionalComponent.spec.tsx +53 -0
  271. package/src/ui/createFunctionalComponent.ts +86 -65
  272. package/src/ui/expr.ts +4 -1
  273. package/src/ui/exprHelpers.spec.ts +379 -0
  274. package/src/ui/exprHelpers.ts +78 -0
  275. package/src/ui/index.ts +47 -46
  276. package/src/ui/layout/Content.ts +30 -30
  277. package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +1 -1
  278. package/src/ui/layout/FirstVisibleChildLayout.ts +60 -60
  279. package/src/ui/selection/KeySelection.ts +153 -153
  280. package/src/ui/selection/Selection.ts +128 -128
  281. package/src/util/Console.ts +13 -11
  282. package/src/util/Format.ts +267 -267
  283. package/src/util/addEventListenerWithOptions.ts +41 -41
  284. package/src/util/browserSupportsPassiveEventHandlers.ts +20 -20
  285. package/src/util/color/rgbToHsl.ts +35 -35
  286. package/src/util/getActiveElement.ts +4 -4
  287. package/src/util/hasKey.ts +18 -18
  288. package/src/util/index.ts +55 -55
  289. package/src/util/innerTextTrim.ts +10 -10
  290. package/src/util/isArray.ts +3 -3
  291. package/src/util/isDataRecord.ts +5 -5
  292. package/src/util/isDefined.ts +3 -3
  293. package/src/util/isString.ts +3 -3
  294. package/src/widgets/AccessorBindings.spec.tsx +26 -0
  295. package/src/widgets/Button.tsx +5 -17
  296. package/src/widgets/DocumentTitle.ts +95 -92
  297. package/src/widgets/Heading.ts +2 -2
  298. package/src/widgets/HtmlElement.spec.helpers.tsx +108 -0
  299. package/src/widgets/HtmlElement.spec.tsx +20 -12
  300. package/src/widgets/HtmlElement.tsx +77 -23
  301. package/src/widgets/Icon.ts +3 -17
  302. package/src/widgets/List.tsx +6 -0
  303. package/src/widgets/ReactElementWrapper.spec.tsx +452 -0
  304. package/src/widgets/ReactElementWrapper.tsx +108 -0
  305. package/src/widgets/Sandbox.ts +103 -103
  306. package/src/widgets/autoFocus.ts +9 -9
  307. package/src/widgets/cx.ts +63 -63
  308. package/src/widgets/drag-drop/DragSource.tsx +3 -4
  309. package/src/widgets/drag-drop/DropZone.tsx +3 -4
  310. package/src/widgets/form/Checkbox.tsx +3 -0
  311. package/src/widgets/form/ColorField.tsx +3 -0
  312. package/src/widgets/form/DateTimeField.tsx +5 -0
  313. package/src/widgets/form/Field.tsx +0 -3
  314. package/src/widgets/form/Label.tsx +1 -0
  315. package/src/widgets/form/LabeledContainer.ts +22 -26
  316. package/src/widgets/form/LookupField.spec.tsx +93 -0
  317. package/src/widgets/form/LookupField.tsx +104 -9
  318. package/src/widgets/form/MonthField.tsx +5 -0
  319. package/src/widgets/form/NumberField.tsx +3 -0
  320. package/src/widgets/form/Radio.tsx +5 -0
  321. package/src/widgets/form/Select.tsx +5 -0
  322. package/src/widgets/form/Slider.tsx +4 -0
  323. package/src/widgets/form/Switch.tsx +3 -0
  324. package/src/widgets/form/TextField.tsx +62 -0
  325. package/src/widgets/form/TimeList.tsx +84 -73
  326. package/src/widgets/form/UploadButton.tsx +53 -2
  327. package/src/widgets/form/Validator.ts +40 -3
  328. package/src/widgets/grid/Grid.tsx +9 -12
  329. package/src/widgets/grid/GridCell.ts +143 -143
  330. package/src/widgets/grid/TreeNode.tsx +9 -0
  331. package/src/widgets/icons/calendar.tsx +17 -17
  332. package/src/widgets/icons/check.tsx +13 -13
  333. package/src/widgets/icons/clear.tsx +15 -15
  334. package/src/widgets/icons/close.tsx +20 -20
  335. package/src/widgets/icons/cx.tsx +38 -38
  336. package/src/widgets/icons/drop-down.tsx +15 -15
  337. package/src/widgets/icons/file.tsx +13 -13
  338. package/src/widgets/icons/folder-open.tsx +15 -15
  339. package/src/widgets/icons/folder.tsx +13 -13
  340. package/src/widgets/icons/forward.tsx +22 -22
  341. package/src/widgets/icons/loading.tsx +24 -24
  342. package/src/widgets/icons/menu.tsx +17 -17
  343. package/src/widgets/icons/pixel-picker.tsx +18 -18
  344. package/src/widgets/icons/search.tsx +13 -13
  345. package/src/widgets/icons/sort-asc.tsx +14 -14
  346. package/src/widgets/icons/square.tsx +18 -18
  347. package/src/widgets/index.ts +1 -0
  348. package/src/widgets/nav/MenuItem.tsx +3 -2
  349. package/src/widgets/nav/Route.ts +142 -142
  350. package/src/widgets/nav/Scroller.tsx +8 -9
  351. package/src/widgets/nav/Tab.ts +2 -2
  352. package/src/widgets/overlay/ContextMenu.ts +42 -42
  353. package/src/widgets/overlay/Dropdown.tsx +762 -762
  354. package/src/widgets/overlay/MsgBox.tsx +141 -141
  355. package/src/widgets/overlay/Overlay.tsx +5 -4
  356. package/src/widgets/overlay/Toast.ts +111 -111
  357. package/src/widgets/overlay/Window.tsx +299 -299
  358. package/src/widgets/overlay/alerts.ts +46 -46
  359. package/src/widgets/overlay/captureMouse.ts +195 -195
  360. package/src/widgets/overlay/createHotPromiseWindowFactory.ts +72 -72
  361. package/src/widgets/overlay/index.d.ts +11 -11
  362. package/src/widgets/overlay/index.ts +11 -11
  363. 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];