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
@@ -0,0 +1,108 @@
1
+ /** @jsxImportSource react */
2
+ import React from "react";
3
+
4
+ // Function component
5
+ export function ReactFunctionComponent(props: { title: string; children?: React.ReactNode }) {
6
+ return (
7
+ <div className="react-function-component">
8
+ <h3>{props.title}</h3>
9
+ <div className="content">{props.children}</div>
10
+ </div>
11
+ );
12
+ }
13
+
14
+ // Function component with hooks
15
+ export function ReactCounterComponent(props: { initialCount?: number }) {
16
+ const [count, setCount] = React.useState(props.initialCount ?? 0);
17
+ return (
18
+ <div className="react-counter">
19
+ <span className="count">{count}</span>
20
+ <button onClick={() => setCount(count + 1)}>Increment</button>
21
+ </div>
22
+ );
23
+ }
24
+
25
+ // Class component
26
+ export class ReactClassComponent extends React.Component<
27
+ { label: string; children?: React.ReactNode },
28
+ { active: boolean }
29
+ > {
30
+ constructor(props: { label: string; children?: React.ReactNode }) {
31
+ super(props);
32
+ this.state = { active: false };
33
+ }
34
+
35
+ render() {
36
+ return (
37
+ <div className={`react-class-component ${this.state.active ? "active" : ""}`}>
38
+ <label>{this.props.label}</label>
39
+ <div className="body">{this.props.children}</div>
40
+ </div>
41
+ );
42
+ }
43
+ }
44
+
45
+ // Pure component
46
+ export class ReactPureComponent extends React.PureComponent<{ value: string }> {
47
+ render() {
48
+ return <span className="react-pure-component">{this.props.value}</span>;
49
+ }
50
+ }
51
+
52
+ // Function component with useRef and useEffect
53
+ export function ReactRefEffectComponent(props: { onMount?: (element: HTMLDivElement | null) => void }) {
54
+ const divRef = React.useRef<HTMLDivElement>(null);
55
+ const mountedRef = React.useRef(false);
56
+
57
+ React.useEffect(() => {
58
+ mountedRef.current = true;
59
+ props.onMount?.(divRef.current);
60
+ return () => {
61
+ mountedRef.current = false;
62
+ };
63
+ }, []);
64
+
65
+ return (
66
+ <div ref={divRef} className="react-ref-effect-component" data-mounted={mountedRef.current ? "true" : "false"}>
67
+ Component with ref and effect
68
+ </div>
69
+ );
70
+ }
71
+
72
+ // Function component with useEffect that updates state
73
+ export function ReactEffectStateComponent(props: { value: string }) {
74
+ const [processed, setProcessed] = React.useState<string>("");
75
+ const renderCountRef = React.useRef(0);
76
+
77
+ React.useEffect(() => {
78
+ setProcessed(`Processed: ${props.value}`);
79
+ }, [props.value]);
80
+
81
+ renderCountRef.current += 1;
82
+
83
+ return (
84
+ <div className="react-effect-state-component">
85
+ <span className="processed">{processed}</span>
86
+ <span className="render-count">{renderCountRef.current}</span>
87
+ </div>
88
+ );
89
+ }
90
+
91
+ // Component for testing prop translation
92
+ export function ReactPropsComponent(props: {
93
+ text: string;
94
+ count: number;
95
+ enabled: boolean;
96
+ tags?: string[];
97
+ onClick?: () => void;
98
+ }) {
99
+ return (
100
+ <div className="react-props-component">
101
+ <span className="text">{props.text}</span>
102
+ <span className="count">{props.count}</span>
103
+ <span className="enabled">{props.enabled ? "yes" : "no"}</span>
104
+ {props.tags && <span className="tags">{props.tags.join(", ")}</span>}
105
+ {props.onClick && <button onClick={props.onClick}>Click</button>}
106
+ </div>
107
+ );
108
+ }
@@ -54,28 +54,36 @@ describe("HtmlElement", () => {
54
54
  });
55
55
  });
56
56
 
