@cratis/scene.primereact 4.5.0 → 4.7.0

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 (513) hide show
  1. package/.storybook/preview.tsx +8 -1
  2. package/EnumerationResolution.ts +7 -0
  3. package/README.md +42 -10
  4. package/chart/ChartGallery.stories.tsx +63 -0
  5. package/chart/ChartType.ts +14 -0
  6. package/chart/ChartTypeResolution.ts +14 -0
  7. package/chart/PrimeChart.tsx +62 -0
  8. package/chart/chartHasData.ts +22 -0
  9. package/chart/chartTypeChoices.ts +32 -0
  10. package/chart/index.ts +7 -0
  11. package/chart/resolveChartType.ts +61 -0
  12. package/chart/useChart.ts +61 -0
  13. package/data/DataGallery.stories.tsx +6 -0
  14. package/data/DataScrollerRow.tsx +35 -0
  15. package/data/PrimeDataScroller.tsx +84 -0
  16. package/data/PrimeTreeTable.tsx +145 -0
  17. package/data/TreeTableCheckState.ts +9 -0
  18. package/data/TreeTableRow.ts +22 -0
  19. package/data/TreeTableRowView.tsx +86 -0
  20. package/data/TreeTableSelectionMode.ts +10 -0
  21. package/data/checkboxSelection.ts +92 -0
  22. package/data/index.ts +4 -0
  23. package/data/isSerializedLegacyElement.ts +30 -0
  24. package/data/readableValue.ts +32 -0
  25. package/data/selectionKeysOf.ts +40 -0
  26. package/data/treeTableRows.ts +32 -0
  27. package/data/useIncrementalLoad.ts +36 -0
  28. package/data/useLoadOnReach.ts +31 -0
  29. package/data/useTreeGridNavigation.ts +81 -0
  30. package/dist/cjs/chart/ChartType.js +18 -0
  31. package/dist/cjs/chart/ChartType.js.map +1 -0
  32. package/dist/cjs/chart/PrimeChart.js +92 -0
  33. package/dist/cjs/chart/PrimeChart.js.map +1 -0
  34. package/dist/cjs/chart/chartHasData.js +24 -0
  35. package/dist/cjs/chart/chartHasData.js.map +1 -0
  36. package/dist/cjs/chart/chartTypeChoices.js +43 -0
  37. package/dist/cjs/chart/chartTypeChoices.js.map +1 -0
  38. package/dist/cjs/chart/resolveChartType.js +69 -0
  39. package/dist/cjs/chart/resolveChartType.js.map +1 -0
  40. package/dist/cjs/chart/useChart.js +62 -0
  41. package/dist/cjs/chart/useChart.js.map +1 -0
  42. package/dist/cjs/data/DataScrollerRow.js +50 -0
  43. package/dist/cjs/data/DataScrollerRow.js.map +1 -0
  44. package/dist/cjs/data/PrimeDataScroller.js +120 -0
  45. package/dist/cjs/data/PrimeDataScroller.js.map +1 -0
  46. package/dist/cjs/data/PrimeTreeTable.js +217 -0
  47. package/dist/cjs/data/PrimeTreeTable.js.map +1 -0
  48. package/dist/cjs/data/TreeTableCheckState.js +13 -0
  49. package/dist/cjs/data/TreeTableCheckState.js.map +1 -0
  50. package/dist/cjs/data/TreeTableRowView.js +76 -0
  51. package/dist/cjs/data/TreeTableRowView.js.map +1 -0
  52. package/dist/cjs/data/TreeTableSelectionMode.js +14 -0
  53. package/dist/cjs/data/TreeTableSelectionMode.js.map +1 -0
  54. package/dist/cjs/data/checkboxSelection.js +88 -0
  55. package/dist/cjs/data/checkboxSelection.js.map +1 -0
  56. package/dist/cjs/data/isSerializedLegacyElement.js +30 -0
  57. package/dist/cjs/data/isSerializedLegacyElement.js.map +1 -0
  58. package/dist/cjs/data/readableValue.js +31 -0
  59. package/dist/cjs/data/readableValue.js.map +1 -0
  60. package/dist/cjs/data/selectionKeysOf.js +40 -0
  61. package/dist/cjs/data/selectionKeysOf.js.map +1 -0
  62. package/dist/cjs/data/treeTableRows.js +42 -0
  63. package/dist/cjs/data/treeTableRows.js.map +1 -0
  64. package/dist/cjs/data/useIncrementalLoad.js +46 -0
  65. package/dist/cjs/data/useIncrementalLoad.js.map +1 -0
  66. package/dist/cjs/data/useLoadOnReach.js +42 -0
  67. package/dist/cjs/data/useLoadOnReach.js.map +1 -0
  68. package/dist/cjs/data/useTreeGridNavigation.js +75 -0
  69. package/dist/cjs/data/useTreeGridNavigation.js.map +1 -0
  70. package/dist/cjs/editor/PrimeEditor.js +96 -0
  71. package/dist/cjs/editor/PrimeEditor.js.map +1 -0
  72. package/dist/cjs/editor/QuillLoaderContext.js +10 -0
  73. package/dist/cjs/editor/QuillLoaderContext.js.map +1 -0
  74. package/dist/cjs/editor/QuillLoaderProvider.js +21 -0
  75. package/dist/cjs/editor/QuillLoaderProvider.js.map +1 -0
  76. package/dist/cjs/editor/applyHtml.js +25 -0
  77. package/dist/cjs/editor/applyHtml.js.map +1 -0
  78. package/dist/cjs/editor/characterCount.js +10 -0
  79. package/dist/cjs/editor/characterCount.js.map +1 -0
  80. package/dist/cjs/editor/htmlToPlainText.js +101 -0
  81. package/dist/cjs/editor/htmlToPlainText.js.map +1 -0
  82. package/dist/cjs/editor/renderSafeNodes.js +35 -0
  83. package/dist/cjs/editor/renderSafeNodes.js.map +1 -0
  84. package/dist/cjs/editor/safeUrls.js +44 -0
  85. package/dist/cjs/editor/safeUrls.js.map +1 -0
  86. package/dist/cjs/editor/sanitizeHtml.js +140 -0
  87. package/dist/cjs/editor/sanitizeHtml.js.map +1 -0
  88. package/dist/cjs/editor/serializeSafeNodes.js +33 -0
  89. package/dist/cjs/editor/serializeSafeNodes.js.map +1 -0
  90. package/dist/cjs/editor/toolbarLayout.js +35 -0
  91. package/dist/cjs/editor/toolbarLayout.js.map +1 -0
  92. package/dist/cjs/editor/useQuillEditor.js +137 -0
  93. package/dist/cjs/editor/useQuillEditor.js.map +1 -0
  94. package/dist/cjs/file/FileUploadContext.js +13 -0
  95. package/dist/cjs/file/FileUploadContext.js.map +1 -0
  96. package/dist/cjs/file/FileUploadHandlerProvider.js +25 -0
  97. package/dist/cjs/file/FileUploadHandlerProvider.js.map +1 -0
  98. package/dist/cjs/file/FileUploadMode.js +13 -0
  99. package/dist/cjs/file/FileUploadMode.js.map +1 -0
  100. package/dist/cjs/file/PrimeFileUpload.js +161 -0
  101. package/dist/cjs/file/PrimeFileUpload.js.map +1 -0
  102. package/dist/cjs/file/postFiles.js +31 -0
  103. package/dist/cjs/file/postFiles.js.map +1 -0
  104. package/dist/cjs/file/resolveUploadTarget.js +68 -0
  105. package/dist/cjs/file/resolveUploadTarget.js.map +1 -0
  106. package/dist/cjs/file/useUploadSession.js +62 -0
  107. package/dist/cjs/file/useUploadSession.js.map +1 -0
  108. package/dist/cjs/form/MultiStateGlyph.js +59 -0
  109. package/dist/cjs/form/MultiStateGlyph.js.map +1 -0
  110. package/dist/cjs/form/PrimeMultiStateCheckbox.js +123 -0
  111. package/dist/cjs/form/PrimeMultiStateCheckbox.js.map +1 -0
  112. package/dist/cjs/form/multiStateOptions.js +77 -0
  113. package/dist/cjs/form/multiStateOptions.js.map +1 -0
  114. package/dist/cjs/form/multiStateStates.js +32 -0
  115. package/dist/cjs/form/multiStateStates.js.map +1 -0
  116. package/dist/cjs/form/useMultiStateSelection.js +51 -0
  117. package/dist/cjs/form/useMultiStateSelection.js.map +1 -0
  118. package/dist/cjs/index.js +44 -0
  119. package/dist/cjs/index.js.map +1 -1
  120. package/dist/cjs/legacyEnumerationChoices.js +39 -0
  121. package/dist/cjs/legacyEnumerationChoices.js.map +1 -0
  122. package/dist/cjs/loadQuill/index.js +22 -0
  123. package/dist/cjs/loadQuill/index.js.map +1 -0
  124. package/dist/cjs/primeReactComponents.js +15 -0
  125. package/dist/cjs/primeReactComponents.js.map +1 -1
  126. package/dist/cjs/primeReactDescriptors.js +400 -0
  127. package/dist/cjs/primeReactDescriptors.js.map +1 -0
  128. package/dist/cjs/primeReactPackage.js +8 -0
  129. package/dist/cjs/primeReactPackage.js.map +1 -1
  130. package/dist/cjs/properties.js +11 -0
  131. package/dist/cjs/properties.js.map +1 -1
  132. package/dist/cjs/resolveEnumeration.js +55 -0
  133. package/dist/cjs/resolveEnumeration.js.map +1 -0
  134. package/dist/cjs/structurallyEqual.js +27 -0
  135. package/dist/cjs/structurallyEqual.js.map +1 -0
  136. package/dist/cjs/treeNodes.js +42 -7
  137. package/dist/cjs/treeNodes.js.map +1 -1
  138. package/dist/cjs/useResettingState.js +47 -0
  139. package/dist/cjs/useResettingState.js.map +1 -0
  140. package/dist/cjs/useStructuralValue.js +20 -0
  141. package/dist/cjs/useStructuralValue.js.map +1 -0
  142. package/dist/esm/EnumerationResolution.d.ts +9 -0
  143. package/dist/esm/EnumerationResolution.d.ts.map +1 -0
  144. package/dist/esm/EnumerationResolution.js +2 -0
  145. package/dist/esm/EnumerationResolution.js.map +1 -0
  146. package/dist/esm/chart/ChartGallery.stories.d.ts +14 -0
  147. package/dist/esm/chart/ChartGallery.stories.d.ts.map +1 -0
  148. package/dist/esm/chart/ChartGallery.stories.js +47 -0
  149. package/dist/esm/chart/ChartGallery.stories.js.map +1 -0
  150. package/dist/esm/chart/ChartType.d.ts +11 -0
  151. package/dist/esm/chart/ChartType.d.ts.map +1 -0
  152. package/dist/esm/chart/ChartType.js +16 -0
  153. package/dist/esm/chart/ChartType.js.map +1 -0
  154. package/dist/esm/chart/ChartTypeResolution.d.ts +10 -0
  155. package/dist/esm/chart/ChartTypeResolution.d.ts.map +1 -0
  156. package/dist/esm/chart/ChartTypeResolution.js +2 -0
  157. package/dist/esm/chart/ChartTypeResolution.js.map +1 -0
  158. package/dist/esm/chart/PrimeChart.d.ts +3 -0
  159. package/dist/esm/chart/PrimeChart.d.ts.map +1 -0
  160. package/dist/esm/chart/PrimeChart.js +90 -0
  161. package/dist/esm/chart/PrimeChart.js.map +1 -0
  162. package/dist/esm/chart/chartHasData.d.ts +2 -0
  163. package/dist/esm/chart/chartHasData.d.ts.map +1 -0
  164. package/dist/esm/chart/chartHasData.js +22 -0
  165. package/dist/esm/chart/chartHasData.js.map +1 -0
  166. package/dist/esm/chart/chartTypeChoices.d.ts +3 -0
  167. package/dist/esm/chart/chartTypeChoices.d.ts.map +1 -0
  168. package/dist/esm/chart/chartTypeChoices.js +41 -0
  169. package/dist/esm/chart/chartTypeChoices.js.map +1 -0
  170. package/dist/esm/chart/index.d.ts +5 -0
  171. package/dist/esm/chart/index.d.ts.map +1 -0
  172. package/dist/esm/chart/index.js +5 -0
  173. package/dist/esm/chart/index.js.map +1 -0
  174. package/dist/esm/chart/resolveChartType.d.ts +6 -0
  175. package/dist/esm/chart/resolveChartType.d.ts.map +1 -0
  176. package/dist/esm/chart/resolveChartType.js +66 -0
  177. package/dist/esm/chart/resolveChartType.js.map +1 -0
  178. package/dist/esm/chart/useChart.d.ts +4 -0
  179. package/dist/esm/chart/useChart.d.ts.map +1 -0
  180. package/dist/esm/chart/useChart.js +60 -0
  181. package/dist/esm/chart/useChart.js.map +1 -0
  182. package/dist/esm/data/DataGallery.stories.d.ts.map +1 -1
  183. package/dist/esm/data/DataGallery.stories.js +6 -0
  184. package/dist/esm/data/DataGallery.stories.js.map +1 -1
  185. package/dist/esm/data/DataScrollerRow.d.ts +4 -0
  186. package/dist/esm/data/DataScrollerRow.d.ts.map +1 -0
  187. package/dist/esm/data/DataScrollerRow.js +48 -0
  188. package/dist/esm/data/DataScrollerRow.js.map +1 -0
  189. package/dist/esm/data/PrimeDataScroller.d.ts +3 -0
  190. package/dist/esm/data/PrimeDataScroller.d.ts.map +1 -0
  191. package/dist/esm/data/PrimeDataScroller.js +118 -0
  192. package/dist/esm/data/PrimeDataScroller.js.map +1 -0
  193. package/dist/esm/data/PrimeTreeTable.d.ts +3 -0
  194. package/dist/esm/data/PrimeTreeTable.d.ts.map +1 -0
  195. package/dist/esm/data/PrimeTreeTable.js +215 -0
  196. package/dist/esm/data/PrimeTreeTable.js.map +1 -0
  197. package/dist/esm/data/TreeTableCheckState.d.ts +6 -0
  198. package/dist/esm/data/TreeTableCheckState.d.ts.map +1 -0
  199. package/dist/esm/data/TreeTableCheckState.js +11 -0
  200. package/dist/esm/data/TreeTableCheckState.js.map +1 -0
  201. package/dist/esm/data/TreeTableRow.d.ts +10 -0
  202. package/dist/esm/data/TreeTableRow.d.ts.map +1 -0
  203. package/dist/esm/data/TreeTableRow.js +2 -0
  204. package/dist/esm/data/TreeTableRow.js.map +1 -0
  205. package/dist/esm/data/TreeTableRowView.d.ts +21 -0
  206. package/dist/esm/data/TreeTableRowView.d.ts.map +1 -0
  207. package/dist/esm/data/TreeTableRowView.js +74 -0
  208. package/dist/esm/data/TreeTableRowView.js.map +1 -0
  209. package/dist/esm/data/TreeTableSelectionMode.d.ts +7 -0
  210. package/dist/esm/data/TreeTableSelectionMode.d.ts.map +1 -0
  211. package/dist/esm/data/TreeTableSelectionMode.js +12 -0
  212. package/dist/esm/data/TreeTableSelectionMode.js.map +1 -0
  213. package/dist/esm/data/checkboxSelection.d.ts +9 -0
  214. package/dist/esm/data/checkboxSelection.d.ts.map +1 -0
  215. package/dist/esm/data/checkboxSelection.js +85 -0
  216. package/dist/esm/data/checkboxSelection.js.map +1 -0
  217. package/dist/esm/data/index.d.ts +4 -0
  218. package/dist/esm/data/index.d.ts.map +1 -1
  219. package/dist/esm/data/index.js +4 -0
  220. package/dist/esm/data/index.js.map +1 -1
  221. package/dist/esm/data/isSerializedLegacyElement.d.ts +3 -0
  222. package/dist/esm/data/isSerializedLegacyElement.d.ts.map +1 -0
  223. package/dist/esm/data/isSerializedLegacyElement.js +27 -0
  224. package/dist/esm/data/isSerializedLegacyElement.js.map +1 -0
  225. package/dist/esm/data/readableValue.d.ts +2 -0
  226. package/dist/esm/data/readableValue.d.ts.map +1 -0
  227. package/dist/esm/data/readableValue.js +29 -0
  228. package/dist/esm/data/readableValue.js.map +1 -0
  229. package/dist/esm/data/selectionKeysOf.d.ts +2 -0
  230. package/dist/esm/data/selectionKeysOf.d.ts.map +1 -0
  231. package/dist/esm/data/selectionKeysOf.js +38 -0
  232. package/dist/esm/data/selectionKeysOf.js.map +1 -0
  233. package/dist/esm/data/treeTableRows.d.ts +6 -0
  234. package/dist/esm/data/treeTableRows.d.ts.map +1 -0
  235. package/dist/esm/data/treeTableRows.js +38 -0
  236. package/dist/esm/data/treeTableRows.js.map +1 -0
  237. package/dist/esm/data/useIncrementalLoad.d.ts +6 -0
  238. package/dist/esm/data/useIncrementalLoad.d.ts.map +1 -0
  239. package/dist/esm/data/useIncrementalLoad.js +44 -0
  240. package/dist/esm/data/useIncrementalLoad.js.map +1 -0
  241. package/dist/esm/data/useLoadOnReach.d.ts +3 -0
  242. package/dist/esm/data/useLoadOnReach.d.ts.map +1 -0
  243. package/dist/esm/data/useLoadOnReach.js +40 -0
  244. package/dist/esm/data/useLoadOnReach.js.map +1 -0
  245. package/dist/esm/data/useTreeGridNavigation.d.ts +17 -0
  246. package/dist/esm/data/useTreeGridNavigation.d.ts.map +1 -0
  247. package/dist/esm/data/useTreeGridNavigation.js +73 -0
  248. package/dist/esm/data/useTreeGridNavigation.js.map +1 -0
  249. package/dist/esm/editor/PrimeEditor.d.ts +3 -0
  250. package/dist/esm/editor/PrimeEditor.d.ts.map +1 -0
  251. package/dist/esm/editor/PrimeEditor.js +94 -0
  252. package/dist/esm/editor/PrimeEditor.js.map +1 -0
  253. package/dist/esm/editor/QuillConstructor.d.ts +4 -0
  254. package/dist/esm/editor/QuillConstructor.d.ts.map +1 -0
  255. package/dist/esm/editor/QuillConstructor.js +2 -0
  256. package/dist/esm/editor/QuillConstructor.js.map +1 -0
  257. package/dist/esm/editor/QuillEditorOptions.d.ts +13 -0
  258. package/dist/esm/editor/QuillEditorOptions.d.ts.map +1 -0
  259. package/dist/esm/editor/QuillEditorOptions.js +2 -0
  260. package/dist/esm/editor/QuillEditorOptions.js.map +1 -0
  261. package/dist/esm/editor/QuillEditorState.d.ts +6 -0
  262. package/dist/esm/editor/QuillEditorState.d.ts.map +1 -0
  263. package/dist/esm/editor/QuillEditorState.js +2 -0
  264. package/dist/esm/editor/QuillEditorState.js.map +1 -0
  265. package/dist/esm/editor/QuillInstance.d.ts +16 -0
  266. package/dist/esm/editor/QuillInstance.d.ts.map +1 -0
  267. package/dist/esm/editor/QuillInstance.js +2 -0
  268. package/dist/esm/editor/QuillInstance.js.map +1 -0
  269. package/dist/esm/editor/QuillLoader.d.ts +5 -0
  270. package/dist/esm/editor/QuillLoader.d.ts.map +1 -0
  271. package/dist/esm/editor/QuillLoader.js +2 -0
  272. package/dist/esm/editor/QuillLoader.js.map +1 -0
  273. package/dist/esm/editor/QuillLoaderContext.d.ts +3 -0
  274. package/dist/esm/editor/QuillLoaderContext.d.ts.map +1 -0
  275. package/dist/esm/editor/QuillLoaderContext.js +8 -0
  276. package/dist/esm/editor/QuillLoaderContext.js.map +1 -0
  277. package/dist/esm/editor/QuillLoaderProvider.d.ts +8 -0
  278. package/dist/esm/editor/QuillLoaderProvider.d.ts.map +1 -0
  279. package/dist/esm/editor/QuillLoaderProvider.js +19 -0
  280. package/dist/esm/editor/QuillLoaderProvider.js.map +1 -0
  281. package/dist/esm/editor/QuillOptions.d.ts +9 -0
  282. package/dist/esm/editor/QuillOptions.d.ts.map +1 -0
  283. package/dist/esm/editor/QuillOptions.js +2 -0
  284. package/dist/esm/editor/QuillOptions.js.map +1 -0
  285. package/dist/esm/editor/SafeElement.d.ts +7 -0
  286. package/dist/esm/editor/SafeElement.d.ts.map +1 -0
  287. package/dist/esm/editor/SafeElement.js +2 -0
  288. package/dist/esm/editor/SafeElement.js.map +1 -0
  289. package/dist/esm/editor/SafeNode.d.ts +3 -0
  290. package/dist/esm/editor/SafeNode.d.ts.map +1 -0
  291. package/dist/esm/editor/SafeNode.js +2 -0
  292. package/dist/esm/editor/SafeNode.js.map +1 -0
  293. package/dist/esm/editor/applyHtml.d.ts +3 -0
  294. package/dist/esm/editor/applyHtml.d.ts.map +1 -0
  295. package/dist/esm/editor/applyHtml.js +23 -0
  296. package/dist/esm/editor/applyHtml.js.map +1 -0
  297. package/dist/esm/editor/characterCount.d.ts +3 -0
  298. package/dist/esm/editor/characterCount.d.ts.map +1 -0
  299. package/dist/esm/editor/characterCount.js +8 -0
  300. package/dist/esm/editor/characterCount.js.map +1 -0
  301. package/dist/esm/editor/htmlToPlainText.d.ts +2 -0
  302. package/dist/esm/editor/htmlToPlainText.d.ts.map +1 -0
  303. package/dist/esm/editor/htmlToPlainText.js +99 -0
  304. package/dist/esm/editor/htmlToPlainText.js.map +1 -0
  305. package/dist/esm/editor/index.d.ts +14 -0
  306. package/dist/esm/editor/index.d.ts.map +1 -0
  307. package/dist/esm/editor/index.js +14 -0
  308. package/dist/esm/editor/index.js.map +1 -0
  309. package/dist/esm/editor/renderSafeNodes.d.ts +4 -0
  310. package/dist/esm/editor/renderSafeNodes.d.ts.map +1 -0
  311. package/dist/esm/editor/renderSafeNodes.js +33 -0
  312. package/dist/esm/editor/renderSafeNodes.js.map +1 -0
  313. package/dist/esm/editor/safeUrls.d.ts +3 -0
  314. package/dist/esm/editor/safeUrls.d.ts.map +1 -0
  315. package/dist/esm/editor/safeUrls.js +41 -0
  316. package/dist/esm/editor/safeUrls.js.map +1 -0
  317. package/dist/esm/editor/sanitizeHtml.d.ts +3 -0
  318. package/dist/esm/editor/sanitizeHtml.d.ts.map +1 -0
  319. package/dist/esm/editor/sanitizeHtml.js +138 -0
  320. package/dist/esm/editor/sanitizeHtml.js.map +1 -0
  321. package/dist/esm/editor/serializeSafeNodes.d.ts +3 -0
  322. package/dist/esm/editor/serializeSafeNodes.d.ts.map +1 -0
  323. package/dist/esm/editor/serializeSafeNodes.js +31 -0
  324. package/dist/esm/editor/serializeSafeNodes.js.map +1 -0
  325. package/dist/esm/editor/toolbarLayout.d.ts +2 -0
  326. package/dist/esm/editor/toolbarLayout.d.ts.map +1 -0
  327. package/dist/esm/editor/toolbarLayout.js +33 -0
  328. package/dist/esm/editor/toolbarLayout.js.map +1 -0
  329. package/dist/esm/editor/useQuillEditor.d.ts +4 -0
  330. package/dist/esm/editor/useQuillEditor.d.ts.map +1 -0
  331. package/dist/esm/editor/useQuillEditor.js +135 -0
  332. package/dist/esm/editor/useQuillEditor.js.map +1 -0
  333. package/dist/esm/file/FileGallery.stories.d.ts +19 -0
  334. package/dist/esm/file/FileGallery.stories.d.ts.map +1 -0
  335. package/dist/esm/file/FileGallery.stories.js +23 -0
  336. package/dist/esm/file/FileGallery.stories.js.map +1 -0
  337. package/dist/esm/file/FileUploadContext.d.ts +7 -0
  338. package/dist/esm/file/FileUploadContext.d.ts.map +1 -0
  339. package/dist/esm/file/FileUploadContext.js +11 -0
  340. package/dist/esm/file/FileUploadContext.js.map +1 -0
  341. package/dist/esm/file/FileUploadHandler.d.ts +4 -0
  342. package/dist/esm/file/FileUploadHandler.d.ts.map +1 -0
  343. package/dist/esm/file/FileUploadHandler.js +2 -0
  344. package/dist/esm/file/FileUploadHandler.js.map +1 -0
  345. package/dist/esm/file/FileUploadHandlerProvider.d.ts +9 -0
  346. package/dist/esm/file/FileUploadHandlerProvider.d.ts.map +1 -0
  347. package/dist/esm/file/FileUploadHandlerProvider.js +23 -0
  348. package/dist/esm/file/FileUploadHandlerProvider.js.map +1 -0
  349. package/dist/esm/file/FileUploadMode.d.ts +6 -0
  350. package/dist/esm/file/FileUploadMode.d.ts.map +1 -0
  351. package/dist/esm/file/FileUploadMode.js +11 -0
  352. package/dist/esm/file/FileUploadMode.js.map +1 -0
  353. package/dist/esm/file/PrimeFileUpload.d.ts +3 -0
  354. package/dist/esm/file/PrimeFileUpload.d.ts.map +1 -0
  355. package/dist/esm/file/PrimeFileUpload.js +159 -0
  356. package/dist/esm/file/PrimeFileUpload.js.map +1 -0
  357. package/dist/esm/file/UploadStatus.d.ts +5 -0
  358. package/dist/esm/file/UploadStatus.d.ts.map +1 -0
  359. package/dist/esm/file/UploadStatus.js +2 -0
  360. package/dist/esm/file/UploadStatus.js.map +1 -0
  361. package/dist/esm/file/UploadTarget.d.ts +8 -0
  362. package/dist/esm/file/UploadTarget.d.ts.map +1 -0
  363. package/dist/esm/file/UploadTarget.js +2 -0
  364. package/dist/esm/file/UploadTarget.js.map +1 -0
  365. package/dist/esm/file/index.d.ts +7 -0
  366. package/dist/esm/file/index.d.ts.map +1 -0
  367. package/dist/esm/file/index.js +7 -0
  368. package/dist/esm/file/index.js.map +1 -0
  369. package/dist/esm/file/postFiles.d.ts +2 -0
  370. package/dist/esm/file/postFiles.d.ts.map +1 -0
  371. package/dist/esm/file/postFiles.js +29 -0
  372. package/dist/esm/file/postFiles.js.map +1 -0
  373. package/dist/esm/file/resolveUploadTarget.d.ts +3 -0
  374. package/dist/esm/file/resolveUploadTarget.d.ts.map +1 -0
  375. package/dist/esm/file/resolveUploadTarget.js +66 -0
  376. package/dist/esm/file/resolveUploadTarget.js.map +1 -0
  377. package/dist/esm/file/useUploadSession.d.ts +10 -0
  378. package/dist/esm/file/useUploadSession.d.ts.map +1 -0
  379. package/dist/esm/file/useUploadSession.js +60 -0
  380. package/dist/esm/file/useUploadSession.js.map +1 -0
  381. package/dist/esm/form/FormGallery.stories.d.ts.map +1 -1
  382. package/dist/esm/form/FormGallery.stories.js +9 -0
  383. package/dist/esm/form/FormGallery.stories.js.map +1 -1
  384. package/dist/esm/form/MultiStateGlyph.d.ts +8 -0
  385. package/dist/esm/form/MultiStateGlyph.d.ts.map +1 -0
  386. package/dist/esm/form/MultiStateGlyph.js +57 -0
  387. package/dist/esm/form/MultiStateGlyph.js.map +1 -0
  388. package/dist/esm/form/MultiStateOption.d.ts +7 -0
  389. package/dist/esm/form/MultiStateOption.d.ts.map +1 -0
  390. package/dist/esm/form/MultiStateOption.js +2 -0
  391. package/dist/esm/form/MultiStateOption.js.map +1 -0
  392. package/dist/esm/form/PrimeMultiStateCheckbox.d.ts +3 -0
  393. package/dist/esm/form/PrimeMultiStateCheckbox.d.ts.map +1 -0
  394. package/dist/esm/form/PrimeMultiStateCheckbox.js +121 -0
  395. package/dist/esm/form/PrimeMultiStateCheckbox.js.map +1 -0
  396. package/dist/esm/form/index.d.ts +1 -0
  397. package/dist/esm/form/index.d.ts.map +1 -1
  398. package/dist/esm/form/index.js +1 -0
  399. package/dist/esm/form/index.js.map +1 -1
  400. package/dist/esm/form/multiStateOptions.d.ts +4 -0
  401. package/dist/esm/form/multiStateOptions.d.ts.map +1 -0
  402. package/dist/esm/form/multiStateOptions.js +75 -0
  403. package/dist/esm/form/multiStateOptions.js.map +1 -0
  404. package/dist/esm/form/multiStateStates.d.ts +4 -0
  405. package/dist/esm/form/multiStateStates.d.ts.map +1 -0
  406. package/dist/esm/form/multiStateStates.js +30 -0
  407. package/dist/esm/form/multiStateStates.js.map +1 -0
  408. package/dist/esm/form/useMultiStateSelection.d.ts +6 -0
  409. package/dist/esm/form/useMultiStateSelection.d.ts.map +1 -0
  410. package/dist/esm/form/useMultiStateSelection.js +49 -0
  411. package/dist/esm/form/useMultiStateSelection.js.map +1 -0
  412. package/dist/esm/index.d.ts +4 -0
  413. package/dist/esm/index.d.ts.map +1 -1
  414. package/dist/esm/index.js +22 -2
  415. package/dist/esm/index.js.map +1 -1
  416. package/dist/esm/legacyEnumerationChoices.d.ts +3 -0
  417. package/dist/esm/legacyEnumerationChoices.d.ts.map +1 -0
  418. package/dist/esm/legacyEnumerationChoices.js +37 -0
  419. package/dist/esm/legacyEnumerationChoices.js.map +1 -0
  420. package/dist/esm/loadQuill/index.d.ts +3 -0
  421. package/dist/esm/loadQuill/index.d.ts.map +1 -0
  422. package/dist/esm/loadQuill/index.js +20 -0
  423. package/dist/esm/loadQuill/index.js.map +1 -0
  424. package/dist/esm/primeReactComponents.d.ts.map +1 -1
  425. package/dist/esm/primeReactComponents.js +15 -0
  426. package/dist/esm/primeReactComponents.js.map +1 -1
  427. package/dist/esm/primeReactDescriptors.d.ts +3 -0
  428. package/dist/esm/primeReactDescriptors.d.ts.map +1 -0
  429. package/dist/esm/primeReactDescriptors.js +398 -0
  430. package/dist/esm/primeReactDescriptors.js.map +1 -0
  431. package/dist/esm/primeReactPackage.d.ts.map +1 -1
  432. package/dist/esm/primeReactPackage.js +8 -0
  433. package/dist/esm/primeReactPackage.js.map +1 -1
  434. package/dist/esm/properties.d.ts +1 -0
  435. package/dist/esm/properties.d.ts.map +1 -1
  436. package/dist/esm/properties.js +11 -1
  437. package/dist/esm/properties.js.map +1 -1
  438. package/dist/esm/resolveEnumeration.d.ts +3 -0
  439. package/dist/esm/resolveEnumeration.d.ts.map +1 -0
  440. package/dist/esm/resolveEnumeration.js +53 -0
  441. package/dist/esm/resolveEnumeration.js.map +1 -0
  442. package/dist/esm/structurallyEqual.d.ts +2 -0
  443. package/dist/esm/structurallyEqual.d.ts.map +1 -0
  444. package/dist/esm/structurallyEqual.js +25 -0
  445. package/dist/esm/structurallyEqual.js.map +1 -0
  446. package/dist/esm/treeNodes.d.ts +2 -1
  447. package/dist/esm/treeNodes.d.ts.map +1 -1
  448. package/dist/esm/treeNodes.js +42 -8
  449. package/dist/esm/treeNodes.js.map +1 -1
  450. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  451. package/dist/esm/useResettingState.d.ts +3 -0
  452. package/dist/esm/useResettingState.d.ts.map +1 -0
  453. package/dist/esm/useResettingState.js +45 -0
  454. package/dist/esm/useResettingState.js.map +1 -0
  455. package/dist/esm/useStructuralValue.d.ts +2 -0
  456. package/dist/esm/useStructuralValue.d.ts.map +1 -0
  457. package/dist/esm/useStructuralValue.js +18 -0
  458. package/dist/esm/useStructuralValue.js.map +1 -0
  459. package/editor/PrimeEditor.tsx +83 -0
  460. package/editor/QuillConstructor.ts +8 -0
  461. package/editor/QuillEditorOptions.ts +29 -0
  462. package/editor/QuillEditorState.ts +14 -0
  463. package/editor/QuillInstance.ts +27 -0
  464. package/editor/QuillLoader.ts +13 -0
  465. package/editor/QuillLoaderContext.ts +8 -0
  466. package/editor/QuillLoaderProvider.tsx +24 -0
  467. package/editor/QuillOptions.ts +10 -0
  468. package/editor/SafeElement.ts +15 -0
  469. package/editor/SafeNode.ts +7 -0
  470. package/editor/applyHtml.ts +21 -0
  471. package/editor/characterCount.ts +9 -0
  472. package/editor/htmlToPlainText.ts +74 -0
  473. package/editor/index.ts +16 -0
  474. package/editor/renderSafeNodes.tsx +26 -0
  475. package/editor/safeUrls.ts +43 -0
  476. package/editor/sanitizeHtml.ts +94 -0
  477. package/editor/serializeSafeNodes.ts +26 -0
  478. package/editor/toolbarLayout.ts +10 -0
  479. package/editor/useQuillEditor.ts +114 -0
  480. package/file/FileGallery.stories.tsx +32 -0
  481. package/file/FileUploadContext.ts +17 -0
  482. package/file/FileUploadHandler.ts +15 -0
  483. package/file/FileUploadHandlerProvider.tsx +33 -0
  484. package/file/FileUploadMode.ts +9 -0
  485. package/file/PrimeFileUpload.tsx +129 -0
  486. package/file/UploadStatus.ts +9 -0
  487. package/file/UploadTarget.ts +12 -0
  488. package/file/index.ts +9 -0
  489. package/file/postFiles.ts +23 -0
  490. package/file/resolveUploadTarget.ts +61 -0
  491. package/file/useUploadSession.ts +67 -0
  492. package/form/FormGallery.stories.tsx +9 -0
  493. package/form/MultiStateGlyph.tsx +55 -0
  494. package/form/MultiStateOption.ts +17 -0
  495. package/form/PrimeMultiStateCheckbox.tsx +101 -0
  496. package/form/index.ts +1 -0
  497. package/form/multiStateOptions.ts +78 -0
  498. package/form/multiStateStates.ts +23 -0
  499. package/form/useMultiStateSelection.ts +48 -0
  500. package/index.ts +4 -0
  501. package/legacyEnumerationChoices.ts +35 -0
  502. package/loadQuill/index.ts +21 -0
  503. package/package.json +27 -7
  504. package/primeReactComponents.ts +12 -0
  505. package/primeReactDescriptors.ts +111 -0
  506. package/primeReactPackage.ts +5 -3
  507. package/primeReactTheme.css +69 -0
  508. package/properties.ts +14 -0
  509. package/resolveEnumeration.ts +50 -0
  510. package/structurallyEqual.ts +29 -0
  511. package/treeNodes.ts +44 -6
  512. package/useResettingState.ts +34 -0
  513. package/useStructuralValue.ts +17 -0
