@cratis/scene.primereact 4.6.0 → 4.8.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 (388) hide show
  1. package/.storybook/preview.tsx +8 -1
  2. package/EnumerationResolution.ts +7 -0
  3. package/README.md +22 -12
  4. package/data/DataGallery.stories.tsx +6 -0
  5. package/data/DataScrollerRow.tsx +35 -0
  6. package/data/PrimeDataScroller.tsx +84 -0
  7. package/data/PrimeTreeTable.tsx +145 -0
  8. package/data/TreeTableCheckState.ts +9 -0
  9. package/data/TreeTableRow.ts +22 -0
  10. package/data/TreeTableRowView.tsx +86 -0
  11. package/data/TreeTableSelectionMode.ts +10 -0
  12. package/data/checkboxSelection.ts +92 -0
  13. package/data/index.ts +4 -0
  14. package/data/isSerializedLegacyElement.ts +30 -0
  15. package/data/readableValue.ts +32 -0
  16. package/data/selectionKeysOf.ts +40 -0
  17. package/data/treeTableRows.ts +32 -0
  18. package/data/useIncrementalLoad.ts +36 -0
  19. package/data/useLoadOnReach.ts +31 -0
  20. package/data/useTreeGridNavigation.ts +81 -0
  21. package/dist/cjs/data/DataScrollerRow.js +50 -0
  22. package/dist/cjs/data/DataScrollerRow.js.map +1 -0
  23. package/dist/cjs/data/PrimeDataScroller.js +120 -0
  24. package/dist/cjs/data/PrimeDataScroller.js.map +1 -0
  25. package/dist/cjs/data/PrimeTreeTable.js +217 -0
  26. package/dist/cjs/data/PrimeTreeTable.js.map +1 -0
  27. package/dist/cjs/data/TreeTableCheckState.js +13 -0
  28. package/dist/cjs/data/TreeTableCheckState.js.map +1 -0
  29. package/dist/cjs/data/TreeTableRowView.js +76 -0
  30. package/dist/cjs/data/TreeTableRowView.js.map +1 -0
  31. package/dist/cjs/data/TreeTableSelectionMode.js +14 -0
  32. package/dist/cjs/data/TreeTableSelectionMode.js.map +1 -0
  33. package/dist/cjs/data/checkboxSelection.js +88 -0
  34. package/dist/cjs/data/checkboxSelection.js.map +1 -0
  35. package/dist/cjs/data/isSerializedLegacyElement.js +30 -0
  36. package/dist/cjs/data/isSerializedLegacyElement.js.map +1 -0
  37. package/dist/cjs/data/readableValue.js +31 -0
  38. package/dist/cjs/data/readableValue.js.map +1 -0
  39. package/dist/cjs/data/selectionKeysOf.js +40 -0
  40. package/dist/cjs/data/selectionKeysOf.js.map +1 -0
  41. package/dist/cjs/data/treeTableRows.js +42 -0
  42. package/dist/cjs/data/treeTableRows.js.map +1 -0
  43. package/dist/cjs/data/useIncrementalLoad.js +46 -0
  44. package/dist/cjs/data/useIncrementalLoad.js.map +1 -0
  45. package/dist/cjs/data/useLoadOnReach.js +42 -0
  46. package/dist/cjs/data/useLoadOnReach.js.map +1 -0
  47. package/dist/cjs/data/useTreeGridNavigation.js +75 -0
  48. package/dist/cjs/data/useTreeGridNavigation.js.map +1 -0
  49. package/dist/cjs/editor/PrimeEditor.js +96 -0
  50. package/dist/cjs/editor/PrimeEditor.js.map +1 -0
  51. package/dist/cjs/editor/QuillLoaderContext.js +10 -0
  52. package/dist/cjs/editor/QuillLoaderContext.js.map +1 -0
  53. package/dist/cjs/editor/QuillLoaderProvider.js +21 -0
  54. package/dist/cjs/editor/QuillLoaderProvider.js.map +1 -0
  55. package/dist/cjs/editor/applyHtml.js +25 -0
  56. package/dist/cjs/editor/applyHtml.js.map +1 -0
  57. package/dist/cjs/editor/characterCount.js +10 -0
  58. package/dist/cjs/editor/characterCount.js.map +1 -0
  59. package/dist/cjs/editor/htmlToPlainText.js +101 -0
  60. package/dist/cjs/editor/htmlToPlainText.js.map +1 -0
  61. package/dist/cjs/editor/renderSafeNodes.js +35 -0
  62. package/dist/cjs/editor/renderSafeNodes.js.map +1 -0
  63. package/dist/cjs/editor/safeUrls.js +44 -0
  64. package/dist/cjs/editor/safeUrls.js.map +1 -0
  65. package/dist/cjs/editor/sanitizeHtml.js +140 -0
  66. package/dist/cjs/editor/sanitizeHtml.js.map +1 -0
  67. package/dist/cjs/editor/serializeSafeNodes.js +33 -0
  68. package/dist/cjs/editor/serializeSafeNodes.js.map +1 -0
  69. package/dist/cjs/editor/toolbarLayout.js +35 -0
  70. package/dist/cjs/editor/toolbarLayout.js.map +1 -0
  71. package/dist/cjs/editor/useQuillEditor.js +137 -0
  72. package/dist/cjs/editor/useQuillEditor.js.map +1 -0
  73. package/dist/cjs/file/FileUploadContext.js +13 -0
  74. package/dist/cjs/file/FileUploadContext.js.map +1 -0
  75. package/dist/cjs/file/FileUploadHandlerProvider.js +25 -0
  76. package/dist/cjs/file/FileUploadHandlerProvider.js.map +1 -0
  77. package/dist/cjs/file/FileUploadMode.js +13 -0
  78. package/dist/cjs/file/FileUploadMode.js.map +1 -0
  79. package/dist/cjs/file/PrimeFileUpload.js +161 -0
  80. package/dist/cjs/file/PrimeFileUpload.js.map +1 -0
  81. package/dist/cjs/file/postFiles.js +31 -0
  82. package/dist/cjs/file/postFiles.js.map +1 -0
  83. package/dist/cjs/file/resolveUploadTarget.js +68 -0
  84. package/dist/cjs/file/resolveUploadTarget.js.map +1 -0
  85. package/dist/cjs/file/useUploadSession.js +62 -0
  86. package/dist/cjs/file/useUploadSession.js.map +1 -0
  87. package/dist/cjs/index.js +32 -0
  88. package/dist/cjs/index.js.map +1 -1
  89. package/dist/cjs/legacyEnumerationChoices.js +39 -0
  90. package/dist/cjs/legacyEnumerationChoices.js.map +1 -0
  91. package/dist/cjs/loadQuill/index.js +22 -0
  92. package/dist/cjs/loadQuill/index.js.map +1 -0
  93. package/dist/cjs/primeReactComponents.js +10 -0
  94. package/dist/cjs/primeReactComponents.js.map +1 -1
  95. package/dist/cjs/primeReactDescriptors.js +243 -0
  96. package/dist/cjs/primeReactDescriptors.js.map +1 -1
  97. package/dist/cjs/primeReactPackage.js +4 -0
  98. package/dist/cjs/primeReactPackage.js.map +1 -1
  99. package/dist/cjs/resolveEnumeration.js +55 -0
  100. package/dist/cjs/resolveEnumeration.js.map +1 -0
  101. package/dist/cjs/treeNodes.js +42 -7
  102. package/dist/cjs/treeNodes.js.map +1 -1
  103. package/dist/cjs/useResettingState.js +47 -0
  104. package/dist/cjs/useResettingState.js.map +1 -0
  105. package/dist/esm/EnumerationResolution.d.ts +9 -0
  106. package/dist/esm/EnumerationResolution.d.ts.map +1 -0
  107. package/dist/esm/EnumerationResolution.js +2 -0
  108. package/dist/esm/EnumerationResolution.js.map +1 -0
  109. package/dist/esm/data/DataGallery.stories.d.ts.map +1 -1
  110. package/dist/esm/data/DataGallery.stories.js +6 -0
  111. package/dist/esm/data/DataGallery.stories.js.map +1 -1
  112. package/dist/esm/data/DataScrollerRow.d.ts +4 -0
  113. package/dist/esm/data/DataScrollerRow.d.ts.map +1 -0
  114. package/dist/esm/data/DataScrollerRow.js +48 -0
  115. package/dist/esm/data/DataScrollerRow.js.map +1 -0
  116. package/dist/esm/data/PrimeDataScroller.d.ts +3 -0
  117. package/dist/esm/data/PrimeDataScroller.d.ts.map +1 -0
  118. package/dist/esm/data/PrimeDataScroller.js +118 -0
  119. package/dist/esm/data/PrimeDataScroller.js.map +1 -0
  120. package/dist/esm/data/PrimeTreeTable.d.ts +3 -0
  121. package/dist/esm/data/PrimeTreeTable.d.ts.map +1 -0
  122. package/dist/esm/data/PrimeTreeTable.js +215 -0
  123. package/dist/esm/data/PrimeTreeTable.js.map +1 -0
  124. package/dist/esm/data/TreeTableCheckState.d.ts +6 -0
  125. package/dist/esm/data/TreeTableCheckState.d.ts.map +1 -0
  126. package/dist/esm/data/TreeTableCheckState.js +11 -0
  127. package/dist/esm/data/TreeTableCheckState.js.map +1 -0
  128. package/dist/esm/data/TreeTableRow.d.ts +10 -0
  129. package/dist/esm/data/TreeTableRow.d.ts.map +1 -0
  130. package/dist/esm/data/TreeTableRow.js +2 -0
  131. package/dist/esm/data/TreeTableRow.js.map +1 -0
  132. package/dist/esm/data/TreeTableRowView.d.ts +21 -0
  133. package/dist/esm/data/TreeTableRowView.d.ts.map +1 -0
  134. package/dist/esm/data/TreeTableRowView.js +74 -0
  135. package/dist/esm/data/TreeTableRowView.js.map +1 -0
  136. package/dist/esm/data/TreeTableSelectionMode.d.ts +7 -0
  137. package/dist/esm/data/TreeTableSelectionMode.d.ts.map +1 -0
  138. package/dist/esm/data/TreeTableSelectionMode.js +12 -0
  139. package/dist/esm/data/TreeTableSelectionMode.js.map +1 -0
  140. package/dist/esm/data/checkboxSelection.d.ts +9 -0
  141. package/dist/esm/data/checkboxSelection.d.ts.map +1 -0
  142. package/dist/esm/data/checkboxSelection.js +85 -0
  143. package/dist/esm/data/checkboxSelection.js.map +1 -0
  144. package/dist/esm/data/index.d.ts +4 -0
  145. package/dist/esm/data/index.d.ts.map +1 -1
  146. package/dist/esm/data/index.js +4 -0
  147. package/dist/esm/data/index.js.map +1 -1
  148. package/dist/esm/data/isSerializedLegacyElement.d.ts +3 -0
  149. package/dist/esm/data/isSerializedLegacyElement.d.ts.map +1 -0
  150. package/dist/esm/data/isSerializedLegacyElement.js +27 -0
  151. package/dist/esm/data/isSerializedLegacyElement.js.map +1 -0
  152. package/dist/esm/data/readableValue.d.ts +2 -0
  153. package/dist/esm/data/readableValue.d.ts.map +1 -0
  154. package/dist/esm/data/readableValue.js +29 -0
  155. package/dist/esm/data/readableValue.js.map +1 -0
  156. package/dist/esm/data/selectionKeysOf.d.ts +2 -0
  157. package/dist/esm/data/selectionKeysOf.d.ts.map +1 -0
  158. package/dist/esm/data/selectionKeysOf.js +38 -0
  159. package/dist/esm/data/selectionKeysOf.js.map +1 -0
  160. package/dist/esm/data/treeTableRows.d.ts +6 -0
  161. package/dist/esm/data/treeTableRows.d.ts.map +1 -0
  162. package/dist/esm/data/treeTableRows.js +38 -0
  163. package/dist/esm/data/treeTableRows.js.map +1 -0
  164. package/dist/esm/data/useIncrementalLoad.d.ts +6 -0
  165. package/dist/esm/data/useIncrementalLoad.d.ts.map +1 -0
  166. package/dist/esm/data/useIncrementalLoad.js +44 -0
  167. package/dist/esm/data/useIncrementalLoad.js.map +1 -0
  168. package/dist/esm/data/useLoadOnReach.d.ts +3 -0
  169. package/dist/esm/data/useLoadOnReach.d.ts.map +1 -0
  170. package/dist/esm/data/useLoadOnReach.js +40 -0
  171. package/dist/esm/data/useLoadOnReach.js.map +1 -0
  172. package/dist/esm/data/useTreeGridNavigation.d.ts +17 -0
  173. package/dist/esm/data/useTreeGridNavigation.d.ts.map +1 -0
  174. package/dist/esm/data/useTreeGridNavigation.js +73 -0
  175. package/dist/esm/data/useTreeGridNavigation.js.map +1 -0
  176. package/dist/esm/editor/PrimeEditor.d.ts +3 -0
  177. package/dist/esm/editor/PrimeEditor.d.ts.map +1 -0
  178. package/dist/esm/editor/PrimeEditor.js +94 -0
  179. package/dist/esm/editor/PrimeEditor.js.map +1 -0
  180. package/dist/esm/editor/QuillConstructor.d.ts +4 -0
  181. package/dist/esm/editor/QuillConstructor.d.ts.map +1 -0
  182. package/dist/esm/editor/QuillConstructor.js +2 -0
  183. package/dist/esm/editor/QuillConstructor.js.map +1 -0
  184. package/dist/esm/editor/QuillEditorOptions.d.ts +13 -0
  185. package/dist/esm/editor/QuillEditorOptions.d.ts.map +1 -0
  186. package/dist/esm/editor/QuillEditorOptions.js +2 -0
  187. package/dist/esm/editor/QuillEditorOptions.js.map +1 -0
  188. package/dist/esm/editor/QuillEditorState.d.ts +6 -0
  189. package/dist/esm/editor/QuillEditorState.d.ts.map +1 -0
  190. package/dist/esm/editor/QuillEditorState.js +2 -0
  191. package/dist/esm/editor/QuillEditorState.js.map +1 -0
  192. package/dist/esm/editor/QuillInstance.d.ts +16 -0
  193. package/dist/esm/editor/QuillInstance.d.ts.map +1 -0
  194. package/dist/esm/editor/QuillInstance.js +2 -0
  195. package/dist/esm/editor/QuillInstance.js.map +1 -0
  196. package/dist/esm/editor/QuillLoader.d.ts +5 -0
  197. package/dist/esm/editor/QuillLoader.d.ts.map +1 -0
  198. package/dist/esm/editor/QuillLoader.js +2 -0
  199. package/dist/esm/editor/QuillLoader.js.map +1 -0
  200. package/dist/esm/editor/QuillLoaderContext.d.ts +3 -0
  201. package/dist/esm/editor/QuillLoaderContext.d.ts.map +1 -0
  202. package/dist/esm/editor/QuillLoaderContext.js +8 -0
  203. package/dist/esm/editor/QuillLoaderContext.js.map +1 -0
  204. package/dist/esm/editor/QuillLoaderProvider.d.ts +8 -0
  205. package/dist/esm/editor/QuillLoaderProvider.d.ts.map +1 -0
  206. package/dist/esm/editor/QuillLoaderProvider.js +19 -0
  207. package/dist/esm/editor/QuillLoaderProvider.js.map +1 -0
  208. package/dist/esm/editor/QuillOptions.d.ts +9 -0
  209. package/dist/esm/editor/QuillOptions.d.ts.map +1 -0
  210. package/dist/esm/editor/QuillOptions.js +2 -0
  211. package/dist/esm/editor/QuillOptions.js.map +1 -0
  212. package/dist/esm/editor/SafeElement.d.ts +7 -0
  213. package/dist/esm/editor/SafeElement.d.ts.map +1 -0
  214. package/dist/esm/editor/SafeElement.js +2 -0
  215. package/dist/esm/editor/SafeElement.js.map +1 -0
  216. package/dist/esm/editor/SafeNode.d.ts +3 -0
  217. package/dist/esm/editor/SafeNode.d.ts.map +1 -0
  218. package/dist/esm/editor/SafeNode.js +2 -0
  219. package/dist/esm/editor/SafeNode.js.map +1 -0
  220. package/dist/esm/editor/applyHtml.d.ts +3 -0
  221. package/dist/esm/editor/applyHtml.d.ts.map +1 -0
  222. package/dist/esm/editor/applyHtml.js +23 -0
  223. package/dist/esm/editor/applyHtml.js.map +1 -0
  224. package/dist/esm/editor/characterCount.d.ts +3 -0
  225. package/dist/esm/editor/characterCount.d.ts.map +1 -0
  226. package/dist/esm/editor/characterCount.js +8 -0
  227. package/dist/esm/editor/characterCount.js.map +1 -0
  228. package/dist/esm/editor/htmlToPlainText.d.ts +2 -0
  229. package/dist/esm/editor/htmlToPlainText.d.ts.map +1 -0
  230. package/dist/esm/editor/htmlToPlainText.js +99 -0
  231. package/dist/esm/editor/htmlToPlainText.js.map +1 -0
  232. package/dist/esm/editor/index.d.ts +14 -0
  233. package/dist/esm/editor/index.d.ts.map +1 -0
  234. package/dist/esm/editor/index.js +14 -0
  235. package/dist/esm/editor/index.js.map +1 -0
  236. package/dist/esm/editor/renderSafeNodes.d.ts +4 -0
  237. package/dist/esm/editor/renderSafeNodes.d.ts.map +1 -0
  238. package/dist/esm/editor/renderSafeNodes.js +33 -0
  239. package/dist/esm/editor/renderSafeNodes.js.map +1 -0
  240. package/dist/esm/editor/safeUrls.d.ts +3 -0
  241. package/dist/esm/editor/safeUrls.d.ts.map +1 -0
  242. package/dist/esm/editor/safeUrls.js +41 -0
  243. package/dist/esm/editor/safeUrls.js.map +1 -0
  244. package/dist/esm/editor/sanitizeHtml.d.ts +3 -0
  245. package/dist/esm/editor/sanitizeHtml.d.ts.map +1 -0
  246. package/dist/esm/editor/sanitizeHtml.js +138 -0
  247. package/dist/esm/editor/sanitizeHtml.js.map +1 -0
  248. package/dist/esm/editor/serializeSafeNodes.d.ts +3 -0
  249. package/dist/esm/editor/serializeSafeNodes.d.ts.map +1 -0
  250. package/dist/esm/editor/serializeSafeNodes.js +31 -0
  251. package/dist/esm/editor/serializeSafeNodes.js.map +1 -0
  252. package/dist/esm/editor/toolbarLayout.d.ts +2 -0
  253. package/dist/esm/editor/toolbarLayout.d.ts.map +1 -0
  254. package/dist/esm/editor/toolbarLayout.js +33 -0
  255. package/dist/esm/editor/toolbarLayout.js.map +1 -0
  256. package/dist/esm/editor/useQuillEditor.d.ts +4 -0
  257. package/dist/esm/editor/useQuillEditor.d.ts.map +1 -0
  258. package/dist/esm/editor/useQuillEditor.js +135 -0
  259. package/dist/esm/editor/useQuillEditor.js.map +1 -0
  260. package/dist/esm/file/FileGallery.stories.d.ts +19 -0
  261. package/dist/esm/file/FileGallery.stories.d.ts.map +1 -0
  262. package/dist/esm/file/FileGallery.stories.js +23 -0
  263. package/dist/esm/file/FileGallery.stories.js.map +1 -0
  264. package/dist/esm/file/FileUploadContext.d.ts +7 -0
  265. package/dist/esm/file/FileUploadContext.d.ts.map +1 -0
  266. package/dist/esm/file/FileUploadContext.js +11 -0
  267. package/dist/esm/file/FileUploadContext.js.map +1 -0
  268. package/dist/esm/file/FileUploadHandler.d.ts +4 -0
  269. package/dist/esm/file/FileUploadHandler.d.ts.map +1 -0
  270. package/dist/esm/file/FileUploadHandler.js +2 -0
  271. package/dist/esm/file/FileUploadHandler.js.map +1 -0
  272. package/dist/esm/file/FileUploadHandlerProvider.d.ts +9 -0
  273. package/dist/esm/file/FileUploadHandlerProvider.d.ts.map +1 -0
  274. package/dist/esm/file/FileUploadHandlerProvider.js +23 -0
  275. package/dist/esm/file/FileUploadHandlerProvider.js.map +1 -0
  276. package/dist/esm/file/FileUploadMode.d.ts +6 -0
  277. package/dist/esm/file/FileUploadMode.d.ts.map +1 -0
  278. package/dist/esm/file/FileUploadMode.js +11 -0
  279. package/dist/esm/file/FileUploadMode.js.map +1 -0
  280. package/dist/esm/file/PrimeFileUpload.d.ts +3 -0
  281. package/dist/esm/file/PrimeFileUpload.d.ts.map +1 -0
  282. package/dist/esm/file/PrimeFileUpload.js +159 -0
  283. package/dist/esm/file/PrimeFileUpload.js.map +1 -0
  284. package/dist/esm/file/UploadStatus.d.ts +5 -0
  285. package/dist/esm/file/UploadStatus.d.ts.map +1 -0
  286. package/dist/esm/file/UploadStatus.js +2 -0
  287. package/dist/esm/file/UploadStatus.js.map +1 -0
  288. package/dist/esm/file/UploadTarget.d.ts +8 -0
  289. package/dist/esm/file/UploadTarget.d.ts.map +1 -0
  290. package/dist/esm/file/UploadTarget.js +2 -0
  291. package/dist/esm/file/UploadTarget.js.map +1 -0
  292. package/dist/esm/file/index.d.ts +7 -0
  293. package/dist/esm/file/index.d.ts.map +1 -0
  294. package/dist/esm/file/index.js +7 -0
  295. package/dist/esm/file/index.js.map +1 -0
  296. package/dist/esm/file/postFiles.d.ts +2 -0
  297. package/dist/esm/file/postFiles.d.ts.map +1 -0
  298. package/dist/esm/file/postFiles.js +29 -0
  299. package/dist/esm/file/postFiles.js.map +1 -0
  300. package/dist/esm/file/resolveUploadTarget.d.ts +3 -0
  301. package/dist/esm/file/resolveUploadTarget.d.ts.map +1 -0
  302. package/dist/esm/file/resolveUploadTarget.js +66 -0
  303. package/dist/esm/file/resolveUploadTarget.js.map +1 -0
  304. package/dist/esm/file/useUploadSession.d.ts +10 -0
  305. package/dist/esm/file/useUploadSession.d.ts.map +1 -0
  306. package/dist/esm/file/useUploadSession.js +60 -0
  307. package/dist/esm/file/useUploadSession.js.map +1 -0
  308. package/dist/esm/form/FormGallery.stories.d.ts.map +1 -1
  309. package/dist/esm/form/FormGallery.stories.js +1 -0
  310. package/dist/esm/form/FormGallery.stories.js.map +1 -1
  311. package/dist/esm/index.d.ts +2 -0
  312. package/dist/esm/index.d.ts.map +1 -1
  313. package/dist/esm/index.js +16 -1
  314. package/dist/esm/index.js.map +1 -1
  315. package/dist/esm/legacyEnumerationChoices.d.ts +3 -0
  316. package/dist/esm/legacyEnumerationChoices.d.ts.map +1 -0
  317. package/dist/esm/legacyEnumerationChoices.js +37 -0
  318. package/dist/esm/legacyEnumerationChoices.js.map +1 -0
  319. package/dist/esm/loadQuill/index.d.ts +3 -0
  320. package/dist/esm/loadQuill/index.d.ts.map +1 -0
  321. package/dist/esm/loadQuill/index.js +20 -0
  322. package/dist/esm/loadQuill/index.js.map +1 -0
  323. package/dist/esm/primeReactComponents.d.ts.map +1 -1
  324. package/dist/esm/primeReactComponents.js +10 -0
  325. package/dist/esm/primeReactComponents.js.map +1 -1
  326. package/dist/esm/primeReactDescriptors.d.ts.map +1 -1
  327. package/dist/esm/primeReactDescriptors.js +243 -0
  328. package/dist/esm/primeReactDescriptors.js.map +1 -1
  329. package/dist/esm/primeReactPackage.js +4 -0
  330. package/dist/esm/primeReactPackage.js.map +1 -1
  331. package/dist/esm/resolveEnumeration.d.ts +3 -0
  332. package/dist/esm/resolveEnumeration.d.ts.map +1 -0
  333. package/dist/esm/resolveEnumeration.js +53 -0
  334. package/dist/esm/resolveEnumeration.js.map +1 -0
  335. package/dist/esm/treeNodes.d.ts +2 -1
  336. package/dist/esm/treeNodes.d.ts.map +1 -1
  337. package/dist/esm/treeNodes.js +42 -8
  338. package/dist/esm/treeNodes.js.map +1 -1
  339. package/dist/esm/tsconfig.tsbuildinfo +1 -1
  340. package/dist/esm/useResettingState.d.ts +3 -0
  341. package/dist/esm/useResettingState.d.ts.map +1 -0
  342. package/dist/esm/useResettingState.js +45 -0
  343. package/dist/esm/useResettingState.js.map +1 -0
  344. package/editor/PrimeEditor.tsx +83 -0
  345. package/editor/QuillConstructor.ts +8 -0
  346. package/editor/QuillEditorOptions.ts +29 -0
  347. package/editor/QuillEditorState.ts +14 -0
  348. package/editor/QuillInstance.ts +27 -0
  349. package/editor/QuillLoader.ts +13 -0
  350. package/editor/QuillLoaderContext.ts +8 -0
  351. package/editor/QuillLoaderProvider.tsx +24 -0
  352. package/editor/QuillOptions.ts +10 -0
  353. package/editor/SafeElement.ts +15 -0
  354. package/editor/SafeNode.ts +7 -0
  355. package/editor/applyHtml.ts +21 -0
  356. package/editor/characterCount.ts +9 -0
  357. package/editor/htmlToPlainText.ts +74 -0
  358. package/editor/index.ts +16 -0
  359. package/editor/renderSafeNodes.tsx +26 -0
  360. package/editor/safeUrls.ts +43 -0
  361. package/editor/sanitizeHtml.ts +94 -0
  362. package/editor/serializeSafeNodes.ts +26 -0
  363. package/editor/toolbarLayout.ts +10 -0
  364. package/editor/useQuillEditor.ts +114 -0
  365. package/file/FileGallery.stories.tsx +32 -0
  366. package/file/FileUploadContext.ts +17 -0
  367. package/file/FileUploadHandler.ts +15 -0
  368. package/file/FileUploadHandlerProvider.tsx +33 -0
  369. package/file/FileUploadMode.ts +9 -0
  370. package/file/PrimeFileUpload.tsx +129 -0
  371. package/file/UploadStatus.ts +9 -0
  372. package/file/UploadTarget.ts +12 -0
  373. package/file/index.ts +9 -0
  374. package/file/postFiles.ts +23 -0
  375. package/file/resolveUploadTarget.ts +61 -0
  376. package/file/useUploadSession.ts +67 -0
  377. package/form/FormGallery.stories.tsx +1 -0
  378. package/index.ts +2 -0
  379. package/legacyEnumerationChoices.ts +35 -0
  380. package/loadQuill/index.ts +21 -0
  381. package/package.json +17 -7
  382. package/primeReactComponents.ts +8 -0
  383. package/primeReactDescriptors.ts +63 -0
  384. package/primeReactPackage.ts +2 -2
  385. package/primeReactTheme.css +69 -0
  386. package/resolveEnumeration.ts +50 -0
  387. package/treeNodes.ts +44 -6
  388. package/useResettingState.ts +34 -0
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cratis/scene.primereact",
3
- "version": "4.6.0",
3
+ "version": "4.8.0",
4
4
  "description": "The PrimeReact component package: maps Scene's abstract component names onto real PrimeReact components, and PrimeReact's free themes onto Scene themes.",
