@jmruthers/pace-core 0.5.193 → 0.6.2

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 (577) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +299 -0
  4. package/cursor-rules/01-standards-compliance.mdc +244 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +222 -0
  7. package/cursor-rules/04-testing-standards.mdc +268 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +309 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
  11. package/cursor-rules/08-markup-quality.mdc +452 -0
  12. package/cursor-rules/CHANGELOG.md +119 -0
  13. package/cursor-rules/README.md +192 -0
  14. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  15. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
  16. package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
  17. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
  18. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  19. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  20. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  21. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  22. package/dist/chunk-24UVZUZG.js.map +1 -0
  23. package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
  24. package/dist/chunk-2UOI2FG5.js.map +1 -0
  25. package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
  26. package/dist/chunk-3XC4CPTD.js.map +1 -0
  27. package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
  28. package/dist/chunk-6J4GEEJR.js.map +1 -0
  29. package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
  30. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  31. package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
  32. package/dist/chunk-EHMR7VYL.js.map +1 -0
  33. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  34. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  35. package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
  36. package/dist/chunk-FFQEQTNW.js.map +1 -0
  37. package/dist/chunk-FMUCXFII.js +76 -0
  38. package/dist/chunk-FMUCXFII.js.map +1 -0
  39. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  40. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  41. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  42. package/dist/chunk-L4OXEN46.js.map +1 -0
  43. package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
  44. package/dist/chunk-M43Y4SSO.js.map +1 -0
  45. package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
  46. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  47. package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
  48. package/dist/chunk-NECFR5MM.js.map +1 -0
  49. package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
  50. package/dist/chunk-SFZUDBL5.js.map +1 -0
  51. package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
  52. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  53. package/dist/components.d.ts +6 -6
  54. package/dist/components.js +15 -12
  55. package/dist/components.js.map +1 -1
  56. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  57. package/dist/hooks.d.ts +59 -126
  58. package/dist/hooks.js +19 -28
  59. package/dist/hooks.js.map +1 -1
  60. package/dist/index.d.ts +63 -16
  61. package/dist/index.js +23 -24
  62. package/dist/index.js.map +1 -1
  63. package/dist/providers.d.ts +21 -3
  64. package/dist/providers.js +2 -2
  65. package/dist/rbac/index.d.ts +146 -115
  66. package/dist/rbac/index.js +8 -11
  67. package/dist/theming/runtime.d.ts +1 -13
  68. package/dist/theming/runtime.js +1 -1
  69. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  70. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  71. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  72. package/dist/types.d.ts +2 -2
  73. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
  74. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  75. package/dist/utils.d.ts +4 -5
  76. package/dist/utils.js +15 -15
  77. package/dist/utils.js.map +1 -1
  78. package/docs/api/README.md +7 -1
  79. package/docs/api/classes/ColumnFactory.md +8 -8
  80. package/docs/api/classes/InvalidScopeError.md +4 -4
  81. package/docs/api/classes/Logger.md +1 -1
  82. package/docs/api/classes/MissingUserContextError.md +4 -4
  83. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  84. package/docs/api/classes/PermissionDeniedError.md +4 -4
  85. package/docs/api/classes/RBACAuditManager.md +1 -1
  86. package/docs/api/classes/RBACCache.md +1 -1
  87. package/docs/api/classes/RBACEngine.md +1 -1
  88. package/docs/api/classes/RBACError.md +4 -4
  89. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  90. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  91. package/docs/api/classes/StorageUtils.md +1 -1
  92. package/docs/api/enums/FileCategory.md +1 -1
  93. package/docs/api/enums/LogLevel.md +1 -1
  94. package/docs/api/enums/RBACErrorCode.md +1 -1
  95. package/docs/api/enums/RPCFunction.md +1 -1
  96. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  97. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  98. package/docs/api/interfaces/AggregateConfig.md +4 -4
  99. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  100. package/docs/api/interfaces/AvatarProps.md +1 -1
  101. package/docs/api/interfaces/BadgeProps.md +9 -2
  102. package/docs/api/interfaces/ButtonProps.md +7 -4
  103. package/docs/api/interfaces/CalendarProps.md +8 -5
  104. package/docs/api/interfaces/CardProps.md +8 -5
  105. package/docs/api/interfaces/ColorPalette.md +1 -1
  106. package/docs/api/interfaces/ColorShade.md +1 -1
  107. package/docs/api/interfaces/ComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  109. package/docs/api/interfaces/DataRecord.md +1 -1
  110. package/docs/api/interfaces/DataTableAction.md +24 -21
  111. package/docs/api/interfaces/DataTableColumn.md +31 -31
  112. package/docs/api/interfaces/DataTableProps.md +1 -1
  113. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  114. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  115. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  118. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  119. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  120. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  121. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  122. package/docs/api/interfaces/ExportColumn.md +1 -1
  123. package/docs/api/interfaces/ExportOptions.md +8 -8
  124. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  125. package/docs/api/interfaces/FileMetadata.md +1 -1
  126. package/docs/api/interfaces/FileReference.md +1 -1
  127. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  128. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  129. package/docs/api/interfaces/FileUploadProps.md +26 -23
  130. package/docs/api/interfaces/FooterProps.md +10 -8
  131. package/docs/api/interfaces/FormFieldProps.md +10 -10
  132. package/docs/api/interfaces/FormProps.md +1 -1
  133. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  134. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  135. package/docs/api/interfaces/InputProps.md +7 -4
  136. package/docs/api/interfaces/LabelProps.md +1 -1
  137. package/docs/api/interfaces/LoggerConfig.md +1 -1
  138. package/docs/api/interfaces/LoginFormProps.md +14 -11
  139. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  140. package/docs/api/interfaces/NavigationContextType.md +1 -1
  141. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  142. package/docs/api/interfaces/NavigationItem.md +11 -11
  143. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  144. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  145. package/docs/api/interfaces/Organisation.md +1 -1
  146. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  147. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  148. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  149. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  150. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  151. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  152. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  153. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  154. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  155. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  156. package/docs/api/interfaces/PaletteData.md +1 -1
  157. package/docs/api/interfaces/ParsedAddress.md +1 -1
  158. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  159. package/docs/api/interfaces/ProgressProps.md +1 -1
  160. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  161. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  162. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  163. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  164. package/docs/api/interfaces/QuickFix.md +1 -1
  165. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  166. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  167. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  168. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  169. package/docs/api/interfaces/RBACConfig.md +1 -1
  170. package/docs/api/interfaces/RBACContext.md +1 -1
  171. package/docs/api/interfaces/RBACLogger.md +1 -1
  172. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  173. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  174. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  175. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  176. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  177. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  178. package/docs/api/interfaces/RBACResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  181. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  182. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  183. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  184. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  185. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  186. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  187. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  188. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  189. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  190. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  191. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  192. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  193. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  194. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  195. package/docs/api/interfaces/RouteConfig.md +1 -1
  196. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  197. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  198. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  199. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  200. package/docs/api/interfaces/SetupIssue.md +1 -1
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  215. package/docs/api/interfaces/TextareaProps.md +1 -1
  216. package/docs/api/interfaces/ToastActionElement.md +4 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  220. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  221. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  222. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  223. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  224. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  225. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  226. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  227. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  228. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  229. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  230. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  231. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  232. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  233. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  234. package/docs/api/interfaces/UserEventAccess.md +14 -11
  235. package/docs/api/interfaces/UserMenuProps.md +8 -6
  236. package/docs/api/interfaces/UserProfile.md +1 -1
  237. package/docs/api/modules.md +575 -634
  238. package/docs/architecture/database-schema-requirements.md +161 -0
  239. package/docs/core-concepts/rbac-system.md +3 -3
  240. package/docs/documentation-index.md +2 -4
  241. package/docs/getting-started/cursor-rules.md +263 -0
  242. package/docs/getting-started/installation-guide.md +6 -1
  243. package/docs/getting-started/quick-start.md +6 -1
  244. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  245. package/docs/migration/MIGRATION_GUIDE.md +6 -28
  246. package/docs/migration/README.md +52 -6
  247. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  248. package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
  249. package/docs/migration/database-changes-december-2025.md +3 -3
  250. package/docs/rbac/event-based-apps.md +1 -1
  251. package/docs/rbac/getting-started.md +1 -1
  252. package/docs/rbac/quick-start.md +1 -1
  253. package/docs/standards/README.md +40 -0
  254. package/docs/troubleshooting/migration.md +4 -4
  255. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  256. package/package.json +12 -6
  257. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  258. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  259. package/scripts/audit/core/checks/bundle.cjs +142 -0
  260. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
  261. package/scripts/audit/core/checks/config.cjs +54 -0
  262. package/scripts/audit/core/checks/coverage.cjs +84 -0
  263. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  264. package/scripts/audit/core/checks/documentation.cjs +203 -0
  265. package/scripts/audit/core/checks/environment.cjs +128 -0
  266. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  267. package/scripts/audit/core/checks/forms.cjs +172 -0
  268. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  269. package/scripts/audit/core/checks/hooks.cjs +334 -0
  270. package/scripts/audit/core/checks/imports.cjs +244 -0
  271. package/scripts/audit/core/checks/performance.cjs +325 -0
  272. package/scripts/audit/core/checks/routes.cjs +117 -0
  273. package/scripts/audit/core/checks/state.cjs +130 -0
  274. package/scripts/audit/core/checks/structure.cjs +65 -0
  275. package/scripts/audit/core/checks/style.cjs +584 -0
  276. package/scripts/audit/core/checks/testing.cjs +122 -0
  277. package/scripts/audit/core/checks/typescript.cjs +61 -0
  278. package/scripts/audit/core/scanner.cjs +199 -0
  279. package/scripts/audit/core/utils.cjs +137 -0
  280. package/scripts/audit/index.cjs +223 -0
  281. package/scripts/audit/reporters/console.cjs +151 -0
  282. package/scripts/audit/reporters/json.cjs +54 -0
  283. package/scripts/audit/reporters/markdown.cjs +124 -0
  284. package/scripts/audit-consuming-app.cjs +86 -0
  285. package/scripts/build-docs/build-decision.js +240 -0
  286. package/scripts/build-docs/cache-utils.js +105 -0
  287. package/scripts/build-docs/content-normalization.js +150 -0
  288. package/scripts/build-docs/file-utils.js +105 -0
  289. package/scripts/build-docs/git-utils.js +86 -0
  290. package/scripts/build-docs/hash-utils.js +116 -0
  291. package/scripts/build-docs/typedoc-runner.js +220 -0
  292. package/scripts/build-docs-incremental.js +77 -913
  293. package/scripts/install-cursor-rules.cjs +236 -0
  294. package/scripts/utils/command-runner.js +16 -11
  295. package/scripts/validate-formats.js +61 -56
  296. package/scripts/validate-master.js +74 -69
  297. package/scripts/validate-pre-publish.js +70 -65
  298. package/src/__tests__/helpers/test-providers.tsx +1 -1
  299. package/src/__tests__/helpers/test-utils.tsx +1 -1
  300. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  301. package/src/components/Alert/Alert.test.tsx +12 -18
  302. package/src/components/Alert/Alert.tsx +5 -7
  303. package/src/components/Avatar/Avatar.test.tsx +4 -4
  304. package/src/components/Badge/Badge.tsx +16 -4
  305. package/src/components/Button/Button.tsx +27 -4
  306. package/src/components/Calendar/Calendar.tsx +9 -3
  307. package/src/components/Card/Card.tsx +4 -0
  308. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  309. package/src/components/Checkbox/Checkbox.tsx +2 -2
  310. package/src/components/DataTable/DataTable.test.tsx +57 -93
  311. package/src/components/DataTable/DataTable.tsx +40 -6
  312. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  313. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
  314. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  315. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  316. package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
  317. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  318. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  319. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  320. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  321. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  322. package/src/components/DataTable/components/DataTableCore.tsx +200 -561
  323. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  324. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  325. package/src/components/DataTable/components/DataTableModals.tsx +9 -1
  326. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  327. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  328. package/src/components/DataTable/components/EditFields.tsx +307 -0
  329. package/src/components/DataTable/components/EditableRow.tsx +9 -1
  330. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  331. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  332. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  333. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  334. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  335. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  336. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  337. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  338. package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
  339. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  340. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  341. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  342. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  343. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  344. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  345. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  346. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  347. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  348. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  349. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  350. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  351. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  352. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  353. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  354. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  355. package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
  356. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  357. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  358. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  359. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  360. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  361. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  362. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  363. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  364. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  365. package/src/components/DataTable/styles.ts +6 -6
  366. package/src/components/DataTable/types.ts +6 -10
  367. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  368. package/src/components/DataTable/utils/debugTools.ts +18 -113
  369. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  370. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  371. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  372. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  373. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  374. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  375. package/src/components/Dialog/Dialog.tsx +8 -7
  376. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  377. package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
  378. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  379. package/src/components/ErrorBoundary/index.ts +27 -2
  380. package/src/components/EventSelector/EventSelector.tsx +4 -1
  381. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  382. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  383. package/src/components/FileUpload/FileUpload.tsx +22 -2
  384. package/src/components/Footer/Footer.test.tsx +16 -16
  385. package/src/components/Footer/Footer.tsx +15 -12
  386. package/src/components/Form/Form.test.tsx +36 -15
  387. package/src/components/Form/Form.tsx +31 -26
  388. package/src/components/Header/Header.tsx +22 -11
  389. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  390. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  391. package/src/components/Input/Input.test.tsx +2 -2
  392. package/src/components/Input/Input.tsx +36 -34
  393. package/src/components/Label/Label.tsx +1 -1
  394. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  395. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  396. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  397. package/src/components/LoginForm/LoginForm.tsx +12 -8
  398. package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
  399. package/src/components/NavigationMenu/types.ts +56 -0
  400. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  401. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  402. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  403. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
  404. package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
  405. package/src/components/PaceAppLayout/README.md +1 -1
  406. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  407. package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
  408. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  409. package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
  410. package/src/components/Progress/Progress.tsx +1 -1
  411. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  412. package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
  413. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  414. package/src/components/Select/Select.tsx +95 -438
  415. package/src/components/Select/context.ts +23 -0
  416. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  417. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  418. package/src/components/Select/hooks/useSelectState.ts +104 -0
  419. package/src/components/Select/index.ts +9 -1
  420. package/src/components/Select/types.ts +123 -0
  421. package/src/components/Select/utils/text.ts +26 -0
  422. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
  423. package/src/components/Switch/Switch.tsx +4 -4
  424. package/src/components/Table/Table.tsx +1 -1
  425. package/src/components/Tabs/Tabs.tsx +1 -1
  426. package/src/components/Textarea/Textarea.tsx +27 -29
  427. package/src/components/Toast/Toast.tsx +5 -1
  428. package/src/components/Tooltip/Tooltip.tsx +3 -3
  429. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  430. package/src/components/UserMenu/UserMenu.tsx +22 -19
  431. package/src/components/index.ts +2 -2
  432. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  433. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  434. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  435. package/src/hooks/index.ts +1 -2
  436. package/src/hooks/public/usePublicEvent.ts +5 -1
  437. package/src/hooks/public/usePublicEventLogo.ts +5 -1
  438. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  439. package/src/hooks/public/usePublicRouteParams.ts +5 -1
  440. package/src/hooks/services/useAuth.ts +32 -0
  441. package/src/hooks/services/useCurrentEvent.ts +6 -0
  442. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  443. package/src/hooks/useDataTableState.ts +8 -18
  444. package/src/hooks/useDebounce.ts +9 -0
  445. package/src/hooks/useEventTheme.ts +6 -0
  446. package/src/hooks/useFileDisplay.ts +4 -0
  447. package/src/hooks/useFileReference.ts +25 -7
  448. package/src/hooks/useFileUrl.ts +11 -1
  449. package/src/hooks/useFocusManagement.ts +16 -2
  450. package/src/hooks/useFocusTrap.ts +7 -4
  451. package/src/hooks/useFormDialog.ts +8 -7
  452. package/src/hooks/useInactivityTracker.ts +4 -1
  453. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  454. package/src/hooks/useOrganisationPermissions.ts +4 -0
  455. package/src/hooks/useOrganisationSecurity.ts +4 -0
  456. package/src/hooks/usePerformanceMonitor.ts +4 -0
  457. package/src/hooks/usePermissionCache.ts +8 -1
  458. package/src/hooks/useQueryCache.ts +12 -1
  459. package/src/hooks/useSessionRestoration.ts +4 -0
  460. package/src/hooks/useStorage.ts +4 -0
  461. package/src/hooks/useToast.ts +3 -3
  462. package/src/index.ts +2 -1
  463. package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
  464. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  465. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  466. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  467. package/src/providers/services/EventServiceProvider.tsx +18 -0
  468. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  469. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  470. package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
  471. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
  472. package/src/rbac/README.md +1 -1
  473. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
  474. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  475. package/src/rbac/adapters.tsx +14 -5
  476. package/src/rbac/api.ts +100 -67
  477. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  478. package/src/rbac/components/NavigationGuard.tsx +1 -1
  479. package/src/rbac/components/NavigationProvider.tsx +5 -2
  480. package/src/rbac/components/PagePermissionGuard.tsx +158 -18
  481. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  482. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  483. package/src/rbac/components/RoleBasedRouter.tsx +6 -2
  484. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  485. package/src/rbac/components/SecureDataProvider.tsx +21 -6
  486. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  487. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  488. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  489. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  490. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  491. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  492. package/src/rbac/engine.ts +38 -14
  493. package/src/rbac/hooks/permissions/index.ts +7 -0
  494. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  495. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  496. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  497. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  498. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  499. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  500. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  501. package/src/rbac/hooks/useCan.test.ts +71 -64
  502. package/src/rbac/hooks/usePermissions.ts +14 -995
  503. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  504. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  505. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  506. package/src/rbac/permissions.ts +0 -30
  507. package/src/rbac/secureClient.ts +212 -61
  508. package/src/rbac/types.ts +8 -0
  509. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  510. package/src/theming/parseEventColours.ts +5 -19
  511. package/src/types/vitest-globals.d.ts +51 -26
  512. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  513. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  514. package/src/utils/__tests__/index.unit.test.ts +2 -2
  515. package/src/utils/audit/audit.ts +0 -3
  516. package/src/utils/core/cn.ts +1 -1
  517. package/src/utils/file-reference/index.ts +53 -1
  518. package/src/utils/formatting/formatting.ts +8 -18
  519. package/src/utils/index.ts +0 -1
  520. package/src/utils/security/secureDataAccess.test.ts +31 -20
  521. package/src/utils/security/secureDataAccess.ts +4 -3
  522. package/dist/chunk-6C4YBBJM.js +0 -628
  523. package/dist/chunk-6C4YBBJM.js.map +0 -1
  524. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  525. package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
  526. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  527. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  528. package/dist/chunk-7FLMSG37.js.map +0 -1
  529. package/dist/chunk-BC4IJKSL.js.map +0 -1
  530. package/dist/chunk-E3SPN4VZ.js +0 -12917
  531. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  532. package/dist/chunk-E66EQZE6 5.js +0 -37
  533. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  534. package/dist/chunk-HWIIPPNI.js.map +0 -1
  535. package/dist/chunk-I7PSE6JW 5.js +0 -191
  536. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  537. package/dist/chunk-I7PSE6JW.js.map +0 -1
  538. package/dist/chunk-IIELH4DL.js.map +0 -1
  539. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  540. package/dist/chunk-KNC55RTG.js.map +0 -1
  541. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  542. package/dist/chunk-LFNCN2SP.js +0 -412
  543. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  544. package/dist/chunk-LFNCN2SP.js.map +0 -1
  545. package/dist/chunk-LMC26NLJ 2.js +0 -84
  546. package/dist/chunk-NOAYCWCX.js +0 -4993
  547. package/dist/chunk-NOAYCWCX.js.map +0 -1
  548. package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
  549. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  550. package/dist/chunk-QXHPKYJV 3.js +0 -113
  551. package/dist/chunk-R77UEZ4E.js +0 -68
  552. package/dist/chunk-R77UEZ4E.js.map +0 -1
  553. package/dist/chunk-SQGMNID3.js.map +0 -1
  554. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  555. package/dist/chunk-XNXXZ43G.js.map +0 -1
  556. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  557. package/dist/components.js 5.map +0 -1
  558. package/dist/styles/index 2.js +0 -12
  559. package/dist/styles/index.js 5.map +0 -1
  560. package/dist/theming/runtime 5.js +0 -19
  561. package/dist/theming/runtime.js 5.map +0 -1
  562. package/docs/api/classes/ErrorBoundary.md +0 -144
  563. package/docs/migration/quick-migration-guide.md +0 -356
  564. package/docs/migration/service-architecture.md +0 -281
  565. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  566. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  567. package/src/hooks/useSecureDataAccess.ts +0 -666
  568. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  569. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  570. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  571. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  572. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  573. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  574. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  575. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  576. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  577. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -78,7 +78,7 @@ const createMockRow = (overrides: Partial<Row<TestData>> = {}): Row<TestData> =>