@@ -0,0 +1,145 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { useEffect, useMemo, useState } from 'react';
5
+ import { RegisteredComponentProps } from '@cratis/scene.react';
6
+ import { arrayProperty, booleanProperty, numberProperty, stringProperty } from '../properties';
7
+ import { resolveEnumeration } from '../resolveEnumeration';
8
+ import { countUnreadableEntries, toTreeNodes } from '../treeNodes';
9
+ import { useResettingState } from '../useResettingState';
10
+ import { useStructuralValue } from '../useStructuralValue';
11
+ import { ColumnDefinition } from './ColumnDefinition';
12
+ import { TreeTableRow } from './TreeTableRow';
13
+ import { TreeTableRowView } from './TreeTableRowView';
14
+ import { TreeTableSelectionMode } from './TreeTableSelectionMode';
15
+ import { columnDefinitions } from './columnDefinitions';
16
+ import { SettledSelection, settleSelection, toggleCheckbox } from './checkboxSelection';
17
+ import { isSerializedLegacyElement, legacyElementMessage } from './isSerializedLegacyElement';
18
+ import { selectionKeysOf } from './selectionKeysOf';
19
+ import { expandedKeysOf, visibleRows } from './treeTableRows';
20
+ import { useTreeGridNavigation } from './useTreeGridNavigation';
21
+
22
+ const labelColumn: ColumnDefinition[] = [{ field: 'label', header: 'Label', sortable: false }];
23
+
24
+ /**
25
+ * The `PrimeReact:treeTable` component, an ARIA tree grid over the canonical Scene node and column properties.
26
+ *
27
+ * `items` is an array of nodes - strings, numbers, or records with `key`, `label`, `data`, `children`,
28
+ * `expanded` and `selectable` - and the columns come from nested `column` elements, a `columns` property or the
29
+ * fields of the first row's `data`, in that order (see `columnDefinitions`). Serialized legacy UI elements in
30
+ * `items` or `columns` are refused with a visible message; see the package documentation for how they map to
31
+ * canonical slots.
32
+ *
33
+ * - Selection follows the authored `selection` (keys, numbers, `{ key }` objects or PrimeReact's key map) and
34
+ * starts over when it changes; expansion starts from the authored `expanded` flags the same way. An unrelated
35
+ * property edit leaves what the user did alone.
36
+ * - In checkbox mode a parent checks and unchecks its subtree and shows a partial state when only some of it is
37
+ * checked.
38
+ * - The rows form a `treegrid` with a roving tab index and the usual arrow-key navigation.
39
+ * - Object cell values are shown readably, never as `[object Object]`.
40
+ */
41
+ export function PrimeTreeTable({ element, interactions }: RegisteredComponentProps) {
42
+ const authoredItems = useStructuralValue(arrayProperty(element, 'items'));
43
+ const items = useMemo(() => authoredItems.filter(entry => !isSerializedLegacyElement(entry)), [authoredItems]);
44
+ const nodes = useMemo(() => toTreeNodes(items), [items]);
45
+ const modeResolution = resolveEnumeration('selectionMode', element.properties.selectionMode, TreeTableSelectionMode, TreeTableSelectionMode.None);
46
+ const mode = modeResolution.isValid ? modeResolution.value : TreeTableSelectionMode.None;
47
+ const enabled = element.isEnabled;
48
+ const pageSize = Math.max(Math.floor(numberProperty(element, 'rows', 10)), 1);
49
+ const paginator = booleanProperty(element, 'paginator', false);
50
+ const [expanded, setExpanded] = useResettingState(expandedKeysOf(nodes), () => new Set(expandedKeysOf(nodes)));
51
+ const [requested, setRequested] = useResettingState(element.properties.selection, () => selectionKeysOf(element.properties.selection));
52
+ const [page, setPage] = useState(0);
53
+ const pageCount = Math.max(Math.ceil(nodes.length / pageSize), 1);
54
+ const currentPage = Math.min(page, pageCount - 1);
55
+ const rows = useMemo(() => visibleRows(paginator ? nodes.slice(currentPage * pageSize, (currentPage + 1) * pageSize) : nodes, expanded), [nodes, paginator, currentPage, pageSize, expanded]);
56
+ const settled = useMemo<SettledSelection>(
57
+ () => mode === TreeTableSelectionMode.Checkbox ? settleSelection(nodes, requested) : { checked: requested, states: new Map() },
58
+ [mode, nodes, requested]
59
+ );
60
+ const columns = useMemo(() => {
61
+ const first = rows.find(row => typeof row.node.data === 'object' && row.node.data !== null && !Array.isArray(row.node.data))?.node.data as Record<string, unknown> | undefined;
62
+ const defined = columnDefinitions(element, first === undefined ? [] : [first]);
63
+ return defined.length > 0 ? defined : labelColumn;
64
+ }, [element, rows]);
65
+
66
+ useEffect(() => setPage(current => Math.min(current, pageCount - 1)), [pageCount]);
67
+
68
+ const toggle = (key: string) => {
69
+ if (enabled) setExpanded(current => {
70
+ const next = new Set(current);
71
+ if (next.has(key)) next.delete(key); else next.add(key);
72
+ return next;
73
+ });
74
+ };
75
+
76
+ const select = (row: TreeTableRow) => {
77
+ if (mode === TreeTableSelectionMode.None || !enabled || row.node.selectable === false) return;
78
+ if (mode === TreeTableSelectionMode.Checkbox) {
79
+ setRequested(toggleCheckbox(nodes, settled, row.node));
80
+ } else if (mode === TreeTableSelectionMode.Single) {
81
+ setRequested(new Set([row.key]));
82
+ } else {
83
+ const next = new Set(settled.checked);
84
+ if (next.has(row.key)) next.delete(row.key); else next.add(row.key);
85
+ setRequested(next);
86
+ }
87
+
88
+ interactions?.onSelect?.();
89
+ interactions?.onChange?.();
90
+ };
91
+
92
+ const navigation = useTreeGridNavigation({ rows, expanded, enabled, toggle, select });
93
+ const changePage = (target: number) => { if (enabled && target >= 0 && target < pageCount) setPage(target); };
94
+ const refusals = [
95
+ modeResolution.isValid ? undefined : modeResolution.message,
96
+ legacyElementMessage(authoredItems, 'items', 'Provide items as node data: strings, numbers, or records with key, label, data and children.'),
97
+ legacyElementMessage(arrayProperty(element, 'columns'), 'columns', "Author them as child elements in the 'columns' slot, or as column definitions."),
98
+ ].filter((message): message is string => message !== undefined);
99
+ const skipped = countUnreadableEntries(items);
100
+
101
+ return (
102
+ <div data-scene-id={element.id} data-scene-component='treeTable' aria-disabled={!enabled} onClick={interactions?.onClick} onDoubleClick={interactions?.onDoubleClick}>
103
+ <table
104
+ role='treegrid'
105
+ aria-label={stringProperty(element, 'ariaLabel', 'Hierarchical data')}
106
+ aria-multiselectable={mode === TreeTableSelectionMode.Multiple || mode === TreeTableSelectionMode.Checkbox ? true : undefined}>
107
+ <thead>
108
+ <tr role='row'>{columns.map((column, index) => <th key={index} role='columnheader'>{column.header}</th>)}</tr>
109
+ </thead>
110
+ <tbody>
111
+ {rows.map(row => (
112
+ <TreeTableRowView
113
+ key={row.key}
114
+ row={row}
115
+ columns={columns}
116
+ mode={mode}
117
+ enabled={enabled}
118
+ expanded={expanded.has(row.key)}
119
+ selected={settled.checked.has(row.key)}
120
+ checkState={settled.states.get(row.key)}
121
+ tabStop={navigation.tabStopKey === row.key}
122
+ register={navigation.register}
123
+ onActivate={() => navigation.activate(row.key)}
124
+ onToggle={() => toggle(row.key)}
125
+ onSelect={() => select(row)}
126
+ onKeyDown={event => navigation.onKeyDown(row, event)}
127
+ />
128
+ ))}
129
+ {rows.length === 0 && (
130
+ <tr role='row'><td role='gridcell' colSpan={columns.length}>{stringProperty(element, 'emptyLabel', 'No records found')}</td></tr>
131
+ )}
132
+ </tbody>
133
+ </table>
134
+ {paginator && (
135
+ <nav aria-label='Tree table pages'>
136
+ <button type='button' aria-disabled={!enabled || currentPage === 0} onClick={() => changePage(currentPage - 1)}>Previous</button>
137
+ <span>{currentPage + 1} / {pageCount}</span>
138
+ <button type='button' aria-disabled={!enabled || currentPage + 1 >= pageCount} onClick={() => changePage(currentPage + 1)}>Next</button>
139
+ </nav>
140
+ )}
141
+ {refusals.map(message => <p key={message} role='alert' data-scene-state='refused'>{message}</p>)}
142
+ {skipped > 0 && <p role='status'>{`${skipped} entr${skipped === 1 ? 'y' : 'ies'} of items could not be read as a node and ${skipped === 1 ? 'was' : 'were'} skipped.`}</p>}
143
+ </div>
144
+ );
145
+ }
@@ -0,0 +1,9 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /** How much of a tree table row's subtree is checked, in checkbox selection mode. */
5
+ export enum TreeTableCheckState {
6
+ Unchecked = 'unchecked',
7
+ Partial = 'partial',
8
+ Checked = 'checked',
9
+ }
@@ -0,0 +1,22 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { TreeNode } from '../TreeNode';
5
+
6
+ /** One visible row of a tree table, with where it sits in the tree. */
7
+ export interface TreeTableRow {
8
+ node: TreeNode;
9
+ key: string;
10
+
11
+ /** Zero for a root row. */
12
+ depth: number;
13
+
14
+ /** The key of the parent row, `undefined` for a root row. */
15
+ parentKey: string | undefined;
16
+
17
+ /** The 1-based position among the siblings, for `aria-posinset`. */
18
+ position: number;
19
+
20
+ /** The number of siblings, for `aria-setsize`. */
21
+ siblings: number;
22
+ }
@@ -0,0 +1,86 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { ColumnDefinition } from './ColumnDefinition';
5
+ import { TreeTableCheckState } from './TreeTableCheckState';
6
+ import { TreeTableRow } from './TreeTableRow';
7
+ import { TreeTableSelectionMode } from './TreeTableSelectionMode';
8
+ import { nodeLabel } from './treeTableRows';
9
+ import { readableValue } from './readableValue';
10
+
11
+ export interface TreeTableRowViewProps {
12
+ row: TreeTableRow;
13
+ columns: ColumnDefinition[];
14
+ mode: TreeTableSelectionMode;
15
+ enabled: boolean;
16
+ expanded: boolean;
17
+ selected: boolean;
18
+ checkState: TreeTableCheckState | undefined;
19
+ tabStop: boolean;
20
+ register(key: string, element: HTMLElement | null): void;
21
+ onActivate(): void;
22
+ onToggle(): void;
23
+ onSelect(): void;
24
+ onKeyDown(event: React.KeyboardEvent<HTMLElement>): void;
25
+ }
26
+
27
+ /** One `row` of the tree grid: its cells, its expand button and, in checkbox mode, its tri-state checkbox. */
28
+ export function TreeTableRowView({ row, columns, mode, enabled, expanded, selected, checkState, tabStop, register, onActivate, onToggle, onSelect, onKeyDown }: TreeTableRowViewProps) {
29
+ const { node } = row;
30
+ const label = nodeLabel(node);
31
+ const hasChildren = (node.children?.length ?? 0) > 0;
32
+ const selectionOffered = mode !== TreeTableSelectionMode.None;
33
+ const rowSelectable = selectionOffered && node.selectable !== false;
34
+
35
+ return (
36
+ <tr
37
+ ref={element => register(row.key, element)}
38
+ role='row'
39
+ tabIndex={tabStop ? 0 : -1}
40
+ aria-level={row.depth + 1}
41
+ aria-posinset={row.position}
42
+ aria-setsize={row.siblings}
43
+ aria-expanded={hasChildren ? expanded : undefined}
44
+ aria-selected={selectionOffered ? selected : undefined}
45
+ className={node.className}
46
+ onFocus={onActivate}
47
+ onKeyDown={onKeyDown}
48
+ onClick={event => {
49
+ onActivate();
50
+ if (mode === TreeTableSelectionMode.Single || mode === TreeTableSelectionMode.Multiple) {
51
+ if (!(event.target as HTMLElement).closest('button, input')) onSelect();
52
+ }
53
+ }}>
54
+ {columns.map((column, index) => (
55
+ <td key={index} role='gridcell' style={index === 0 ? { paddingInlineStart: `${row.depth * 1.25}rem` } : undefined}>
56
+ {index === 0 && hasChildren && (
57
+ <button type='button' tabIndex={-1} disabled={!enabled} aria-expanded={expanded} aria-label={`${expanded ? 'Collapse' : 'Expand'} ${label}`} onClick={onToggle}>
58
+ {expanded ? 'Collapse' : 'Expand'}
59
+ </button>
60
+ )}
61
+ {index === 0 && mode === TreeTableSelectionMode.Checkbox && checkState !== undefined && (
62
+ <input
63
+ type='checkbox'
64
+ tabIndex={-1}
65
+ ref={input => { if (input !== null) input.indeterminate = checkState === TreeTableCheckState.Partial; }}
66
+ checked={checkState === TreeTableCheckState.Checked}
67
+ disabled={!enabled || !rowSelectable}
68
+ aria-label={`Select ${label}`}
69
+ aria-checked={checkState === TreeTableCheckState.Partial ? 'mixed' : checkState === TreeTableCheckState.Checked}
70
+ onChange={onSelect}
71
+ />
72
+ )}
73
+ {cellText(row, column.field, index === 0)}
74
+ </td>
75
+ ))}
76
+ </tr>
77
+ );
78
+ }
79
+
80
+ function cellText(row: TreeTableRow, field: string, firstColumn: boolean): string {
81
+ const { data } = row.node;
82
+ const record = typeof data === 'object' && data !== null && !Array.isArray(data) ? data as Record<string, unknown> : undefined;
83
+ if (record !== undefined && record[field] !== undefined) return readableValue(record[field]);
84
+ if (!firstColumn) return '';
85
+ return row.node.label ?? (record === undefined ? readableValue(data) : '');
86
+ }
@@ -0,0 +1,10 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /** The canonical selection behavior for a hierarchical table. */
5
+ export enum TreeTableSelectionMode {
6
+ None = 'none',
7
+ Single = 'single',
8
+ Multiple = 'multiple',
9
+ Checkbox = 'checkbox',
10
+ }
@@ -0,0 +1,92 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { TreeNode } from '../TreeNode';
5
+ import { TreeTableCheckState } from './TreeTableCheckState';
6
+
7
+ /** The outcome of settling a checkbox selection: the keys that are checked, and how each row reads. */
8
+ export interface SettledSelection {
9
+ checked: Set<string>;
10
+ states: Map<string, TreeTableCheckState>;
11
+ }
12
+
13
+ const selectable = (node: TreeNode) => node.selectable !== false;
14
+
15
+ /**
16
+ * Settles a checkbox selection against the tree, the way a checkbox tree reads:
17
+ * - a checked parent has all of its selectable descendants checked;
18
+ * - a parent is checked when all of its selectable children are, partially checked when some are, and
19
+ * unchecked otherwise;
20
+ * - a node that is not selectable, and has nothing selectable below it, takes no part.
21
+ *
22
+ * Applying this to what the user toggled, or to an authored selection, is what keeps both consistent.
23
+ *
24
+ * @param nodes The root nodes.
25
+ * @param requested The keys asked for.
26
+ */
27
+ export function settleSelection(nodes: TreeNode[], requested: ReadonlySet<string>): SettledSelection {
28
+ const cascaded = new Set<string>();
29
+ const cascade = (node: TreeNode, inherited: boolean) => {
30
+ const on = inherited || requested.has(node.key ?? '');
31
+ if (on) cascaded.add(node.key ?? '');
32
+ node.children?.forEach(child => cascade(child, on));
33
+ };
34
+ nodes.forEach(node => cascade(node, false));
35
+
36
+ const checked = new Set<string>();
37
+ const states = new Map<string, TreeTableCheckState>();
38
+ const settle = (node: TreeNode): TreeTableCheckState | undefined => {
39
+ const key = node.key ?? '';
40
+ const childStates = (node.children ?? []).map(settle).filter((state): state is TreeTableCheckState => state !== undefined);
41
+ let state: TreeTableCheckState | undefined;
42
+ if (childStates.length === 0) {
43
+ state = selectable(node) ? (cascaded.has(key) ? TreeTableCheckState.Checked : TreeTableCheckState.Unchecked) : undefined;
44
+ } else if (childStates.every(child => child === TreeTableCheckState.Checked)) {
45
+ state = TreeTableCheckState.Checked;
46
+ } else {
47
+ state = childStates.some(child => child !== TreeTableCheckState.Unchecked) ? TreeTableCheckState.Partial : TreeTableCheckState.Unchecked;
48
+ }
49
+
50
+ if (state !== undefined) states.set(key, state);
51
+ if (state === TreeTableCheckState.Checked) checked.add(key);
52
+ return state;
53
+ };
54
+ nodes.forEach(settle);
55
+
56
+ return { checked, states };
57
+ }
58
+
59
+ /**
60
+ * Toggles one row's checkbox: a checked row unchecks its whole subtree, any other row checks it.
61
+ *
62
+ * @param nodes The root nodes.
63
+ * @param settled The current settled selection.
64
+ * @param node The row's node.
65
+ * @returns The keys to settle again.
66
+ */
67
+ export function toggleCheckbox(nodes: TreeNode[], settled: SettledSelection, node: TreeNode): Set<string> {
68
+ const subtree: string[] = [];
69
+ const collect = (current: TreeNode) => {
70
+ subtree.push(current.key ?? '');
71
+ current.children?.forEach(collect);
72
+ };
73
+ collect(node);
74
+
75
+ const next = new Set(settled.checked);
76
+ const checking = settled.states.get(node.key ?? '') !== TreeTableCheckState.Checked;
77
+ subtree.forEach(key => { if (checking) next.add(key); else next.delete(key); });
78
+
79
+ // A checked ancestor would check the unchecked subtree again, so unchecking also unchecks the ancestors.
80
+ if (!checking) (ancestorKeys(nodes, node.key ?? '') ?? []).forEach(key => next.delete(key));
81
+ return settleSelection(nodes, next).checked;
82
+ }
83
+
84
+ function ancestorKeys(nodes: TreeNode[], key: string, path: string[] = []): string[] | undefined {
85
+ for (const node of nodes) {
86
+ if (node.key === key) return path;
87
+ const found = ancestorKeys(node.children ?? [], key, [...path, node.key ?? '']);
88
+ if (found !== undefined) return found;
89
+ }
90
+
91
+ return undefined;
92
+ }
package/data/index.ts CHANGED
@@ -13,3 +13,7 @@ export * from './PrimePaginator';
13
13
  export * from './PrimeOrderList';
