@jmruthers/pace-core 0.5.191 → 0.6.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (380) hide show
  1. package/CHANGELOG.md +29 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +372 -0
  4. package/cursor-rules/01-standards-compliance.mdc +275 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +341 -0
  7. package/cursor-rules/04-testing-standards.mdc +315 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +392 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +309 -0
  11. package/cursor-rules/CHANGELOG.md +101 -0
  12. package/cursor-rules/README.md +191 -0
  13. package/dist/{AuthService-CbP_utw2.d.ts → AuthService-DjnJHDtC.d.ts} +1 -0
  14. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-CH1U5Tpy.d.ts} +1 -1
  15. package/dist/{DataTable-WKRZD47S.js → DataTable-DQ7RSOHE.js} +8 -7
  16. package/dist/{PublicPageProvider-ULXC_u6U.d.ts → PublicPageProvider-ce4xlHYA.d.ts} +37 -156
  17. package/dist/{UnifiedAuthProvider-BYA9qB-o.d.ts → UnifiedAuthProvider-185Ih4dj.d.ts} +2 -0
  18. package/dist/{UnifiedAuthProvider-FTSG5XH7.js → UnifiedAuthProvider-ATAP5UTR.js} +3 -3
  19. package/dist/{api-IHKALJZD.js → api-N774RPUA.js} +2 -2
  20. package/dist/{chunk-6C4YBBJM.js → chunk-3QRJFVBR.js} +1 -1
  21. package/dist/chunk-3QRJFVBR.js.map +1 -0
  22. package/dist/{chunk-OETXORNB.js → chunk-3XTALGJF.js} +211 -136
  23. package/dist/chunk-3XTALGJF.js.map +1 -0
  24. package/dist/{chunk-6TQDD426.js → chunk-4N5C5XZU.js} +47 -228
  25. package/dist/chunk-4N5C5XZU.js.map +1 -0
  26. package/dist/{chunk-LOMZXPSN.js → chunk-4ZC4GX36.js} +47 -74
  27. package/dist/chunk-4ZC4GX36.js.map +1 -0
  28. package/dist/{chunk-6LTQQAT6.js → chunk-BYFSK72L.js} +357 -158
  29. package/dist/chunk-BYFSK72L.js.map +1 -0
  30. package/dist/{chunk-XYXSXPUK.js → chunk-EXUD6RNJ.js} +50 -10
  31. package/dist/chunk-EXUD6RNJ.js.map +1 -0
  32. package/dist/{chunk-VKB2CO4Z.js → chunk-GLK6VM3F.js} +244 -249
  33. package/dist/chunk-GLK6VM3F.js.map +1 -0
  34. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  35. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  36. package/dist/{chunk-XNYQOL3Z.js → chunk-JBKQ3SAO.js} +9 -18
  37. package/dist/chunk-JBKQ3SAO.js.map +1 -0
  38. package/dist/{chunk-ROXMHMY2.js → chunk-KNC55RTG.js} +13 -3
  39. package/dist/{chunk-ROXMHMY2.js.map → chunk-KNC55RTG.js.map} +1 -1
  40. package/dist/{chunk-QWWZ5CAQ.js → chunk-LXQLPRQ2.js} +2 -2
  41. package/dist/{chunk-ULHIJK66.js → chunk-T33XF5ZC.js} +255 -140
  42. package/dist/chunk-T33XF5ZC.js.map +1 -0
  43. package/dist/{chunk-VRGWKHDB.js → chunk-XM25TVIE.js} +100 -33
  44. package/dist/chunk-XM25TVIE.js.map +1 -0
  45. package/dist/components.d.ts +4 -4
  46. package/dist/components.js +9 -9
  47. package/dist/hooks.d.ts +6 -6
  48. package/dist/hooks.js +20 -25
  49. package/dist/hooks.js.map +1 -1
  50. package/dist/index.d.ts +11 -11
  51. package/dist/index.js +18 -21
  52. package/dist/index.js.map +1 -1
  53. package/dist/providers.d.ts +3 -3
  54. package/dist/providers.js +2 -2
  55. package/dist/rbac/index.d.ts +2 -20
  56. package/dist/rbac/index.js +7 -9
  57. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-BJAlWfuJ.d.ts} +3 -3
  58. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  59. package/dist/utils.d.ts +1 -1
  60. package/dist/utils.js +3 -3
  61. package/docs/api/classes/ColumnFactory.md +1 -1
  62. package/docs/api/classes/ErrorBoundary.md +1 -1
  63. package/docs/api/classes/InvalidScopeError.md +1 -1
  64. package/docs/api/classes/Logger.md +1 -1
  65. package/docs/api/classes/MissingUserContextError.md +1 -1
  66. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  67. package/docs/api/classes/PermissionDeniedError.md +2 -2
  68. package/docs/api/classes/RBACAuditManager.md +2 -2
  69. package/docs/api/classes/RBACCache.md +1 -1
  70. package/docs/api/classes/RBACEngine.md +2 -2
  71. package/docs/api/classes/RBACError.md +1 -1
  72. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  73. package/docs/api/classes/SecureSupabaseClient.md +10 -10
  74. package/docs/api/classes/StorageUtils.md +1 -1
  75. package/docs/api/enums/FileCategory.md +1 -1
  76. package/docs/api/enums/LogLevel.md +1 -1
  77. package/docs/api/enums/RBACErrorCode.md +1 -1
  78. package/docs/api/enums/RPCFunction.md +1 -1
  79. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  80. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  81. package/docs/api/interfaces/AggregateConfig.md +1 -1
  82. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  83. package/docs/api/interfaces/AvatarProps.md +1 -1
  84. package/docs/api/interfaces/BadgeProps.md +1 -1
  85. package/docs/api/interfaces/ButtonProps.md +1 -1
  86. package/docs/api/interfaces/CalendarProps.md +1 -1
  87. package/docs/api/interfaces/CardProps.md +1 -1
  88. package/docs/api/interfaces/ColorPalette.md +1 -1
  89. package/docs/api/interfaces/ColorShade.md +1 -1
  90. package/docs/api/interfaces/ComplianceResult.md +1 -1
  91. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  92. package/docs/api/interfaces/DataRecord.md +1 -1
  93. package/docs/api/interfaces/DataTableAction.md +1 -1
  94. package/docs/api/interfaces/DataTableColumn.md +1 -1
  95. package/docs/api/interfaces/DataTableProps.md +1 -1
  96. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  97. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  98. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  99. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  100. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  101. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  102. package/docs/api/interfaces/ExportColumn.md +1 -1
  103. package/docs/api/interfaces/ExportOptions.md +1 -1
  104. package/docs/api/interfaces/FileDisplayProps.md +24 -11
  105. package/docs/api/interfaces/FileMetadata.md +1 -1
  106. package/docs/api/interfaces/FileReference.md +1 -1
  107. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  108. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  109. package/docs/api/interfaces/FileUploadProps.md +1 -1
  110. package/docs/api/interfaces/FooterProps.md +1 -1
  111. package/docs/api/interfaces/FormFieldProps.md +1 -1
  112. package/docs/api/interfaces/FormProps.md +1 -1
  113. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  114. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  115. package/docs/api/interfaces/InputProps.md +1 -1
  116. package/docs/api/interfaces/LabelProps.md +1 -1
  117. package/docs/api/interfaces/LoggerConfig.md +1 -1
  118. package/docs/api/interfaces/LoginFormProps.md +1 -1
  119. package/docs/api/interfaces/NavigationAccessRecord.md +2 -2
  120. package/docs/api/interfaces/NavigationContextType.md +1 -1
  121. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  122. package/docs/api/interfaces/NavigationItem.md +1 -1
  123. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  124. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  125. package/docs/api/interfaces/Organisation.md +1 -1
  126. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  127. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  128. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  129. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  130. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  131. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  132. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  133. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  134. package/docs/api/interfaces/PagePermissionGuardProps.md +2 -2
  135. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  136. package/docs/api/interfaces/PaletteData.md +1 -1
  137. package/docs/api/interfaces/ParsedAddress.md +1 -1
  138. package/docs/api/interfaces/PermissionEnforcerProps.md +4 -4
  139. package/docs/api/interfaces/ProgressProps.md +1 -1
  140. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  141. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  142. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  143. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  144. package/docs/api/interfaces/QuickFix.md +1 -1
  145. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  146. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  147. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  148. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  149. package/docs/api/interfaces/RBACConfig.md +2 -2
  150. package/docs/api/interfaces/RBACContext.md +1 -1
  151. package/docs/api/interfaces/RBACLogger.md +1 -1
  152. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  153. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  154. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  155. package/docs/api/interfaces/RBACPermissionCheckResult.md +2 -2
  156. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  157. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  158. package/docs/api/interfaces/RBACResult.md +1 -1
  159. package/docs/api/interfaces/RBACRoleGrantParams.md +2 -2
  160. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  161. package/docs/api/interfaces/RBACRoleRevokeParams.md +2 -2
  162. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  163. package/docs/api/interfaces/RBACRoleValidateParams.md +2 -2
  164. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  165. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  166. package/docs/api/interfaces/RBACRolesListResult.md +2 -2
  167. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  168. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  169. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  170. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  171. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  172. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  173. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  174. package/docs/api/interfaces/RouteAccessRecord.md +2 -2
  175. package/docs/api/interfaces/RouteConfig.md +2 -2
  176. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  177. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  178. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  179. package/docs/api/interfaces/SessionRestorationLoaderProps.md +1 -1
  180. package/docs/api/interfaces/SetupIssue.md +1 -1
  181. package/docs/api/interfaces/StorageConfig.md +1 -1
  182. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  183. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  184. package/docs/api/interfaces/StorageListOptions.md +1 -1
  185. package/docs/api/interfaces/StorageListResult.md +1 -1
  186. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  187. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  188. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  189. package/docs/api/interfaces/StyleImport.md +1 -1
  190. package/docs/api/interfaces/SwitchProps.md +1 -1
  191. package/docs/api/interfaces/TabsContentProps.md +1 -1
  192. package/docs/api/interfaces/TabsListProps.md +1 -1
  193. package/docs/api/interfaces/TabsProps.md +1 -1
  194. package/docs/api/interfaces/TabsTriggerProps.md +1 -1
  195. package/docs/api/interfaces/TextareaProps.md +1 -1
  196. package/docs/api/interfaces/ToastActionElement.md +1 -1
  197. package/docs/api/interfaces/ToastProps.md +1 -1
  198. package/docs/api/interfaces/UnifiedAuthContextType.md +60 -38
  199. package/docs/api/interfaces/UnifiedAuthProviderProps.md +13 -13
  200. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  201. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  202. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  203. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  204. package/docs/api/interfaces/UsePublicEventLogoOptions.md +2 -2
  205. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  206. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  207. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  208. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +2 -2
  209. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  210. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  211. package/docs/api/interfaces/UseResolvedScopeOptions.md +2 -2
  212. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  213. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  214. package/docs/api/interfaces/UserEventAccess.md +1 -1
  215. package/docs/api/interfaces/UserMenuProps.md +1 -1
  216. package/docs/api/interfaces/UserProfile.md +1 -1
  217. package/docs/api/modules.md +194 -209
  218. package/docs/getting-started/cursor-rules.md +262 -0
  219. package/docs/getting-started/installation-guide.md +6 -1
  220. package/docs/getting-started/quick-start.md +6 -1
  221. package/docs/migration/MIGRATION_GUIDE.md +4 -4
  222. package/docs/migration/REACT_19_MIGRATION.md +227 -0
  223. package/docs/migration/database-changes-december-2025.md +2 -1
  224. package/docs/rbac/event-based-apps.md +124 -6
  225. package/docs/standards/README.md +39 -0
  226. package/docs/troubleshooting/migration.md +4 -4
  227. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  228. package/package.json +11 -6
  229. package/scripts/audit-consuming-app.cjs +961 -0
  230. package/scripts/check-pace-core-compliance.cjs +315 -61
  231. package/scripts/install-cursor-rules.cjs +236 -0
  232. package/src/__tests__/helpers/test-providers.tsx +1 -1
  233. package/src/__tests__/helpers/test-utils.tsx +1 -1
  234. package/src/__tests__/rls-policies.test.ts +3 -1
  235. package/src/components/Badge/Badge.tsx +2 -4
  236. package/src/components/Button/Button.tsx +5 -4
  237. package/src/components/Calendar/Calendar.tsx +1 -1
  238. package/src/components/DataTable/DataTable.test.tsx +57 -93
  239. package/src/components/DataTable/DataTable.tsx +2 -2
  240. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +172 -45
  241. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +121 -28
  242. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +9 -8
  243. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +20 -52
  244. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +170 -34
  245. package/src/components/DataTable/__tests__/keyboard.test.tsx +75 -12
  246. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +88 -16
  247. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  248. package/src/components/DataTable/components/AccessDeniedPage.tsx +1 -1
  249. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  250. package/src/components/DataTable/components/DataTableCore.tsx +4 -7
  251. package/src/components/DataTable/components/DataTableModals.tsx +1 -1
  252. package/src/components/DataTable/components/EditableRow.tsx +1 -1
  253. package/src/components/DataTable/components/UnifiedTableBody.tsx +86 -17
  254. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  255. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  256. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  257. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  258. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  259. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  260. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  261. package/src/components/DataTable/hooks/useColumnReordering.ts +2 -2
  262. package/src/components/DataTable/hooks/useDataTablePermissions.ts +75 -10
  263. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  264. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  265. package/src/components/Dialog/Dialog.tsx +6 -5
  266. package/src/components/ErrorBoundary/ErrorBoundary.tsx +1 -1
  267. package/src/components/EventSelector/EventSelector.tsx +1 -1
  268. package/src/components/FileDisplay/FileDisplay.test.tsx +4 -3
  269. package/src/components/FileDisplay/FileDisplay.tsx +16 -4
  270. package/src/components/Footer/Footer.tsx +1 -1
  271. package/src/components/Form/Form.test.tsx +36 -15
  272. package/src/components/Form/Form.tsx +30 -26
  273. package/src/components/Header/Header.tsx +1 -1
  274. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  275. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  276. package/src/components/Input/Input.tsx +28 -30
  277. package/src/components/Label/Label.tsx +1 -1
  278. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  279. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  280. package/src/components/LoginForm/LoginForm.tsx +8 -8
  281. package/src/components/NavigationMenu/NavigationMenu.test.tsx +6 -4
  282. package/src/components/NavigationMenu/NavigationMenu.tsx +2 -11
  283. package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -1
  284. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  285. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +75 -52
  286. package/src/components/PaceAppLayout/PaceAppLayout.tsx +98 -69
  287. package/src/components/PaceAppLayout/README.md +1 -1
  288. package/src/components/PaceLoginPage/PaceLoginPage.tsx +1 -8
  289. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  290. package/src/components/PasswordChange/PasswordChangeForm.tsx +1 -1
  291. package/src/components/Progress/Progress.tsx +1 -1
  292. package/src/components/ProtectedRoute/ProtectedRoute.test.tsx +5 -9
  293. package/src/components/ProtectedRoute/ProtectedRoute.tsx +0 -1
  294. package/src/components/PublicLayout/PublicPageLayout.tsx +1 -1
  295. package/src/components/PublicLayout/PublicPageProvider.tsx +0 -1
  296. package/src/components/Select/Select.tsx +33 -22
  297. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +1 -1
  298. package/src/components/Table/Table.tsx +1 -1
  299. package/src/components/Textarea/Textarea.tsx +27 -29
  300. package/src/components/Toast/Toast.tsx +1 -1
  301. package/src/components/Tooltip/Tooltip.tsx +1 -1
  302. package/src/components/UserMenu/UserMenu.tsx +1 -1
  303. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  304. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +14 -7
  305. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  306. package/src/hooks/public/usePublicEvent.ts +1 -1
  307. package/src/hooks/public/usePublicEventLogo.ts +1 -1
  308. package/src/hooks/public/usePublicRouteParams.ts +1 -1
  309. package/src/hooks/services/useAuthService.ts +21 -3
  310. package/src/hooks/services/useEventService.ts +21 -3
  311. package/src/hooks/services/useInactivityService.ts +21 -3
  312. package/src/hooks/services/useOrganisationService.ts +21 -3
  313. package/src/hooks/useDataTableState.ts +8 -18
  314. package/src/hooks/useFileDisplay.ts +10 -17
  315. package/src/hooks/useFocusManagement.ts +2 -2
  316. package/src/hooks/useFocusTrap.ts +4 -4
  317. package/src/hooks/useFormDialog.ts +8 -7
  318. package/src/hooks/useInactivityTracker.ts +1 -1
  319. package/src/hooks/usePermissionCache.ts +1 -1
  320. package/src/hooks/useSecureDataAccess.test.ts +16 -9
  321. package/src/hooks/useSecureDataAccess.ts +22 -6
  322. package/src/hooks/useToast.ts +2 -2
  323. package/src/providers/__tests__/OrganisationProvider.test.tsx +57 -13
  324. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  325. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  326. package/src/providers/services/EventServiceProvider.tsx +0 -8
  327. package/src/providers/services/UnifiedAuthProvider.tsx +196 -46
  328. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +13 -3
  329. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +34 -40
  330. package/src/rbac/__tests__/isSuperAdmin.real.test.ts +82 -0
  331. package/src/rbac/adapters.tsx +3 -22
  332. package/src/rbac/api.test.ts +2 -2
  333. package/src/rbac/api.ts +7 -1
  334. package/src/rbac/components/EnhancedNavigationMenu.tsx +3 -16
  335. package/src/rbac/components/NavigationGuard.tsx +2 -11
  336. package/src/rbac/components/NavigationProvider.tsx +1 -2
  337. package/src/rbac/components/PagePermissionGuard.tsx +1 -1
  338. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  339. package/src/rbac/components/PermissionEnforcer.tsx +46 -13
  340. package/src/rbac/components/RoleBasedRouter.tsx +1 -1
  341. package/src/rbac/components/SecureDataProvider.tsx +1 -2
  342. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +7 -43
  343. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +4 -11
  344. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +3 -3
  345. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +1 -1
  346. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +1 -1
  347. package/src/rbac/engine.ts +14 -2
  348. package/src/rbac/hooks/index.ts +0 -3
  349. package/src/rbac/hooks/usePermissions.ts +51 -11
  350. package/src/rbac/hooks/useRBAC.ts +3 -13
  351. package/src/rbac/hooks/useResolvedScope.test.ts +75 -54
  352. package/src/rbac/hooks/useResolvedScope.ts +58 -33
  353. package/src/rbac/hooks/useSecureSupabase.ts +4 -9
  354. package/src/rbac/secureClient.ts +43 -0
  355. package/src/services/EventService.ts +4 -57
  356. package/src/services/InactivityService.ts +127 -34
  357. package/src/services/OrganisationService.ts +68 -10
  358. package/src/utils/security/secureDataAccess.test.ts +31 -20
  359. package/src/utils/security/secureDataAccess.ts +4 -3
  360. package/dist/chunk-6C4YBBJM.js.map +0 -1
  361. package/dist/chunk-6LTQQAT6.js.map +0 -1
  362. package/dist/chunk-6TQDD426.js.map +0 -1
  363. package/dist/chunk-LOMZXPSN.js.map +0 -1
  364. package/dist/chunk-OETXORNB.js.map +0 -1
  365. package/dist/chunk-ULHIJK66.js.map +0 -1
  366. package/dist/chunk-VKB2CO4Z.js.map +0 -1
  367. package/dist/chunk-VRGWKHDB.js.map +0 -1
  368. package/dist/chunk-XNYQOL3Z.js.map +0 -1
  369. package/dist/chunk-XYXSXPUK.js.map +0 -1
  370. package/scripts/check-pace-core-compliance.js +0 -512
  371. package/src/rbac/hooks/useSuperAdminBypass.ts +0 -126
  372. package/src/utils/context/superAdminOverride.ts +0 -58
  373. /package/dist/{DataTable-WKRZD47S.js.map → DataTable-DQ7RSOHE.js.map} +0 -0
  374. /package/dist/{UnifiedAuthProvider-FTSG5XH7.js.map → UnifiedAuthProvider-ATAP5UTR.js.map} +0 -0
  375. /package/dist/{api-IHKALJZD.js.map → api-N774RPUA.js.map} +0 -0
  376. /package/dist/{chunk-QWWZ5CAQ.js.map → chunk-LXQLPRQ2.js.map} +0 -0
  377. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  378. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  379. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  380. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -295,24 +295,18 @@ describe('DatePickerWithTimezone Component', () => {
295
295
 
296
296
  render(<DatePickerWithTimezone selected={selected} onSelect={onSelect} />);
297
297
 
298
- expect(MockedCalendar).toHaveBeenCalledWith(
299
- expect.objectContaining({
300
- mode: 'single',
301
- selected: selected,
302
- onSelect: onSelect,
303
- initialFocus: true,
304
- captionLayout: 'dropdown',
305
- startMonth: expect.any(Date),
306
- endMonth: expect.any(Date),
307
- className: 'p-0'
308
- }),
309
- expect.anything()
310
- );
298
+ expect(MockedCalendar).toHaveBeenCalled();
311
299
 
312
- // Verify the date range is correct
300
+ // Verify the props are correct
313
301
  const callArgs = MockedCalendar.mock.calls[0][0];
302
+ expect(callArgs.mode).toBe('single');
303
+ expect(callArgs.selected).toEqual(selected);
304
+ expect(callArgs.onSelect).toBe(onSelect);
305
+ expect(callArgs.initialFocus).toBe(true);
306
+ expect(callArgs.captionLayout).toBe('dropdown');
314
307
  expect(callArgs.startMonth).toEqual(new Date(1900, 0));
315
308
  expect(callArgs.endMonth).toEqual(new Date(2100, 11));
309
+ expect(callArgs.className).toBe('p-0');
316
310
  });
