@jmruthers/pace-core 0.5.135 → 0.5.137

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 (544) hide show
  1. package/dist/{DataTable-A36PJG6N.js → DataTable-6M4L6BI2.js} +26 -13
  2. package/dist/{DataTable-C7GaRZye.d.ts → DataTable-CWAZZcXC.d.ts} +1 -1
  3. package/dist/{PublicLoadingSpinner-CUAnTvcg.d.ts → EventLogo-rFL_kRjk.d.ts} +123 -135
  4. package/dist/{UnifiedAuthProvider-BVKmQd9u.d.ts → UnifiedAuthProvider-DJxGTftH.d.ts} +1 -1
  5. package/dist/{UnifiedAuthProvider-CQDZRJIS.js → UnifiedAuthProvider-XIQQ7LVU.js} +5 -5
  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-F64FFPOZ.js → chunk-22WKWKRX.js} +26 -20
  9. package/dist/chunk-22WKWKRX.js.map +1 -0
  10. package/dist/{chunk-VZ5OR6HD.js → chunk-4C7EXCAR.js} +62 -150
  11. package/dist/chunk-4C7EXCAR.js.map +1 -0
  12. package/dist/{chunk-PYUXFQJ3.js → chunk-56XJ3TU6.js} +2 -2
  13. package/dist/chunk-56XJ3TU6.js.map +1 -0
  14. package/dist/{chunk-CTJRBUX2.js → chunk-6LAAY47Q.js} +2 -2
  15. package/dist/{chunk-UJI6WSMD.js → chunk-7QCC6MCP.js} +90 -3
  16. package/dist/chunk-7QCC6MCP.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-CQZU6TFE.js → chunk-BCIBECNB.js} +100 -62
  20. package/dist/chunk-BCIBECNB.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-BJPBT3CU.js +21 -0
  24. package/dist/chunk-BJPBT3CU.js.map +1 -0
  25. package/dist/{chunk-BYXRHAIF.js → chunk-BLCXZEYF.js} +23 -14
  26. package/dist/chunk-BLCXZEYF.js.map +1 -0
  27. package/dist/{chunk-WP5I5GLN.js → chunk-BVYWGZVV.js} +112 -97
  28. package/dist/chunk-BVYWGZVV.js.map +1 -0
  29. package/dist/{chunk-GEVIB2UB.js → chunk-ERISIBYU.js} +14 -5
  30. package/dist/chunk-ERISIBYU.js.map +1 -0
  31. package/dist/{chunk-O3NWNXDY.js → chunk-FMUCXFII.js} +2 -2
  32. package/dist/chunk-FMUCXFII.js.map +1 -0
  33. package/dist/{chunk-GVDR7WNV.js → chunk-HAWZXGR2.js} +334 -614
  34. package/dist/chunk-HAWZXGR2.js.map +1 -0
  35. package/dist/{chunk-ZV77RZMU.js → chunk-INQLMHPF.js} +2 -2
  36. package/dist/chunk-JISYG63F.js +70 -0
  37. package/dist/chunk-JISYG63F.js.map +1 -0
  38. package/dist/{chunk-HMNOSGVA.js → chunk-KYRHUBIU.js} +576 -767
  39. package/dist/chunk-KYRHUBIU.js.map +1 -0
  40. package/dist/{chunk-M6DDYFUD.js → chunk-LS353YLY.js} +19 -16
  41. package/dist/chunk-LS353YLY.js.map +1 -0
  42. package/dist/{chunk-TGIY2AR2.js → chunk-MA6EPSGZ.js} +4 -3
  43. package/dist/{chunk-TGIY2AR2.js.map → chunk-MA6EPSGZ.js.map} +1 -1
  44. package/dist/chunk-OWAG3GSU.js +58 -0
  45. package/dist/chunk-OWAG3GSU.js.map +1 -0
  46. package/dist/{chunk-JCQZ6LA7.js → chunk-Q5QRDWKI.js} +9 -3
  47. package/dist/chunk-Q5QRDWKI.js.map +1 -0
  48. package/dist/chunk-S5OFRT4M.js +94 -0
  49. package/dist/chunk-S5OFRT4M.js.map +1 -0
  50. package/dist/{chunk-3DBFLLLU.js → chunk-SBVILCCA.js} +14 -9
  51. package/dist/chunk-SBVILCCA.js.map +1 -0
  52. package/dist/{chunk-ZYZCRSBD.js → chunk-T6JN6LH6.js} +16 -11
  53. package/dist/chunk-T6JN6LH6.js.map +1 -0
  54. package/dist/chunk-XDNLUEXI.js +138 -0
  55. package/dist/chunk-XDNLUEXI.js.map +1 -0
  56. package/dist/{chunk-3CG5L6RN.js → chunk-YCWDTTUK.js} +90 -75
  57. package/dist/chunk-YCWDTTUK.js.map +1 -0
  58. package/dist/{chunk-5F3NDPJV.js → chunk-ZZ2SS7NI.js} +10 -5
  59. package/dist/chunk-ZZ2SS7NI.js.map +1 -0
  60. package/dist/components.d.ts +7 -287
  61. package/dist/components.js +27 -157
  62. package/dist/components.js.map +1 -1
  63. package/dist/{file-reference-C9isKNPn.d.ts → file-reference-C6Gkn77H.d.ts} +1 -1
  64. package/dist/{formatting-DFcCxUEk.d.ts → formatting-CvUXy2mF.d.ts} +1 -1
  65. package/dist/hooks.d.ts +3 -3
  66. package/dist/hooks.js +21 -16
  67. package/dist/hooks.js.map +1 -1
  68. package/dist/index.d.ts +101 -9
  69. package/dist/index.js +44 -31
  70. package/dist/index.js.map +1 -1
  71. package/dist/providers.d.ts +1 -1
  72. package/dist/providers.js +4 -4
  73. package/dist/rbac/index.js +12 -12
  74. package/dist/schema-DTDZQe2u.d.ts +28 -0
  75. package/dist/styles/index.js +2 -1
  76. package/dist/theming/runtime.d.ts +2 -19
  77. package/dist/theming/runtime.js +2 -1
  78. package/dist/{types-D5rqZQXk.d.ts → types-Dfz9dmVH.d.ts} +12 -1
  79. package/dist/types.d.ts +153 -4
  80. package/dist/types.js +51 -16
  81. package/dist/types.js.map +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 +221 -173
  85. package/dist/utils.js +185 -225
  86. package/dist/utils.js.map +1 -1
  87. package/dist/validation.d.ts +24 -115
  88. package/dist/validation.js +19 -474
  89. package/dist/validation.js.map +1 -1
  90. package/docs/api/classes/ColumnFactory.md +1 -1
  91. package/docs/api/classes/ErrorBoundary.md +6 -6
  92. package/docs/api/classes/InvalidScopeError.md +1 -1
  93. package/docs/api/classes/MissingUserContextError.md +1 -1
  94. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  95. package/docs/api/classes/PermissionDeniedError.md +1 -1
  96. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  97. package/docs/api/classes/RBACAuditManager.md +6 -6
  98. package/docs/api/classes/RBACCache.md +1 -1
  99. package/docs/api/classes/RBACEngine.md +7 -7
  100. package/docs/api/classes/RBACError.md +1 -1
  101. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  102. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  103. package/docs/api/classes/StorageUtils.md +1 -1
  104. package/docs/api/enums/FileCategory.md +1 -1
  105. package/docs/api/interfaces/AggregateConfig.md +4 -4
  106. package/docs/api/interfaces/BadgeProps.md +27 -0
  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 +591 -220
  199. package/docs/api-reference/components.md +106 -26
  200. package/docs/architecture/README.md +0 -3
  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/docs/styles/README.md +0 -2
  205. package/examples/README.md +30 -14
  206. package/examples/STRUCTURE.md +125 -0
  207. package/examples/components 2/DataTable/HierarchicalActionsExample.tsx +421 -0
  208. package/examples/components 2/DataTable/HierarchicalExample.tsx +475 -0
  209. package/examples/components 2/DataTable/InitialPageSizeExample.tsx +177 -0
  210. package/examples/components 2/DataTable/PerformanceExample.tsx +506 -0
  211. package/examples/components 2/DataTable/index.ts +13 -0
  212. package/examples/components 2/Dialog/BasicHtmlTest.tsx +55 -0
  213. package/examples/components 2/Dialog/DebugHtmlExample.tsx +68 -0
  214. package/examples/components 2/Dialog/HtmlDialogExample.tsx +202 -0
  215. package/examples/components 2/Dialog/ScrollableDialogExample.tsx +290 -0
  216. package/examples/components 2/Dialog/SimpleHtmlTest.tsx +61 -0
  217. package/examples/components 2/Dialog/SmartDialogExample.tsx +322 -0
  218. package/examples/components 2/Dialog/index.ts +15 -0
  219. package/examples/components 2/index.ts +11 -0
  220. package/examples/features/index.ts +12 -0
  221. package/{src/examples → examples/features/public-pages}/CorrectPublicPageImplementation.tsx +14 -17
  222. package/{src/examples → examples/features/public-pages}/PublicEventPage.tsx +14 -27
  223. package/{src/examples → examples/features/public-pages}/PublicPageApp.tsx +15 -28
  224. package/{src/examples → examples/features/public-pages}/PublicPageUsageExample.tsx +8 -10
  225. package/examples/features/public-pages/index.ts +14 -0
  226. package/examples/features/rbac/CompleteRBACExample.tsx +324 -0
  227. package/examples/features/rbac/EventBasedApp.tsx +239 -0
  228. package/examples/features/rbac/PermissionExample.tsx +151 -0
  229. package/examples/features/rbac/index.ts +13 -0
  230. package/examples/index.ts +11 -3
  231. package/package.json +30 -19
  232. package/src/__tests__/TEST_STANDARD.md +92 -0
  233. package/src/components/Alert/Alert.tsx +1 -1
  234. package/src/components/Avatar/Avatar.tsx +1 -1
  235. package/src/components/Badge/Badge.test.tsx +314 -0
  236. package/src/components/Badge/Badge.tsx +304 -0
  237. package/src/components/Badge/index.ts +3 -0
  238. package/src/components/Button/Button.tsx +1 -1
  239. package/src/components/Card/Card.tsx +1 -1
  240. package/src/components/Checkbox/Checkbox.tsx +1 -1
  241. package/src/components/DataTable/DataTable.test.tsx +1 -1
  242. package/src/components/DataTable/DataTable.tsx +1 -30
  243. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +562 -0
  244. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +217 -0
  245. package/src/components/DataTable/__tests__/styles.test.ts +3 -3
  246. package/src/components/DataTable/components/ActionButtons.tsx +0 -15
  247. package/src/components/DataTable/components/ColumnFilter.tsx +8 -4
  248. package/src/components/DataTable/components/DataTableBody.tsx +461 -0
  249. package/src/components/DataTable/components/DataTableCore.tsx +4 -185
  250. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +1 -1
  251. package/src/components/DataTable/components/DataTableModals.tsx +1 -27
  252. package/src/components/DataTable/components/DraggableColumnHeader.tsx +144 -0
  253. package/src/components/DataTable/components/EditableRow.tsx +1 -1
  254. package/src/components/DataTable/components/FilterRow.tsx +9 -3
  255. package/src/components/DataTable/components/ImportModal.tsx +2 -14
  256. package/src/components/DataTable/components/PaginationControls.tsx +2 -1
  257. package/src/components/DataTable/components/UnifiedTableBody.tsx +109 -82
  258. package/src/components/DataTable/components/VirtualizedDataTable.tsx +513 -0
  259. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +14 -68
  260. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +1 -1
  261. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +62 -0
  262. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +1 -1
  263. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +1 -1
  264. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +43 -0
  265. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +1 -1
  266. package/src/components/DataTable/core/ActionManager.ts +235 -0
  267. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  268. package/src/components/DataTable/core/DataManager.ts +188 -0
  269. package/src/components/DataTable/core/DataTableContext.tsx +181 -0
  270. package/src/components/DataTable/core/LocalDataAdapter.ts +273 -0
  271. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  272. package/src/components/DataTable/core/StateManager.ts +311 -0
  273. package/src/components/DataTable/core/interfaces.ts +338 -0
  274. package/src/components/DataTable/examples/GroupingAggregationExample.tsx +273 -0
  275. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +1 -1
  276. package/src/components/DataTable/examples/__tests__/HierarchicalActionsExample.test.tsx +1 -1
  277. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +1 -1
  278. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +1 -1
  279. package/src/components/DataTable/hooks/useDataTablePermissions.ts +2 -23
  280. package/src/components/DataTable/index.ts +4 -0
  281. package/src/components/DataTable/styles.ts +28 -7
  282. package/src/components/DataTable/types.ts +13 -0
  283. package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +94 -0
  284. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +1 -1
  285. package/src/components/DataTable/utils/aggregationUtils.ts +161 -0
  286. package/src/components/DataTable/utils/columnUtils.ts +40 -0
  287. package/src/components/DataTable/utils/debugTools.ts +609 -0
  288. package/src/components/DataTable/utils/exportUtils.ts +1 -1
  289. package/src/components/DataTable/utils/flexibleImport.ts +1 -11
  290. package/src/components/DataTable/utils/index.ts +2 -0
  291. package/src/components/DataTable/utils/paginationUtils.ts +1 -1
  292. package/src/components/Dialog/Dialog.tsx +2 -2
  293. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +8 -1
  294. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +35 -7
  295. package/src/components/ErrorBoundary/ErrorBoundary.tsx +5 -4
  296. package/src/components/EventSelector/EventSelector.tsx +3 -2
  297. package/src/components/FileDisplay/FileDisplay.tsx +2 -36
  298. package/src/components/FileUpload/FileUpload.test.tsx +2 -2
  299. package/src/components/FileUpload/FileUpload.tsx +2 -2
  300. package/src/components/Footer/Footer.test.tsx +1 -1
  301. package/src/components/Footer/Footer.tsx +1 -1
  302. package/src/components/Form/Form.test.tsx +5 -510
  303. package/src/components/Form/Form.tsx +1 -1
  304. package/src/components/Form/FormField.tsx +1 -1
  305. package/src/components/Form/index.ts +0 -12
  306. package/src/components/Header/Header.tsx +1 -1
  307. package/src/components/Input/Input.tsx +1 -1
  308. package/src/components/Label/Label.tsx +1 -1
  309. package/src/components/LoginForm/LoginForm.test.tsx +1 -1
  310. package/src/components/LoginForm/LoginForm.tsx +1 -1
  311. package/src/components/NavigationMenu/NavigationMenu.test.tsx +19 -3
  312. package/src/components/NavigationMenu/NavigationMenu.tsx +9 -8
  313. package/src/components/OrganisationSelector/OrganisationSelector.tsx +4 -3
  314. package/src/components/PaceAppLayout/PaceAppLayout.tsx +14 -12
  315. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +0 -16
  316. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +76 -10
  317. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +0 -1
  318. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +0 -9
  319. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +35 -3
  320. package/src/components/PaceLoginPage/PaceLoginPage.tsx +14 -13
  321. package/src/components/PasswordReset/PasswordChangeForm.tsx +1 -1
  322. package/src/components/PasswordReset/index.ts +0 -2
  323. package/src/components/Progress/Progress.tsx +1 -1
  324. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +35 -8
  325. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -2
  326. package/src/components/PublicLayout/PublicErrorBoundary.tsx +1 -1
  327. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +1 -1
  328. package/src/components/PublicLayout/PublicPageContextChecker.tsx +44 -43
  329. package/src/components/PublicLayout/PublicPageFooter.tsx +1 -1
  330. package/src/components/PublicLayout/PublicPageHeader.tsx +1 -15
  331. package/src/components/PublicLayout/PublicPageProvider.tsx +3 -2
  332. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +2 -0
  333. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +1 -1
  334. package/src/components/PublicLayout/index.ts +4 -2
  335. package/src/components/Select/Select.test.tsx +1 -1
  336. package/src/components/Select/Select.tsx +21 -9
  337. package/src/components/{SessionRestorationLoader.tsx → SessionRestorationLoader/SessionRestorationLoader.tsx} +3 -2
  338. package/src/components/SessionRestorationLoader/index.ts +3 -0
  339. package/src/components/Switch/Switch.tsx +1 -1
  340. package/src/components/Table/Table.tsx +1 -1
  341. package/src/components/Table/__tests__/Table.test.tsx +1 -1
  342. package/src/components/Toast/Toast.tsx +1 -1
  343. package/src/components/Tooltip/Tooltip.tsx +1 -1
  344. package/src/components/index.ts +7 -10
  345. package/src/hooks/__tests__/hooks.integration.test.tsx +37 -22
  346. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +33 -17
  347. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +28 -3
  348. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +36 -9
  349. package/src/hooks/__tests__/useFileUrl.unit.test.ts +83 -85
  350. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +26 -2
  351. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +19 -6
  352. package/src/hooks/__tests__/usePermissionCache.simple.test.ts +17 -4
  353. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +17 -4
  354. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +26 -6
  355. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +16 -6
  356. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +3 -3
  357. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +17 -3
  358. package/src/hooks/public/usePublicEvent.ts +7 -6
  359. package/src/hooks/public/usePublicEventLogo.ts +7 -4
  360. package/src/hooks/public/usePublicFileDisplay.ts +6 -150
  361. package/src/hooks/useComponentPerformance.ts +4 -1
  362. package/src/hooks/useDataTablePerformance.ts +4 -3
  363. package/src/hooks/useEventTheme.test.ts +18 -5
  364. package/src/hooks/useEventTheme.ts +4 -1
  365. package/src/hooks/useEvents.ts +2 -0
  366. package/src/hooks/useFileDisplay.ts +9 -8
  367. package/src/hooks/useFileReference.ts +4 -1
  368. package/src/hooks/useFileUrl.ts +4 -1
  369. package/src/hooks/useInactivityTracker.ts +5 -4
  370. package/src/hooks/useOrganisationSecurity.test.ts +33 -12
  371. package/src/hooks/useOrganisationSecurity.ts +8 -7
  372. package/src/hooks/usePerformanceMonitor.ts +6 -3
  373. package/src/hooks/usePermissionCache.ts +13 -6
  374. package/src/hooks/useSecureDataAccess.test.ts +2 -2
  375. package/src/hooks/useSecureDataAccess.ts +9 -8
  376. package/src/hooks/useSessionRestoration.ts +4 -1
  377. package/src/hooks/useStorage.ts +4 -1
  378. package/src/index.ts +20 -7
  379. package/src/providers/services/AuthServiceProvider.tsx +3 -2
  380. package/src/providers/services/EventServiceProvider.tsx +2 -1
  381. package/src/providers/services/InactivityServiceProvider.tsx +2 -1
  382. package/src/providers/services/OrganisationServiceProvider.tsx +2 -1
  383. package/src/providers/services/UnifiedAuthProvider.tsx +4 -3
  384. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +22 -2
  385. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +24 -2
  386. package/src/rbac/__tests__/cache-invalidation.test.ts +20 -6
  387. package/src/rbac/api.ts +5 -2
  388. package/src/rbac/audit-enhanced.ts +6 -6
  389. package/src/rbac/audit.test.ts +60 -38
  390. package/src/rbac/audit.ts +8 -8
  391. package/src/rbac/cache-invalidation.ts +7 -4
  392. package/src/rbac/components/EnhancedNavigationMenu.tsx +11 -5
  393. package/src/rbac/components/NavigationGuard.tsx +7 -3
  394. package/src/rbac/components/NavigationProvider.tsx +6 -3
  395. package/src/rbac/components/PagePermissionGuard.tsx +28 -16
  396. package/src/rbac/components/PagePermissionProvider.tsx +4 -1
  397. package/src/rbac/components/PermissionEnforcer.tsx +9 -3
  398. package/src/rbac/components/RoleBasedRouter.tsx +3 -1
  399. package/src/rbac/components/SecureDataProvider.tsx +7 -3
  400. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +87 -61
  401. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +83 -33
  402. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +36 -13
  403. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +2 -2
  404. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +22 -8
  405. package/src/rbac/components/__tests__/PermissionEnforcer.test.tsx +19 -6
  406. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +43 -17
  407. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +42 -17
  408. package/src/rbac/engine.ts +15 -7
  409. package/src/rbac/hooks/usePermissions.ts +7 -3
  410. package/src/rbac/hooks/useResolvedScope.test.ts +2 -2
  411. package/src/rbac/hooks/useResolvedScope.ts +10 -7
  412. package/src/rbac/permissions.ts +5 -2
  413. package/src/rbac/security.test.ts +27 -16
  414. package/src/rbac/security.ts +5 -4
  415. package/src/services/AuthService.ts +22 -21
  416. package/src/services/EventService.ts +12 -12
  417. package/src/services/InactivityService.ts +5 -4
  418. package/src/services/OrganisationService.ts +26 -25
  419. package/src/services/__tests__/AuthService.test.ts +51 -19
  420. package/src/services/__tests__/EventService.test.ts +37 -5
  421. package/src/services/__tests__/InactivityService.test.ts +38 -4
  422. package/src/services/__tests__/OrganisationService.test.ts +3 -8
  423. package/src/services/base/BaseService.ts +3 -1
  424. package/src/styles/core.css +3 -0
  425. package/src/theming/__tests__/runtime.test.ts +21 -12
  426. package/src/theming/parseEventColours.ts +5 -19
  427. package/src/theming/runtime.ts +8 -4
  428. package/src/types/validation.ts +2 -29
  429. package/src/utils/__tests__/appConfig.unit.test.ts +1 -1
  430. package/src/utils/__tests__/audit.unit.test.ts +1 -1
  431. package/src/utils/__tests__/auth-utils.unit.test.ts +1 -1
  432. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +19 -19
  433. package/src/utils/__tests__/cn.unit.test.ts +1 -1
  434. package/src/utils/__tests__/debugLogger.test.ts +1 -1
  435. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +1 -1
  436. package/src/utils/__tests__/dynamicUtils.unit.test.ts +1 -1
  437. package/src/utils/__tests__/formatting.unit.test.ts +1 -1
  438. package/src/utils/__tests__/lazyLoad.unit.test.tsx +1 -1
  439. package/src/utils/__tests__/logger.unit.test.ts +1 -1
  440. package/src/utils/__tests__/organisationContext.unit.test.ts +1 -1
  441. package/src/utils/__tests__/performanceBenchmark.test.ts +1 -1
  442. package/src/utils/__tests__/performanceBudgets.unit.test.ts +1 -1
  443. package/src/utils/__tests__/permissionTypes.unit.test.ts +1 -1
  444. package/src/utils/__tests__/permissionUtils.unit.test.ts +1 -1
  445. package/src/utils/__tests__/sanitization.unit.test.ts +1 -1
  446. package/src/utils/__tests__/schemaUtils.unit.test.ts +1 -1
  447. package/src/utils/__tests__/secureDataAccess.unit.test.ts +1 -1
  448. package/src/utils/__tests__/secureErrors.unit.test.ts +33 -15
  449. package/src/utils/__tests__/secureStorage.unit.test.ts +1 -1
  450. package/src/utils/__tests__/security.unit.test.ts +40 -18
  451. package/src/utils/__tests__/securityMonitor.unit.test.ts +1 -1
  452. package/src/utils/__tests__/sessionTracking.unit.test.ts +40 -29
  453. package/src/utils/__tests__/validationUtils.unit.test.ts +19 -6
  454. package/src/utils/app/appConfig.ts +47 -0
  455. package/src/utils/app/appIdResolver.test.ts +497 -0
  456. package/src/utils/app/appIdResolver.ts +133 -0
  457. package/src/utils/app/appNameResolver.simple.test.ts +212 -0
  458. package/src/utils/app/appNameResolver.test.ts +121 -0
  459. package/src/utils/app/appNameResolver.ts +195 -0
  460. package/src/utils/audit/audit.ts +127 -0
  461. package/src/utils/context/organisationContext.test.ts +322 -0
  462. package/src/utils/context/organisationContext.ts +156 -0
  463. package/src/utils/context/sessionTracking.ts +125 -0
  464. package/src/utils/core/cn.ts +7 -0
  465. package/src/utils/core/debugLogger.ts +67 -0
  466. package/src/utils/core/logger.ts +181 -0
  467. package/src/utils/device/deviceFingerprint.ts +215 -0
  468. package/src/utils/dynamic/dynamicUtils.ts +105 -0
  469. package/src/utils/dynamic/lazyLoad.tsx +44 -0
  470. package/src/utils/file-reference/__tests__/file-reference.test.ts +788 -0
  471. package/src/utils/file-reference/index.ts +501 -0
  472. package/src/utils/formatting/formatDate.test.ts +237 -0
  473. package/src/utils/formatting/formatting.ts +133 -0
  474. package/src/utils/index.ts +39 -54
  475. package/src/utils/performance/bundleAnalysis.ts +129 -0
  476. package/src/utils/performance/performanceBenchmark.ts +64 -0
  477. package/src/utils/performance/performanceBudgets.ts +110 -0
  478. package/src/utils/permissions/permissionTypes.ts +37 -0
  479. package/src/utils/permissions/permissionUtils.test.ts +393 -0
  480. package/src/utils/permissions/permissionUtils.ts +34 -0
  481. package/src/utils/security/auth-utils.ts +96 -0
  482. package/src/utils/security/secureDataAccess.test.ts +711 -0
  483. package/src/utils/security/secureDataAccess.ts +377 -0
  484. package/src/utils/security/secureErrors.ts +82 -0
  485. package/src/utils/security/secureStorage.ts +244 -0
  486. package/src/utils/security/security.ts +159 -0
  487. package/src/utils/security/securityMonitor.ts +45 -0
  488. package/src/utils/storage/__tests__/helpers.unit.test.ts +1 -4
  489. package/src/utils/storage/helpers.ts +15 -8
  490. package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +598 -0
  491. package/src/{validation → utils/validation}/csrf.ts +1 -1
  492. package/src/utils/validation/htmlSanitization.ts +184 -0
  493. package/src/utils/validation/index.ts +79 -0
  494. package/src/utils/validation/sanitization.ts +333 -0
  495. package/src/{validation/schemaUtils.ts → utils/validation/schema.ts} +11 -6
  496. package/src/{validation → utils/validation}/sqlInjectionProtection.ts +2 -0
  497. package/src/utils/validation/validation.ts +111 -0
  498. package/src/utils/validation/validationUtils.ts +123 -0
  499. package/src/validation/index.ts +3 -34
  500. package/dist/chunk-24MKLB7U.js +0 -81
  501. package/dist/chunk-24MKLB7U.js.map +0 -1
  502. package/dist/chunk-3CG5L6RN.js.map +0 -1
  503. package/dist/chunk-3DBFLLLU.js.map +0 -1
  504. package/dist/chunk-5F3NDPJV.js.map +0 -1
  505. package/dist/chunk-66C4BSAY.js.map +0 -1
  506. package/dist/chunk-BDZUMRBD.js +0 -87
  507. package/dist/chunk-BDZUMRBD.js.map +0 -1
  508. package/dist/chunk-BYXRHAIF.js.map +0 -1
  509. package/dist/chunk-CDQ3PX7L.js +0 -18
  510. package/dist/chunk-CDQ3PX7L.js.map +0 -1
  511. package/dist/chunk-CQZU6TFE.js.map +0 -1
  512. package/dist/chunk-F64FFPOZ.js.map +0 -1
  513. package/dist/chunk-GEVIB2UB.js.map +0 -1
  514. package/dist/chunk-GKHF54DI.js.map +0 -1
  515. package/dist/chunk-GVDR7WNV.js.map +0 -1
  516. package/dist/chunk-HMNOSGVA.js.map +0 -1
  517. package/dist/chunk-JCQZ6LA7.js.map +0 -1
  518. package/dist/chunk-M6DDYFUD.js.map +0 -1
  519. package/dist/chunk-O3NWNXDY.js.map +0 -1
  520. package/dist/chunk-PYUXFQJ3.js.map +0 -1
  521. package/dist/chunk-UJI6WSMD.js.map +0 -1
  522. package/dist/chunk-VZ5OR6HD.js.map +0 -1
  523. package/dist/chunk-WP5I5GLN.js.map +0 -1
  524. package/dist/chunk-ZYZCRSBD.js.map +0 -1
  525. package/dist/validation-DnhrNMju.d.ts +0 -159
  526. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +0 -185
  527. package/src/validation/__tests__/common.unit.test.ts +0 -101
  528. package/src/validation/__tests__/csrf.unit.test.ts +0 -365
  529. package/src/validation/__tests__/passwordSchema.unit.test.ts +0 -203
  530. package/src/validation/__tests__/sanitization.unit.test.ts +0 -250
  531. package/src/validation/__tests__/schemaUtils.unit.test.ts +0 -451
  532. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +0 -462
  533. package/src/validation/__tests__/user.unit.test.ts +0 -440
  534. package/src/validation/sanitization.ts +0 -96
  535. /package/dist/{DataTable-A36PJG6N.js.map → DataTable-6M4L6BI2.js.map} +0 -0
  536. /package/dist/{UnifiedAuthProvider-CQDZRJIS.js.map → UnifiedAuthProvider-XIQQ7LVU.js.map} +0 -0
  537. /package/dist/{api-TNIBJWLM.js.map → api-45XYYO2A.js.map} +0 -0
  538. /package/dist/{audit-T36HM7IM.js.map → audit-64X3VJXB.js.map} +0 -0
  539. /package/dist/{chunk-CTJRBUX2.js.map → chunk-6LAAY47Q.js.map} +0 -0
  540. /package/dist/{chunk-ZV77RZMU.js.map → chunk-INQLMHPF.js.map} +0 -0
  541. /package/dist/{useInactivityTracker-MRUU55XI.js.map → useInactivityTracker-TO6ZOF35.js.map} +0 -0
  542. /package/src/{validation → utils/validation}/common.ts +0 -0
  543. /package/src/{validation → utils/validation}/passwordSchema.ts +0 -0
  544. /package/src/{validation → utils/validation}/user.ts +0 -0