57
- it("allows React components as tag", () => {
58
- class MyReactComponent extends VDOM.Component<any> {
59
- render() {
60
- return VDOM.createElement("div", { className: "my-component" }, this.props.children);
61
- }
62
- }
63
-
57
+ it("supports SVG elements with camelCase attributes", () => {
64
58
  let store = new Store();
65
59
 
66
60
  const component = createTestRenderer(
67
61
  store,
68
62
  <cx>
69
- <MyReactComponent>
70
- <span>Child content</span>
71
- </MyReactComponent>
63
+ <svg>
64
+ <path
65
+ d="M200,176V64a23.9,23.9,0,0,0-24-24H40"
66
+ fill="none"
67
+ stroke="#343434"
68
+ strokeLinecap="round"
69
+ strokeLinejoin="round"
70
+ strokeWidth="12"
71
+ />
72
+ </svg>
72
73
  </cx>,
73
74
  );
74
75
 
75
76
  let tree = component.toJSON();
76
77
  assert(tree && !Array.isArray(tree), "Expected single element");
77
- assert.equal(tree.type, "div");
78
- assert.equal(tree.props.className, "my-component");
78
+ assert.equal(tree.type, "svg");
79
79
  assert(tree.children && tree.children.length === 1, "Expected one child");
80
+ let path = tree.children[0] as any;
81
+ assert.equal(path.type, "path");
82
+ assert.equal(path.props.d, "M200,176V64a23.9,23.9,0,0,0-24-24H40");
83
+ assert.equal(path.props.fill, "none");
84
+ assert.equal(path.props.stroke, "#343434");
85
+ assert.equal(path.props.strokeLinecap, "round");
86
+ assert.equal(path.props.strokeLinejoin, "round");
87
+ assert.equal(path.props.strokeWidth, "12");
80
88
  });
81
89
  });
@@ -1,29 +1,30 @@
1
1
  /** @jsxImportSource react */
2
2
 
3
- import { Widget, VDOM } from "../ui/Widget";
4
- import { ContainerBase, StyledContainerConfig } from "../ui/Container";
5
- import {
6
- tooltipMouseMove,
7
- tooltipParentWillUnmount,
8
- tooltipMouseLeave,
9
- tooltipParentWillReceiveProps,
10
- tooltipParentDidMount,
11
- tooltipParentDidUpdate,
12
- TooltipParentInstance,
13
- } from "./overlay/tooltip-ops";
14
- import type { TooltipInstance } from "./overlay/Tooltip";
3
+ import type { JSX as ReactJSX } from "react";
15
4
  import { Url } from "../ui/app/Url";
5
+ import { ChildNode, StyledContainerBase, StyledContainerConfig } from "../ui/Container";
6
+ import type { RenderProps, WidgetData } from "../ui/Instance";
7
+ import { Instance } from "../ui/Instance";
8
+ import { BooleanProp, ClassProp, NumberProp, Prop, StringProp, StructuredProp } from "../ui/Prop";
9
+ import type { CxChild, RenderingContext } from "../ui/RenderingContext";
10
+ import { VDOM, Widget } from "../ui/Widget";
16
11
  import { debug } from "../util/Debug";
12
+ import { isArray } from "../util/isArray";
13
+ import { isDefined } from "../util/isDefined";
17
14
  import { isString } from "../util/isString";
18
15
  import { isUndefined } from "../util/isUndefined";
19
- import { isDefined } from "../util/isDefined";
20
- import { isArray } from "../util/isArray";
21
16
  import { autoFocus } from "./autoFocus";
22
- import type { CxChild, RenderingContext } from "../ui/RenderingContext";
23
- import type { WidgetData, RenderProps } from "../ui/Instance";
24
- import { Instance } from "../ui/Instance";
17
+ import type { TooltipInstance } from "./overlay/Tooltip";
25
18
  import type { TooltipConfig, TooltipProp } from "./overlay/tooltip-ops";