317
311
  });
318
312
  });
@@ -149,7 +149,7 @@
149
149
  * @dependencies
150
150
  * - @radix-ui/react-dialog - Core dialog functionality
151
151
  * - lucide-react - Icons
152
- * - React 18+ - Hooks and refs
152
+ * - React 19+ - Hooks and refs
153
153
  * - Tailwind CSS - Styling and animations
154
154
  */
155
155
 
@@ -465,17 +465,18 @@ const DialogContent = React.forwardRef<
465
465
  enableScrolling
466
466
  });
467
467
 
468
- const handleEscapeKeyDown = React.useCallback((event: KeyboardEvent) => {
468
+ // React Compiler handles memoization automatically
469
+ const handleEscapeKeyDown = (event: KeyboardEvent) => {
469
470
  if (preventCloseOnEscape) {
470
471
  event.preventDefault();
471
472
  }
472
- }, [preventCloseOnEscape]);
473
+ };
473
474
 
474
- const handlePointerDownOutside = React.useCallback((event: Event) => {
475
+ const handlePointerDownOutside = (event: Event) => {
475
476
  if (preventCloseOnOutsideClick) {
476
477
  event.preventDefault();
477
478
  }
478
- }, [preventCloseOnOutsideClick]);
479
+ };
479
480
 
