cx 25.11.1 → 26.0.1

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 (1200) hide show
  1. package/.mocharc.json +5 -0
  2. package/build.js +129 -0
  3. package/dist/charts.css +250 -250
  4. package/dist/charts.js +2421 -3102
  5. package/dist/data.js +857 -1063
  6. package/dist/hooks.js +48 -59
  7. package/dist/jsx-runtime.js +24 -0
  8. package/dist/manifest.js +925 -919
  9. package/dist/svg.js +266 -432
  10. package/dist/ui.js +1933 -2388
  11. package/dist/util.js +587 -557
  12. package/dist/widgets.css +6 -6
  13. package/dist/widgets.js +7542 -9910
  14. package/package.json +39 -5
  15. package/src/charts/Bar.scss +5 -3
  16. package/src/charts/Bar.ts +114 -0
  17. package/src/charts/BarGraph.scss +4 -3
  18. package/src/charts/BarGraph.tsx +145 -0
  19. package/src/charts/BubbleGraph.scss +5 -3
  20. package/src/charts/BubbleGraph.tsx +165 -0
  21. package/src/charts/Chart.ts +108 -0
  22. package/src/charts/ColorMap.ts +150 -0
  23. package/src/charts/Column.scss +5 -3
  24. package/src/charts/Column.ts +124 -0
  25. package/src/charts/ColumnBarBase.tsx +284 -0
  26. package/src/charts/ColumnBarGraphBase.tsx +229 -0
  27. package/src/charts/ColumnGraph.scss +5 -3
  28. package/src/charts/ColumnGraph.tsx +153 -0
  29. package/src/charts/Grid.ts +5 -0
  30. package/src/charts/Gridlines.scss +5 -3
  31. package/src/charts/Gridlines.tsx +88 -0
  32. package/src/charts/Legend.scss +5 -3
  33. package/src/charts/Legend.tsx +270 -0
  34. package/src/charts/LegendEntry.scss +5 -3
  35. package/src/charts/LegendEntry.tsx +197 -0
  36. package/src/charts/LineGraph.scss +4 -3
  37. package/src/charts/LineGraph.tsx +441 -0
  38. package/src/charts/Marker.scss +5 -3
  39. package/src/charts/Marker.tsx +483 -0
  40. package/src/charts/MarkerLine.scss +5 -3
  41. package/src/charts/MarkerLine.tsx +214 -0
  42. package/src/charts/MouseTracker.tsx +112 -0
  43. package/src/charts/Pie.ts +8 -0
  44. package/src/charts/PieChart.scss +5 -3
  45. package/src/charts/PieChart.tsx +717 -0
  46. package/src/charts/PieLabel.tsx +106 -0
  47. package/src/charts/PieLabelsContainer.ts +68 -0
  48. package/src/charts/Range.scss +4 -3
  49. package/src/charts/Range.tsx +318 -0
  50. package/src/charts/RangeMarker.scss +5 -3
  51. package/src/charts/RangeMarker.tsx +233 -0
  52. package/src/charts/ScatterGraph.scss +5 -3
  53. package/src/charts/ScatterGraph.tsx +245 -0
  54. package/src/charts/Swimlane.scss +5 -3
  55. package/src/charts/Swimlane.tsx +195 -0
  56. package/src/charts/Swimlanes.scss +5 -3
  57. package/src/charts/Swimlanes.tsx +179 -0
  58. package/src/charts/axis/Axis.tsx +444 -0
  59. package/src/charts/axis/CategoryAxis.scss +5 -3
  60. package/src/charts/axis/CategoryAxis.tsx +313 -0
  61. package/src/charts/axis/NumericAxis.scss +5 -3
  62. package/src/charts/axis/NumericAxis.tsx +437 -0
  63. package/src/charts/axis/Stack.ts +61 -0
  64. package/src/charts/axis/TimeAxis.scss +4 -3
  65. package/src/charts/axis/TimeAxis.tsx +718 -0
  66. package/src/charts/axis/index.ts +4 -0
  67. package/src/charts/helpers/MinMaxFinder.ts +66 -0
  68. package/src/charts/helpers/PointReducer.ts +135 -0
  69. package/src/charts/helpers/SnapPointFinder.ts +136 -0
  70. package/src/charts/helpers/ValueAtFinder.ts +72 -0
  71. package/src/charts/helpers/index.ts +4 -0
  72. package/src/charts/palette.scss +7 -5
  73. package/src/charts/shapes.tsx +86 -0
  74. package/src/charts/variables.scss +2 -1
  75. package/src/core.d.ts +182 -310
  76. package/src/data/AggregateFunction.ts +171 -0
  77. package/src/data/ArrayElementView.spec.ts +88 -0
  78. package/src/data/ArrayElementView.ts +90 -0
  79. package/src/data/ArrayRef.ts +35 -0
  80. package/src/data/AugmentedViewBase.ts +88 -0
  81. package/src/data/Binding.ts +104 -0
  82. package/src/data/ExposedRecordView.ts +95 -0
  83. package/src/data/ExposedValueView.ts +89 -0
  84. package/src/data/Expression.spec.ts +229 -0
  85. package/src/data/Expression.ts +233 -0
  86. package/src/data/Grouper.ts +158 -0
  87. package/src/data/NestedDataView.ts +43 -0
  88. package/src/data/ReadOnlyDataView.ts +39 -0
  89. package/src/data/Ref.spec.ts +79 -0
  90. package/src/data/Ref.ts +104 -0
  91. package/src/data/Selector.ts +10 -0
  92. package/src/data/Store.spec.ts +22 -0
  93. package/src/data/Store.ts +52 -0
  94. package/src/data/StoreProxy.ts +19 -0
  95. package/src/data/StoreRef.spec.ts +24 -0
  96. package/src/data/StoreRef.ts +66 -0
  97. package/src/data/StringTemplate.spec.ts +132 -0
  98. package/src/data/StringTemplate.ts +93 -0
  99. package/src/data/StructuredSelector.spec.ts +113 -0
  100. package/src/data/StructuredSelector.ts +146 -0
  101. package/src/data/SubscribableView.ts +63 -0
  102. package/src/data/View.ts +289 -0
  103. package/src/data/ZoomIntoPropertyView.spec.ts +64 -0
  104. package/src/data/ZoomIntoPropertyView.ts +45 -0
  105. package/src/data/comparer.ts +78 -0
  106. package/src/data/computable.spec.ts +62 -0
  107. package/src/data/computable.ts +72 -0
  108. package/src/data/createAccessorModelProxy.ts +60 -0
  109. package/src/data/createStructuredSelector.spec.ts +45 -0
  110. package/src/data/createStructuredSelector.ts +62 -0
  111. package/src/data/defaultCompare.ts +15 -0
  112. package/src/data/diff/diffArrays.ts +49 -0
  113. package/src/data/diff/diffs.spec.ts +49 -0
  114. package/src/data/diff/index.ts +1 -0
  115. package/src/data/enableFatArrowExpansion.ts +6 -0
  116. package/src/data/getAccessor.spec.ts +11 -0
  117. package/src/data/getAccessor.ts +74 -0
  118. package/src/data/getSelector.spec.ts +43 -0
  119. package/src/data/getSelector.ts +66 -0
  120. package/src/data/index.ts +30 -0
  121. package/src/data/isSelector.ts +26 -0
  122. package/src/data/ops/append.spec.ts +28 -0
  123. package/src/data/ops/append.ts +5 -0
  124. package/src/data/ops/filter.spec.ts +35 -0
  125. package/src/data/ops/filter.ts +9 -0
  126. package/src/data/ops/findTreeNode.spec.ts +23 -0
  127. package/src/data/ops/findTreeNode.ts +18 -0
  128. package/src/data/ops/findTreePath.ts +23 -0
  129. package/src/data/ops/insertElement.ts +3 -0
  130. package/src/data/ops/merge.spec.ts +27 -0
  131. package/src/data/ops/merge.ts +13 -0
  132. package/src/data/ops/moveElement.ts +21 -0
  133. package/src/data/ops/removeTreeNodes.spec.ts +37 -0
  134. package/src/data/ops/removeTreeNodes.ts +15 -0
  135. package/src/data/ops/updateArray.spec.ts +69 -0
  136. package/src/data/ops/updateArray.ts +31 -0
  137. package/src/data/ops/updateTree.spec.ts +54 -0
  138. package/src/data/ops/updateTree.ts +23 -0
  139. package/src/data/test-types.ts +7 -0
  140. package/src/hooks/createLocalStorageRef.ts +21 -0
  141. package/src/hooks/invokeCallback.spec.tsx +59 -0
  142. package/src/hooks/invokeCallback.ts +8 -0
  143. package/src/hooks/resolveCallback.spec.tsx +48 -0
  144. package/src/hooks/resolveCallback.ts +16 -0
  145. package/src/hooks/store.spec.tsx +67 -0
  146. package/src/hooks/store.ts +46 -0
  147. package/src/hooks/useEffect.ts +14 -0
  148. package/src/hooks/useInterval.ts +8 -0
  149. package/src/hooks/useState.ts +20 -0
  150. package/src/hooks/useTrigger.spec.tsx +99 -0
  151. package/src/hooks/useTrigger.ts +26 -0
  152. package/src/index.scss +6 -6
  153. package/src/jsx-runtime.ts +72 -0
  154. package/src/locale/de-de.ts +76 -0
  155. package/src/locale/en-us.ts +75 -0
  156. package/src/locale/es-es.ts +76 -0
  157. package/src/locale/fr-fr.ts +76 -0
  158. package/src/locale/nl-nl.ts +76 -0
  159. package/src/locale/pt-pt.ts +76 -0
  160. package/src/locale/sr-latn-ba.ts +76 -0
  161. package/src/svg/BoundedObject.ts +101 -0
  162. package/src/svg/ClipRect.tsx +29 -0
  163. package/src/svg/Ellipse.tsx +69 -0
  164. package/src/svg/Line.tsx +58 -0
  165. package/src/svg/NonOverlappingRect.ts +26 -0
  166. package/src/svg/NonOverlappingRectGroup.ts +49 -0
  167. package/src/svg/Rectangle.tsx +91 -0
  168. package/src/svg/Svg.scss +5 -4
  169. package/src/svg/Svg.tsx +241 -0
  170. package/src/svg/Text.tsx +134 -0
  171. package/src/svg/TextualBoundedObject.ts +35 -0
  172. package/src/svg/util/Rect.ts +105 -0
  173. package/src/ui/CSS.ts +87 -0
  174. package/src/ui/CSSHelper.ts +17 -0
  175. package/src/ui/Container.tsx +216 -0
  176. package/src/ui/ContentResolver.spec.tsx +430 -0
  177. package/src/ui/ContentResolver.ts +124 -0
  178. package/src/ui/Controller.spec.tsx +566 -0
  179. package/src/ui/Controller.ts +189 -0
  180. package/src/ui/Culture.ts +159 -0
  181. package/src/ui/Cx.spec.tsx +208 -0
  182. package/src/ui/Cx.tsx +386 -0
  183. package/src/ui/DataProxy.spec.tsx +337 -0
  184. package/src/ui/DataProxy.ts +55 -0
  185. package/src/ui/DetachedScope.tsx +159 -0
  186. package/src/ui/FocusManager.ts +171 -0
  187. package/src/ui/Format.ts +108 -0
  188. package/src/ui/HoverSync.tsx +189 -0
  189. package/src/ui/Instance.ts +868 -0
  190. package/src/ui/IsolatedScope.spec.tsx +55 -0
  191. package/src/ui/IsolatedScope.ts +50 -0
  192. package/src/ui/Localization.ts +70 -0
  193. package/src/ui/Prop.ts +112 -0
  194. package/src/ui/PureContainer.spec.tsx +230 -0
  195. package/src/ui/PureContainer.tsx +19 -0
  196. package/src/ui/RenderingContext.ts +99 -0
  197. package/src/ui/Repeater.spec.tsx +141 -0
  198. package/src/ui/Repeater.ts +203 -0
  199. package/src/ui/Rescope.spec.tsx +199 -0
  200. package/src/ui/Rescope.ts +49 -0
  201. package/src/ui/ResizeManager.ts +31 -0
  202. package/src/ui/Restate.spec.tsx +418 -0
  203. package/src/ui/Restate.tsx +217 -0
  204. package/src/ui/StaticText.ts +11 -0
  205. package/src/ui/StructuredInstanceDataAccessor.ts +32 -0
  206. package/src/ui/Text.ts +30 -0
  207. package/src/ui/VDOM.ts +34 -0
  208. package/src/ui/Widget.spec.tsx +53 -0
  209. package/src/ui/Widget.tsx +308 -0
  210. package/src/ui/ZIndexManager.ts +11 -0
  211. package/src/ui/adapter/ArrayAdapter.spec.ts +55 -0
  212. package/src/ui/adapter/ArrayAdapter.ts +226 -0
  213. package/src/ui/adapter/DataAdapter.ts +52 -0
  214. package/src/ui/adapter/GroupAdapter.ts +235 -0
  215. package/src/ui/adapter/TreeAdapter.spec.ts +76 -0
  216. package/src/ui/adapter/TreeAdapter.ts +185 -0
  217. package/src/ui/app/History.ts +133 -0
  218. package/src/ui/app/Url.spec.ts +50 -0
  219. package/src/ui/app/Url.ts +102 -0
  220. package/src/ui/app/startAppLoop.tsx +74 -0
  221. package/src/ui/app/startHotAppLoop.ts +40 -0
  222. package/src/ui/batchUpdates.ts +77 -0
  223. package/src/ui/bind.ts +10 -0
  224. package/src/ui/createFunctionalComponent.spec.tsx +399 -0
  225. package/src/ui/createFunctionalComponent.ts +65 -0
  226. package/src/ui/expr.ts +44 -0
  227. package/src/ui/flattenProps.ts +21 -0
  228. package/src/ui/index.ts +45 -0
  229. package/src/ui/keyboardShortcuts.ts +40 -0
  230. package/src/ui/layout/Content.ts +30 -0
  231. package/src/ui/layout/ContentPlaceholder.spec.tsx +587 -0
  232. package/src/ui/layout/ContentPlaceholder.ts +133 -0
  233. package/src/ui/layout/FirstVisibleChildLayout.spec.tsx +195 -0
  234. package/src/ui/layout/FirstVisibleChildLayout.ts +60 -0
  235. package/src/ui/layout/LabelsLeftLayout.scss +6 -4
  236. package/src/ui/layout/LabelsLeftLayout.tsx +76 -0
  237. package/src/ui/layout/LabelsTopLayout.scss +5 -4
  238. package/src/ui/layout/LabelsTopLayout.tsx +156 -0
  239. package/src/ui/layout/UseParentLayout.ts +8 -0
  240. package/src/ui/layout/exploreChildren.ts +38 -0
  241. package/src/ui/selection/KeySelection.ts +165 -0
  242. package/src/ui/selection/PropertySelection.ts +87 -0
  243. package/src/ui/selection/Selection.ts +118 -0
  244. package/src/ui/tpl.ts +5 -0
  245. package/src/util/Component.spec.ts +381 -0
  246. package/src/util/Component.ts +296 -0
  247. package/src/util/Console.ts +11 -0
  248. package/src/util/DOM.ts +88 -0
  249. package/src/util/Debug.ts +71 -0
  250. package/src/util/Format.spec.ts +69 -0
  251. package/src/util/Format.ts +267 -0
  252. package/src/util/GlobalCacheIdentifier.ts +11 -0
  253. package/src/util/KeyCode.ts +21 -0
  254. package/src/util/SubscriberList.ts +87 -0
  255. package/src/util/Timing.ts +59 -0
  256. package/src/util/TraversalStack.spec.ts +54 -0
  257. package/src/util/TraversalStack.ts +48 -0
  258. package/src/util/addEventListenerWithOptions.ts +41 -0
  259. package/src/util/browserSupportsPassiveEventHandlers.ts +20 -0
  260. package/src/util/calculateNaturalElementHeight.ts +22 -0
  261. package/src/util/capitalize.ts +4 -0
  262. package/src/util/coalesce.ts +6 -0
  263. package/src/util/color/hslToRgb.ts +34 -0
  264. package/src/util/color/parseColor.ts +173 -0
  265. package/src/util/color/rgbToHex.ts +15 -0
  266. package/src/util/color/rgbToHsl.ts +36 -0
  267. package/src/util/date/dateDiff.ts +9 -0
  268. package/src/util/date/diff.ts +13 -0
  269. package/src/util/date/encodeDate.ts +8 -0
  270. package/src/util/date/encodeDateWithTimezoneOffset.ts +19 -0
  271. package/src/util/date/lowerBoundCheck.ts +13 -0
  272. package/src/util/date/maxDate.ts +14 -0
  273. package/src/util/date/minDate.ts +14 -0
  274. package/src/util/date/monthStart.ts +8 -0
  275. package/src/util/date/parseDateInvariant.ts +20 -0
  276. package/src/util/date/sameDate.ts +11 -0
  277. package/src/util/date/upperBoundCheck.ts +13 -0
  278. package/src/util/date/zeroTime.ts +9 -0
  279. package/src/util/debounce.ts +26 -0
  280. package/src/util/dummyCallback.ts +1 -0
  281. package/src/util/escapeSpecialRegexCharacters.ts +8 -0
  282. package/src/util/eventCallbacks.ts +12 -0
  283. package/src/util/expandFatArrows.ts +118 -0
  284. package/src/util/findScrollableParent.ts +15 -0
  285. package/src/util/getActiveElement.ts +4 -0
  286. package/src/util/getParentFrameBoundingClientRect.ts +13 -0
  287. package/src/util/getScrollerBoundingClientRect.ts +12 -0
  288. package/src/util/getSearchQueryPredicate.ts +58 -0
  289. package/src/util/getTopLevelBoundingClientRect.ts +7 -0
  290. package/src/util/getVendorPrefix.ts +33 -0
  291. package/src/util/hasKey.ts +18 -0
  292. package/src/util/index.ts +55 -0
  293. package/src/util/innerTextTrim.ts +10 -0
  294. package/src/util/isArray.ts +3 -0
  295. package/src/util/isDataRecord.ts +5 -0
  296. package/src/util/isDefined.ts +3 -0
  297. package/src/util/isDigit.ts +8 -0
  298. package/src/util/isFunction.ts +3 -0
  299. package/src/util/isNonEmptyArray.ts +3 -0
  300. package/src/util/isNumber.ts +3 -0
  301. package/src/util/isObject.ts +3 -0
  302. package/src/util/isPromise.ts +6 -0
  303. package/src/util/isString.ts +3 -0
  304. package/src/util/isTextInputElement.ts +3 -0
  305. package/src/util/isTouchDevice.ts +7 -0
  306. package/src/util/isTouchEvent.ts +64 -0
  307. package/src/util/isUndefined.ts +3 -0
  308. package/src/util/isValidIdentifierName.ts +5 -0
  309. package/src/util/onIdleCallback.ts +10 -0
  310. package/src/util/parseStyle.ts +29 -0
  311. package/src/util/quote.ts +6 -0
  312. package/src/util/reverseSlice.ts +10 -0
  313. package/src/util/routeAppend.ts +16 -0
  314. package/src/util/scrollElementIntoView.ts +40 -0
  315. package/src/util/scss/add-rules.scss +7 -5
  316. package/src/util/scss/calc.scss +12 -8
  317. package/src/util/scss/call-once.scss +5 -3
  318. package/src/util/scss/clockwise.scss +20 -18
  319. package/src/util/scss/colors.scss +4 -2
  320. package/src/util/scss/deep-get.scss +3 -1
  321. package/src/util/scss/deep-merge.scss +6 -3
  322. package/src/util/scss/include.scss +6 -5
  323. package/src/util/shallowEquals.ts +43 -0
  324. package/src/util/test/createTestRenderer.tsx +12 -0
  325. package/src/util/throttle.ts +21 -0
  326. package/src/util/validatedDebounce.ts +23 -0
  327. package/src/widgets/AccessorBindings.spec.tsx +5 -7
  328. package/src/widgets/Button.scss +6 -4
  329. package/src/widgets/Button.tsx +201 -0
  330. package/src/widgets/Button.variables.scss +13 -10
  331. package/src/widgets/CxCredit.scss +6 -4
  332. package/src/widgets/CxCredit.tsx +46 -0
  333. package/src/widgets/DocumentTitle.ts +92 -0
  334. package/src/widgets/FlexBox.scss +7 -5
  335. package/src/widgets/FlexBox.tsx +169 -0
  336. package/src/widgets/Heading.scss +6 -4
  337. package/src/widgets/Heading.ts +43 -0
  338. package/src/widgets/HighlightedSearchText.scss +6 -4
  339. package/src/widgets/HighlightedSearchText.tsx +54 -0
  340. package/src/widgets/HtmlElement.spec.tsx +79 -0
  341. package/src/widgets/HtmlElement.tsx +349 -0
  342. package/src/widgets/Icon.scss +6 -4
  343. package/src/widgets/Icon.ts +78 -0
  344. package/src/widgets/List.scss +6 -4
  345. package/src/widgets/List.tsx +787 -0
  346. package/src/widgets/ProgressBar.scss +5 -4
  347. package/src/widgets/ProgressBar.tsx +66 -0
  348. package/src/widgets/Resizer.scss +5 -4
  349. package/src/widgets/Resizer.tsx +200 -0
  350. package/src/widgets/Sandbox.ts +103 -0
  351. package/src/widgets/Section.scss +5 -4
  352. package/src/widgets/Section.tsx +187 -0
  353. package/src/widgets/autoFocus.ts +9 -0
  354. package/src/widgets/cx.ts +63 -0
  355. package/src/widgets/drag-drop/DragClone.scss +6 -4
  356. package/src/widgets/drag-drop/DragHandle.scss +6 -4
  357. package/src/widgets/drag-drop/DragHandle.tsx +47 -0
  358. package/src/widgets/drag-drop/DragSource.scss +6 -4
  359. package/src/widgets/drag-drop/DragSource.tsx +238 -0
  360. package/src/widgets/drag-drop/DropZone.scss +6 -4
  361. package/src/widgets/drag-drop/DropZone.tsx +354 -0
  362. package/src/widgets/drag-drop/ops.tsx +422 -0
  363. package/src/widgets/drag-drop/variables.scss +4 -1
  364. package/src/widgets/enableAllInternalDependencies.ts +11 -0
  365. package/src/widgets/form/Calendar.scss +8 -5
  366. package/src/widgets/form/Calendar.tsx +760 -0
  367. package/src/widgets/form/Checkbox.scss +5 -3
  368. package/src/widgets/form/Checkbox.tsx +285 -0
  369. package/src/widgets/form/ColorField.scss +5 -3
  370. package/src/widgets/form/ColorField.tsx +491 -0
  371. package/src/widgets/form/ColorPicker.scss +5 -3
  372. package/src/widgets/form/ColorPicker.tsx +544 -0
  373. package/src/widgets/form/DateField.ts +21 -0
  374. package/src/widgets/form/DateTimeField.scss +5 -3
  375. package/src/widgets/form/DateTimeField.tsx +723 -0
  376. package/src/widgets/form/DateTimePicker.scss +6 -4
  377. package/src/widgets/form/DateTimePicker.tsx +431 -0
  378. package/src/widgets/form/Field.scss +4 -2
  379. package/src/widgets/form/Field.tsx +611 -0
  380. package/src/widgets/form/FieldGroup.ts +10 -0
  381. package/src/widgets/form/FieldIcon.ts +61 -0
  382. package/src/widgets/form/HelpText.scss +5 -4
  383. package/src/widgets/form/HelpText.ts +15 -0
  384. package/src/widgets/form/Label.scss +5 -4
  385. package/src/widgets/form/Label.tsx +116 -0
  386. package/src/widgets/form/LabeledContainer.ts +81 -0
  387. package/src/widgets/form/LookupField.scss +5 -3
  388. package/src/widgets/form/LookupField.tsx +1326 -0
  389. package/src/widgets/form/MonthField.scss +4 -3
  390. package/src/widgets/form/MonthField.tsx +665 -0
  391. package/src/widgets/form/MonthPicker.scss +8 -5
  392. package/src/widgets/form/MonthPicker.tsx +822 -0
  393. package/src/widgets/form/NumberField.scss +5 -3
  394. package/src/widgets/form/NumberField.tsx +540 -0
  395. package/src/widgets/form/Radio.scss +5 -3
  396. package/src/widgets/form/Radio.tsx +245 -0
  397. package/src/widgets/form/Select.scss +6 -4
  398. package/src/widgets/form/Select.tsx +322 -0
  399. package/src/widgets/form/Slider.scss +6 -3
  400. package/src/widgets/form/Slider.tsx +461 -0
  401. package/src/widgets/form/Switch.scss +5 -3
  402. package/src/widgets/form/Switch.tsx +174 -0
  403. package/src/widgets/form/TextArea.scss +6 -4
  404. package/src/widgets/form/TextArea.tsx +229 -0
  405. package/src/widgets/form/TextField.scss +6 -4
  406. package/src/widgets/form/TextField.tsx +345 -0
  407. package/src/widgets/form/TimeField.ts +10 -0
  408. package/src/widgets/form/TimeList.tsx +94 -0
  409. package/src/widgets/form/UploadButton.scss +5 -3
  410. package/src/widgets/form/UploadButton.tsx +256 -0
  411. package/src/widgets/form/ValidationError.scss +4 -3
  412. package/src/widgets/form/ValidationError.tsx +72 -0
  413. package/src/widgets/form/ValidationGroup.spec.tsx +147 -0
  414. package/src/widgets/form/ValidationGroup.ts +141 -0
  415. package/src/widgets/form/Validator.ts +23 -0
  416. package/src/widgets/form/Wheel.scss +9 -7
  417. package/src/widgets/form/Wheel.tsx +315 -0
  418. package/src/widgets/form/variables.scss +3 -1
  419. package/src/widgets/grid/Grid.scss +6 -4
  420. package/src/widgets/grid/Grid.tsx +4247 -0
  421. package/src/widgets/grid/GridCell.ts +143 -0
  422. package/src/widgets/grid/GridCellEditor.tsx +52 -0
  423. package/src/widgets/grid/GridRow.ts +302 -0
  424. package/src/widgets/grid/GridRowLine.ts +49 -0
  425. package/src/widgets/grid/Pagination.scss +5 -3
  426. package/src/widgets/grid/Pagination.tsx +126 -0
  427. package/src/widgets/grid/TreeNode.scss +6 -4
  428. package/src/widgets/grid/TreeNode.tsx +145 -0
  429. package/src/widgets/grid/createGridCellEditor.tsx +18 -0
  430. package/src/widgets/grid/index.ts +17 -0
  431. package/src/widgets/grid/variables.scss +8 -4
  432. package/src/widgets/icons/calendar.tsx +17 -0
  433. package/src/widgets/icons/check.tsx +13 -0
  434. package/src/widgets/icons/clear.tsx +15 -0
  435. package/src/widgets/icons/close.tsx +20 -0
  436. package/src/widgets/icons/cx.tsx +38 -0
  437. package/src/widgets/icons/drop-down.tsx +15 -0
  438. package/src/widgets/icons/file.tsx +13 -0
  439. package/src/widgets/icons/folder-open.tsx +15 -0
  440. package/src/widgets/icons/folder.tsx +13 -0
  441. package/src/widgets/icons/forward.tsx +22 -0
  442. package/src/widgets/icons/loading.tsx +24 -0
  443. package/src/widgets/icons/menu.tsx +17 -0
  444. package/src/widgets/icons/pixel-picker.tsx +18 -0
  445. package/src/widgets/icons/registry.ts +57 -0
  446. package/src/widgets/icons/search.tsx +13 -0
  447. package/src/widgets/icons/sort-asc.tsx +14 -0
  448. package/src/widgets/icons/square.tsx +18 -0
  449. package/src/widgets/nav/Link.scss +5 -3
  450. package/src/widgets/nav/Link.ts +12 -0
  451. package/src/widgets/nav/LinkButton.ts +176 -0
  452. package/src/widgets/nav/Menu.scss +7 -5
  453. package/src/widgets/nav/Menu.tsx +489 -0
  454. package/src/widgets/nav/Menu.variables.scss +3 -1
  455. package/src/widgets/nav/MenuItem.scss +6 -4
  456. package/src/widgets/nav/MenuItem.tsx +523 -0
  457. package/src/widgets/nav/MenuSpacer.ts +19 -0
  458. package/src/widgets/nav/RedirectRoute.ts +50 -0
  459. package/src/widgets/nav/Route.spec.tsx +24 -0
  460. package/src/widgets/nav/Route.ts +142 -0
  461. package/src/widgets/nav/Scroller.scss +5 -3
  462. package/src/widgets/nav/Scroller.tsx +253 -0
  463. package/src/widgets/nav/Submenu.ts +6 -0
  464. package/src/widgets/nav/Tab.scss +5 -4
  465. package/src/widgets/nav/Tab.ts +120 -0
  466. package/src/widgets/nav/cover.scss +5 -4
  467. package/src/widgets/nav/variables.scss +3 -1
  468. package/src/widgets/overlay/ContextMenu.ts +42 -0
  469. package/src/widgets/overlay/Dropdown.scss +11 -9
  470. package/src/widgets/overlay/Dropdown.tsx +762 -0
  471. package/src/widgets/overlay/FlyweightTooltipTracker.ts +57 -0
  472. package/src/widgets/overlay/MsgBox.tsx +141 -0
  473. package/src/widgets/overlay/Overlay.scss +5 -3
  474. package/src/widgets/overlay/Overlay.tsx +942 -0
  475. package/src/widgets/overlay/Toast.scss +8 -7
  476. package/src/widgets/overlay/Toast.ts +111 -0
  477. package/src/widgets/overlay/Tooltip.scss +6 -4
  478. package/src/widgets/overlay/Tooltip.tsx +393 -0
  479. package/src/widgets/overlay/Window.scss +6 -4
  480. package/src/widgets/overlay/Window.tsx +299 -0
  481. package/src/widgets/overlay/alerts.ts +46 -0
  482. package/src/widgets/overlay/captureMouse.ts +195 -0
  483. package/src/widgets/overlay/createHotPromiseWindowFactory.ts +72 -0
  484. package/src/widgets/overlay/index.d.ts +11 -11
  485. package/src/widgets/overlay/index.ts +11 -0
  486. package/src/widgets/overlay/tooltip-ops.ts +173 -0
  487. package/src/widgets/overlay/variables.scss +3 -1
  488. package/src/widgets/variables.scss +3 -1
  489. package/tsconfig.compile.json +4 -0
  490. package/tsconfig.json +34 -0
  491. package/tsconfig.mocha.json +14 -0
  492. package/charts.d.ts +0 -1
  493. package/charts.js +0 -1
  494. package/data.d.ts +0 -1
  495. package/data.js +0 -1
  496. package/hooks.d.ts +0 -1
  497. package/hooks.js +0 -1
  498. package/index.js +0 -17
  499. package/locale/de-de.js +0 -75
  500. package/locale/en-us.js +0 -75
  501. package/locale/es-es.js +0 -75
  502. package/locale/fr-fr.js +0 -75
  503. package/locale/nl-nl.js +0 -75
  504. package/locale/pt-pt.js +0 -75
  505. package/locale/sr-latn-ba.js +0 -75
  506. package/manifest.js +0 -1
  507. package/src/charts/Bar.d.ts +0 -28
  508. package/src/charts/Bar.js +0 -90
  509. package/src/charts/BarGraph.d.ts +0 -15
  510. package/src/charts/BarGraph.js +0 -112
  511. package/src/charts/BubbleGraph.js +0 -93
  512. package/src/charts/Chart.d.ts +0 -12
  513. package/src/charts/Chart.js +0 -75
  514. package/src/charts/ColorMap.d.ts +0 -21
  515. package/src/charts/ColorMap.js +0 -97
  516. package/src/charts/Column.d.ts +0 -29
  517. package/src/charts/Column.js +0 -88
  518. package/src/charts/ColumnBarBase.d.ts +0 -64
  519. package/src/charts/ColumnBarBase.js +0 -176
  520. package/src/charts/ColumnBarGraphBase.d.ts +0 -73
  521. package/src/charts/ColumnBarGraphBase.js +0 -114
  522. package/src/charts/ColumnGraph.d.ts +0 -18
  523. package/src/charts/ColumnGraph.js +0 -120
  524. package/src/charts/Grid.js +0 -5
  525. package/src/charts/Gridlines.d.ts +0 -25
  526. package/src/charts/Gridlines.js +0 -49
  527. package/src/charts/Legend.d.ts +0 -45
  528. package/src/charts/Legend.js +0 -187
  529. package/src/charts/LegendEntry.d.ts +0 -54
  530. package/src/charts/LegendEntry.js +0 -128
  531. package/src/charts/LineGraph.d.ts +0 -101
  532. package/src/charts/LineGraph.js +0 -300
  533. package/src/charts/Marker.d.ts +0 -110
  534. package/src/charts/Marker.js +0 -311
  535. package/src/charts/MarkerLine.d.ts +0 -56
  536. package/src/charts/MarkerLine.js +0 -128
  537. package/src/charts/MouseTracker.d.ts +0 -17
  538. package/src/charts/MouseTracker.js +0 -81
  539. package/src/charts/Pie.js +0 -8
  540. package/src/charts/PieChart.d.ts +0 -92
  541. package/src/charts/PieChart.js +0 -530
  542. package/src/charts/PieLabel.d.ts +0 -26
  543. package/src/charts/PieLabel.js +0 -71
  544. package/src/charts/PieLabelsContainer.d.ts +0 -6
  545. package/src/charts/PieLabelsContainer.js +0 -55
  546. package/src/charts/Range.d.ts +0 -75
  547. package/src/charts/Range.js +0 -206
  548. package/src/charts/RangeMarker.d.ts +0 -35
  549. package/src/charts/RangeMarker.js +0 -159
  550. package/src/charts/ScatterGraph.d.ts +0 -64
  551. package/src/charts/ScatterGraph.js +0 -164
  552. package/src/charts/Swimlane.d.ts +0 -24
  553. package/src/charts/Swimlane.js +0 -140
  554. package/src/charts/Swimlanes.d.ts +0 -41
  555. package/src/charts/Swimlanes.js +0 -114
  556. package/src/charts/axis/Axis.d.ts +0 -113
  557. package/src/charts/axis/Axis.js +0 -288
  558. package/src/charts/axis/CategoryAxis.d.ts +0 -30
  559. package/src/charts/axis/CategoryAxis.js +0 -241
  560. package/src/charts/axis/NumericAxis.d.ts +0 -46
  561. package/src/charts/axis/NumericAxis.js +0 -351
  562. package/src/charts/axis/Stack.d.ts +0 -11
  563. package/src/charts/axis/Stack.js +0 -55
  564. package/src/charts/axis/TimeAxis.d.ts +0 -31
  565. package/src/charts/axis/TimeAxis.js +0 -611
  566. package/src/charts/axis/index.d.ts +0 -4
  567. package/src/charts/axis/index.js +0 -4
  568. package/src/charts/helpers/MinMaxFinder.d.ts +0 -22
  569. package/src/charts/helpers/MinMaxFinder.js +0 -36
  570. package/src/charts/helpers/PointReducer.d.ts +0 -24
  571. package/src/charts/helpers/PointReducer.js +0 -61
  572. package/src/charts/helpers/SnapPointFinder.d.ts +0 -30
  573. package/src/charts/helpers/SnapPointFinder.js +0 -69
  574. package/src/charts/helpers/ValueAtFinder.d.ts +0 -16
  575. package/src/charts/helpers/ValueAtFinder.js +0 -46
  576. package/src/charts/helpers/index.d.ts +0 -4
  577. package/src/charts/helpers/index.js +0 -4
  578. package/src/charts/index.d.ts +0 -27
  579. package/src/charts/shapes.d.ts +0 -23
  580. package/src/charts/shapes.js +0 -79
  581. package/src/data/AggregateFunction.d.ts +0 -20
  582. package/src/data/AggregateFunction.js +0 -145
  583. package/src/data/ArrayElementView.d.ts +0 -13
  584. package/src/data/ArrayElementView.js +0 -64
  585. package/src/data/ArrayElementView.spec.js +0 -88
  586. package/src/data/ArrayRef.d.ts +0 -15
  587. package/src/data/ArrayRef.js +0 -35
  588. package/src/data/AugmentedViewBase.d.ts +0 -18
  589. package/src/data/AugmentedViewBase.js +0 -77
  590. package/src/data/Binding.d.ts +0 -19
  591. package/src/data/Binding.js +0 -76
  592. package/src/data/ExposedRecordView.d.ts +0 -14
  593. package/src/data/ExposedRecordView.js +0 -75
  594. package/src/data/ExposedValueView.d.ts +0 -19
  595. package/src/data/ExposedValueView.js +0 -73
  596. package/src/data/Expression.d.ts +0 -17
  597. package/src/data/Expression.js +0 -229
  598. package/src/data/Expression.spec.js +0 -229
  599. package/src/data/Grouper.d.ts +0 -21
  600. package/src/data/Grouper.js +0 -144
  601. package/src/data/NestedDataView.d.ts +0 -19
  602. package/src/data/NestedDataView.js +0 -22
  603. package/src/data/ReadOnlyDataView.d.ts +0 -14
  604. package/src/data/ReadOnlyDataView.js +0 -27
  605. package/src/data/Ref.d.ts +0 -24
  606. package/src/data/Ref.js +0 -79
  607. package/src/data/Ref.spec.js +0 -79
  608. package/src/data/Store.d.ts +0 -14
  609. package/src/data/Store.js +0 -46
  610. package/src/data/Store.spec.js +0 -22
  611. package/src/data/StoreProxy.d.ts +0 -5
  612. package/src/data/StoreProxy.js +0 -17
  613. package/src/data/StoreRef.js +0 -54
  614. package/src/data/StoreRef.spec.js +0 -24
  615. package/src/data/StringTemplate.d.ts +0 -15
  616. package/src/data/StringTemplate.js +0 -92
  617. package/src/data/StringTemplate.spec.js +0 -132
  618. package/src/data/StructuredDataAccessor.d.ts +0 -7
  619. package/src/data/StructuredSelector.d.ts +0 -17
  620. package/src/data/StructuredSelector.js +0 -132
  621. package/src/data/StructuredSelector.spec.js +0 -113
  622. package/src/data/SubscribableView.d.ts +0 -11
  623. package/src/data/SubscribableView.js +0 -54
  624. package/src/data/View.d.ts +0 -155
  625. package/src/data/View.js +0 -182
  626. package/src/data/ZoomIntoPropertyView.d.ts +0 -11
  627. package/src/data/ZoomIntoPropertyView.js +0 -33
  628. package/src/data/ZoomIntoPropertyView.spec.js +0 -65
  629. package/src/data/comparer.d.ts +0 -7
  630. package/src/data/comparer.js +0 -54
  631. package/src/data/computable.d.ts +0 -125
  632. package/src/data/computable.js +0 -56
  633. package/src/data/computable.spec.js +0 -55
  634. package/src/data/createAccessorModelProxy.d.ts +0 -6
  635. package/src/data/createAccessorModelProxy.js +0 -43
  636. package/src/data/createStructuredSelector.d.ts +0 -3
  637. package/src/data/createStructuredSelector.js +0 -43
  638. package/src/data/createStructuredSelector.spec.js +0 -46
  639. package/src/data/defaultCompare.d.ts +0 -1
  640. package/src/data/defaultCompare.js +0 -15
  641. package/src/data/diff/diffArrays.d.ts +0 -15
  642. package/src/data/diff/diffArrays.js +0 -41
  643. package/src/data/diff/diffs.spec.js +0 -49
  644. package/src/data/diff/index.d.ts +0 -1
  645. package/src/data/diff/index.js +0 -1
  646. package/src/data/enableFatArrowExpansion.d.ts +0 -1
  647. package/src/data/enableFatArrowExpansion.js +0 -6
  648. package/src/data/getAccessor.d.ts +0 -9
  649. package/src/data/getAccessor.js +0 -61
  650. package/src/data/getAccessor.spec.js +0 -11
  651. package/src/data/getSelector.d.ts +0 -3
  652. package/src/data/getSelector.js +0 -49
  653. package/src/data/getSelector.spec.js +0 -43
  654. package/src/data/index.d.ts +0 -30
  655. package/src/data/index.js +0 -29
  656. package/src/data/isSelector.d.ts +0 -1
  657. package/src/data/isSelector.js +0 -26
  658. package/src/data/ops/append.d.ts +0 -1
  659. package/src/data/ops/append.js +0 -7
  660. package/src/data/ops/append.spec.js +0 -28
  661. package/src/data/ops/filter.d.ts +0 -1
  662. package/src/data/ops/filter.js +0 -8
  663. package/src/data/ops/filter.spec.js +0 -29
  664. package/src/data/ops/findTreeNode.d.ts +0 -1
  665. package/src/data/ops/findTreeNode.js +0 -15
  666. package/src/data/ops/findTreeNode.spec.js +0 -24
  667. package/src/data/ops/findTreePath.d.ts +0 -6
  668. package/src/data/ops/findTreePath.js +0 -16
  669. package/src/data/ops/index.d.ts +0 -10
  670. package/src/data/ops/insertElement.d.ts +0 -1
  671. package/src/data/ops/insertElement.js +0 -3
  672. package/src/data/ops/merge.d.ts +0 -3
  673. package/src/data/ops/merge.js +0 -9
  674. package/src/data/ops/merge.spec.js +0 -27
  675. package/src/data/ops/moveElement.d.ts +0 -1
  676. package/src/data/ops/moveElement.js +0 -14
  677. package/src/data/ops/removeTreeNodes.d.ts +0 -5
  678. package/src/data/ops/removeTreeNodes.js +0 -5
  679. package/src/data/ops/removeTreeNodes.spec.js +0 -28
  680. package/src/data/ops/updateArray.d.ts +0 -6
  681. package/src/data/ops/updateArray.js +0 -24
  682. package/src/data/ops/updateArray.spec.js +0 -38
  683. package/src/data/ops/updateTree.d.ts +0 -7
  684. package/src/data/ops/updateTree.js +0 -25
  685. package/src/data/ops/updateTree.spec.js +0 -36
  686. package/src/hooks/createLocalStorageRef.d.ts +0 -3
  687. package/src/hooks/createLocalStorageRef.js +0 -20
  688. package/src/hooks/index.js +0 -8
  689. package/src/hooks/invokeCallback.d.ts +0 -5
  690. package/src/hooks/invokeCallback.js +0 -7
  691. package/src/hooks/invokeCallback.spec.js +0 -53
  692. package/src/hooks/resolveCallback.d.ts +0 -3
  693. package/src/hooks/resolveCallback.js +0 -12
  694. package/src/hooks/resolveCallback.spec.js +0 -54
  695. package/src/hooks/store.d.ts +0 -8
  696. package/src/hooks/store.js +0 -32
  697. package/src/hooks/store.spec.js +0 -73
  698. package/src/hooks/useEffect.d.ts +0 -3
  699. package/src/hooks/useEffect.js +0 -15
  700. package/src/hooks/useInterval.d.ts +0 -1
  701. package/src/hooks/useInterval.js +0 -8
  702. package/src/hooks/useState.d.ts +0 -3
  703. package/src/hooks/useState.js +0 -16
  704. package/src/hooks/useTrigger.d.ts +0 -5
  705. package/src/hooks/useTrigger.js +0 -20
  706. package/src/hooks/useTrigger.spec.js +0 -102
  707. package/src/svg/BoundedObject.d.ts +0 -23
  708. package/src/svg/BoundedObject.js +0 -59
  709. package/src/svg/ClipRect.d.ts +0 -5
  710. package/src/svg/ClipRect.js +0 -23
  711. package/src/svg/Ellipse.d.ts +0 -24
  712. package/src/svg/Ellipse.js +0 -37
  713. package/src/svg/Line.d.ts +0 -21
  714. package/src/svg/Line.js +0 -33
  715. package/src/svg/NonOverlappingRect.d.ts +0 -5
  716. package/src/svg/NonOverlappingRect.js +0 -15
  717. package/src/svg/NonOverlappingRectGroup.d.ts +0 -3
  718. package/src/svg/NonOverlappingRectGroup.js +0 -37
  719. package/src/svg/Rectangle.d.ts +0 -37
  720. package/src/svg/Rectangle.js +0 -42
  721. package/src/svg/Svg.d.ts +0 -32
  722. package/src/svg/Svg.js +0 -177
  723. package/src/svg/Text.d.ts +0 -40
  724. package/src/svg/Text.js +0 -78
  725. package/src/svg/TextualBoundedObject.d.ts +0 -7
  726. package/src/svg/TextualBoundedObject.js +0 -28
  727. package/src/svg/index.d.ts +0 -11
  728. package/src/svg/util/Rect.d.ts +0 -41
  729. package/src/svg/util/Rect.js +0 -109
  730. package/src/svg/util/index.js +0 -1
  731. package/src/ui/CSS.d.ts +0 -20
  732. package/src/ui/CSS.js +0 -79
  733. package/src/ui/CSSHelper.d.ts +0 -11
  734. package/src/ui/CSSHelper.js +0 -18
  735. package/src/ui/Container.d.ts +0 -18
  736. package/src/ui/Container.js +0 -154
  737. package/src/ui/ContentResolver.d.ts +0 -12
  738. package/src/ui/ContentResolver.js +0 -78
  739. package/src/ui/Controller.d.ts +0 -182
  740. package/src/ui/Controller.js +0 -114
  741. package/src/ui/Controller.spec.js +0 -415
  742. package/src/ui/Culture.d.ts +0 -57
  743. package/src/ui/Culture.js +0 -139
  744. package/src/ui/Cx.d.ts +0 -18
  745. package/src/ui/Cx.js +0 -325
  746. package/src/ui/Cx.spec.js +0 -194
  747. package/src/ui/DataProxy.d.ts +0 -12
  748. package/src/ui/DataProxy.js +0 -31
  749. package/src/ui/DataProxy.spec.js +0 -338
  750. package/src/ui/DetachedScope.d.ts +0 -21
  751. package/src/ui/DetachedScope.js +0 -98
  752. package/src/ui/FocusManager.d.ts +0 -29
  753. package/src/ui/FocusManager.js +0 -171
  754. package/src/ui/Format.d.ts +0 -3
  755. package/src/ui/Format.js +0 -108
  756. package/src/ui/HoverSync.d.ts +0 -13
  757. package/src/ui/HoverSync.js +0 -147
  758. package/src/ui/Instance.d.ts +0 -72
  759. package/src/ui/Instance.js +0 -620
  760. package/src/ui/IsolatedScope.d.ts +0 -16
  761. package/src/ui/IsolatedScope.js +0 -30
  762. package/src/ui/IsolatedScope.spec.js +0 -62
  763. package/src/ui/Localization.d.ts +0 -17
  764. package/src/ui/Localization.js +0 -70
  765. package/src/ui/PureContainer.d.ts +0 -16
  766. package/src/ui/PureContainer.js +0 -7
  767. package/src/ui/RenderingContext.d.ts +0 -9
  768. package/src/ui/RenderingContext.js +0 -88
  769. package/src/ui/Repeater.d.ts +0 -61
  770. package/src/ui/Repeater.js +0 -109
  771. package/src/ui/Repeater.spec.js +0 -143
  772. package/src/ui/Rescope.d.ts +0 -10
  773. package/src/ui/Rescope.js +0 -35
  774. package/src/ui/Rescope.spec.js +0 -195
  775. package/src/ui/ResizeManager.d.ts +0 -10
  776. package/src/ui/ResizeManager.js +0 -31
  777. package/src/ui/Restate.d.ts +0 -21
  778. package/src/ui/Restate.js +0 -167
  779. package/src/ui/Restate.spec.js +0 -422
  780. package/src/ui/StaticText.d.ts +0 -8
  781. package/src/ui/StaticText.js +0 -9
  782. package/src/ui/StructuredInstanceDataAccessor.d.ts +0 -16
  783. package/src/ui/StructuredInstanceDataAccessor.js +0 -26
  784. package/src/ui/Text.d.ts +0 -10
  785. package/src/ui/Text.js +0 -25
  786. package/src/ui/VDOM.d.ts +0 -12
  787. package/src/ui/VDOM.js +0 -2
  788. package/src/ui/Widget.d.ts +0 -14
  789. package/src/ui/Widget.js +0 -184
  790. package/src/ui/ZIndexManager.d.ts +0 -7
  791. package/src/ui/ZIndexManager.js +0 -11
  792. package/src/ui/adapter/ArrayAdapter.d.ts +0 -17
  793. package/src/ui/adapter/ArrayAdapter.js +0 -152
  794. package/src/ui/adapter/ArrayAdapter.spec.js +0 -55
  795. package/src/ui/adapter/DataAdapter.d.ts +0 -31
  796. package/src/ui/adapter/DataAdapter.js +0 -15
  797. package/src/ui/adapter/GroupAdapter.d.ts +0 -23
  798. package/src/ui/adapter/GroupAdapter.js +0 -143
  799. package/src/ui/adapter/TreeAdapter.d.ts +0 -24
  800. package/src/ui/adapter/TreeAdapter.js +0 -101
  801. package/src/ui/adapter/TreeAdapter.spec.js +0 -67
  802. package/src/ui/adapter/index.js +0 -4
  803. package/src/ui/app/History.d.ts +0 -17
  804. package/src/ui/app/History.js +0 -114
  805. package/src/ui/app/Url.d.ts +0 -21
  806. package/src/ui/app/Url.js +0 -103
  807. package/src/ui/app/Url.spec.js +0 -51
  808. package/src/ui/app/index.d.ts +0 -4
  809. package/src/ui/app/startAppLoop.d.ts +0 -4
  810. package/src/ui/app/startAppLoop.js +0 -58
  811. package/src/ui/app/startHotAppLoop.d.ts +0 -7
  812. package/src/ui/app/startHotAppLoop.js +0 -25
  813. package/src/ui/batchUpdates.d.ts +0 -11
  814. package/src/ui/batchUpdates.js +0 -67
  815. package/src/ui/bind.d.ts +0 -4
  816. package/src/ui/bind.js +0 -7
  817. package/src/ui/createFunctionalComponent.d.ts +0 -1
  818. package/src/ui/createFunctionalComponent.js +0 -63
  819. package/src/ui/createFunctionalComponent.spec.js +0 -400
  820. package/src/ui/expr.d.ts +0 -24
  821. package/src/ui/expr.js +0 -17
  822. package/src/ui/flattenProps.js +0 -21
  823. package/src/ui/index.d.ts +0 -42
  824. package/src/ui/index.js +0 -44
  825. package/src/ui/keyboardShortcuts.d.ts +0 -5
  826. package/src/ui/keyboardShortcuts.js +0 -31
  827. package/src/ui/layout/Content.d.ts +0 -14
  828. package/src/ui/layout/Content.js +0 -16
  829. package/src/ui/layout/ContentPlaceholder.d.ts +0 -19
  830. package/src/ui/layout/ContentPlaceholder.js +0 -105
  831. package/src/ui/layout/ContentPlaceholder.spec.js +0 -579
  832. package/src/ui/layout/FirstVisibleChildLayout.d.ts +0 -4
  833. package/src/ui/layout/FirstVisibleChildLayout.js +0 -66
  834. package/src/ui/layout/FirstVisibleChildLayout.spec.js +0 -196
  835. package/src/ui/layout/LabelsLeftLayout.d.ts +0 -11
  836. package/src/ui/layout/LabelsLeftLayout.js +0 -59
  837. package/src/ui/layout/LabelsTopLayout.d.ts +0 -15
  838. package/src/ui/layout/LabelsTopLayout.js +0 -135
  839. package/src/ui/layout/UseParentLayout.d.ts +0 -4
  840. package/src/ui/layout/UseParentLayout.js +0 -6
  841. package/src/ui/layout/exploreChildren.d.ts +0 -12
  842. package/src/ui/layout/exploreChildren.js +0 -27
  843. package/src/ui/layout/index.js +0 -10
  844. package/src/ui/selection/KeySelection.d.ts +0 -17
  845. package/src/ui/selection/KeySelection.js +0 -129
  846. package/src/ui/selection/PropertySelection.d.ts +0 -17
  847. package/src/ui/selection/PropertySelection.js +0 -55
  848. package/src/ui/selection/Selection.d.ts +0 -27
  849. package/src/ui/selection/Selection.js +0 -93
  850. package/src/ui/selection/index.js +0 -3
  851. package/src/ui/tpl.d.ts +0 -3
  852. package/src/ui/tpl.js +0 -5
  853. package/src/util/Component.d.ts +0 -42
  854. package/src/util/Component.js +0 -108
  855. package/src/util/Console.d.ts +0 -4
  856. package/src/util/Console.js +0 -11
  857. package/src/util/DOM.d.ts +0 -33
  858. package/src/util/DOM.js +0 -72
  859. package/src/util/Debug.d.ts +0 -11
  860. package/src/util/Debug.js +0 -45
  861. package/src/util/Format.d.ts +0 -18
  862. package/src/util/Format.js +0 -270
  863. package/src/util/Format.spec.js +0 -69
  864. package/src/util/GlobalCacheIdentifier.js +0 -11
  865. package/src/util/GlobalCacheldentifier.d.ts +0 -7
  866. package/src/util/KeyCode.d.ts +0 -21
  867. package/src/util/KeyCode.js +0 -21
  868. package/src/util/SubscriberList.d.ts +0 -42
  869. package/src/util/SubscriberList.js +0 -58
  870. package/src/util/Timing.d.ts +0 -14
  871. package/src/util/Timing.js +0 -58
  872. package/src/util/TraversalStack.js +0 -43
  873. package/src/util/TraversalStack.spec.js +0 -47
  874. package/src/util/addEventListenerWithOptions.d.ts +0 -6
  875. package/src/util/addEventListenerWithOptions.js +0 -9
  876. package/src/util/browserSupportsPassiveEventHandlers.d.ts +0 -5
  877. package/src/util/browserSupportsPassiveEventHandlers.js +0 -18
  878. package/src/util/calculateNaturalElementHeight.d.ts +0 -1
  879. package/src/util/calculateNaturalElementHeight.js +0 -22
  880. package/src/util/capitalize.d.ts +0 -1
  881. package/src/util/capitalize.js +0 -4
  882. package/src/util/coalesce.d.ts +0 -1
  883. package/src/util/coalesce.js +0 -6
  884. package/src/util/color/hslToRgb.d.ts +0 -9
  885. package/src/util/color/hslToRgb.js +0 -27
  886. package/src/util/color/index.d.ts +0 -4
  887. package/src/util/color/parseColor.d.ts +0 -60
  888. package/src/util/color/parseColor.js +0 -119
  889. package/src/util/color/rgbToHex.d.ts +0 -9
  890. package/src/util/color/rgbToHex.js +0 -8
  891. package/src/util/color/rgbToHsl.d.ts +0 -9
  892. package/src/util/color/rgbToHsl.js +0 -28
  893. package/src/util/date/dateDiff.d.ts +0 -8
  894. package/src/util/date/dateDiff.js +0 -3
  895. package/src/util/date/diff.d.ts +0 -8
  896. package/src/util/date/diff.js +0 -7
  897. package/src/util/date/encodeDate.d.ts +0 -1
  898. package/src/util/date/encodeDate.js +0 -8
  899. package/src/util/date/encodeDateWithTimezoneOffset.d.ts +0 -1
  900. package/src/util/date/encodeDateWithTimezoneOffset.js +0 -19
  901. package/src/util/date/index.js +0 -11
  902. package/src/util/date/lowerBoundCheck.d.ts +0 -8
  903. package/src/util/date/lowerBoundCheck.js +0 -6
  904. package/src/util/date/maxDate.d.ts +0 -6
  905. package/src/util/date/maxDate.js +0 -9
  906. package/src/util/date/minDate.d.ts +0 -6
  907. package/src/util/date/minDate.js +0 -9
  908. package/src/util/date/monthStart.d.ts +0 -6
  909. package/src/util/date/monthStart.js +0 -3
  910. package/src/util/date/parseDateInvariant.d.ts +0 -3
  911. package/src/util/date/parseDateInvariant.js +0 -20
  912. package/src/util/date/sameDate.d.ts +0 -7
  913. package/src/util/date/sameDate.js +0 -5
  914. package/src/util/date/upperBoundCheck.d.ts +0 -8
  915. package/src/util/date/upperBoundCheck.js +0 -6
  916. package/src/util/date/zeroTime.d.ts +0 -7
  917. package/src/util/date/zeroTime.js +0 -3
  918. package/src/util/debounce.d.ts +0 -9
  919. package/src/util/debounce.js +0 -18
  920. package/src/util/dummyCallback.d.ts +0 -1
  921. package/src/util/dummyCallback.js +0 -1
  922. package/src/util/escapeSpecialRegexCharacters.d.ts +0 -7
  923. package/src/util/escapeSpecialRegexCharacters.js +0 -3
  924. package/src/util/eventCallbacks.d.ts +0 -5
  925. package/src/util/eventCallbacks.js +0 -2
  926. package/src/util/expandFatArrows.d.ts +0 -1
  927. package/src/util/expandFatArrows.js +0 -118
  928. package/src/util/findScrollableParent.d.ts +0 -1
  929. package/src/util/findScrollableParent.js +0 -16
  930. package/src/util/getActiveElement.d.ts +0 -1
  931. package/src/util/getActiveElement.js +0 -4
  932. package/src/util/getParentFrameBoundingClientRect.d.ts +0 -1
  933. package/src/util/getParentFrameBoundingClientRect.js +0 -21
  934. package/src/util/getScrollerBoundingClientRect.d.ts +0 -1
  935. package/src/util/getScrollerBoundingClientRect.js +0 -22
  936. package/src/util/getSearchQueryPredicate.d.ts +0 -1
  937. package/src/util/getSearchQueryPredicate.js +0 -59
  938. package/src/util/getTopLevelBoundingClientRect.d.ts +0 -1
  939. package/src/util/getTopLevelBoundingClientRect.js +0 -14
  940. package/src/util/getVendorPrefix.d.ts +0 -1
  941. package/src/util/getVendorPrefix.js +0 -26
  942. package/src/util/index.d.ts +0 -51
  943. package/src/util/index.js +0 -54
  944. package/src/util/innerTextTrim.d.ts +0 -7
  945. package/src/util/innerTextTrim.js +0 -5
  946. package/src/util/isArray.d.ts +0 -1
  947. package/src/util/isArray.js +0 -3
  948. package/src/util/isDefined.d.ts +0 -1
  949. package/src/util/isDefined.js +0 -3
  950. package/src/util/isDigit.d.ts +0 -7
  951. package/src/util/isDigit.js +0 -3
  952. package/src/util/isFunction.d.ts +0 -1
  953. package/src/util/isFunction.js +0 -3
  954. package/src/util/isNonEmptyArray.d.ts +0 -1
  955. package/src/util/isNonEmptyArray.js +0 -3
  956. package/src/util/isNumber.d.ts +0 -1
  957. package/src/util/isNumber.js +0 -3
  958. package/src/util/isObject.d.ts +0 -1
  959. package/src/util/isObject.js +0 -3
  960. package/src/util/isPromise.d.ts +0 -1
  961. package/src/util/isPromise.js +0 -6
  962. package/src/util/isString.d.ts +0 -1
  963. package/src/util/isString.js +0 -3
  964. package/src/util/isTextInputElement.d.ts +0 -1
  965. package/src/util/isTextInputElement.js +0 -3
  966. package/src/util/isTouchDevice.d.ts +0 -2
  967. package/src/util/isTouchDevice.js +0 -7
  968. package/src/util/isTouchEvent.d.ts +0 -4
  969. package/src/util/isTouchEvent.js +0 -64
  970. package/src/util/isUndefined.d.ts +0 -1
  971. package/src/util/isUndefined.js +0 -3
  972. package/src/util/isValidIdentifierName.d.ts +0 -1
  973. package/src/util/isValidIdentifierName.js +0 -5
  974. package/src/util/onIdleCallback.d.ts +0 -1
  975. package/src/util/onIdleCallback.js +0 -14
  976. package/src/util/parseStyle.d.ts +0 -4
  977. package/src/util/parseStyle.js +0 -27
  978. package/src/util/quote.d.ts +0 -3
  979. package/src/util/quote.js +0 -4
  980. package/src/util/reverseSlice.d.ts +0 -1
  981. package/src/util/reverseSlice.js +0 -10
  982. package/src/util/routeAppend.d.ts +0 -1
  983. package/src/util/routeAppend.js +0 -16
  984. package/src/util/scrollElementIntoView.d.ts +0 -7
  985. package/src/util/scrollElementIntoView.js +0 -34
  986. package/src/util/shallowEquals.d.ts +0 -1
  987. package/src/util/shallowEquals.js +0 -43
  988. package/src/util/throttle.d.ts +0 -9
  989. package/src/util/throttle.js +0 -14
  990. package/src/util/validatedDebounce.js +0 -19
  991. package/src/widgets/Button.d.ts +0 -58
  992. package/src/widgets/Button.js +0 -118
  993. package/src/widgets/CxCredit.d.ts +0 -12
  994. package/src/widgets/CxCredit.js +0 -32
  995. package/src/widgets/DocumentTitle.d.ts +0 -11
  996. package/src/widgets/DocumentTitle.js +0 -69
  997. package/src/widgets/FlexBox.d.ts +0 -69
  998. package/src/widgets/FlexBox.js +0 -93
  999. package/src/widgets/Heading.d.ts +0 -16
  1000. package/src/widgets/Heading.js +0 -33
  1001. package/src/widgets/HighlightedSearchText.d.ts +0 -9
  1002. package/src/widgets/HighlightedSearchText.js +0 -36
  1003. package/src/widgets/HtmlElement.d.ts +0 -30
  1004. package/src/widgets/HtmlElement.js +0 -275
  1005. package/src/widgets/HtmlElement.spec.js +0 -57
  1006. package/src/widgets/Icon.d.ts +0 -34
  1007. package/src/widgets/Icon.js +0 -50
  1008. package/src/widgets/List.d.ts +0 -96
  1009. package/src/widgets/List.js +0 -594
  1010. package/src/widgets/ProgressBar.d.ts +0 -17
  1011. package/src/widgets/ProgressBar.js +0 -46
  1012. package/src/widgets/Resizer.d.ts +0 -27
  1013. package/src/widgets/Resizer.js +0 -151
  1014. package/src/widgets/Sandbox.d.ts +0 -18
  1015. package/src/widgets/Sandbox.js +0 -65
  1016. package/src/widgets/Section.d.ts +0 -52
  1017. package/src/widgets/Section.js +0 -139
  1018. package/src/widgets/autoFocus.d.ts +0 -1
  1019. package/src/widgets/autoFocus.js +0 -9
  1020. package/src/widgets/cx.d.ts +0 -2
  1021. package/src/widgets/cx.js +0 -72
  1022. package/src/widgets/drag-drop/DragHandle.d.ts +0 -10
  1023. package/src/widgets/drag-drop/DragHandle.js +0 -37
  1024. package/src/widgets/drag-drop/DragSource.d.ts +0 -45
  1025. package/src/widgets/drag-drop/DragSource.js +0 -160
  1026. package/src/widgets/drag-drop/DropZone.d.ts +0 -98
  1027. package/src/widgets/drag-drop/DropZone.js +0 -214
  1028. package/src/widgets/drag-drop/index.js +0 -4
  1029. package/src/widgets/drag-drop/ops.d.ts +0 -57
  1030. package/src/widgets/drag-drop/ops.js +0 -344
  1031. package/src/widgets/enableAllInternalDependencies.d.ts +0 -1
  1032. package/src/widgets/enableAllInternalDependencies.js +0 -11
  1033. package/src/widgets/form/Calendar.d.ts +0 -86
  1034. package/src/widgets/form/Calendar.js +0 -618
  1035. package/src/widgets/form/Checkbox.d.ts +0 -43
  1036. package/src/widgets/form/Checkbox.js +0 -203
  1037. package/src/widgets/form/ColorField.d.ts +0 -44
  1038. package/src/widgets/form/ColorField.js +0 -397
  1039. package/src/widgets/form/ColorPicker.d.ts +0 -23
  1040. package/src/widgets/form/ColorPicker.js +0 -485
  1041. package/src/widgets/form/DateField.d.ts +0 -6
  1042. package/src/widgets/form/DateField.js +0 -12
  1043. package/src/widgets/form/DateTimeField.d.ts +0 -89
  1044. package/src/widgets/form/DateTimeField.js +0 -576
  1045. package/src/widgets/form/DateTimePicker.js +0 -392
  1046. package/src/widgets/form/Field.d.ts +0 -112
  1047. package/src/widgets/form/Field.js +0 -446
  1048. package/src/widgets/form/FieldGroup.d.ts +0 -6
  1049. package/src/widgets/form/FieldGroup.js +0 -6
  1050. package/src/widgets/form/FieldIcon.js +0 -42
  1051. package/src/widgets/form/HelpText.d.ts +0 -10
  1052. package/src/widgets/form/HelpText.js +0 -9
  1053. package/src/widgets/form/Label.d.ts +0 -23
  1054. package/src/widgets/form/Label.js +0 -89
  1055. package/src/widgets/form/LabeledContainer.d.ts +0 -9
  1056. package/src/widgets/form/LabeledContainer.js +0 -59
  1057. package/src/widgets/form/LookupField.d.ts +0 -179
  1058. package/src/widgets/form/LookupField.js +0 -1135
  1059. package/src/widgets/form/MonthField.d.ts +0 -104
  1060. package/src/widgets/form/MonthField.js +0 -524
  1061. package/src/widgets/form/MonthPicker.d.ts +0 -97
  1062. package/src/widgets/form/MonthPicker.js +0 -687
  1063. package/src/widgets/form/NumberField.d.ts +0 -96
  1064. package/src/widgets/form/NumberField.js +0 -459
  1065. package/src/widgets/form/Radio.d.ts +0 -37
  1066. package/src/widgets/form/Radio.js +0 -188
  1067. package/src/widgets/form/Select.d.ts +0 -69
  1068. package/src/widgets/form/Select.js +0 -269
  1069. package/src/widgets/form/Slider.d.ts +0 -65
  1070. package/src/widgets/form/Slider.js +0 -351
  1071. package/src/widgets/form/Switch.d.ts +0 -38
  1072. package/src/widgets/form/Switch.js +0 -118
  1073. package/src/widgets/form/TextArea.d.ts +0 -17
  1074. package/src/widgets/form/TextArea.js +0 -195
  1075. package/src/widgets/form/TextField.d.ts +0 -78
  1076. package/src/widgets/form/TextField.js +0 -290
  1077. package/src/widgets/form/TimeField.d.ts +0 -6
  1078. package/src/widgets/form/TimeField.js +0 -11
  1079. package/src/widgets/form/TimeList.js +0 -84
  1080. package/src/widgets/form/UploadButton.d.ts +0 -34
  1081. package/src/widgets/form/UploadButton.js +0 -213
  1082. package/src/widgets/form/ValidationError.d.ts +0 -10
  1083. package/src/widgets/form/ValidationError.js +0 -44
  1084. package/src/widgets/form/ValidationGroup.d.ts +0 -41
  1085. package/src/widgets/form/ValidationGroup.js +0 -68
  1086. package/src/widgets/form/ValidationGroup.spec.js +0 -148
  1087. package/src/widgets/form/Validator.d.ts +0 -8
  1088. package/src/widgets/form/Validator.js +0 -21
  1089. package/src/widgets/form/Wheel.js +0 -261
  1090. package/src/widgets/form/index.d.ts +0 -26
  1091. package/src/widgets/grid/Grid.d.ts +0 -445
  1092. package/src/widgets/grid/Grid.js +0 -3431
  1093. package/src/widgets/grid/GridCell.d.ts +0 -38
  1094. package/src/widgets/grid/GridCell.js +0 -71
  1095. package/src/widgets/grid/GridCellEditor.js +0 -41
  1096. package/src/widgets/grid/GridRow.js +0 -228
  1097. package/src/widgets/grid/GridRowLine.js +0 -24
  1098. package/src/widgets/grid/Pagination.d.ts +0 -14
  1099. package/src/widgets/grid/Pagination.js +0 -95
  1100. package/src/widgets/grid/TreeNode.d.ts +0 -23
  1101. package/src/widgets/grid/TreeNode.js +0 -102
  1102. package/src/widgets/grid/index.d.ts +0 -4
  1103. package/src/widgets/grid/index.js +0 -15
  1104. package/src/widgets/icons/calendar.js +0 -16
  1105. package/src/widgets/icons/check.js +0 -12
  1106. package/src/widgets/icons/clear.js +0 -14
  1107. package/src/widgets/icons/close.js +0 -19
  1108. package/src/widgets/icons/cx.js +0 -37
  1109. package/src/widgets/icons/drop-down.js +0 -14
  1110. package/src/widgets/icons/file.js +0 -12
  1111. package/src/widgets/icons/folder-open.js +0 -14
  1112. package/src/widgets/icons/folder.js +0 -12
  1113. package/src/widgets/icons/forward.js +0 -21
  1114. package/src/widgets/icons/loading.js +0 -23
  1115. package/src/widgets/icons/menu.js +0 -16
  1116. package/src/widgets/icons/pixel-picker.js +0 -17
  1117. package/src/widgets/icons/registry.js +0 -54
  1118. package/src/widgets/icons/search.js +0 -12
  1119. package/src/widgets/icons/sort-asc.js +0 -13
  1120. package/src/widgets/icons/square.js +0 -17
  1121. package/src/widgets/nav/Link.d.ts +0 -26
  1122. package/src/widgets/nav/Link.js +0 -8
  1123. package/src/widgets/nav/LinkButton.d.ts +0 -34
  1124. package/src/widgets/nav/LinkButton.js +0 -128
  1125. package/src/widgets/nav/Menu.d.ts +0 -27
  1126. package/src/widgets/nav/Menu.js +0 -406
  1127. package/src/widgets/nav/MenuItem.d.ts +0 -31
  1128. package/src/widgets/nav/MenuItem.js +0 -445
  1129. package/src/widgets/nav/MenuSpacer.d.ts +0 -5
  1130. package/src/widgets/nav/MenuSpacer.js +0 -13
  1131. package/src/widgets/nav/RedirectRoute.d.ts +0 -9
  1132. package/src/widgets/nav/RedirectRoute.js +0 -41
  1133. package/src/widgets/nav/Route.d.ts +0 -21
  1134. package/src/widgets/nav/Route.js +0 -102
  1135. package/src/widgets/nav/Route.spec.js +0 -27
  1136. package/src/widgets/nav/Scroller.d.ts +0 -17
  1137. package/src/widgets/nav/Scroller.js +0 -214
  1138. package/src/widgets/nav/Submenu.d.ts +0 -6
  1139. package/src/widgets/nav/Submenu.js +0 -6
  1140. package/src/widgets/nav/Tab.d.ts +0 -33
  1141. package/src/widgets/nav/Tab.js +0 -82
  1142. package/src/widgets/nav/index.js +0 -10
  1143. package/src/widgets/overlay/ContextMenu.d.ts +0 -10
  1144. package/src/widgets/overlay/ContextMenu.js +0 -29
  1145. package/src/widgets/overlay/Dropdown.d.ts +0 -32
  1146. package/src/widgets/overlay/Dropdown.js +0 -612
  1147. package/src/widgets/overlay/FlyweightTooltipTracker.d.ts +0 -8
  1148. package/src/widgets/overlay/FlyweightTooltipTracker.js +0 -39
  1149. package/src/widgets/overlay/MsgBox.d.ts +0 -17
  1150. package/src/widgets/overlay/MsgBox.js +0 -116
  1151. package/src/widgets/overlay/Overlay.d.ts +0 -73
  1152. package/src/widgets/overlay/Overlay.js +0 -747
  1153. package/src/widgets/overlay/Toast.d.ts +0 -30
  1154. package/src/widgets/overlay/Toast.js +0 -93
  1155. package/src/widgets/overlay/Tooltip.d.ts +0 -50
  1156. package/src/widgets/overlay/Tooltip.js +0 -308
  1157. package/src/widgets/overlay/Window.d.ts +0 -42
  1158. package/src/widgets/overlay/Window.js +0 -202
  1159. package/src/widgets/overlay/alerts.d.ts +0 -7
  1160. package/src/widgets/overlay/alerts.js +0 -39
  1161. package/src/widgets/overlay/captureMouse.d.ts +0 -54
  1162. package/src/widgets/overlay/captureMouse.js +0 -124
  1163. package/src/widgets/overlay/createHotPromiseWindowFactory.d.ts +0 -18
  1164. package/src/widgets/overlay/createHotPromiseWindowFactory.js +0 -56
  1165. package/src/widgets/overlay/index.js +0 -11
  1166. package/src/widgets/overlay/tooltip-ops.d.ts +0 -11
  1167. package/src/widgets/overlay/tooltip-ops.js +0 -29
  1168. package/svg.d.ts +0 -1
  1169. package/svg.js +0 -1
  1170. package/ui.d.ts +0 -1
  1171. package/ui.js +0 -1
  1172. package/util.d.ts +0 -1
  1173. package/util.js +0 -1
  1174. package/widgets.d.ts +0 -1
  1175. package/widgets.js +0 -1
  1176. /package/src/charts/{index.js → index.ts} +0 -0
  1177. /package/src/data/{Binding.spec.js → Binding.spec.ts} +0 -0
  1178. /package/src/data/{Grouper.spec.js → Grouper.spec.ts} +0 -0
  1179. /package/src/data/{View.spec.js → View.spec.ts} +0 -0
  1180. /package/src/data/{comparer.spec.js → comparer.spec.ts} +0 -0
  1181. /package/src/data/ops/{index.js → index.ts} +0 -0
  1182. /package/src/hooks/{index.d.ts → index.ts} +0 -0
  1183. /package/src/{index.js → index.ts} +0 -0
  1184. /package/src/svg/{index.js → index.ts} +0 -0
  1185. /package/src/svg/util/{index.d.ts → index.ts} +0 -0
  1186. /package/src/ui/adapter/{index.d.ts → index.ts} +0 -0
  1187. /package/src/ui/app/{index.js → index.ts} +0 -0
  1188. /package/src/ui/layout/{index.d.ts → index.ts} +0 -0
  1189. /package/src/ui/selection/{index.d.ts → index.ts} +0 -0
  1190. /package/src/util/color/{index.js → index.ts} +0 -0
  1191. /package/src/util/date/{index.d.ts → index.ts} +0 -0
  1192. /package/src/util/date/{upperBoundCheck.spec.js → upperBoundCheck.spec.ts} +0 -0
  1193. /package/src/util/{getSearchQueryPredicate.spec.js → getSearchQueryPredicate.spec.ts} +0 -0
  1194. /package/src/util/{isValidIdentifierName.spec.js → isValidIdentifierName.spec.ts} +0 -0
  1195. /package/src/util/{routeAppend.spec.js → routeAppend.spec.ts} +0 -0
  1196. /package/src/widgets/drag-drop/{index.d.ts → index.ts} +0 -0
  1197. /package/src/widgets/form/{index.js → index.ts} +0 -0
  1198. /package/src/widgets/icons/{index.js → index.ts} +0 -0
  1199. /package/src/widgets/{index.js → index.ts} +0 -0
  1200. /package/src/widgets/nav/{index.d.ts → index.ts} +0 -0