78
78
  } as unknown as Row<TestData>);
79
79
 
80
80
  describe('[component] GroupHeader', () => {
81
- const defaultProps = {
81
+ const baseProps = {
82
82
  row: createMockRow(),
83
83
  groupByColumn: 'category',
84
84
  isExpanded: false,
@@ -96,40 +96,40 @@ describe('[component] GroupHeader', () => {
96
96
 
97
97
  describe('Rendering', () => {
98
98
  it('renders group header container', () => {
99
- render(<GroupHeader {...defaultProps} />);
99
+ render(<GroupHeader {...baseProps} />);
100
100
 
101
101
  const container = screen.getByText(/Category A/i).closest('div');
102
102
  expect(container).toBeInTheDocument();
103
103
  });
104
104
 
105
105
  it('displays group value', () => {
106
- render(<GroupHeader {...defaultProps} />);
106
+ render(<GroupHeader {...baseProps} />);
107
107
 
108
108
  expect(screen.getByText(/Category A/i)).toBeInTheDocument();
109
109
  });
110
110
 
111
111
  it('displays subRowsCount', () => {
112
- render(<GroupHeader {...defaultProps} subRowsCount={10} />);
112
+ render(<GroupHeader {...baseProps} subRowsCount={10} />);
113
113
 
114
114
  expect(screen.getByText(/\(10 items\)/i)).toBeInTheDocument();
115
115
  });
116
116
 
117
117
  it('renders ChevronRight icon when not expanded', () => {
118
- render(<GroupHeader {...defaultProps} isExpanded={false} />);
118
+ render(<GroupHeader {...baseProps} isExpanded={false} />);
119
119
 
120
120
  expect(screen.getByTestId('chevron-right-icon')).toBeInTheDocument();
121
121
  expect(screen.queryByTestId('chevron-down-icon')).not.toBeInTheDocument();
122
122
  });
123
123
 
124
124
  it('renders ChevronDown icon when expanded', () => {
125
- render(<GroupHeader {...defaultProps} isExpanded={true} />);
125
+ render(<GroupHeader {...baseProps} isExpanded={true} />);
126
126
 
127
127
  expect(screen.getByTestId('chevron-down-icon')).toBeInTheDocument();
128
128
  expect(screen.queryByTestId('chevron-right-icon')).not.toBeInTheDocument();
129
129
  });
130
130
 
131
131
  it('renders toggle button', () => {
132
- render(<GroupHeader {...defaultProps} />);
132
+ render(<GroupHeader {...baseProps} />);
133
133
 
134
134
  const button = screen.getByRole('button');
135
135
  expect(button).toBeInTheDocument();
@@ -147,7 +147,7 @@ describe('[component] GroupHeader', () => {
147
147
 
148
148
  render(
149
149
  <GroupHeader
150
- {...defaultProps}
150
+ {...baseProps}
151
151
  row={row}
152
152
  />
153
153
  );
@@ -165,7 +165,7 @@ describe('[component] GroupHeader', () => {
165
165
 
166
166
  render(
167
167
  <GroupHeader
168
- {...defaultProps}
168
+ {...baseProps}
169
169
  row={row}
170
170
  />
171
171
  );
@@ -183,7 +183,7 @@ describe('[component] GroupHeader', () => {
183
183
 
184
184
  render(
185
185
  <GroupHeader
186
- {...defaultProps}
186
+ {...baseProps}
187
187
  row={row}
188
188
  />
189
189
  );
@@ -201,7 +201,7 @@ describe('[component] GroupHeader', () => {
201
201
 
202
202
  render(
203
203
  <GroupHeader
204
- {...defaultProps}
204
+ {...baseProps}
205
205
  row={row}
206
206
  />
207
207
  );
@@ -212,19 +212,19 @@ describe('[component] GroupHeader', () => {
212
212
 
213
213
  describe('SubRows Count Display', () => {
214
214
  it('displays correct count for single item', () => {
215
- render(<GroupHeader {...defaultProps} subRowsCount={1} />);
215
+ render(<GroupHeader {...baseProps} subRowsCount={1} />);
216
216
 
217
217
  expect(screen.getByText(/\(1 items\)/i)).toBeInTheDocument();
218
218
  });
219
219
 
220
220
  it('displays correct count for multiple items', () => {
221
- render(<GroupHeader {...defaultProps} subRowsCount={25} />);
221
+ render(<GroupHeader {...baseProps} subRowsCount={25} />);
222
222
 
223
223
  expect(screen.getByText(/\(25 items\)/i)).toBeInTheDocument();
224
224
  });
225
225
 
226
226
  it('displays zero count', () => {
227
- render(<GroupHeader {...defaultProps} subRowsCount={0} />);
227
+ render(<GroupHeader {...baseProps} subRowsCount={0} />);
228
228
 
229
229
  expect(screen.getByText(/\(0 items\)/i)).toBeInTheDocument();
230
230
  });
@@ -237,7 +237,7 @@ describe('[component] GroupHeader', () => {
237
237
 
238
238
  render(
239
239
  <GroupHeader
240
- {...defaultProps}
240
+ {...baseProps}
241
241
  onToggle={handleToggle}
242
242
  />
243
243
  );
@@ -254,7 +254,7 @@ describe('[component] GroupHeader', () => {
254
254
 
255
255
  render(
256
256
  <GroupHeader
257
- {...defaultProps}
257
+ {...baseProps}
258
258
  onToggle={handleToggle}
259
259
  />
260
260
  );
@@ -270,7 +270,7 @@ describe('[component] GroupHeader', () => {
270
270
  it('updates icon when expanded state changes', () => {
271
271
  const { rerender } = render(
272
272
  <GroupHeader
273
- {...defaultProps}
273
+ {...baseProps}
274
274
  isExpanded={false}
275
275
  />
276
276
  );
@@ -279,7 +279,7 @@ describe('[component] GroupHeader', () => {
279
279
 
280
280
  rerender(
281
281
  <GroupHeader
282
- {...defaultProps}
282
+ {...baseProps}
283
283
  isExpanded={true}
284
284
  />
285
285
  );
@@ -299,7 +299,7 @@ describe('[component] GroupHeader', () => {
299
299
 
300
300
  render(
301
301
  <GroupHeader
302
- {...defaultProps}
302
+ {...baseProps}
303
303
  row={row}
304
304
  />
305
305
  );
@@ -308,7 +308,7 @@ describe('[component] GroupHeader', () => {
308
308
  });
309
309
 
310
310
  it('handles very large subRowsCount', () => {
311
- render(<GroupHeader {...defaultProps} subRowsCount={999999} />);
311
+ render(<GroupHeader {...baseProps} subRowsCount={999999} />);
312
312
 
313
313
  expect(screen.getByText(/\(999999 items\)/i)).toBeInTheDocument();
314
314
  });
@@ -323,7 +323,7 @@ describe('[component] GroupHeader', () => {
323
323
 
324
324
  render(
325
325
  <GroupHeader
326
- {...defaultProps}
326
+ {...baseProps}
327
327
  row={row}
328
328
  groupByColumn="status"
329
329
  />
@@ -342,7 +342,7 @@ describe('[component] GroupHeader', () => {
342
342
 
343
343
  render(
344
344
  <GroupHeader
345
- {...defaultProps}
345
+ {...baseProps}
346
346
  row={row}
347
347
  />
348
348
  );
@@ -353,21 +353,21 @@ describe('[component] GroupHeader', () => {
353
353
 
354
354
  describe('Styling', () => {
355
355
  it('has proper container styling', () => {
356
- render(<GroupHeader {...defaultProps} />);
356
+ render(<GroupHeader {...baseProps} />);
357
357
 
358
358
  const container = screen.getByText(/Category A/i).closest('div');
359
359
  expect(container).toHaveClass('flex', 'items-center');
360
360
  });
361
361
 
362
362
  it('applies background and border styling', () => {
363
- render(<GroupHeader {...defaultProps} />);
363
+ render(<GroupHeader {...baseProps} />);
364
364
 
365
365
  const container = screen.getByText(/Category A/i).closest('div');
366
366
  expect(container).toHaveClass('bg-muted/50', 'border-b');
367
367
  });
368
368
 
369
369
  it('applies font styling', () => {
370
- render(<GroupHeader {...defaultProps} />);
370
+ render(<GroupHeader {...baseProps} />);
371
371
 
372
372
  const container = screen.getByText(/Category A/i).closest('div');
373
373
  expect(container).toHaveClass('font-medium');
@@ -376,14 +376,14 @@ describe('[component] GroupHeader', () => {
376
376
 
377
377
  describe('Accessibility', () => {
378
378
  it('has accessible button for toggling', () => {
379
- render(<GroupHeader {...defaultProps} />);
379
+ render(<GroupHeader {...baseProps} />);
380
380
 
381
381
  const button = screen.getByRole('button');
382
382
  expect(button).toBeInTheDocument();
383
383
  });
384
384
 
385
385
  it('displays group information clearly', () => {
386
- render(<GroupHeader {...defaultProps} />);
386
+ render(<GroupHeader {...baseProps} />);
387
387
 
388
388
  expect(screen.getByText(/Category A/i)).toBeInTheDocument();
389
389
  expect(screen.getByText(/\(5 items\)/i)).toBeInTheDocument();
@@ -89,7 +89,7 @@ vi.mock('../../../utils/core/logger', () => ({
89
89
  }));
90
90
 
91
91
  describe('[component] ImportModal', () => {
92
- const defaultProps = {
92
+ const baseProps = {
93
93
  isOpen: true,
94
94
  onClose: vi.fn(),
95
95
  onImport: vi.fn(),
@@ -133,13 +133,13 @@ describe('[component] ImportModal', () => {
133
133
  describe('Rendering', () => {
134
134
  it('returns null when modal is closed', () => {
135
135
  const { container } = render(
136
- <ImportModal {...defaultProps} isOpen={false} />
136
+ <ImportModal {...baseProps} isOpen={false} />
137
137
  );
138
138
  expect(container.firstChild).toBeNull();
139
139
  });
140
140
 
141
141
  it('renders modal when open', () => {
142
- render(<ImportModal {...defaultProps} />);
142
+ render(<ImportModal {...baseProps} />);
143
143
 
144
144
  // Dialog renders with role="dialog" from Radix UI
145
145
  expect(screen.getByRole('dialog')).toBeInTheDocument();
@@ -148,7 +148,7 @@ describe('[component] ImportModal', () => {
148
148
  });
149
149
 
150
150
  it('renders default title', () => {
151
- render(<ImportModal {...defaultProps} />);
151
+ render(<ImportModal {...baseProps} />);
152
152
 
153
153
  // DialogTitle renders as h2
154
154
  expect(screen.getByRole('heading', { name: 'Import Data' })).toBeInTheDocument();
@@ -157,7 +157,7 @@ describe('[component] ImportModal', () => {
157
157
  it('renders custom title from config', () => {
158
158
  render(
159
159
  <ImportModal
160
- {...defaultProps}
160
+ {...baseProps}
161
161
  config={{ title: 'Custom Import Title' }}
162
162
  />
163
163
  );
@@ -167,7 +167,7 @@ describe('[component] ImportModal', () => {
167
167
  });
168
168
 
169
169
  it('renders default description', () => {
170
- render(<ImportModal {...defaultProps} />);
170
+ render(<ImportModal {...baseProps} />);
171
171
 
172
172
  // DialogDescription renders as p
173
173
  expect(screen.getByText('Upload a CSV file to import multiple records at once.')).toBeInTheDocument();
@@ -176,7 +176,7 @@ describe('[component] ImportModal', () => {
176
176
  it('renders custom description from config', () => {
177
177
  render(
178
178
  <ImportModal
179
- {...defaultProps}
179
+ {...baseProps}
180
180
  config={{ description: 'Custom description' }}
181
181
  />
182
182
  );
@@ -186,20 +186,20 @@ describe('[component] ImportModal', () => {
186
186
  });
187
187
 
188
188
  it('renders file upload area', () => {
189
- render(<ImportModal {...defaultProps} />);
189
+ render(<ImportModal {...baseProps} />);
190
190
 
191
191
  expect(screen.getByText(/choose a csv file/i)).toBeInTheDocument();
192
192
  expect(screen.getByRole('button', { name: /select file/i })).toBeInTheDocument();
193
193
  });
194
194
 
195
195
  it('renders cancel button', () => {
196
- render(<ImportModal {...defaultProps} />);
196
+ render(<ImportModal {...baseProps} />);
197
197
 
198
198
  expect(screen.getByRole('button', { name: /cancel/i })).toBeInTheDocument();
199
199
  });
200
200
 
201
201
  it('renders import button', () => {
202
- render(<ImportModal {...defaultProps} />);
202
+ render(<ImportModal {...baseProps} />);
203
203
 
204
204
  expect(screen.getByRole('button', { name: /import/i })).toBeInTheDocument();
205
205
  });
@@ -211,7 +211,7 @@ describe('[component] ImportModal', () => {
211
211
  const csvContent = 'name,email\nJohn,john@example.com';
212
212
  const file = createCSVFile(csvContent);
213
213
 
214
- render(<ImportModal {...defaultProps} />);
214
+ render(<ImportModal {...baseProps} />);
215
215
 
216
216
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
217
217
  await user.upload(fileInput, file);
@@ -226,7 +226,7 @@ describe('[component] ImportModal', () => {
226
226
  const csvContent = 'name,email\nJohn,john@example.com';
227
227
  const file = createCSVFile(csvContent);
228
228
 
229
- const { rerender } = render(<ImportModal {...defaultProps} />);
229
+ const { rerender } = render(<ImportModal {...baseProps} />);
230
230
 
231
231
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
232
232
  await user.upload(fileInput, file);
@@ -235,8 +235,8 @@ describe('[component] ImportModal', () => {
235
235
  expect(screen.getByText(`Selected: ${file.name}`)).toBeInTheDocument();
236
236
  });
237
237
 
238
- rerender(<ImportModal {...defaultProps} isOpen={false} />);
239
- rerender(<ImportModal {...defaultProps} isOpen={true} />);
238
+ rerender(<ImportModal {...baseProps} isOpen={false} />);
239
+ rerender(<ImportModal {...baseProps} isOpen={true} />);
240
240
 
241
241
  // File should be reset
242
242
  expect(screen.queryByText(`Selected: ${file.name}`)).not.toBeInTheDocument();
@@ -249,7 +249,7 @@ describe('[component] ImportModal', () => {
249
249
  const csvContent = 'name,email\nJohn,john@example.com\nJane,jane@example.com';
250
250
  const file = createCSVFile(csvContent);
251
251
 
252
- render(<ImportModal {...defaultProps} />);
252
+ render(<ImportModal {...baseProps} />);
253
253
 
254
254
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
255
255
  await user.upload(fileInput, file);
@@ -272,7 +272,7 @@ describe('[component] ImportModal', () => {
272
272
  const csvContent = 'name,email\nJohn,john@example.com\nJane,jane@example.com';
273
273
  const file = createCSVFile(csvContent);
274
274
 
275
- render(<ImportModal {...defaultProps} />);
275
+ render(<ImportModal {...baseProps} />);
276
276
 
277
277
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
278
278
  await user.upload(fileInput, file);
@@ -295,7 +295,7 @@ describe('[component] ImportModal', () => {
295
295
  const csvContent = 'name,email\nJohn,john@example.com\nJane,jane@example.com\nBob,bob@example.com';
296
296
  const file = createCSVFile(csvContent);
297
297
 
298
- render(<ImportModal {...defaultProps} />);
298
+ render(<ImportModal {...baseProps} />);
299
299
 
300
300
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
301
301
  await user.upload(fileInput, file);
@@ -317,7 +317,7 @@ describe('[component] ImportModal', () => {
317
317
  const csvContent = 'name,email\n"John Doe","john@example.com"\n"Jane Smith","jane@example.com"';
318
318
  const file = createCSVFile(csvContent);
319
319
 
320
- render(<ImportModal {...defaultProps} />);
320
+ render(<ImportModal {...baseProps} />);
321
321
 
322
322
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
323
323
  await user.upload(fileInput, file);
@@ -339,7 +339,7 @@ describe('[component] ImportModal', () => {
339
339
  const csvContent = 'name,description\nJohn,"Description, with comma"\nJane,"Another, description"';
340
340
  const file = createCSVFile(csvContent);
341
341
 
342
- render(<ImportModal {...defaultProps} />);
342
+ render(<ImportModal {...baseProps} />);
343
343
 
344
344
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
345
345
  await user.upload(fileInput, file);
@@ -365,7 +365,7 @@ describe('[component] ImportModal', () => {
365
365
  const invalidContent = 'name,email';
366
366
  const file = createCSVFile(invalidContent);
367
367
 
368
- render(<ImportModal {...defaultProps} />);
368
+ render(<ImportModal {...baseProps} />);
369
369
 
370
370
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
371
371
  await user.upload(fileInput, file);
@@ -384,7 +384,7 @@ describe('[component] ImportModal', () => {
384
384
  const csvContent = 'name,email';
385
385
  const file = createCSVFile(csvContent);
386
386
 
387
- render(<ImportModal {...defaultProps} />);
387
+ render(<ImportModal {...baseProps} />);
388
388
 
389
389
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
390
390
  await user.upload(fileInput, file);
@@ -399,7 +399,7 @@ describe('[component] ImportModal', () => {
399
399
  const invalidFile = createCSVFile('invalid');
400
400
  const validFile = createCSVFile('name,email\nJohn,john@example.com');
401
401
 
402
- render(<ImportModal {...defaultProps} />);
402
+ render(<ImportModal {...baseProps} />);
403
403
 
404
404
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
405
405
  await user.upload(fileInput, invalidFile);
@@ -425,7 +425,7 @@ describe('[component] ImportModal', () => {
425
425
  const csvContent = 'name,email\nJohn,john@example.com';
426
426
  const file = createCSVFile(csvContent);
427
427
 
428
- render(<ImportModal {...defaultProps} onImport={onImport} />);
428
+ render(<ImportModal {...baseProps} onImport={onImport} />);
429
429
 
430
430
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
431
431
  await user.upload(fileInput, file);
@@ -457,7 +457,7 @@ describe('[component] ImportModal', () => {
457
457
  });
458
458
 
459
459
  it('disables import button when no file is selected', () => {
460
- render(<ImportModal {...defaultProps} />);
460
+ render(<ImportModal {...baseProps} />);
461
461
 
462
462
  const importButton = screen.getByRole('button', { name: /import/i });
463
463
  expect(importButton).toBeDisabled();
@@ -469,7 +469,7 @@ describe('[component] ImportModal', () => {
469
469
  const csvContent = 'name,email\nJohn,john@example.com';
470
470
  const file = createCSVFile(csvContent);
471
471
 
472
- render(<ImportModal {...defaultProps} onImport={onImport} />);
472
+ render(<ImportModal {...baseProps} onImport={onImport} />);
473
473
 
474
474
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
475
475
  await user.upload(fileInput, file);
@@ -498,7 +498,7 @@ describe('[component] ImportModal', () => {
498
498
  const csvContent = 'name,email\nJohn,john@example.com';
499
499
  const file = createCSVFile(csvContent);
500
500
 
501
- render(<ImportModal {...defaultProps} onImport={onImport} />);
501
+ render(<ImportModal {...baseProps} onImport={onImport} />);
502
502
 
503
503
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
504
504
  await user.upload(fileInput, file);
@@ -529,7 +529,7 @@ describe('[component] ImportModal', () => {
529
529
  const csvContent = 'name,email\nJohn,john@example.com';
530
530
  const file = createCSVFile(csvContent);
531
531
 
532
- render(<ImportModal {...defaultProps} onClose={onClose} />);
532
+ render(<ImportModal {...baseProps} onClose={onClose} />);
533
533
 
534
534
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
535
535
  await user.upload(fileInput, file);
@@ -558,7 +558,7 @@ describe('[component] ImportModal', () => {
558
558
  const user = userEvent.setup();
559
559
  const onClose = vi.fn();
560
560
 
561
- render(<ImportModal {...defaultProps} onClose={onClose} />);
561
+ render(<ImportModal {...baseProps} onClose={onClose} />);
562
562
 
563
563
  const cancelButton = screen.getByRole('button', { name: /cancel/i });
564
564
  await user.click(cancelButton);
@@ -571,7 +571,7 @@ describe('[component] ImportModal', () => {
571
571
  const csvContent = 'name,email\nJohn,john@example.com';
572
572
  const file = createCSVFile(csvContent);
573
573
 
574
- const { rerender } = render(<ImportModal {...defaultProps} />);
574
+ const { rerender } = render(<ImportModal {...baseProps} />);
575
575
 
576
576
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
577
577
  await user.upload(fileInput, file);
@@ -586,8 +586,8 @@ describe('[component] ImportModal', () => {
586
586
  expect(screen.getByText('John')).toBeInTheDocument();
587
587
  }, { timeout: 2000 });
588
588
 
589
- rerender(<ImportModal {...defaultProps} isOpen={false} />);
590
- rerender(<ImportModal {...defaultProps} isOpen={true} />);
589
+ rerender(<ImportModal {...baseProps} isOpen={false} />);
590
+ rerender(<ImportModal {...baseProps} isOpen={true} />);
591
591
 
592
592
  // State should be reset - wait for modal to reopen
593
593
  await waitFor(() => {
@@ -600,7 +600,7 @@ describe('[component] ImportModal', () => {
600
600
  it('uses custom button texts from config', () => {
601
601
  render(
602
602
  <ImportModal
603
- {...defaultProps}
603
+ {...baseProps}
604
604
  config={{
605
605
  selectFileButtonText: 'Browse Files',
606
606
  importButtonText: 'Import Data',
@@ -624,7 +624,7 @@ describe('[component] ImportModal', () => {
624
624
 
625
625
  render(
626
626
  <ImportModal
627
- {...defaultProps}
627
+ {...baseProps}
628
628
  config={{ previewHeaderText: 'Data Preview' }}
629
629
  />
630
630
  );
@@ -645,7 +645,7 @@ describe('[component] ImportModal', () => {
645
645
 
646
646
  render(
647
647
  <ImportModal
648
- {...defaultProps}
648
+ {...baseProps}
649
649
  config={{ totalRowsText: 'Found {count} records' }}
650
650
  />
651
651
  );
@@ -670,7 +670,7 @@ describe('[component] ImportModal', () => {
670
670
  const user = userEvent.setup();
671
671
  const file = createCSVFile('');
672
672
 
673
- render(<ImportModal {...defaultProps} />);
673
+ render(<ImportModal {...baseProps} />);
674
674
 
675
675
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
676
676
  await user.upload(fileInput, file);
@@ -684,7 +684,7 @@ describe('[component] ImportModal', () => {
684
684
  const user = userEvent.setup();
685
685
  const file = createCSVFile(' \n \n ');
686
686
 
687
- render(<ImportModal {...defaultProps} />);
687
+ render(<ImportModal {...baseProps} />);
688
688
 
689
689
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
690
690
  await user.upload(fileInput, file);
@@ -701,7 +701,7 @@ describe('[component] ImportModal', () => {
701
701
  const csvContent = headers + rows;
702
702
  const file = createCSVFile(csvContent);
703
703
 
704
- render(<ImportModal {...defaultProps} />);
704
+ render(<ImportModal {...baseProps} />);
705
705
 
706
706
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
707
707
  await user.upload(fileInput, file);
@@ -714,7 +714,7 @@ describe('[component] ImportModal', () => {
714
714
 
715
715
  describe('Accessibility', () => {
716
716
  it('provides accessible file input', () => {
717
- render(<ImportModal {...defaultProps} />);
717
+ render(<ImportModal {...baseProps} />);
718
718
 
719
719
  const fileInput = document.querySelector('input[type="file"]') as HTMLInputElement;
720
720
  expect(fileInput).toBeInTheDocument();
@@ -723,7 +723,7 @@ describe('[component] ImportModal', () => {
723
723
  });
724
724
 
725
725
  it('provides accessible button labels', () => {
726
- render(<ImportModal {...defaultProps} />);
726
+ render(<ImportModal {...baseProps} />);
727
727
 
728
728
  expect(screen.getByRole('button', { name: /select file/i })).toBeInTheDocument();
729
729
  expect(screen.getByRole('button', { name: /import/i })).toBeInTheDocument();