26
- import { StringProp, NumberProp, StructuredProp } from "../ui/Prop";
19
+ import {
20
+ tooltipMouseLeave,
21
+ tooltipMouseMove,
22
+ tooltipParentDidMount,
23
+ tooltipParentDidUpdate,
24
+ TooltipParentInstance,
25
+ tooltipParentWillReceiveProps,
26
+ tooltipParentWillUnmount,
27
+ } from "./overlay/tooltip-ops";
27
28
 
28
29
  const isDataAttribute = (attr: string): string | false => (attr.indexOf("data-") === 0 ? attr.substring(5) : false);
29
30
 
@@ -33,19 +34,73 @@ export let urlAttributes: Record<string, boolean> = {
33
34
  "iframe.src": true,
34
35
  };
35
36
 
36
- export interface HtmlElementConfig extends StyledContainerConfig {
37
+ type ReactIntrinsicElements = ReactJSX.IntrinsicElements;
38
+
39
+ // Check if a key is an event handler (starts with "on" and is a function)
40
+ // Use NonNullable to handle optional event handlers (T | undefined)
41
+ type IsEventHandler<K, T> = K extends `on${string}` ? (NonNullable<T> extends Function ? true : false) : false;
42
+
43
+ // CxJS event handler type - can be string (controller method) or callback with Instance
44
+ type CxEventHandler<T> = T extends (event: infer E) => any
45
+ ? string | ((event: E, instance: Instance) => void)
46
+ : T extends undefined
47
+ ? undefined
48
+ : string | T;
49
+
50
+ // Transform React element props to CxJS props
51
+ // Note: For string literal union props (like SVG's strokeLinecap), we also accept `string`
52
+ // because TypeScript widens string literals to `string` in JSX attribute syntax.
53
+ // This is a known TypeScript behavior where `<path strokeLinecap="round"/>` infers "round" as string.
54
+ type TransformHtmlElementProps<T> = {
55
+ [K in keyof T]: K extends "children"
56
+ ? ChildNode | ChildNode[]
57
+ : K extends "className" | "class"
58
+ ? ClassProp
59
+ : IsEventHandler<K, T[K]> extends true
60
+ ? CxEventHandler<T[K]>
61
+ : string extends T[K]
62
+ ? Prop<T[K]> // Plain string props - no change needed
63
+ : NonNullable<T[K]> extends string
64
+ ? Prop<T[K]> | string // String literal unions - accept string for JSX compatibility
65
+ : Prop<T[K]>;
66
+ };
67
+
68
+ /** Base HtmlElement configuration - core CxJS properties for extension by widgets */
69
+ export interface HtmlElementConfigBase extends StyledContainerConfig {
37
70
  id?: StringProp | NumberProp;
38
71
 
72
+ /** HTML tag name */
73
+ tag?: string;
74
+
39
75
  /** Inner text contents. */
40
76
  text?: StringProp | NumberProp;
41
77
 
78
+ /** Inner html contents. */
79
+ innerHtml?: StringProp;
80
+
42
81
  /** Inner html contents. */
43
82
  html?: StringProp;
44
83
 
45
84
  /** Tooltip configuration. */
46
85
  tooltip?: StringProp | TooltipConfig;
86
+
87
+ /** Additional attributes to be applied. */
88
+ attrs?: StructuredProp;
89
+
90
+ /** Additional data attributes. */
91
+ data?: StructuredProp;
92
+
93
+ //** Set to true to automatically focus the element when mounted. */
94
+ autoFocus?: BooleanProp;
95
+
96
+ //** Callback to receive the HTMLElement where this component is mounted. */
97
+ onRef?: string | ((element: HTMLElement | null, instance: Instance) => void);
47
98
  }
48
99
 
100
+ /** HtmlElement configuration with tag-specific attributes and events */
101
+ export type HtmlElementConfig<Tag extends keyof ReactIntrinsicElements = "div"> = Omit<HtmlElementConfigBase, "tag"> &
102
+ TransformHtmlElementProps<ReactIntrinsicElements[Tag]> & { tag?: Tag };
103
+
49
104
  export class HtmlElementInstance<E extends HtmlElement<any, any> = HtmlElement<any, any>>
50
105
  extends Instance<E>
51
106
  implements TooltipParentInstance
@@ -55,9 +110,9 @@ export class HtmlElementInstance<E extends HtmlElement<any, any> = HtmlElement<a
55
110
  }