5
5
  "keywords": [
6
6
  "cratis",
@@ -38,6 +38,11 @@
38
38
  "require": "./dist/cjs/index.js",
39
39
  "import": "./dist/esm/index.js"
40
40
  },
41
+ "./quill": {
42
+ "types": "./dist/esm/loadQuill/index.d.ts",
43
+ "require": "./dist/cjs/loadQuill/index.js",
44
+ "import": "./dist/esm/loadQuill/index.js"
45
+ },
41
46
  "./primeReactTheme.css": "./primeReactTheme.css"
42
47
  },
43
48
  "scripts": {
@@ -54,15 +59,15 @@
54
59
  "build-storybook": "storybook build"
55
60
  },
56
61
  "dependencies": {
57
- "@cratis/scene.engine": "4.6.0",
58
- "@cratis/scene.model": "4.6.0",
59
- "@cratis/scene.react": "4.6.0",
62
+ "@cratis/scene.engine": "4.8.0",
63
+ "@cratis/scene.model": "4.8.0",
64
+ "@cratis/scene.react": "4.8.0",
60
65
  "@primeuix/themes": "^3.0.1"
61
66
  },
62
67
  "devDependencies": {
63
- "@cratis/scene.engine": "4.6.0",
64
- "@cratis/scene.model": "4.6.0",
65
- "@cratis/scene.react": "4.6.0",
68
+ "@cratis/scene.engine": "4.8.0",
69
+ "@cratis/scene.model": "4.8.0",
70
+ "@cratis/scene.react": "4.8.0",
66
71
  "@primereact/core": "11.2.0",
67
72
  "@primereact/headless": "11.2.0",
68
73
  "@primereact/types": "11.2.0",
@@ -74,6 +79,7 @@
74
79
  "playwright-core": "1.63.0",
75
80
  "primeicons": "8.0.2",
76
81
  "primereact": "11.2.0",
82
+ "quill": "2.0.3",
77
83
  "react": "^19.3.0",
78
84
  "react-dom": "^19.3.0",
79
85
  "storybook": "^10.6.1"
@@ -84,12 +90,16 @@
84
90
  "chart.js": "^4.5.1",
85
91
  "primeicons": "^8.0.0",
86
92
  "primereact": "^11.0.0",
93
+ "quill": "^2.0.3",
87
94
  "react": "^19.0.0",
88
95
  "react-dom": "^19.0.0"
89
96
  },