480
481
  // Merge smart dimensions with provided style
481
482
  const mergedStyle = React.useMemo(() => {
@@ -75,7 +75,7 @@
75
75
  * - Configurable error reporting
76
76
  *
77
77
  * @dependencies
78
- * - React 18+ - Component lifecycle
78
+ * - React 19+ - Component lifecycle
79
79
  * - Performance monitoring utilities
80
80
  * - Tailwind CSS - Styling
81
81
  */
@@ -80,7 +80,7 @@
80
80
  * - Button component - Retry functionality
81
81
  * - Alert component - Error display
82
82
  * - LoadingSpinner - Loading states
83
- * - React 18+ - Hooks and effects
83
+ * - React 19+ - Hooks and effects
84
84
  * - Tailwind CSS - Styling
85
85
  */
86
86
 
@@ -49,7 +49,7 @@ vi.mock('../../utils/storage/helpers', () => ({
49
49
  }));
50
50
 
51
51
  // Helper to render with UnifiedAuthProvider
52
- const renderWithUnifiedAuth = (ui: React.ReactElement) => {
52
+ const renderWithUnifiedAuth = (ui: React.ReactElement<any>) => {
53
53
  return renderWithProviders(
54
54
  <UnifiedAuthProvider
55
55
  supabaseClient={supabase}
@@ -64,7 +64,7 @@ const renderWithUnifiedAuth = (ui: React.ReactElement) => {
64
64
  );
65
65
  };
66
66
 
67
- const renderWithPublicContext = (ui: React.ReactElement, value: any = null) => {
67
+ const renderWithPublicContext = (ui: React.ReactElement<any>, value: any = null) => {
68
68
  const Context = publicPageContextStore.value ?? React.createContext(null);
69
69
 
70
70
  return renderWithProviders(
@@ -334,7 +334,8 @@ describe('[component] FileDisplay', () => {
334
334
  // The image should not be inside a wrapper div with "space-y-2" class
335
335
  const parentDiv = image.parentElement;
336
336
  expect(parentDiv?.className).not.toContain('space-y-2');
337
- expect(image.className).toContain('max-w-full');
337
+ // The image uses imgClassName or default "object-cover size-full", not "max-w-full"
338
+ expect(image.className).toContain('object-cover');
338
339
  });
339
340
 
340
341
  it('renders with wrapper when displayOnly is true but showDelete is also true', async () => {
@@ -69,6 +69,8 @@ export interface FileDisplayProps {
69
69
  displayOnly?: boolean;
70
70
  showDelete?: boolean;
71
71
  className?: string;
72
+ /** Classes to apply to the first child element of <figure> (img, p, or other elements) */
73
+ imgClassName?: string;
72
74
  children?: React.ReactNode;
73
75
  /** Custom loading component to render during data fetching */
74
76
  loadingComponent?: React.ComponentType;
@@ -107,6 +109,7 @@ interface FileDisplayContentProps {
107
109
  displayOnly: boolean;
108
110
  showDelete: boolean;
109
111
  className: string;
112
+ imgClassName?: string;
110
113
  children?: React.ReactNode;
111
114
  onDelete?: () => Promise<void>;
112
115
  clearError?: () => void;
@@ -134,6 +137,7 @@ function FileDisplayContent({
134
137
  displayOnly,
135
138
  showDelete,
136
139
  className,
140
+ imgClassName,
137
141
  children,
138
142
  onDelete,
139
143
  clearError,
@@ -330,11 +334,11 @@ function FileDisplayContent({
330
334
  }
331
335
 
332
336
  return (
333
- <figure className={className || "max-w-full h-auto"}>
337
+ <figure className={className || ""}>
334
338
  <img
335
339
  src={fileUrl}
336
340
  alt={fileReference.file_metadata.fileName || 'File'}
337
- className="max-w-full h-auto"
341
+ className={imgClassName || "object-cover size-full"}
338
342
  onError={handleImageError}
339
343
  />
340
344
  </figure>
@@ -393,7 +397,7 @@ function FileDisplayContent({
393
397
  <img
394
398
  src={fileUrl}
395
399
  alt={fileReference.file_metadata.fileName || 'File'}
396
- className="max-w-full h-auto"
400
+ className={imgClassName || "object-cover size-full"}
397
401
  onError={handleImageError}
398
402
  />
399
403
  {showDelete && (
@@ -534,7 +538,7 @@ function FileDisplayContent({
534
538
  <img
535
539
  src={fileUrl}
536
540
  alt={fileRef.file_metadata.fileName || 'File'}
537
- className="w-12 h-12 object-cover rounded"
541
+ className={imgClassName || "object-cover size-full"}
538
542
  onError={handleImageError}
539
543
  />
540
544
  ) : (
@@ -601,6 +605,7 @@ function FileDisplayPublic({
601
605
  displayOnly = false,
602
606
  showDelete = false,
603
607
  className = '',
608
+ imgClassName,
604
609
  children,
605
610
  loadingComponent,
606
611
  errorComponent,
@@ -631,6 +636,7 @@ function FileDisplayPublic({
631
636
  displayOnly={displayOnly}
632
637
  showDelete={false}
633
638
  className={className}
639
+ imgClassName={imgClassName}
634
640
  children={children}
635
641
  onDelete={undefined}
636
642
  organisation_id={organisation_id}
@@ -724,6 +730,7 @@ function FileDisplayPublic({
724
730
  displayOnly={displayOnly}
725
731
  showDelete={false} // Never show delete in public context
726
732
  className={className}
733
+ imgClassName={imgClassName}
727
734
  children={children}
728
735
  onDelete={showDelete ? handleDelete : undefined}
729
736
  organisation_id={organisation_id}
@@ -752,6 +759,7 @@ function FileDisplayAuthenticated({
752
759
  displayOnly = false,
753
760
  showDelete = false,
754
761
  className = '',
762
+ imgClassName,
755
763
  children,
756
764
  loadingComponent,
757
765
  errorComponent,
@@ -862,6 +870,7 @@ function FileDisplayAuthenticated({
862
870
  displayOnly={displayOnly}
863
871
  showDelete={showDelete}
864
872
  className={className}
873
+ imgClassName={imgClassName}
865
874
  children={children}
866
875
  onDelete={showDelete ? handleDelete : undefined}
867
876
  clearError={refetch}
@@ -905,6 +914,7 @@ export function FileDisplay({
905
914
  displayOnly = false,
906
915
  showDelete = false,
907
916
  className = '',
917
+ imgClassName,
908
918
  children,
909
919
  loadingComponent,
910
920
  errorComponent,
@@ -930,6 +940,7 @@ export function FileDisplay({
930
940
  displayOnly={displayOnly}
931
941
  showDelete={showDelete}
932
942
  className={className}
943
+ imgClassName={imgClassName}
933
944
  children={children}
934
945
  loadingComponent={loadingComponent}
935
946
  errorComponent={errorComponent}
@@ -955,6 +966,7 @@ export function FileDisplay({
955
966
  displayOnly={displayOnly}
956
967
  showDelete={showDelete}
957
968
  className={className}
969
+ imgClassName={imgClassName}
958
970
  children={children}
959
971
  loadingComponent={loadingComponent}
960
972
  errorComponent={errorComponent}
@@ -81,7 +81,7 @@
81
81
  * - Clear link identification
82
82
  *
83
83
  * @dependencies
84
- * - React 18+ - Component framework
84
+ * - React 19+ - Component framework
85
85
  * - Tailwind CSS - Styling
86
86
  */
87
87
  import React from 'react';
@@ -8,10 +8,12 @@
8
8
  * Tests form rendering, validation, submission, and accessibility.
9
9
  */
10
10
 
11
+ import React from 'react';
11
12
  import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest';
12
13
  import { render, screen, waitFor, act } from '@testing-library/react';
13
14
  import userEvent from '@testing-library/user-event';
14
15
  import { z } from 'zod';
16
+ import { useWatch, useFormState, useFormContext } from 'react-hook-form';
15
17
  import { Form, FormField } from './index';
16
18
  import { renderWithProviders } from '../../__tests__/helpers/test-utils';
17
19
 
@@ -108,27 +110,46 @@ describe('Form Component', () => {
108
110
 
109
111
  it('shares live form state with render prop children', async () => {
110
112
  const onSubmit = vi.fn();
111
-
112
- renderWithProviders(
113
- <Form onSubmit={onSubmit} defaultValues={{ name: '' }}>
114
- {({ formState, watch }) => (
115
- <>
116
- <span data-testid="dirty-flag">{formState.isDirty ? 'dirty' : 'pristine'}</span>
117
- <span data-testid="watched-value">{watch('name')}</span>
118
- <FormField name="name" label="Name" />
119
- </>
120
- )}
121
- </Form>
122
- );
113
+ const InnerComponent = () => {
114
+ // useWatch and useFormState must be called inside FormProvider context
115
+ // useFormState subscribes to form state changes and triggers re-renders
116
+ const { control } = useFormContext();
117
+ const nameValue = useWatch({ name: 'name', control });
118
+ const { isDirty } = useFormState({ control });
119
+
120
+ return (
121
+ <>
122
+ <span data-testid="dirty-flag">{isDirty ? 'dirty' : 'pristine'}</span>
123
+ <span data-testid="watched-value">{nameValue || ''}</span>
124
+ <FormField name="name" label="Name" />
125
+ </>
126
+ );
127
+ };
128
+
129
+ const TestComponent = () => {
130
+ return (
131
+ <Form onSubmit={onSubmit} defaultValues={{ name: '' }}>
132
+ <InnerComponent />
133
+ </Form>
134
+ );
135
+ };
136
+
137
+ renderWithProviders(<TestComponent />);
123
138
 
124
139
  const input = screen.getByLabelText('Name');
125
140
  expect(screen.getByTestId('dirty-flag')).toHaveTextContent('pristine');
141
+
142
+ // Type into the input field
143
+ await user.clear(input);
126
144
  await user.type(input, 'Jane');
127
145
 
146
+ // Wait for both the watched value and dirty state to update
128
147
  await waitFor(() => {
129
- expect(screen.getByTestId('dirty-flag')).toHaveTextContent('dirty');
130
- expect(screen.getByTestId('watched-value')).toHaveTextContent('Jane');
131
- });
148
+ const watchedValue = screen.getByTestId('watched-value');
149
+ const dirtyFlag = screen.getByTestId('dirty-flag');
150
+ expect(watchedValue).toHaveTextContent('Jane');
151
+ expect(dirtyFlag).toHaveTextContent('dirty');
152
+ }, { timeout: 5000 });
132
153
  });
133
154
  });
134
155
 
@@ -68,7 +68,7 @@
68
68
  * - react-hook-form - Form state management
69
69
  * - @hookform/resolvers/zod - Zod validation integration
70
70
  * - zod - Schema validation
71
- * - React 18+ - Hooks and context
71
+ * - React 19+ - Hooks and context
72
72
  */
73
73
 
74
74
  import React from 'react';
@@ -153,6 +153,7 @@ export function Form<TFieldValues extends FieldValues = FieldValues>({
153
153
  resolver: schema ? zodResolver(schema) : undefined,
154
154
  defaultValues,
155
155
  mode,
156
+ shouldUnregister: false,
156
157
  });
157
158
 
158
159
  const handleSubmit = methods.handleSubmit(onSubmit, onError);
@@ -224,7 +225,7 @@ export interface FormFieldProps<
224
225
  field: ControllerRenderProps<TFieldValues, TName>;
225
226
  fieldState: ControllerFieldState;
226
227
  formState: UseFormStateReturn<TFieldValues>;
227
- }) => React.ReactElement;
228
+ }) => React.ReactElement<any>;
228
229
 
229
230
  /**
230
231
  * Test ID
@@ -318,13 +319,7 @@ export function FormField<
318
319
  'data-testid': testId,
319
320
  className,
320
321
  }: FormFieldProps<TFieldValues, TName>) {
321
- const { control, formState: { errors } } = useFormContext<TFieldValues>();
322
- const fieldError = errors[name];
323
-
324
- // Safely extract error message
325
- const errorMessage = fieldError && typeof fieldError === 'object' && 'message' in fieldError
326
- ? String(fieldError.message)
327
- : undefined;
322
+ const { control } = useFormContext<TFieldValues>();
328
323
 
329
324
  return (
330
325
  <div className={cn("space-y-2", className)}>
@@ -344,32 +339,41 @@ export function FormField<
344
339
  control={control}
345
340
  rules={validation}
346
341
  render={(props) => {
342
+ const { field, fieldState } = props;
343
+ const fieldError = fieldState.error;
344
+
345
+ // Safely extract error message
346
+ const errorMessage = fieldError && typeof fieldError === 'object' && 'message' in fieldError
347
+ ? String(fieldError.message)
348
+ : undefined;
349
+
347
350
  if (render) {
348
351
  return render(props);
349
352
  }
350
353
 
351
354
  return (
352
- <input
353
- {...props.field}
354
- id={name}
355
- type={type}
356
- placeholder={placeholder}
357
- data-testid={testId}
358
- className={cn(
359
- "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
360
- fieldError && "border-destructive focus-visible:ring-destructive"
355
+ <>
356
+ <input
357
+ {...field}
358
+ id={name}
359
+ type={type}
360
+ placeholder={placeholder}
361
+ data-testid={testId}
362
+ className={cn(
363
+ "flex h-10 w-full rounded-md border border-input bg-background px-3 py-2 text-sm ring-offset-background file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:cursor-not-allowed disabled:opacity-50",
364
+ fieldError && "border-destructive focus-visible:ring-destructive"
365
+ )}
366
+ {...inputProps}
367
+ />
368
+ {errorMessage && (
369
+ <p className="text-destructive" role="alert">
370
+ {errorMessage}
371
+ </p>
361
372
  )}
362
- {...inputProps}
363
- />
373
+ </>
364
374
  );
365
375
  }}
366
376
  />
367
-
368
- {errorMessage && (
369
- <p className="text-destructive" role="alert">
370
- {errorMessage}
371
- </p>
372
- )}
373
377
  </div>
374
378
  );
375
379
  }
@@ -79,7 +79,7 @@
79
79
  *
80
80
  * @dependencies
81
81
  * - @supabase/supabase-js - User authentication
82
- * - React 18+ - Component framework
82
+ * - React 19+ - Component framework
83
83
  * - Tailwind CSS - Styling
84
84
  * - NavigationMenu component
85
85
  * - UserMenu component