@@ -12,11 +12,11 @@ import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
12
12
  import { render, screen, fireEvent, waitFor, act } from '@testing-library/react';
13
13
  import userEvent from '@testing-library/user-event';
14
14
  import { z } from 'zod';
15
- import { Form, FormField, FormFieldset, FormErrorSummary, FormLiveRegion } from './index';
15
+ import { Form, FormField } from './index';
16
16
  import { renderWithProviders } from '../../__tests__/helpers/test-utils';
17
17
 
18
18
  // Mock the cn utility
19
- vi.mock('../../utils/cn', () => ({
19
+ vi.mock('../../utils/core/cn', () => ({
20
20
  cn: (...classes: (string | undefined)[]) => classes.filter(Boolean).join(' ')
21
21
  }));
22
22
 
@@ -566,507 +566,6 @@ describe('FormField Component', () => {
566
566
  });
567
567
  });
568
568
 
569
- describe('FormFieldset Component', () => {
570
- describe('Rendering', () => {
571
- it('renders with legend', () => {
572
- renderWithProviders(
573
- <FormFieldset legend="Personal Information">
574
- <div>Field content</div>
575
- </FormFieldset>
576
- );
577
-
578
- expect(screen.getByText('Personal Information')).toBeInTheDocument();
579
- expect(screen.getByRole('group')).toBeInTheDocument();
580
- });
581
-
582
- it('renders with description', () => {
583
- renderWithProviders(
584
- <FormFieldset
585
- legend="Personal Information"
586
- description="Please provide your personal details"
587
- >
588
- <div>Field content</div>
589
- </FormFieldset>
590
- );
591
-
592
- expect(screen.getByText('Please provide your personal details')).toBeInTheDocument();
593
- });
594
-
595
- it('renders with required indicator', () => {
596
- renderWithProviders(
597
- <FormFieldset legend="Personal Information" required>
598
- <div>Field content</div>
599
- </FormFieldset>
600
- );
601
-
602
- expect(screen.getByText('*')).toBeInTheDocument();
603
- });
604
-
605
- it('renders with custom className', () => {
606
- renderWithProviders(
607
- <FormFieldset
608
- legend="Personal Information"
609
- className="custom-fieldset"
610
- >
611
- <div>Field content</div>
612
- </FormFieldset>
613
- );
614
-
615
- const fieldset = screen.getByRole('group');
616
- expect(fieldset).toHaveClass('custom-fieldset');
617
- });
618
-
619
- it('forwards ref correctly', () => {
620
- const ref = { current: null };
621
-
622
- renderWithProviders(
623
- <FormFieldset legend="Personal Information" ref={ref}>
624
- <div>Field content</div>
625
- </FormFieldset>
626
- );
627
-
628
- expect(ref.current).toBeInstanceOf(HTMLFieldSetElement);
629
- });
630
- });
631
-
632
- describe('Accessibility', () => {
633
- it('has proper ARIA attributes', () => {
634
- renderWithProviders(
635
- <FormFieldset
636
- legend="Personal Information"
637
- description="Please provide your personal details"
638
- >
639
- <div>Field content</div>
640
- </FormFieldset>
641
- );
642
-
643
- const fieldset = screen.getByRole('group');
644
- const description = screen.getByText('Please provide your personal details');
645
-
646
- expect(fieldset).toHaveAttribute('aria-describedby', description.id);
647
- });
648
-
649
- it('has proper semantic structure', () => {
650
- renderWithProviders(
651
- <FormFieldset legend="Personal Information">
652
- <div>Field content</div>
653
- </FormFieldset>
654
- );
655
-
656
- const fieldset = screen.getByRole('group');
657
- const legend = screen.getByText('Personal Information');
658
-
659
- expect(fieldset).toBeInTheDocument();
660
- expect(legend).toBeInTheDocument();
661
- });
662
- });
663
- });
664
-
665
- describe('FormErrorSummary Component', () => {
666
- describe('Rendering', () => {
667
- it('renders nothing when no errors', () => {
668
- renderWithProviders(
669
- <FormErrorSummary errors={{}} />
670
- );
671
-
672
- expect(screen.queryByRole('alert')).not.toBeInTheDocument();
673
- });
674
-
675
- it('renders with default title', () => {
676
- const errors = {
677
- name: { message: 'Name is required' },
678
- email: { message: 'Email is invalid' }
679
- };
680
-
681
- renderWithProviders(
682
- <FormErrorSummary errors={errors} />
683
- );
684
-
685
- expect(screen.getByText('Please fix the following errors:')).toBeInTheDocument();
686
- expect(screen.getByText('Name is required')).toBeInTheDocument();
687
- expect(screen.getByText('Email is invalid')).toBeInTheDocument();
688
- });
689
-
690
- it('renders with custom title', () => {
691
- const errors = {
692
- name: { message: 'Name is required' }
693
- };
694
-
695
- renderWithProviders(
696
- <FormErrorSummary
697
- errors={errors}
698
- title="Please correct these issues:"
699
- />
700
- );
701
-
702
- expect(screen.getByText('Please correct these issues:')).toBeInTheDocument();
703
- });
704
-
705
- it('renders with field names when showFieldNames is true', () => {
706
- const errors = {
707
- name: { message: 'Name is required' },
708
- email: { message: 'Email is invalid' }
709
- };
710
-
711
- renderWithProviders(
712
- <FormErrorSummary
713
- errors={errors}
714
- showFieldNames={true}
715
- />
716
- );
717
-
718
- expect(screen.getByText('name: Name is required')).toBeInTheDocument();
719
- expect(screen.getByText('email: Email is invalid')).toBeInTheDocument();
720
- });
721
-
722
- it('filters out empty errors', () => {
723
- const errors = {
724
- name: { message: 'Name is required' },
725
- email: null,
726
- phone: undefined,
727
- address: ''
728
- };
729
-
730
- renderWithProviders(
731
- <FormErrorSummary errors={errors} />
732
- );
733
-
734
- expect(screen.getByText('Name is required')).toBeInTheDocument();
735
- expect(screen.queryByText('email:')).not.toBeInTheDocument();
736
- });
737
- });
738
-
739
- describe('Error Message Handling', () => {
740
- it('handles string error messages', () => {
741
- const errors = {
742
- name: 'Name is required'
743
- };
744
-
745
- renderWithProviders(
746
- <FormErrorSummary errors={errors} />
747
- );
748
-
749
- expect(screen.getByText('Name is required')).toBeInTheDocument();
750
- });
751
-
752
- it('handles object error messages', () => {
753
- const errors = {
754
- name: { message: 'Name is required' }
755
- };
756
-
757
- renderWithProviders(
758
- <FormErrorSummary errors={errors} />
759
- );
760
-
761
- expect(screen.getByText('Name is required')).toBeInTheDocument();
762
- });
763
- });
764
- });
765
-
766
- describe('FormLiveRegion Component', () => {
767
- describe('Rendering', () => {
768
- it('renders nothing when no message', () => {
769
- const mockForm = {
770
- formState: {
771
- isSubmitting: false,
772
- isSubmitSuccessful: false,
773
- errors: {},
774
- isValid: false,
775
- isDirty: false
776
- }
777
- } as any;
778
-
779
- renderWithProviders(
780
- <FormLiveRegion form={mockForm} />
781
- );
782
-
783
- expect(screen.queryByRole('status')).not.toBeInTheDocument();
784
- });
785
-
786
- it('renders with default politeness', () => {
787
- const mockForm = {
788
- formState: {
789
- isSubmitting: true,
790
- isSubmitSuccessful: false,
791
- errors: {},
792
- isValid: false,
793
- isDirty: false
794
- }
795
- } as any;
796
-
797
- renderWithProviders(
798
- <FormLiveRegion form={mockForm} />
799
- );
800
-
801
- const liveRegion = screen.getByRole('status');
802
- expect(liveRegion).toHaveAttribute('aria-live', 'polite');
803
- });
804
-
805
- it('renders with custom politeness', () => {
806
- const mockForm = {
807
- formState: {
808
- isSubmitting: true,
809
- isSubmitSuccessful: false,
810
- errors: {},
811
- isValid: false,
812
- isDirty: false
813
- }
814
- } as any;
815
-
816
- renderWithProviders(
817
- <FormLiveRegion form={mockForm} politeness="assertive" />
818
- );
819
-
820
- const liveRegion = screen.getByRole('status');
821
- expect(liveRegion).toHaveAttribute('aria-live', 'assertive');
822
- });
823
- });
824
-
825
- describe('Form State Announcements', () => {
826
- it('announces submitting state', () => {
827
- const mockForm = {
828
- formState: {
829
- isSubmitting: true,
830
- isSubmitSuccessful: false,
831
- errors: {},
832
- isValid: false,
833
- isDirty: false
834
- }
835
- } as any;
836
-
837
- renderWithProviders(
838
- <FormLiveRegion form={mockForm} />
839
- );
840
-
841
- expect(screen.getByText('Submitting form...')).toBeInTheDocument();
842
- });
843
-
844
- it('announces successful submission', async () => {
845
- vi.useFakeTimers();
846
-
847
- const mockForm = {
848
- formState: {
849
- isSubmitting: false,
850
- isSubmitSuccessful: true,
851
- errors: {},
852
- isValid: false,
853
- isDirty: false
854
- }
855
- } as any;
856
-
857
- renderWithProviders(
858
- <FormLiveRegion form={mockForm} />
859
- );
860
-
861
- // Advance timers to trigger the timeout
862
- await act(async () => {
863
- vi.advanceTimersByTime(500);
864
- });
865
-
866
- // The message should be set after the timeout
867
- expect(screen.getByRole('status')).toHaveTextContent('Form submitted successfully');
868
-
869
- vi.useRealTimers();
870
- });
871
-
872
- it('announces custom success message', async () => {
873
- vi.useFakeTimers();
874
-
875
- const mockForm = {
876
- formState: {
877
- isSubmitting: false,
878
- isSubmitSuccessful: true,
879
- errors: {},
880
- isValid: false,
881
- isDirty: false
882
- }
883
- } as any;
884
-
885
- renderWithProviders(
886
- <FormLiveRegion
887
- form={mockForm}
888
- successMessage="Your data was saved successfully!"
889
- />
890
- );
891
-
892
- await act(async () => {
893
- vi.advanceTimersByTime(500);
894
- });
895
-
896
- expect(screen.getByRole('status')).toHaveTextContent('Your data was saved successfully!');
897
-
898
- vi.useRealTimers();
899
- });
900
-
901
- it('announces form errors', async () => {
902
- const mockForm = {
903
- formState: {
904
- isSubmitting: false,
905
- isSubmitSuccessful: false,
906
- errors: {
907
- name: { message: 'Name is required' },
908
- email: { message: 'Email is invalid' }
909
- },
910
- isValid: false,
911
- isDirty: false,
912
- touchedFields: {}
913
- }
914
- } as any;
915
-
916
- renderWithProviders(
917
- <FormLiveRegion form={mockForm} />
918
- );
919
-
920
- // Error messages are set immediately without a timeout
921
- expect(screen.getByRole('status')).toHaveTextContent('Form has 2 errors in: name, email');
922
- });
923
-
924
- it('announces single error', async () => {
925
- const mockForm = {
926
- formState: {
927
- isSubmitting: false,
928
- isSubmitSuccessful: false,
929
- errors: {
930
- name: { message: 'Name is required' }
931
- },
932
- isValid: false,
933
- isDirty: false,
934
- touchedFields: {}
935
- }
936
- } as any;
937
-
938
- renderWithProviders(
939
- <FormLiveRegion form={mockForm} />
940
- );
941
-
942
- // Error messages are set immediately without a timeout
943
- expect(screen.getByRole('status')).toHaveTextContent('Form has 1 error in: name');
944
- });
945
-
946
- it('announces valid form', () => {
947
- const mockForm = {
948
- formState: {
949
- isSubmitting: false,
950
- isSubmitSuccessful: false,
951
- errors: {},
952
- isValid: true,
953
- isDirty: true
954
- }
955
- } as any;
956
-
957
- renderWithProviders(
958
- <FormLiveRegion form={mockForm} />
959
- );
960
-
961
- expect(screen.getByRole('status')).toHaveTextContent('Form is valid');
962
- });
963
- });
964
-
965
- describe('Field-Level Announcements', () => {
966
- it('announces field errors when enabled', async () => {
967
- vi.useFakeTimers();
968
-
969
- const mockForm = {
970
- formState: {
971
- isSubmitting: false,
972
- isSubmitSuccessful: false,
973
- errors: {
974
- name: { message: 'Name is required' }
975
- },
976
- touchedFields: { name: true },
977
- isValid: false,
978
- isDirty: false
979
- }
980
- } as any;
981
-
982
- renderWithProviders(
983
- <FormLiveRegion form={mockForm} enableFieldAnnouncements={true} />
984
- );
985
-
986
- await act(async () => {
987
- vi.advanceTimersByTime(500);
988
- });
989
-
990
- expect(screen.getByRole('status')).toHaveTextContent('name: Name is required');
991
-
992
- vi.useRealTimers();
993
- });
994
-
995
- it('does not announce field errors when disabled', () => {
996
- vi.useFakeTimers();
997
-
998
- const mockForm = {
999
- formState: {
1000
- isSubmitting: false,
1001
- isSubmitSuccessful: false,
1002
- errors: {
1003
- name: { message: 'Name is required' }
1004
- },
1005
- touchedFields: { name: true },
1006
- isValid: false,
1007
- isDirty: false
1008
- }
1009
- } as any;
1010
-
1011
- renderWithProviders(
1012
- <FormLiveRegion form={mockForm} enableFieldAnnouncements={false} />
1013
- );
1014
-
1015
- vi.advanceTimersByTime(500);
1016
-
1017
- vi.useRealTimers();
1018
-
1019
- expect(screen.queryByText('name: Name is required')).not.toBeInTheDocument();
1020
- });
1021
- });
1022
-
1023
- describe('Accessibility', () => {
1024
- it('has proper ARIA attributes', () => {
1025
- const mockForm = {
1026
- formState: {
1027
- isSubmitting: true,
1028
- isSubmitSuccessful: false,
1029
- errors: {},
1030
- isValid: false,
1031
- isDirty: false
1032
- }
1033
- } as any;
1034
-
1035
- renderWithProviders(
1036
- <FormLiveRegion form={mockForm} />
1037
- );
1038
-
1039
- const liveRegion = screen.getByRole('status');
1040
- expect(liveRegion).toHaveAttribute('aria-live', 'polite');
1041
- expect(liveRegion).toHaveAttribute('aria-atomic', 'true');
1042
- });
1043
-
1044
- it('is visually hidden', () => {
1045
- const mockForm = {
1046
- formState: {
1047
- isSubmitting: true,
1048
- isSubmitSuccessful: false,
1049
- errors: {},
1050
- isValid: false,
1051
- isDirty: false
1052
- }
1053
- } as any;
1054
-
1055
- renderWithProviders(
1056
- <FormLiveRegion form={mockForm} />
1057
- );
1058
-
1059
- const liveRegion = screen.getByRole('status');
1060
- expect(liveRegion).toHaveClass('sr-only');
1061
- expect(liveRegion.getAttribute('style')).toContain('position: absolute');
1062
- expect(liveRegion.getAttribute('style')).toContain('left: -10000px');
1063
- expect(liveRegion.getAttribute('style')).toContain('width: 1px');
1064
- expect(liveRegion.getAttribute('style')).toContain('height: 1px');
1065
- expect(liveRegion.getAttribute('style')).toContain('overflow: hidden');
1066
- });
1067
- });
1068
- });
1069
-
1070
569
  describe('Integration', () => {
1071
570
  const user = userEvent.setup();
1072
571
 
@@ -1086,12 +585,9 @@ describe('Integration', () => {
1086
585
  onError={onError}
1087
586
  defaultValues={{ name: '', email: '', age: 0 }}
1088
587
  >
1089
- <FormFieldset legend="Personal Information">
1090
- <FormField name="name" label="Name" />
1091
- <FormField name="email" label="Email" type="email" />
1092
- <FormField name="age" label="Age" type="number" />
1093
- </FormFieldset>
1094
- <FormErrorSummary />
588
+ <FormField name="name" label="Name" />
589
+ <FormField name="email" label="Email" type="email" />
590
+ <FormField name="age" label="Age" type="number" />
1095
591
  <button type="submit">Submit</button>
1096
592
  </Form>
1097
593
  );
@@ -1131,7 +627,6 @@ describe('Integration', () => {
1131
627
  >
1132
628
  <FormField name="name" label="Name" />
1133
629
  <FormField name="email" label="Email" type="email" />
1134
- <FormErrorSummary />
1135
630
  <button type="submit">Submit</button>
1136
631
  </Form>
1137
632
  );
@@ -75,7 +75,7 @@ import React from 'react';
75
75
  import { useForm, FormProvider, UseFormReturn, FieldValues, DefaultValues, SubmitHandler, SubmitErrorHandler } from 'react-hook-form';
76
76
  import { zodResolver } from '@hookform/resolvers/zod';
77
77
  import { z } from 'zod';
78
- import { cn } from '../../utils/cn';
78
+ import { cn } from '../../utils/core/cn';
79
79
 
80
80
  /**
81
81
  * Props for the Form component
@@ -87,7 +87,7 @@
87
87
 
88
88
  import React from 'react';
89
89
  import { useFormContext, Controller, FieldPath, FieldValues } from 'react-hook-form';
90
- import { cn } from '../../utils/cn';
90
+ import { cn } from '../../utils/core/cn';
91
91
  import { Label } from '../Label';
92
92
 
93
93
  export interface FormFieldProps<
@@ -12,15 +12,3 @@ export type { FormProps } from './Form';
12
12
  // Form Field component
13
13
  export { FormField } from './FormField';
14
14
  export type { FormFieldProps } from './FormField';
15
-
16
- // Form Error Summary component
17
- export { FormErrorSummary } from './FormErrorSummary';
18
- export type { FormErrorSummaryProps } from './FormErrorSummary';
19
-
20
- // Form Live Region component
21
- export { FormLiveRegion } from './FormLiveRegion';
22
- export type { FormLiveRegionProps } from './FormLiveRegion';
23
-
24
- // Form Fieldset component
25
- export { FormFieldset } from './FormFieldset';
26
- export type { FormFieldsetProps } from './FormFieldset';
@@ -88,7 +88,7 @@
88
88
  import React from 'react';
89
89
  import { Link } from 'react-router-dom';
90
90
  import { User } from '@supabase/supabase-js';
91
- import { cn } from '../../utils/cn';
91
+ import { cn } from '../../utils/core/cn';
92
92
  import { EventSelector } from '../EventSelector';
93
93
  import { UserMenu } from '../UserMenu';
94
94
  import { NavigationMenu } from '../NavigationMenu';
@@ -49,7 +49,7 @@
49
49
  */
50
50
 
51
51
  import * as React from 'react';
52
- import { cn } from '../../utils/cn';
52
+ import { cn } from '../../utils/core/cn';
53
53
 
54
54
  // ============================================================================
55
55
  // BASE INPUT COMPONENT
@@ -75,7 +75,7 @@
75
75
 
76
76
  import * as React from 'react';
77
77
  import * as LabelPrimitive from '@radix-ui/react-label';
78
- import { cn } from '../../utils/cn';
78
+ import { cn } from '../../utils/core/cn';
79
79
 
80
80
  const getLabelClasses = (): string => {
81
81
  return 'font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70';
@@ -100,7 +100,7 @@ vi.mock('../Alert/Alert', () => ({
100
100
  }));
101
101
 
102
102
  // Mock the cn utility
103
- vi.mock('../../utils/cn', () => ({
103
+ vi.mock('../../utils/core/cn', () => ({
104
104
  cn: (...classes: any[]) => classes.filter(Boolean).join(' '),
105
105
  }));
106
106
 
@@ -104,7 +104,7 @@ import { Input } from '../Input/Input';
104
104
  import { Label } from '../Label/Label';
105
105
  import { Card, CardContent, CardDescription, CardFooter, CardHeader, CardTitle } from '../Card/index';
106
106
  import { Alert, AlertDescription } from '../Alert/Alert';
107
- import { cn } from '../../utils/cn';
107
+ import { cn } from '../../utils/core/cn';
108
108
 
109
109
  export interface LoginFormProps {
110
110
  /** Callback invoked when the form is submitted */
@@ -11,6 +11,7 @@ import { NavigationMenu } from './NavigationMenu';
11
11
  import { NavigationItem } from './types';
12
12
  import { renderWithProviders } from '../../__tests__/helpers/test-utils';
13
13
  import { AccessLevel } from '../../types/unified';
14
+ import { Logger, LogLevel } from '../../utils/core/logger';
14
15
 
15
16
  // Mock the UnifiedAuthProvider
16
17
  const mockAuthContext = {
@@ -87,6 +88,7 @@ vi.mock('../../rbac/hooks/usePermissions', () => ({
87
88
 
88
89
  // Mock console methods to avoid noise in tests
89
90
  const originalConsoleLog = console.log;
91
+ const originalConsoleDebug = console.debug;
90
92
  const originalConsoleWarn = console.warn;
91
93
  const originalConsoleError = console.error;
92
94
 
@@ -133,8 +135,19 @@ describe('NavigationMenu Component', () => {
133
135
  beforeEach(() => {
134
136
  vi.clearAllMocks();
135
137
 
136
- // Reset console mocks
138
+ // Ensure logger is enabled by setting MODE to development
139
+ (import.meta.env as any).MODE = 'development';
140
+
141
+ // Configure logger to ensure it logs in test environment
142
+ Logger.configure({
143
+ level: LogLevel.DEBUG,
144
+ includeTimestamp: false,
145
+ includeComponent: true,
146
+ });
147
+
148
+ // Reset console mocks (logger uses console.debug, console.warn, console.error)
137
149
  console.log = vi.fn();
150
+ console.debug = vi.fn();
138
151
  console.warn = vi.fn();
139
152
  console.error = vi.fn();
140
153
 
@@ -178,6 +191,7 @@ describe('NavigationMenu Component', () => {
178
191
  afterEach(() => {
179
192
  // Restore console methods
180
193
  console.log = originalConsoleLog;
194
+ console.debug = originalConsoleDebug;
181
195
  console.warn = originalConsoleWarn;
182
196
  console.error = originalConsoleError;
183
197
  });
@@ -1104,7 +1118,8 @@ describe('NavigationMenu Component', () => {
1104
1118
  const homeItem = screen.getByText('Home');
1105
1119
  await user.click(homeItem);
1106
1120
 
1107
- expect(console.log).toHaveBeenCalledWith(
1121
+ // Logger.debug calls console.debug with formatted message
1122
+ expect(console.debug).toHaveBeenCalledWith(
1108
1123
  expect.stringContaining('[NavigationMenu] Navigation access attempt:'),
1109
1124
  expect.objectContaining({
1110
1125
  itemId: 'home',
@@ -1135,7 +1150,8 @@ describe('NavigationMenu Component', () => {
1135
1150
  const homeItem = screen.getByText('Home');
1136
1151
  await user.click(homeItem);
1137
1152
 
1138
- expect(console.log).not.toHaveBeenCalledWith(
1153
+ // Logger.debug should not be called when auditLog is disabled
1154
+ expect(console.debug).not.toHaveBeenCalledWith(
1139
1155
  expect.stringContaining('[NavigationMenu] Navigation access attempt:')
1140
1156
  );
1141
1157
  });