@@ -0,0 +1,4247 @@
1
+ /** @jsxImportSource react */
2
+ import * as React from "react";
3
+ import { View } from "../../data";
4
+ import { Binding } from "../../data/Binding";
5
+ import { getAccessor } from "../../data/getAccessor";
6
+ import { getSelector } from "../../data/getSelector";
7
+ import { isSelector } from "../../data/isSelector";
8
+ import { ArrayAdapter } from "../../ui/adapter/ArrayAdapter";
9
+ import { DataAdapter, DataAdapterRecord } from "../../ui/adapter/DataAdapter";
10
+ import { GroupAdapter } from "../../ui/adapter/GroupAdapter";
11
+ import { batchUpdates } from "../../ui/batchUpdates";
12
+ import { ContainerBase, StyledContainerConfig } from "../../ui/Container";
13
+ import { Cx } from "../../ui/Cx";
14
+ import { FocusManager, offFocusOut, oneFocusOut, unfocusElement } from "../../ui/FocusManager";
15
+ import { Format } from "../../ui/Format";
16
+ import { Instance, InstanceCache } from "../../ui/Instance";
17
+ import { Localization } from "../../ui/Localization";
18
+ import {
19
+ BooleanProp,
20
+ ClassProp,
21
+ CollatorOptions,
22
+ Config,
23
+ DataRecord,
24
+ NumberProp,
25
+ Prop,
26
+ RecordAlias,
27
+ SortDirection,
28
+ SortersProp,
29
+ StringProp,
30
+ StructuredProp,
31
+ StyleProp,
32
+ UnknownProp,
33
+ } from "../../ui/Prop";
34
+ import { PureContainer, PureContainerBase, PureContainerConfig } from "../../ui/PureContainer";
35
+ import { RenderingContext } from "../../ui/RenderingContext";
36
+ import { ResizeManager } from "../../ui/ResizeManager";
37
+ import { Selection, SimpleSelection } from "../../ui/selection/Selection";
38
+ import type { KeySelection } from "../../ui/selection/KeySelection";
39
+ import type { PropertySelection } from "../../ui/selection/PropertySelection";
40
+ import { StaticText } from "../../ui/StaticText";
41
+ import { getContent, VDOM, Widget, WidgetConfig } from "../../ui/Widget";
42
+ import { Console } from "../../util/Console";
43
+ import { debounce } from "../../util/debounce";
44
+ import { closest, findFirstChild } from "../../util/DOM";
45
+ import { findScrollableParent } from "../../util/findScrollableParent";
46
+ import { getActiveElement } from "../../util/getActiveElement";
47
+ import { getParentFrameBoundingClientRect } from "../../util/getParentFrameBoundingClientRect";
48
+ import { getTopLevelBoundingClientRect } from "../../util/getTopLevelBoundingClientRect";
49
+ import { isArray } from "../../util/isArray";
50
+ import { isDefined } from "../../util/isDefined";
51
+ import { isNonEmptyArray } from "../../util/isNonEmptyArray";
52
+ import { isNumber } from "../../util/isNumber";
53
+ import { isObject } from "../../util/isObject";
54
+ import { isString } from "../../util/isString";
55
+ import { isTextInputElement } from "../../util/isTextInputElement";
56
+ import { KeyCode } from "../../util/KeyCode";
57
+ import { parseStyle } from "../../util/parseStyle";
58
+ import { scrollElementIntoView } from "../../util/scrollElementIntoView";
59
+ import { shallowEquals } from "../../util/shallowEquals";
60
+ import { SubscriberList } from "../../util/SubscriberList";
61
+ import {
62
+ ddDetect,
63
+ ddMouseDown,
64
+ DragDropOperationContext,
65
+ DragEvent,
66
+ initiateDragDrop,
67
+ registerDropZone,
68
+ } from "../drag-drop/ops";
69
+ import { HtmlElement } from "../HtmlElement";
70
+ import DropDownIcon from "../icons/sort-asc";
71
+ import { captureMouse2, getCursorPos } from "../overlay/captureMouse";
72
+ import { tooltipMouseLeave, tooltipMouseMove } from "../overlay/tooltip-ops";
73
+ import { createGridCellEditor } from "./createGridCellEditor";
74
+ import { GridRow, GridRowComponent, GridRowConfig, GridRowInstance } from "./GridRow";
75
+ import { Create, CreateConfig } from "../../util";
76
+ import type { TreeAdapter } from "../../ui/adapter/TreeAdapter";
77
+ export { GridRowConfig };
78
+
79
+ type FetchRecordsResult<T> = T[] | { records: T[]; lastPage?: boolean; totalRecordCount?: number };
80
+
81
+ interface MappedGridRecord<T = any> extends DataAdapterRecord<T> {
82
+ row?: GridRowInstance;
83
+ vdom?: any;
84
+ fixedVdom?: any;
85
+ grouping?: any;
86
+ level?: number;
87
+ group?: any;
88
+ }
89
+
90
+ interface GridDragEvent<T> extends DragEvent {
91
+ target: {
92
+ recordBefore?: MappedGridRecord<T>;
93
+ recordAfter?: MappedGridRecord<T>;
94
+ insertionIndex: number;
95
+ totalRecordCount: number;
96
+ dropNextToTheRowAbove?: boolean | null;
97
+ };
98
+ }
99
+
100
+ interface GridRowDragEvent<T> extends DragEvent {
101
+ target: {
102
+ record: MappedGridRecord<T>;
103
+ index: number;
104
+ };
105
+ }
106
+
107
+ interface GridColumnDropEvent extends DragEvent {
108
+ target: {
109
+ grid: any;
110
+ instance: Instance;
111
+ index: number;
112
+ };
113
+ }
114
+
115
+ interface GridDropOperationContext extends DragDropOperationContext {
116
+ test: {
117
+ grid: any;
118
+ row: any;
119
+ column: any;
120
+ };
121
+ }
122
+
123
+ interface GridMoveCursorOptions {
124
+ focused?: boolean;
125
+ hover?: any;
126
+ scrollIntoView?: boolean;
127
+ select?: boolean;
128
+ selectRange?: boolean;
129
+ selectOptions?: any;
130
+ cellIndex?: number;
131
+ cellEdit?: boolean;
132
+ cancelEdit?: boolean;
133
+ }
134
+
135
+ interface GridGroupingKey {
136
+ [key: string]:
137
+ | Prop<any>
138
+ | {
139
+ value: Prop<any>;
140
+ direction: SortDirection;
141
+ };
142
+ }
143
+
144
+ interface GroupingResult<T> {
145
+ key: any;
146
+ aggregates: any;
147
+ name: string;
148
+ indexes: number[];
149
+ records: MappedGridRecord<T>[];
150
+ }
151
+
152
+ type GridColumnAlignment = "left" | "right" | "center";
153
+
154
+ interface GridGroupingConfig<T> {
155
+ key: GridGroupingKey;
156
+ aggregates?: StructuredProp;
157
+ showCaption?: boolean;
158
+ showFooter?: boolean;
159
+ showHeader?: boolean;
160
+ caption?: StringProp;
161
+ name?: StringProp;
162
+ text?: StringProp;
163
+ comparer?: (a: GroupingResult<T>, b: GroupingResult<T>) => number;
164
+ }
165
+
166
+ // TODO: Check Column config
167
+ // Props are in order based on docs
168
+
169
+ export interface GridColumnHeaderConfig {
170
+ text?: StringProp;
171
+ colSpan?: NumberProp;
172
+ rowSpan?: NumberProp;
173
+ align?: GridColumnAlignment;
174
+ allowSorting?: boolean;
175
+ items?: React.ReactNode;
176
+ children?: React.ReactNode;
177
+ tool?: React.ReactNode;
178
+ style?: StyleProp;
179
+ class?: ClassProp;
180
+ className?: ClassProp;
181
+ tooltip?: StringProp | StructuredProp;
182
+ defaultWidth?: NumberProp;
183
+ width?: NumberProp;
184
+ resizable?: boolean;
185
+ }
186
+
187
+ export interface GridColumnFooterConfig {
188
+ value?: Prop<any>;
189
+ format?: StringProp;
190
+ style?: StyleProp;
191
+ class?: StyleProp;
192
+ expand?: boolean;
193
+ }
194
+
195
+ export interface GridColumnCaptionConfig {
196
+ value?: Prop<any>;
197
+ format?: StringProp;
198
+ style?: StyleProp;
199
+ class?: StyleProp;
200
+ children?: React.ReactNode;
201
+ items?: React.ReactNode;
202
+ expand?: boolean;
203
+ }
204
+
205
+ export interface GridColumnConfig {
206
+ align?: GridColumnAlignment;
207
+ field?: string;
208
+ format?: StringProp;
209
+ header?: StringProp | GridColumnHeaderConfig;
210
+ header1?: StringProp | GridColumnHeaderConfig;
211
+ header2?: StringProp | GridColumnHeaderConfig;
212
+ header3?: StringProp | GridColumnHeaderConfig;
213
+ fixed?: BooleanProp;
214
+ sortable?: boolean;
215
+ aggregate?: "min" | "max" | "count" | "sum" | "distinct" | "avg";
216
+ aggregateAlias?: string;
217
+ aggregateField?: string;
218
+ aggregateValue?: UnknownProp;
219
+ caption?: GridColumnCaptionConfig | StringProp | false;
220
+ class?: ClassProp;
221
+ className?: ClassProp;
222
+ draggable?: boolean;
223
+ editable?: boolean;
224
+ editor?: React.ReactNode;
225
+ footer?: GridColumnFooterConfig | StringProp | false;
226
+ items?: React.ReactNode;
227
+ children?: React.ReactNode;
228
+ key?: string;
229
+ pad?: boolean;
230
+ sortField?: string;
231
+ sortValue?: Prop<any>;
232
+ style?: StyleProp;
233
+ trimWhitespace?: boolean;
234
+ visible?: BooleanProp;
235
+ if?: BooleanProp;
236
+ weightField?: string;
237
+
238
+ // Not in docs
239
+ value?: Prop<any>;
240
+ defaultWidth?: NumberProp;
241
+ width?: NumberProp;
242
+ resizable?: boolean;
243
+ comparer?: (a: any, b: any) => number;
244
+
245
+ /** Options for data sorting. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator */
246
+ sortOptions?: CollatorOptions;
247
+ colSpan?: NumberProp;
248
+
249
+ mergeCells?: Prop<null | false | "same-value" | "always">;
250
+ primarySortDirection?: "ASC" | "DESC";
251
+ }
252
+
253
+ export interface GridConfig<T = any> extends StyledContainerConfig {
254
+ /** An array of records to be displayed in the grid. */
255
+ records?: Prop<T[]>;
256
+
257
+ /** Set to true to add a vertical scroll and a fixed header to the grid. */
258
+ scrollable?: boolean;
259
+
260
+ /** A binding used to store the sorting order list. Commonly used for server-side sorting. */
261
+ sorters?: SortersProp;
262
+
263
+ /** A list of sorters to be prepended to the actual list of sorters. */
264
+ preSorters?: SortersProp;
265
+
266
+ /** A binding used to store the name of the field used for sorting grids. Available only if sorters are not used. */
267
+ sortField?: StringProp;
268
+
269
+ /** A binding used to store the sort direction. Available only if sorters are not used. Possible values are "ASC" and "DESC". Defaults to "ASC". */
270
+ sortDirection?: StringProp;
271
+
272
+ /** Default sort field. Used if neither sortField or sorters are set. */
273
+ defaultSortField?: string;
274
+
275
+ /** Default sort direction. */
276
+ defaultSortDirection?: "ASC" | "DESC";
277
+
278
+ /** Set to true to add vertical gridlines. */
279
+ vlines?: boolean;
280
+
281
+ /** Text to be displayed instead of an empty table. */
282
+ emptyText?: StringProp;
283
+
284
+ /** Drag source configuration. Define mode as 'move' or 'copy` and additional data. */
285
+ dragSource?: StructuredProp;
286
+
287
+ /** Drop zone configuration. Define mode as either preview or insertion. */
288
+ dropZone?: StructuredProp;
289
+
290
+ /** Row configuration. See grid examples. */
291
+ row?: GridRowConfig;
292
+
293
+ /**An array of columns. Check column configuration options in the section below. */
294
+ columns?: GridColumnConfig[];
295
+
296
+ /** Whenever columnParams change, columns are recalculated using the onGetColumn callback. */
297
+ columnParams?: StructuredProp;
298
+
299
+ /** Selection configuration. */
300
+ selection?:
301
+ | CreateConfig<typeof Selection>
302
+ | CreateConfig<typeof KeySelection>
303
+ | CreateConfig<typeof PropertySelection>
304
+ | CreateConfig<typeof SimpleSelection>;
305
+
306
+ /** A grouping definition, field name, or an array of grouping level definitions. */
307
+ grouping?: string | GridGroupingConfig<T> | (string | GridGroupingConfig<T>)[];
308
+
309
+ /** Params for grouping. Whenever params change grouping is recalculated using the onGetGrouping callback. */
310
+ groupingParams?: StructuredProp;
311
+
312
+ /**
313
+ * Determines header appearance. Supported values are plain and default. Default mode is used if some of the columns are sortable.
314
+ * Plain mode better suits reports and other scenarios in which users do not interact with the grid.
315
+ */
316
+ headerMode?: StringProp;
317
+
318
+ /** Set to true to add default border around the table. Automatically set if grid is scrollable. */
319
+ border?: BooleanProp;
320
+
321
+ /** Base CSS class to be applied to the element. Default is 'grid'. */
322
+ baseClass?: string;
323
+
324
+ /** A field used to get the unique identifier of the record. Setting keyField improves grid performance on sort operations as the widget is able to identify row movement inside the grid. */
325
+ keyField?: string;
326
+
327
+ /** Show grid header within the group. Useful for long report-like (printable) grids. Defaults to false. */
328
+ showHeader?: boolean;
329
+
330
+ /** Show grid footer. Defaults to false. */
331
+ showFooter?: boolean;
332
+
333
+ /** Record alias. Default is $record. */
334
+ recordName?: RecordAlias;
335
+
336
+ /** Record alias. Default is $record. */
337
+ recordAlias?: RecordAlias;
338
+
339
+ /** Set to true if sorting is done remotely, on the server-side. Default value is false. */
340
+ remoteSort?: boolean;
341
+
342
+ /** Set to true to enable row caching. This greatly improves grid performance
343
+ on subsequent render operations, however, only changes on records
344
+ are allowed. If grid rows display any data outside records, changes on that
345
+ data will be ignored. */
346
+ cached?: boolean;
347
+
348
+ /** Render only rows visible on the screen. */
349
+ buffered?: boolean;
350
+
351
+ /** Specifies how many rows should be visible on the screen */
352
+ bufferSize?: number;
353
+
354
+ /** Specifies how many rows needs to be scrolled in order to recalculate buffer */
355
+ bufferStep?: number;
356
+
357
+ /** Used when rows have variable heights to improve buffered rendering by measuring and caching rendered row heights. Default value is false. */
358
+ measureRowHeights?: boolean;
359
+
360
+ /** Scrolls selection into the view. Default value is false. */
361
+ scrollSelectionIntoView?: boolean;
362
+
363
+ /**
364
+ * Set to true to lock column widths after the first render.
365
+ * This is helpful in pagination scenarios to maintain consistent looks across pages.
366
+ */
367
+ lockColumnWidths?: boolean;
368
+
369
+ lockColumnWidthsRequiredRowCount?: number;
370
+ focused?: boolean;
371
+ showBorder?: boolean;
372
+
373
+ /** Data adapter used to convert data in list of records. Used to enable grouping and tree operations. */
374
+ dataAdapter?:
375
+ | Create<typeof DataAdapter>
376
+ | Create<typeof ArrayAdapter>
377
+ | Create<typeof TreeAdapter>
378
+ | Create<typeof GroupAdapter>;
379
+
380
+ /** Additional CSS class to be added to each grid row. */
381
+ rowClass?: ClassProp;
382
+
383
+ /** Additional CSS styles to be added to each grid row. */
384
+ rowStyle?: StyleProp;
385
+
386
+ // drag-drop handlers
387
+ onDrop?: string | ((e: GridDragEvent<T>, instance: Instance) => void);
388
+ onDropTest?: string | ((e: DragEvent, instance: Instance) => boolean);
389
+ onDragStart?: string | ((e: DragEvent, instance: Instance) => void);
390
+ onDragEnd?: string | ((e: DragEvent, instance: Instance) => void);
391
+ onDragOver?: string | ((e: GridDragEvent<T>, instance: Instance) => void | boolean);
392
+
393
+ onRowDropTest?: string | ((e: DragEvent, instance: Instance) => boolean);
394
+ onRowDragOver?: string | ((e: GridRowDragEvent<T>, instance: Instance) => void | boolean);
395
+ onRowDrop?: string | ((e: GridRowDragEvent<T>, instance: Instance) => void | boolean);
396
+
397
+ onColumnDrop?: string | ((e: GridColumnDropEvent, instance: Instance) => void);
398
+ onColumnDropTest?: string | ((e: DragEvent, instance: Instance) => boolean);
399
+
400
+ /** Parameters that affect filtering. */
401
+ filterParams?: StructuredProp;
402
+
403
+ /** Callback function to be executed when a row is right-clicked. */
404
+ onRowContextMenu?: string | ((e: React.SyntheticEvent<any>, instance: Instance) => void);
405
+
406
+ /** Callback to create a filter function for given filter params. */
407
+ onCreateFilter?: (filterParams: any, instance?: Instance) => (record: T) => boolean;
408
+
409
+ /** Enable infinite scrolling */
410
+ infinite?: boolean;
411
+
412
+ /** If set, clicking on the column header will loop between ASC, DESC and no sorting order, instead of ASC and DESC only. */
413
+ clearableSort?: boolean;
414
+
415
+ /** A callback to fetch records during infinite loading */
416
+ onFetchRecords?: (
417
+ pageInfo: {
418
+ page: number;
419
+ pageSize: number;
420
+ sorters?: DataRecord[];
421
+ sortField?: string;
422
+ sortDirection?: string;
423
+ },
424
+ instance?: Instance,
425
+ ) => FetchRecordsResult<T> | Promise<FetchRecordsResult<T>>;
426
+
427
+ /** Callback function to be executed when a row is double-clicked. */
428
+ onRowDoubleClick?: string | ((e: React.SyntheticEvent<any>, instance: Instance) => void);
429
+
430
+ /** Callback function to be executed on key down. Accepts instance of the currently focused record as the second argument. */
431
+ onRowKeyDown?: string | ((e: React.SyntheticEvent<any>, instance: Instance) => void);
432
+
433
+ /** Callback function to be executed when a row is clicked. */
434
+ onRowClick?: string | ((e: React.SyntheticEvent<any>, instance: Instance) => void);
435
+
436
+ /** Set to true to add a fixed footer at the bottom of the grid. */
437
+ fixedFooter?: boolean;
438
+
439
+ /** Set to true to enable cell editing. Please note that all editable columns should specify the editor field. */
440
+ cellEditable?: boolean;
441
+
442
+ /** A callback function which is executed before a cell editor is initialized. Return false from the callback to prevent the cell from going into the edit mode. */
443
+ onBeforeCellEdit?: string | ((change: GridCellBeforeEditInfo, record: DataAdapterRecord<T>) => any);
444
+
445
+ /** A callback function which is executed after a cell has been successfully edited. */
446
+ onCellEdited?: string | ((change: GridCellEditInfo<T>, record: DataAdapterRecord<T>) => void);
447
+
448
+ /** A callback function which is executed after a column has been resized. */
449
+ onColumnResize?: (data: { width: number; column: Config }, instance: Instance) => void;
450
+
451
+ /** Options for data sorting. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Collator */
452
+ sortOptions?: CollatorOptions;
453
+
454
+ /** Callback to create a function that can be used to check whether a record is selectable. */
455
+ onCreateIsRecordSelectable?: (
456
+ params: any,
457
+ instance: Instance,
458
+ ) => (record: T, options?: { range?: boolean; toggle?: boolean }) => boolean;
459
+
460
+ /** Parameters whose change will cause scroll to be reset. */
461
+ scrollResetParams?: StructuredProp;
462
+
463
+ /** Enable precise (sub-pixel) measurements. Useful for grids with many columns. Better behavior at small zoom factors. */
464
+ preciseMeasurements?: boolean;
465
+
466
+ /** A value used to identify the group of components participating in hover effect synchronization. */
467
+ hoverChannel?: string;
468
+
469
+ /** A value used to uniquely identify the record within the hover sync group. */
470
+ rowHoverId?: Prop<string | number>;
471
+
472
+ /** Set to true or false to explicitly define if grid is allowed to receive focus. */
473
+ focusable?: boolean;
474
+
475
+ /** Callback function to retrieve grouping data. */
476
+ onGetGrouping?: (params: any, instance: Instance) => GridGroupingConfig<T>[];
477
+
478
+ /** Callback function to dynamically calculate columns. */
479
+ onGetColumns?: (params: any, instance: Instance) => GridColumnConfig[] | GridRowConfig;
480
+
481
+ /** Allow grid to receive drag and drop operations containing files. */
482
+ allowsFileDrops?: boolean;
483
+
484
+ /**
485
+ * Callback function to track and retrieve displayed records.
486
+ * Accepts new records as a first argument.
487
+ * If onCreateFilter callback is defined, filtered records can be retrieved using this callback.
488
+ */
489
+ onTrackMappedRecords?: string | ((records: DataAdapterRecord<T>[], instance: Instance) => void);
490
+
491
+ /** Callback to create a function that can be used to check whether a record is draggable. */
492
+ onCreateIsRecordDraggable?: (params: any, instance: Instance) => (record: T) => boolean;
493
+
494
+ /** Callback function to get grid component and instance references on component init. */
495
+ onRef?: string | ((element: any, instance: Instance) => void);
496
+
497
+ /** When enabled, groups are shown in the same order as the source records. */
498
+ preserveGroupOrder?: boolean;
499
+ }
500
+
501
+ export interface GridCellInfo {
502
+ column: any;
503
+ field: string;
504
+ }
505
+
506
+ export interface GridCellBeforeEditInfo extends GridCellInfo {
507
+ data: any;
508
+ }
509
+
510
+ export interface GridCellEditInfo<T> extends GridCellInfo {
511
+ oldData: T;
512
+ newData: T;
513
+ }
514
+
515
+ export interface GridInstance<T = any> extends Instance<Grid<T>> {
516
+ widget: Grid<T>;
517
+ isRecordSelectable?: (record: any, options?: any) => boolean;
518
+ visibleColumns: any[];
519
+ isRecordDraggable?: (record: any) => boolean;
520
+ row?: any;
521
+ fixedFooterVDOM?: any;
522
+ fixedColumnsFixedFooterVDOM?: any;
523
+ hasFixedColumns?: boolean;
524
+ recordInstanceCache?: any;
525
+ records?: MappedGridRecord<T>[];
526
+ isSelected: (record: any, index?: number) => boolean;
527
+ v: number;
528
+ buffer?: any;
529
+ dataAdapter: ArrayAdapter<T>;
530
+ fixedFooterIsGroupFooter?: boolean;
531
+ state?: any;
532
+ fixedColumnCount: number;
533
+ fixedHeaderResizeEvent?: any;
534
+ hoverSync?: any;
535
+ header?: any;
536
+ cached: any;
537
+ fixedFooterOverlap?: boolean;
538
+ }
539
+
540
+ export class Grid<T = unknown> extends ContainerBase<GridConfig<T>, GridInstance<T>> {
541
+ constructor(config?: GridConfig<T>) {
542
+ super(config);
543
+ }
544
+
545
+ declare records?: any;
546
+ declare scrollable?: boolean;
547
+ declare sorters?: any;
548
+ declare preSorters?: any;
549
+ declare sortField?: any;
550
+ declare sortDirection?: any;
551
+ declare defaultSortField?: string;
552
+ declare defaultSortDirection?: "ASC" | "DESC";
553
+ declare vlines?: boolean;
554
+ declare emptyText?: any;
555
+ declare dragSource?: any;
556
+ declare dropZone?: any;
557
+ declare row?: any;
558
+ declare columns?: any[];
559
+ declare columnParams?: any;
560
+ declare selection: any;
561
+ declare grouping?: string | GridGroupingConfig<any> | (string | GridGroupingConfig<any>)[];
562
+ declare groupingParams?: any;
563
+ declare headerMode?: any;
564
+ declare border?: any;
565
+ declare baseClass: string;
566
+ declare keyField?: string;
567
+ declare showHeader: boolean;
568
+ declare showFooter: boolean;
569
+ declare recordName: string;
570
+ declare recordAlias?: string;
571
+ declare indexName: string;
572
+ declare indexAlias?: string;
573
+ declare remoteSort: boolean;
574
+ declare cached: boolean;
575
+ declare buffered: boolean;
576
+ declare bufferSize: number;
577
+ declare bufferStep: number;
578
+ declare pageSize: number;
579
+ declare measureRowHeights?: boolean;
580
+ declare scrollSelectionIntoView: boolean;
581
+ declare lockColumnWidths: boolean;
582
+ declare lockColumnWidthsRequiredRowCount: number;
583
+ declare focused: boolean;
584
+ declare showBorder: boolean;
585
+ declare dataAdapter?: DataAdapter;
586
+ declare rowClass?: any;
587
+ declare rowStyle?: any;
588
+ declare onDrop?: any;
589
+ declare onDropTest?: any;
590
+ declare onDragStart?: any;
591
+ declare onDragEnd?: any;
592
+ declare onDragOver?: any;
593
+ declare onRowDropTest?: any;
594
+ declare onRowDragOver?: any;
595
+ declare onRowDrop?: any;
596
+ declare onColumnDrop?: any;
597
+ declare onColumnDropTest?: any;
598
+ declare filterParams?: any;
599
+ declare onRowContextMenu?: any;
600
+ declare onColumnContextMenu?: any;
601
+ declare onCreateFilter?: any;
602
+ declare infinite: boolean;
603
+ declare clearableSort: boolean;
604
+ declare onFetchRecords?: any;
605
+ declare onRowDoubleClick?: any;
606
+ declare onRowKeyDown?: any;
607
+ declare onKeyDown?: any;
608
+ declare onCellKeyDown?: any;
609
+ declare onRowClick?: any;
610
+ declare fixedFooter?: boolean;
611
+ declare cellEditable: boolean;
612
+ declare onBeforeCellEdit?: any;
613
+ declare onCellEdited?: any;
614
+ declare onColumnResize?: any;
615
+ declare sortOptions?: any;
616
+ declare onCreateIsRecordSelectable?: any;
617
+ declare scrollResetParams?: any;
618
+ declare preciseMeasurements: boolean;
619
+ declare hoverChannel: string;
620
+ declare rowHoverId?: any;
621
+ declare focusable: boolean | null;
622
+ declare onGetGrouping?: any;
623
+ declare onGetColumns?: any;
624
+ declare allowsFileDrops: boolean;
625
+ declare onTrackMappedRecords?: any;
626
+ declare onCreateIsRecordDraggable?: any;
627
+ declare onRef?: any;
628
+ declare preserveGroupOrder: boolean;
629
+ declare styled: boolean;
630
+ declare selectable?: boolean;
631
+ declare recordsAccessor: any;
632
+ declare hasResizableColumns?: boolean;
633
+ declare pipeKeyDown?: any;
634
+ declare onLoadingError?: any;
635
+
636
+ declareData(...args: any[]) {
637
+ let selection = this.selection.configureWidget(this);
638
+
639
+ super.declareData(
640
+ ...args,
641
+ {
642
+ records: undefined,
643
+ sorters: undefined,
644
+ preSorters: undefined,
645
+ scrollable: undefined,
646
+ sortField: undefined,
647
+ sortDirection: undefined,
648
+ emptyText: undefined,
649
+ dragSource: { structured: true },
650
+ dropZone: { structured: true },
651
+ filterParams: { structured: true },
652
+ groupingParams: { structured: true },
653
+ scrollResetParams: { structured: true },
654
+ page: undefined,
655
+ totalRecordCount: undefined,
656
+ tabIndex: undefined,
657
+ columnParams: { structured: true },
658
+ },
659
+ selection,
660
+ );
661
+ }
662
+
663
+ init() {
664
+ if (this.recordAlias) this.recordName = this.recordAlias;
665
+
666
+ if (this.indexAlias) this.indexName = this.indexAlias;
667
+
668
+ if (this.infinite) {
669
+ this.buffered = true;
670
+ this.remoteSort = true;
671
+ }
672
+
673
+ if (this.buffered) this.scrollable = true;
674
+
675
+ this.recordsAccessor = getAccessor(this.records);
676
+
677
+ this.selection = Selection.create(this.selection, {
678
+ records: this.records,
679
+ });
680
+
681
+ if (!this.selection.isDummy || this.onRowClick || this.onRowDoubleClick) this.selectable = true;
682
+ if (this.focusable == null) this.focusable = !this.selection.isDummy || this.cellEditable;
683
+
684
+ super.init();
685
+ }
686
+
687
+ initState(context: RenderingContext, instance: GridInstance) {
688
+ instance.state = {
689
+ colWidth: {},
690
+ lockedColWidth: {},
691
+ dimensionsVersion: 0,
692
+ disableDefaultSort: false,
693
+ };
694
+ instance.v = 0;
695
+ if (this.infinite)
696
+ instance.buffer = {
697
+ records: [],
698
+ totalRecordCount: 0,
699
+ page: 1,
700
+ };
701
+ }
702
+
703
+ applyParentStore(instance: GridInstance) {
704
+ super.applyParentStore(instance);
705
+
706
+ // force prepareData to execute again and propagate the store change to the records
707
+ if (instance.cached) delete instance.cached.rawData;
708
+ }
709
+
710
+ createRowTemplate(context: RenderingContext, columnParams: any, instance: GridInstance, groupingData: any) {
711
+ var row = this.row || {};
712
+ let columns = this.columns;
713
+ if (this.onGetColumns) {
714
+ let result = instance.invoke("onGetColumns", columnParams, instance);
715
+ if (isArray(result)) columns = result;
716
+ else row = result;
717
+ }
718
+
719
+ if (columns)
720
+ row.line1 = {
721
+ columns,
722
+ };
723
+
724
+ row.hasSortableColumns = false;
725
+ row.hasResizableColumns = false;
726
+ row.hasMergedCells = false;
727
+ row.mergedColumns = [];
728
+
729
+ let aggregates: Record<string, { value: any; weight: any; type: any }> = {};
730
+ let showFooter = false;
731
+ let lines = [];
732
+ for (let i = 0; i < 10; i++) {
733
+ let l = row["line" + i];
734
+ if (l) {
735
+ if (isArray(l.columns))
736
+ for (let c = 0; c < l.columns.length; c++)
737
+ l.columns[c].uniqueColumnId = `l${i}-${l.columns[c].key || c}`;
738
+ lines.push(l);
739
+ }
740
+ }
741
+
742
+ row.header = PureContainer.create({
743
+ items: GridColumnHeaderLine.create(lines),
744
+ });
745
+
746
+ row.header.items.forEach((line: any) => {
747
+ line.items.forEach((c: any, index: number) => {
748
+ if (c.sortable) row.hasSortableColumns = true;
749
+
750
+ if (c.mergeCells) {
751
+ if (row.header.items.length > 1)
752
+ Console.warn("Merged columns are only supported in grids in which rows have only one line of cells.");
753
+ else {
754
+ row.hasMergedCells = true;
755
+ row.mergedColumns.push({ uniqueColumnId: c.uniqueColumnId, index, mode: c.mergeCells });
756
+ }
757
+ }
758
+
759
+ if (
760
+ c.resizable ||
761
+ (c.header && c.header.resizable) ||
762
+ (c.header1 && c.header1.resizable) ||
763
+ (c.header2 && c.header2.resizable) ||
764
+ (c.header3 && c.header3.resizable)
765
+ )
766
+ row.hasResizableColumns = true;
767
+
768
+ if (c.aggregate && c.aggregateAlias && (c.aggregateField || isDefined(c.aggregateValue))) {
769
+ aggregates[c.aggregateAlias] = {
770
+ value: isDefined(c.aggregateValue)
771
+ ? c.aggregateValue
772
+ : isDefined(c.value)
773
+ ? c.value
774
+ : c.aggregateField
775
+ ? { bind: this.recordName + "." + c.aggregateField }
776
+ : null,
777
+ weight:
778
+ c.weight != null
779
+ ? c.weight
780
+ : c.weightField && {
781
+ bind: this.recordName + "." + c.weightField,
782
+ },
783
+ type: c.aggregate,
784
+ };
785
+ } else if (c.footer && !showFooter) {
786
+ showFooter = true;
787
+ }
788
+ });
789
+ });
790
+
791
+ //add default footer if some columns have aggregates and grouping is not defined
792
+ if (!groupingData && (Object.keys(aggregates).length > 0 || this.fixedFooter || showFooter))
793
+ groupingData = [
794
+ {
795
+ key: {},
796
+ showFooter: true,
797
+ },
798
+ ];
799
+
800
+ let { grouping, showHeader } = this.resolveGrouping(groupingData);
801
+
802
+ this.showHeader = showHeader;
803
+
804
+ if (this.fixedFooter && isNonEmptyArray(grouping)) {
805
+ grouping[0].showFooter = true;
806
+ if (grouping[0].key && Object.keys(grouping[0].key).length > 0)
807
+ Console.warn(
808
+ "First grouping level in grids with a fixed footer must group all data. The key field should be omitted.",
809
+ );
810
+ }
811
+
812
+ instance.dataAdapter =
813
+ this.dataAdapter instanceof ArrayAdapter
814
+ ? this.dataAdapter
815
+ : GroupAdapter.create(
816
+ {
817
+ recordsAccessor: this.recordsAccessor,
818
+ keyField: this.keyField,
819
+ aggregates: aggregates,
820
+ recordName: this.recordName,
821
+ indexName: this.indexName,
822
+ sortOptions: this.sortOptions,
823
+ groupings: grouping,
824
+ preserveOrder: this.preserveGroupOrder,
825
+ },
826
+ this.dataAdapter,
827
+ );
828
+
829
+ instance.dataAdapter.initInstance(context, instance);
830
+
831
+ return Widget.create(GridRow, {
832
+ class: this.CSS.element(this.baseClass, "data"),
833
+ className: this.rowClass,
834
+ style: this.rowStyle,
835
+ recordName: this.recordName,
836
+ hoverId: this.rowHoverId,
837
+ ...row,
838
+ });
839
+ }
840
+
841
+ prepareData(context: RenderingContext, instance: GridInstance) {
842
+ let { data, state, cached, row } = instance;
843
+
844
+ let grouping = this.grouping;
845
+
846
+ if (this.onGetGrouping) {
847
+ if (!cached.data || cached.data.groupingParams !== data.groupingParams)
848
+ grouping = instance.invoke("onGetGrouping", data.groupingParams, instance);
849
+ else grouping = cached.grouping;
850
+ }
851
+
852
+ let groupingChanged = instance.cache("grouping", grouping);
853
+
854
+ if (instance.cache("columnParams", data.columnParams) || groupingChanged || !row) {
855
+ row = instance.row = this.createRowTemplate(context, data.columnParams, instance, grouping);
856
+ }
857
+
858
+ data.version = instance.v++;
859
+
860
+ if (!this.infinite) data.totalRecordCount = isArray(data.records) ? data.records.length : 0;
861
+ else {
862
+ if (isNumber(data.totalRecordCount)) instance.buffer.totalRecordCount = data.totalRecordCount;
863
+ else data.totalRecordCount = instance.buffer.totalRecordCount;
864
+
865
+ if (isDefined(data.records)) instance.buffer.records = data.records;
866
+ else data.records = instance.buffer.records;
867
+
868
+ if (isNumber(data.page)) instance.buffer.page = data.page;
869
+ else data.page = instance.buffer.page;
870
+
871
+ data.offset = (data.page - 1) * this.pageSize;
872
+ }
873
+
874
+ if (!isArray(data.records)) data.records = [];
875
+
876
+ if (state.sorters && !isDefined(this.sorters)) data.sorters = state.sorters;
877
+
878
+ let sortField = null;
879
+
880
+ if (isDefined(this.sortField) && isDefined(this.sortDirection)) {
881
+ let sorter = {
882
+ field: data.sortField,
883
+ direction: data.sortDirection,
884
+ };
885
+ sortField = data.sortField;
886
+ data.sorters = [sorter];
887
+ }
888
+
889
+ let skipDefaultSorting = this.clearableSort && instance.state.disableDefaultSort;
890
+ if (!skipDefaultSorting && !isNonEmptyArray(data.sorters) && this.defaultSortField) {
891
+ let sorter = {
892
+ field: this.defaultSortField,
893
+ direction: this.defaultSortDirection || "ASC",
894
+ };
895
+ sortField = this.defaultSortField;
896
+ data.sorters = [sorter];
897
+ }
898
+
899
+ if (sortField) {
900
+ for (let l = 1; l < 10; l++) {
901
+ let line = instance.row[`line${l}`];
902
+ let sortColumn = line && line.columns && line.columns.find((c: any) => c.field == sortField);
903
+ if (sortColumn) {
904
+ data.sorters[0].value = sortColumn.sortValue || sortColumn.value;
905
+ data.sorters[0].comparer = sortColumn.comparer;
906
+ data.sorters[0].sortOptions = sortColumn.sortOptions;
907
+ break;
908
+ }
909
+ }
910
+ }
911
+
912
+ let headerMode = this.headerMode;
913
+
914
+ if (this.headerMode == null) {
915
+ if (this.scrollable || row.hasSortableColumns || row.hasResizableColumns) headerMode = "default";
916
+ else headerMode = "plain";
917
+ }
918
+
919
+ let border = this.border;
920
+
921
+ if (this.showBorder || (border == null && this.scrollable)) border = true;
922
+
923
+ let dragMode = false;
924
+ if (data.dragSource) dragMode = data.dragSource.mode || "move";
925
+
926
+ let dropMode = data.dropZone && data.dropZone.mode;
927
+
928
+ if (this.onDrop && !dropMode) dropMode = "preview";
929
+
930
+ data.dropMode = dropMode;
931
+
932
+ data.stateMods = {
933
+ selectable: this.selectable,
934
+ "cell-editable": this.cellEditable,
935
+ scrollable: data.scrollable,
936
+ buffered: this.buffered,
937
+ ["header-" + headerMode]: true,
938
+ border: border,
939
+ vlines: this.vlines,
940
+ ["drag-" + dragMode]: dragMode,
941
+ ["drop-" + dropMode]: dropMode,
942
+ resizable: row.hasResizableColumns,
943
+ };
944
+
945
+ super.prepareData(context, instance);
946
+
947
+ instance.records = this.mapRecords(context, instance);
948
+
949
+ //tree adapters can have additional (child) records, filtering also affects actual record count
950
+ if (instance.records && !this.infinite) {
951
+ //apply record count after filtering
952
+ data.totalRecordCount = instance.records.length;
953
+
954
+ //recheck if there are any actual records
955
+ //when grouping is enabled group header/footer are always in
956
+ if (instance.records.length < 5) {
957
+ data.empty = true;
958
+ for (let i = 0; i < instance.records.length; i++)
959
+ if (instance.records[i].type == "data") {
960
+ data.empty = false;
961
+ break;
962
+ }
963
+ } else data.empty = data.totalRecordCount == 0;
964
+ } else data.empty = data.totalRecordCount == 0;
965
+
966
+ if (this.onCreateIsRecordSelectable) {
967
+ instance.isRecordSelectable = instance.invoke("onCreateIsRecordSelectable", null, instance);
968
+ }
969
+
970
+ if (this.onCreateIsRecordDraggable) {
971
+ instance.isRecordDraggable = instance.invoke("onCreateIsRecordDraggable", null, instance);
972
+ }
973
+
974
+ if (this.onTrackMappedRecords) {
975
+ instance.invoke("onTrackMappedRecords", instance.records, instance);
976
+ }
977
+ }
978
+
979
+ initInstance(context: RenderingContext, instance: GridInstance) {
980
+ instance.fixedHeaderResizeEvent = new SubscriberList();
981
+ super.initInstance(context, instance);
982
+ }
983
+
984
+ explore(context: RenderingContext, instance: GridInstance) {
985
+ context.push("parentPositionChangeEvent", instance.fixedHeaderResizeEvent);
986
+
987
+ instance.hoverSync = context.hoverSync;
988
+
989
+ super.explore(context, instance);
990
+
991
+ instance.header = instance.getChild(context, instance.row.header, "header");
992
+ instance.header.scheduleExploreIfVisible(context);
993
+
994
+ let { store } = instance;
995
+ instance.isSelected = this.selection.getIsSelectedDelegate(store);
996
+
997
+ //do not process rows in buffered mode or cached mode if nothing has changed;
998
+ if (!this.buffered && (!this.cached || instance.shouldUpdate)) {
999
+ for (let i = 0; i < instance.records!.length; i++) {
1000
+ let record = instance.records![i];
1001
+ if (record.type == "data") {
1002
+ let row = (record.row = instance.getChild(
1003
+ context,
1004
+ instance.row,
1005
+ record.key,
1006
+ record.store,
1007
+ ) as GridRowInstance);
1008
+ row.selected = instance.isSelected(record.data, record.index);
1009
+ let changed = false;
1010
+ if (row.cache("selected", row.selected)) changed = true;
1011
+ if (row.cache("recordData", record.data)) changed = true;
1012
+ if (this.cached && !changed && !row.childStateDirty) row.shouldUpdate = false;
1013
+ else row.scheduleExploreIfVisible(context);
1014
+ }
1015
+ }
1016
+ }
1017
+ }
1018
+
1019
+ exploreCleanup(context: RenderingContext, instance: GridInstance) {
1020
+ context.pop("parentPositionChangeEvent");
1021
+ let fixedColumnCount = 0,
1022
+ visibleColumns: any[] = [];
1023
+ instance.header.children.forEach((line: any) => {
1024
+ line.children.forEach((col: any) => {
1025
+ if (col.data.fixed) fixedColumnCount++;
1026
+ visibleColumns.push(col.widget);
1027
+ });
1028
+ });
1029
+ instance.visibleColumns = visibleColumns;
1030
+ instance.hasFixedColumns = fixedColumnCount > 0;
1031
+ instance.fixedColumnCount = fixedColumnCount;
1032
+ if (fixedColumnCount > 0) {
1033
+ instance.data.classNames += ` ${instance.widget.CSS.state("fixed-columns")}`;
1034
+ }
1035
+ }
1036
+
1037
+ resolveGrouping(grouping: any) {
1038
+ if (grouping) {
1039
+ if (!isArray(grouping)) {
1040
+ if (isString(grouping) || isObject(grouping)) grouping = [grouping];
1041
+ else throw new Error("Dynamic grouping should be an array of grouping objects.");
1042
+ }
1043
+
1044
+ grouping = grouping.map((g: any, i: any) => {
1045
+ let group;
1046
+ if (isString(g))
1047
+ group = {
1048
+ key: {
1049
+ [g]: {
1050
+ bind: this.recordName + "." + g,
1051
+ },
1052
+ },
1053
+ showHeader: !this.scrollable && i == grouping.length - 1,
1054
+ showFooter: true,
1055
+ caption: { bind: `$group.${g}` },
1056
+ text: { bind: `${this.recordName}.${g}` },
1057
+ };
1058
+ else
1059
+ group = {
1060
+ ...g,
1061
+ };
1062
+ if (group.caption) group.caption = getSelector(group.caption);
1063
+ return group;
1064
+ });
1065
+ }
1066
+
1067
+ let showHeader = !isArray(grouping) || !grouping.some((g: any) => g.showHeader);
1068
+
1069
+ return { showHeader, grouping };
1070
+ }
1071
+
1072
+ groupBy(groupingData: any, options?: any) {
1073
+ let { grouping, showHeader } = this.resolveGrouping(groupingData);
1074
+ this.grouping = grouping;
1075
+ if (options?.autoConfigure) this.showHeader = showHeader;
1076
+ this.update();
1077
+ }
1078
+
1079
+ render(context: RenderingContext, instance: GridInstance, key: string) {
1080
+ let { data, hasFixedColumns } = instance;
1081
+
1082
+ let fixedHeader =
1083
+ data.scrollable && this.showHeader && this.renderHeader(context, instance, "header", true, false);
1084
+
1085
+ let fixedColumnsFixedHeader =
1086
+ data.scrollable &&
1087
+ this.showHeader &&
1088
+ hasFixedColumns &&
1089
+ this.renderHeader(context, instance, "header", true, true);
1090
+
1091
+ if (!this.buffered) this.renderRows(context, instance);
1092
+
1093
+ if (this.fixedFooter) this.renderFixedFooter(context, instance);
1094
+
1095
+ let header = this.showHeader && this.renderHeader(context, instance, "header", false, false);
1096
+
1097
+ let fixedColumnsHeader =
1098
+ this.showHeader && hasFixedColumns && this.renderHeader(context, instance, "header", false, true);
1099
+
1100
+ return (
1101
+ <GridComponent
1102
+ key={key}
1103
+ instance={instance}
1104
+ data={instance.data}
1105
+ shouldUpdate={instance.shouldUpdate}
1106
+ header={header}
1107
+ fixedColumnsHeader={fixedColumnsHeader}
1108
+ fixedColumnsFixedHeader={fixedColumnsFixedHeader}
1109
+ fixedHeader={fixedHeader}
1110
+ fixedFooter={instance.fixedFooterVDOM}
1111
+ fixedColumnsFixedFooter={instance.fixedColumnsFixedFooterVDOM}
1112
+ >
1113
+ {this.renderChildren(context, instance)}
1114
+ </GridComponent>
1115
+ );
1116
+ }
1117
+
1118
+ renderResizer(instance: GridInstance, hdinst: any, header: any, colIndex: number, forPreviousColumn?: any) {
1119
+ let { widget } = instance;
1120
+
1121
+ let { CSS, baseClass } = widget;
1122
+
1123
+ let hdwidget = hdinst.widget;
1124
+
1125
+ let resizerClassName = "col-resizer";
1126
+ if (forPreviousColumn) resizerClassName += "-prev-col";
1127
+
1128
+ return (
1129
+ <div
1130
+ className={CSS.element(baseClass, resizerClassName)}
1131
+ onClick={(e) => {
1132
+ e.stopPropagation();
1133
+ }}
1134
+ data-unique-col-id={hdwidget.uniqueColumnId}
1135
+ onMouseDown={(e) => {
1136
+ if (e.buttons != 1) return;
1137
+ let resizeOverlayEl: HTMLDivElement | null = document.createElement("div");
1138
+
1139
+ let gridEl = (e.target as HTMLElement).parentElement!.parentElement!.parentElement!.parentElement!
1140
+ .parentElement!.parentElement!;
1141
+ let uniqueColId = (e.currentTarget as HTMLElement).dataset.uniqueColId;
1142
+
1143
+ // if we use fixed columns, rhs resizer of the last fixed column is within regular columns header tbody
1144
+ let headerCell = findFirstChild(
1145
+ gridEl,
1146
+ (el) =>
1147
+ el.tagName == "TH" &&
1148
+ (el as HTMLElement).dataset &&
1149
+ (el as HTMLElement).dataset.uniqueColId == uniqueColId,
1150
+ );
1151
+
1152
+ let initialWidth = (headerCell as HTMLElement).offsetWidth;
1153
+ let initialPosition = getCursorPos(e);
1154
+ resizeOverlayEl.className = CSS.element(baseClass, "resize-overlay");
1155
+ resizeOverlayEl.style.width = `${initialWidth}px`;
1156
+ resizeOverlayEl.style.left = `${
1157
+ (headerCell as HTMLElement).getBoundingClientRect().left - gridEl.getBoundingClientRect().left
1158
+ }px`;
1159
+ gridEl.appendChild(resizeOverlayEl);
1160
+ captureMouse2(e, {
1161
+ onMouseMove: (e) => {
1162
+ let cursor = getCursorPos(e);
1163
+ let width = Math.max(30, Math.round(initialWidth + cursor.clientX - initialPosition.clientX));
1164
+ resizeOverlayEl!.style.width = `${width}px`;
1165
+ },
1166
+ onMouseUp: (e) => {
1167
+ if (!resizeOverlayEl) return; //dblclick
1168
+ let width = resizeOverlayEl.offsetWidth;
1169
+ hdinst.assignedWidth = width;
1170
+ gridEl.removeChild(resizeOverlayEl);
1171
+ resizeOverlayEl = null;
1172
+ if (widget.onColumnResize) instance.invoke("onColumnResize", { width, column: hdwidget }, hdinst);
1173
+ header.set("width", width);
1174
+ instance.setState({
1175
+ dimensionsVersion: instance.state.dimensionsVersion + 1,
1176
+ colWidth: {
1177
+ ...instance.state.colWidth,
1178
+ [hdwidget.uniqueColumnId]: width,
1179
+ },
1180
+ });
1181
+ },
1182
+ onDblClick: () => {
1183
+ let table = gridEl.querySelector("table")!;
1184
+ let parentEl = table.parentElement!;
1185
+ let tableClone: HTMLTableElement = table.cloneNode(true) as HTMLTableElement;
1186
+ tableClone.childNodes.forEach((tbody: any) => {
1187
+ tbody.childNodes.forEach((tr: any) => {
1188
+ tr.childNodes.forEach((td: any, index: number) => {
1189
+ if (index == colIndex) {
1190
+ td.style.maxWidth = null;
1191
+ td.style.minWidth = null;
1192
+ td.style.width = "auto";
1193
+ } else {
1194
+ td.style.display = "none";
1195
+ }
1196
+ });
1197
+ });
1198
+ });
1199
+ tableClone.style.position = "absolute";
1200
+ tableClone.style.visibility = "hidden";
1201
+ tableClone.style.top = "0";
1202
+ tableClone.style.left = "0";
1203
+ tableClone.style.width = "auto";
1204
+ parentEl.appendChild(tableClone);
1205
+ let width = tableClone.offsetWidth;
1206
+ parentEl.removeChild(tableClone);
1207
+ header.set("width", width);
1208
+ instance.setState({
1209
+ dimensionsVersion: instance.state.dimensionsVersion + 1,
1210
+ colWidth: {
1211
+ ...instance.state.colWidth,
1212
+ [hdwidget.uniqueColumnId]: width,
1213
+ },
1214
+ });
1215
+ },
1216
+ });
1217
+ }}
1218
+ />
1219
+ );
1220
+ }
1221
+
1222
+ renderHeader(context: RenderingContext, instance: GridInstance, key: any, fixed: any, fixedColumns: any) {
1223
+ let { data, widget, header } = instance;
1224
+
1225
+ let { CSS, baseClass } = widget;
1226
+
1227
+ let headerRows: any[] = [];
1228
+
1229
+ if (!header) return null;
1230
+
1231
+ let skip: any = {};
1232
+ let lineIndex = 0;
1233
+
1234
+ header.children.forEach((line: any) => {
1235
+ let empty = [true, true, true];
1236
+ let result: any[] = [[], [], []];
1237
+
1238
+ line.children.forEach((hdinst: any, colIndex: number) => {
1239
+ let hdwidget = hdinst.widget;
1240
+ for (let l = 0; l < 3; l++) {
1241
+ let colKey = `${lineIndex + l}-${colIndex}`;
1242
+
1243
+ if (skip[colKey]) continue;
1244
+
1245
+ if (Boolean(hdinst.data.fixed) != fixedColumns) continue;
1246
+
1247
+ let header = hdinst.components[`header${l + 1}`];
1248
+ let colSpan,
1249
+ rowSpan,
1250
+ style,
1251
+ cls,
1252
+ mods = [],
1253
+ content,
1254
+ sortIcon,
1255
+ tool;
1256
+
1257
+ let resizer = null,
1258
+ prevColumnResizer = null;
1259
+
1260
+ if (header) {
1261
+ empty[l] = false;
1262
+
1263
+ if (header.widget.align) mods.push("aligned-" + header.widget.align);
1264
+ else if (hdwidget.align) mods.push("aligned-" + hdwidget.align);
1265
+
1266
+ if (hdwidget.sortable && header.widget.allowSorting) {
1267
+ mods.push("sortable");
1268
+ if (data.sorters && data.sorters[0].field == (hdwidget.sortField || hdwidget.field)) {
1269
+ mods.push("sorted-" + data.sorters[0].direction.toLowerCase());
1270
+ sortIcon = <DropDownIcon className={CSS.element(baseClass, "column-sort-icon")} />;
1271
+ }
1272
+ }
1273
+
1274
+ let uniqueColumnId = header.data.colSpan > 1 ? null : hdwidget.uniqueColumnId;
1275
+
1276
+ style = header.data.style;
1277
+ let customWidth =
1278
+ header.data.width ||
1279
+ instance.state.colWidth[uniqueColumnId] ||
1280
+ header.data.defaultWidth ||
1281
+ instance.state.lockedColWidth[uniqueColumnId];
1282
+ if (customWidth) {
1283
+ if (instance.state.colWidth[uniqueColumnId] != customWidth)
1284
+ instance.state.colWidth[uniqueColumnId] = customWidth;
1285
+ let s = `${customWidth}px`;
1286
+ style = {
1287
+ ...style,
1288
+ width: s,
1289
+ minWidth: s,
1290
+ maxWidth: s,
1291
+ };
1292
+ }
1293
+
1294
+ if (header.data.classNames) cls = header.data.classNames;
1295
+
1296
+ content = header.render(context);
1297
+
1298
+ if (header.components && header.components.tool) {
1299
+ tool = (
1300
+ <div className={CSS.element(baseClass, "col-header-tool")}>
1301
+ {getContent(header.components.tool.render(context))}
1302
+ </div>
1303
+ );
1304
+ mods.push("tool");
1305
+ }
1306
+
1307
+ if (header.data.colSpan > 1 || header.data.rowSpan > 1) {
1308
+ colSpan = header.data.colSpan;
1309
+ rowSpan = header.data.rowSpan;
1310
+
1311
+ for (let r = 0; r < header.data.rowSpan; r++)
1312
+ for (let c = 0; c < header.data.colSpan; c++)
1313
+ skip[`${lineIndex + l + r}-${colIndex + c}`] = true;
1314
+ }
1315
+
1316
+ if ((hdwidget.resizable || header.data.resizable) && header.data.colSpan < 2) {
1317
+ resizer = this.renderResizer(instance, hdinst, header, colIndex);
1318
+ }
1319
+
1320
+ if (colIndex > 0) {
1321
+ let hdinstPrev = line.children[colIndex - 1];
1322
+ let prevLine = 3;
1323
+ let headerPrev;
1324
+ while (!headerPrev && prevLine >= 0) {
1325
+ headerPrev = hdinstPrev.components[`header${prevLine + 1}`];
1326
+ prevLine--;
1327
+ }
1328
+ if (
1329
+ (hdinstPrev.widget.resizable || headerPrev?.data?.resizable) &&
1330
+ headerPrev?.data?.colSpan < 2
1331
+ ) {
1332
+ prevColumnResizer = this.renderResizer(instance, hdinstPrev, headerPrev, colIndex - 1, true);
1333
+ }
1334
+ }
1335
+ }
1336
+
1337
+ cls = CSS.element(baseClass, "col-header", mods) + (cls ? " " + cls : "");
1338
+
1339
+ let onContextMenu;
1340
+
1341
+ if (this.onColumnContextMenu)
1342
+ onContextMenu = (e: any) => instance.invoke("onColumnContextMenu", e, hdinst);
1343
+
1344
+ result[l].push(
1345
+ <th
1346
+ key={colIndex}
1347
+ colSpan={colSpan}
1348
+ rowSpan={rowSpan}
1349
+ className={cls}
1350
+ style={style}
1351
+ onMouseDown={ddMouseDown}
1352
+ onMouseMove={(e) => this.onHeaderMouseMove(e, hdwidget, hdinst, instance, l)}
1353
+ onMouseLeave={(e) => this.onHeaderMouseLeave(e, hdinst, l)}
1354
+ onClick={(e) => this.onHeaderClick(e, hdwidget, instance, l)}
1355
+ onContextMenu={onContextMenu}
1356
+ data-unique-col-id={colSpan > 1 ? null : hdwidget.uniqueColumnId}
1357
+ >
1358
+ {getContent(content)}
1359
+ {sortIcon}
1360
+ {tool}
1361
+ {prevColumnResizer}
1362
+ {resizer}
1363
+ </th>,
1364
+ );
1365
+ }
1366
+ });
1367
+
1368
+ result = result.filter((_, i) => !empty[i]);
1369
+ lineIndex += result.length;
1370
+
1371
+ if (result[0]) {
1372
+ if (fixed && !fixedColumns) {
1373
+ result[0].push(
1374
+ <th key="dummy" rowSpan={result.length} className={CSS.element(baseClass, "col-header")} />,
1375
+ );
1376
+ }
1377
+
1378
+ headerRows.push(...result.map((h, i) => <tr key={`${lineIndex}-${i}`}>{h}</tr>));
1379
+ }
1380
+ });
1381
+
1382
+ if (headerRows.length == 0) return null;
1383
+
1384
+ return (
1385
+ <tbody key={"h" + key} className={CSS.element(baseClass, "header")}>
1386
+ {headerRows}
1387
+ </tbody>
1388
+ );
1389
+ }
1390
+
1391
+ onHeaderMouseMove(e: any, column: any, columnInstance: any, gridInstance: any, headerLine: any) {
1392
+ let { baseClass, CSS } = gridInstance.widget;
1393
+ if (columnInstance.data.fixed) return;
1394
+ let headerInstance = columnInstance.components[`header${headerLine + 1}`];
1395
+ if (!headerInstance) return;
1396
+ let { store, data } = headerInstance;
1397
+ if (headerInstance.widget?.tooltip) {
1398
+ tooltipMouseMove(e, headerInstance, headerInstance.widget.tooltip);
1399
+ }
1400
+ if (data.draggable && !data.fixed && ddDetect(e) && e.buttons == 1) {
1401
+ initiateDragDrop(
1402
+ e,
1403
+ {
1404
+ sourceEl: e.currentTarget,
1405
+ source: {
1406
+ type: "grid-column",
1407
+ store,
1408
+ column,
1409
+ columnInstance,
1410
+ headerInstance,
1411
+ gridInstance,
1412
+ headerLine,
1413
+ },
1414
+ clone: {
1415
+ store: store,
1416
+ matchCursorOffset: true,
1417
+ matchWidth: true,
1418
+ widget: () => <div className={CSS.element(baseClass, "col-header-drag-clone")}>{data.text}</div>,
1419
+ },
1420
+ },
1421
+ () => {},
1422
+ );
1423
+ }
1424
+ }
1425
+
1426
+ onHeaderMouseLeave(e: any, columnInstance: any, headerLine: any) {
1427
+ let headerInstance = columnInstance.components[`header${headerLine + 1}`];
1428
+ if (!headerInstance) return;
1429
+ if (headerInstance.widget?.tooltip) {
1430
+ tooltipMouseLeave(e, headerInstance, headerInstance.widget.tooltip);
1431
+ }
1432
+ }
1433
+
1434
+ onHeaderClick(e: any, column: any, instance: any, headerLine: any) {
1435
+ e.preventDefault();
1436
+ e.stopPropagation();
1437
+
1438
+ let { data } = instance;
1439
+ let header = column.components[`header${headerLine + 1}`];
1440
+
1441
+ let field = column.sortField || column.field;
1442
+ let value = column.sortValue || column.value;
1443
+ let comparer = column.comparer;
1444
+ let sortOptions = column.sortOptions;
1445
+
1446
+ if (header && header.allowSorting && column.sortable && (field || value || data.sortField)) {
1447
+ let direction = column.primarySortDirection ?? "ASC";
1448
+ if (
1449
+ isNonEmptyArray(data.sorters) &&
1450
+ ((!!data.sorters[0].field && data.sorters[0].field == (field || data.sortField)) ||
1451
+ (!!value && data.sorters[0].value == value))
1452
+ ) {
1453
+ if (data.sorters[0].direction == "ASC" && (!this.clearableSort || direction == "ASC")) direction = "DESC";
1454
+ else if (data.sorters[0].direction == "DESC" && (!this.clearableSort || direction == "DESC"))
1455
+ direction = "ASC";
1456
+ else {
1457
+ direction = null;
1458
+ instance.state.disableDefaultSort = true;
1459
+ }
1460
+ }
1461
+
1462
+ let sorters = direction
1463
+ ? [
1464
+ {
1465
+ field,
1466
+ direction,
1467
+ value,
1468
+ comparer,
1469
+ sortOptions,
1470
+ },
1471
+ ]
1472
+ : null;
1473
+
1474
+ if (sorters == null) field = null;
1475
+
1476
+ instance.set("sorters", sorters);
1477
+ instance.set("sortField", field);
1478
+ instance.set("sortDirection", direction);
1479
+
1480
+ if (!this.remoteSort || this.infinite) instance.setState({ sorters });
1481
+ }
1482
+ }
1483
+
1484
+ renderGroupHeader(
1485
+ context: RenderingContext | null,
1486
+ instance: GridInstance,
1487
+ g: any,
1488
+ level: any,
1489
+ group: any,
1490
+ i: any,
1491
+ store: any,
1492
+ fixedColumns: any,
1493
+ ) {
1494
+ let { CSS, baseClass } = this;
1495
+ let data = store.getData();
1496
+ if (g.caption) {
1497
+ let caption = g.caption(data);
1498
+ return (
1499
+ <tbody
1500
+ key={`g-${level}-${group.$key}`}
1501
+ className={CSS.element(baseClass, "group-caption", ["level-" + level])}
1502
+ data-group-key={group.$key}
1503
+ data-group-element={`group-caption-${level}`}
1504
+ >
1505
+ <tr>
1506
+ <td colSpan={1000}>{caption}</td>
1507
+ </tr>
1508
+ </tbody>
1509
+ );
1510
+ } else if (g.showCaption) {
1511
+ let skip = 0;
1512
+
1513
+ let { header } = instance;
1514
+
1515
+ let lines: any[] = [];
1516
+ header.children.forEach((line: any, lineIndex: number) => {
1517
+ let empty = true;
1518
+
1519
+ let cells = line.children.map((ci: any, i: any) => {
1520
+ if (--skip >= 0) return null;
1521
+
1522
+ if (Boolean(ci.data.fixed) != fixedColumns) return null;
1523
+
1524
+ let v,
1525
+ c = ci.widget,
1526
+ colSpan,
1527
+ pad,
1528
+ cls = "",
1529
+ style = null;
1530
+ if (c.caption) {
1531
+ if (c.caption.children)
1532
+ v = <Cx widget={c.caption.children} store={store} parentInstance={instance} subscribe />;
1533
+ else {
1534
+ v = c.caption.value(data);
1535
+ let fmt = c.caption.format(data);
1536
+ if (fmt) v = Format.value(v, fmt);
1537
+ }
1538
+ pad = c.caption.pad;
1539
+ colSpan = c.caption.colSpan;
1540
+ empty = false;
1541
+ cls = CSS.expand(c.caption.class(data)) || "";
1542
+ style = parseStyle(c.caption.style(data));
1543
+ if (c.caption.expand) {
1544
+ colSpan = 1;
1545
+ for (
1546
+ let ind = i + 1;
1547
+ ind < line.children.length &&
1548
+ !line.children[ind].widget.caption &&
1549
+ !line.children[ind].widget.aggregate;
1550
+ ind++
1551
+ )
1552
+ colSpan++;
1553
+ }
1554
+
1555
+ if (colSpan > 1) skip = colSpan - 1;
1556
+ } else if (c.aggregate && c.aggregateAliasGetter && c.caption !== false) {
1557
+ empty = false;
1558
+ v = c.aggregateAliasGetter(group);
1559
+ if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
1560
+ }
1561
+
1562
+ if (cls) cls += " ";
1563
+ if (c.align) cls += CSS.state("aligned-" + c.align);
1564
+
1565
+ if (pad !== false) cls += (cls ? " " : "") + CSS.state("pad");
1566
+
1567
+ return (
1568
+ <td key={i} className={cls} colSpan={colSpan} style={style}>
1569
+ {v}
1570
+ </td>
1571
+ );
1572
+ });
1573
+
1574
+ if (empty) return;
1575
+
1576
+ lines.push(<tr key={lineIndex}>{cells}</tr>);
1577
+ });
1578
+
1579
+ if (lines.length == 0) return null;
1580
+
1581
+ return (
1582
+ <tbody
1583
+ key={"c" + group.$key}
1584
+ className={CSS.element(baseClass, "group-caption", ["level-" + level])}
1585
+ data-group-key={group.$key}
1586
+ data-group-element={`group-caption-${level}`}
1587
+ >
1588
+ {lines}
1589
+ </tbody>
1590
+ );
1591
+ }
1592
+ }
1593
+
1594
+ renderGroupFooter(
1595
+ context: RenderingContext | null,
1596
+ instance: GridInstance,
1597
+ g: any,
1598
+ level: any,
1599
+ group: any,
1600
+ i: any,
1601
+ store: any,
1602
+ fixed: any,
1603
+ fixedColumns: any,
1604
+ ) {
1605
+ let { CSS, baseClass } = this;
1606
+ let data = store.getData();
1607
+ let skip = 0;
1608
+
1609
+ let { header, state } = instance;
1610
+ let rowStyle = {};
1611
+
1612
+ let lines: any[] = [];
1613
+ header.children.forEach((line: any, lineIndex: number) => {
1614
+ let empty = true;
1615
+
1616
+ let cells = line.children.map((ci: any, i: any) => {
1617
+ if (--skip >= 0) return null;
1618
+
1619
+ if (Boolean(ci.data.fixed) != fixedColumns) return null;
1620
+
1621
+ let v,
1622
+ c = ci.widget,
1623
+ colSpan = 1,
1624
+ pad,
1625
+ cls = "",
1626
+ style = null;
1627
+ if (c.footer) {
1628
+ v = c.footer.value(data);
1629
+ let fmt = c.footer.format(data);
1630
+ if (fmt) v = Format.value(v, fmt);
1631
+ pad = c.footer.pad;
1632
+ colSpan = c.footer.colSpan;
1633
+ empty = false;
1634
+ cls = CSS.expand(c.footer.class(data)) || "";
1635
+ style = parseStyle(c.footer.style(data));
1636
+ if (c.footer.expand) {
1637
+ colSpan = 1;
1638
+ for (
1639
+ let ind = i + 1;
1640
+ ind < line.children.length &&
1641
+ !line.children[ind].widget.footer &&
1642
+ !line.children[ind].widget.aggregate;
1643
+ ind++
1644
+ )
1645
+ colSpan++;
1646
+ }
1647
+
1648
+ if (colSpan > 1) skip = colSpan - 1;
1649
+ } else if (c.aggregate && c.aggregateAliasGetter && c.footer !== false) {
1650
+ empty = false;
1651
+ v = c.aggregateAliasGetter(group);
1652
+ if (isString(ci.data.format)) v = Format.value(v, ci.data.format);
1653
+ }
1654
+
1655
+ if (cls) cls += " ";
1656
+ if (c.align) cls += CSS.state("aligned-" + c.align);
1657
+
1658
+ if (pad !== false) cls += (cls ? " " : "") + CSS.state("pad");
1659
+
1660
+ // apply column width to footers too, but only if colSpan == 1,
1661
+ // otherwise set 1px so that the footer is not participating in the layout
1662
+
1663
+ let maxWidth = 1;
1664
+ if (colSpan == 1) maxWidth = state.colWidth[c.uniqueColumnId];
1665
+ style = {
1666
+ ...style,
1667
+ maxWidth,
1668
+ };
1669
+
1670
+ return (
1671
+ <td key={i} className={cls} colSpan={colSpan} style={style}>
1672
+ {v}
1673
+ </td>
1674
+ );
1675
+ });
1676
+
1677
+ if (empty) return;
1678
+
1679
+ if (fixed && !fixedColumns)
1680
+ cells.push(<td key="dummy" className={CSS.element(baseClass, "fixed-footer-corner")} />);
1681
+
1682
+ lines.push(<tr key={lineIndex}>{cells}</tr>);
1683
+ });
1684
+
1685
+ if (lines.length == 0) return null;
1686
+
1687
+ return (
1688
+ <tbody
1689
+ key={"f" + i}
1690
+ style={rowStyle}
1691
+ className={CSS.element(baseClass, "group-footer", ["level-" + level])}
1692
+ data-group-key={group.$key}
1693
+ data-group-element={`group-footer-${level}`}
1694
+ >
1695
+ {lines}
1696
+ </tbody>
1697
+ );
1698
+ }
1699
+
1700
+ renderRows(context: RenderingContext, instance: GridInstance) {
1701
+ let { records, hasFixedColumns } = instance;
1702
+
1703
+ if (!isArray<any>(records)) return null;
1704
+
1705
+ let record, g;
1706
+
1707
+ for (let i = 0; i < records.length; i++) {
1708
+ record = records[i];
1709
+ if (record.type == "data") record.vdom = record.row!.render(context);
1710
+
1711
+ if (record.type == "group-header") {
1712
+ record.vdom = [];
1713
+ record.fixedVdom = [];
1714
+ g = record.grouping;
1715
+ if (g.caption || g.showCaption)
1716
+ record.vdom.push(
1717
+ this.renderGroupHeader(
1718
+ context,
1719
+ instance,
1720
+ g,
1721
+ record.level,
1722
+ record.group,
1723
+ record.key + "-caption",
1724
+ record.store,
1725
+ false,
1726
+ ),
1727
+ );
1728
+
1729
+ if (hasFixedColumns)
1730
+ record.fixedVdom.push(
1731
+ this.renderGroupHeader(
1732
+ context,
1733
+ instance,
1734
+ g,
1735
+ record.level,
1736
+ record.group,
1737
+ record.key + "-caption",
1738
+ record.store,
1739
+ true,
1740
+ ),
1741
+ );
1742
+
1743
+ if (g.showHeader) {
1744
+ record.vdom.push(this.renderHeader(context, instance, record.key + "-header", false, false));
1745
+ if (hasFixedColumns)
1746
+ record.fixedVdom.push(this.renderHeader(context, instance, record.key + "-header", false, true));
1747
+ }
1748
+ }
1749
+
1750
+ if (record.type == "group-footer") {
1751
+ g = record.grouping;
1752
+ if (g.showFooter) {
1753
+ record.vdom = this.renderGroupFooter(
1754
+ context,
1755
+ instance,
1756
+ g,
1757
+ record.level,
1758
+ record.group,
1759
+ record.key + "-footer",
1760
+ record.store,
1761
+ false,
1762
+ false,
1763
+ );
1764
+ if (hasFixedColumns)
1765
+ record.fixedVdom = this.renderGroupFooter(
1766
+ context,
1767
+ instance,
1768
+ g,
1769
+ record.level,
1770
+ record.group,
1771
+ record.key + "-footer",
1772
+ record.store,
1773
+ false,
1774
+ true,
1775
+ );
1776
+ }
1777
+ }
1778
+ }
1779
+ }
1780
+
1781
+ renderFixedFooter(context: RenderingContext, instance: GridInstance) {
1782
+ let { records, hasFixedColumns, data } = instance;
1783
+
1784
+ instance.fixedFooterVDOM = null;
1785
+ instance.fixedColumnsFixedFooterVDOM = null;
1786
+
1787
+ if (data.empty || !isNonEmptyArray(records)) return;
1788
+
1789
+ //all type of records are allowed here because the footer can be based on pre-computed data
1790
+ //it doesn't make sense to show the footer if the grid is empty though
1791
+ let record = records[records.length - 1];
1792
+
1793
+ instance.fixedFooterOverlap = true;
1794
+ instance.fixedFooterIsGroupFooter = record.type == "group-footer";
1795
+
1796
+ instance.fixedFooterVDOM = this.renderGroupFooter(
1797
+ context,
1798
+ instance,
1799
+ record.grouping,
1800
+ record.level || 1,
1801
+ record.group || { $key: "fixed-footer" },
1802
+ record.key + "-footer",
1803
+ record.store,
1804
+ true,
1805
+ false,
1806
+ );
1807
+
1808
+ if (hasFixedColumns)
1809
+ instance.fixedColumnsFixedFooterVDOM = this.renderGroupFooter(
1810
+ context,
1811
+ instance,
1812
+ record.grouping,
1813
+ record.level,
1814
+ record.group || { $key: "fixed-footer" },
1815
+ record.key + "-footer",
1816
+ record.store,
1817
+ true,
1818
+ true,
1819
+ );
1820
+ }
1821
+
1822
+ mapRecords(context: RenderingContext, instance: GridInstance) {
1823
+ let { data, store, dataAdapter } = instance;
1824
+
1825
+ let filter = null;
1826
+ if (this.onCreateFilter) filter = instance.invoke("onCreateFilter", data.filterParams, instance);
1827
+
1828
+ let sorters = !this.remoteSort && data.sorters;
1829
+
1830
+ //apply pre-sorters only if some sorting is applied
1831
+ if (isNonEmptyArray(data.sorters) && isNonEmptyArray(data.preSorters)) {
1832
+ sorters = [...data.preSorters, ...data.sorters];
1833
+ }
1834
+
1835
+ dataAdapter.setFilter(filter);
1836
+ dataAdapter.sort(sorters);
1837
+
1838
+ //if no filtering or sorting applied, let the component maps records on demand
1839
+ if (
1840
+ this.buffered &&
1841
+ !this.fixedFooter &&
1842
+ !filter &&
1843
+ !isNonEmptyArray(sorters) &&
1844
+ !dataAdapter.isTreeAdapter &&
1845
+ !(instance.dataAdapter as any).groupings
1846
+ )
1847
+ return undefined;
1848
+
1849
+ return dataAdapter.getRecords(context, instance, data.records, store);
1850
+ }
1851
+
1852
+ mapRecord(context: RenderingContext, instance: GridInstance, data: any, index: number) {
1853
+ return instance.dataAdapter.mapRecord(context, instance, data, instance.store, this.recordsAccessor, index);
1854
+ }
1855
+ }
1856
+
1857
+ Grid.prototype.baseClass = "grid";
1858
+ Grid.prototype.showHeader = true;
1859
+ Grid.prototype.showFooter = false;
1860
+ Grid.prototype.recordName = "$record";
1861
+ Grid.prototype.indexName = "$index";
1862
+ Grid.prototype.remoteSort = false;
1863
+ Grid.prototype.lockColumnWidths = false;
1864
+ Grid.prototype.lockColumnWidthsRequiredRowCount = 3;
1865
+ Grid.prototype.focused = false;
1866
+ Grid.prototype.emptyText = false;
1867
+ Grid.prototype.showBorder = false; // show border override for material theme
1868
+ Grid.prototype.cached = false;
1869
+ Grid.prototype.buffered = false;
1870
+ Grid.prototype.bufferStep = 15;
1871
+ Grid.prototype.bufferSize = 60;
1872
+ Grid.prototype.pageSize = 100;
1873
+ Grid.prototype.infinite = false;
1874
+ Grid.prototype.styled = true;
1875
+ Grid.prototype.scrollSelectionIntoView = false;
1876
+ Grid.prototype.clearableSort = false;
1877
+ Grid.prototype.cellEditable = false;
1878
+ Grid.prototype.preciseMeasurements = false;
1879
+ Grid.prototype.hoverChannel = "default";
1880
+ Grid.prototype.focusable = null; // automatically resolved
1881
+ Grid.prototype.allowsFileDrops = false;
1882
+ Grid.prototype.preserveGroupOrder = false;
1883
+
1884
+ Widget.alias("grid", Grid);
1885
+ Localization.registerPrototype("cx/widgets/Grid", Grid);
1886
+
1887
+ interface GridComponentProps {
1888
+ instance: GridInstance;
1889
+ data: any;
1890
+ shouldUpdate: boolean | undefined;
1891
+ header?: any;
1892
+ fixedColumnsHeader?: any;
1893
+ fixedColumnsFixedHeader?: any;
1894
+ fixedHeader?: any;
1895
+ fixedFooter?: any;
1896
+ fixedColumnsFixedFooter?: any;
1897
+ children?: any;
1898
+ }
1899
+
1900
+ interface GridComponentState {
1901
+ cursor: number;
1902
+ cursorCellIndex: number;
1903
+ focused: boolean;
1904
+ dropInsertionIndex: number | null;
1905
+ dropNextToTheRowAbove: boolean | null;
1906
+ start: number;
1907
+ end: number;
1908
+ dragged?: any;
1909
+ cellEdit?: any;
1910
+ dropTarget?: any;
1911
+ dropItemHeight?: number;
1912
+ colDropInsertionLeft?: number;
1913
+ colDropInsertionIndex?: number;
1914
+ selectionStart?: number;
1915
+ }
1916
+
1917
+ class GridComponent extends VDOM.Component<GridComponentProps, GridComponentState> {
1918
+ dom: {
1919
+ el?: HTMLElement | null;
1920
+ table?: HTMLElement | null;
1921
+ scroller?: HTMLElement | null;
1922
+ fixedScroller?: HTMLElement | null;
1923
+ fixedTable?: HTMLElement | null;
1924
+ fixedHeader?: HTMLElement | null;
1925
+ fixedColumnsFixedHeader?: HTMLElement | null;
1926
+ fixedFooter?: HTMLElement | null;
1927
+ fixedColumnsFixedFooter?: HTMLElement | null;
1928
+ };
1929
+ syncBuffering: boolean = false;
1930
+ declare start?: number;
1931
+ declare end?: number;
1932
+ declare loadingStartPage?: number;
1933
+ declare loadingEndPage?: number;
1934
+ declare heightStats?: AvgHeight;
1935
+ declare rowHeights?: Record<string, number>;
1936
+ declare rowHeight?: number;
1937
+ scrollerRef: (el: HTMLElement | null) => void;
1938
+ fixedScrollerRef: (el: HTMLElement | null) => void;
1939
+ gridRef: (el: HTMLElement | null) => void;
1940
+ declare cellEditorValid?: boolean;
1941
+ declare scrollWidth: number;
1942
+ declare loading?: boolean;
1943
+ declare loadPageRange?: any;
1944
+ declare prevFetchRecordsState?: any;
1945
+ declare pending?: any;
1946
+ offResize?: () => void;
1947
+ unregisterDropZone?: () => void;
1948
+ declare lastSorters?: any;
1949
+ declare lastScrollFilterParams?: any;
1950
+ declare lastScrollResetParams?: any;
1951
+ declare selectedEl?: Element | null;
1952
+ declare cellEditUndoData?: any;
1953
+
1954
+ constructor(props: GridComponentProps) {
1955
+ super(props);
1956
+ this.dom = {};
1957
+ let { widget } = props.instance;
1958
+
1959
+ let end = Math.min(widget.bufferSize, props.data.totalRecordCount);
1960
+
1961
+ this.state = {
1962
+ cursor: widget.focused && widget.selectable ? 0 : -1,
1963
+ cursorCellIndex: 0,
1964
+ focused: widget.focused,
1965
+ dropInsertionIndex: null,
1966
+ dropNextToTheRowAbove: null,
1967
+ start: 0,
1968
+ end: end,
1969
+ };
1970
+
1971
+ this.syncBuffering = false;
1972
+
1973
+ if (widget.infinite) {
1974
+ this.start = 0;
1975
+ this.end = end;
1976
+ this.loadingStartPage = 0;
1977
+ this.loadingEndPage = 0;
1978
+ }
1979
+
1980
+ this.scrollerRef = (el) => {
1981
+ this.dom.scroller = el;
1982
+ };
1983
+
1984
+ this.fixedScrollerRef = (el) => {
1985
+ this.dom.fixedScroller = el;
1986
+ };
1987
+
1988
+ this.gridRef = (el) => {
1989
+ this.dom.el = el;
1990
+ };
1991
+ }
1992
+
1993
+ getBufferStartEnd(): { start: number; end: number } {
1994
+ return this.syncBuffering ? { start: this.start!, end: this.end! } : this.state;
1995
+ }
1996
+
1997
+ renderCellEditor(key: any, CSS: any, baseClass: any, instance: any, column: any) {
1998
+ //add an inner div with fixed height in order to help IE absolutely position the contents inside
1999
+ let editor = createGridCellEditor(
2000
+ CSS.element(baseClass, "cell-editor-wrap"),
2001
+ this.rowHeight != null && this.rowHeight > 0
2002
+ ? {
2003
+ height: this.rowHeight + 1,
2004
+ }
2005
+ : null,
2006
+ {
2007
+ get: () => this.cellEditorValid ?? false,
2008
+ set: (value: any) => {
2009
+ this.cellEditorValid = value;
2010
+ return true;
2011
+ },
2012
+ },
2013
+ column.editor,
2014
+ );
2015
+ return (
2016
+ <td key={key} className={CSS.element(baseClass, "cell-editor")}>
2017
+ <Cx parentInstance={instance} subscribe widget={editor}></Cx>
2018
+ </td>
2019
+ );
2020
+ }
2021
+
2022
+ createRowRenderer(cellWrap: any) {
2023
+ let { instance, data } = this.props;
2024
+ let { widget, isRecordSelectable, visibleColumns, isRecordDraggable, row } = instance;
2025
+ let { CSS, baseClass } = widget;
2026
+ let { dragSource } = data;
2027
+ let { dragged, cursor, cursorCellIndex, cellEdit, dropInsertionIndex, dropTarget } = this.state;
2028
+ let { colWidth, dimensionsVersion } = instance.state;
2029
+ let { hasMergedCells } = row;
2030
+
2031
+ return (record: MappedGridRecord, index: number, standalone: any, fixed: any) => {
2032
+ let { store, key, row } = record;
2033
+ let isDragged = dragged && (row?.selected || record == dragged);
2034
+ let mod: Record<string, any> = {
2035
+ selected: row?.selected,
2036
+ dragged: isDragged,
2037
+ cursor: widget.selectable && index == cursor,
2038
+ over: dropTarget == "row" && dropInsertionIndex === index,
2039
+ alternate: index % 2 == 1,
2040
+ };
2041
+
2042
+ if (isRecordSelectable) {
2043
+ let selectable = isRecordSelectable(record.data, {});
2044
+ mod["selectable"] = selectable;
2045
+ mod["non-selectable"] = !selectable;
2046
+ }
2047
+
2048
+ let draggable =
2049
+ dragSource &&
2050
+ !isNonEmptyArray((row as any).dragHandles) &&
2051
+ (!isRecordDraggable || isRecordDraggable(record.data));
2052
+ mod["draggable"] = draggable;
2053
+ mod["non-draggable"] = !draggable;
2054
+
2055
+ let wrap = (children: any) => {
2056
+ let skipCells: any = {};
2057
+ return (
2058
+ <GridRowComponent
2059
+ key={key}
2060
+ className={CSS.state(mod)}
2061
+ store={store}
2062
+ dragSource={dragSource}
2063
+ instance={row!}
2064
+ grid={instance}
2065
+ record={record}
2066
+ parent={this}
2067
+ cursorIndex={index}
2068
+ selected={row?.selected}
2069
+ isBeingDragged={dragged}
2070
+ isDraggedOver={mod.over}
2071
+ cursor={mod.cursor}
2072
+ cursorCellIndex={index == cursor && cursorCellIndex}
2073
+ cellEdit={index == cursor && cursorCellIndex != null && cellEdit}
2074
+ shouldUpdate={row?.shouldUpdate}
2075
+ dimensionsVersion={dimensionsVersion}
2076
+ fixed={fixed}
2077
+ useTrTag={hasMergedCells}
2078
+ >
2079
+ {children.content.map(({ key, data, content }: any, line: any) => {
2080
+ let cells = content.map(
2081
+ ({ key, data, content, uniqueColumnId, merged, mergeRowSpan }: any, cellIndex: number) => {
2082
+ if (Boolean(data.fixed) !== fixed) return null;
2083
+ if (merged) return null;
2084
+ let cellected =
2085
+ index == cursor && cellIndex == cursorCellIndex && widget.cellEditable && line == 0;
2086
+ let className = cellected
2087
+ ? CSS.expand(data.classNames, CSS.state("cellected"))
2088
+ : data.classNames;
2089
+ if (cellected && cellEdit) {
2090
+ let column = visibleColumns[cursorCellIndex];
2091
+ if (column && column.editor && data.editable)
2092
+ return this.renderCellEditor(key, CSS, baseClass, row, column);
2093
+ }
2094
+ let width = colWidth[uniqueColumnId];
2095
+ let style = data.style;
2096
+ if (width) {
2097
+ style = {
2098
+ ...style,
2099
+ maxWidth: `${width}px`,
2100
+ };
2101
+ }
2102
+
2103
+ if (skipCells[`${line}-${cellIndex}`]) return null;
2104
+
2105
+ if (data.colSpan > 1 || data.rowSpan > 1) {
2106
+ for (let r = line; r < line + (data.rowSpan ?? 1); r++)
2107
+ for (let c = cellIndex; c < cellIndex + (data.colSpan ?? 1); c++)
2108
+ skipCells[`${r}-${c}`] = true;
2109
+ }
2110
+
2111
+ if (cellWrap) content = cellWrap(content);
2112
+
2113
+ return (
2114
+ <td
2115
+ key={key}
2116
+ className={className}
2117
+ style={style}
2118
+ colSpan={data.colSpan}
2119
+ rowSpan={mergeRowSpan ?? data.rowSpan}
2120
+ >
2121
+ {content}
2122
+ </td>
2123
+ );
2124
+ },
2125
+ );
2126
+ if (hasMergedCells) return cells;
2127
+ return (
2128
+ <tr key={key} className={data.classNames} style={data.style}>
2129
+ {cells}
2130
+ </tr>
2131
+ );
2132
+ })}
2133
+ </GridRowComponent>
2134
+ );
2135
+ };
2136
+
2137
+ if (!standalone) return wrap(record.vdom);
2138
+
2139
+ return (
2140
+ <Cx
2141
+ key={key}
2142
+ instance={record.row}
2143
+ parentInstance={instance}
2144
+ options={{ name: "grid-row" }}
2145
+ contentFactory={(x) =>
2146
+ wrap({
2147
+ content: Array.isArray(x.children) ? x.children : x.children != null ? [x.children] : [],
2148
+ data: {},
2149
+ })
2150
+ }
2151
+ params={{
2152
+ ...mod,
2153
+ dimensionsVersion: dimensionsVersion,
2154
+ cursorIndex: index,
2155
+ data: record.data,
2156
+ cursorCellIndex: index == cursor && cursorCellIndex,
2157
+ cellEdit: index == cursor && cursorCellIndex != null && cellEdit,
2158
+ }}
2159
+ />
2160
+ );
2161
+ };
2162
+ }
2163
+
2164
+ render() {
2165
+ let { instance, data, fixedFooter, fixedColumnsFixedFooter } = this.props;
2166
+ let { widget, hasFixedColumns } = instance;
2167
+ let { CSS, baseClass } = widget;
2168
+ let { start, end } = this.getBufferStartEnd();
2169
+
2170
+ let cellWrap: any = false;
2171
+
2172
+ if (widget.cellEditable && (widget.hasResizableColumns || hasFixedColumns)) {
2173
+ cellWrap = (children: any) => <div className="cxe-grid-cell-clip">{children}</div>;
2174
+ }
2175
+
2176
+ let children: any[] = [],
2177
+ fixedChildren: any[] = [];
2178
+
2179
+ let renderRow = this.createRowRenderer(cellWrap);
2180
+
2181
+ let addRow = (record: any, index: number, standalone?: boolean) => {
2182
+ children.push(renderRow(record, index, standalone, false));
2183
+ if (hasFixedColumns) fixedChildren.push(renderRow(record, index, standalone, true));
2184
+
2185
+ //avoid re-rendering on cursor change
2186
+ record.row.shouldUpdate = false;
2187
+ };
2188
+
2189
+ if (widget.buffered) {
2190
+ let context = new RenderingContext();
2191
+ let dummyDataClass = CSS.element(baseClass, "data", { dummy: true });
2192
+ if (!instance.recordInstanceCache) instance.recordInstanceCache = new InstanceCache(instance);
2193
+ instance.recordInstanceCache.mark();
2194
+ this.getRecordsSlice(start, end).forEach((r: any, i: any) => {
2195
+ if (r == null) {
2196
+ addRow(
2197
+ {
2198
+ key: "dummy-" + start + i,
2199
+ row: {
2200
+ data: { classNames: dummyDataClass },
2201
+ widget: instance.row,
2202
+ },
2203
+ vdom: {
2204
+ content: [
2205
+ {
2206
+ key: 0,
2207
+ data: {},
2208
+ content: [
2209
+ {
2210
+ key: 0,
2211
+ data: {
2212
+ colSpan: 1000,
2213
+ style: {
2214
+ height: `${this.rowHeight}px`,
2215
+ },
2216
+ },
2217
+ },
2218
+ ],
2219
+ },
2220
+ ],
2221
+ },
2222
+ },
2223
+ start + i,
2224
+ );
2225
+ } else {
2226
+ let record = instance.records
2227
+ ? r
2228
+ : widget.mapRecord(context, instance, r, widget.infinite ? start + i - data.offset : start + i);
2229
+ let row = (record.row = instance.recordInstanceCache.getChild(instance.row, record.store, record.key));
2230
+ instance.recordInstanceCache.addChild(row);
2231
+ row.detached = true;
2232
+ row.selected = instance.isSelected(record.data, record.index);
2233
+
2234
+ if (record.type == "data") {
2235
+ addRow(record, start + i, true);
2236
+ } else if (record.type == "group-header") {
2237
+ let g = record.grouping;
2238
+ if (g.caption || g.showCaption) {
2239
+ children.push(
2240
+ widget.renderGroupHeader(
2241
+ null,
2242
+ instance,
2243
+ g,
2244
+ record.level,
2245
+ record.group,
2246
+ record.key + "-caption",
2247
+ record.store,
2248
+ false,
2249
+ ),
2250
+ );
2251
+
2252
+ if (hasFixedColumns)
2253
+ fixedChildren.push(
2254
+ widget.renderGroupHeader(
2255
+ null,
2256
+ instance,
2257
+ g,
2258
+ record.level,
2259
+ record.group,
2260
+ record.key + "-caption",
2261
+ record.store,
2262
+ true,
2263
+ ),
2264
+ );
2265
+ }
2266
+ } else if (record.type == "group-footer") {
2267
+ let g = record.grouping;
2268
+ if (g.showFooter && (!widget.fixedFooter || start + i != instance.records!.length - 1)) {
2269
+ children.push(
2270
+ widget.renderGroupFooter(
2271
+ null,
2272
+ instance,
2273
+ g,
2274
+ record.level,
2275
+ record.group,
2276
+ record.key + "-footer",
2277
+ record.store,
2278
+ false,
2279
+ false,
2280
+ ),
2281
+ );
2282
+
2283
+ if (hasFixedColumns)
2284
+ fixedChildren.push(
2285
+ widget.renderGroupFooter(
2286
+ null,
2287
+ instance,
2288
+ g,
2289
+ record.level,
2290
+ record.group,
2291
+ record.key + "-footer",
2292
+ record.store,
2293
+ false,
2294
+ true,
2295
+ ),
2296
+ );
2297
+ }
2298
+ }
2299
+ }
2300
+ });
2301
+ instance.recordInstanceCache.sweep();
2302
+ } else {
2303
+ let { row } = instance;
2304
+ let { hasMergedCells, mergedColumns } = row;
2305
+ if (hasMergedCells) {
2306
+ // merge adjacent cells with the same value in columns that are marked as merged
2307
+ let rowSpan: Record<string, any> = {};
2308
+ let getCellRenderInfo = (vdom: any, cellIndex: number) => vdom.content[0]?.content[cellIndex];
2309
+ for (let index = instance.records!.length - 1; index >= 0; index--) {
2310
+ let row = instance.records![index];
2311
+ let prevRow = instance.records![index - 1];
2312
+ if (row.type == "data") {
2313
+ let stopMerge = false;
2314
+ for (let mi = 0; mi < mergedColumns.length; mi++) {
2315
+ let mergedCol = mergedColumns[mi];
2316
+ let cellInfo = getCellRenderInfo(row.vdom, mergedCol.index);
2317
+ cellInfo.merged = false;
2318
+ delete cellInfo.mergeRowSpan;
2319
+ if (prevRow?.type == "data") {
2320
+ let shouldMerge = false;
2321
+ switch (mergedCol.mode) {
2322
+ case "always":
2323
+ shouldMerge = true;
2324
+ break;
2325
+ case "same-value":
2326
+ let prevCellInfo = getCellRenderInfo(prevRow.vdom, mergedCol.index);
2327
+ shouldMerge = !stopMerge && cellInfo.data.value === prevCellInfo.data.value;
2328
+ break;
2329
+ }
2330
+
2331
+ if (shouldMerge) {
2332
+ cellInfo.merged = true;
2333
+ rowSpan[mergedCol.uniqueColumnId] = (rowSpan[mergedCol.uniqueColumnId] ?? 1) + 1;
2334
+ } else {
2335
+ if (mergedCol.mode == "same-value") stopMerge = true;
2336
+ }
2337
+ }
2338
+ if (!cellInfo.merged && rowSpan[mergedCol.uniqueColumnId] > 1) {
2339
+ cellInfo.mergeRowSpan = rowSpan[mergedCol.uniqueColumnId];
2340
+ rowSpan[mergedCol.uniqueColumnId] = 1;
2341
+ }
2342
+ }
2343
+ } else rowSpan = {};
2344
+ }
2345
+ }
2346
+
2347
+ instance.records!.forEach((record, i) => {
2348
+ if (record.type == "data") addRow(record, i, false);
2349
+ else {
2350
+ children.push(record.vdom);
2351
+ if (hasFixedColumns) fixedChildren.push(record.fixedVdom);
2352
+ }
2353
+ });
2354
+ }
2355
+
2356
+ if (this.state.dropTarget == "grid" && this.state.dropInsertionIndex != null) {
2357
+ let dragInsertionRow = (
2358
+ <tbody key="dropzone">
2359
+ <tr>
2360
+ <td
2361
+ className={CSS.element(baseClass, "dropzone")}
2362
+ colSpan={1000}
2363
+ style={{
2364
+ height: data.dropMode == "insertion" ? 0 : this.state.dropItemHeight,
2365
+ }}
2366
+ />
2367
+ </tr>
2368
+ </tbody>
2369
+ );
2370
+
2371
+ let dataRecordClass = CSS.element(baseClass, "data");
2372
+
2373
+ let isDataRecord = widget.buffered
2374
+ ? (item: any) => item?.props?.instance?.data?.class == dataRecordClass
2375
+ : (item: any) => item?.props?.record?.type;
2376
+
2377
+ let index = 0;
2378
+ while (index < children.length && !isDataRecord(children[index])) index++;
2379
+
2380
+ let count = 0;
2381
+ while (index < children.length && count < this.state.dropInsertionIndex) {
2382
+ if (isDataRecord(children[index])) count++;
2383
+ index++;
2384
+ }
2385
+
2386
+ let savedIndexPos = index;
2387
+
2388
+ if (!this.state.dropNextToTheRowAbove)
2389
+ while (index < children.length && !isDataRecord(children[index])) index++;
2390
+
2391
+ // do not allow insertion after the last group footer
2392
+ if (savedIndexPos < index && index == children.length) index = savedIndexPos;
2393
+
2394
+ children.splice(index, 0, dragInsertionRow);
2395
+ }
2396
+
2397
+ let content = [],
2398
+ fixedColumnsContent = [];
2399
+
2400
+ //instance.records holds the record count after filtering
2401
+ if (data.emptyText && data.empty) {
2402
+ children = [
2403
+ <tbody key="empty" className={CSS.element(baseClass, "empty-text")}>
2404
+ <tr>
2405
+ <td colSpan={1000}>{data.emptyText}</td>
2406
+ </tr>
2407
+ </tbody>,
2408
+ ];
2409
+ } else if (widget.fixedFooter && (widget.buffered || !instance.fixedFooterIsGroupFooter)) {
2410
+ //add fixed footer content for buffered grids
2411
+ if (fixedFooter || fixedColumnsFixedFooter) {
2412
+ children.push(fixedFooter);
2413
+ if (hasFixedColumns) fixedChildren.push(fixedColumnsFixedFooter);
2414
+ }
2415
+ }
2416
+
2417
+ let shouldRenderFixedFooter = widget.scrollable && (fixedFooter || fixedColumnsFixedFooter);
2418
+
2419
+ if (hasFixedColumns) {
2420
+ fixedColumnsContent.push(
2421
+ <div
2422
+ key="fixedscroller"
2423
+ ref={this.fixedScrollerRef}
2424
+ className={CSS.element(baseClass, "fixed-scroll-area", {
2425
+ "fixed-header": !!this.props.header,
2426
+ "fixed-footer": shouldRenderFixedFooter,
2427
+ })}
2428
+ >
2429
+ <div className={CSS.element(baseClass, "fixed-table-wrapper")}>
2430
+ <table
2431
+ ref={(el) => {
2432
+ this.dom.fixedTable = el;
2433
+ }}
2434
+ >
2435
+ {this.props.fixedColumnsHeader}
2436
+ {fixedChildren}
2437
+ </table>
2438
+ </div>
2439
+ </div>,
2440
+ );
2441
+ }
2442
+
2443
+ content.push(
2444
+ <div
2445
+ key="scroller"
2446
+ ref={this.scrollerRef}
2447
+ onScroll={this.onScroll.bind(this)}
2448
+ className={CSS.element(baseClass, "scroll-area", {
2449
+ "fixed-header": !!this.props.header,
2450
+ "fixed-footer": shouldRenderFixedFooter,
2451
+ })}
2452
+ >
2453
+ <div className={CSS.element(baseClass, "table-wrapper")}>
2454
+ <table
2455
+ ref={(el) => {
2456
+ this.dom.table = el;
2457
+ if (this.props.instance.widget.onRef) this.props.instance.invoke("onRef", el, this.props.instance);
2458
+ }}
2459
+ >
2460
+ {this.props.header}
2461
+ {children}
2462
+ </table>
2463
+ </div>
2464
+ </div>,
2465
+ );
2466
+
2467
+ if (this.props.fixedHeader)
2468
+ content.push(
2469
+ <div
2470
+ key="fh"
2471
+ ref={(el) => {
2472
+ this.dom.fixedHeader = el;
2473
+ }}
2474
+ className={CSS.element(baseClass, "fixed-header")}
2475
+ style={{
2476
+ display: this.scrollWidth > 0 ? "block" : "none",
2477
+ }}
2478
+ >
2479
+ <table>{this.props.fixedHeader}</table>
2480
+ </div>,
2481
+ );
2482
+
2483
+ if (this.props.fixedColumnsFixedHeader)
2484
+ fixedColumnsContent.push(
2485
+ <div
2486
+ key="fcfh"
2487
+ ref={(el) => {
2488
+ this.dom.fixedColumnsFixedHeader = el;
2489
+ }}
2490
+ className={CSS.element(baseClass, "fixed-fixed-header")}
2491
+ style={{
2492
+ display: this.scrollWidth > 0 ? "block" : "none",
2493
+ }}
2494
+ >
2495
+ <table>{this.props.fixedColumnsFixedHeader}</table>
2496
+ </div>,
2497
+ );
2498
+
2499
+ if (shouldRenderFixedFooter) {
2500
+ content.push(
2501
+ <div
2502
+ key="ff"
2503
+ ref={(el) => {
2504
+ this.dom.fixedFooter = el;
2505
+ }}
2506
+ className={CSS.element(baseClass, "fixed-footer")}
2507
+ >
2508
+ <table>{fixedFooter}</table>
2509
+ </div>,
2510
+ );
2511
+
2512
+ if (hasFixedColumns)
2513
+ fixedColumnsContent.push(
2514
+ <div
2515
+ key="fcff"
2516
+ ref={(el) => {
2517
+ this.dom.fixedColumnsFixedFooter = el;
2518
+ }}
2519
+ className={CSS.element(baseClass, "fixed-fixed-footer")}
2520
+ >
2521
+ <table>{fixedColumnsFixedFooter}</table>
2522
+ </div>,
2523
+ );
2524
+ }
2525
+
2526
+ let columnInsertionMarker = null;
2527
+ if (this.state.dropTarget == "column") {
2528
+ columnInsertionMarker = (
2529
+ <div
2530
+ className={CSS.element(baseClass, "col-insertion-marker")}
2531
+ style={{
2532
+ left: this.state.colDropInsertionLeft,
2533
+ }}
2534
+ />
2535
+ );
2536
+ }
2537
+
2538
+ return (
2539
+ <div
2540
+ className={data.classNames}
2541
+ style={{ ...data.style, counterReset: `cx-row-number ${start}` }}
2542
+ tabIndex={widget.focusable ? data.tabIndex || 0 : null}
2543
+ ref={this.gridRef}
2544
+ onKeyDown={this.handleKeyDown.bind(this)}
2545
+ onFocus={this.onFocus.bind(this)}
2546
+ onBlur={this.onBlur.bind(this)}
2547
+ onDragEnter={this.onFileDragEnter.bind(this)}
2548
+ onDragOver={this.onFileDragOver.bind(this)}
2549
+ onDragLeave={this.onFileDragLeave.bind(this)}
2550
+ onDrop={this.onFileDrop.bind(this)}
2551
+ >
2552
+ {fixedColumnsContent}
2553
+ {content}
2554
+ {columnInsertionMarker}
2555
+ {this.props.children}
2556
+ </div>
2557
+ );
2558
+ }
2559
+
2560
+ getRecordsSlice(start: number, end: number): MappedGridRecord<any>[] {
2561
+ let { data, instance } = this.props;
2562
+ let { widget } = instance;
2563
+ if (!widget.infinite) {
2564
+ let source = instance.records || data.records;
2565
+ return source.slice(start, end);
2566
+ }
2567
+
2568
+ let { offset, records } = data;
2569
+ let result = [];
2570
+ for (let i = start; i < Math.min(end, data.totalRecordCount); i++) {
2571
+ if (i >= offset && i < offset + records.length) result.push(records[i - offset]);
2572
+ else result.push(null);
2573
+ }
2574
+
2575
+ return result;
2576
+ }
2577
+
2578
+ ensureData(visibleStart: number, visibleEnd: number) {
2579
+ if (this.loading) return;
2580
+
2581
+ let { instance } = this.props;
2582
+ let { widget } = instance;
2583
+ let { pageSize } = widget;
2584
+
2585
+ let startPage = Math.trunc(visibleStart / pageSize) + 1,
2586
+ endPage = Math.trunc((visibleEnd - 1) / pageSize) + 1;
2587
+
2588
+ //debouncing restricts excessive page loading on fast scrolling as rendering data is
2589
+ //useless because visible region is scrolled away before data appears
2590
+ //the user should spent some time on the page before loading it
2591
+
2592
+ if (!this.loadPageRange)
2593
+ this.loadPageRange = debounce((startPage, endPage) => {
2594
+ let { data } = this.props;
2595
+ let { records, offset } = data;
2596
+ let promises = [];
2597
+
2598
+ for (let page = startPage; page <= endPage; page++) {
2599
+ let s = (page - 1) * pageSize,
2600
+ e = s + pageSize;
2601
+ if (s >= offset && e <= offset + records.length) {
2602
+ promises.push(Promise.resolve(records.slice(s - offset, e - offset)));
2603
+ } else {
2604
+ let result = instance.invoke(
2605
+ "onFetchRecords",
2606
+ {
2607
+ page,
2608
+ pageSize,
2609
+ sorters: data.sorters,
2610
+ sortField: data.sortField,
2611
+ sortDirection: data.sortDirection,
2612
+ filterParams: data.filterParams,
2613
+ state: this.prevFetchRecordsState,
2614
+ },
2615
+ instance,
2616
+ );
2617
+ promises.push(Promise.resolve(result));
2618
+ }
2619
+ }
2620
+
2621
+ this.loading = true;
2622
+
2623
+ Promise.all(promises)
2624
+ .then((pageRecords) => {
2625
+ this.loading = false;
2626
+ let records: any[] = [];
2627
+ let totalRecordCount: number | undefined;
2628
+ let lastPage: boolean | undefined;
2629
+
2630
+ pageRecords.forEach((page) => {
2631
+ if (Array.isArray(page)) {
2632
+ records.push(...page);
2633
+ } else {
2634
+ if (!Array.isArray(page.records))
2635
+ throw new Error(
2636
+ "onFetchRecords should return an array of records or an object with results inside records property.",
2637
+ );
2638
+ totalRecordCount = page.totalRecordCount;
2639
+ lastPage = page.lastPage;
2640
+ this.prevFetchRecordsState = page.state;
2641
+ records.push(...page.records);
2642
+ }
2643
+ });
2644
+
2645
+ let { data } = this.props;
2646
+
2647
+ if (!isNumber(totalRecordCount)) {
2648
+ totalRecordCount = (startPage - 1) * pageSize + records.length;
2649
+ if (!lastPage && records.length == (endPage - startPage + 1) * pageSize) totalRecordCount++;
2650
+ if (data.totalRecordCount > totalRecordCount) totalRecordCount = data.totalRecordCount;
2651
+ }
2652
+
2653
+ instance.buffer.totalRecordCount = data.totalRecordCount = totalRecordCount;
2654
+ instance.buffer.records = data.records = records;
2655
+ instance.buffer.page = data.page = startPage;
2656
+ data.offset = (startPage - 1) * pageSize;
2657
+
2658
+ instance.store.silently(() => {
2659
+ instance.set("records", records);
2660
+ instance.set("page", startPage);
2661
+ instance.set("totalRecordCount", totalRecordCount);
2662
+ });
2663
+
2664
+ let stateChanges: any = {
2665
+ startPage,
2666
+ endPage,
2667
+ };
2668
+
2669
+ if (this.state.end == 0) stateChanges.end = Math.min(widget.bufferSize!, totalRecordCount!);
2670
+
2671
+ this.setState(stateChanges, () => {
2672
+ this.loadingStartPage = startPage;
2673
+ this.loadingEndPage = endPage;
2674
+ this.onScroll();
2675
+ });
2676
+ })
2677
+ .catch((error) => {
2678
+ this.loading = false;
2679
+ if (widget.onLoadingError) instance.invoke(error, "onLoadingError", instance);
2680
+ });
2681
+ }, 30);
2682
+
2683
+ if (startPage < this.loadingStartPage! || endPage > this.loadingEndPage!) {
2684
+ this.loadingStartPage = startPage;
2685
+ this.loadingEndPage = endPage;
2686
+ this.loadPageRange(startPage, endPage);
2687
+ }
2688
+ }
2689
+
2690
+ onScroll() {
2691
+ //check if unmounted
2692
+ if (!this.dom.scroller!) return;
2693
+
2694
+ if (this.dom.fixedHeader!) {
2695
+ this.dom.fixedHeader!.scrollLeft = this.dom.scroller!.scrollLeft;
2696
+ }
2697
+
2698
+ if (this.dom.fixedFooter!) {
2699
+ this.dom.fixedFooter!.scrollLeft = this.dom.scroller!.scrollLeft;
2700
+ }
2701
+
2702
+ if (this.dom.fixedScroller!) {
2703
+ this.dom.fixedScroller!.scrollTop = this.dom.scroller!.scrollTop;
2704
+ }
2705
+
2706
+ let { instance, data } = this.props;
2707
+ let { widget } = instance;
2708
+ if (widget.buffered && !this.pending) {
2709
+ let start = 0;
2710
+ if (widget.measureRowHeights && instance.records)
2711
+ start = Math.max(0, this.estimateStart(instance.records, this.dom.scroller!.scrollTop) - widget.bufferStep);
2712
+ else if (this.rowHeight! > 0)
2713
+ start = Math.round(this.dom.scroller!.scrollTop / this.rowHeight! - widget.bufferStep);
2714
+
2715
+ start = Math.round(start / widget.bufferStep) * widget.bufferStep;
2716
+ start = Math.max(0, Math.min(start, data.totalRecordCount - widget.bufferSize));
2717
+ let end = Math.min(data.totalRecordCount, start + widget.bufferSize);
2718
+
2719
+ if (widget.infinite) {
2720
+ this.ensureData(start, end);
2721
+ }
2722
+
2723
+ if (this.syncBuffering) {
2724
+ this.start = start;
2725
+ this.end = end;
2726
+ } else if (this.state.end != end) {
2727
+ this.pending = true;
2728
+ this.setState({ start, end }, () => {
2729
+ this.pending = false;
2730
+ });
2731
+ }
2732
+ }
2733
+ }
2734
+
2735
+ onFixedColumnsWheel(e: WheelEvent) {
2736
+ this.dom.scroller!.scrollTop += e.deltaY;
2737
+ e.preventDefault();
2738
+ }
2739
+
2740
+ shouldComponentUpdate(props: GridComponentProps, state: GridComponentState) {
2741
+ return props.shouldUpdate !== false || state !== this.state;
2742
+ }
2743
+
2744
+ componentDidMount() {
2745
+ this.componentDidUpdate();
2746
+ let { instance } = this.props;
2747
+ let { widget } = instance;
2748
+ if (widget.scrollable) {
2749
+ //update fixed header/footer on resize
2750
+ this.offResize = ResizeManager.trackElement(this.dom.scroller!, () => {
2751
+ requestAnimationFrame(() => {
2752
+ //ignore changes if the element is not visible on the page
2753
+ if (!this.dom.scroller?.offsetWidth) return;
2754
+ this.componentDidUpdate();
2755
+ instance.setState({
2756
+ dimensionsVersion: instance.state.dimensionsVersion + 1,
2757
+ lockedColWidth: {},
2758
+ });
2759
+ });
2760
+ });
2761
+ }
2762
+ if (widget.pipeKeyDown) instance.invoke("pipeKeyDown", this.handleKeyDown.bind(this), instance);
2763
+ this.unregisterDropZone = registerDropZone(this);
2764
+ if (widget.infinite) this.ensureData(0, 0);
2765
+ if (this.dom.fixedScroller!) {
2766
+ this.onFixedColumnsWheel = this.onFixedColumnsWheel.bind(this);
2767
+ this.dom.fixedScroller!.addEventListener("wheel", this.onFixedColumnsWheel, { passive: false });
2768
+ }
2769
+ }
2770
+
2771
+ onDragStart(e: DragEvent) {
2772
+ let { instance } = this.props;
2773
+ let { widget } = instance;
2774
+ if (widget.onDragStart) instance.invoke("onDragStart", e, instance);
2775
+ }
2776
+
2777
+ onDrop(e: DragEvent) {
2778
+ try {
2779
+ let { instance } = this.props;
2780
+ let { widget } = instance;
2781
+ let { start } = this.getBufferStartEnd();
2782
+ let { dropInsertionIndex, dropTarget, dropNextToTheRowAbove } = this.state;
2783
+ if (dropTarget == "grid" && widget.onDrop && dropInsertionIndex != null) {
2784
+ let gridEvent = e as GridDragEvent<any>;
2785
+ gridEvent.target = {
2786
+ insertionIndex: start + dropInsertionIndex,
2787
+ recordBefore: this.getDataRecordAt(start + dropInsertionIndex - 1),
2788
+ recordAfter: this.getDataRecordAt(start + dropInsertionIndex),
2789
+ totalRecordCount: instance.records!.length,
2790
+ dropNextToTheRowAbove,
2791
+ };
2792
+ instance.invoke("onDrop", gridEvent, instance);
2793
+ } else if (dropTarget == "row") {
2794
+ let rowEvent = e as GridRowDragEvent<any>;
2795
+ rowEvent.target = {
2796
+ index: start + dropInsertionIndex!,
2797
+ record: this.getDataRecordAt(start + dropInsertionIndex!)!,
2798
+ };
2799
+ instance.invoke("onRowDrop", rowEvent, instance);
2800
+ } else if (dropTarget == "column" && widget.onColumnDrop) {
2801
+ let colEvent = e as GridColumnDropEvent;
2802
+ colEvent.target = {
2803
+ index: this.state.colDropInsertionIndex!,
2804
+ grid: widget,
2805
+ instance,
2806
+ };
2807
+ instance.invoke("onColumnDrop", colEvent, instance);
2808
+ }
2809
+ } catch (err) {
2810
+ console.error("Grid drop operation failed. Please fix this error:", err);
2811
+ }
2812
+
2813
+ //in some cases drop operation is not followed by leave
2814
+ this.onDragLeave(e);
2815
+ }
2816
+
2817
+ onDropTest(e: DragEvent) {
2818
+ let { instance } = this.props;
2819
+ let { widget } = instance;
2820
+ let grid = widget.onDropTest && instance.invoke("onDropTest", e, instance);
2821
+ let row = widget.onRowDropTest && instance.invoke("onRowDropTest", e, instance);
2822
+ let column = widget.onColumnDropTest && instance.invoke("onColumnDropTest", e, instance);
2823
+ return (grid || row || column) && { grid, row, column };
2824
+ }
2825
+
2826
+ onDragEnd(e: DragEvent) {
2827
+ this.setState({
2828
+ dropTarget: null,
2829
+ dropInsertionIndex: null,
2830
+ colDropInsertionIndex: undefined,
2831
+ colDropInsertionLeft: undefined,
2832
+ });
2833
+ let { instance } = this.props;
2834
+ let { widget } = instance;
2835
+ if (widget.onDragEnd) instance.invoke("onDragEnd", e, instance);
2836
+ }
2837
+
2838
+ onDragMeasure(e: DragEvent, { test: { grid, row, column } }: any) {
2839
+ //columns can be dropped anywhere, while rows only in the scrollable area
2840
+ let r = getTopLevelBoundingClientRect(column ? this.dom.el! : this.dom.scroller!);
2841
+ let { clientX, clientY } = e.cursor;
2842
+
2843
+ if (clientX < r.left || clientX >= r.right || clientY < r.top || clientY >= r.bottom) return false;
2844
+
2845
+ return {
2846
+ over: 1000,
2847
+ near: false,
2848
+ };
2849
+ }
2850
+
2851
+ onColumnDragOver(ev: DragEvent) {
2852
+ let headerTBody = this.dom.table!.firstChild as HTMLElement;
2853
+ let positions: number[] = [];
2854
+ let bounds: DOMRect;
2855
+
2856
+ let exists: Record<string, boolean> = {};
2857
+
2858
+ for (let r = 0; r < headerTBody!.children.length; r++) {
2859
+ let cells = headerTBody!.children[r].children;
2860
+ for (let c = 0; c < cells.length; c++) {
2861
+ bounds = cells[c].getBoundingClientRect();
2862
+ let key = bounds.left.toFixed(0);
2863
+ if (exists[key]) continue;
2864
+ positions.push(bounds.left);
2865
+ exists[key] = true;
2866
+ }
2867
+ if (r == 0) positions.push(bounds!.right);
2868
+ }
2869
+
2870
+ //due to the order of enumeration it's possible that positions are out of order
2871
+ positions.sort((a, b) => a - b);
2872
+ let index = 0;
2873
+ while (index + 1 < positions.length && ev.cursor.clientX > positions[index + 1]) index++;
2874
+
2875
+ let { fixedColumnCount } = this.props.instance;
2876
+
2877
+ this.setState({
2878
+ colDropInsertionIndex: fixedColumnCount + index,
2879
+ colDropInsertionLeft:
2880
+ positions[index] - positions[0] - this.dom.scroller!.scrollLeft + this.dom.scroller!.offsetLeft,
2881
+ dropTarget: "column",
2882
+ });
2883
+ }
2884
+
2885
+ onDragOver(ev: DragEvent, { test: { grid, row, column } }: GridDropOperationContext) {
2886
+ if (column) this.onColumnDragOver(ev);
2887
+
2888
+ if (!grid && !row) return;
2889
+
2890
+ let { instance } = this.props;
2891
+ let { widget, data } = instance;
2892
+ let { CSS, baseClass } = widget;
2893
+ let rowClass = CSS.element(baseClass, "data");
2894
+ let nodes = Array.from(this.dom.table!.children).filter(
2895
+ (node) => node.className && node.className.indexOf(rowClass) != -1,
2896
+ );
2897
+ let { start } = this.getBufferStartEnd();
2898
+
2899
+ let s = 0,
2900
+ e = nodes.length,
2901
+ m,
2902
+ b;
2903
+ let parentOffset = getParentFrameBoundingClientRect(this.dom.scroller!);
2904
+ let cy = ev.cursor.clientY - parentOffset.top;
2905
+
2906
+ let rowOverIndex = null;
2907
+ let nextToTheRowAbove = false;
2908
+
2909
+ while (s < e) {
2910
+ m = Math.floor((s + e) / 2);
2911
+ b = nodes[m].getBoundingClientRect();
2912
+
2913
+ //dragged items might be invisible and have no client bounds
2914
+ if (b.top == 0 && b.bottom == 0) {
2915
+ //it's important to go all the way in one direction otherwise infinite loop might occur
2916
+ while (m > s && b.top == 0 && b.bottom == 0) {
2917
+ m--;
2918
+ b = nodes[m].getBoundingClientRect();
2919
+ }
2920
+ while (m + 1 < e && b.top == 0 && b.bottom == 0) {
2921
+ m = m + 1;
2922
+ b = nodes[m].getBoundingClientRect();
2923
+ }
2924
+ if (b.top == 0 && b.bottom == 0) {
2925
+ s = e = m;
2926
+ break;
2927
+ }
2928
+ }
2929
+
2930
+ if (cy < b.top) e = m;
2931
+ else if (cy > b.bottom) s = m + 1;
2932
+ else {
2933
+ //hovering over a row here
2934
+ if (row) {
2935
+ let confirmed = !grid;
2936
+ if (!confirmed) {
2937
+ let insertionZone = (b.bottom - b.top) / 4;
2938
+ confirmed = cy > b.top + insertionZone && cy < b.bottom - insertionZone;
2939
+ }
2940
+ if (confirmed) {
2941
+ rowOverIndex = m;
2942
+ break;
2943
+ }
2944
+ }
2945
+
2946
+ if (cy > (b.bottom + b.top) / 2) {
2947
+ s = e = m + 1;
2948
+ nextToTheRowAbove = true;
2949
+ } else s = e = m;
2950
+ }
2951
+ }
2952
+
2953
+ let cancel = false;
2954
+
2955
+ if (rowOverIndex != null) {
2956
+ let evt = {
2957
+ ...ev,
2958
+ target: {
2959
+ record: this.getRecordAt(rowOverIndex),
2960
+ index: start + rowOverIndex,
2961
+ },
2962
+ };
2963
+ if (widget.onRowDragOver && instance.invoke("onRowDragOver", evt, instance) === false) cancel = true;
2964
+ else if (rowOverIndex != this.state.dropInsertionIndex || this.state.dropTarget != "row") {
2965
+ this.setState({
2966
+ dropInsertionIndex: rowOverIndex,
2967
+ dropNextToTheRowAbove: false,
2968
+ dropItemHeight: ev.source.height - 1,
2969
+ dropTarget: "row",
2970
+ });
2971
+ }
2972
+ } else if (grid) {
2973
+ let evt = {
2974
+ ...ev,
2975
+ target: {
2976
+ recordBefore: this.getRecordAt(s - 1),
2977
+ recordAfter: this.getRecordAt(s),
2978
+ insertionIndex: start + s,
2979
+ totalRecordCount: data.totalRecordCount,
2980
+ },
2981
+ };
2982
+ if (widget.onDragOver && instance.invoke("onDragOver", evt, instance) === false) cancel = true;
2983
+ else if (s != this.state.dropInsertionIndex || this.state.dropTarget != "grid") {
2984
+ this.setState({
2985
+ dropInsertionIndex: s,
2986
+ dropNextToTheRowAbove: nextToTheRowAbove,
2987
+ dropItemHeight: ev.source.height - 1,
2988
+ dropTarget: "grid",
2989
+ });
2990
+ }
2991
+ }
2992
+ if (cancel) {
2993
+ this.setState({
2994
+ dropInsertionIndex: null,
2995
+ dropNextToTheRowAbove: null,
2996
+ dropTarget: null,
2997
+ });
2998
+ }
2999
+ }
3000
+
3001
+ onDragLeave(e: DragEvent) {
3002
+ this.setState({
3003
+ dropInsertionIndex: null,
3004
+ dropNextToTheRowAbove: null,
3005
+ dropTarget: null,
3006
+ });
3007
+ }
3008
+
3009
+ onGetHScrollParent() {
3010
+ let { widget } = this.props.instance;
3011
+ if (widget.scrollable) return this.dom.scroller!;
3012
+ return findScrollableParent(this.dom.table!, true);
3013
+ }
3014
+
3015
+ onGetVScrollParent({ test: { grid, row, column } }: GridDropOperationContext) {
3016
+ if (column && !grid && !row) return null;
3017
+ let { widget } = this.props.instance;
3018
+ if (widget.scrollable) return this.dom.scroller!;
3019
+ return findScrollableParent(this.dom.table!);
3020
+ }
3021
+
3022
+ UNSAFE_componentWillReceiveProps(props: GridComponentProps) {
3023
+ let { data, widget } = props.instance;
3024
+ if (this.state.cursor >= data.totalRecordCount)
3025
+ this.setState({
3026
+ cursor: data.totalRecordCount - 1,
3027
+ });
3028
+ else if (widget.selectable && this.state.focused && this.state.cursor < 0)
3029
+ this.setState({
3030
+ cursor: 0,
3031
+ });
3032
+ }
3033
+
3034
+ componentWillUnmount() {
3035
+ let { instance } = this.props;
3036
+ let { widget } = instance;
3037
+ if (this.offResize) this.offResize();
3038
+
3039
+ offFocusOut(this);
3040
+
3041
+ if (this.unregisterDropZone) this.unregisterDropZone();
3042
+
3043
+ if (widget.pipeKeyDown) instance.invoke("pipeKeyDown", null, instance);
3044
+
3045
+ if (this.dom.fixedScroller!) {
3046
+ this.dom.fixedScroller!.removeEventListener("wheel", this.onFixedColumnsWheel);
3047
+ }
3048
+ }
3049
+
3050
+ estimateHeight(
3051
+ records: MappedGridRecord[],
3052
+ start: number,
3053
+ end: number,
3054
+ breakCondition?: (index: number, totalHeight: number) => boolean,
3055
+ ) {
3056
+ let avgDataRowHeight = this.heightStats!.estimate("data") ?? 0;
3057
+ let totalHeight = 0;
3058
+ for (let i = start; i < end; i++) {
3059
+ let record = records[i];
3060
+ switch (record.type) {
3061
+ case "data":
3062
+ if (record.key in this.rowHeights!) totalHeight += this.rowHeights![record.key];
3063
+ else totalHeight += avgDataRowHeight;
3064
+ break;
3065
+
3066
+ case "group-header":
3067
+ if (record.grouping.showCaption) {
3068
+ let captionKey = "group-caption-" + record.level;
3069
+ if (`${captionKey}-${record.group.$key}` in this.rowHeights!)
3070
+ totalHeight += this.rowHeights![`${captionKey}-${record.group.$key}`];
3071
+ else totalHeight += this.heightStats!.estimate(captionKey) ?? avgDataRowHeight;
3072
+ }
3073
+ break;
3074
+
3075
+ case "group-footer":
3076
+ if (record.grouping.showFooter) {
3077
+ let captionKey = "group-footer-" + record.level;
3078
+ if (`${captionKey}-${record.group.$key}` in this.rowHeights!)
3079
+ totalHeight += this.rowHeights![`${captionKey}-${record.group.$key}`];
3080
+ else totalHeight += this.heightStats!.estimate(captionKey) ?? avgDataRowHeight;
3081
+ }
3082
+ break;
3083
+
3084
+ default:
3085
+ Console.warn("UNPROCESSED RECORD TYPE", record);
3086
+ break;
3087
+ }
3088
+
3089
+ if (breakCondition && breakCondition(i, totalHeight) === false) break;
3090
+ }
3091
+ return totalHeight;
3092
+ }
3093
+
3094
+ estimateStart(records: MappedGridRecord[], height: number) {
3095
+ let start = 0;
3096
+ if (height == 0) return 0;
3097
+ this.estimateHeight(records, 0, records.length, (index, h) => {
3098
+ start = index;
3099
+ return h < height;
3100
+ });
3101
+ return start;
3102
+ }
3103
+
3104
+ componentDidUpdate() {
3105
+ let { instance, data } = this.props;
3106
+ let { widget, fixedFooterOverlap } = instance;
3107
+
3108
+ if (
3109
+ widget.lockColumnWidths &&
3110
+ isArray(data.records) &&
3111
+ data.records.length >= widget.lockColumnWidthsRequiredRowCount
3112
+ ) {
3113
+ let headerTBody = this.dom.table!.firstChild! as HTMLElement;
3114
+ for (let r = 0; r < headerTBody.children.length; r++) {
3115
+ let sr = headerTBody.children[r];
3116
+ for (let c = 0; c < sr.children.length; c++) {
3117
+ let cell = sr.children[c] as HTMLElement;
3118
+ cell.style.width =
3119
+ cell.style.minWidth =
3120
+ cell.style.maxWidth =
3121
+ `${(sr.children[c] as HTMLElement).offsetWidth}px`;
3122
+ cell.style.boxSizing = "border-box";
3123
+ if ((cell as HTMLElement).dataset.uniqueColId)
3124
+ instance.state.lockedColWidth[(cell as HTMLElement).dataset.uniqueColId!] = (
3125
+ sr.children[c] as HTMLElement
3126
+ ).offsetWidth;
3127
+ }
3128
+ }
3129
+ }
3130
+
3131
+ if (widget.scrollable) {
3132
+ this.scrollWidth = this.dom.scroller!.offsetWidth - this.dom.scroller!.clientWidth;
3133
+
3134
+ let resized = false,
3135
+ headerHeight = 0,
3136
+ footerHeight = 0,
3137
+ rowHeight = 0;
3138
+
3139
+ if (this.dom.fixedTable!)
3140
+ syncHeaderHeights(
3141
+ this.dom.table!.firstChild as HTMLTableSectionElement,
3142
+ this.dom.fixedTable!.firstChild as HTMLTableSectionElement,
3143
+ );
3144
+
3145
+ if (this.dom.fixedHeader!) {
3146
+ let fixedHeaderTBody = this.dom.fixedHeader!.firstChild!.firstChild as HTMLTableSectionElement;
3147
+
3148
+ resized = widget.preciseMeasurements
3149
+ ? copyCellSizePrecise(this.dom.table!.firstChild as HTMLTableSectionElement, fixedHeaderTBody)
3150
+ : copyCellSize(this.dom.table!.firstChild as HTMLTableSectionElement, fixedHeaderTBody);
3151
+
3152
+ let scrollColumnEl = fixedHeaderTBody?.firstChild?.lastChild as HTMLElement | null;
3153
+ if (scrollColumnEl) scrollColumnEl.style.minWidth = scrollColumnEl.style.maxWidth = this.scrollWidth + "px";
3154
+
3155
+ this.dom.fixedHeader!.style.display = "block";
3156
+ headerHeight = this.dom.fixedHeader!.offsetHeight;
3157
+ this.dom.scroller!.style.marginTop = `${headerHeight}px`;
3158
+ if (this.dom.fixedScroller!) this.dom.fixedScroller!.style.marginTop = `${headerHeight}px`;
3159
+ else if (this.dom.fixedHeader!.style.left != null) this.dom.fixedHeader!.style.removeProperty("left");
3160
+ } else {
3161
+ this.dom.scroller!.style.removeProperty("marginTop");
3162
+ if (this.dom.fixedScroller!) this.dom.fixedScroller!.style.removeProperty("marginTop");
3163
+ }
3164
+
3165
+ if (this.dom.fixedColumnsFixedHeader!) {
3166
+ let fixedColumnsWidth = `${this.dom.fixedScroller!.offsetWidth}px`;
3167
+ this.dom.fixedColumnsFixedHeader!.style.right = "auto";
3168
+ this.dom.fixedColumnsFixedHeader!.style.width = fixedColumnsWidth;
3169
+ if (this.dom.fixedHeader!) this.dom.fixedHeader!.style.left = fixedColumnsWidth;
3170
+
3171
+ this.dom.fixedColumnsFixedHeader!.style.display = "block";
3172
+
3173
+ let fixedHeaderTBody = this.dom.fixedColumnsFixedHeader!.firstElementChild
3174
+ ?.firstElementChild as HTMLTableSectionElement;
3175
+
3176
+ if (this.dom.fixedTable!.firstChild) {
3177
+ resized = copyCellSize(
3178
+ this.dom.fixedTable!.firstElementChild as HTMLTableSectionElement,
3179
+ fixedHeaderTBody,
3180
+ );
3181
+ }
3182
+ }
3183
+
3184
+ if (this.dom.fixedFooter! || this.dom.fixedColumnsFixedFooter!) {
3185
+ if (this.dom.fixedColumnsFixedFooter!) {
3186
+ let fixedColumnsWidth = `${this.dom.fixedScroller!.offsetWidth}px`;
3187
+ this.dom.fixedColumnsFixedFooter!.style.right = "auto";
3188
+ this.dom.fixedColumnsFixedFooter!.style.width = fixedColumnsWidth;
3189
+
3190
+ let dstTableBody = this.dom.fixedColumnsFixedFooter!.firstElementChild
3191
+ ?.firstElementChild as HTMLTableSectionElement;
3192
+ if (dstTableBody) {
3193
+ let srcTableBody = this.dom.fixedTable!.lastElementChild as HTMLTableSectionElement;
3194
+ copyCellSize(srcTableBody, dstTableBody, fixedFooterOverlap);
3195
+ this.dom.fixedColumnsFixedFooter!.style.display = "block";
3196
+ footerHeight = this.dom.fixedFooter!.offsetHeight;
3197
+ }
3198
+ }
3199
+
3200
+ if (this.dom.fixedFooter!) {
3201
+ let dstTableBody = this.dom.fixedFooter!.firstElementChild?.firstElementChild as HTMLTableSectionElement;
3202
+
3203
+ if (dstTableBody) {
3204
+ let srcTableBody = this.dom.table!.lastElementChild as HTMLTableSectionElement;
3205
+
3206
+ copyCellSize(srcTableBody, dstTableBody, fixedFooterOverlap);
3207
+
3208
+ let scrollColumnEl = dstTableBody.firstElementChild?.firstElementChild as HTMLElement;
3209
+ if (scrollColumnEl)
3210
+ scrollColumnEl.style.minWidth = scrollColumnEl.style.maxWidth = this.scrollWidth + "px";
3211
+
3212
+ this.dom.fixedFooter!.style.display = "block";
3213
+ footerHeight = this.dom.fixedFooter!.offsetHeight;
3214
+ }
3215
+
3216
+ if (this.dom.fixedScroller!)
3217
+ this.dom.fixedFooter!.style.left = `${this.dom.fixedScroller!.offsetWidth}px`;
3218
+ else if (this.dom.fixedFooter!.style.left != null) this.dom.fixedFooter!.style.removeProperty("left");
3219
+ }
3220
+
3221
+ this.dom.scroller!.style.marginBottom = `${footerHeight}px`;
3222
+ if (this.dom.fixedScroller!) this.dom.fixedScroller!.style.marginBottom = `${footerHeight}px`;
3223
+ } else {
3224
+ this.dom.scroller!.style.marginBottom = "0";
3225
+ if (this.dom.fixedScroller!) this.dom.fixedScroller!.style.marginBottom = "0";
3226
+ }
3227
+
3228
+ let scrollOverlap = fixedFooterOverlap ? footerHeight : 0;
3229
+
3230
+ if (widget.buffered) {
3231
+ let { start, end } = this.getBufferStartEnd();
3232
+ let remaining = 0,
3233
+ count = Math.min(data.totalRecordCount, end! - start!);
3234
+
3235
+ if (widget.measureRowHeights) {
3236
+ if (!this.rowHeights) this.rowHeights = {};
3237
+ if (!this.heightStats) this.heightStats = new AvgHeight();
3238
+ for (let i = 0; i < this.dom.table!.children.length; i++) {
3239
+ let body = this.dom.table!.children[i] as HTMLElement;
3240
+ if (body.dataset.recordKey != null) {
3241
+ if (!(body.dataset.recordKey in this.rowHeights)) this.heightStats.add("data", body.offsetHeight);
3242
+ this.rowHeights[body.dataset.recordKey] = body.offsetHeight;
3243
+ } else if (body.dataset.groupKey) {
3244
+ let key = body.dataset.groupElement + "-" + body.dataset.groupKey;
3245
+ this.rowHeights[key] = body.offsetHeight;
3246
+ if (!(body.dataset.recordKey! in this.rowHeights))
3247
+ this.heightStats.add(body.dataset.groupElement!, body.offsetHeight);
3248
+ }
3249
+ }
3250
+ }
3251
+
3252
+ if (count > 0) {
3253
+ //do not change row height while a drag-drop operation is in place
3254
+ rowHeight = this.state.dragged
3255
+ ? this.rowHeight!
3256
+ : Math.round((this.dom.table!.offsetHeight - headerHeight) / count);
3257
+ // if (this.rowHeight && this.rowHeight != rowHeight) {
3258
+ // console.warn("ROW-HEIGHT-CHANGE", this.rowHeight, rowHeight);
3259
+ // }
3260
+ remaining = Math.max(0, data.totalRecordCount - end);
3261
+ }
3262
+
3263
+ let upperMargin = 0,
3264
+ lowerMargin = 0;
3265
+ if (widget.measureRowHeights && instance.records) {
3266
+ upperMargin = this.estimateHeight(instance.records, 0, start);
3267
+ lowerMargin = this.estimateHeight(instance.records, end, instance.records.length);
3268
+ } else {
3269
+ upperMargin = start * rowHeight;
3270
+ lowerMargin = remaining * rowHeight;
3271
+ }
3272
+
3273
+ //console.log(upperMargin, start * rowHeight, this.rowHeights, this.heightStats);
3274
+
3275
+ this.dom.table!.style.marginTop = `${(-headerHeight + upperMargin).toFixed(0)}px`;
3276
+ this.dom.table!.style.marginBottom = `${(lowerMargin - scrollOverlap).toFixed(0)}px`;
3277
+ } else {
3278
+ this.dom.table!.style.marginTop = `${-headerHeight}px`;
3279
+ this.dom.table!.style.marginBottom = `${-scrollOverlap}px`;
3280
+ }
3281
+
3282
+ if (this.dom.fixedTable!) {
3283
+ this.dom.fixedTable!.style.marginTop = this.dom.table!.style.marginTop;
3284
+ this.dom.fixedTable!.style.marginBottom = this.dom.table!.style.marginBottom;
3285
+ }
3286
+
3287
+ this.rowHeight = rowHeight;
3288
+
3289
+ let sortersChanged = widget.infinite && !shallowEquals(data.sorters, this.lastSorters);
3290
+
3291
+ if (data.empty && !widget.infinite) {
3292
+ this.dom.scroller!.scrollTop = 0;
3293
+ }
3294
+
3295
+ if (
3296
+ sortersChanged ||
3297
+ data.filterParams !== this.lastScrollFilterParams ||
3298
+ data.scrollResetParams !== this.lastScrollResetParams
3299
+ ) {
3300
+ this.dom.scroller!.scrollTop = 0;
3301
+ this.lastScrollFilterParams = data.filterParams;
3302
+ this.lastScrollResetParams = data.scrollResetParams;
3303
+ this.lastSorters = data.sorters;
3304
+ if (widget.infinite) {
3305
+ this.loadingStartPage = 0;
3306
+ this.loadingEndPage = 0;
3307
+ instance.buffer.records = data.records = [];
3308
+ instance.buffer.totalRecordCount = 0;
3309
+ instance.buffer.page = 1;
3310
+ this.prevFetchRecordsState = null;
3311
+ this.loading = false;
3312
+ }
3313
+ }
3314
+
3315
+ if (widget.scrollSelectionIntoView && !widget.buffered) {
3316
+ let { CSS, baseClass } = widget;
3317
+ let selectedRowSelector = `.${CSS.element(baseClass, "data")}.${CSS.state("selected")}`;
3318
+ let firstSelectedRow = this.dom.table!.querySelector(selectedRowSelector);
3319
+ if (firstSelectedRow != this.selectedEl) {
3320
+ firstSelectedRow && scrollElementIntoView(firstSelectedRow);
3321
+ this.selectedEl = firstSelectedRow;
3322
+ }
3323
+ }
3324
+
3325
+ setTimeout(this.onScroll.bind(this), 0);
3326
+
3327
+ if (resized) instance.fixedHeaderResizeEvent.notify();
3328
+ }
3329
+ }
3330
+
3331
+ moveCursor(
3332
+ index: number,
3333
+ {
3334
+ focused,
3335
+ hover,
3336
+ scrollIntoView,
3337
+ select,
3338
+ selectRange,
3339
+ selectOptions,
3340
+ cellIndex,
3341
+ cellEdit,
3342
+ cancelEdit,
3343
+ }: GridMoveCursorOptions = {},
3344
+ ) {
3345
+ let { widget, visibleColumns } = this.props.instance;
3346
+ if (!widget.selectable && !widget.cellEditable) return;
3347
+
3348
+ let newState: Partial<GridComponentState> = {};
3349
+
3350
+ if (cellEdit != null && cellEdit != this.state.cellEdit) {
3351
+ newState.cellEdit = cellEdit;
3352
+ if (
3353
+ cellEdit &&
3354
+ (!visibleColumns[this.state.cursorCellIndex] || !visibleColumns[this.state.cursorCellIndex].editor)
3355
+ )
3356
+ newState.cellEdit = false;
3357
+ }
3358
+
3359
+ if (cellIndex != null && cellIndex != this.state.cursorCellIndex) {
3360
+ newState.cursorCellIndex = cellIndex;
3361
+ newState.cellEdit = false;
3362
+ }
3363
+
3364
+ if (widget.focused) focused = true;
3365
+
3366
+ if (focused != null && this.state.focused != focused) {
3367
+ newState.focused = focused;
3368
+ newState.cellEdit = false;
3369
+ }
3370
+
3371
+ if (index != this.state.cursor) {
3372
+ newState.cursor = index;
3373
+ newState.cellEdit = false;
3374
+ }
3375
+
3376
+ batchUpdates(() => {
3377
+ if (select) {
3378
+ let start =
3379
+ selectRange && this.state.selectionStart != null && this.state.selectionStart >= 0
3380
+ ? this.state.selectionStart
3381
+ : index;
3382
+ if (start < 0) start = index;
3383
+ this.selectRange(start!, index, selectOptions);
3384
+ if (!selectRange) newState.selectionStart = index;
3385
+ }
3386
+
3387
+ if (Object.keys(newState).length > 0) {
3388
+ let prevState = this.state;
3389
+ let wasCellEditing = prevState.focused && prevState.cellEdit;
3390
+ let futureState = { ...this.state, ...newState };
3391
+
3392
+ if (!futureState.cellEdit && wasCellEditing) {
3393
+ // If cell editing is in progress, moving the cursor may cause that the cell editor to unmount before
3394
+ // the blur event which may cause data loss for components which do not have reactOn=change set, e.g. NumberField.
3395
+ unfocusElement(null, false);
3396
+ let record = this.getRecordAt(prevState.cursor)!;
3397
+ if ((!this.cellEditorValid || cancelEdit) && this.cellEditUndoData)
3398
+ record.store.set(widget.recordName, this.cellEditUndoData);
3399
+ else {
3400
+ let newData = record.store.get(widget.recordName); //record.data might be stale at this point
3401
+ if (widget.onCellEdited && newData != this.cellEditUndoData) {
3402
+ this.props.instance.invoke(
3403
+ "onCellEdited",
3404
+ {
3405
+ column: visibleColumns[prevState.cursorCellIndex],
3406
+ newData,
3407
+ oldData: this.cellEditUndoData,
3408
+ field: visibleColumns[prevState.cursorCellIndex].field,
3409
+ },
3410
+ record,
3411
+ );
3412
+ this.cellEditUndoData = newData;
3413
+ }
3414
+ }
3415
+ }
3416
+
3417
+ if (futureState.cellEdit && !wasCellEditing) {
3418
+ let record = this.getRecordAt(futureState.cursor)!;
3419
+ let cellEditUndoData = record.data;
3420
+
3421
+ if (
3422
+ widget.onBeforeCellEdit &&
3423
+ this.props.instance.invoke(
3424
+ "onBeforeCellEdit",
3425
+ {
3426
+ column: visibleColumns[futureState.cursorCellIndex],
3427
+ data: cellEditUndoData,
3428
+ field: visibleColumns[futureState.cursorCellIndex].field,
3429
+ },
3430
+ record,
3431
+ ) === false
3432
+ )
3433
+ return;
3434
+
3435
+ this.cellEditUndoData = cellEditUndoData;
3436
+ }
3437
+
3438
+ this.setState(newState as any, () => {
3439
+ if (this.state.focused && !this.state.cellEdit && wasCellEditing) FocusManager.focus(this.dom.el!);
3440
+
3441
+ if (scrollIntoView) {
3442
+ let record = this.getRecordAt(index)!;
3443
+
3444
+ let item = record && this.dom.table!.querySelector(`tbody[data-record-key="${record.key}"]`);
3445
+
3446
+ let hscroll = false;
3447
+ if (item) {
3448
+ if (widget.cellEditable)
3449
+ if (this.state.cursorCellIndex >= this.props.instance.fixedColumnCount) {
3450
+ hscroll = true;
3451
+ item = (item.firstChild as HTMLElement)!.children[
3452
+ this.state.cursorCellIndex - this.props.instance.fixedColumnCount
3453
+ ] as Element;
3454
+ } else {
3455
+ let fixedItem = this.dom.fixedTable!.querySelector(`tbody[data-record-key="${record.key}"]`);
3456
+ let cell =
3457
+ fixedItem && (fixedItem.firstChild as HTMLElement)!.children[this.state.cursorCellIndex];
3458
+ if (cell) scrollElementIntoView(cell, false, true, 10);
3459
+ }
3460
+
3461
+ scrollElementIntoView(item!, true, hscroll, widget.cellEditable ? 10 : 0);
3462
+ }
3463
+ }
3464
+ });
3465
+ }
3466
+ });
3467
+ }
3468
+
3469
+ showCursor(focused?: boolean) {
3470
+ let { records, isSelected } = this.props.instance;
3471
+ let cursor = this.state.cursor;
3472
+ if (cursor == -1) {
3473
+ if (records) {
3474
+ cursor = records.findIndex((x) => isSelected(x.data, x.index));
3475
+ //if there are no selected records, find the first data record (skip group header)
3476
+ if (cursor == -1) cursor = records.findIndex((x) => x.type == "data");
3477
+ } else cursor = 0;
3478
+ }
3479
+ this.moveCursor(cursor, { focused: true, scrollIntoView: false });
3480
+ }
3481
+
3482
+ onFocus() {
3483
+ FocusManager.nudge();
3484
+
3485
+ //focus moved within the grid
3486
+ if (this.state.focused) {
3487
+ if (this.state.cellEdit && this.dom.el! == getActiveElement())
3488
+ this.moveCursor(this.state.cursor, {
3489
+ cellEdit: false,
3490
+ });
3491
+ return;
3492
+ }
3493
+
3494
+ let { widget } = this.props.instance;
3495
+
3496
+ //the cursor will be set if focus in originating from a mouse event
3497
+ setTimeout(() => {
3498
+ this.showCursor(true);
3499
+ }, 0);
3500
+
3501
+ if (!widget.focused) {
3502
+ if (this.dom.el!) {
3503
+ //if an inner element is focused first (autoFocus), this.dom.el! might be undefined
3504
+ oneFocusOut(this, this.dom.el!, () => {
3505
+ this.moveCursor(-1, { focused: false });
3506
+ });
3507
+ }
3508
+ }
3509
+
3510
+ this.setState({
3511
+ focused: true,
3512
+ });
3513
+ }
3514
+
3515
+ onBlur() {
3516
+ FocusManager.nudge();
3517
+ }
3518
+
3519
+ selectRange(from: number, to: number, options?: any) {
3520
+ let { instance, data } = this.props;
3521
+ let { records, widget } = instance;
3522
+
3523
+ if (from > to) {
3524
+ let tmp = from;
3525
+ from = to;
3526
+ to = tmp;
3527
+ }
3528
+
3529
+ options = {
3530
+ ...options,
3531
+ range: from < to,
3532
+ };
3533
+
3534
+ let selection = [],
3535
+ indexes = [];
3536
+
3537
+ for (let cursor = from; cursor <= to; cursor++) {
3538
+ let record;
3539
+ if (records) record = records[cursor];
3540
+ else {
3541
+ let offset = widget.infinite ? data.offset : 0;
3542
+ let r = data.records[cursor - offset];
3543
+ if (r) record = widget.mapRecord(null!, instance, r, cursor - offset);
3544
+ }
3545
+ if (record && record.type == "data") {
3546
+ if (instance.isRecordSelectable && !instance.isRecordSelectable(record.data, options)) continue;
3547
+ selection.push(record.data);
3548
+ indexes.push(record.index);
3549
+ }
3550
+ }
3551
+
3552
+ widget.selection.selectMultiple(instance.store, selection, indexes, options);
3553
+ }
3554
+
3555
+ getDataRecordAt(index: number): MappedGridRecord | undefined {
3556
+ let { records } = this.props.instance;
3557
+ if (!records) return this.getRecordAt(index);
3558
+ let dataRecords = records.filter((r) => r.type == "data");
3559
+ return dataRecords[index];
3560
+ }
3561
+
3562
+ getRecordAt(cursor: number): MappedGridRecord | undefined {
3563
+ let { instance, data } = this.props;
3564
+ let { records, widget } = instance;
3565
+
3566
+ if (records) return records[cursor];
3567
+
3568
+ let offset = widget.infinite ? data.offset : 0;
3569
+ let r = data.records[cursor - offset];
3570
+ if (r) return widget.mapRecord(null!, instance, r, cursor - offset);
3571
+
3572
+ return undefined;
3573
+ }
3574
+
3575
+ getRecordInstanceAt(cursor: number) {
3576
+ let record = this.getRecordAt(cursor);
3577
+ if (!record) return null;
3578
+ let { instance } = this.props;
3579
+ if (instance.recordInstanceCache)
3580
+ return instance.recordInstanceCache.getChild(instance.row, record.store, record.key);
3581
+
3582
+ //different signature
3583
+ return instance.getChild(null, instance.row, record.key, record.store);
3584
+ }
3585
+
3586
+ handleKeyDown(e: React.KeyboardEvent) {
3587
+ let { instance, data } = this.props;
3588
+ let { widget } = instance;
3589
+
3590
+ if (widget.onKeyDown && instance.invoke("onKeyDown", e, instance) === false) return;
3591
+
3592
+ let recordInstance = this.getRecordInstanceAt(this.state.cursor);
3593
+ if (recordInstance && widget.onRowKeyDown && instance.invoke("onRowKeyDown", e, recordInstance) === false) return;
3594
+
3595
+ if (widget.onCellKeyDown && widget.cellEditable && this.state.cursorCellIndex != -1) {
3596
+ if (
3597
+ instance.invoke("onCellKeyDown", e, instance, {
3598
+ cellIndex: this.state.cursorCellIndex,
3599
+ record: recordInstance,
3600
+ }) === false
3601
+ )
3602
+ return;
3603
+ }
3604
+
3605
+ switch (e.keyCode) {
3606
+ case KeyCode.enter:
3607
+ this.moveCursor(this.state.cursor, {
3608
+ select: true,
3609
+ selectOptions: {
3610
+ toggle: e.ctrlKey && !e.shiftKey,
3611
+ add: e.ctrlKey && e.shiftKey,
3612
+ },
3613
+ selectRange: e.shiftKey,
3614
+ cellEdit: widget.cellEditable && !this.state.cellEdit,
3615
+ focused: true,
3616
+ });
3617
+ e.stopPropagation();
3618
+ e.preventDefault();
3619
+ break;
3620
+
3621
+ case KeyCode.esc:
3622
+ if (this.state.cellEdit) {
3623
+ this.moveCursor(this.state.cursor, {
3624
+ cellEdit: false,
3625
+ focused: true,
3626
+ cancelEdit: true,
3627
+ });
3628
+ e.stopPropagation();
3629
+ e.preventDefault();
3630
+ }
3631
+ break;
3632
+
3633
+ case KeyCode.tab:
3634
+ if (widget.cellEditable) {
3635
+ e.stopPropagation();
3636
+ e.preventDefault();
3637
+ let direction = e.shiftKey ? -1 : +1;
3638
+ let cursor = this.state.cursor;
3639
+ let cellIndex = (this.state.cursorCellIndex + direction) % instance.row.line1.columns.length;
3640
+ if (cellIndex == -1) {
3641
+ cellIndex += instance.row.line1.columns.length;
3642
+ cursor--;
3643
+ } else if (cellIndex == 0 && direction > 0) cursor++;
3644
+ for (; ; cursor += direction) {
3645
+ let record = this.getRecordAt(cursor);
3646
+ if (!record) break;
3647
+ if (record.type != "data") continue;
3648
+ this.moveCursor(cursor, {
3649
+ focused: true,
3650
+ cellIndex,
3651
+ scrollIntoView: true,
3652
+ cellEdit: false,
3653
+ });
3654
+ break;
3655
+ }
3656
+ }
3657
+ break;
3658
+
3659
+ case KeyCode.down:
3660
+ for (let cursor = this.state.cursor + 1; ; cursor++) {
3661
+ let record = this.getRecordAt(cursor);
3662
+ if (!record) break;
3663
+ if (record.type != "data") continue;
3664
+ this.moveCursor(cursor, {
3665
+ focused: true,
3666
+ scrollIntoView: true,
3667
+ select: e.shiftKey,
3668
+ selectRange: e.shiftKey,
3669
+ });
3670
+ break;
3671
+ }
3672
+ e.stopPropagation();
3673
+ e.preventDefault();
3674
+ break;
3675
+
3676
+ case KeyCode.up:
3677
+ for (let cursor = this.state.cursor - 1; cursor >= 0; cursor--) {
3678
+ let record = this.getRecordAt(cursor);
3679
+ if (!record) break;
3680
+ if (record.type != "data") continue;
3681
+ this.moveCursor(cursor, {
3682
+ focused: true,
3683
+ scrollIntoView: true,
3684
+ select: e.shiftKey,
3685
+ selectRange: e.shiftKey,
3686
+ });
3687
+ break;
3688
+ }
3689
+ e.stopPropagation();
3690
+ e.preventDefault();
3691
+ break;
3692
+
3693
+ case KeyCode.right:
3694
+ if (widget.cellEditable) {
3695
+ if (this.state.cursorCellIndex + 1 < instance.row.line1.columns.length) {
3696
+ this.moveCursor(this.state.cursor, {
3697
+ focused: true,
3698
+ cellIndex: this.state.cursorCellIndex + 1,
3699
+ scrollIntoView: true,
3700
+ });
3701
+ }
3702
+ e.stopPropagation();
3703
+ e.preventDefault();
3704
+ }
3705
+ break;
3706
+
3707
+ case KeyCode.left:
3708
+ if (widget.cellEditable) {
3709
+ if (this.state.cursorCellIndex > 0) {
3710
+ this.moveCursor(this.state.cursor, {
3711
+ focused: true,
3712
+ cellIndex: this.state.cursorCellIndex - 1,
3713
+ scrollIntoView: true,
3714
+ });
3715
+ }
3716
+ e.stopPropagation();
3717
+ e.preventDefault();
3718
+ }
3719
+ break;
3720
+
3721
+ case KeyCode.a:
3722
+ if (!e.ctrlKey || !widget.selection.multiple) return;
3723
+
3724
+ if (isTextInputElement(e.target as Element)) return;
3725
+
3726
+ this.selectRange(0, data.totalRecordCount);
3727
+
3728
+ e.stopPropagation();
3729
+ e.preventDefault();
3730
+ break;
3731
+ }
3732
+ }
3733
+
3734
+ beginDragDrop(e: React.MouseEvent, record: MappedGridRecord) {
3735
+ let { instance, data } = this.props;
3736
+ let { widget, store } = instance;
3737
+ let { isRecordDraggable } = instance;
3738
+
3739
+ if (isRecordDraggable && !isRecordDraggable(record.data)) return;
3740
+
3741
+ //get a fresh isSelected delegate
3742
+ let isSelected = widget.selection.getIsSelectedDelegate(store);
3743
+
3744
+ let selected: MappedGridRecord[] = [];
3745
+
3746
+ let add = (rec: MappedGridRecord | null, data: any, index: number, force?: boolean) => {
3747
+ if (!data || !(force || isSelected(data, index)) || (isRecordDraggable && !isRecordDraggable(data))) return;
3748
+ let mappedRecord = rec ? { ...rec } : (widget.mapRecord(null!, instance, data, index) as MappedGridRecord);
3749
+ let row = (mappedRecord.row = instance.getDetachedChild(
3750
+ instance.row,
3751
+ "DD:" + mappedRecord.key,
3752
+ mappedRecord.store,
3753
+ ) as GridRowInstance);
3754
+ row.selected = true;
3755
+ selected.push(mappedRecord);
3756
+ };
3757
+
3758
+ if (!record.row?.selected) {
3759
+ if (instance.records) instance.records.forEach((r) => add(r, r.data, r.index!));
3760
+ else this.getRecordsSlice(0, data.totalRecordCount).forEach((r, index) => add(null, r, index));
3761
+ }
3762
+
3763
+ if (selected.length == 0) add(record, record.data, record.index!, true);
3764
+
3765
+ let renderRow = this.createRowRenderer(false);
3766
+
3767
+ let contents = selected.map((record, i) => ({
3768
+ type: StaticText,
3769
+ text: renderRow(record, i, true, false),
3770
+ }));
3771
+
3772
+ initiateDragDrop(
3773
+ e,
3774
+ {
3775
+ sourceEl: closest(e.currentTarget, (a) => a.tagName == "TBODY"),
3776
+ source: {
3777
+ data: data.dragSource.data,
3778
+ store: store,
3779
+ record: record,
3780
+ records: selected,
3781
+ },
3782
+ clone: {
3783
+ store: record.store,
3784
+ matchCursorOffset: true,
3785
+ matchWidth: true,
3786
+ widget: {
3787
+ type: HtmlElement,
3788
+ tag: "div",
3789
+ className: data.classNames,
3790
+ children: [
3791
+ {
3792
+ type: HtmlElement,
3793
+ tag: "table",
3794
+ children: contents,
3795
+ },
3796
+ ],
3797
+ },
3798
+ },
3799
+ },
3800
+ () => {
3801
+ this.setState({
3802
+ dragged: false,
3803
+ });
3804
+ },
3805
+ );
3806
+
3807
+ this.setState({
3808
+ dragged: record,
3809
+ });
3810
+ }
3811
+
3812
+ onFileDragEnter(ev: React.DragEvent) {
3813
+ if (!this.props.instance.widget.allowsFileDrops) return;
3814
+ let event = getDragDropEvent(ev, this.props.instance.store, "dragmove");
3815
+ var test = this.onDropTest(event);
3816
+ if (test) {
3817
+ ev.preventDefault();
3818
+ ev.stopPropagation();
3819
+ this.onDragStart(event);
3820
+ }
3821
+ }
3822
+ onFileDragOver(ev: React.DragEvent) {
3823
+ if (!this.props.instance.widget.allowsFileDrops) return;
3824
+ let event = getDragDropEvent(ev, this.props.instance.store, "dragmove");
3825
+ var test = this.onDropTest(event);
3826
+ if (test) {
3827
+ ev.preventDefault();
3828
+ ev.stopPropagation();
3829
+ this.onDragOver(event, { test });
3830
+ }
3831
+ }
3832
+ onFileDragLeave(ev: React.DragEvent) {
3833
+ if (!this.props.instance.widget.allowsFileDrops) return;
3834
+ if (ev.target != this.dom.el!) {
3835
+ //The dragleave event fires when the cursor leave any of the child elements.
3836
+ //We need to be sure that the cursor left the top element too.
3837
+ let el = document.elementFromPoint(ev.clientX, ev.clientY);
3838
+ if (el == this.dom.el! || this.dom.el!.contains(el)) return;
3839
+ }
3840
+ let event = getDragDropEvent(ev, this.props.instance.store, "dragmove");
3841
+ var test = this.onDropTest(event);
3842
+ if (test) {
3843
+ this.onDragLeave(event);
3844
+ }
3845
+ }
3846
+ onFileDrop(ev: React.DragEvent) {
3847
+ if (!this.props.instance.widget.allowsFileDrops) return;
3848
+ let event = getDragDropEvent(ev, this.props.instance.store, "dragdrop");
3849
+ var test = this.onDropTest(event);
3850
+ if (test) {
3851
+ ev.preventDefault();
3852
+ ev.stopPropagation();
3853
+ this.onDrop(event);
3854
+ }
3855
+ }
3856
+ }
3857
+
3858
+ export interface GridColumnHeaderLineConfig extends PureContainerConfig {
3859
+ columns?: GridColumnConfig[];
3860
+ showHeader?: BooleanProp;
3861
+ headerStyle?: StyleProp;
3862
+ headerClass?: ClassProp;
3863
+ }
3864
+
3865
+ class GridColumnHeaderLine extends PureContainerBase<GridColumnHeaderLineConfig> {
3866
+ declare columns?: GridColumnConfig[];
3867
+ declare showHeader: boolean;
3868
+ declare headerStyle?: any;
3869
+ declare headerClass?: any;
3870
+ declare className?: any;
3871
+ declare class?: any;
3872
+ declare isPureContainer: boolean;
3873
+ declare styled: boolean;
3874
+
3875
+ declareData() {
3876
+ return super.declareData(...arguments, {
3877
+ showHeader: undefined,
3878
+ });
3879
+ }
3880
+
3881
+ init() {
3882
+ this.items = Widget.create(GridColumnHeader, this.columns || []) as any;
3883
+ this.visible = this.showHeader;
3884
+ this.style = this.headerStyle;
3885
+ this.className = this.headerClass;
3886
+ this.class = null;
3887
+ super.init();
3888
+ }
3889
+
3890
+ render(context: RenderingContext, instance: Instance, key: string) {
3891
+ let { data } = instance;
3892
+ return (
3893
+ <tr key={key} className={data.classNames} style={data.style}>
3894
+ {this.renderChildren(context, instance)}
3895
+ </tr>
3896
+ );
3897
+ }
3898
+ }
3899
+
3900
+ GridColumnHeaderLine.prototype.isPureContainer = false;
3901
+ GridColumnHeaderLine.prototype.styled = true;
3902
+ GridColumnHeaderLine.prototype.showHeader = true;
3903
+ GridColumnHeaderLine.autoInit = true;
3904
+
3905
+ export interface GridColumnHeaderConfig extends WidgetConfig {
3906
+ format?: StringProp;
3907
+ width?: NumberProp;
3908
+ defaultWidth?: NumberProp;
3909
+ fixed?: BooleanProp;
3910
+ field?: string;
3911
+ sortable?: boolean;
3912
+ resizable?: boolean;
3913
+ draggable?: boolean;
3914
+ header?: StringProp | GridColumnHeaderConfig;
3915
+ header1?: StringProp | GridColumnHeaderConfig;
3916
+ header2?: StringProp | GridColumnHeaderConfig;
3917
+ header3?: StringProp | GridColumnHeaderConfig;
3918
+ footer?: any;
3919
+ caption?: any;
3920
+ aggregateField?: string;
3921
+ aggregateAlias?: string;
3922
+ pad?: boolean;
3923
+ colSpan?: NumberProp;
3924
+ }
3925
+
3926
+ class GridColumnHeader extends Widget<GridColumnHeaderConfig> {
3927
+ declare format?: any;
3928
+ declare width?: any;
3929
+ declare defaultWidth?: any;
3930
+ declare fixed?: any;
3931
+ declare field?: string;
3932
+ declare sortable?: boolean;
3933
+ declare resizable?: boolean;
3934
+ declare draggable?: boolean;
3935
+ declare header?: any;
3936
+ declare header1?: any;
3937
+ declare header2?: any;
3938
+ declare header3?: any;
3939
+ declare footer?: any;
3940
+ declare caption?: any;
3941
+ declare aggregateField?: string;
3942
+ declare aggregateAlias?: string;
3943
+ declare aggregateAliasGetter?: any;
3944
+ declare pad?: boolean;
3945
+ declare colSpan?: any;
3946
+ declare style?: any;
3947
+ declare className?: any;
3948
+ declare class?: any;
3949
+ declareData() {
3950
+ return super.declareData(...arguments, {
3951
+ format: undefined,
3952
+ width: undefined,
3953
+ defaultWidth: undefined,
3954
+ fixed: undefined,
3955
+ });
3956
+ }
3957
+
3958
+ init() {
3959
+ delete this.style;
3960
+ delete this.className;
3961
+ delete this.class;
3962
+
3963
+ if (this.header) this.header1 = this.header;
3964
+
3965
+ if (this.header1 || this.resizable || this.width || this.defaultWidth || this.sortable || this.draggable) {
3966
+ if (!isObject(this.header1))
3967
+ this.header1 = {
3968
+ text: this.header1 || "",
3969
+ };
3970
+
3971
+ if (this.resizable) this.header1.resizable = this.resizable;
3972
+
3973
+ if (this.width) this.header1.width = this.width;
3974
+
3975
+ if (this.defaultWidth) this.header1.defaultWidth = this.defaultWidth;
3976
+
3977
+ if (this.draggable) this.header1.draggable = this.draggable;
3978
+ }
3979
+
3980
+ if (this.header2 && isSelector(this.header2))
3981
+ this.header2 = {
3982
+ text: this.header2,
3983
+ };
3984
+
3985
+ if (this.header3 && isSelector(this.header3))
3986
+ this.header3 = {
3987
+ text: this.header3,
3988
+ };
3989
+
3990
+ if (!this.aggregateField && this.field) this.aggregateField = this.field;
3991
+
3992
+ if (!this.aggregateAlias) this.aggregateAlias = this.aggregateField;
3993
+ if (this.aggregateAlias) this.aggregateAliasGetter = Binding.get(this.aggregateAlias).value;
3994
+
3995
+ if (this.footer && isSelector(this.footer))
3996
+ this.footer = {
3997
+ value: this.footer,
3998
+ pad: this.pad,
3999
+ colSpan: this.colSpan,
4000
+ };
4001
+
4002
+ if (this.footer) {
4003
+ this.footer.value = getSelector(this.footer.value);
4004
+ this.footer.class = getSelector(this.footer.class);
4005
+ this.footer.style = getSelector(this.footer.style);
4006
+ this.footer.format = getSelector(this.footer.format);
4007
+ }
4008
+
4009
+ if (this.caption && isSelector(this.caption))
4010
+ this.caption = {
4011
+ value: this.caption,
4012
+ pad: this.pad,
4013
+ format: this.format,
4014
+ };
4015
+
4016
+ if (this.caption) {
4017
+ let children = this.caption.children || this.caption.items;
4018
+ if (children) {
4019
+ delete this.caption.items;
4020
+ this.caption.children = Widget.create(children);
4021
+ } else {
4022
+ this.caption.value = getSelector(this.caption.value);
4023
+ this.caption.format = getSelector(this.caption.format);
4024
+ }
4025
+ this.caption.class = getSelector(this.caption.class);
4026
+ this.caption.style = getSelector(this.caption.style);
4027
+ }
4028
+
4029
+ super.init();
4030
+ }
4031
+
4032
+ initComponents() {
4033
+ return super.initComponents({
4034
+ header1: this.header1 && GridColumnHeaderCell.create(this.header1),
4035
+ header2: this.header2 && GridColumnHeaderCell.create(this.header2),
4036
+ header3: this.header3 && GridColumnHeaderCell.create(this.header3),
4037
+ });
4038
+ }
4039
+
4040
+ render() {
4041
+ return null;
4042
+ }
4043
+ }
4044
+
4045
+ GridColumnHeader.autoInit = true;
4046
+
4047
+ export interface GridColumnHeaderCellConfig extends PureContainerConfig {
4048
+ text?: StringProp;
4049
+ colSpan?: NumberProp;
4050
+ rowSpan?: NumberProp;
4051
+ width?: NumberProp;
4052
+ defaultWidth?: NumberProp;
4053
+ resizable?: BooleanProp;
4054
+ fixed?: BooleanProp;
4055
+ draggable?: BooleanProp;
4056
+ tool?: any;
4057
+ allowSorting?: boolean;
4058
+ }
4059
+
4060
+ class GridColumnHeaderCell extends PureContainerBase<GridColumnHeaderCellConfig> {
4061
+ declare text?: any;
4062
+ declare colSpan?: any;
4063
+ declare rowSpan?: any;
4064
+ declare width?: any;
4065
+ declare defaultWidth?: any;
4066
+ declare resizable?: any;
4067
+ declare fixed?: any;
4068
+ declare draggable?: any;
4069
+ declare tool?: any;
4070
+ declare allowSorting?: boolean;
4071
+
4072
+ declareData() {
4073
+ return super.declareData(...arguments, {
4074
+ text: undefined,
4075
+ colSpan: undefined,
4076
+ rowSpan: undefined,
4077
+ width: undefined,
4078
+ defaultWidth: undefined,
4079
+ resizable: undefined,
4080
+ fixed: undefined,
4081
+ draggable: undefined,
4082
+ });
4083
+ }
4084
+
4085
+ initComponents() {
4086
+ return super.initComponents(...arguments, {
4087
+ tool: this.tool && Widget.create(this.tool),
4088
+ });
4089
+ }
4090
+
4091
+ render(context: RenderingContext, instance: Instance, key: string) {
4092
+ let { data } = instance;
4093
+ return data.text || super.render(context, instance, key);
4094
+ }
4095
+ }
4096
+
4097
+ GridColumnHeaderCell.prototype.colSpan = 1;
4098
+ GridColumnHeaderCell.prototype.rowSpan = 1;
4099
+ GridColumnHeaderCell.prototype.allowSorting = true;
4100
+ GridColumnHeaderCell.prototype.styled = true;
4101
+ GridColumnHeaderCell.prototype.fixed = false;
4102
+
4103
+ // function initGrouping(grouping) {
4104
+ // grouping.forEach((g) => {
4105
+ // if (g.caption) g.caption = getSelector(g.caption);
4106
+ // });
4107
+ // }
4108
+
4109
+ function copyCellSize(
4110
+ srcTableBody: HTMLTableSectionElement,
4111
+ dstTableBody: HTMLTableSectionElement,
4112
+ applyHeight = true,
4113
+ ) {
4114
+ if (!srcTableBody || !dstTableBody) return false;
4115
+
4116
+ let changed = false;
4117
+ for (let r = 0; r < dstTableBody.children.length && r < srcTableBody.children.length; r++) {
4118
+ let sr = srcTableBody.children[r];
4119
+ let dr = dstTableBody.children[r];
4120
+ for (let c = 0; c < dr.children.length && c < sr.children.length; c++) {
4121
+ let dc = dr.children[c] as HTMLElement;
4122
+ let sc = sr.children[c] as HTMLElement;
4123
+ let ws = `${sc.offsetWidth}px`;
4124
+ if (!changed && dc.style.width != ws) changed = true;
4125
+ dc.style.width = dc.style.minWidth = dc.style.maxWidth = ws;
4126
+ if (applyHeight) dc.style.height = `${sc.offsetHeight}px`;
4127
+ }
4128
+ }
4129
+ return changed;
4130
+ }
4131
+
4132
+ function copyCellSizePrecise(
4133
+ srcTableBody: HTMLTableSectionElement,
4134
+ dstTableBody: HTMLTableSectionElement,
4135
+ applyHeight = true,
4136
+ ) {
4137
+ if (!srcTableBody || !dstTableBody) return false;
4138
+ let changed = false;
4139
+ for (let r = 0; r < dstTableBody.children.length && r < srcTableBody.children.length; r++) {
4140
+ let sr = srcTableBody.children[r];
4141
+ let dr = dstTableBody.children[r];
4142
+ for (let c = 0; c < dr.children.length && c < sr.children.length; c++) {
4143
+ let dc = dr.children[c] as HTMLElement;
4144
+ let sc = sr.children[c] as HTMLElement;
4145
+ let bounds = sc.getBoundingClientRect();
4146
+ let ws = `${bounds.width}px`;
4147
+ if (!changed && dc.style.width != ws) changed = true;
4148
+ dc.style.width = dc.style.minWidth = dc.style.maxWidth = ws;
4149
+ if (applyHeight) dc.style.height = `${bounds.height}px`;
4150
+ }
4151
+ }
4152
+ return changed;
4153
+ }
4154
+
4155
+ function syncHeaderHeights(header1: HTMLElement, header2: HTMLElement) {
4156
+ /**
4157
+ * In the first pass measure all row heights.
4158
+ * In the second pass apply those heights.
4159
+ * Use getBoundingClientRect() for sub-pixel accuracy.
4160
+ */
4161
+
4162
+ if (!header1 || !header2) return;
4163
+ const rowCount = Math.max(header1.children.length, header2.children.length);
4164
+ let rowHeight = [];
4165
+ for (let r = 0; r < rowCount; r++) {
4166
+ rowHeight.push(0);
4167
+ let tr1 = header1.children[r];
4168
+ let tr2 = header2.children[r];
4169
+ if (tr1) {
4170
+ for (let i = 0; i < tr1.children.length; i++) {
4171
+ let td = tr1.children[i] as HTMLTableCellElement;
4172
+ let h = td.getBoundingClientRect().height;
4173
+ if (td.rowSpan == 1 && h > rowHeight[r]) {
4174
+ rowHeight[r] = h;
4175
+ break;
4176
+ }
4177
+ }
4178
+ }
4179
+ if (tr2) {
4180
+ for (let i = 0; i < tr2.children.length; i++) {
4181
+ let td = tr2.children[i] as HTMLTableCellElement;
4182
+ let h = td.getBoundingClientRect().height;
4183
+ if (td.rowSpan == 1 && h > rowHeight[r]) {
4184
+ rowHeight[r] = h;
4185
+ break;
4186
+ }
4187
+ }
4188
+ }
4189
+ }
4190
+
4191
+ for (let r = 0; r < rowCount; r++) {
4192
+ let tr1 = header1.children[r];
4193
+ let tr2 = header2.children[r];
4194
+ if (tr1) {
4195
+ for (let i = 0; i < tr1.children.length; i++) {
4196
+ let td = tr1.children[i] as HTMLTableCellElement;
4197
+ let h = 0;
4198
+ for (let x = 0; x < td.rowSpan; x++) h += rowHeight[r + x];
4199
+ td.style.height = `${h}px`;
4200
+ }
4201
+ }
4202
+ if (tr2) {
4203
+ for (let i = 0; i < tr2.children.length; i++) {
4204
+ let td = tr2.children[i] as HTMLTableCellElement;
4205
+ let h = 0;
4206
+ for (let x = 0; x < td.rowSpan; x++) h += rowHeight[r + x];
4207
+ td.style.height = `${h}px`;
4208
+ }
4209
+ }
4210
+ }
4211
+ }
4212
+
4213
+ class AvgHeight {
4214
+ declare groups: Record<string, { sum: number; count: number }>;
4215
+
4216
+ constructor() {
4217
+ this.groups = {};
4218
+ }
4219
+
4220
+ add(group: string, height: number) {
4221
+ let g = this.groups[group];
4222
+ if (!g) g = this.groups[group] = { sum: 0, count: 0 };
4223
+ g.sum += height;
4224
+ g.count++;
4225
+ }
4226
+
4227
+ estimate(group: string): number | null {
4228
+ let g = this.groups[group];
4229
+ if (!g || g.count == 0) return null;
4230
+ return Math.round(g.sum / g.count);
4231
+ }
4232
+ }
4233
+
4234
+ function getDragDropEvent(ev: React.DragEvent, store: View, type: "dragstart" | "dragmove" | "dragdrop"): DragEvent {
4235
+ return {
4236
+ type,
4237
+ event: ev,
4238
+ cursor: getCursorPos(ev),
4239
+ dataTransfer: ev.dataTransfer,
4240
+ source: {
4241
+ width: 32,
4242
+ height: 32,
4243
+ margin: [],
4244
+ store,
4245
+ },
4246
+ };
4247
+ }