90
97
  "peerDependenciesMeta": {
91
98
  "chart.js": {
92
99
  "optional": true
100
+ },
101
+ "quill": {
102
+ "optional": true
93
103
  }
94
104
  }
95
105
  }
@@ -6,6 +6,7 @@ import { PrimeButton, PrimeButtonGroup, PrimeSpeedDial, PrimeSplitButton } from
6
6
  import { PrimeChart } from './chart';
7
7
  import {
8
8
  PrimeColumn,
9
+ PrimeDataScroller,
9
10
  PrimeDataTable,
10
11
  PrimeDataView,
11
12
  PrimeOrderList,
@@ -14,6 +15,7 @@ import {
14
15
  PrimePickList,
15
16
  PrimeTimeline,
16
17
  PrimeTree,
18
+ PrimeTreeTable,
17
19
  } from './data';
18
20
  import {
19
21
  PrimeAutoComplete,
@@ -39,6 +41,8 @@ import {
39
41
  PrimeToggleSwitch,
40
42
  PrimeTreeSelect,
41
43
  } from './form';
44
+ import { PrimeEditor } from './editor';
45
+ import { PrimeFileUpload } from './file';
42
46
  import { PrimeCarousel, PrimeGalleria, PrimeImage } from './media';
43
47
  import {
44
48
  PrimeBreadcrumb,
@@ -121,6 +125,8 @@ export const primeReactComponents: ComponentRegistry = {
121
125
  [componentRegistryKey('PrimeReact', 'chips')]: PrimeChips,
122
126
  [componentRegistryKey('PrimeReact', 'autoComplete')]: PrimeAutoComplete,
123
127
  [componentRegistryKey('PrimeReact', 'treeSelect')]: PrimeTreeSelect,
128
+ [componentRegistryKey('PrimeReact', 'editor')]: PrimeEditor,
129
+ [componentRegistryKey('PrimeReact', 'fileUpload')]: PrimeFileUpload,
124
130
 
125
131
  [componentRegistryKey('PrimeReact', 'button')]: PrimeButton,
126
132
  [componentRegistryKey('PrimeReact', 'splitButton')]: PrimeSplitButton,
@@ -131,7 +137,9 @@ export const primeReactComponents: ComponentRegistry = {
131
137
  [componentRegistryKey('PrimeReact', 'table')]: PrimeDataTable,
132
138
  [componentRegistryKey('PrimeReact', 'column')]: PrimeColumn,
133
139
  [componentRegistryKey('PrimeReact', 'dataView')]: PrimeDataView,
140
+ [componentRegistryKey('PrimeReact', 'dataScroller')]: PrimeDataScroller,
134
141
  [componentRegistryKey('PrimeReact', 'tree')]: PrimeTree,
142
+ [componentRegistryKey('PrimeReact', 'treeTable')]: PrimeTreeTable,
135
143
  [componentRegistryKey('PrimeReact', 'timeline')]: PrimeTimeline,
136
144
  [componentRegistryKey('PrimeReact', 'paginator')]: PrimePaginator,
137
145
  [componentRegistryKey('PrimeReact', 'orderList')]: PrimeOrderList,
@@ -4,7 +4,10 @@
4
4
  import { ComponentDescriptor, PropertyValueType } from '@cratis/scene.model';
5
5
  import { componentRegistryKey } from '@cratis/scene.react';
6
6
  import { chartTypeChoices } from './chart/chartTypeChoices';
7
+ import { legacyEnumerationChoices } from './legacyEnumerationChoices';
7
8
  import { ChartType } from './chart';
9
+ import { TreeTableSelectionMode } from './data';
10
+ import { FileUploadMode } from './file';
8
11
 
9
12
  const key = (name: string) => componentRegistryKey('PrimeReact', name);
10
13
 
@@ -27,6 +30,66 @@ export const primeReactDescriptors: ComponentDescriptor[] = [
27
30
  { path: 'ariaLabel', label: 'Accessible name', group: 'Accessibility', valueType: PropertyValueType.String },
28
31
  ],
29
32
  },
33
+ {
34
+ component: key('fileUpload'),
35
+ displayName: 'File upload',
36
+ description: 'An accessible file picker and drop zone. A host provides its upload effect, or the files are posted to the authored server URL. The URL must be on the page\'s own origin unless the host allows another one.',
37
+ properties: [
38
+ {
39
+ path: 'mode', label: 'Mode', group: 'Behavior', valueType: PropertyValueType.Enum, default: FileUploadMode.Advanced,
40
+ choices: legacyEnumerationChoices(FileUploadMode, { [FileUploadMode.Advanced]: 'Advanced', [FileUploadMode.Basic]: 'Basic', [FileUploadMode.Auto]: 'Automatic' }),
41
+ },
42
+ { path: 'url', label: 'Server URL', group: 'Upload', valueType: PropertyValueType.String, description: 'Where the files are posted. Only the origin of the page, or an origin the host allows, is accepted; anything else is refused and nothing is sent.' },
43
+ { path: 'name', label: 'Request field name', group: 'Upload', valueType: PropertyValueType.String, default: 'files' },
44
+ { path: 'accept', label: 'Accepted MIME types', group: 'Upload', valueType: PropertyValueType.String },
45
+ { path: 'multiple', label: 'Allow multiple files', group: 'Behavior', valueType: PropertyValueType.Boolean, default: false },
46
+ { path: 'maxFileSize', label: 'Maximum file size', group: 'Upload', valueType: PropertyValueType.Number, constraints: { minimum: 0, integer: true } },
47
+ { path: 'ariaLabel', label: 'Accessible name', group: 'Accessibility', valueType: PropertyValueType.String },
48
+ ],
49
+ },
50
+ {
51
+ component: key('dataScroller'),
52
+ displayName: 'Data scroller',
53
+ description: 'A list that loads a chunk at a time as its end is reached. Items are strings, numbers or records, plus any child elements in the items slot; serialized legacy UI elements are refused.',
54
+ properties: [
55
+ { path: 'items', label: 'Items', group: 'Data', valueType: PropertyValueType.Json, description: 'Strings, numbers or records. A record is titled by its label, title, name, text or header field.' },
56
+ { path: 'rows', label: 'Rows per load', group: 'Behavior', valueType: PropertyValueType.Number, default: 10, constraints: { minimum: 1, integer: true } },
57
+ { path: 'inline', label: 'Scroll inline', group: 'Layout', valueType: PropertyValueType.Boolean, default: false, description: 'Scroll inside the control (true) or load as the page scrolls the end of the list into view (false).' },
58
+ { path: 'scrollHeight', label: 'Inline scroll height', group: 'Layout', valueType: PropertyValueType.Number, constraints: { minimum: 1 }, description: 'The height in pixels of an inline scroller. 320 when omitted.' },
59
+ { path: 'emptyLabel', label: 'No items label', group: 'Accessibility', valueType: PropertyValueType.String, default: 'No items to show' },
60
+ { path: 'ariaLabel', label: 'Accessible name', group: 'Accessibility', valueType: PropertyValueType.String },
61
+ ],
62
+ },
63
+ {
64
+ component: key('treeTable'),
65
+ displayName: 'Tree table',
66
+ description: 'A hierarchical table with authored columns, selection, and optional pagination. Items are nodes (strings, numbers or records with key, label, data, children); serialized legacy UI elements are refused.',
67
+ properties: [
68
+ { path: 'columns', label: 'Columns', group: 'Data', valueType: PropertyValueType.Json, description: 'Column definitions with field and header, or nested column elements. Inferred from the first row when absent.' },
69
+ { path: 'items', label: 'Items', group: 'Data', valueType: PropertyValueType.Json, description: 'The nodes: strings, numbers, or records with key, label, data, children, expanded and selectable.' },
70
+ {
71
+ path: 'selectionMode', label: 'Selection mode', group: 'Behavior', valueType: PropertyValueType.Enum, default: TreeTableSelectionMode.None,
72
+ choices: legacyEnumerationChoices(TreeTableSelectionMode, { [TreeTableSelectionMode.None]: 'None', [TreeTableSelectionMode.Single]: 'Single', [TreeTableSelectionMode.Multiple]: 'Multiple', [TreeTableSelectionMode.Checkbox]: 'Checkbox' }),
73
+ },
74
+ { path: 'selection', label: 'Selection', group: 'Behavior', valueType: PropertyValueType.Json, description: 'The selected node keys: a key, an array of keys or { key } objects, or PrimeReact\'s key map.' },
75
+ { path: 'paginator', label: 'Show pagination', group: 'Behavior', valueType: PropertyValueType.Boolean, default: false },
76
+ { path: 'rows', label: 'Rows per page', group: 'Behavior', valueType: PropertyValueType.Number, default: 10, constraints: { minimum: 1, integer: true } },
77
+ { path: 'emptyLabel', label: 'No records label', group: 'Accessibility', valueType: PropertyValueType.String, default: 'No records found' },
78
+ { path: 'ariaLabel', label: 'Accessible name', group: 'Accessibility', valueType: PropertyValueType.String },
79
+ ],
80
+ },
81
+ {
82
+ component: key('editor'),
83
+ displayName: 'Rich text editor',
84
+ description: 'A rich-text HTML editor. Editing needs the host to provide Quill (QuillLoaderProvider); without it the content is shown read-only. The HTML is sanitized before it is shown.',
85
+ properties: [
86
+ { path: 'value', label: 'HTML value', group: 'Content', valueType: PropertyValueType.String },
87
+ { path: 'placeholder', label: 'Placeholder', group: 'Content', valueType: PropertyValueType.String },
88
+ { path: 'showHeader', label: 'Show toolbar', group: 'Behavior', valueType: PropertyValueType.Boolean, default: true },
89
+ { path: 'readOnly', label: 'Read only', group: 'Behavior', valueType: PropertyValueType.Boolean, default: false },
90
+ { path: 'ariaLabel', label: 'Accessible name', group: 'Accessibility', valueType: PropertyValueType.String },
91
+ ],
92
+ },
30
93
  {
31
94
  component: key('multiStateCheckbox'),
32
95
  displayName: 'Multi-state checkbox',
@@ -36,8 +36,8 @@ export const primeReactPackageManifest: ScenePackage = {
36
36
  components: [
37
37
  'inputText', 'inputTextarea', 'inputNumber', 'password', 'floatLabel', 'iconField', 'dropdown', 'multiSelect',
38
38
  'listBox', 'selectButton', 'checkbox', 'multiStateCheckbox', 'radioButton', 'toggleSwitch', 'slider', 'rating', 'knob', 'calendar', 'colorPicker',
39
- 'chips', 'autoComplete', 'treeSelect', 'button', 'splitButton', 'speedDial', 'buttonGroup', 'dataTable', 'table',
40
- 'column', 'dataView', 'tree', 'timeline', 'paginator', 'orderList', 'pickList', 'organizationChart', 'chart',
39
+ 'chips', 'autoComplete', 'treeSelect', 'editor', 'fileUpload', 'button', 'splitButton', 'speedDial', 'buttonGroup', 'dataTable', 'table',
40
+ 'column', 'dataView', 'dataScroller', 'tree', 'treeTable', 'timeline', 'paginator', 'orderList', 'pickList', 'organizationChart', 'chart',
41
41
  'card', 'panel', 'accordion', 'fieldset', 'divider', 'splitter', 'scrollPanel', 'tabView', 'toolbar', 'stepper', 'dialog',
42
42
  'confirmDialog', 'overlayPanel', 'sidebar', 'tooltip', 'menu', 'menubar', 'breadcrumb', 'tabMenu', 'steps', 'tieredMenu',
43
43
  'panelMenu', 'contextMenu', 'megaMenu', 'dock', 'message', 'inlineMessage', 'toast', 'image', 'galleria', 'carousel', 'avatar',
@@ -109,3 +109,72 @@
109
109
  background: var(--scene-surface-background);
110
110
  color: var(--scene-text-color);
111
111
  }
112
+
113
+ /*
114
+ * The Cratis-owned controls that have no PrimeReact component behind them. They read the Scene tokens and
115
+ * carry a literal fallback, so they stay legible in a host that has not loaded a preset.
116
+ */
117
+
118
+ [data-scene-component='editor'] .ql-editor {
119
+ min-height: 8rem;
120
+ }
121
+
122
+ [data-scene-component='dataScroller'] ol {
123
+ list-style: none;
124
+ margin: 0;
125
+ padding: 0;
126
+ }
127
+
128
+ [data-scene-component='dataScroller'] li {
129
+ padding: 0.5rem 0.75rem;
130
+ border-bottom: 1px solid var(--scene-surface-border, #d4d4d8);
131
+ }
132
+
133
+ [data-scene-component='dataScroller'] dl {
134
+ margin: 0.25rem 0 0;
135
+ color: var(--scene-text-muted-color, inherit);
136
+ }
137
+
138
+ [data-scene-component='dataScroller'] dl > div {
139
+ display: flex;
140
+ gap: 0.5rem;
141
+ }
142
+
143
+ [data-scene-component='dataScroller'] dt {
144
+ font-weight: 600;
145
+ }
146
+
147
+ [data-scene-component='dataScroller'] dd {
148
+ margin: 0;
149
+ }
150
+
151
+ [data-scene-component='treeTable'] table {
152
+ width: 100%;
153
+ border-collapse: collapse;
154
+ }
155
+
156
+ [data-scene-component='treeTable'] th,
157
+ [data-scene-component='treeTable'] td {
158
+ padding: 0.5rem 0.75rem;
159
+ text-align: start;
160
+ border-bottom: 1px solid var(--scene-surface-border, #d4d4d8);
161
+ }
162
+
163
+ [data-scene-component='treeTable'] tbody tr:hover {
164
+ background: var(--scene-surface-hover, #f4f4f5);
165
+ }
166
+
167
+ [data-scene-component='treeTable'] tbody tr[aria-selected='true'] {
168
+ background: var(--scene-highlight-background, #e0e7ff);
169
+ color: var(--scene-highlight-color, inherit);
170
+ }
171
+
172
+ [data-scene-component='treeTable'] tbody tr:focus-visible {
173
+ outline: 2px solid var(--scene-primary-color, #4f46e5);
174
+ outline-offset: -2px;
175
+ }
176
+
177
+ [data-scene-component='dataScroller'] li:focus-visible {
178
+ outline: 2px solid var(--scene-primary-color, #4f46e5);
179
+ outline-offset: -2px;
180
+ }
@@ -0,0 +1,50 @@
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 { EnumerationResolution } from './EnumerationResolution';
5
+
6
+ /**
7
+ * Resolves an authored value to a member of one of this package's string enums.
8
+ *
9
+ * Three forms are accepted, and the stored value is never rewritten:
10
+ * - the canonical string value the enum declares (`'checkbox'`), which new documents use;
11
+ * - the ordinal of the original .NET enum (`3`), which migrated documents carry. The ordinal is the member's
12
+ * position in declaration order, so that order is part of the stored-data contract and must not change;
13
+ * - the .NET member name in its original Pascal case (`'Checkbox'`), which a JSON serialization of that enum
14
+ * produces.
15
+ *
16
+ * An absent value is the one default. Anything else - an out-of-range or fractional ordinal, a numeric
17
+ * string, a differently cased name, `null` - resolves to a finding with a message, because the intended
18
+ * behavior cannot be known and a silent fallback hides a mistyped document.
19
+ *
20
+ * @param property The property name, used in the message.
21
+ * @param value The authored value.
22
+ * @param members The enum object.
23
+ * @param fallback The member an absent value means.
24
+ * @returns The resolved member, or the finding.
25
+ */
26
+ export function resolveEnumeration<TMember extends string>(
27
+ property: string,
28
+ value: unknown,
29
+ members: Record<string, TMember>,
30
+ fallback: TMember
31
+ ): EnumerationResolution<TMember> {
32
+ if (value === undefined) return { isValid: true, value: fallback };
33
+
34
+ const canonical = Object.values(members);
35
+ if (typeof value === 'number' && Number.isInteger(value) && value >= 0 && value < canonical.length) {
36
+ return { isValid: true, value: canonical[value] };
37
+ }
38
+
39
+ if (typeof value === 'string') {
40
+ if (canonical.includes(value as TMember)) return { isValid: true, value: value as TMember };
41
+ if (Object.hasOwn(members, value)) return { isValid: true, value: members[value] };
42
+ }
43
+
44
+ const shown = typeof value === 'string' ? `'${value}'` : JSON.stringify(value) ?? String(value);
45
+ return {
46
+ isValid: false,
47
+ value,
48
+ message: `Unsupported ${property} ${shown}. Use one of ${canonical.join(', ')}, or a legacy ordinal from 0 to ${canonical.length - 1}.`,
49
+ };
50
+ }
package/treeNodes.ts CHANGED
@@ -14,35 +14,73 @@ import { arrayProperty } from './properties';
14
14
  * expands the wrong rows the moment two siblings share a label. Deriving the key from the path makes it
15
15
  * unique and stable across re-renders without asking the author for anything.
16
16
  *
17
+ * An authored key may be a string or a number (a numeric id is a natural key); it is kept as a string. Keys
18
+ * are unique across the whole tree: a node whose authored key was already taken by an earlier node falls back
19
+ * to its path key, so two nodes can never share expansion or selection.
20
+ *
21
+ * An entry that is a string, number or boolean is a leaf labeled with it. Anything else that is not a record
22
+ * (`null`, a nested array) cannot be a node and is skipped; see {@link countUnreadableEntries}.
23
+ *
17
24
  * @param entries The raw entries to convert.
18
25
  * @param parentKey The key of the node these entries belong to, used to build stable child keys.
26
+ * @param usedKeys The keys already given out in this tree, shared down the recursion.
19
27
  * @returns The converted nodes, in order.
20
28
  */
21
- export function toTreeNodes(entries: unknown[], parentKey = ''): TreeNode[] {
29
+ export function toTreeNodes(entries: unknown[], parentKey = '', usedKeys: Set<string> = new Set()): TreeNode[] {
22
30
  const nodes: TreeNode[] = [];
23
31
  entries.forEach((entry, index) => {
24
32
  const path = parentKey === '' ? `${index}` : `${parentKey}-${index}`;
25
- if (typeof entry === 'string') {
26
- nodes.push({ key: path, label: entry });
33
+ if (typeof entry === 'string' || typeof entry === 'number' || typeof entry === 'boolean') {
34
+ nodes.push({ key: uniqueKey(undefined, path, usedKeys), label: String(entry) });
27
35
  return;
28
36
  }
29
37
 
30
38
  if (typeof entry !== 'object' || entry === undefined || entry === null || Array.isArray(entry)) return;
31
39
 
32
40
  const record = entry as Record<string, unknown>;
33
- const node: TreeNode = { key: typeof record.key === 'string' ? record.key : path };
41
+ const node: TreeNode = { key: uniqueKey(authoredKey(record.key), path, usedKeys) };
34
42
  if (typeof record.label === 'string') node.label = record.label;
35
43
  if (typeof record.icon === 'string') node.icon = record.icon;
36
44
  if (typeof record.className === 'string') node.className = record.className;
37
45
  if (typeof record.leaf === 'boolean') node.leaf = record.leaf;
38
- if (typeof record.data === 'object' && record.data !== null) node.data = record.data;
39
- if (Array.isArray(record.children)) node.children = toTreeNodes(record.children, node.key as string);
46
+ if (typeof record.expanded === 'boolean') node.expanded = record.expanded;
47
+ if (typeof record.selectable === 'boolean') node.selectable = record.selectable;
48
+ if (record.data !== undefined && record.data !== null) node.data = record.data;
49
+ if (Array.isArray(record.children)) node.children = toTreeNodes(record.children, node.key as string, usedKeys);
40
50
  nodes.push(node);
41
51
  });
42
52
 
43
53
  return nodes;
44
54
  }
45
55
 
56
+ /**
57
+ * Counts the entries `toTreeNodes` skips, so a control can say that some of its data was not shown instead
58
+ * of silently showing less.
59
+ *
60
+ * @param entries The raw entries.
61
+ * @returns How many entries, at any depth, were neither a scalar nor a record.
62
+ */
63
+ export function countUnreadableEntries(entries: unknown[]): number {
64
+ return entries.reduce<number>((count, entry) => {
65
+ if (typeof entry === 'string' || typeof entry === 'number' || typeof entry === 'boolean') return count;
66
+ if (typeof entry !== 'object' || entry === null || Array.isArray(entry)) return count + 1;
67
+ const children = (entry as { children?: unknown }).children;
68
+ return count + (Array.isArray(children) ? countUnreadableEntries(children) : 0);
69
+ }, 0);
70
+ }
71
+
72
+ function authoredKey(value: unknown): string | undefined {
73
+ if (typeof value === 'string' && value !== '') return value;
74
+ return typeof value === 'number' && Number.isFinite(value) ? String(value) : undefined;
75
+ }
76
+
77
+ function uniqueKey(authored: string | undefined, path: string, usedKeys: Set<string>): string {
78
+ let key = authored !== undefined && !usedKeys.has(authored) ? authored : path;
79
+ while (usedKeys.has(key)) key = `${key}~`;
80
+ usedKeys.add(key);
81
+ return key;
82
+ }
83
+
46
84
  /**
47
85
  * Reads a tree model off a Scene element's properties.
48
86
  *
@@ -0,0 +1,34 @@
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 { Dispatch, SetStateAction, useCallback, useState } from 'react';
5
+ import { useStructuralValue } from './useStructuralValue';
6
+
7
+ /**
8
+ * State that starts from authored data and starts over when that data really changes.
9
+ *
10
+ * A control's selection or expansion is runtime state the user changes, yet it is also authored on the
11
+ * element. Reading the authored value once (`useState(() => authored)`) ignores a later edit of the document;
12
+ * resetting on every render discards what the user did. This does neither: the state follows `source` when
13
+ * its content changes, compared structurally because every document edit clones the data, and is otherwise
14
+ * left alone - so an unrelated property edit does not undo the user's choice.
15
+ *
16
+ * @param source The authored data the state derives from.
17
+ * @param initial Derives the starting state from the authored data.
18
+ * @returns The state and its setter, like `useState`.
19
+ */
20
+ export function useResettingState<TState>(source: unknown, initial: () => TState): [TState, Dispatch<SetStateAction<TState>>] {
21
+ const stable = useStructuralValue(source);
22
+ const [held, setHeld] = useState(() => ({ source: stable, value: initial() }));
23
+ let current = held;
24
+ if (held.source !== stable) {
25
+ current = { source: stable, value: initial() };
26
+ setHeld(current);
27
+ }
28
+
29
+ const update = useCallback((action: SetStateAction<TState>) => {
30
+ setHeld(previous => ({ source: previous.source, value: typeof action === 'function' ? (action as (state: TState) => TState)(previous.value) : action }));
31
+ }, []);
32
+
33
+ return [current.value, update];
34
+ }