@jmruthers/pace-core 0.5.135 → 0.5.136

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 (522) hide show
  1. package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
  2. package/dist/{DataTable-A36PJG6N.js → DataTable-CYOHOX3O.js} +25 -13
  3. package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-801uofbR.d.ts} +51 -135
  4. package/dist/UnifiedAuthProvider-5E5TUNMS.js +17 -0
  5. package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
  6. package/dist/{api-TNIBJWLM.js → api-45XYYO2A.js} +4 -3
  7. package/dist/{audit-T36HM7IM.js → audit-64X3VJXB.js} +3 -2
  8. package/dist/{chunk-CTJRBUX2.js → chunk-2TWNJ46Y.js} +2 -2
  9. package/dist/{chunk-UJI6WSMD.js → chunk-444EZN6N.js} +3 -3
  10. package/dist/chunk-444EZN6N.js.map +1 -0
  11. package/dist/{chunk-3CG5L6RN.js → chunk-4MT5BGGL.js} +90 -73
  12. package/dist/chunk-4MT5BGGL.js.map +1 -0
  13. package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
  14. package/dist/chunk-56XJ3TU6.js.map +1 -0
  15. package/dist/chunk-5DPZ5EAT.js +60 -0
  16. package/dist/chunk-5DPZ5EAT.js.map +1 -0
  17. package/dist/{chunk-66C4BSAY.js → chunk-ANBQRTPX.js} +9 -2
  18. package/dist/chunk-ANBQRTPX.js.map +1 -0
  19. package/dist/chunk-APIBCTL2.js +670 -0
  20. package/dist/chunk-APIBCTL2.js.map +1 -0
  21. package/dist/{chunk-GKHF54DI.js → chunk-BESYRHQM.js} +10 -4
  22. package/dist/chunk-BESYRHQM.js.map +1 -0
  23. package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
  24. package/dist/chunk-BVYWGZVV.js.map +1 -0
  25. package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
  26. package/dist/chunk-ERISIBYU.js.map +1 -0
  27. package/dist/{chunk-CQZU6TFE.js → chunk-FHWWBIHA.js} +100 -62
  28. package/dist/chunk-FHWWBIHA.js.map +1 -0
  29. package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
  30. package/dist/chunk-FMUCXFII.js.map +1 -0
  31. package/dist/{chunk-GVDR7WNV.js → chunk-HJGGOMQ6.js} +194 -518
  32. package/dist/chunk-HJGGOMQ6.js.map +1 -0
  33. package/dist/{chunk-BDZUMRBD.js → chunk-K2WWTH7O.js} +13 -6
  34. package/dist/chunk-K2WWTH7O.js.map +1 -0
  35. package/dist/{chunk-BYXRHAIF.js → chunk-L6PGMCMD.js} +23 -14
  36. package/dist/chunk-L6PGMCMD.js.map +1 -0
  37. package/dist/chunk-LMC26NLJ.js +84 -0
  38. package/dist/chunk-LMC26NLJ.js.map +1 -0
  39. package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
  40. package/dist/chunk-LS353YLY.js.map +1 -0
  41. package/dist/{chunk-ZYZCRSBD.js → chunk-LTV3XIJJ.js} +16 -11
  42. package/dist/chunk-LTV3XIJJ.js.map +1 -0
  43. package/dist/{chunk-HMNOSGVA.js → chunk-NOHEVYVX.js} +377 -666
  44. package/dist/chunk-NOHEVYVX.js.map +1 -0
  45. package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
  46. package/dist/chunk-Q5QRDWKI.js.map +1 -0
  47. package/dist/chunk-S5OFRT4M.js +94 -0
  48. package/dist/chunk-S5OFRT4M.js.map +1 -0
  49. package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
  50. package/dist/chunk-SBVILCCA.js.map +1 -0
  51. package/dist/{chunk-TGIY2AR2.js → chunk-SL2YQDR6.js} +4 -3
  52. package/dist/{chunk-TGIY2AR2.js.map → chunk-SL2YQDR6.js.map} +1 -1
  53. package/dist/{chunk-VZ5OR6HD.js → chunk-TVYPTYOY.js} +55 -179
  54. package/dist/chunk-TVYPTYOY.js.map +1 -0
  55. package/dist/{chunk-ZV77RZMU.js → chunk-XARJS7CD.js} +2 -2
  56. package/dist/chunk-XDNLUEXI.js +138 -0
  57. package/dist/chunk-XDNLUEXI.js.map +1 -0
  58. package/dist/{chunk-F64FFPOZ.js → chunk-YLKIDTUK.js} +26 -20
  59. package/dist/chunk-YLKIDTUK.js.map +1 -0
  60. package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
  61. package/dist/chunk-ZZ2SS7NI.js.map +1 -0
  62. package/dist/components.d.ts +7 -287
  63. package/dist/components.js +26 -157
  64. package/dist/components.js.map +1 -1
  65. package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
  66. package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
  67. package/dist/hooks.d.ts +3 -3
  68. package/dist/hooks.js +22 -16
  69. package/dist/hooks.js.map +1 -1
  70. package/dist/index.d.ts +101 -9
  71. package/dist/index.js +43 -31
  72. package/dist/index.js.map +1 -1
  73. package/dist/providers.d.ts +1 -1
  74. package/dist/providers.js +5 -4
  75. package/dist/rbac/index.js +13 -12
  76. package/dist/styles/index.js +2 -1
  77. package/dist/theming/runtime.d.ts +2 -19
  78. package/dist/theming/runtime.js +2 -1
  79. package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
  80. package/dist/types.d.ts +2 -2
  81. package/dist/types.js +1 -1
  82. package/dist/{useInactivityTracker-MRUU55XI.js → useInactivityTracker-TO6ZOF35.js} +3 -2
  83. package/dist/{usePublicRouteParams-Dyt1tzI9.d.ts → usePublicRouteParams-B7PabvuH.d.ts} +1 -1
  84. package/dist/utils.d.ts +195 -232
  85. package/dist/utils.js +173 -331
  86. package/dist/utils.js.map +1 -1
  87. package/dist/{validation-DnhrNMju.d.ts → validation-8npbysjg.d.ts} +26 -8
  88. package/dist/validation.d.ts +261 -10
  89. package/dist/validation.js +82 -440
  90. package/dist/validation.js.map +1 -1
  91. package/docs/api/classes/ColumnFactory.md +1 -1
  92. package/docs/api/classes/ErrorBoundary.md +6 -6
  93. package/docs/api/classes/InvalidScopeError.md +1 -1
  94. package/docs/api/classes/MissingUserContextError.md +1 -1
  95. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  96. package/docs/api/classes/PermissionDeniedError.md +1 -1
  97. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  98. package/docs/api/classes/RBACAuditManager.md +6 -6
  99. package/docs/api/classes/RBACCache.md +1 -1
  100. package/docs/api/classes/RBACEngine.md +7 -7
  101. package/docs/api/classes/RBACError.md +1 -1
  102. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  103. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  104. package/docs/api/classes/StorageUtils.md +1 -1
  105. package/docs/api/enums/FileCategory.md +1 -1
  106. package/docs/api/interfaces/AggregateConfig.md +4 -4
  107. package/docs/api/interfaces/ButtonProps.md +1 -1
  108. package/docs/api/interfaces/CardProps.md +1 -1
  109. package/docs/api/interfaces/ColorPalette.md +1 -1
  110. package/docs/api/interfaces/ColorShade.md +29 -4
  111. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  112. package/docs/api/interfaces/DataRecord.md +1 -1
  113. package/docs/api/interfaces/DataTableAction.md +18 -18
  114. package/docs/api/interfaces/DataTableColumn.md +61 -1
  115. package/docs/api/interfaces/DataTableProps.md +1 -1
  116. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  117. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  118. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +14 -14
  119. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  120. package/docs/api/interfaces/EventLogoProps.md +152 -0
  121. package/docs/api/interfaces/ExportColumn.md +1 -1
  122. package/docs/api/interfaces/ExportOptions.md +8 -8
  123. package/docs/api/interfaces/FileDisplayProps.md +15 -15
  124. package/docs/api/interfaces/FileMetadata.md +1 -1
  125. package/docs/api/interfaces/FileReference.md +1 -1
  126. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  127. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  128. package/docs/api/interfaces/FileUploadProps.md +1 -1
  129. package/docs/api/interfaces/FooterProps.md +1 -1
  130. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  131. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  132. package/docs/api/interfaces/InputProps.md +1 -1
  133. package/docs/api/interfaces/LabelProps.md +1 -1
  134. package/docs/api/interfaces/LoginFormProps.md +1 -1
  135. package/docs/api/interfaces/NavigationAccessRecord.md +10 -10
  136. package/docs/api/interfaces/NavigationContextType.md +9 -9
  137. package/docs/api/interfaces/NavigationGuardProps.md +10 -10
  138. package/docs/api/interfaces/NavigationItem.md +1 -1
  139. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  140. package/docs/api/interfaces/NavigationProviderProps.md +7 -7
  141. package/docs/api/interfaces/Organisation.md +1 -1
  142. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  143. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  144. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  145. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  146. package/docs/api/interfaces/PaceAppLayoutProps.md +27 -27
  147. package/docs/api/interfaces/PaceLoginPageProps.md +4 -4
  148. package/docs/api/interfaces/PageAccessRecord.md +8 -8
  149. package/docs/api/interfaces/PagePermissionContextType.md +8 -8
  150. package/docs/api/interfaces/PagePermissionGuardProps.md +11 -11
  151. package/docs/api/interfaces/PagePermissionProviderProps.md +7 -7
  152. package/docs/api/interfaces/PaletteData.md +4 -4
  153. package/docs/api/interfaces/PermissionEnforcerProps.md +11 -11
  154. package/docs/api/interfaces/ProtectedRouteProps.md +6 -6
  155. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  156. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  157. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  158. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  159. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  160. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  161. package/docs/api/interfaces/RBACConfig.md +1 -1
  162. package/docs/api/interfaces/RBACLogger.md +1 -1
  163. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  164. package/docs/api/interfaces/RoleBasedRouterContextType.md +8 -8
  165. package/docs/api/interfaces/RoleBasedRouterProps.md +10 -10
  166. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  167. package/docs/api/interfaces/RouteAccessRecord.md +10 -10
  168. package/docs/api/interfaces/RouteConfig.md +10 -10
  169. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  170. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  171. package/docs/api/interfaces/SessionRestorationLoaderProps.md +21 -0
  172. package/docs/api/interfaces/StorageConfig.md +1 -1
  173. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  174. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  175. package/docs/api/interfaces/StorageListOptions.md +1 -1
  176. package/docs/api/interfaces/StorageListResult.md +1 -1
  177. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  178. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  179. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  180. package/docs/api/interfaces/StyleImport.md +1 -1
  181. package/docs/api/interfaces/SwitchProps.md +1 -1
  182. package/docs/api/interfaces/ToastActionElement.md +1 -1
  183. package/docs/api/interfaces/ToastProps.md +1 -1
  184. package/docs/api/interfaces/UnifiedAuthContextType.md +53 -53
  185. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  186. package/docs/api/interfaces/UseInactivityTrackerOptions.md +9 -9
  187. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  188. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  189. package/docs/api/interfaces/UsePublicEventReturn.md +5 -5
  190. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  191. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +9 -9
  192. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  193. package/docs/api/interfaces/UseResolvedScopeOptions.md +4 -4
  194. package/docs/api/interfaces/UseResolvedScopeReturn.md +4 -4
  195. package/docs/api/interfaces/UserEventAccess.md +11 -11
  196. package/docs/api/interfaces/UserMenuProps.md +1 -1
  197. package/docs/api/interfaces/UserProfile.md +1 -1
  198. package/docs/api/modules.md +514 -212
  199. package/docs/api-reference/components.md +106 -26
  200. package/docs/architecture/README.md +0 -2
  201. package/docs/implementation-guides/data-tables.md +277 -13
  202. package/docs/implementation-guides/forms.md +1 -16
  203. package/docs/implementation-guides/permission-enforcement.md +8 -2
  204. package/examples/README.md +30 -14
  205. package/examples/STRUCTURE.md +125 -0
  206. package/examples/components/DataTable/HierarchicalActionsExample.tsx +421 -0
  207. package/examples/components/DataTable/HierarchicalExample.tsx +475 -0
  208. package/examples/components/DataTable/InitialPageSizeExample.tsx +177 -0
  209. package/examples/components/DataTable/PerformanceExample.tsx +506 -0
  210. package/examples/components/DataTable/index.ts +13 -0
  211. package/examples/components/Dialog/BasicHtmlTest.tsx +55 -0
  212. package/examples/components/Dialog/DebugHtmlExample.tsx +68 -0
  213. package/examples/components/Dialog/HtmlDialogExample.tsx +202 -0
  214. package/examples/components/Dialog/ScrollableDialogExample.tsx +290 -0
  215. package/examples/components/Dialog/SimpleHtmlTest.tsx +61 -0
  216. package/examples/components/Dialog/SmartDialogExample.tsx +322 -0
  217. package/examples/components/Dialog/index.ts +15 -0
  218. package/examples/components/index.ts +11 -0
  219. package/examples/features/index.ts +12 -0
  220. package/examples/{public-pages → features/public-pages}/CorrectPublicPageImplementation.tsx +1 -1
  221. package/examples/{public-pages → features/public-pages}/PublicEventPage.tsx +1 -1
  222. package/examples/{public-pages → features/public-pages}/PublicPageApp.tsx +1 -1
  223. package/examples/{public-pages → features/public-pages}/PublicPageUsageExample.tsx +1 -1
  224. package/examples/index.ts +11 -3
  225. package/package.json +30 -10
  226. package/src/components/Alert/Alert.tsx +1 -1
  227. package/src/components/Avatar/Avatar.tsx +1 -1
  228. package/src/components/Button/Button.tsx +1 -1
  229. package/src/components/Card/Card.tsx +1 -1
  230. package/src/components/Checkbox/Checkbox.tsx +1 -1
  231. package/src/components/DataTable/DataTable.test.tsx +1 -1
  232. package/src/components/DataTable/DataTable.tsx +1 -30
  233. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
  234. package/src/components/DataTable/__tests__/styles.test.ts +2 -2
  235. package/src/components/DataTable/components/ActionButtons.tsx +0 -15
  236. package/src/components/DataTable/components/DataTableCore.tsx +4 -185
  237. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
  238. package/src/components/DataTable/components/DataTableModals.tsx +1 -27
  239. package/src/components/DataTable/components/EditableRow.tsx +1 -1
  240. package/src/components/DataTable/components/ImportModal.tsx +2 -14
  241. package/src/components/DataTable/components/PaginationControls.tsx +1 -1
  242. package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
  243. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
  244. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
  245. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
  246. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
  247. package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
  248. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
  249. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
  250. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
  251. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
  252. package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
  253. package/src/components/DataTable/index.ts +4 -0
  254. package/src/components/DataTable/styles.ts +1 -1
  255. package/src/components/DataTable/types.ts +13 -0
  256. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
  257. package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
  258. package/src/components/DataTable/utils/exportUtils.ts +1 -1
  259. package/src/components/DataTable/utils/flexibleImport.ts +1 -11
  260. package/src/components/DataTable/utils/index.ts +1 -0
  261. package/src/components/DataTable/utils/paginationUtils.ts +1 -1
  262. package/src/components/Dialog/Dialog.tsx +2 -2
  263. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
  264. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
  265. package/src/components/EventSelector/EventSelector.tsx +3 -2
  266. package/src/components/FileDisplay/FileDisplay.tsx +2 -36
  267. package/src/components/FileUpload/FileUpload.test.tsx +2 -2
  268. package/src/components/FileUpload/FileUpload.tsx +2 -2
  269. package/src/components/Footer/Footer.tsx +1 -1
  270. package/src/components/Form/Form.test.tsx +4 -509
  271. package/src/components/Form/Form.tsx +1 -1
  272. package/src/components/Form/FormField.tsx +1 -1
  273. package/src/components/Form/index.ts +0 -12
  274. package/src/components/Header/Header.tsx +1 -1
  275. package/src/components/Input/Input.tsx +1 -1
  276. package/src/components/Label/Label.tsx +1 -1
  277. package/src/components/LoginForm/LoginForm.tsx +1 -1
  278. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
  279. package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
  280. package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
  281. package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
  282. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
  283. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
  284. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
  285. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
  286. package/src/components/PaceLoginPage/PaceLoginPage.tsx +13 -12
  287. package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
  288. package/src/components/PasswordReset/index.ts +0 -2
  289. package/src/components/Progress/Progress.tsx +1 -1
  290. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
  291. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
  292. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  293. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
  294. package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
  295. package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
  296. package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
  297. package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
  298. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
  299. package/src/components/PublicLayout/index.ts +4 -2
  300. package/src/components/Select/Select.tsx +1 -1
  301. package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
  302. package/src/components/SessionRestorationLoader/index.ts +3 -0
  303. package/src/components/Switch/Switch.tsx +1 -1
  304. package/src/components/Table/Table.tsx +1 -1
  305. package/src/components/Toast/Toast.tsx +1 -1
  306. package/src/components/Tooltip/Tooltip.tsx +1 -1
  307. package/src/components/index.ts +4 -10
  308. package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
  309. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
  310. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
  311. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
  312. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
  313. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
  314. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
  315. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
  316. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
  317. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
  318. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
  319. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
  320. package/src/hooks/public/usePublicEvent.ts +7 -6
  321. package/src/hooks/public/usePublicEventLogo.ts +7 -4
  322. package/src/hooks/public/usePublicFileDisplay.ts +6 -150
  323. package/src/hooks/useComponentPerformance.ts +4 -1
  324. package/src/hooks/useDataTablePerformance.ts +4 -3
  325. package/src/hooks/useEventTheme.test.ts +18 -5
  326. package/src/hooks/useEventTheme.ts +4 -1
  327. package/src/hooks/useEvents.ts +2 -0
  328. package/src/hooks/useFileDisplay.ts +9 -8
  329. package/src/hooks/useFileReference.ts +4 -1
  330. package/src/hooks/useFileUrl.ts +4 -1
  331. package/src/hooks/useInactivityTracker.ts +5 -4
  332. package/src/hooks/useOrganisationSecurity.test.ts +33 -12
  333. package/src/hooks/useOrganisationSecurity.ts +8 -7
  334. package/src/hooks/usePerformanceMonitor.ts +6 -3
  335. package/src/hooks/usePermissionCache.ts +13 -6
  336. package/src/hooks/useSecureDataAccess.test.ts +2 -2
  337. package/src/hooks/useSecureDataAccess.ts +9 -8
  338. package/src/hooks/useSessionRestoration.ts +4 -1
  339. package/src/hooks/useStorage.ts +4 -1
  340. package/src/index.ts +16 -7
  341. package/src/providers/services/AuthServiceProvider.tsx +3 -2
  342. package/src/providers/services/EventServiceProvider.tsx +2 -1
  343. package/src/providers/services/InactivityServiceProvider.tsx +2 -1
  344. package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
  345. package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
  346. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
  347. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
  348. package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
  349. package/src/rbac/api.ts +5 -2
  350. package/src/rbac/audit-enhanced.ts +6 -6
  351. package/src/rbac/audit.test.ts +60 -38
  352. package/src/rbac/audit.ts +8 -8
  353. package/src/rbac/cache-invalidation.ts +7 -4
  354. package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
  355. package/src/rbac/components/NavigationGuard.tsx +7 -3
  356. package/src/rbac/components/NavigationProvider.tsx +6 -3
  357. package/src/rbac/components/PagePermissionGuard.tsx +28 -16
  358. package/src/rbac/components/PagePermissionProvider.tsx +4 -1
  359. package/src/rbac/components/PermissionEnforcer.tsx +9 -3
  360. package/src/rbac/components/RoleBasedRouter.tsx +3 -1
  361. package/src/rbac/components/SecureDataProvider.tsx +7 -3
  362. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
  363. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
  364. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
  365. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
  366. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
  367. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
  368. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
  369. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
  370. package/src/rbac/engine.ts +15 -7
  371. package/src/rbac/hooks/usePermissions.ts +7 -3
  372. package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
  373. package/src/rbac/hooks/useResolvedScope.ts +10 -7
  374. package/src/rbac/permissions.ts +5 -2
  375. package/src/rbac/security.test.ts +27 -16
  376. package/src/rbac/security.ts +5 -4
  377. package/src/services/AuthService.ts +22 -21
  378. package/src/services/EventService.ts +12 -12
  379. package/src/services/InactivityService.ts +5 -4
  380. package/src/services/OrganisationService.ts +26 -25
  381. package/src/services/__tests__/AuthService.test.ts +51 -19
  382. package/src/services/__tests__/EventService.test.ts +37 -5
  383. package/src/services/__tests__/InactivityService.test.ts +38 -4
  384. package/src/services/__tests__/OrganisationService.test.ts +3 -8
  385. package/src/services/base/BaseService.ts +3 -1
  386. package/src/theming/__tests__/runtime.test.ts +21 -12
  387. package/src/theming/parseEventColours.ts +5 -19
  388. package/src/theming/runtime.ts +8 -4
  389. package/src/types/validation.ts +2 -29
  390. package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
  391. package/src/utils/__tests__/audit.unit.test.ts +1 -1
  392. package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
  393. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
  394. package/src/utils/__tests__/cn.unit.test.ts +1 -1
  395. package/src/utils/__tests__/debugLogger.test.ts +1 -1
  396. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
  397. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
  398. package/src/utils/__tests__/formatting.unit.test.ts +1 -1
  399. package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
  400. package/src/utils/__tests__/logger.unit.test.ts +1 -1
  401. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
  402. package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
  403. package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
  404. package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
  405. package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
  406. package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
  407. package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
  408. package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
  409. package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
  410. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
  411. package/src/utils/__tests__/security.unit.test.ts +40 -18
  412. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
  413. package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
  414. package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
  415. package/src/utils/{appIdResolver.test.ts → app/appIdResolver.test.ts} +28 -30
  416. package/src/utils/{appIdResolver.ts → app/appIdResolver.ts} +8 -5
  417. package/src/utils/{appNameResolver.test.ts → app/appNameResolver.test.ts} +1 -1
  418. package/src/utils/{appNameResolver.ts → app/appNameResolver.ts} +5 -1
  419. package/src/utils/{organisationContext.ts → context/organisationContext.ts} +6 -3
  420. package/src/utils/{sessionTracking.ts → context/sessionTracking.ts} +11 -12
  421. package/src/utils/{logger.ts → core/logger.ts} +4 -2
  422. package/src/utils/{deviceFingerprint.ts → device/deviceFingerprint.ts} +1 -1
  423. package/src/utils/{lazyLoad.tsx → dynamic/lazyLoad.tsx} +2 -2
  424. package/src/utils/{file-reference.test.ts → file-reference/__tests__/file-reference.test.ts} +5 -5
  425. package/src/utils/{file-reference.ts → file-reference/index.ts} +20 -38
  426. package/src/utils/index.ts +32 -54
  427. package/src/utils/{secureErrors.ts → security/secureErrors.ts} +6 -3
  428. package/src/utils/{security.ts → security/security.ts} +5 -2
  429. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
  430. package/src/utils/storage/helpers.ts +15 -8
  431. package/src/{components/Dialog/utils/__tests__/safeHtml.unit.test.ts → utils/validation/__tests__/htmlSanitization.unit.test.ts} +9 -15
  432. package/src/{validation → utils/validation}/csrf.ts +1 -1
  433. package/src/{components/Dialog/utils/safeHtml.ts → utils/validation/htmlSanitization.ts} +9 -10
  434. package/src/utils/validation/index.ts +79 -0
  435. package/src/utils/{sanitization.ts → validation/sanitization.ts} +71 -2
  436. package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
  437. package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
  438. package/src/utils/{validationUtils.ts → validation/validationUtils.ts} +4 -1
  439. package/src/validation/index.ts +3 -34
  440. package/dist/UnifiedAuthProvider-CQDZRJIS.js +0 -16
  441. package/dist/chunk-24MKLB7U.js +0 -81
  442. package/dist/chunk-24MKLB7U.js.map +0 -1
  443. package/dist/chunk-3CG5L6RN.js.map +0 -1
  444. package/dist/chunk-3DBFLLLU.js.map +0 -1
  445. package/dist/chunk-5F3NDPJV.js.map +0 -1
  446. package/dist/chunk-66C4BSAY.js.map +0 -1
  447. package/dist/chunk-BDZUMRBD.js.map +0 -1
  448. package/dist/chunk-BYXRHAIF.js.map +0 -1
  449. package/dist/chunk-CDQ3PX7L.js +0 -18
  450. package/dist/chunk-CDQ3PX7L.js.map +0 -1
  451. package/dist/chunk-CQZU6TFE.js.map +0 -1
  452. package/dist/chunk-F64FFPOZ.js.map +0 -1
  453. package/dist/chunk-GEVIB2UB.js.map +0 -1
  454. package/dist/chunk-GKHF54DI.js.map +0 -1
  455. package/dist/chunk-GVDR7WNV.js.map +0 -1
  456. package/dist/chunk-HMNOSGVA.js.map +0 -1
  457. package/dist/chunk-JCQZ6LA7.js.map +0 -1
  458. package/dist/chunk-M6DDYFUD.js.map +0 -1
  459. package/dist/chunk-O3NWNXDY.js.map +0 -1
  460. package/dist/chunk-PYUXFQJ3.js.map +0 -1
  461. package/dist/chunk-UJI6WSMD.js.map +0 -1
  462. package/dist/chunk-VZ5OR6HD.js.map +0 -1
  463. package/dist/chunk-WP5I5GLN.js.map +0 -1
  464. package/dist/chunk-ZYZCRSBD.js.map +0 -1
  465. package/src/components/Dialog/README.md +0 -804
  466. package/src/components/Form/FormErrorSummary.tsx +0 -113
  467. package/src/components/Form/FormFieldset.tsx +0 -127
  468. package/src/components/Form/FormLiveRegion.tsx +0 -198
  469. package/src/components/PasswordReset/PasswordResetForm.test.tsx +0 -597
  470. package/src/components/PasswordReset/PasswordResetForm.tsx +0 -201
  471. package/src/components/PublicLayout/PublicPageDebugger.tsx +0 -104
  472. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +0 -162
  473. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
  474. package/src/examples/CorrectPublicPageImplementation.tsx +0 -304
  475. package/src/examples/PublicEventPage.tsx +0 -287
  476. package/src/examples/PublicPageApp.tsx +0 -321
  477. package/src/examples/PublicPageUsageExample.tsx +0 -218
  478. package/src/utils/schemaUtils.ts +0 -37
  479. package/src/validation/__tests__/common.unit.test.ts +0 -101
  480. package/src/validation/__tests__/csrf.unit.test.ts +0 -365
  481. package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
  482. package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
  483. package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
  484. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
  485. package/src/validation/__tests__/user.unit.test.ts +0 -440
  486. package/src/validation/sanitization.ts +0 -96
  487. /package/dist/{DataTable-A36PJG6N.js.map → DataTable-CYOHOX3O.js.map} +0 -0
  488. /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-5E5TUNMS.js.map} +0 -0
  489. /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
  490. /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
  491. /package/dist/{chunk-CTJRBUX2.js.map → chunk-2TWNJ46Y.js.map} +0 -0
  492. /package/dist/{chunk-ZV77RZMU.js.map → chunk-XARJS7CD.js.map} +0 -0
  493. /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
  494. /package/examples/{public-pages → features/public-pages}/index.ts +0 -0
  495. /package/examples/{RBAC → features/rbac}/CompleteRBACExample.tsx +0 -0
  496. /package/examples/{RBAC → features/rbac}/EventBasedApp.tsx +0 -0
  497. /package/examples/{RBAC → features/rbac}/PermissionExample.tsx +0 -0
  498. /package/examples/{RBAC → features/rbac}/index.ts +0 -0
  499. /package/src/utils/{appConfig.ts → app/appConfig.ts} +0 -0
  500. /package/src/utils/{appNameResolver.simple.test.ts → app/appNameResolver.simple.test.ts} +0 -0
  501. /package/src/utils/{audit.ts → audit/audit.ts} +0 -0
  502. /package/src/utils/{organisationContext.test.ts → context/organisationContext.test.ts} +0 -0
  503. /package/src/utils/{cn.ts → core/cn.ts} +0 -0
  504. /package/src/utils/{debugLogger.ts → core/debugLogger.ts} +0 -0
  505. /package/src/utils/{dynamicUtils.ts → dynamic/dynamicUtils.ts} +0 -0
  506. /package/src/utils/{formatDate.test.ts → formatting/formatDate.test.ts} +0 -0
  507. /package/src/utils/{formatting.ts → formatting/formatting.ts} +0 -0
  508. /package/src/utils/{bundleAnalysis.ts → performance/bundleAnalysis.ts} +0 -0
  509. /package/src/utils/{performanceBenchmark.ts → performance/performanceBenchmark.ts} +0 -0
  510. /package/src/utils/{performanceBudgets.ts → performance/performanceBudgets.ts} +0 -0
  511. /package/src/utils/{permissionTypes.ts → permissions/permissionTypes.ts} +0 -0
  512. /package/src/utils/{permissionUtils.test.ts → permissions/permissionUtils.test.ts} +0 -0
  513. /package/src/utils/{permissionUtils.ts → permissions/permissionUtils.ts} +0 -0
  514. /package/src/utils/{auth-utils.ts → security/auth-utils.ts} +0 -0
  515. /package/src/utils/{secureDataAccess.test.ts → security/secureDataAccess.test.ts} +0 -0
  516. /package/src/utils/{secureDataAccess.ts → security/secureDataAccess.ts} +0 -0
  517. /package/src/utils/{secureStorage.ts → security/secureStorage.ts} +0 -0
  518. /package/src/utils/{securityMonitor.ts → security/securityMonitor.ts} +0 -0
  519. /package/src/{validation → utils/validation}/common.ts +0 -0
  520. /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
  521. /package/src/{validation → utils/validation}/user.ts +0 -0
  522. /package/src/utils/{validation.ts → validation/validation.ts} +0 -0