56
111
 
57
112
  export class HtmlElement<
58
- Config extends HtmlElementConfig = HtmlElementConfig,
113
+ Config extends HtmlElementConfigBase = HtmlElementConfig,
59
114
  InstanceType extends HtmlElementInstance<any> = HtmlElementInstance<any>,
60
- > extends ContainerBase<Config, InstanceType> {
115
+ > extends StyledContainerBase<Config, InstanceType> {
61
116
  declare public tag?: string;
62
117
  declare public html?: string;
63
118
  declare public innerText?: string;
@@ -69,7 +124,7 @@ export class HtmlElement<
69
124
  declare public urlAttributes?: string[];
70
125
  declare public extraProps?: Record<string, unknown>;
71
126
  declare public tooltip?: TooltipProp;
72
- declare public onRef?: (element: HTMLElement | null, instance: Instance) => void;
127
+ declare public onRef?: string | ((element: HTMLElement | null, instance: Instance) => void);
73
128
  declare public autoFocus?: boolean | string;
74
129
  [key: string]: unknown; // Index signature for dynamic properties
75
130
 
@@ -253,7 +308,6 @@ export class HtmlElement<
253
308
  }
254
309
 
255
310
  HtmlElement.prototype.tag = "div";
256
- HtmlElement.prototype.styled = true;
257
311
 
258
312
  interface ContainerComponentProps {
259
313
  tag: string | React.ComponentType;
@@ -1,4 +1,4 @@
1
- import { Widget, VDOM, WidgetConfig } from "../ui/Widget";
1
+ import { Widget, VDOM, WidgetConfig, WidgetStyleConfig } from "../ui/Widget";
2
2
  import {
3
3
  registerIcon,
4
4
  registerIconFactory,
@@ -10,25 +10,11 @@ import {
10
10
  import "./icons/index";
11
11
  import { RenderingContext } from "../ui/RenderingContext";
12
12
  import { Instance } from "../ui/Instance";
13
- import { StringProp, ClassProp, StyleProp } from "../ui/Prop";
13
+ import { StringProp } from "../ui/Prop";
14
14
 
15
- export interface IconConfig extends WidgetConfig {
15
+ export interface IconConfig extends WidgetConfig, WidgetStyleConfig {
16
16
  /** Name under which the icon is registered. */
17
17
  name?: StringProp;
18
-
19
- /** Additional CSS classes to be applied to the field.
20
- * If an object is provided, all keys with a "truthy" value will be added to the CSS class list. */
21
- className?: ClassProp;
22
-
23
- /** Additional CSS classes to be applied to the field.
24
- * If an object is provided, all keys with a "truthy" value will be added to the CSS class list. */
25
- class?: ClassProp;
26
-
27
- /** Style object applied to the wrapper div. Used for setting the dimensions of the field. */
28
- style?: StyleProp;
29
-
30
- /** Base CSS class to be applied to the element. Default is `icon`. */
31
- baseClass?: string;
32
18
  }
33
19
 
34
20
  export class Icon extends Widget<IconConfig> {
@@ -32,9 +32,15 @@ export interface ListConfig<T = any> extends StyledContainerConfig {
32
32
  /** Record alias. Default is `$record`. */
33
33
  recordName?: RecordAlias;
34
34
 
35
+ /** Record alias. Alias for `recordName`. Default is `$record`. */
36
+ recordAlias?: RecordAlias;
37
+
35
38
  /** Index alias. Default is `$index`. */
36
39
  indexName?: RecordAlias;
37
40
 
41
+ /** Index alias. Alias for `indexName`. Default is `$index`. */
42
+ indexAlias?: RecordAlias;
43
+
38
44
  /** Style to be applied to each list item. */
39
45
  itemStyle?: StyleProp;
40
46