14
14
  export * from './PrimePickList';
15
15
  export * from './PrimeOrganizationChart';
16
+ export * from './PrimeDataScroller';
17
+ export * from './PrimeTreeTable';
18
+ export * from './TreeTableSelectionMode';
19
+ export * from './readableValue';
@@ -0,0 +1,30 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /**
5
+ * Whether an entry is a serialized legacy UI element - an object that names its type in `_derivedTypeId`.
6
+ *
7
+ * The original `ItemsControl.Items` and `TreeTable.Columns` held UI elements, not data. Scene does not
8
+ * read those shapes and has no runtime adapter for them: the controls recognize them only to refuse them
9
+ * visibly, instead of listing the element's fields as if they were rows. Converting them is the migration
10
+ * tool's job, which maps each element to a canonical slot (see the package documentation).
11
+ *
12
+ * @param entry An entry of `items` or `columns`.
13
+ */
14
+ export function isSerializedLegacyElement(entry: unknown): boolean {
15
+ return typeof entry === 'object' && entry !== null && !Array.isArray(entry) && typeof (entry as { _derivedTypeId?: unknown })._derivedTypeId === 'string';
16
+ }
17
+
18
+ /**
19
+ * The message for entries that were refused, or `undefined` when there were none.
20
+ *
21
+ * @param entries The authored entries.
22
+ * @param property The property they came from.
23
+ * @param guidance What the author should do instead, finishing the sentence "Author them ..." or similar.
24
+ */
25
+ export function legacyElementMessage(entries: unknown[], property: string, guidance: string): string | undefined {
26
+ const refused = entries.filter(isSerializedLegacyElement).length;
27
+ return refused === 0
28
+ ? undefined
29
+ : `${refused} entr${refused === 1 ? 'y' : 'ies'} of ${property} ${refused === 1 ? 'is a' : 'are'} serialized legacy UI element${refused === 1 ? '' : 's'}, which this control does not read. ${guidance}`;
30
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /** Nested deeper than this is shown as an ellipsis, so a cyclic or enormous value cannot flood the page. */
5
+ const maximumDepth = 3;
6
+
7
+ /**
8
+ * Writes any authored value as text a person can read.
9
+ *
10
+ * Scalars are shown as they are. An array is its readable entries joined by commas, and an object is
11
+ * `name: value` pairs joined by semicolons - never `[object Object]`, and never a raw JSON document. `null`
12
+ * and `undefined` are empty.
13
+ *
14
+ * @param value The authored value.
15
+ * @param depth How deep the value is nested already; callers leave it out.
16
+ */
17
+ export function readableValue(value: unknown, depth = 0): string {
18
+ if (value === undefined || value === null) return '';
19
+ if (typeof value === 'string') return value;
20
+ if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') return String(value);
21
+ if (depth >= maximumDepth) return '…';
22
+ if (Array.isArray(value)) return value.map(entry => readableValue(entry, depth + 1)).filter(text => text !== '').join(', ');
23
+ if (typeof value === 'object') {
24
+ return Object.entries(value)
25
+ .map(([name, entry]) => [name, readableValue(entry, depth + 1)])
26
+ .filter(([, text]) => text !== '')
27
+ .map(([name, text]) => `${name}: ${text}`)
28
+ .join('; ');
29
+ }
30
+
31
+ return '';
32
+ }
@@ -0,0 +1,40 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ /** The keys of one node, whichever of the shapes a selection may use. */
5
+ function keyOf(value: unknown): string | undefined {
6
+ if (typeof value === 'string' && value !== '') return value;
7
+ return typeof value === 'number' && Number.isFinite(value) ? String(value) : undefined;
8
+ }
9
+
10
+ function nodeKeyOf(value: unknown): string | undefined {
11
+ if (typeof value !== 'object' || value === null || Array.isArray(value)) return keyOf(value);
12
+ return keyOf((value as { key?: unknown }).key);
13
+ }
14
+
15
+ /**
16
+ * Reads the keys an authored `selection` selects.
17
+ *
18
+ * Every shape a legacy document may hold is accepted, and none is rewritten:
19
+ * - one key, string or number (`'b'`, `6`);
20
+ * - an array mixing keys and `{ key }` objects (`['a', 6, { key: 'c' }]`);
21
+ * - one `{ key }` object;
22
+ * - PrimeReact's key map (`{ b: { checked: true, partialChecked: false } }`), whose `checked` entries are
23
+ * selected. A `partialChecked` entry is derived state, not a selection, so it is ignored: the control
24
+ * computes it from the selected descendants.
25
+ *
26
+ * Numeric keys are matched as the strings the tree builds from them.
27
+ *
28
+ * @param value The authored selection.
29
+ */
30
+ export function selectionKeysOf(value: unknown): Set<string> {
31
+ if (Array.isArray(value)) return new Set(value.flatMap(entry => nodeKeyOf(entry) ?? []));
32
+ const single = nodeKeyOf(value);
33
+ if (single !== undefined) return new Set([single]);
34
+
35
+ if (typeof value === 'object' && value !== null && keyOf((value as { key?: unknown }).key) === undefined) {
36
+ return new Set(Object.entries(value).filter(([, state]) => (state as { checked?: unknown } | null)?.checked === true).map(([key]) => key));
37
+ }
38
+
39
+ return new Set();
40
+ }
@@ -0,0 +1,32 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { TreeNode } from '../TreeNode';
5
+ import { TreeTableRow } from './TreeTableRow';
6
+
7
+ /**
8
+ * Flattens the nodes into the rows that are visible: a node's children follow it only while it is expanded.
9
+ *
10
+ * @param nodes The sibling nodes to flatten.
11
+ * @param expanded The keys of the expanded nodes.
12
+ */
13
+ export function visibleRows(nodes: TreeNode[], expanded: ReadonlySet<string>, depth = 0, parentKey?: string): TreeTableRow[] {
14
+ return nodes.flatMap((node, index) => {
15
+ const key = node.key ?? '';
16
+ const row: TreeTableRow = { node, key, depth, parentKey, position: index + 1, siblings: nodes.length };
17
+ return [row, ...(node.children !== undefined && expanded.has(key) ? visibleRows(node.children, expanded, depth + 1, key) : [])];
18
+ });
19
+ }
20
+
21
+ /** The keys of the nodes authored as expanded, at any depth, in tree order. */
22
+ export function expandedKeysOf(nodes: TreeNode[]): string[] {
23
+ return nodes.flatMap(node => [
24
+ ...(node.expanded === true && node.key !== undefined ? [node.key] : []),
25
+ ...expandedKeysOf(node.children ?? []),
26
+ ]);
27
+ }
28
+
29
+ /** A node's own text for naming it: its label, else its key. */
30
+ export function nodeLabel(node: TreeNode): string {
31
+ return node.label ?? node.key ?? '';
32
+ }
@@ -0,0 +1,36 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { useCallback, useState } from 'react';
5
+
6
+ /** How much of a list is loaded and how to load more. */
7
+ export interface IncrementalLoad {
8
+ /** The number of entries loaded, never more than the total. */
9
+ loaded: number;
10
+
11
+ /** Loads the next chunk. */
12
+ loadMore(): void;
13
+ }
14
+
15
+ /**
16
+ * Tracks how many entries of a list are loaded, a chunk at a time.
17
+ *
18
+ * The count follows the authored properties: it starts over at one chunk when the chunk size changes or when
19
+ * `resetKey` does, so a document edit that replaces the items does not leave the old count behind. Pass a
20
+ * structurally stable `resetKey` (see `useStructuralValue`), or every render would reset it.
21
+ *
22
+ * @param total The number of entries there are.
23
+ * @param chunk The number of entries per load.
24
+ * @param resetKey Changes when the entries are replaced.
25
+ */
26
+ export function useIncrementalLoad(total: number, chunk: number, resetKey: unknown): IncrementalLoad {
27
+ const [state, setState] = useState({ resetKey, chunk, loaded: chunk });
28
+ let loaded = state.loaded;
29
+ if (state.resetKey !== resetKey || state.chunk !== chunk) {
30
+ setState({ resetKey, chunk, loaded: chunk });
31
+ loaded = chunk;
32
+ }
33
+
34
+ const loadMore = useCallback(() => setState(current => ({ ...current, loaded: Math.min(current.loaded + chunk, total) })), [chunk, total]);
35
+ return { loaded: Math.min(loaded, total), loadMore };
36
+ }
@@ -0,0 +1,31 @@
1
+ // Copyright (c) Cratis. All rights reserved.
2
+ // Licensed under the MIT license. See LICENSE file in the project root for full license information.
3
+
4
+ import { RefObject, useEffect } from 'react';
5
+
6
+ /**
7
+ * Calls `onReach` while the sentinel is visible, which is what scrolling to the end of a list means.
8
+ *
9
+ * The observer is rebuilt whenever `revision` changes, so a sentinel that is still visible after a chunk was
10
+ * loaded loads the next one, until the viewport is filled or the list ends. `root` is the element that
11
+ * scrolls for an inline list; `null` observes the page's own viewport. Where there is no
12
+ * `IntersectionObserver` nothing is observed and the list's own button remains the way to load more.
13
+ *
14
+ * @param sentinel The element placed after the last loaded entry.
15
+ * @param root The scrolling container, or `null` for the page.
16
+ * @param active Whether reaching the end should load anything.
17
+ * @param revision A value that changes each time the list changed.
18
+ * @param onReach Loads the next chunk.
19
+ */
20
+ export function useLoadOnReach(sentinel: RefObject<HTMLElement | null>, root: RefObject<HTMLElement | null> | null, active: boolean, revision: unknown, onReach: () => void): void {
21
+ useEffect(() => {
22
+ const target = sentinel.current;
23
+ if (!active || target === null || typeof IntersectionObserver === 'undefined') return undefined;
24
+
25
+ const observer = new IntersectionObserver(entries => {
26
+ if (entries.some(entry => entry.isIntersecting)) onReach();
27
+ }, { root: root?.current ?? null, rootMargin: '0px 0px 48px 0px' });
28
+ observer.observe(target);
29
+ return () => observer.disconnect();
30
+ }, [sentinel, root, active, revision, onReach]);
31
+ }