@@ -346,11 +346,18 @@ const userSchema = z.object({
346
346
  age: z.number().min(18, "Must be at least 18 years old")
347
347
  });
348
348
 
349
+ import { logger } from '@jmruthers/pace-core/utils';
350
+
349
351
  <Form
350
352
  schema={userSchema}
351
353
  defaultValues={{ name: "", email: "", age: 0 }}
352
- onSubmit={(data) => console.log(data)}
353
- onError={(errors) => console.error(errors)}
354
+ onSubmit={(data) => {
355
+ // Handle form submission
356
+ logger.debug('Form', 'Form submitted:', data);
357
+ }}
358
+ onError={(errors) => {
359
+ logger.error('Form', 'Form validation errors:', errors);
360
+ }}
354
361
  >
355
362
  <FormField name="name" label="Name" />
356
363
  <FormField name="email" label="Email" type="email" />
@@ -362,13 +369,29 @@ const userSchema = z.object({
362
369
  ### Form Components
363
370
 
364
371
  - **FormField**: Individual form fields with validation
365
- - **FormErrorSummary**: Error display for forms
366
- - **FormLiveRegion**: Live region for accessibility
367
- - **FormFieldset**: Grouped form fields
368
372
 
369
373
  ## Dialog
370
374
 
371
- A comprehensive, accessible dialog component system with enhanced features for modern web applications. Built on Radix UI primitives with semantic HTML structure and smart height management.
375
+ A comprehensive, accessible dialog component system built on top of Radix UI primitives with enhanced features for modern web applications.
376
+
377
+ ### Features
378
+
379
+ #### Core Features
380
+ - **Semantic HTML Structure** - Uses native `<dialog>` element with proper header, main, footer elements
381
+ - **Accessibility First** - WCAG 2.1 AA compliant with full screen reader support
382
+ - **Focus Management** - Automatic focus trapping and restoration
383
+ - **Keyboard Navigation** - Escape to close, Tab for focus management
384
+ - **Responsive Design** - Adapts to all screen sizes with smart constraints
385
+
386
+ #### Advanced Features
387
+ - **Smart Height Management** - Automatic viewport-based height constraints
388
+ - **Scrollable Content** - Long content scrolls while keeping headers/footers visible
389
+ - **Sticky Headers/Footers** - Important UI elements remain accessible during scrolling
390
+ - **Multiple Size Variants** - sm, md, lg, xl, full, auto sizing options
391
+ - **Custom Dimensions** - Fine-grained control over width and height
392
+ - **Configurable Close Behavior** - Control escape key and outside click behavior
393
+ - **Smooth Animations** - Polished transitions and micro-interactions
394
+ - **HTML Content Rendering** - Safe HTML content with automatic sanitization
372
395
 
373
396
  ### Props
374
397
 
@@ -585,24 +608,40 @@ import {
585
608
  </Dialog>
586
609
  ```
587
610
 
588
- ### Features
611
+ ### HTML Content Rendering
589
612
 
590
- #### Core Features
591
- - **Semantic HTML Structure**: Uses native `<dialog>` element with proper header, main, footer elements
592
- - **Accessibility First**: WCAG 2.1 AA compliant with full screen reader support
593
- - **Focus Management**: Automatic focus trapping and restoration
594
- - **Keyboard Navigation**: Escape to close, Tab for focus management
595
- - **Responsive Design**: Adapts to all screen sizes with smart constraints
613
+ The Dialog components support rich HTML content rendering with automatic sanitization. This is perfect for formatted instructions, feature announcements, error details, or any HTML that needs to be displayed in dialogs.
596
614
 
597
- #### Advanced Features
598
- - **Smart Height Management**: Automatic viewport-based height constraints
599
- - **Scrollable Content**: Long content scrolls while keeping headers/footers visible
600
- - **Sticky Headers/Footers**: Important UI elements remain accessible during scrolling
601
- - **HTML Content Rendering**: Safe HTML content with automatic sanitization
602
- - **Multiple Size Variants**: sm, md, lg, xl, full, auto sizing options
603
- - **Custom Dimensions**: Fine-grained control over width and height
604
- - **Configurable Close Behavior**: Control escape key and outside click behavior
605
- - **Smooth Animations**: Polished transitions and micro-interactions
615
+ **Key Features:**
616
+ - **Rich HTML Rendering**: Full HTML support with proper styling
617
+ - **Safe Sanitization**: Automatic XSS protection
618
+ - **Prose Styling**: Typography classes for readable content
619
+ - **Fallback Support**: Graceful degradation if HTML fails
620
+
621
+ **Configuration Options:**
622
+
623
+ | Property | Type | Default | Description |
624
+ |----------|------|---------|-------------|
625
+ | `htmlContent` | `string` | `undefined` | HTML string to render |
626
+ | `allowHtml` | `boolean` | `true` | Enable/disable HTML rendering |
627
+ | `strictSanitization` | `boolean` | `true` | Use strict HTML sanitization |
628
+ | `logWarnings` | `boolean` | `false` | Log sanitization warnings to console |
629
+
630
+ **Supported HTML Elements:**
631
+ - Text formatting: `p`, `div`, `span`, `h1`-`h6`, `strong`, `em`, `b`, `i`, `u`, `s`, `mark`, `small`, `sub`, `sup`
632
+ - Lists: `ul`, `ol`, `li`, `dl`, `dt`, `dd`
633
+ - Code: `pre`, `code`, `kbd`, `samp`
634
+ - Links: `a` (with href validation)
635
+ - Tables: `table`, `thead`, `tbody`, `tfoot`, `tr`, `th`, `td`
636
+ - Media: `img` (with src validation)
637
+ - Layout: `section`, `article`, `aside`, `header`, `footer`, `main`, `nav`
638
+ - Interactive: `details`, `summary`
639
+
640
+ **Removed Elements (for security):**
641
+ - Scripts: `script`, `iframe`, `object`, `embed`
642
+ - Forms: `form`, `input`, `button`
643
+ - Event handlers: `onclick`, `onload`, etc.
644
+ - Dangerous protocols: `javascript:`, `data:`
606
645
 
607
646
  ### Size Variants
608
647
 
@@ -615,6 +654,46 @@ import {
615
654
  | `full` | 100% | Full screen experiences |
616
655
  | `auto` | Content-based | Dynamic content sizing |
617
656
 
657
+ ### Accessibility
658
+
659
+ #### WCAG 2.1 AA Compliance
660
+ - **Semantic HTML** - Uses proper `<dialog>`, `<header>`, `<main>`, `<footer>` elements
661
+ - **Focus Management** - Automatic focus trapping and restoration
662
+ - **Keyboard Navigation** - Full keyboard support with proper tab order
663
+ - **Screen Reader Support** - Complete ARIA attributes and announcements
664
+ - **Landmark Navigation** - Proper semantic structure for screen reader navigation
665
+
666
+ #### Keyboard Shortcuts
667
+ - **Escape** - Close dialog (configurable)
668
+ - **Tab** - Navigate through focusable elements
669
+ - **Shift + Tab** - Navigate backwards through focusable elements
670
+
671
+ ### Performance
672
+
673
+ #### Optimizations
674
+ - **Efficient Focus Management** - Minimal DOM queries and updates
675
+ - **Optimized Animations** - Hardware-accelerated transitions
676
+ - **Memory Leak Prevention** - Proper cleanup of event listeners
677
+ - **Conditional Rendering** - Only renders when needed
678
+ - **Optimized Scroll Handling** - Debounced resize events
679
+
680
+ #### Best Practices
681
+ - Use `enableScrolling={true}` for content that might overflow
682
+ - Set appropriate `maxHeightPercent` to prevent viewport overflow
683
+ - Use sticky headers/footers for important UI elements
684
+ - Consider `size="auto"` for dynamic content
685
+
686
+ ### Troubleshooting
687
+
688
+ **Common Issues:**
689
+
690
+ 1. **Content not scrolling** - Ensure `enableScrolling={true}` is set
691
+ 2. **Header/footer not sticky** - Add `sticky={true}` to header/footer props
692
+ 3. **Dialog too tall** - Use `maxHeightPercent` or `maxHeight` props
693
+ 4. **Focus issues** - Ensure proper semantic structure with DialogBody
694
+ 5. **HTML not rendering** - Check that `allowHtml={true}` is set and HTML is valid
695
+ 6. **Content being stripped** - Check sanitization settings and verify HTML elements are allowed
696
+
618
697
  ## Select
619
698
 
620
699
  A dropdown select component with search functionality and keyboard navigation.
@@ -1388,12 +1467,13 @@ For more details, see the [Authentication Implementation Guide](../implementatio
1388
1467
  Form component for changing user passwords.
1389
1468
 
1390
1469
  ```tsx
1391
- import { PasswordChangeForm } from '@jmruthers/pace-core';
1470
+ import { PasswordChangeForm, logger } from '@jmruthers/pace-core';
1392
1471
 
1393
1472
  <PasswordChangeForm
1394
1473
  onSubmit={(values) => {
1395
1474
  // Handle password change
1396
- console.log('New password:', values.newPassword);
1475
+ logger.debug('PasswordChange', 'Password change initiated');
1476
+ // Note: Never log actual password values in production
1397
1477
  }}
1398
1478
  />
1399
1479
  ```
@@ -1594,11 +1674,11 @@ interface FileUploadProps {
1594
1674
  #### Usage
1595
1675
 
1596
1676
  ```tsx
1597
- import { FileUpload, FileCategory } from '@jmruthers/pace-core';
1677
+ import { FileUpload, FileCategory, logger } from '@jmruthers/pace-core';
1598
1678
 
1599
1679
  function MyFileUpload() {
1600
1680
  const handleUpload = (fileRef: FileReference) => {
1601
- console.log('File uploaded:', fileRef);
1681
+ logger.debug('FileUpload', 'File uploaded:', { fileId: fileRef.id, fileName: fileRef.name });
1602
1682
  };
1603
1683
 
1604
1684
  return (
@@ -229,8 +229,6 @@ graph TD
229
229
 
230
230
  E --> R[Form]
231
231
  E --> S[FormField]
232
- E --> T[FormErrorSummary]
233
- E --> U[FormLiveRegion]
234
232
  ```
235
233
 
236
234
  ### Styling Architecture
@@ -532,6 +532,266 @@ const columns: DataTableColumn<Dish>[] = [
532
532
  // 3. Parent-child relationships are maintained
533
533
  ```
534
534
 
535
+ ## Grouped Row Aggregation
536
+
537
+ ### Overview
538
+
539
+ The DataTable supports custom aggregation functions in grouped rows, allowing columns to display aggregated values (sum, average, count, etc.) instead of just row counts. This is particularly useful for data analysis and reporting use cases.
540
+
541
+ ### Quick Start
542
+
543
+ #### 1. Enable Grouping
544
+
545
+ ```tsx
546
+ <DataTable
547
+ data={data}
548
+ columns={columns}
549
+ features={{
550
+ grouping: true, // Enable grouping
551
+ }}
552
+ defaultGrouping={['category']} // Optional: group by category on load
553
+ />
554
+ ```
555
+
556
+ #### 2. Add Aggregation Functions to Columns
557
+
558
+ ```tsx
559
+ import { DataTable, sum, average, count } from '@jmruthers/pace-core';
560
+
561
+ const columns: DataTableColumn<DinerData>[] = [
562
+ {
563
+ accessorKey: 'diet',
564
+ header: 'Diet',
565
+ enableGrouping: true,
566
+ },
567
+ {
568
+ accessorKey: 'youth',
569
+ header: 'Total Youth',
570
+ aggregateFn: sum('youth'), // Sum all youth values in the group
571
+ },
572
+ {
573
+ accessorKey: 'adults',
574
+ header: 'Total Adults',
575
+ aggregateFn: sum('adults'), // Sum all adult values in the group
576
+ },
577
+ {
578
+ accessorKey: 'cost',
579
+ header: 'Avg Cost',
580
+ aggregateFn: average('cost'), // Average cost across the group
581
+ },
582
+ ];
583
+ ```
584
+
585
+ ### Built-in Aggregation Functions
586
+
587
+ The DataTable provides several built-in aggregation utility functions:
588
+
589
+ #### Sum
590
+
591
+ ```tsx
592
+ {
593
+ accessorKey: 'quantity',
594
+ header: 'Total Quantity',
595
+ aggregateFn: sum('quantity'),
596
+ }
597
+ ```
598
+
599
+ #### Average
600
+
601
+ ```tsx
602
+ {
603
+ accessorKey: 'price',
604
+ header: 'Avg Price',
605
+ aggregateFn: average('price'),
606
+ }
607
+ ```
608
+
609
+ #### Count
610
+
611
+ ```tsx
612
+ {
613
+ accessorKey: 'id',
614
+ header: 'Count',
615
+ aggregateFn: count(),
616
+ }
617
+ ```
618
+
619
+ #### Min
620
+
621
+ ```tsx
622
+ {
623
+ accessorKey: 'price',
624
+ header: 'Min Price',
625
+ aggregateFn: min('price'),
626
+ }
627
+ ```
628
+
629
+ #### Max
630
+
631
+ ```tsx
632
+ {
633
+ accessorKey: 'price',
634
+ header: 'Max Price',
635
+ aggregateFn: max('price'),
636
+ }
637
+ ```
638
+
639
+ ### Custom Aggregation Functions
640
+
641
+ You can create custom aggregation functions for more complex calculations:
642
+
643
+ ```tsx
644
+ const columns: DataTableColumn<DinerData>[] = [
645
+ {
646
+ accessorKey: 'diet',
647
+ header: 'Diet',
648
+ enableGrouping: true,
649
+ },
650
+ {
651
+ accessorKey: 'youth',
652
+ header: 'Total Diners',
653
+ aggregateFn: (rows) => {
654
+ // Custom: sum of youth + adults
655
+ return rows.reduce((total, row) => total + (row.youth || 0) + (row.adults || 0), 0);
656
+ },
657
+ },
658
+ ];
659
+ ```
660
+
661
+ ### Custom Aggregate Cell Renderer
662
+
663
+ Use `aggregateCell` to customize how aggregated values are displayed:
664
+
665
+ ```tsx
666
+ {
667
+ accessorKey: 'cost',
668
+ header: 'Total Cost',
669
+ aggregateFn: sum('cost'),
670
+ aggregateCell: (value) => {
671
+ // Custom formatting for aggregated value
672
+ return `$${value.toFixed(2)}`;
673
+ },
674
+ }
675
+ ```
676
+
677
+ If `aggregateCell` is not provided, the column's regular `cell` renderer will be used, or the raw value will be displayed.
678
+
679
+ ### Complete Example
680
+
681
+ ```tsx
682
+ import { DataTable, sum, average, type DataTableColumn } from '@jmruthers/pace-core';
683
+
684
+ interface DinerData {
685
+ id: string;
686
+ diet: string;
687
+ youth: number;
688
+ adults: number;
689
+ cost: number;
690
+ }
691
+
692
+ const dinerData: DinerData[] = [
693
+ { id: '1', diet: 'Standard', youth: 10, adults: 5, cost: 100.50 },
694
+ { id: '2', diet: 'Standard', youth: 15, adults: 8, cost: 150.75 },
695
+ { id: '3', diet: 'Standard', youth: 20, adults: 10, cost: 200.00 },
696
+ { id: '4', diet: 'Gluten Free', youth: 5, adults: 3, cost: 75.25 },
697
+ { id: '5', diet: 'Gluten Free', youth: 8, adults: 4, cost: 120.00 },
698
+ ];
699
+
700
+ const columns: DataTableColumn<DinerData>[] = [
701
+ {
702
+ accessorKey: 'diet',
703
+ header: 'Diet',
704
+ enableGrouping: true,
705
+ },
706
+ {
707
+ accessorKey: 'youth',
708
+ header: 'Youth',
709
+ sortable: true,
710
+ aggregateFn: sum('youth'),
711
+ aggregateCell: (value) => value.toLocaleString(),
712
+ },
713
+ {
714
+ accessorKey: 'adults',
715
+ header: 'Adults',
716
+ sortable: true,
717
+ aggregateFn: sum('adults'),
718
+ aggregateCell: (value) => value.toLocaleString(),
719
+ },
720
+ {
721
+ accessorKey: 'cost',
722
+ header: 'Avg Cost',
723
+ sortable: true,
724
+ aggregateFn: average('cost'),
725
+ aggregateCell: (value) => `$${value.toFixed(2)}`,
726
+ },
727
+ ];
728
+
729
+ function DinersTable() {
730
+ return (
731
+ <DataTable
732
+ data={dinerData}
733
+ columns={columns}
734
+ rbac={{ pageName: 'diners' }}
735
+ features={{
736
+ grouping: true,
737
+ sorting: true,
738
+ pagination: true,
739
+ }}
740
+ defaultGrouping={['diet']}
741
+ getRowId={(row) => row.id}
742
+ />
743
+ );
744
+ }
745
+ ```
746
+
747
+ ### Edge Cases and Best Practices
748
+
749
+ #### Handling Null/Undefined Values
750
+
751
+ Aggregation functions should handle null/undefined values gracefully:
752
+
753
+ ```tsx
754
+ {
755
+ accessorKey: 'quantity',
756
+ header: 'Total',
757
+ aggregateFn: (rows) => {
758
+ return rows.reduce((sum, row) => {
759
+ const value = row.quantity;
760
+ return sum + (value != null ? value : 0);
761
+ }, 0);
762
+ },
763
+ }
764
+ ```
765
+
766
+ The built-in aggregation functions (`sum`, `average`, etc.) already handle null/undefined values correctly.
767
+
768
+ #### Empty Groups
769
+
770
+ When a group has no rows, aggregation functions should return appropriate defaults:
771
+ - `sum`: Returns `0`
772
+ - `average`: Returns `0`
773
+ - `count`: Returns `0`
774
+ - `min`/`max`: Returns `null`
775
+
776
+ #### Columns Without Aggregation
777
+
778
+ Columns without an `aggregateFn` will show empty cells in grouped rows (current behavior). This is intentional and allows you to selectively aggregate only the columns that need it.
779
+
780
+ #### Performance Considerations
781
+
782
+ - Aggregation functions are called once per group when the group is rendered
783
+ - For large datasets, consider memoizing expensive aggregation functions
784
+ - Aggregated values are recalculated when group membership changes
785
+
786
+ ### Integration with Other Features
787
+
788
+ Grouped row aggregation works seamlessly with:
789
+ - **Sorting**: Aggregated values can be sorted
790
+ - **Filtering**: Aggregated values respect filters
791
+ - **Pagination**: Aggregated values work with pagination
792
+ - **Search**: Aggregated values are searchable
793
+ - **Nested Grouping**: Aggregation works at each grouping level
794
+
535
795
  ## Advanced Filtering
536
796
 
537
797
  ### Filter Types
@@ -1019,12 +1279,14 @@ const columns = [
1019
1279
  #### Real-Time Metrics
1020
1280
 
1021
1281
  ```tsx
1282
+ import { logger } from '@jmruthers/pace-core/utils';
1283
+
1022
1284
  <DataTable
1023
1285
  data={data}
1024
1286
  columns={columns}
1025
1287
  showPerformanceMetrics={true}
1026
1288
  onPerformanceMetrics={(metrics) => {
1027
- console.log('Performance metrics:', {
1289
+ logger.debug('DataTable', 'Performance metrics:', {
1028
1290
  renderTime: metrics.renderTime,
1029
1291
  memoryUsage: metrics.memoryUsage,
1030
1292
  visibleRows: metrics.visibleRows,
@@ -1075,7 +1337,7 @@ const columns = [
1075
1337
 
1076
1338
  ```tsx
1077
1339
  import { useState } from 'react';
1078
- import { DataTable } from '@jmruthers/pace-core';
1340
+ import { DataTable, logger } from '@jmruthers/pace-core';
1079
1341
  import { supabase } from '../supabaseClient';
1080
1342
 
1081
1343
  interface User {
@@ -1101,7 +1363,7 @@ function UserManagement() {
1101
1363
  if (error) throw error;
1102
1364
  setUsers(data || []);
1103
1365
  } catch (error) {
1104
- console.error('Error fetching users:', error);
1366
+ logger.error('UserManagement', 'Error fetching users:', error);
1105
1367
  } finally {
1106
1368
  setLoading(false);
1107
1369
  }
@@ -1123,7 +1385,7 @@ function UserManagement() {
1123
1385
 
1124
1386
  return { success: true, data };
1125
1387
  } catch (error) {
1126
- console.error('Error creating user:', error);
1388
+ logger.error('UserManagement', 'Error creating user:', error);
1127
1389
  return { success: false, error };
1128
1390
  }
1129
1391
  };
@@ -1147,7 +1409,7 @@ function UserManagement() {
1147
1409
 
1148
1410
  return { success: true, data };
1149
1411
  } catch (error) {
1150
- console.error('Error updating user:', error);
1412
+ logger.error('UserManagement', 'Error updating user:', error);
1151
1413
  return { success: false, error };
1152
1414
  }
1153
1415
  };
@@ -1167,7 +1429,7 @@ function UserManagement() {
1167
1429
 
1168
1430
  return { success: true };
1169
1431
  } catch (error) {
1170
- console.error('Error deleting user:', error);
1432
+ logger.error('UserManagement', 'Error deleting user:', error);
1171
1433
  return { success: false, error };
1172
1434
  }
1173
1435
  };
@@ -1187,7 +1449,7 @@ function UserManagement() {
1187
1449
 
1188
1450
  return { success: true };
1189
1451
  } catch (error) {
1190
- console.error('Error deleting selected users:', error);
1452
+ logger.error('UserManagement', 'Error deleting selected users:', error);
1191
1453
  return { success: false, error };
1192
1454
  }
1193
1455
  };
@@ -1333,7 +1595,7 @@ const columns = [
1333
1595
 
1334
1596
  ```tsx
1335
1597
  import { useState, useCallback, useMemo } from 'react';
1336
- import { DataTable } from '@jmruthers/pace-core';
1598
+ import { DataTable, logger } from '@jmruthers/pace-core';
1337
1599
 
1338
1600
  interface Item {
1339
1601
  id: string;
@@ -1363,7 +1625,7 @@ function ItemsTable() {
1363
1625
  };
1364
1626
 
1365
1627
  setCategories(prev => [...prev, newCategory]);
1366
- console.log(`Created new category: "${inputValue}"`);
1628
+ logger.debug('CategoryManager', `Created new category: "${inputValue}"`);
1367
1629
 
1368
1630
  return newCategory.value;
1369
1631
  }, []);
@@ -1756,7 +2018,7 @@ The export filename is automatically generated from the table `title` prop:
1756
2018
  By default, the DataTable exports all **visible columns**. To customize the export (different columns, custom filename, etc.), you can provide a custom `onExport` handler:
1757
2019
 
1758
2020
  ```tsx
1759
- import { DataTable, type ExportOptions, exportToCSVWithTableRows, type ExportColumn } from '@jmruthers/pace-core';
2021
+ import { DataTable, type ExportOptions, exportToCSVWithTableRows, type ExportColumn, logger } from '@jmruthers/pace-core';
1760
2022
 
1761
2023
  <DataTable
1762
2024
  title="Meals"
@@ -1780,7 +2042,7 @@ import { DataTable, type ExportOptions, exportToCSVWithTableRows, type ExportCol
1780
2042
 
1781
2043
  // Verify this column ID exists in the mapping (for getValue() to work)
1782
2044
  if (!options.columnIdToTableColumn.has(tableColumnId)) {
1783
- console.warn(`Column ID ${tableColumnId} not found in columnIdToTableColumn map`);
2045
+ logger.warn('DataTable', `Column ID ${tableColumnId} not found in columnIdToTableColumn map`);
1784
2046
  return null;
1785
2047
  }
1786
2048
 
@@ -2105,6 +2367,8 @@ Enable debug logging for DataTable issues:
2105
2367
 
2106
2368
  Enable detailed logging:
2107
2369
  ```tsx
2370
+ import { logger } from '@jmruthers/pace-core/utils';
2371
+
2108
2372
  <DataTable
2109
2373
  data={data}
2110
2374
  columns={columns}
@@ -2112,10 +2376,10 @@ Enable detailed logging:
2112
2376
  onPerformanceMetrics={(metrics) => {
2113
2377
  // Log performance issues
2114
2378
  if (metrics.renderTime > 100) {
2115
- console.warn('Slow render detected:', metrics.renderTime);
2379
+ logger.warn('DataTable', 'Slow render detected:', metrics.renderTime);
2116
2380
  }
2117
2381
  if (metrics.memoryUsage > 100) {
2118
- console.warn('High memory usage:', metrics.memoryUsage);
2382
+ logger.warn('DataTable', 'High memory usage:', metrics.memoryUsage);
2119
2383
  }
2120
2384
  }}
2121
2385
  />
@@ -484,22 +484,7 @@ function FormWithState() {
484
484
  </p>
485
485
  ```
486
486
 
487
- ### 2. Error Announcements
488
-
489
- ```tsx
490
- import { FormLiveRegion } from '@jmruthers/pace-core';
491
-
492
- function AccessibleForm() {
493
- return (
494
- <Form schema={userSchema} onSubmit={handleSubmit}>
495
- <FormLiveRegion />
496
- {/* Form fields */}
497
- </Form>
498
- );
499
- }
500
- ```
501
-
502
- ### 3. Keyboard Navigation
487
+ ### 2. Keyboard Navigation
503
488
 
504
489
  All form components support full keyboard navigation:
505
490
 
@@ -570,12 +570,15 @@ FOR SELECT USING (
570
570
  Monitor permission checks for security:
571
571
 
572
572
  ```tsx
573
+ import { getRBACLogger } from '@jmruthers/pace-core/rbac';
574
+
573
575
  // Enable audit trail in development
574
576
  const { getAuditTrail } = usePermissionCache();
577
+ const rbacLogger = getRBACLogger();
575
578
 
576
579
  // Log permission decisions
577
580
  const auditTrail = getAuditTrail();
578
- console.log('Permission audit:', auditTrail);
581
+ rbacLogger.debug('Permission audit:', auditTrail);
579
582
  ```
580
583
 
581
584
  ## Best Practices
@@ -743,12 +746,15 @@ setupRBAC(supabase);
743
746
  Enable debug logging to troubleshoot permission issues:
744
747
 
745
748
  ```tsx
749
+ import { getRBACLogger } from '@jmruthers/pace-core/rbac';
750
+
746
751
  // Add to your app for debugging
747
752
  const { getDebugInfo } = usePermissionCache();
753
+ const rbacLogger = getRBACLogger();
748
754
 
749
755
  // Log debug information
750
756
  const debugInfo = getDebugInfo();
751
- console.log('Permission debug:', debugInfo);
757
+ rbacLogger.debug('Permission debug:', debugInfo);
752
758
  ```
753
759
 
754
760
  ## 🎯 **Pattern Selection Guide**