@jmruthers/pace-core 0.6.10 → 0.6.12

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 (1500) hide show
  1. package/CHANGELOG.md +21 -0
  2. package/audit-tool/00-dependencies.cjs +46 -13
  3. package/audit-tool/audits/01-pace-core-compliance.cjs +96 -21
  4. package/audit-tool/audits/02-project-structure.cjs +13 -3
  5. package/audit-tool/audits/03-architecture.cjs +78 -4
  6. package/audit-tool/audits/04-code-quality.cjs +9 -2
  7. package/audit-tool/audits/05-styling.cjs +19 -7
  8. package/audit-tool/audits/06-security-rbac.cjs +105 -14
  9. package/audit-tool/audits/07-api-tech-stack.cjs +31 -15
  10. package/audit-tool/audits/08-testing-documentation.cjs +11 -3
  11. package/audit-tool/audits/09-operations.cjs +19 -7
  12. package/audit-tool/index.cjs +22 -11
  13. package/audit-tool/utils/report-utils.cjs +4 -0
  14. package/cursor-rules/01-pace-core-compliance.mdc +1 -0
  15. package/cursor-rules/02-project-structure.mdc +1 -0
  16. package/cursor-rules/03-architecture.mdc +3 -1
  17. package/cursor-rules/04-code-quality.mdc +1 -0
  18. package/cursor-rules/05-styling.mdc +41 -7
  19. package/cursor-rules/06-security-rbac.mdc +2 -1
  20. package/cursor-rules/07-api-tech-stack.mdc +1 -0
  21. package/cursor-rules/08-testing-documentation.mdc +1 -0
  22. package/cursor-rules/09-operations.mdc +1 -0
  23. package/dist/DataTable-AQAHSFLM.js +17 -0
  24. package/dist/InactivityServiceProvider-BbxwwDz1.d.ts +308 -0
  25. package/dist/UnifiedAuthProvider-Bkt_tzdS.d.ts +183 -0
  26. package/dist/api-6OQXYT67.js +6 -0
  27. package/dist/api-result-USV1Czr-.d.ts +51 -0
  28. package/dist/audit-HI2DHUVU.js +4 -0
  29. package/dist/auth-JvdRVaud.d.ts +49 -0
  30. package/dist/chunk-2DL2WSOE.js +327 -0
  31. package/dist/chunk-2GBDPPUC.js +61 -0
  32. package/dist/chunk-44CNXN4P.js +15 -0
  33. package/dist/chunk-AP5FG7W4.js +2159 -0
  34. package/dist/chunk-CU2BU2MQ.js +2 -0
  35. package/dist/chunk-D6BMFMQZ.js +200 -0
  36. package/dist/chunk-ENLXB7GP.js +721 -0
  37. package/dist/chunk-GHCUP64P.js +105 -0
  38. package/dist/chunk-H6RTU4DZ.js +1098 -0
  39. package/dist/chunk-HQTYP6BX.js +6468 -0
  40. package/dist/chunk-M7QE7XOA.js +529 -0
  41. package/dist/chunk-MVVWZ7JV.js +1329 -0
  42. package/dist/chunk-NJ7FGQWB.js +811 -0
  43. package/dist/chunk-QRYSEPHB.js +429 -0
  44. package/dist/chunk-QWIG36BZ.js +264 -0
  45. package/dist/chunk-S57OLCLO.js +2946 -0
  46. package/dist/chunk-VFLR5K2H.js +23 -0
  47. package/dist/chunk-XOJME5T7.js +407 -0
  48. package/dist/chunk-XPFVT3GN.js +492 -0
  49. package/dist/chunk-Y2LWSLLB.js +9614 -0
  50. package/dist/chunk-YFGNMB67.js +2390 -0
  51. package/dist/components.d.ts +10 -9
  52. package/dist/components.js +20 -17
  53. package/dist/database.generated-qkdoiVrJ.d.ts +9441 -0
  54. package/dist/eslint-rules/index.cjs +3 -0
  55. package/dist/eslint-rules/rules/03-architecture.cjs +74 -0
  56. package/dist/eslint-rules/rules/06-security-rbac.cjs +74 -0
  57. package/dist/event-BfCox3N2.d.ts +265 -0
  58. package/dist/file-reference-DU1hcawx.d.ts +164 -0
  59. package/dist/functions-hF5ImHCr.d.ts +208 -0
  60. package/dist/hooks.d.ts +22 -9
  61. package/dist/hooks.js +35 -25
  62. package/dist/icons/index.d.ts +1 -0
  63. package/dist/icons/index.js +1 -0
  64. package/dist/index.d.ts +69 -180
  65. package/dist/index.js +319 -342
  66. package/dist/pagination-BW1mqywp.d.ts +201 -0
  67. package/dist/providers.d.ts +6 -5
  68. package/dist/providers.js +6 -3
  69. package/dist/rbac/index.d.ts +133 -148
  70. package/dist/rbac/index.js +12 -9
  71. package/dist/theming/runtime.d.ts +19 -2
  72. package/dist/theming/runtime.js +1 -1
  73. package/dist/timezone-BTWWXKVY.d.ts +696 -0
  74. package/dist/types-Besvoyzb.d.ts +55 -0
  75. package/dist/types-CGHrxfqc.d.ts +114 -0
  76. package/dist/types.d.ts +19 -12
  77. package/dist/types.js +1 -0
  78. package/dist/usePublicPageContext-BQrHf95t.d.ts +4367 -0
  79. package/dist/usePublicRouteParams-BgV6VhMi.d.ts +946 -0
  80. package/dist/utils.d.ts +163 -145
  81. package/dist/utils.js +45 -27
  82. package/docs/api/@jmruthers/namespaces/DialogPortal/README.md +14 -0
  83. package/docs/api/@jmruthers/namespaces/DialogPortal/variables/displayName.md +11 -0
  84. package/docs/api/README.md +6 -2
  85. package/docs/api/_media/README.md +186 -0
  86. package/docs/api/classes/ColumnFactory.md +225 -0
  87. package/docs/api/classes/Logger.md +246 -0
  88. package/docs/api/classes/RBACAuditManager.md +299 -0
  89. package/docs/api/classes/RBACCache.md +389 -0
  90. package/docs/api/classes/RBACEngine.md +181 -0
  91. package/docs/api/classes/SecureSupabaseClient.md +168 -0
  92. package/docs/api/classes/StorageUtils.md +324 -0
  93. package/docs/api/enumerations/FileCategory.md +137 -0
  94. package/docs/api/enumerations/LogLevel.md +43 -0
  95. package/docs/api/enumerations/RBACErrorCode.md +169 -0
  96. package/docs/api/enumerations/RPCFunction.md +89 -0
  97. package/docs/api/functions/AccessDenied.md +30 -0
  98. package/docs/api/functions/AppSwitcher.md +21 -0
  99. package/docs/api/functions/Badge.md +42 -0
  100. package/docs/api/functions/ContextSelector.md +43 -0
  101. package/docs/api/functions/DataTable.md +36 -0
  102. package/docs/api/functions/DatePickerWithTimezone.md +28 -0
  103. package/docs/api/functions/DialogBody.md +24 -0
  104. package/docs/api/functions/DialogFooter.md +24 -0
  105. package/docs/api/functions/DialogHeader.md +24 -0
  106. package/docs/api/functions/ErrorBoundaryProvider.md +28 -0
  107. package/docs/api/functions/EventServiceProvider.md +28 -0
  108. package/docs/api/functions/FileDisplay.md +25 -0
  109. package/docs/api/functions/FileUpload.md +21 -0
  110. package/docs/api/functions/Form.md +50 -0
  111. package/docs/api/functions/FormField.md +102 -0
  112. package/docs/api/functions/Header.md +21 -0
  113. package/docs/api/functions/InactivityServiceProvider.md +28 -0
  114. package/docs/api/functions/InactivityWarningModal.md +21 -0
  115. package/docs/api/functions/Input.md +49 -0
  116. package/docs/api/functions/NavigationGuard.md +31 -0
  117. package/docs/api/functions/OrganisationServiceProvider.md +28 -0
  118. package/docs/api/functions/PaceAppLayout.md +169 -0
  119. package/docs/api/functions/PasswordChangeForm.md +21 -0
  120. package/docs/api/functions/ProtectedRoute.md +37 -0
  121. package/docs/api/functions/PublicPageFooter.md +21 -0
  122. package/docs/api/functions/PublicPageHeader.md +21 -0
  123. package/docs/api/functions/PublicPageLayout.md +33 -0
  124. package/docs/api/functions/PublicPageProvider.md +30 -0
  125. package/docs/api/functions/Textarea.md +49 -0
  126. package/docs/api/functions/Toaster.md +34 -0
  127. package/docs/api/functions/UnifiedAuthProvider.md +28 -0
  128. package/docs/api/functions/applyPalette.md +33 -0
  129. package/docs/api/functions/archiveFile.md +47 -0
  130. package/docs/api/functions/average.md +63 -0
  131. package/docs/api/functions/buildAppUrl.md +46 -0
  132. package/docs/api/functions/clearInFlightRequests.md +17 -0
  133. package/docs/api/functions/clearPalette.md +18 -0
  134. package/docs/api/functions/clearPublicEventCache.md +18 -0
  135. package/docs/api/functions/clearPublicFileDisplayCache.md +18 -0
  136. package/docs/api/functions/clearPublicLogoCache.md +18 -0
  137. package/docs/api/functions/cn.md +21 -0
  138. package/docs/api/functions/count.md +56 -0
  139. package/docs/api/functions/createAuditManager.md +45 -0
  140. package/docs/api/functions/createBaseClient.md +75 -0
  141. package/docs/api/functions/createLogger.md +95 -0
  142. package/docs/api/functions/createRBACConfig.md +21 -0
  143. package/docs/api/functions/createRBACEngine.md +33 -0
  144. package/docs/api/functions/createRBACExpressMiddleware.md +84 -0
  145. package/docs/api/functions/createRBACMiddleware.md +88 -0
  146. package/docs/api/functions/createSecureClient.md +80 -0
  147. package/docs/api/functions/createSecureDataAccess.md +39 -0
  148. package/docs/api/functions/deleteFile.md +33 -0
  149. package/docs/api/functions/disablePerformanceMonitoring.md +17 -0
  150. package/docs/api/functions/downloadFile.md +33 -0
  151. package/docs/api/functions/emitAuditEvent.md +27 -0
  152. package/docs/api/functions/enablePerformanceMonitoring.md +17 -0
  153. package/docs/api/functions/err.md +23 -0
  154. package/docs/api/functions/exportToCSV.md +56 -0
  155. package/docs/api/functions/exportToCSVWithTableRows.md +46 -0
  156. package/docs/api/functions/extractEventCodeFromPath.md +24 -0
  157. package/docs/api/functions/extractFileMetadata.md +33 -0
  158. package/docs/api/functions/formatCompactNumber.md +27 -0
  159. package/docs/api/functions/formatCurrency.md +31 -0
  160. package/docs/api/functions/formatDate.md +23 -0
  161. package/docs/api/functions/formatDateTime.md +24 -0
  162. package/docs/api/functions/formatFileSize.md +23 -0
  163. package/docs/api/functions/formatInTimeZone.md +46 -0
  164. package/docs/api/functions/formatNumber.md +31 -0
  165. package/docs/api/functions/formatPercent.md +64 -0
  166. package/docs/api/functions/formatTime.md +24 -0
  167. package/docs/api/functions/formatTimeInTimeZone.md +40 -0
  168. package/docs/api/functions/fromSupabaseClient.md +49 -0
  169. package/docs/api/functions/fromZonedTime.md +41 -0
  170. package/docs/api/functions/generateCSVContent.md +55 -0
  171. package/docs/api/functions/generateFilePath.md +29 -0
  172. package/docs/api/functions/generateFileUrlsBatch.md +33 -0
  173. package/docs/api/functions/generatePublicRoutePath.md +27 -0
  174. package/docs/api/functions/generateUniqueFileName.md +24 -0
  175. package/docs/api/functions/getAccessLevel.md +48 -0
  176. package/docs/api/functions/getAllAppPorts.md +19 -0
  177. package/docs/api/functions/getAllStylePaths.md +15 -0
  178. package/docs/api/functions/getAppConfig.md +17 -0
  179. package/docs/api/functions/getAppPort.md +34 -0
  180. package/docs/api/functions/getBucketName.md +27 -0
  181. package/docs/api/functions/getCurrentAppId.md +17 -0
  182. package/docs/api/functions/getCurrentAppName.md +17 -0
  183. package/docs/api/functions/getFileSizeLimit.md +23 -0
  184. package/docs/api/functions/getGlobalAuditManager.md +19 -0
  185. package/docs/api/functions/getInFlightRequestCount.md +19 -0
  186. package/docs/api/functions/getPerformanceMetrics.md +17 -0
  187. package/docs/api/functions/getPerformanceSummary.md +17 -0
  188. package/docs/api/functions/getPermissionMap.md +52 -0
  189. package/docs/api/functions/getPublicEventCacheStats.md +25 -0
  190. package/docs/api/functions/getPublicFileDisplayCacheStats.md +25 -0
  191. package/docs/api/functions/getPublicLogoCacheStats.md +25 -0
  192. package/docs/api/functions/getPublicUrl.md +39 -0
  193. package/docs/api/functions/getRBACConfig.md +15 -0
  194. package/docs/api/functions/getRBACLogger.md +15 -0
  195. package/docs/api/functions/getRoleContext.md +31 -0
  196. package/docs/api/functions/getSignedUrl.md +34 -0
  197. package/docs/api/functions/getStylePath.md +21 -0
  198. package/docs/api/functions/getTimeZoneDifference.md +40 -0
  199. package/docs/api/functions/getTimezoneAbbreviation.md +40 -0
  200. package/docs/api/functions/getUserTimeZone.md +26 -0
  201. package/docs/api/functions/hasAllPermissions.md +41 -0
  202. package/docs/api/functions/hasAnyPermission.md +41 -0
  203. package/docs/api/functions/isDebugMode.md +15 -0
  204. package/docs/api/functions/isDevelopmentMode.md +15 -0
  205. package/docs/api/functions/isErr.md +29 -0
  206. package/docs/api/functions/isOk.md +29 -0
  207. package/docs/api/functions/isPerformanceMonitoringEnabled.md +17 -0
  208. package/docs/api/functions/isPermitted.md +58 -0
  209. package/docs/api/functions/isPermittedCached.md +36 -0
  210. package/docs/api/functions/isRBACInitialized.md +19 -0
  211. package/docs/api/functions/isSecureClient.md +38 -0
  212. package/docs/api/functions/isValidPermission.md +27 -0
  213. package/docs/api/functions/listFiles.md +29 -0
  214. package/docs/api/functions/max.md +63 -0
  215. package/docs/api/functions/min.md +63 -0
  216. package/docs/api/functions/ok.md +29 -0
  217. package/docs/api/functions/parseAndNormalizeEventColours.md +105 -0
  218. package/docs/api/functions/recordAuditEvent.md +23 -0
  219. package/docs/api/functions/recordPermissionCheck.md +31 -0
  220. package/docs/api/functions/resetPerformanceMetrics.md +17 -0
  221. package/docs/api/functions/resolveAppContext.md +27 -0
  222. package/docs/api/functions/roundToNearestMinutes.md +41 -0
  223. package/docs/api/functions/sanitizeFormData.md +49 -0
  224. package/docs/api/functions/sanitizeHtml.md +39 -0
  225. package/docs/api/functions/sanitizeUserInput.md +27 -0
  226. package/docs/api/functions/setAppConfig.md +23 -0
  227. package/docs/api/functions/setGlobalAuditManager.md +25 -0
  228. package/docs/api/functions/setupRBAC.md +31 -0
  229. package/docs/api/functions/sum.md +63 -0
  230. package/docs/api/functions/toZonedTime.md +41 -0
  231. package/docs/api/functions/uploadFile.md +32 -0
  232. package/docs/api/functions/useAccessLevel.md +71 -0
  233. package/docs/api/functions/useAccessibleApps.md +55 -0
  234. package/docs/api/functions/useAppConfig.md +20 -0
  235. package/docs/api/functions/useAuthService.md +15 -0
  236. package/docs/api/functions/useCan.md +99 -0
  237. package/docs/api/functions/useEventService.md +15 -0
  238. package/docs/api/functions/useEventTheme.md +26 -0
  239. package/docs/api/functions/useEvents.md +45 -0
  240. package/docs/api/functions/useFileReference.md +264 -0
  241. package/docs/api/functions/useFileReferenceById.md +63 -0
  242. package/docs/api/functions/useFileReferenceForRecord.md +129 -0
  243. package/docs/api/functions/useFilesByCategory.md +80 -0
  244. package/docs/api/functions/useFormDialog.md +62 -0
  245. package/docs/api/functions/useInactivityService.md +15 -0
  246. package/docs/api/functions/useInactivityTracker.md +21 -0
  247. package/docs/api/functions/useIsPublicPage.md +19 -0
  248. package/docs/api/functions/useMultiplePermissions.md +88 -0
  249. package/docs/api/functions/useOptionalEvents.md +31 -0
  250. package/docs/api/functions/useOrganisationPermissions.md +27 -0
  251. package/docs/api/functions/useOrganisationSecurity.md +15 -0
  252. package/docs/api/functions/useOrganisationService.md +15 -0
  253. package/docs/api/functions/useOrganisations.md +48 -0
  254. package/docs/api/functions/usePermissions.md +130 -0
  255. package/docs/api/functions/usePublicEvent.md +36 -0
  256. package/docs/api/functions/usePublicEventCode.md +32 -0
  257. package/docs/api/functions/usePublicEventLogo.md +48 -0
  258. package/docs/api/functions/usePublicFileDisplay.md +54 -0
  259. package/docs/api/functions/usePublicPageContext.md +19 -0
  260. package/docs/api/functions/usePublicRouteParams.md +31 -0
  261. package/docs/api/functions/useRBAC.md +21 -0
  262. package/docs/api/functions/useResolvedScope.md +46 -0
  263. package/docs/api/functions/useResourcePermissions.md +25 -0
  264. package/docs/api/functions/useRoleManagement.md +121 -0
  265. package/docs/api/functions/useSecureSupabase.md +51 -0
  266. package/docs/api/functions/useSessionRestoration.md +15 -0
  267. package/docs/api/functions/useSessionTracking.md +62 -0
  268. package/docs/api/functions/useToast.md +83 -0
  269. package/docs/api/functions/useUnifiedAuth.md +24 -0
  270. package/docs/api/functions/useZodForm.md +27 -0
  271. package/docs/api/functions/validateFileSize.md +31 -0
  272. package/docs/api/functions/warnIfInsecureClient.md +40 -0
  273. package/docs/api/functions/withAccessLevelGuard.md +67 -0
  274. package/docs/api/functions/withPermissionGuard.md +73 -0
  275. package/docs/api/functions/withRoleGuard.md +86 -0
  276. package/docs/api/globals.md +502 -0
  277. package/docs/api/interfaces/AccessDeniedProps.md +87 -0
  278. package/docs/api/interfaces/AccessibleApp.md +41 -0
  279. package/docs/api/interfaces/AddressFieldProps.md +195 -0
  280. package/docs/api/interfaces/AddressFieldRef.md +67 -0
  281. package/docs/api/interfaces/AggregateConfig.md +35 -0
  282. package/docs/api/interfaces/AppSwitcherProps.md +51 -0
  283. package/docs/api/interfaces/AuthSessionData.md +27 -0
  284. package/docs/api/interfaces/AutocompleteOptions.md +61 -0
  285. package/docs/api/interfaces/AvatarProps.md +97 -0
  286. package/docs/api/interfaces/BadgeProps.md +30 -0
  287. package/docs/api/interfaces/BuildAppUrlOptions.md +41 -0
  288. package/docs/api/interfaces/ButtonProps.md +46 -0
  289. package/docs/api/interfaces/CalendarProps.md +60 -0
  290. package/docs/api/interfaces/CardProps.md +56 -0
  291. package/docs/api/interfaces/ColorPalette.md +13 -0
  292. package/docs/api/interfaces/ColorShade.md +58 -0
  293. package/docs/api/interfaces/ContextSelectorProps.md +131 -0
  294. package/docs/api/interfaces/DataRecord.md +16 -0
  295. package/docs/api/interfaces/DataTableAction.md +198 -0
  296. package/docs/api/interfaces/DataTableColumn.md +422 -0
  297. package/docs/api/interfaces/DataTableProps.md +511 -0
  298. package/docs/api/interfaces/DataTableToolbarButton.md +75 -0
  299. package/docs/api/interfaces/DatePickerWithTimezoneProps.md +75 -0
  300. package/docs/api/interfaces/DialogBodyProps.md +55 -0
  301. package/docs/api/interfaces/DialogCloseProps.md +25 -0
  302. package/docs/api/interfaces/DialogContentProps.md +160 -0
  303. package/docs/api/interfaces/DialogFooterProps.md +25 -0
  304. package/docs/api/interfaces/DialogHeaderProps.md +25 -0
  305. package/docs/api/interfaces/DialogPortalProps.md +19 -0
  306. package/docs/api/interfaces/DialogProps.md +53 -0
  307. package/docs/api/interfaces/DialogTriggerProps.md +53 -0
  308. package/docs/api/interfaces/EmptyStateConfig.md +55 -0
  309. package/docs/api/interfaces/ErrorBoundaryProps.md +131 -0
  310. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +31 -0
  311. package/docs/api/interfaces/ErrorBoundaryState.md +61 -0
  312. package/docs/api/interfaces/EventAppRoleData.md +54 -0
  313. package/docs/api/interfaces/ExportColumn.md +69 -0
  314. package/docs/api/interfaces/ExportOptions.md +109 -0
  315. package/docs/api/interfaces/FileDisplayProps.md +192 -0
  316. package/docs/api/interfaces/FileMetadata.md +97 -0
  317. package/docs/api/interfaces/FileReference.md +89 -0
  318. package/docs/api/interfaces/FileSizeLimits.md +13 -0
  319. package/docs/api/interfaces/FileUploadOptions.md +107 -0
  320. package/docs/api/interfaces/FooterProps.md +37 -0
  321. package/docs/api/interfaces/FormFieldProps.md +171 -0
  322. package/docs/api/interfaces/FormProps.md +93 -0
  323. package/docs/api/interfaces/GrantEventAppRoleParams.md +97 -0
  324. package/docs/api/interfaces/ImportSummary.md +49 -0
  325. package/docs/api/interfaces/InactivityWarningModalProps.md +87 -0
  326. package/docs/api/interfaces/InputProps.md +46 -0
  327. package/docs/api/interfaces/InvalidScopeError.md +37 -0
  328. package/docs/api/interfaces/LabelProps.md +85 -0
  329. package/docs/api/interfaces/LoggerConfig.md +51 -0
  330. package/docs/api/interfaces/LoginFormProps.md +146 -0
  331. package/docs/api/interfaces/MissingUserContextError.md +37 -0
  332. package/docs/api/interfaces/NavigationGuardProps.md +109 -0
  333. package/docs/api/interfaces/NavigationItem.md +91 -0
  334. package/docs/api/interfaces/NavigationMenuProps.md +169 -0
  335. package/docs/api/interfaces/Organisation.md +105 -0
  336. package/docs/api/interfaces/OrganisationContextRequiredError.md +37 -0
  337. package/docs/api/interfaces/OrganisationMembership.md +105 -0
  338. package/docs/api/interfaces/OrganisationSecurityError.md +49 -0
  339. package/docs/api/interfaces/PaceAppLayoutPermissionConfig.md +127 -0
  340. package/docs/api/interfaces/PaceAppLayoutRouteConfigItem.md +91 -0
  341. package/docs/api/interfaces/PaceAppLayoutRoutingConfig.md +79 -0
  342. package/docs/api/interfaces/PaceLoginPageProps.md +41 -0
  343. package/docs/api/interfaces/PagePermissionGuardProps.md +143 -0
  344. package/docs/api/interfaces/PaletteData.md +33 -0
  345. package/docs/api/interfaces/ParsedAddress.md +91 -0
  346. package/docs/api/interfaces/PermissionDeniedError.md +37 -0
  347. package/docs/api/interfaces/ProgressProps.md +35 -0
  348. package/docs/api/interfaces/ProtectedRouteProps.md +67 -0
  349. package/docs/api/interfaces/PublicPageFooterProps.md +97 -0
  350. package/docs/api/interfaces/PublicPageHeaderProps.md +99 -0
  351. package/docs/api/interfaces/PublicPageLayoutProps.md +153 -0
  352. package/docs/api/interfaces/RBACAccessValidateParams.md +41 -0
  353. package/docs/api/interfaces/RBACAccessValidateResult.md +33 -0
  354. package/docs/api/interfaces/RBACAuditLogParams.md +65 -0
  355. package/docs/api/interfaces/RBACAuditLogResult.md +41 -0
  356. package/docs/api/interfaces/RBACContext.md +41 -0
  357. package/docs/api/interfaces/RBACError.md +37 -0
  358. package/docs/api/interfaces/RBACLogger.md +97 -0
  359. package/docs/api/interfaces/RBACNotInitializedError.md +37 -0
  360. package/docs/api/interfaces/RBACPageAccessCheckParams.md +57 -0
  361. package/docs/api/interfaces/RBACPerformanceMetrics.md +109 -0
  362. package/docs/api/interfaces/RBACPermissionCheckParams.md +57 -0
  363. package/docs/api/interfaces/RBACPermissionCheckResult.md +41 -0
  364. package/docs/api/interfaces/RBACPermissionsGetParams.md +49 -0
  365. package/docs/api/interfaces/RBACPermissionsGetResult.md +49 -0
  366. package/docs/api/interfaces/RBACResult.md +47 -0
  367. package/docs/api/interfaces/RBACRoleGrantParams.md +49 -0
  368. package/docs/api/interfaces/RBACRoleGrantResult.md +41 -0
  369. package/docs/api/interfaces/RBACRoleRevokeParams.md +49 -0
  370. package/docs/api/interfaces/RBACRoleRevokeResult.md +41 -0
  371. package/docs/api/interfaces/RBACRoleValidateParams.md +41 -0
  372. package/docs/api/interfaces/RBACRoleValidateResult.md +49 -0
  373. package/docs/api/interfaces/RBACRolesListParams.md +41 -0
  374. package/docs/api/interfaces/RBACRolesListResult.md +57 -0
  375. package/docs/api/interfaces/RBACSessionTrackParams.md +57 -0
  376. package/docs/api/interfaces/RBACSessionTrackResult.md +41 -0
  377. package/docs/api/interfaces/ResourcePermissions.md +119 -0
  378. package/docs/api/interfaces/RevokeEventAppRoleParams.md +81 -0
  379. package/docs/api/interfaces/RoleManagementResult.md +41 -0
  380. package/docs/api/interfaces/SessionRestorationLoaderProps.md +29 -0
  381. package/docs/api/interfaces/StorageConfig.md +33 -0
  382. package/docs/api/interfaces/StorageFileInfo.md +57 -0
  383. package/docs/api/interfaces/StorageFileMetadata.md +113 -0
  384. package/docs/api/interfaces/StorageListOptions.md +79 -0
  385. package/docs/api/interfaces/StorageListResult.md +33 -0
  386. package/docs/api/interfaces/StorageUploadOptions.md +81 -0
  387. package/docs/api/interfaces/StorageUploadResult.md +49 -0
  388. package/docs/api/interfaces/StorageUploadSuccess.md +35 -0
  389. package/docs/api/interfaces/StorageUrlOptions.md +49 -0
  390. package/docs/api/interfaces/StyleImport.md +17 -0
  391. package/docs/api/interfaces/SwitchProps.md +30 -0
  392. package/docs/api/interfaces/TabsContentProps.md +13 -0
  393. package/docs/api/interfaces/TabsListProps.md +13 -0
  394. package/docs/api/interfaces/TabsProps.md +13 -0
  395. package/docs/api/interfaces/TabsTriggerProps.md +41 -0
  396. package/docs/api/interfaces/TextareaProps.md +43 -0
  397. package/docs/api/interfaces/ToastActionElement.md +16 -0
  398. package/docs/api/interfaces/ToastProps.md +13 -0
  399. package/docs/api/interfaces/UnifiedAuthProviderProps.md +129 -0
  400. package/docs/api/interfaces/UseAccessibleAppsReturn.md +55 -0
  401. package/docs/api/interfaces/UseFormDialogOptions.md +49 -0
  402. package/docs/api/interfaces/UseFormDialogReturn.md +95 -0
  403. package/docs/api/interfaces/UseInactivityTrackerOptions.md +103 -0
  404. package/docs/api/interfaces/UseInactivityTrackerReturn.md +91 -0
  405. package/docs/api/interfaces/UsePublicEventLogoOptions.md +69 -0
  406. package/docs/api/interfaces/UsePublicEventLogoReturn.md +66 -0
  407. package/docs/api/interfaces/UsePublicEventOptions.md +29 -0
  408. package/docs/api/interfaces/UsePublicEventReturn.md +56 -0
  409. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +39 -0
  410. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +96 -0
  411. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +76 -0
  412. package/docs/api/interfaces/UseResolvedScopeOptions.md +49 -0
  413. package/docs/api/interfaces/UseResolvedScopeReturn.md +39 -0
  414. package/docs/api/interfaces/UseResourcePermissionsOptions.md +29 -0
  415. package/docs/api/interfaces/UserEventAccess.md +92 -0
  416. package/docs/api/interfaces/UserMenuProps.md +69 -0
  417. package/docs/api/interfaces/UserProfile.md +49 -0
  418. package/docs/api/type-aliases/AccessLevel.md +11 -0
  419. package/docs/api/type-aliases/AccessLevelContext.md +14 -0
  420. package/docs/api/type-aliases/AllPermissions.md +11 -0
  421. package/docs/api/type-aliases/ApiError.md +37 -0
  422. package/docs/api/type-aliases/ApiResult.md +19 -0
  423. package/docs/api/type-aliases/AuditEventType.md +11 -0
  424. package/docs/api/type-aliases/BadgeVariant.md +18 -0
  425. package/docs/api/type-aliases/DataTableFeatureConfig.md +14 -0
  426. package/docs/api/type-aliases/DialogSize.md +13 -0
  427. package/docs/api/type-aliases/EventAppRole.md +11 -0
  428. package/docs/api/type-aliases/FileUploadProps.md +15 -0
  429. package/docs/api/type-aliases/GetRowId.md +33 -0
  430. package/docs/api/type-aliases/GlobalErrorHandler.md +35 -0
  431. package/docs/api/type-aliases/GlobalRole.md +11 -0
  432. package/docs/api/type-aliases/ImportHandlerResult.md +13 -0
  433. package/docs/api/type-aliases/NavigationMode.md +13 -0
  434. package/docs/api/type-aliases/Operation.md +11 -0
  435. package/docs/api/type-aliases/OrganisationContextType.md +13 -0
  436. package/docs/api/type-aliases/OrganisationRole.md +11 -0
  437. package/docs/api/type-aliases/PaceAppLayoutProps.md +14 -0
  438. package/docs/api/type-aliases/Permission.md +11 -0
  439. package/docs/api/type-aliases/PermissionCheck.md +46 -0
  440. package/docs/api/type-aliases/PermissionMap.md +11 -0
  441. package/docs/api/type-aliases/PermissionSource.md +13 -0
  442. package/docs/api/type-aliases/RBACConfig.md +13 -0
  443. package/docs/api/type-aliases/RBACFunctionResponse.md +57 -0
  444. package/docs/api/type-aliases/Scope.md +41 -0
  445. package/docs/api/type-aliases/SessionType.md +11 -0
  446. package/docs/api/type-aliases/UUID.md +11 -0
  447. package/docs/api/type-aliases/UnifiedAuthContextType.md +13 -0
  448. package/docs/api/type-aliases/UseFileReferenceForRecordReturn.md +161 -0
  449. package/docs/api/type-aliases/UseFileReferenceOptions.md +35 -0
  450. package/docs/api/type-aliases/UseFileReferenceReturn.md +13 -0
  451. package/docs/api/variables/ALL_PERMISSIONS.md +281 -0
  452. package/docs/api/variables/APP_PATH_MAPPING.md +14 -0
  453. package/docs/api/variables/AddressField.md +41 -0
  454. package/docs/api/variables/Alert.md +11 -0
  455. package/docs/api/variables/AlertDescription.md +11 -0
  456. package/docs/api/variables/AlertTitle.md +11 -0
  457. package/docs/api/variables/Avatar.md +13 -0
  458. package/docs/api/variables/Button.md +31 -0
  459. package/docs/api/variables/CACHE_PATTERNS.md +89 -0
  460. package/docs/api/variables/Calendar.md +74 -0
  461. package/docs/api/variables/Card.md +11 -0
  462. package/docs/api/variables/CardActions.md +11 -0
  463. package/docs/api/variables/CardContent.md +11 -0
  464. package/docs/api/variables/CardDescription.md +11 -0
  465. package/docs/api/variables/CardFooter.md +11 -0
  466. package/docs/api/variables/CardHeader.md +11 -0
  467. package/docs/api/variables/CardTitle.md +11 -0
  468. package/docs/api/variables/Checkbox.md +11 -0
  469. package/docs/api/variables/DEFAULT_APP_PORT_MAP.md +14 -0
  470. package/docs/api/variables/DEFAULT_FILE_SIZE_LIMIT.md +13 -0
  471. package/docs/api/variables/Dialog.md +14 -0
  472. package/docs/api/variables/DialogClose.md +14 -0
  473. package/docs/api/variables/DialogContent.md +28 -0
  474. package/docs/api/variables/DialogDescription.md +14 -0
  475. package/docs/api/variables/DialogPortal.md +14 -0
  476. package/docs/api/variables/DialogTitle.md +14 -0
  477. package/docs/api/variables/DialogTrigger.md +14 -0
  478. package/docs/api/variables/EVENT_APP_PERMISSIONS.md +109 -0
  479. package/docs/api/variables/ErrorBoundary.md +15 -0
  480. package/docs/api/variables/FILE_SIZE_LIMITS.md +13 -0
  481. package/docs/api/variables/Footer.md +11 -0
  482. package/docs/api/variables/GLOBAL_PERMISSIONS.md +29 -0
  483. package/docs/api/variables/Label.md +34 -0
  484. package/docs/api/variables/LoadingSpinner.md +28 -0
  485. package/docs/api/variables/LoginForm.md +34 -0
  486. package/docs/api/variables/NavigationMenu.md +203 -0
  487. package/docs/api/variables/ORGANISATION_PERMISSIONS.md +89 -0
  488. package/docs/api/variables/PAGE_PERMISSIONS.md +93 -0
  489. package/docs/api/variables/PaceLoginPage.md +40 -0
  490. package/docs/api/variables/PagePermissionGuard.md +11 -0
  491. package/docs/api/variables/Progress.md +32 -0
  492. package/docs/api/variables/SECURE_CLIENT_SYMBOL.md +14 -0
  493. package/docs/api/variables/STORAGE_CONFIG.md +13 -0
  494. package/docs/api/variables/Select.md +26 -0
  495. package/docs/api/variables/SelectContent.md +26 -0
  496. package/docs/api/variables/SelectGroup.md +26 -0
  497. package/docs/api/variables/SelectItem.md +26 -0
  498. package/docs/api/variables/SelectLabel.md +26 -0
  499. package/docs/api/variables/SelectSeparator.md +26 -0
  500. package/docs/api/variables/SelectTrigger.md +26 -0
  501. package/docs/api/variables/SelectValue.md +26 -0
  502. package/docs/api/variables/SessionRestorationLoader.md +11 -0
  503. package/docs/api/variables/Switch.md +23 -0
  504. package/docs/api/variables/Table.md +35 -0
  505. package/docs/api/variables/TableBody.md +11 -0
  506. package/docs/api/variables/TableCaption.md +11 -0
  507. package/docs/api/variables/TableCell.md +11 -0
  508. package/docs/api/variables/TableFooter.md +11 -0
  509. package/docs/api/variables/TableHead.md +11 -0
  510. package/docs/api/variables/TableHeader.md +11 -0
  511. package/docs/api/variables/TableRow.md +11 -0
  512. package/docs/api/variables/Tabs.md +25 -0
  513. package/docs/api/variables/TabsContent.md +24 -0
  514. package/docs/api/variables/TabsList.md +25 -0
  515. package/docs/api/variables/TabsTrigger.md +34 -0
  516. package/docs/api/variables/Toast.md +36 -0
  517. package/docs/api/variables/ToastAction.md +32 -0
  518. package/docs/api/variables/ToastClose.md +32 -0
  519. package/docs/api/variables/ToastDescription.md +32 -0
  520. package/docs/api/variables/ToastProvider.md +11 -0
  521. package/docs/api/variables/ToastTitle.md +32 -0
  522. package/docs/api/variables/ToastViewport.md +26 -0
  523. package/docs/api/variables/Tooltip.md +34 -0
  524. package/docs/api/variables/TooltipContent.md +34 -0
  525. package/docs/api/variables/TooltipProvider.md +11 -0
  526. package/docs/api/variables/TooltipRoot.md +11 -0
  527. package/docs/api/variables/TooltipTrigger.md +11 -0
  528. package/docs/api/variables/UserMenu.md +11 -0
  529. package/docs/api/variables/emailSchema.md +13 -0
  530. package/docs/api/variables/logger.md +203 -0
  531. package/docs/api/variables/nameSchema.md +13 -0
  532. package/docs/api/variables/passwordSchema.md +13 -0
  533. package/docs/api/variables/phoneSchema.md +13 -0
  534. package/docs/api/variables/rbacCache.md +16 -0
  535. package/docs/api/variables/styleConfig.md +25 -0
  536. package/docs/api/variables/urlSchema.md +13 -0
  537. package/docs/api-reference/hooks.md +2 -0
  538. package/docs/api-reference/rpc-functions.md +12 -3
  539. package/docs/core-concepts/rbac-system.md +8 -0
  540. package/docs/getting-started/cursor-rules.md +17 -20
  541. package/docs/getting-started/dependencies.md +1 -1
  542. package/docs/getting-started/setup.md +235 -0
  543. package/docs/implementation-guides/authentication.md +27 -0
  544. package/docs/implementation-guides/data-tables.md +184 -3
  545. package/docs/migration/ApiResult-migration.md +25 -0
  546. package/docs/rbac/api-reference.md +33 -31
  547. package/docs/rbac/getting-started.md +7 -0
  548. package/docs/rbac/troubleshooting.md +5 -1
  549. package/docs/standards/0-standards-overview.md +50 -15
  550. package/docs/standards/1-pace-core-compliance-standards.md +62 -57
  551. package/docs/standards/2-project-structure-standards.md +33 -16
  552. package/docs/standards/3-architecture-standards.md +41 -1
  553. package/docs/standards/4-code-quality-standards.md +26 -6
  554. package/docs/standards/5-styling-standards.md +35 -1
  555. package/docs/standards/6-security-rbac-standards.md +66 -0
  556. package/docs/standards/7-api-tech-stack-standards.md +25 -14
  557. package/docs/standards/8-testing-documentation-standards.md +31 -0
  558. package/docs/standards/9-operations-standards.md +19 -0
  559. package/docs/standards/README.md +20 -201
  560. package/docs/testing/test-setup-for-consumers.md +2 -0
  561. package/docs/troubleshooting/common-issues.md +17 -1
  562. package/docs/troubleshooting/organisation-context-setup.md +8 -0
  563. package/docs/troubleshooting/print-event-name-css-variable-analysis.md +217 -0
  564. package/eslint-config-pace-core.cjs +20 -0
  565. package/package.json +16 -22
  566. package/scripts/build-docs.js +180 -0
  567. package/scripts/setup.cjs +536 -0
  568. package/scripts/validate.cjs +480 -0
  569. package/src/__tests__/helpers/component-test-utils.test.tsx +260 -0
  570. package/src/__tests__/helpers/optimized-test-setup.test.ts +224 -0
  571. package/src/__tests__/helpers/supabaseMock.test.ts +273 -0
  572. package/src/__tests__/helpers/test-providers.test.tsx +99 -0
  573. package/src/__tests__/helpers/test-providers.tsx +37 -39
  574. package/src/__tests__/helpers/test-utils.test.tsx +447 -0
  575. package/src/__tests__/helpers/timer-utils.test.ts +371 -0
  576. package/src/assets/app-icons/index.test.ts +304 -0
  577. package/src/components/AddressField/AddressField.test.tsx +1 -1
  578. package/src/components/AddressField/AddressField.tsx +238 -212
  579. package/src/components/Button/Button.tsx +1 -1
  580. package/src/components/Card/Card.test.tsx +172 -17
  581. package/src/components/Card/Card.tsx +19 -10
  582. package/src/components/ContextSelector/ContextSelector.internals.tsx +204 -0
  583. package/src/components/ContextSelector/ContextSelector.test.tsx +360 -0
  584. package/src/components/ContextSelector/ContextSelector.tsx +66 -280
  585. package/src/components/ContextSelector/ContextSelector.types.ts +35 -0
  586. package/src/components/ContextSelector/useContextSelectorState.tsx +195 -0
  587. package/src/components/DataTable/AUDIT_REPORT.md +59 -44
  588. package/src/components/DataTable/DataTable.comprehensive.test.tsx +759 -0
  589. package/src/components/DataTable/DataTable.default-state.test.tsx +524 -0
  590. package/src/components/DataTable/DataTable.export.test.tsx +705 -0
  591. package/src/components/DataTable/DataTable.grouping-aggregation.test.tsx +658 -0
  592. package/src/components/DataTable/DataTable.hooks.test.tsx +192 -0
  593. package/src/components/DataTable/DataTable.select-label-display.test.tsx +485 -0
  594. package/src/components/DataTable/DataTable.test.tsx +787 -416
  595. package/src/components/DataTable/DataTable.tsx +12 -12
  596. package/src/components/DataTable/DataTableCore.integration.test.tsx +458 -0
  597. package/src/components/DataTable/DataTableCore.test-setup.ts +221 -0
  598. package/src/components/DataTable/DataTableCore.test.tsx +970 -0
  599. package/src/components/DataTable/README.md +155 -0
  600. package/src/components/DataTable/TESTING.md +101 -0
  601. package/src/components/DataTable/a11y.basic.test.tsx +788 -0
  602. package/src/components/DataTable/components/DataTableCore.tsx +104 -864
  603. package/src/components/DataTable/components/GroupingDropdown.test.tsx +621 -0
  604. package/src/components/DataTable/components/GroupingDropdown.tsx +2 -2
  605. package/src/components/DataTable/components/ImportModal.tsx +61 -559
  606. package/src/components/DataTable/components/ImportModalFileSection.tsx +148 -0
  607. package/src/components/DataTable/context/DataTableContext.test.tsx +328 -0
  608. package/src/components/DataTable/context/DataTableContext.tsx +7 -6
  609. package/src/components/DataTable/core/ColumnFactory.test.ts +403 -0
  610. package/src/components/DataTable/hooks/useColumnOrderPersistence.test.ts +516 -0
  611. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.test.ts +256 -0
  612. package/src/components/DataTable/hooks/useDataTableConfiguration.test.ts +297 -0
  613. package/src/components/DataTable/hooks/useDataTableConfiguration.ts +14 -2
  614. package/src/components/DataTable/hooks/useDataTableDataPipeline.test.ts +270 -0
  615. package/src/components/DataTable/hooks/useDataTableDeletionBatching.test.ts +127 -0
  616. package/src/components/DataTable/hooks/useDataTableDeletionBatching.ts +106 -0
  617. package/src/components/DataTable/hooks/useDataTableEffectiveActions.test.ts +461 -0
  618. package/src/components/DataTable/hooks/useDataTableEffectiveActions.ts +248 -0
  619. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.test.ts +296 -0
  620. package/src/components/DataTable/hooks/useDataTableLayoutHandlers.ts +175 -0
  621. package/src/components/DataTable/hooks/useDataTablePaginationSync.test.ts +203 -0
  622. package/src/components/DataTable/hooks/useDataTablePaginationSync.ts +109 -0
  623. package/src/components/DataTable/hooks/useDataTablePermissions.test.ts +280 -0
  624. package/src/components/DataTable/hooks/useDataTablePermissions.ts +79 -247
  625. package/src/components/DataTable/hooks/useDataTablePipeline.test.tsx +219 -0
  626. package/src/components/DataTable/hooks/useDataTablePipeline.tsx +239 -0
  627. package/src/components/DataTable/hooks/useDataTableRenderGuard.test.tsx +316 -0
  628. package/src/components/DataTable/hooks/useDataTableRenderGuard.tsx +195 -0
  629. package/src/components/DataTable/hooks/useDataTableScope.test.ts +102 -0
  630. package/src/components/DataTable/hooks/useDataTableScope.ts +125 -0
  631. package/src/components/DataTable/hooks/useDataTableState.test.ts +733 -0
  632. package/src/components/DataTable/hooks/useDataTableState.ts +145 -94
  633. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.test.ts +277 -0
  634. package/src/components/DataTable/hooks/useDataTableStateAndPersistence.ts +222 -0
  635. package/src/components/DataTable/hooks/useDataTableSuperAdmin.test.ts +93 -0
  636. package/src/components/DataTable/hooks/useDataTableSuperAdmin.ts +86 -0
  637. package/src/components/DataTable/hooks/useDataTableTableInstance.test.ts +185 -0
  638. package/src/components/DataTable/hooks/useDataTableTableInstance.ts +178 -0
  639. package/src/components/DataTable/hooks/useEffectiveColumnOrder.test.ts +183 -0
  640. package/src/components/DataTable/hooks/useHierarchicalState.test.ts +294 -0
  641. package/src/components/DataTable/hooks/useImportModalFocus.test.ts +184 -0
  642. package/src/components/DataTable/hooks/useImportModalFocus.ts +53 -0
  643. package/src/components/DataTable/hooks/useImportModalState.test.ts +390 -0
  644. package/src/components/DataTable/hooks/useImportModalState.ts +345 -0
  645. package/src/components/DataTable/hooks/useKeyboardNavigation.test.ts +787 -0
  646. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +309 -269
  647. package/src/components/DataTable/hooks/usePermissionTracking.test.ts +381 -0
  648. package/src/components/DataTable/hooks/usePermissionTracking.ts +122 -0
  649. package/src/components/DataTable/hooks/useServerSideDataEffect.test.ts +258 -0
  650. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +14 -3
  651. package/src/components/DataTable/hooks/useTableColumns.test.ts +499 -0
  652. package/src/components/DataTable/hooks/useTableHandlers.test.ts +461 -0
  653. package/src/components/DataTable/hooks/useTableHandlers.ts +5 -2
  654. package/src/components/DataTable/index.ts +18 -17
  655. package/src/components/DataTable/keyboard.test.tsx +734 -0
  656. package/src/components/DataTable/mocks/MockRBACProvider.tsx +66 -0
  657. package/src/components/DataTable/pagination.modes.test.tsx +728 -0
  658. package/src/components/DataTable/ssr.strict-mode.test.tsx +319 -0
  659. package/src/components/DataTable/styles.test.ts +379 -0
  660. package/src/components/DataTable/styles.ts +0 -1
  661. package/src/components/DataTable/test-utils/MockDataTableComponents.tsx +55 -0
  662. package/src/components/DataTable/test-utils/dataFactories.ts +103 -0
  663. package/src/components/DataTable/test-utils/featureConfig.ts +10 -0
  664. package/src/components/DataTable/test-utils/sharedTestUtils.ts +419 -0
  665. package/src/components/DataTable/test-utils.ts +94 -0
  666. package/src/components/DataTable/types/actions.ts +71 -0
  667. package/src/components/DataTable/types/base.ts +39 -0
  668. package/src/components/DataTable/types/columns.ts +125 -0
  669. package/src/components/DataTable/types/export.ts +32 -0
  670. package/src/components/DataTable/types/features.ts +81 -0
  671. package/src/components/DataTable/types/hierarchical.ts +44 -0
  672. package/src/components/DataTable/types/index.ts +43 -0
  673. package/src/components/DataTable/types/pagination.ts +85 -0
  674. package/src/components/DataTable/types/performance.ts +47 -0
  675. package/src/components/DataTable/types/props.ts +62 -0
  676. package/src/components/DataTable/types/rbac.ts +45 -0
  677. package/src/components/DataTable/ui/layout/DataTableCore.test.tsx +1194 -0
  678. package/src/components/DataTable/ui/layout/DataTableCore.tsx +345 -0
  679. package/src/components/DataTable/ui/layout/DataTableErrorBoundary.test.tsx +438 -0
  680. package/src/components/DataTable/ui/layout/DataTableErrorBoundary.tsx +225 -0
  681. package/src/components/DataTable/ui/layout/DataTableLayout.test.tsx +1352 -0
  682. package/src/components/DataTable/ui/layout/DataTableLayout.tsx +661 -0
  683. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.test.tsx +91 -0
  684. package/src/components/DataTable/ui/modals/BulkDeleteConfirmDialog.tsx +43 -0
  685. package/src/components/DataTable/ui/modals/DataTableModals.test.tsx +749 -0
  686. package/src/components/DataTable/ui/modals/DataTableModals.tsx +341 -0
  687. package/src/components/DataTable/ui/modals/ImportModal.test.tsx +1834 -0
  688. package/src/components/DataTable/ui/modals/ImportModal.tsx +197 -0
  689. package/src/components/DataTable/ui/modals/ImportModalFailedRowsSection.tsx +60 -0
  690. package/src/components/DataTable/ui/modals/ImportModalFileSection.tsx +148 -0
  691. package/src/components/DataTable/ui/modals/ImportModalPreviewSection.tsx +60 -0
  692. package/src/components/DataTable/ui/modals/ImportModalSummarySection.tsx +59 -0
  693. package/src/components/DataTable/ui/modals/importModalPersistence.ts +73 -0
  694. package/src/components/DataTable/ui/shared/AccessDeniedPage.test.tsx +245 -0
  695. package/src/components/DataTable/ui/shared/AccessDeniedPage.tsx +159 -0
  696. package/src/components/DataTable/ui/shared/ActionButtons.test.tsx +921 -0
  697. package/src/components/DataTable/ui/shared/ActionButtons.tsx +195 -0
  698. package/src/components/DataTable/ui/shared/ColumnFilter.test.tsx +497 -0
  699. package/src/components/DataTable/ui/shared/ColumnFilter.tsx +113 -0
  700. package/src/components/DataTable/ui/shared/PaginationControls.test.tsx +451 -0
  701. package/src/components/DataTable/ui/shared/PaginationControls.tsx +291 -0
  702. package/src/components/DataTable/ui/shared/SortIndicator.test.tsx +135 -0
  703. package/src/components/DataTable/ui/shared/SortIndicator.tsx +50 -0
  704. package/src/components/DataTable/ui/table/EditFields.test.tsx +526 -0
  705. package/src/components/DataTable/ui/table/EditFields.tsx +355 -0
  706. package/src/components/DataTable/ui/table/EditableRow.test.tsx +1003 -0
  707. package/src/components/DataTable/ui/table/EditableRow.tsx +444 -0
  708. package/src/components/DataTable/ui/table/EmptyState.test.tsx +360 -0
  709. package/src/components/DataTable/ui/table/EmptyState.tsx +74 -0
  710. package/src/components/DataTable/ui/table/FilterRow.test.tsx +416 -0
  711. package/src/components/DataTable/ui/table/FilterRow.tsx +148 -0
  712. package/src/components/DataTable/ui/table/LoadingState.test.tsx +77 -0
  713. package/src/components/DataTable/ui/table/LoadingState.tsx +17 -0
  714. package/src/components/DataTable/ui/table/RowComponent.test.tsx +1024 -0
  715. package/src/components/DataTable/ui/table/RowComponent.tsx +429 -0
  716. package/src/components/DataTable/ui/table/UnifiedTableBody.test.tsx +1273 -0
  717. package/src/components/DataTable/ui/table/UnifiedTableBody.tsx +440 -0
  718. package/src/components/DataTable/ui/table/cellValueUtils.test.ts +453 -0
  719. package/src/components/DataTable/ui/table/cellValueUtils.ts +40 -0
  720. package/src/components/DataTable/ui/toolbar/BulkOperationsDropdown.test.tsx +551 -0
  721. package/src/components/DataTable/ui/toolbar/BulkOperationsDropdown.tsx +160 -0
  722. package/src/components/DataTable/ui/toolbar/ColumnVisibilityDropdown.test.tsx +751 -0
  723. package/src/components/DataTable/ui/toolbar/ColumnVisibilityDropdown.tsx +114 -0
  724. package/src/components/DataTable/ui/toolbar/DataTableToolbar.test.tsx +629 -0
  725. package/src/components/DataTable/ui/toolbar/DataTableToolbar.tsx +271 -0
  726. package/src/components/DataTable/ui/toolbar/GroupingDropdown.test.tsx +621 -0
  727. package/src/components/DataTable/ui/toolbar/GroupingDropdown.tsx +107 -0
  728. package/src/components/DataTable/utils/a11yUtils.test.ts +548 -0
  729. package/src/components/DataTable/utils/aggregationUtils.test.ts +288 -0
  730. package/src/components/DataTable/utils/columnUtils.test.ts +94 -0
  731. package/src/components/DataTable/utils/csvParse.test.ts +74 -0
  732. package/src/components/DataTable/utils/csvParse.ts +65 -0
  733. package/src/components/DataTable/utils/errorHandling.test.ts +209 -0
  734. package/src/components/DataTable/utils/exportUtils.test.ts +954 -0
  735. package/src/components/DataTable/utils/flexibleImport.test.ts +573 -0
  736. package/src/components/DataTable/utils/flexibleImport.ts +3 -186
  737. package/src/components/DataTable/utils/hierarchicalSorting.test.ts +235 -0
  738. package/src/components/DataTable/utils/hierarchicalUtils.test.ts +586 -0
  739. package/src/components/DataTable/utils/importDateParser.test.ts +162 -0
  740. package/src/components/DataTable/utils/importDateParser.ts +114 -0
  741. package/src/components/DataTable/utils/importValueParser.test.ts +138 -0
  742. package/src/components/DataTable/utils/importValueParser.ts +91 -0
  743. package/src/components/DataTable/utils/paginationUtils.test.ts +593 -0
  744. package/src/components/DataTable/utils/paginationUtils.ts +6 -3
  745. package/src/components/DataTable/utils/performanceUtils.test.ts +470 -0
  746. package/src/components/DataTable/utils/rowUtils.test.ts +235 -0
  747. package/src/components/DataTable/utils/selectFieldUtils.test.ts +271 -0
  748. package/src/components/DataTable/utils/selectFieldUtils.ts +97 -60
  749. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +1 -1
  750. package/src/components/DateTimeField/DateTimeField.test.tsx +1 -1
  751. package/src/components/Dialog/Dialog.test-utils.ts +49 -0
  752. package/src/components/Dialog/Dialog.test.tsx +896 -89
  753. package/src/components/Dialog/Dialog.tsx +174 -882
  754. package/src/components/Dialog/dialogLock.test.ts +238 -0
  755. package/src/components/Dialog/dialogLock.ts +98 -0
  756. package/src/components/Dialog/index.ts +2 -0
  757. package/src/components/Dialog/useDialogDimensions.test.ts +163 -0
  758. package/src/components/Dialog/useDialogDimensions.ts +140 -0
  759. package/src/components/Dialog/useDialogLifecycle.test.ts +361 -0
  760. package/src/components/Dialog/useDialogLifecycle.ts +135 -0
  761. package/src/components/Dialog/useDialogPersistence.test.ts +381 -0
  762. package/src/components/Dialog/useDialogPersistence.ts +357 -0
  763. package/src/components/FileDisplay/FileDisplay.test.tsx +40 -40
  764. package/src/components/FileDisplay/FileDisplay.tsx +24 -656
  765. package/src/components/FileDisplay/FileDisplayContent.test.tsx +395 -0
  766. package/src/components/FileDisplay/FileDisplayContent.tsx +242 -0
  767. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.test.tsx +74 -0
  768. package/src/components/FileDisplay/FileDisplayDeleteConfirmDialog.tsx +38 -0
  769. package/src/components/FileDisplay/FileDisplayEmptyView.test.tsx +33 -0
  770. package/src/components/FileDisplay/FileDisplayEmptyView.tsx +33 -0
  771. package/src/components/FileDisplay/FileDisplayErrorView.test.tsx +71 -0
  772. package/src/components/FileDisplay/FileDisplayErrorView.tsx +50 -0
  773. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.test.tsx +22 -0
  774. package/src/components/FileDisplay/FileDisplayLoadingFallbackView.tsx +22 -0
  775. package/src/components/FileDisplay/FileDisplayLoadingView.test.tsx +21 -0
  776. package/src/components/FileDisplay/FileDisplayLoadingView.tsx +23 -0
  777. package/src/components/FileDisplay/FileDisplayMultipleFilesView.test.tsx +101 -0
  778. package/src/components/FileDisplay/FileDisplayMultipleFilesView.tsx +109 -0
  779. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.test.tsx +58 -0
  780. package/src/components/FileDisplay/FileDisplaySingleDocumentLinkView.tsx +48 -0
  781. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.test.tsx +111 -0
  782. package/src/components/FileDisplay/FileDisplaySingleFileWithActionsView.tsx +270 -0
  783. package/src/components/FileDisplay/FileDisplaySingleImageView.test.tsx +78 -0
  784. package/src/components/FileDisplay/FileDisplaySingleImageView.tsx +67 -0
  785. package/src/components/FileDisplay/fallbackUtils.test.ts +50 -0
  786. package/src/components/FileDisplay/fallbackUtils.ts +44 -0
  787. package/src/components/FileDisplay/fetchFileDisplayData.ts +24 -0
  788. package/src/components/FileDisplay/fetchFileDisplayData.unit.test.ts +183 -0
  789. package/src/components/FileDisplay/fileDisplayUtils.test.ts +58 -0
  790. package/src/components/FileDisplay/fileDisplayUtils.ts +24 -0
  791. package/src/components/FileDisplay/useFileDisplay.test.ts +538 -0
  792. package/src/components/FileDisplay/useFileDisplay.ts +515 -0
  793. package/src/components/FileDisplay/useFileDisplay.unit.test.ts +1442 -0
  794. package/src/components/FileDisplay/useFileDisplayData.ts +126 -0
  795. package/src/components/FileDisplay/usePublicFileDisplay.test.ts +729 -0
  796. package/src/components/FileDisplay/usePublicFileDisplay.ts +579 -0
  797. package/src/components/FileUpload/FileUpload.test.tsx +16 -10
  798. package/src/components/FileUpload/FileUpload.tsx +107 -525
  799. package/src/components/FileUpload/FileUploadDropZone.tsx +112 -0
  800. package/src/components/FileUpload/FileUploadProgressItem.tsx +86 -0
  801. package/src/components/FileUpload/FileUploadProgressList.tsx +40 -0
  802. package/src/components/FileUpload/useFileUploadManager.test.ts +308 -0
  803. package/src/components/FileUpload/useFileUploadManager.ts +454 -0
  804. package/src/components/FileUpload/useResolvedAppId.test.ts +102 -0
  805. package/src/components/FileUpload/useResolvedAppId.ts +77 -0
  806. package/src/components/Footer/Footer.test.tsx +6 -292
  807. package/src/components/Footer/Footer.tsx +8 -125
  808. package/src/components/Form/Form.test.tsx +44 -27
  809. package/src/components/Form/Form.tsx +64 -287
  810. package/src/components/Form/useFormPersistence.ts +257 -0
  811. package/src/components/Header/Header.test.tsx +17 -18
  812. package/src/components/Header/Header.tsx +10 -1
  813. package/src/components/Input/Input.tsx +1 -1
  814. package/src/components/Label/Label.test.tsx +1 -1
  815. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +1 -1
  816. package/src/components/NavigationMenu/HierarchicalNavItem.tsx +104 -0
  817. package/src/components/NavigationMenu/NavigationMenu.test.tsx +1029 -26
  818. package/src/components/NavigationMenu/NavigationMenu.tsx +61 -361
  819. package/src/components/NavigationMenu/index.ts +6 -1
  820. package/src/components/NavigationMenu/navigationPermissionHelper.ts +188 -0
  821. package/src/components/NavigationMenu/useNavigationFiltering.test.ts +1949 -0
  822. package/src/components/NavigationMenu/useNavigationFiltering.ts +197 -296
  823. package/src/components/NavigationMenu/useNavigationScope.ts +125 -0
  824. package/src/components/PaceAppLayout/PaceAppLayout.edge-cases.test.tsx +109 -70
  825. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +3 -3
  826. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +16 -19
  827. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +529 -5
  828. package/src/components/PaceAppLayout/PaceAppLayout.tsx +280 -756
  829. package/src/components/PaceAppLayout/useFilteredNavItems.ts +319 -0
  830. package/src/components/PaceAppLayout/usePaceAppLayoutConfig.ts +163 -0
  831. package/src/components/PaceAppLayout/usePaceAppLayoutGate.tsx +150 -0
  832. package/src/components/PaceAppLayout/usePaceAppLayoutPermissions.ts +162 -0
  833. package/src/components/PaceAppLayout/usePaceAppLayoutScope.ts +81 -0
  834. package/src/components/PaceAppLayout/useRoleBasedRouteAccess.ts +157 -0
  835. package/src/components/PaceAppLayout/useSuperAdminFallback.ts +58 -0
  836. package/src/components/PaceLoginPage/PaceLoginPage.test.tsx +31 -25
  837. package/src/components/PaceLoginPage/PaceLoginPage.tsx +31 -122
  838. package/src/components/PaceLoginPage/useLoginAppAccess.ts +153 -0
  839. package/src/components/Progress/Progress.tsx +1 -2
  840. package/src/components/ProtectedRoute/ProtectedRoute.tsx +29 -235
  841. package/src/components/ProtectedRoute/useProtectedRouteState.ts +128 -0
  842. package/src/components/ProtectedRoute/useVisibilityRedirectGrace.ts +89 -0
  843. package/src/components/PublicLayout/PublicLayout.test.tsx +217 -36
  844. package/src/components/PublicLayout/PublicPageLayout.tsx +132 -73
  845. package/src/components/PublicLayout/PublicPageProvider.tsx +5 -1
  846. package/src/components/Select/Select.test.tsx +1 -1
  847. package/src/components/Select/Select.tsx +28 -18
  848. package/src/components/Select/context.test.tsx +56 -0
  849. package/src/components/Select/text.test.tsx +104 -0
  850. package/src/components/Select/text.ts +26 -0
  851. package/src/components/Select/useSelectEvents.test.ts +279 -0
  852. package/src/components/Select/useSelectEvents.ts +87 -0
  853. package/src/components/Select/useSelectSearch.test.tsx +295 -0
  854. package/src/components/Select/useSelectSearch.ts +91 -0
  855. package/src/components/Select/useSelectState.test.ts +268 -0
  856. package/src/components/Select/useSelectState.ts +104 -0
  857. package/src/components/Table/Table.test.tsx +348 -0
  858. package/src/components/Tabs/Tabs.test.tsx +270 -0
  859. package/src/components/Tabs/Tabs.tsx +1 -1
  860. package/src/components/Toast/Toast.test.tsx +420 -0
  861. package/src/components/index.test.ts +346 -0
  862. package/src/constants/performance.test.ts +91 -0
  863. package/src/hooks/ServiceHooks.test.tsx +725 -0
  864. package/src/hooks/hooks.integration.test.tsx +608 -0
  865. package/src/hooks/index.ts +7 -4
  866. package/src/hooks/index.unit.test.ts +220 -0
  867. package/src/hooks/public/usePublicEvent.test.ts +1 -1
  868. package/src/hooks/public/usePublicEventLogo.test.ts +1 -1
  869. package/src/hooks/public/usePublicRouteParams.test.ts +1 -1
  870. package/src/hooks/services/useAuth.ts +9 -7
  871. package/src/hooks/useAddressAutocomplete.test.ts +22 -22
  872. package/src/hooks/useAddressAutocomplete.ts +90 -75
  873. package/src/hooks/useAppConfig.unit.test.ts +720 -0
  874. package/src/hooks/useComponentPerformance.unit.test.tsx +316 -0
  875. package/src/hooks/useDataTablePerformance.ts +100 -120
  876. package/src/hooks/useDataTablePerformance.unit.test.ts +720 -0
  877. package/src/hooks/useDataTableState.test.ts +170 -0
  878. package/src/hooks/useDebounce.unit.test.ts +157 -0
  879. package/src/hooks/useEventTheme.test.ts +4 -1
  880. package/src/hooks/useEventTheme.ts +49 -21
  881. package/src/hooks/useEvents.ts +41 -1
  882. package/src/hooks/useEvents.unit.test.ts +227 -0
  883. package/src/hooks/useFileReference.test.ts +44 -41
  884. package/src/hooks/useFileReference.ts +182 -173
  885. package/src/hooks/useFileUrl.ts +1 -1
  886. package/src/hooks/useFileUrl.unit.test.ts +684 -0
  887. package/src/hooks/useFileUrlCache.test.ts +319 -0
  888. package/src/hooks/useFileUrlCache.ts +1 -1
  889. package/src/hooks/useFocusManagement.unit.test.ts +604 -0
  890. package/src/hooks/useFocusTrap.unit.test.tsx +613 -0
  891. package/src/hooks/useFormDialog.test.ts +307 -0
  892. package/src/hooks/useInactivityTracker.ts +138 -131
  893. package/src/hooks/useInactivityTracker.unit.test.ts +450 -0
  894. package/src/hooks/useIsMobile.unit.test.ts +317 -0
  895. package/src/hooks/useIsPrint.ts +62 -0
  896. package/src/hooks/useIsPrint.unit.test.ts +545 -0
  897. package/src/hooks/useKeyboardShortcuts.unit.test.ts +907 -0
  898. package/src/hooks/useOrganisationPermissions.unit.test.tsx +293 -0
  899. package/src/hooks/useOrganisationSecurity.test.ts +3 -3
  900. package/src/hooks/useOrganisationSecurity.ts +190 -201
  901. package/src/hooks/useOrganisationSecurity.unit.test.tsx +959 -0
  902. package/src/hooks/useOrganisations.unit.test.ts +369 -0
  903. package/src/hooks/usePerformanceMonitor.unit.test.ts +683 -0
  904. package/src/hooks/usePermissionCache.test.ts +505 -0
  905. package/src/hooks/usePermissionCache.ts +276 -271
  906. package/src/hooks/usePreventTabReload.test.ts +307 -0
  907. package/src/hooks/usePublicEvent.simple.test.ts +779 -0
  908. package/src/hooks/usePublicEvent.test.ts +664 -0
  909. package/src/hooks/usePublicEvent.unit.test.ts +638 -0
  910. package/src/hooks/usePublicFileDisplay.test.ts +948 -0
  911. package/src/hooks/usePublicRouteParams.unit.test.ts +442 -0
  912. package/src/hooks/useQueryCache.test.ts +391 -0
  913. package/src/hooks/useQueryCache.ts +0 -2
  914. package/src/hooks/useRBAC.unit.test.ts +253 -0
  915. package/src/hooks/useSessionDraft.test.ts +556 -0
  916. package/src/hooks/useSessionRestoration.unit.test.tsx +381 -0
  917. package/src/hooks/useStorage.ts +21 -16
  918. package/src/hooks/useStorage.unit.test.ts +684 -0
  919. package/src/hooks/useToast.test.ts +413 -0
  920. package/src/hooks/useToast.unit.test.tsx +481 -0
  921. package/src/hooks/useZodForm.unit.test.tsx +191 -0
  922. package/src/icons/index.test.ts +133 -0
  923. package/src/icons/index.ts +2 -0
  924. package/src/index.test.ts +528 -0
  925. package/src/index.ts +15 -7
  926. package/src/providers/AuthProvider.test.tsx +218 -0
  927. package/src/providers/EventProvider.test.tsx +487 -0
  928. package/src/providers/InactivityProvider.test-helper.tsx +40 -0
  929. package/src/providers/InactivityProvider.test.tsx +421 -0
  930. package/src/providers/ProviderLifecycle.test.tsx +308 -0
  931. package/src/providers/UnifiedAuthProvider.test.tsx +503 -0
  932. package/src/providers/index.test.ts +138 -0
  933. package/src/providers/services/AuthServiceProvider.integration.test.tsx +229 -0
  934. package/src/providers/services/AuthServiceProvider.test.tsx +643 -0
  935. package/src/providers/services/EventServiceProvider.test.tsx +844 -0
  936. package/src/providers/services/InactivityServiceProvider.test.tsx +667 -0
  937. package/src/providers/services/OrganisationServiceProvider.test.tsx +445 -0
  938. package/src/providers/services/UnifiedAuthContext.ts +30 -27
  939. package/src/providers/services/UnifiedAuthProvider.advanced.test.tsx +434 -0
  940. package/src/providers/services/UnifiedAuthProvider.appId.test.tsx +408 -0
  941. package/src/providers/services/UnifiedAuthProvider.integration.test.tsx +304 -0
  942. package/src/providers/services/UnifiedAuthProvider.tsx +115 -360
  943. package/src/providers/services/contexts.test.tsx +281 -0
  944. package/src/providers/services/useUnifiedAuth.test.tsx +251 -0
  945. package/src/providers/services/useUnifiedAuthContextValue.ts +279 -0
  946. package/src/providers/useInactivity.test-helper.ts +27 -0
  947. package/src/rbac/README.md +7 -5
  948. package/src/rbac/adapters.comprehensive.test.tsx +429 -0
  949. package/src/rbac/adapters.test.tsx +22 -22
  950. package/src/rbac/adapters.tsx +29 -29
  951. package/src/rbac/api.test.ts +1075 -87
  952. package/src/rbac/api.ts +300 -255
  953. package/src/rbac/audit-batched.test.ts +550 -0
  954. package/src/rbac/audit.ts +4 -1
  955. package/src/rbac/auth-rbac-security.integration.test.tsx +300 -0
  956. package/src/rbac/auth-rbac.e2e.test.tsx +510 -0
  957. package/src/rbac/cache-invalidation.test.ts +715 -0
  958. package/src/rbac/components/AccessDenied.test.tsx +324 -0
  959. package/src/rbac/components/NavigationGuard.test.tsx +1148 -0
  960. package/src/rbac/components/NavigationGuard.tsx +2 -1
  961. package/src/rbac/components/PagePermissionGuard.guard.test.tsx +236 -0
  962. package/src/rbac/components/PagePermissionGuard.performance.test.tsx +252 -0
  963. package/src/rbac/components/PagePermissionGuard.race-condition.test.tsx +243 -0
  964. package/src/rbac/components/PagePermissionGuard.test.tsx +1443 -0
  965. package/src/rbac/components/PagePermissionGuard.tsx +177 -372
  966. package/src/rbac/components/PagePermissionGuard.verification.test.tsx +185 -0
  967. package/src/rbac/config.ts +58 -18
  968. package/src/rbac/engine.comprehensive.test.ts +808 -0
  969. package/src/rbac/engine.test.ts +494 -0
  970. package/src/rbac/engine.ts +23 -1
  971. package/src/rbac/errors.ts +89 -55
  972. package/src/rbac/hooks/permissions/runPermissionCheck.ts +91 -0
  973. package/src/rbac/hooks/permissions/useAccessLevel.test.ts +622 -0
  974. package/src/rbac/hooks/permissions/useAccessLevel.ts +16 -6
  975. package/src/rbac/hooks/permissions/useCan.test.ts +837 -0
  976. package/src/rbac/hooks/permissions/useCan.ts +177 -255
  977. package/src/rbac/hooks/permissions/useMultiplePermissions.test.ts +843 -0
  978. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +24 -11
  979. package/src/rbac/hooks/permissions/usePermissions.test.ts +543 -0
  980. package/src/rbac/hooks/permissions/usePermissions.ts +36 -65
  981. package/src/rbac/hooks/useCan.test.ts +44 -45
  982. package/src/rbac/hooks/usePageAccessLogging.ts +160 -0
  983. package/src/rbac/hooks/usePageGuardScope.ts +119 -0
  984. package/src/rbac/hooks/usePagePermissionCheck.ts +67 -0
  985. package/src/rbac/hooks/usePermissions.integration.test.ts +427 -0
  986. package/src/rbac/hooks/usePermissions.stability.test.ts +268 -0
  987. package/src/rbac/hooks/usePermissions.test.ts +54 -54
  988. package/src/rbac/hooks/useRBAC.test.ts +313 -217
  989. package/src/rbac/hooks/useRBAC.ts +145 -81
  990. package/src/rbac/hooks/useResolvedScope.ts +16 -10
  991. package/src/rbac/hooks/useResourcePermissions.test.ts +73 -83
  992. package/src/rbac/hooks/useResourcePermissions.ts +77 -152
  993. package/src/rbac/hooks/useResourcePermissionsSuperAdmin.ts +67 -0
  994. package/src/rbac/hooks/useRoleManagement.test.ts +27 -112
  995. package/src/rbac/hooks/useRoleManagement.ts +153 -585
  996. package/src/rbac/hooks/useSecureSupabase.test.ts +1179 -0
  997. package/src/rbac/hooks/useSecureSupabase.ts +10 -2
  998. package/src/rbac/hooks/useSuperAdminCheck.ts +80 -0
  999. package/src/rbac/performance.test.ts +451 -0
  1000. package/src/rbac/rbac-core.test.tsx +276 -0
  1001. package/src/rbac/rbac-engine-core-logic.test.ts +387 -0
  1002. package/src/rbac/rbac-engine-simplified.test.ts +252 -0
  1003. package/src/rbac/rbac-functions.test.ts +703 -0
  1004. package/src/rbac/rbac-role-isolation.test.ts +456 -0
  1005. package/src/rbac/request-deduplication.test.ts +14 -9
  1006. package/src/rbac/request-deduplication.ts +5 -4
  1007. package/src/rbac/scenarios.user-role.test.tsx +271 -0
  1008. package/src/rbac/secureClient.test.ts +514 -83
  1009. package/src/rbac/secureClient.ts +8 -2
  1010. package/src/rbac/security.test.ts +323 -0
  1011. package/src/rbac/types/roleManagement.ts +66 -0
  1012. package/src/rbac/types.ts +3 -0
  1013. package/src/rbac/utils/clientSecurity.test.ts +192 -0
  1014. package/src/rbac/utils/contextValidator.test.ts +126 -0
  1015. package/src/rbac/utils/contextValidator.ts +5 -1
  1016. package/src/rbac/utils/deep-equal.test.ts +76 -0
  1017. package/src/rbac/utils/eventContext.test.ts +401 -0
  1018. package/src/rbac/utils/eventContext.ts +37 -33
  1019. package/src/rbac/utils/fetchPermissionMap.ts +13 -0
  1020. package/src/rbac/utils/permissionMapHelpers.ts +34 -0
  1021. package/src/rbac/utils/roleManagementRpc.ts +303 -0
  1022. package/src/services/AuthService.edge-cases.test.ts +746 -0
  1023. package/src/services/AuthService.restoreSession.test.ts +59 -0
  1024. package/src/services/AuthService.test.ts +1362 -0
  1025. package/src/services/AuthService.ts +184 -205
  1026. package/src/services/BaseService.edge-cases.test.ts +506 -0
  1027. package/src/services/BaseService.test.ts +363 -0
  1028. package/src/services/EventService.edge-cases.test.ts +636 -0
  1029. package/src/services/EventService.eventColours.test.ts +64 -0
  1030. package/src/services/EventService.test.ts +1250 -0
  1031. package/src/services/EventService.ts +251 -316
  1032. package/src/services/InactivityService.edge-cases.test.ts +492 -0
  1033. package/src/services/InactivityService.lifecycle.test.ts +406 -0
  1034. package/src/services/InactivityService.test.ts +829 -0
  1035. package/src/services/InactivityService.ts +172 -213
  1036. package/src/services/OrganisationService.edge-cases.test.ts +633 -0
  1037. package/src/services/OrganisationService.pagination.test.ts +409 -0
  1038. package/src/services/OrganisationService.test.ts +1579 -0
  1039. package/src/services/OrganisationService.ts +184 -238
  1040. package/src/services/base/BaseService.test.ts +1 -1
  1041. package/src/services/interfaces/IAuthService.test.ts +184 -0
  1042. package/src/services/interfaces/IAuthService.ts +10 -9
  1043. package/src/services/interfaces/IEventService.test.ts +176 -0
  1044. package/src/services/interfaces/IInactivityService.test.ts +183 -0
  1045. package/src/services/interfaces/IOrganisationService.test.ts +207 -0
  1046. package/src/styles/core.css +243 -12
  1047. package/src/theming/parseEventColours.test.ts +321 -0
  1048. package/src/theming/runtime.test.ts +495 -0
  1049. package/src/theming/runtime.ts +71 -2
  1050. package/src/types/api-result.ts +53 -0
  1051. package/src/types/core.test.ts +397 -0
  1052. package/src/types/database-generated.test.ts +78 -0
  1053. package/src/types/database.generated.ts +45 -10
  1054. package/src/types/event.ts +38 -18
  1055. package/src/types/file-reference.test.ts +351 -0
  1056. package/src/types/file-reference.ts +37 -12
  1057. package/src/types/guards.test.ts +246 -0
  1058. package/src/types/index.test.ts +265 -0
  1059. package/src/types/index.ts +3 -0
  1060. package/src/types/organisation.roles.test.ts +55 -0
  1061. package/src/types/organisation.test.ts +1105 -0
  1062. package/src/types/organisation.ts +15 -15
  1063. package/src/types/supabase.ts +13 -4
  1064. package/src/types/theme.test.ts +830 -0
  1065. package/src/types/type-validation.test.ts +526 -0
  1066. package/src/types/validation.test.ts +729 -0
  1067. package/src/utils/app/appIdResolver.test.ts +98 -71
  1068. package/src/utils/app/appIdResolver.ts +31 -20
  1069. package/src/utils/appConfig.unit.test.ts +55 -0
  1070. package/src/utils/audit.unit.test.ts +69 -0
  1071. package/src/utils/auth-utils.unit.test.ts +69 -0
  1072. package/src/utils/bundleAnalysis.unit.test.ts +326 -0
  1073. package/src/utils/cn.unit.test.ts +34 -0
  1074. package/src/utils/context/organisationContext.test.ts +105 -91
  1075. package/src/utils/context/organisationContext.ts +29 -40
  1076. package/src/utils/core/cn.test.ts +66 -0
  1077. package/src/utils/core/debugLogger.test.ts +113 -0
  1078. package/src/utils/core/logger.test.ts +217 -0
  1079. package/src/utils/core/mergeRefs.ts +24 -0
  1080. package/src/utils/debugLogger.test.ts +417 -0
  1081. package/src/utils/deviceFingerprint.unit.test.ts +818 -0
  1082. package/src/utils/dynamic/createLazyComponent.tsx +9 -1
  1083. package/src/utils/dynamic/dynamicUtils.test.ts +185 -0
  1084. package/src/utils/dynamic/lazyLoad.test.tsx +156 -0
  1085. package/src/utils/dynamicUtils.unit.test.ts +331 -0
  1086. package/src/utils/file-reference/file-reference.test.ts +1249 -0
  1087. package/src/utils/file-reference/index.ts +330 -347
  1088. package/src/utils/formatDate.unit.test.ts +109 -0
  1089. package/src/utils/formatting/formatDateTimeTimezone.test.ts +1 -1
  1090. package/src/utils/formatting/formatNumber.test.ts +1 -1
  1091. package/src/utils/formatting.unit.test.ts +99 -0
  1092. package/src/utils/google-places/googlePlacesUtils.test.ts +70 -48
  1093. package/src/utils/google-places/googlePlacesUtils.ts +67 -99
  1094. package/src/utils/google-places/loadGoogleMapsScript.test.ts +25 -22
  1095. package/src/utils/google-places/loadGoogleMapsScript.ts +138 -117
  1096. package/src/utils/index.unit.test.ts +251 -0
  1097. package/src/utils/lazyLoad.unit.test.tsx +319 -0
  1098. package/src/utils/location/location.test.ts +1 -1
  1099. package/src/utils/logger.unit.test.ts +398 -0
  1100. package/src/utils/organisationContext.unit.test.ts +180 -0
  1101. package/src/utils/performance/bundleAnalysis.test.ts +148 -0
  1102. package/src/utils/performance/performanceBenchmark.test.ts +251 -0
  1103. package/src/utils/performance/performanceBudgets.test.ts +241 -0
  1104. package/src/utils/performanceBenchmark.test.ts +174 -0
  1105. package/src/utils/performanceBudgets.unit.test.ts +288 -0
  1106. package/src/utils/permissionTypes.unit.test.ts +250 -0
  1107. package/src/utils/permissionUtils.unit.test.ts +362 -0
  1108. package/src/utils/permissions/permissionTypes.test.ts +149 -0
  1109. package/src/utils/persistence/keyDerivation.test.ts +306 -0
  1110. package/src/utils/persistence/sensitiveFieldDetection.test.ts +271 -0
  1111. package/src/utils/request-deduplication.test.ts +349 -0
  1112. package/src/utils/sanitization.unit.test.ts +346 -0
  1113. package/src/utils/schemaUtils.unit.test.ts +441 -0
  1114. package/src/utils/secureDataAccess.unit.test.ts +334 -0
  1115. package/src/utils/secureErrors.unit.test.ts +390 -0
  1116. package/src/utils/secureStorage.unit.test.ts +289 -0
  1117. package/src/utils/security/auth-utils.ts +34 -23
  1118. package/src/utils/security/secureDataAccess.ts +241 -281
  1119. package/src/utils/security/secureErrors.test.ts +1 -1
  1120. package/src/utils/security/secureStorage.test.ts +1 -1
  1121. package/src/utils/security/security.test.ts +25 -17
  1122. package/src/utils/security/security.ts +15 -18
  1123. package/src/utils/security/securityMonitor.test.ts +1 -1
  1124. package/src/utils/security.unit.test.ts +155 -0
  1125. package/src/utils/securityMonitor.unit.test.ts +276 -0
  1126. package/src/utils/sessionTracking.unit.test.ts +218 -0
  1127. package/src/utils/storage/config.unit.test.ts +239 -0
  1128. package/src/utils/storage/helpers.test.ts +88 -102
  1129. package/src/utils/storage/helpers.ts +173 -251
  1130. package/src/utils/storage/index.unit.test.ts +68 -0
  1131. package/src/utils/storage/types.ts +7 -0
  1132. package/src/utils/supabase/createBaseClient.test.ts +31 -14
  1133. package/src/utils/timezone/timezone.test.ts +1 -1
  1134. package/src/utils/timezone.test.ts +345 -0
  1135. package/src/utils/validation/common.test.ts +115 -0
  1136. package/src/utils/validation/csrf.test.ts +198 -0
  1137. package/src/utils/validation/csrf.ts +42 -41
  1138. package/src/utils/validation/htmlSanitization.unit.test.ts +618 -0
  1139. package/src/utils/validation/passwordSchema.test.ts +164 -0
  1140. package/src/utils/validation/schema.test.ts +127 -0
  1141. package/src/utils/validation/sqlInjectionProtection.test.ts +165 -0
  1142. package/src/utils/validation/user.test.ts +173 -0
  1143. package/src/utils/validation/validation.test.ts +197 -0
  1144. package/src/utils/validation/validationUtils.test.ts +294 -0
  1145. package/src/utils/validation.unit.test.ts +307 -0
  1146. package/src/utils/validationUtils.unit.test.ts +558 -0
  1147. package/dist/DataTable-SAXFG4XI.js +0 -13
  1148. package/dist/InactivityServiceProvider-DHryoh6K.d.ts +0 -299
  1149. package/dist/UnifiedAuthProvider-BBD2PS3Q.js +0 -7
  1150. package/dist/UnifiedAuthProvider-CiBAl9-s.d.ts +0 -151
  1151. package/dist/api-F47QJ7FX.js +0 -4
  1152. package/dist/audit-Z6ZZBWLU.js +0 -3
  1153. package/dist/auth-BZOJqrdd.d.ts +0 -49
  1154. package/dist/chunk-3GWSPISD.js +0 -61
  1155. package/dist/chunk-66R6RLUZ.js +0 -529
  1156. package/dist/chunk-7YDC7LMU.js +0 -487
  1157. package/dist/chunk-BCTXBU6U.js +0 -704
  1158. package/dist/chunk-FBZ7U3ID.js +0 -2209
  1159. package/dist/chunk-FN52B75D.js +0 -246
  1160. package/dist/chunk-JJEYZ3DX.js +0 -165
  1161. package/dist/chunk-KPYQWGFQ.js +0 -183
  1162. package/dist/chunk-KSNLMI7N.js +0 -481
  1163. package/dist/chunk-KYURMOQM.js +0 -977
  1164. package/dist/chunk-LNHFAF4X.js +0 -2279
  1165. package/dist/chunk-MPY44PWB.js +0 -8510
  1166. package/dist/chunk-NIU6DPQV.js +0 -427
  1167. package/dist/chunk-TFIPNIPE.js +0 -5379
  1168. package/dist/chunk-UZNAFKGW.js +0 -125
  1169. package/dist/chunk-W46INAVW.js +0 -1216
  1170. package/dist/chunk-X5EAU5G7.js +0 -793
  1171. package/dist/chunk-Y4PF6HIM.js +0 -2862
  1172. package/dist/database.generated-DT8JTZiP.d.ts +0 -9406
  1173. package/dist/event-WTAQuGcq.d.ts +0 -239
  1174. package/dist/file-reference-BavO2eQj.d.ts +0 -148
  1175. package/dist/functions-DH45k8ec.d.ts +0 -208
  1176. package/dist/timezone-K-ptz3HO.d.ts +0 -696
  1177. package/dist/types-BE2sEHKd.d.ts +0 -55
  1178. package/dist/types-CvOPXWWZ.d.ts +0 -111
  1179. package/dist/types-D05dCGma.d.ts +0 -521
  1180. package/dist/usePublicPageContext-vxBlEHO9.d.ts +0 -4290
  1181. package/dist/usePublicRouteParams-G3Ks53mk.d.ts +0 -877
  1182. package/docs/api/modules.md +0 -9889
  1183. package/scripts/build-docs-incremental.js +0 -179
  1184. package/scripts/eslint-audit.cjs +0 -222
  1185. package/scripts/generate-docs.js +0 -157
  1186. package/scripts/install-cursor-rules.cjs +0 -255
  1187. package/scripts/install-eslint-config.cjs +0 -349
  1188. package/scripts/setup-build-cache.js +0 -73
  1189. package/scripts/validate-pre-publish.js +0 -145
  1190. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +0 -260
  1191. package/src/__tests__/helpers/__tests__/optimized-test-setup.test.ts +0 -224
  1192. package/src/__tests__/helpers/__tests__/supabaseMock.test.ts +0 -273
  1193. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +0 -99
  1194. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +0 -446
  1195. package/src/__tests__/helpers/__tests__/timer-utils.test.ts +0 -371
  1196. package/src/__tests__/hooks/usePermissions.test.ts +0 -268
  1197. package/src/__tests__/index.test.ts +0 -532
  1198. package/src/__tests__/integration/UserProfile.test.tsx +0 -124
  1199. package/src/__tests__/public-recipe-view.test.ts +0 -228
  1200. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +0 -222
  1201. package/src/__tests__/rls-policies.test.ts +0 -472
  1202. package/src/components/ContextSelector/__tests__/ContextSelector.test.tsx +0 -360
  1203. package/src/components/DataTable/__tests__/DataTable.comprehensive.test.tsx +0 -759
  1204. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +0 -524
  1205. package/src/components/DataTable/__tests__/DataTable.export.test.tsx +0 -705
  1206. package/src/components/DataTable/__tests__/DataTable.grouping-aggregation.test.tsx +0 -658
  1207. package/src/components/DataTable/__tests__/DataTable.hooks.test.tsx +0 -192
  1208. package/src/components/DataTable/__tests__/DataTable.select-label-display.test.tsx +0 -485
  1209. package/src/components/DataTable/__tests__/DataTable.test.tsx +0 -876
  1210. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +0 -220
  1211. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +0 -970
  1212. package/src/components/DataTable/__tests__/README.md +0 -145
  1213. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +0 -788
  1214. package/src/components/DataTable/__tests__/keyboard.test.tsx +0 -756
  1215. package/src/components/DataTable/__tests__/mocks/MockRBACProvider.tsx +0 -66
  1216. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +0 -728
  1217. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +0 -319
  1218. package/src/components/DataTable/__tests__/styles.test.ts +0 -382
  1219. package/src/components/DataTable/__tests__/test-utils/dataFactories.ts +0 -103
  1220. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +0 -388
  1221. package/src/components/DataTable/__tests__/test-utils.ts +0 -94
  1222. package/src/components/DataTable/components/AccessDeniedPage.tsx +0 -159
  1223. package/src/components/DataTable/components/ActionButtons.tsx +0 -195
  1224. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +0 -160
  1225. package/src/components/DataTable/components/ColumnFilter.tsx +0 -113
  1226. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +0 -114
  1227. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +0 -225
  1228. package/src/components/DataTable/components/DataTableLayout.tsx +0 -584
  1229. package/src/components/DataTable/components/DataTableModals.tsx +0 -333
  1230. package/src/components/DataTable/components/DataTableToolbar.tsx +0 -271
  1231. package/src/components/DataTable/components/EditFields.tsx +0 -286
  1232. package/src/components/DataTable/components/EditableRow.tsx +0 -462
  1233. package/src/components/DataTable/components/EmptyState.tsx +0 -82
  1234. package/src/components/DataTable/components/FilterRow.tsx +0 -148
  1235. package/src/components/DataTable/components/LoadingState.tsx +0 -17
  1236. package/src/components/DataTable/components/PaginationControls.tsx +0 -285
  1237. package/src/components/DataTable/components/RowComponent.tsx +0 -423
  1238. package/src/components/DataTable/components/SortIndicator.tsx +0 -50
  1239. package/src/components/DataTable/components/UnifiedTableBody.tsx +0 -395
  1240. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +0 -245
  1241. package/src/components/DataTable/components/__tests__/ActionButtons.test.tsx +0 -919
  1242. package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +0 -544
  1243. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +0 -484
  1244. package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.test.tsx +0 -748
  1245. package/src/components/DataTable/components/__tests__/DataTableCore.test.tsx +0 -792
  1246. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +0 -438
  1247. package/src/components/DataTable/components/__tests__/DataTableLayout.test.tsx +0 -467
  1248. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +0 -358
  1249. package/src/components/DataTable/components/__tests__/DataTableToolbar.test.tsx +0 -629
  1250. package/src/components/DataTable/components/__tests__/EditFields.test.tsx +0 -526
  1251. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +0 -994
  1252. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +0 -420
  1253. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +0 -415
  1254. package/src/components/DataTable/components/__tests__/GroupingDropdown.test.tsx +0 -612
  1255. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +0 -957
  1256. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +0 -81
  1257. package/src/components/DataTable/components/__tests__/PaginationControls.test.tsx +0 -429
  1258. package/src/components/DataTable/components/__tests__/RowComponent.test.tsx +0 -629
  1259. package/src/components/DataTable/components/__tests__/SortIndicator.test.tsx +0 -135
  1260. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +0 -864
  1261. package/src/components/DataTable/components/__tests__/cellValueUtils.test.ts +0 -453
  1262. package/src/components/DataTable/components/cellValueUtils.ts +0 -40
  1263. package/src/components/DataTable/components/hooks/useImportModalFocus.test.ts +0 -184
  1264. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +0 -53
  1265. package/src/components/DataTable/components/hooks/usePermissionTracking.test.ts +0 -381
  1266. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +0 -122
  1267. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +0 -328
  1268. package/src/components/DataTable/core/ActionManager.ts +0 -235
  1269. package/src/components/DataTable/core/ColumnManager.ts +0 -204
  1270. package/src/components/DataTable/core/DataManager.ts +0 -190
  1271. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -274
  1272. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  1273. package/src/components/DataTable/core/StateManager.ts +0 -312
  1274. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -235
  1275. package/src/components/DataTable/core/__tests__/ColumnFactory.test.ts +0 -403
  1276. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -141
  1277. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -178
  1278. package/src/components/DataTable/core/__tests__/LocalDataAdapter.test.ts +0 -133
  1279. package/src/components/DataTable/core/__tests__/PluginRegistry.test.ts +0 -142
  1280. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -158
  1281. package/src/components/DataTable/core/interfaces.ts +0 -338
  1282. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +0 -516
  1283. package/src/components/DataTable/hooks/__tests__/useColumnVisibilityPersistence.test.ts +0 -256
  1284. package/src/components/DataTable/hooks/__tests__/useDataTableConfiguration.test.ts +0 -297
  1285. package/src/components/DataTable/hooks/__tests__/useDataTableDataPipeline.test.ts +0 -270
  1286. package/src/components/DataTable/hooks/__tests__/useDataTablePermissions.test.ts +0 -280
  1287. package/src/components/DataTable/hooks/__tests__/useDataTableState.test.ts +0 -691
  1288. package/src/components/DataTable/hooks/__tests__/useEffectiveColumnOrder.test.ts +0 -183
  1289. package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +0 -294
  1290. package/src/components/DataTable/hooks/__tests__/useKeyboardNavigation.test.ts +0 -787
  1291. package/src/components/DataTable/hooks/__tests__/useServerSideDataEffect.test.ts +0 -258
  1292. package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +0 -499
  1293. package/src/components/DataTable/hooks/__tests__/useTableHandlers.test.ts +0 -440
  1294. package/src/components/DataTable/types.ts +0 -764
  1295. package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +0 -548
  1296. package/src/components/DataTable/utils/__tests__/aggregationUtils.test.ts +0 -288
  1297. package/src/components/DataTable/utils/__tests__/columnUtils.test.ts +0 -94
  1298. package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +0 -209
  1299. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +0 -954
  1300. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +0 -573
  1301. package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +0 -235
  1302. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +0 -586
  1303. package/src/components/DataTable/utils/__tests__/paginationUtils.test.ts +0 -593
  1304. package/src/components/DataTable/utils/__tests__/performanceUtils.test.ts +0 -470
  1305. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +0 -235
  1306. package/src/components/DataTable/utils/__tests__/selectFieldUtils.test.ts +0 -208
  1307. package/src/components/NavigationMenu/__tests__/useNavigationFiltering.test.ts +0 -1934
  1308. package/src/components/Select/__tests__/context.test.tsx +0 -56
  1309. package/src/components/Select/hooks/__tests__/useSelectEvents.test.ts +0 -279
  1310. package/src/components/Select/hooks/__tests__/useSelectSearch.test.tsx +0 -295
  1311. package/src/components/Select/hooks/__tests__/useSelectState.test.ts +0 -254
  1312. package/src/components/Select/hooks/useSelectEvents.ts +0 -87
  1313. package/src/components/Select/hooks/useSelectSearch.ts +0 -91
  1314. package/src/components/Select/hooks/useSelectState.ts +0 -104
  1315. package/src/components/Select/utils/__tests__/text.test.tsx +0 -104
  1316. package/src/components/Select/utils/text.ts +0 -26
  1317. package/src/components/__tests__/index.test.ts +0 -346
  1318. package/src/constants/__tests__/performance.test.ts +0 -91
  1319. package/src/hooks/__tests__/ServiceHooks.test.tsx +0 -725
  1320. package/src/hooks/__tests__/hooks.integration.test.tsx +0 -608
  1321. package/src/hooks/__tests__/index.unit.test.ts +0 -220
  1322. package/src/hooks/__tests__/useAppConfig.unit.test.ts +0 -406
  1323. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +0 -328
  1324. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +0 -720
  1325. package/src/hooks/__tests__/useDataTableState.test.ts +0 -170
  1326. package/src/hooks/__tests__/useDebounce.unit.test.ts +0 -157
  1327. package/src/hooks/__tests__/useEvents.unit.test.ts +0 -227
  1328. package/src/hooks/__tests__/useFileDisplay.test.ts +0 -540
  1329. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +0 -1109
  1330. package/src/hooks/__tests__/useFileUrl.unit.test.ts +0 -696
  1331. package/src/hooks/__tests__/useFileUrlCache.test.ts +0 -319
  1332. package/src/hooks/__tests__/useFocusManagement.unit.test.ts +0 -604
  1333. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +0 -613
  1334. package/src/hooks/__tests__/useFormDialog.test.ts +0 -307
  1335. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +0 -446
  1336. package/src/hooks/__tests__/useIsMobile.unit.test.ts +0 -317
  1337. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +0 -907
  1338. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +0 -293
  1339. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +0 -961
  1340. package/src/hooks/__tests__/useOrganisations.unit.test.ts +0 -369
  1341. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +0 -694
  1342. package/src/hooks/__tests__/usePermissionCache.test.ts +0 -506
  1343. package/src/hooks/__tests__/usePreventTabReload.test.ts +0 -307
  1344. package/src/hooks/__tests__/usePublicEvent.simple.test.ts +0 -794
  1345. package/src/hooks/__tests__/usePublicEvent.test.ts +0 -670
  1346. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +0 -638
  1347. package/src/hooks/__tests__/usePublicFileDisplay.test.ts +0 -948
  1348. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +0 -442
  1349. package/src/hooks/__tests__/useQueryCache.test.ts +0 -391
  1350. package/src/hooks/__tests__/useRBAC.unit.test.ts +0 -236
  1351. package/src/hooks/__tests__/useSessionDraft.test.ts +0 -556
  1352. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +0 -390
  1353. package/src/hooks/__tests__/useStorage.unit.test.ts +0 -721
  1354. package/src/hooks/__tests__/useToast.test.ts +0 -413
  1355. package/src/hooks/__tests__/useToast.unit.test.tsx +0 -481
  1356. package/src/hooks/__tests__/useZodForm.unit.test.tsx +0 -191
  1357. package/src/hooks/public/usePublicFileDisplay.test.ts +0 -723
  1358. package/src/hooks/public/usePublicFileDisplay.ts +0 -534
  1359. package/src/hooks/useFileDisplay.ts +0 -748
  1360. package/src/icons/__tests__/index.test.ts +0 -133
  1361. package/src/providers/OrganisationProvider.test.tsx +0 -40
  1362. package/src/providers/OrganisationProvider.tsx +0 -92
  1363. package/src/providers/__tests__/AuthProvider.test.tsx +0 -218
  1364. package/src/providers/__tests__/EventProvider.test.tsx +0 -487
  1365. package/src/providers/__tests__/InactivityProvider.test-helper.tsx +0 -65
  1366. package/src/providers/__tests__/InactivityProvider.test.tsx +0 -428
  1367. package/src/providers/__tests__/OrganisationProvider.test.tsx +0 -616
  1368. package/src/providers/__tests__/OrganisationProvider.wrapper.test.tsx +0 -591
  1369. package/src/providers/__tests__/ProviderLifecycle.test.tsx +0 -308
  1370. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +0 -503
  1371. package/src/providers/__tests__/index.test.ts +0 -138
  1372. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +0 -229
  1373. package/src/providers/services/__tests__/AuthServiceProvider.test.tsx +0 -638
  1374. package/src/providers/services/__tests__/EventServiceProvider.test.tsx +0 -839
  1375. package/src/providers/services/__tests__/InactivityServiceProvider.test.tsx +0 -662
  1376. package/src/providers/services/__tests__/OrganisationServiceProvider.test.tsx +0 -440
  1377. package/src/providers/services/__tests__/UnifiedAuthProvider.advanced.test.tsx +0 -435
  1378. package/src/providers/services/__tests__/UnifiedAuthProvider.appId.test.tsx +0 -408
  1379. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +0 -301
  1380. package/src/providers/services/__tests__/contexts.test.tsx +0 -281
  1381. package/src/providers/services/__tests__/useUnifiedAuth.test.tsx +0 -251
  1382. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +0 -429
  1383. package/src/rbac/__tests__/audit-batched.test.ts +0 -550
  1384. package/src/rbac/__tests__/auth-rbac-security.integration.test.tsx +0 -300
  1385. package/src/rbac/__tests__/auth-rbac.e2e.test.tsx +0 -517
  1386. package/src/rbac/__tests__/cache-invalidation.test.ts +0 -393
  1387. package/src/rbac/__tests__/engine.comprehensive.test.ts +0 -808
  1388. package/src/rbac/__tests__/performance.test.ts +0 -451
  1389. package/src/rbac/__tests__/rbac-core.test.tsx +0 -276
  1390. package/src/rbac/__tests__/rbac-engine-core-logic.test.ts +0 -387
  1391. package/src/rbac/__tests__/rbac-engine-simplified.test.ts +0 -252
  1392. package/src/rbac/__tests__/rbac-functions.test.ts +0 -646
  1393. package/src/rbac/__tests__/rbac-role-isolation.test.ts +0 -456
  1394. package/src/rbac/__tests__/scenarios.user-role.test.tsx +0 -271
  1395. package/src/rbac/components/__tests__/AccessDenied.test.tsx +0 -324
  1396. package/src/rbac/components/__tests__/NavigationGuard.test.tsx +0 -1146
  1397. package/src/rbac/components/__tests__/PagePermissionGuard.performance.test.tsx +0 -231
  1398. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +0 -243
  1399. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +0 -1430
  1400. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +0 -185
  1401. package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +0 -427
  1402. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +0 -1179
  1403. package/src/rbac/hooks/permissions/__tests__/useAccessLevel.test.ts +0 -622
  1404. package/src/rbac/hooks/permissions/__tests__/useCan.test.ts +0 -798
  1405. package/src/rbac/hooks/permissions/__tests__/useMultiplePermissions.test.ts +0 -843
  1406. package/src/rbac/hooks/permissions/__tests__/usePermissions.test.ts +0 -545
  1407. package/src/rbac/utils/__tests__/clientSecurity.test.ts +0 -192
  1408. package/src/rbac/utils/__tests__/contextValidator.test.ts +0 -126
  1409. package/src/rbac/utils/__tests__/deep-equal.test.ts +0 -76
  1410. package/src/rbac/utils/__tests__/eventContext.test.ts +0 -386
  1411. package/src/services/__tests__/AuthService.edge-cases.test.ts +0 -746
  1412. package/src/services/__tests__/AuthService.restoreSession.test.ts +0 -59
  1413. package/src/services/__tests__/AuthService.test.ts +0 -1328
  1414. package/src/services/__tests__/BaseService.edge-cases.test.ts +0 -506
  1415. package/src/services/__tests__/BaseService.test.ts +0 -363
  1416. package/src/services/__tests__/EventService.edge-cases.test.ts +0 -633
  1417. package/src/services/__tests__/EventService.eventColours.test.ts +0 -64
  1418. package/src/services/__tests__/EventService.test.ts +0 -1018
  1419. package/src/services/__tests__/InactivityService.edge-cases.test.ts +0 -492
  1420. package/src/services/__tests__/InactivityService.lifecycle.test.ts +0 -406
  1421. package/src/services/__tests__/InactivityService.test.ts +0 -654
  1422. package/src/services/__tests__/OrganisationService.edge-cases.test.ts +0 -633
  1423. package/src/services/__tests__/OrganisationService.pagination.test.ts +0 -409
  1424. package/src/services/__tests__/OrganisationService.test.ts +0 -1176
  1425. package/src/services/interfaces/__tests__/IAuthService.test.ts +0 -190
  1426. package/src/services/interfaces/__tests__/IEventService.test.ts +0 -176
  1427. package/src/services/interfaces/__tests__/IInactivityService.test.ts +0 -183
  1428. package/src/services/interfaces/__tests__/IOrganisationService.test.ts +0 -207
  1429. package/src/theming/__tests__/parseEventColours.test.ts +0 -321
  1430. package/src/theming/__tests__/runtime.test.ts +0 -504
  1431. package/src/types/__tests__/core.test.ts +0 -397
  1432. package/src/types/__tests__/database-generated.test.ts +0 -78
  1433. package/src/types/__tests__/file-reference.test.ts +0 -351
  1434. package/src/types/__tests__/guards.test.ts +0 -246
  1435. package/src/types/__tests__/index.test.ts +0 -265
  1436. package/src/types/__tests__/organisation.roles.test.ts +0 -55
  1437. package/src/types/__tests__/organisation.test.ts +0 -1133
  1438. package/src/types/__tests__/theme.test.ts +0 -830
  1439. package/src/types/__tests__/type-validation.test.ts +0 -526
  1440. package/src/types/__tests__/validation.test.ts +0 -729
  1441. package/src/utils/__tests__/appConfig.unit.test.ts +0 -55
  1442. package/src/utils/__tests__/audit.unit.test.ts +0 -69
  1443. package/src/utils/__tests__/auth-utils.unit.test.ts +0 -70
  1444. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +0 -326
  1445. package/src/utils/__tests__/cn.unit.test.ts +0 -34
  1446. package/src/utils/__tests__/debugLogger.test.ts +0 -417
  1447. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +0 -818
  1448. package/src/utils/__tests__/dynamicUtils.unit.test.ts +0 -331
  1449. package/src/utils/__tests__/formatDate.unit.test.ts +0 -109
  1450. package/src/utils/__tests__/formatting.unit.test.ts +0 -99
  1451. package/src/utils/__tests__/index.unit.test.ts +0 -251
  1452. package/src/utils/__tests__/lazyLoad.unit.test.tsx +0 -320
  1453. package/src/utils/__tests__/logger.unit.test.ts +0 -398
  1454. package/src/utils/__tests__/organisationContext.unit.test.ts +0 -191
  1455. package/src/utils/__tests__/performanceBenchmark.test.ts +0 -174
  1456. package/src/utils/__tests__/performanceBudgets.unit.test.ts +0 -288
  1457. package/src/utils/__tests__/permissionTypes.unit.test.ts +0 -250
  1458. package/src/utils/__tests__/permissionUtils.unit.test.ts +0 -362
  1459. package/src/utils/__tests__/request-deduplication.test.ts +0 -349
  1460. package/src/utils/__tests__/sanitization.unit.test.ts +0 -346
  1461. package/src/utils/__tests__/schemaUtils.unit.test.ts +0 -441
  1462. package/src/utils/__tests__/secureDataAccess.unit.test.ts +0 -334
  1463. package/src/utils/__tests__/secureErrors.unit.test.ts +0 -390
  1464. package/src/utils/__tests__/secureStorage.unit.test.ts +0 -289
  1465. package/src/utils/__tests__/security.unit.test.ts +0 -149
  1466. package/src/utils/__tests__/securityMonitor.unit.test.ts +0 -276
  1467. package/src/utils/__tests__/sessionTracking.unit.test.ts +0 -218
  1468. package/src/utils/__tests__/timezone.test.ts +0 -345
  1469. package/src/utils/__tests__/validation.unit.test.ts +0 -307
  1470. package/src/utils/__tests__/validationUtils.unit.test.ts +0 -555
  1471. package/src/utils/core/__tests__/cn.test.ts +0 -66
  1472. package/src/utils/core/__tests__/debugLogger.test.ts +0 -113
  1473. package/src/utils/core/__tests__/logger.test.ts +0 -217
  1474. package/src/utils/dynamic/__tests__/dynamicUtils.test.ts +0 -185
  1475. package/src/utils/dynamic/__tests__/lazyLoad.test.tsx +0 -156
  1476. package/src/utils/file-reference/__tests__/file-reference.test.ts +0 -1313
  1477. package/src/utils/performance/__tests__/bundleAnalysis.test.ts +0 -148
  1478. package/src/utils/performance/__tests__/performanceBenchmark.test.ts +0 -251
  1479. package/src/utils/performance/__tests__/performanceBudgets.test.ts +0 -241
  1480. package/src/utils/permissions/__tests__/permissionTypes.test.ts +0 -149
  1481. package/src/utils/persistence/__tests__/keyDerivation.test.ts +0 -306
  1482. package/src/utils/persistence/__tests__/sensitiveFieldDetection.test.ts +0 -271
  1483. package/src/utils/storage/__tests__/config.unit.test.ts +0 -239
  1484. package/src/utils/storage/__tests__/index.unit.test.ts +0 -68
  1485. package/src/utils/validation/__tests__/common.test.ts +0 -115
  1486. package/src/utils/validation/__tests__/csrf.test.ts +0 -170
  1487. package/src/utils/validation/__tests__/htmlSanitization.unit.test.ts +0 -618
  1488. package/src/utils/validation/__tests__/passwordSchema.test.ts +0 -164
  1489. package/src/utils/validation/__tests__/schema.test.ts +0 -127
  1490. package/src/utils/validation/__tests__/sqlInjectionProtection.test.ts +0 -165
  1491. package/src/utils/validation/__tests__/user.test.ts +0 -173
  1492. package/src/utils/validation/__tests__/validation.test.ts +0 -197
  1493. package/src/utils/validation/__tests__/validationUtils.test.ts +0 -294
  1494. /package/src/components/DataTable/{components/__tests__ → ui}/COVERAGE_NOTE.md +0 -0
  1495. /package/src/components/DataTable/utils/{__tests__/COVERAGE_NOTE.md → COVERAGE_NOTE.md} +0 -0
  1496. /package/src/hooks/{__tests__/useApiFetch.unit.test.ts → useApiFetch.unit.test.ts} +0 -0
  1497. /package/src/providers/{__tests__/README.md → README.md} +0 -0
  1498. /package/src/rbac/{__tests__/index.test.ts → index.test.ts} +0 -0
  1499. /package/src/rbac/{__tests__/rbac-integration.test.ts → rbac-integration.test.ts} +0 -0
  1500. /package/src/types/{__tests__/README.md → README.md} +0 -0
@@ -42,7 +42,7 @@
42
42
  * <DialogBody>
43
43
  * <section className="space-y-4">
44
44
  * <fieldset className="grid grid-cols-4 items-center gap-4">
45
- * <Label htmlFor="name" className="text-right">Name</Label>
45
+ * <Label htmlFor="name">Name</Label>
46
46
  * <Input id="name" defaultValue="John Doe" className="col-span-3" />
47
47
  * </fieldset>
48
48
  * </section>
@@ -89,16 +89,20 @@
89
89
 
90
90
  import * as React from 'react';
91
91
  import { createPortal } from 'react-dom';
92
- import { X } from 'lucide-react';
93
92
  import { useLocation } from 'react-router-dom';
93
+ import { Button, IconButton } from '../Button';
94
+ import { X } from '../../icons';
94
95
  import { useUnifiedAuth } from '../../providers/services/UnifiedAuthProvider';
95
96
  import { cn } from '../../utils/core/cn';
97
+ import { mergeRefs } from '../../utils/core/mergeRefs';
96
98
  import { renderSafeHtml } from '../../utils/validation/htmlSanitization';
97
99
  import { useState, useEffect, useRef, useCallback, useId, useMemo } from 'react';
98
100
  import { useFocusTrap } from '../../hooks/useFocusTrap';
99
- import { useSessionDraft } from '../../hooks/useSessionDraft';
100
101
  import { deriveDialogKey } from '../../utils/persistence/keyDerivation';
101
102
  import { createLogger } from '../../utils/core/logger';
103
+ import { useDialogPersistence } from './useDialogPersistence';
104
+ import { useDialogDimensions } from './useDialogDimensions';
105
+ import { useDialogLifecycle } from './useDialogLifecycle';
102
106
 
103
107
  /**
104
108
  * Dialog size variants
@@ -115,7 +119,6 @@ interface DialogContextValue {
115
119
  dialogRef: React.RefObject<HTMLDialogElement | null>;
116
120
  titleId: string;
117
121
  descriptionId: string;
118
- dialogTitle?: string; // For persistence key derivation
119
122
  markClosedByUser?: () => void; // Callback to mark dialog as closed by user (for Cancel buttons, etc.)
120
123
  }
121
124
 
@@ -190,12 +193,6 @@ export interface DialogContentProps extends React.HTMLAttributes<HTMLDialogEleme
190
193
  persistOpenState?: boolean;
191
194
  }
192
195
 
193
- /**
194
- * Props for the DialogOverlay component
195
- * @public
196
- */
197
- export interface DialogOverlayProps extends React.HTMLAttributes<HTMLDivElement> {}
198
-
199
196
  /**
200
197
  * Props for the DialogPortal component
201
198
  * @public
@@ -259,16 +256,6 @@ export interface DialogDescriptionProps extends React.HTMLAttributes<HTMLParagra
259
256
  allowHtml?: boolean;
260
257
  }
261
258
 
262
- // Size mapping for dialog variants
263
- const sizeClasses = {
264
- sm: 'max-w-sm',
265
- md: 'max-w-md',
266
- lg: 'max-w-lg',
267
- xl: 'max-w-xl',
268
- full: 'max-w-full size-full',
269
- auto: 'max-w-none w-auto min-w-0'
270
- };
271
-
272
259
  /**
273
260
  * Dialog root component
274
261
  * Provides context for dialog state management
@@ -283,7 +270,6 @@ const Dialog = React.memo<DialogProps>(function Dialog({
283
270
  const dialogRef = useRef<HTMLDialogElement | null>(null);
284
271
  const titleId = useId();
285
272
  const descriptionId = useId();
286
- const dialogTitleRef = useRef<string | undefined>(undefined);
287
273
  const [markClosedByUser, setMarkClosedByUserState] = useState<(() => void) | undefined>(undefined);
288
274
 
289
275
  const isControlled = controlledOpen !== undefined;
@@ -302,15 +288,9 @@ const Dialog = React.memo<DialogProps>(function Dialog({
302
288
  dialogRef,
303
289
  titleId,
304
290
  descriptionId,
305
- dialogTitle: dialogTitleRef.current,
306
291
  markClosedByUser, // Set by DialogContent
307
292
  }), [open, handleOpenChange, titleId, descriptionId, markClosedByUser]);
308
293
 
309
- // Expose function to set dialog title (called by DialogContent)
310
- const setDialogTitle = useCallback((title: string | undefined) => {
311
- dialogTitleRef.current = title;
312
- }, []);
313
-
314
294
  // Expose function to set markClosedByUser callback (called by DialogContent)
315
295
  const setMarkClosedByUser = useCallback((callback: (() => void) | undefined) => {
316
296
  setMarkClosedByUserState(callback);
@@ -318,22 +298,17 @@ const Dialog = React.memo<DialogProps>(function Dialog({
318
298
 
319
299
  return (
320
300
  <DialogContext.Provider value={contextValue}>
321
- <DialogTitleContext.Provider value={setDialogTitle}>
322
- <DialogMarkClosedContext.Provider value={setMarkClosedByUser}>
323
- {children}
324
- </DialogMarkClosedContext.Provider>
325
- </DialogTitleContext.Provider>
301
+ <DialogMarkClosedContext.Provider value={setMarkClosedByUser}>
302
+ {children}
303
+ </DialogMarkClosedContext.Provider>
326
304
  </DialogContext.Provider>
327
305
  );
328
306
  });
329
307
 
330
- // Context for setting dialog title from DialogContent
331
- const DialogTitleContext = React.createContext<((title: string | undefined) => void) | null>(null);
332
-
333
308
  // Context for setting markClosedByUser callback from DialogContent
334
309
  const DialogMarkClosedContext = React.createContext<((callback: (() => void) | undefined) => void) | null>(null);
335
310
 
336
- // Context for marking dialog as closed by user (from DialogContent to DialogClose)
311
+ // Context for passing markClosedByUser to DialogClose in the same render (DialogContext.markClosedByUser is set async)
337
312
  const DialogCloseContext = React.createContext<(() => void) | null>(null);
338
313
  Dialog.displayName = 'Dialog';
339
314
 
@@ -341,7 +316,7 @@ Dialog.displayName = 'Dialog';
341
316
  * DialogTrigger component
342
317
  * Opens the dialog when clicked
343
318
  */
344
- const DialogTrigger = React.forwardRef<HTMLElement, DialogTriggerProps>(
319
+ const DialogTrigger = React.forwardRef<HTMLButtonElement, DialogTriggerProps>(
345
320
  ({ children, asChild = false, className, onClick, ...props }, ref) => {
346
321
  const { onOpenChange } = useDialogContext();
347
322
 
@@ -357,19 +332,19 @@ const DialogTrigger = React.forwardRef<HTMLElement, DialogTriggerProps>(
357
332
  onClick: handleClick,
358
333
  className: cn(className, childElement.props?.className),
359
334
  ...props,
360
- } as Partial<React.HTMLAttributes<HTMLElement>>) as React.ReactElement;
335
+ } as React.HTMLAttributes<HTMLElement> & React.RefAttributes<HTMLElement>);
361
336
  }
362
337
 
363
338
  return (
364
- <button
365
- ref={ref as React.RefObject<HTMLButtonElement>}
339
+ <Button
340
+ ref={ref}
366
341
  type="button"
367
342
  onClick={handleClick}
368
343
  className={className}
369
344
  {...props}
370
345
  >
371
346
  {children}
372
- </button>
347
+ </Button>
373
348
  );
374
349
  }
375
350
  );
@@ -393,172 +368,28 @@ const DialogPortal: React.FC<DialogPortalProps> = ({ children }) => {
393
368
  };
394
369
  DialogPortal.displayName = 'DialogPortal';
395
370
 
396
- /**
397
- * DialogOverlay component
398
- * Backdrop overlay for the dialog (optional, native dialog provides ::backdrop)
399
- * This component is kept for backward compatibility but may not be needed
400
- * when using native dialog element which provides ::backdrop automatically
401
- */
402
- const DialogOverlay = React.forwardRef<HTMLDivElement, DialogOverlayProps>(
403
- ({ className: _className, ..._props }, _ref) => {
404
- // Note: Native dialog element provides ::backdrop automatically
405
- // This component is kept for API compatibility but may not render
406
- // The native dialog's ::backdrop is styled via CSS
407
- return null;
408
- }
409
- );
410
- DialogOverlay.displayName = 'DialogOverlay';
411
-
412
- /**
413
- * Custom hook for managing smart dialog dimensions
414
- * Handles responsive sizing and viewport-based constraints
415
- * Dimensions are calculated synchronously based on props - no resize listener needed
416
- */
417
- const useSmartDimensions = ({
418
- maxHeightPercent,
419
- maxWidthPercent,
420
- maxHeight,
421
- maxWidth,
422
- minHeight,
423
- minWidth,
424
- }: {
425
- maxHeightPercent?: number;
426
- maxWidthPercent?: number;
427
- maxHeight?: string;
428
- maxWidth?: string;
429
- minHeight?: string;
430
- minWidth?: string;
431
- }) => {
432
- // Calculate dimensions synchronously - no need for resize listener
433
- // CSS viewport units (vh/vw) handle responsiveness automatically
434
- return React.useMemo<React.CSSProperties>(() => {
435
- const result: React.CSSProperties = {};
436
-
437
- // Handle height constraints
438
- if (maxHeightPercent && typeof maxHeightPercent === 'number') {
439
- const constrainedHeight = Math.min(maxHeightPercent, 95);
440
- result.maxHeight = `${constrainedHeight}vh`;
441
- } else if (maxHeight) {
442
- result.maxHeight = maxHeight;
443
- }
444
-
445
- // Handle width constraints
446
- if (maxWidthPercent && typeof maxWidthPercent === 'number') {
447
- const constrainedWidth = Math.min(maxWidthPercent, 95);
448
- result.maxWidth = `${constrainedWidth}vw`;
449
- } else if (maxWidth) {
450
- result.maxWidth = maxWidth;
451
- }
452
-
453
- // Include minHeight/minWidth if provided
454
- if (minHeight) {
455
- result.minHeight = minHeight;
456
- }
457
- if (minWidth) {
458
- result.minWidth = minWidth;
459
- }
460
-
461
- return result;
462
- }, [maxHeightPercent, maxWidthPercent, maxHeight, maxWidth, minHeight, minWidth]);
463
- };
464
-
465
- /**
466
- * Global lock to ensure only one dialog is open at a time
467
- * Uses sessionStorage for persistence across page reloads
468
- */
469
- const DIALOG_LOCK_KEY = 'pace-core:dialog:lock';
470
-
471
- function acquireDialogLock(persistenceKey: string | null): boolean {
472
- if (!persistenceKey) {
473
- return true; // Non-persisted dialogs can always open
474
- }
475
-
476
- try {
477
- const lock = sessionStorage.getItem(DIALOG_LOCK_KEY);
478
- if (lock) {
479
- const lockData = JSON.parse(lock);
480
- // If lock is held by this dialog, allow it
481
- if (lockData.key === persistenceKey) {
482
- return true;
483
- }
484
- // If lock is held by another dialog, check if that dialog is still open
485
- const lockDialog = document.querySelector(`dialog[data-persistence-key="${lockData.key}"]`) as HTMLDialogElement;
486
- if (lockDialog && lockDialog.open) {
487
- return false; // Another dialog is still open
488
- }
489
- // Lock is stale, clear it
490
- sessionStorage.removeItem(DIALOG_LOCK_KEY);
491
- }
492
- // Acquire the lock
493
- sessionStorage.setItem(DIALOG_LOCK_KEY, JSON.stringify({
494
- key: persistenceKey,
495
- timestamp: Date.now(),
496
- }));
497
- return true;
498
- } catch {
499
- // If sessionStorage fails, allow opening (graceful degradation)
500
- return true;
501
- }
502
- }
503
-
504
- function releaseDialogLock(persistenceKey: string | null): void {
505
- if (!persistenceKey) {
506
- return;
507
- }
508
-
509
- try {
510
- const lock = sessionStorage.getItem(DIALOG_LOCK_KEY);
511
- if (lock) {
512
- const lockData = JSON.parse(lock);
513
- if (lockData.key === persistenceKey) {
514
- sessionStorage.removeItem(DIALOG_LOCK_KEY);
515
- }
516
- }
517
- } catch {
518
- // Ignore errors
519
- }
520
- }
521
-
522
- /**
523
- * Check if any other dialog (besides the current one) has persisted open state
524
- * This helps determine if another dialog should be allowed to auto-open
525
- */
526
- function checkOtherDialogsHavePersistedState(currentPersistenceKey: string | null): boolean {
527
- if (!currentPersistenceKey) {
528
- return false;
529
- }
530
-
531
- try {
532
- const lock = sessionStorage.getItem(DIALOG_LOCK_KEY);
533
- if (lock) {
534
- const lockData = JSON.parse(lock);
535
- if (lockData.key !== currentPersistenceKey) {
536
- // Another dialog holds the lock
537
- return true;
538
- }
539
- }
540
- } catch {
541
- // Error accessing sessionStorage - assume no other dialogs
542
- return false;
543
- }
544
-
545
- return false;
371
+ export interface UseDialogContentStateReturn {
372
+ mergedRef: (node: HTMLDialogElement | null) => void;
373
+ canRender: boolean;
374
+ markClosedByUser: () => void;
375
+ sizeClass: string;
376
+ mergedStyle: React.CSSProperties;
377
+ hasHeightConstraint: boolean;
378
+ persistenceKey: string | null;
379
+ persistOpenState: boolean;
380
+ titleId: string;
381
+ descriptionId: string;
382
+ open: boolean;
383
+ title: string | undefined;
384
+ description: string | undefined;
546
385
  }
547
386
 
548
- /**
549
- * DialogContent component
550
- * The main content container using semantic HTML <dialog> element with enhanced features
551
- *
552
- * @param props - Content configuration and styling
553
- * @param ref - Forwarded ref to the dialog element
554
- * @returns JSX.Element - The semantic dialog content with overlay and optional close button
555
- */
556
- const DialogContent = React.forwardRef<HTMLDialogElement, DialogContentProps>(
557
- ({
558
- className,
559
- children,
387
+ function useDialogContentState(
388
+ props: DialogContentProps,
389
+ ref: React.ForwardedRef<HTMLDialogElement>
390
+ ): UseDialogContentStateReturn {
391
+ const {
560
392
  size = 'md',
561
- showCloseButton = true,
562
393
  preventCloseOnEscape = false,
563
394
  preventCloseOnOutsideClick = false,
564
395
  maxHeightPercent,
@@ -572,427 +403,47 @@ const DialogContent = React.forwardRef<HTMLDialogElement, DialogContentProps>(
572
403
  description,
573
404
  style,
574
405
  persistOpenState = true,
575
- ...props
576
- }, ref) => {
577
- // Call all hooks unconditionally at the top level
578
- // Hooks must be called in the same order on every render
579
- const { open, onOpenChange, dialogRef, titleId, descriptionId } = useDialogContext();
580
- const setDialogTitle = React.useContext(DialogTitleContext);
581
- const setMarkClosedByUser = React.useContext(DialogMarkClosedContext);
582
-
583
- // Component mount/unmount tracking removed for performance
584
-
585
- // Call hooks unconditionally - if providers are missing, they will throw
586
- // Errors should be handled by error boundaries at a higher level
587
- const location = useLocation();
588
- const auth = useUnifiedAuth();
589
- const userId = auth.user?.id || null;
590
-
591
- // Create logger after all hooks are called (must be before any useEffects that use it)
592
- const logger = createLogger('Dialog');
593
-
594
- // Set dialog title in context for persistence
595
- useEffect(() => {
596
- if (setDialogTitle) {
597
- setDialogTitle(title);
598
- }
599
- }, [title, setDialogTitle]);
600
-
601
- // Derive persistence key (scoped by user ID)
602
- // CRITICAL: Only enable persistence if we have a valid userId to prevent data leakage
603
- const persistenceKey = useMemo(() => {
604
- if (!persistOpenState) {
605
- return null;
606
- }
607
- // Don't create persistence key if userId is not available
608
- // This prevents unscoped persistence that could leak between users
609
- if (!userId) {
610
- return null;
611
- }
612
- return deriveDialogKey(
613
- {
614
- title,
615
- description,
616
- },
617
- location,
618
- userId
619
- );
620
- }, [title, description, location, userId, persistOpenState]);
621
-
622
- // Use session draft for open state persistence
623
- // Only enabled when we have a valid persistenceKey (which requires userId)
624
- const { state: persistedOpen, setState: setPersistedOpen, clearDraft, wasRestored } = useSessionDraft<boolean>(
625
- persistenceKey ? `${persistenceKey}:open` : 'dialog:no-key:open',
626
- false,
627
- {
628
- enabled: Boolean(persistenceKey && persistOpenState && userId),
629
- debounceMs: 300,
630
- }
631
- );
632
-
633
- // Track if we've attempted auto-open to prevent multiple attempts
634
- const hasAutoOpenedRef = useRef(false);
635
- const hasInitializedRef = useRef(false);
636
- // Track if dialog was closed by user action (to clear persistence)
637
- const wasClosedByUserRef = useRef(false);
638
- // Track if dialog was manually opened (to prevent auto-open from interfering)
639
- const wasManuallyOpenedRef = useRef(false);
640
-
641
- // Callback to mark dialog as closed by user (exposed via context for DialogClose and Cancel buttons)
642
- const markClosedByUser = useCallback(() => {
643
- if (hasInitializedRef.current) {
644
- wasClosedByUserRef.current = true;
645
- }
646
- }, []);
647
-
648
- // Register markClosedByUser with parent Dialog component so it's available via DialogContext
649
- useEffect(() => {
650
- if (setMarkClosedByUser) {
651
- setMarkClosedByUser(markClosedByUser);
652
- }
653
- return () => {
654
- // Cleanup: unregister when DialogContent unmounts
655
- if (setMarkClosedByUser) {
656
- setMarkClosedByUser(undefined);
657
- }
658
- };
659
- }, [setMarkClosedByUser, markClosedByUser]);
660
- // Track if we've cleaned up other dialog states (to prevent multiple cleanup runs)
661
- const hasCleanedUpOtherDialogsRef = useRef(false);
662
-
663
- // Auto-open on mount if dialog was open when tab closed
664
- useEffect(() => {
665
- if (!persistenceKey || !persistOpenState) {
666
- hasInitializedRef.current = true;
667
- return;
668
- }
669
-
670
- // Only attempt auto-open once
671
- // This prevents auto-open from running after manual opens
672
- if (hasAutoOpenedRef.current) {
673
- return;
674
- }
675
-
676
- // CRITICAL: Don't auto-open if dialog was manually opened
677
- // This prevents auto-open from interfering with manual opens
678
- if (wasManuallyOpenedRef.current) {
679
- logger.debug('[Dialog Persistence] ⏭️ Skipping auto-open - dialog was manually opened', {
680
- persistenceKey,
681
- currentOpen: open,
682
- });
683
- return;
684
- }
685
-
686
- // Mark as initialized after first check
687
- if (!hasInitializedRef.current) {
688
- hasInitializedRef.current = true;
689
- }
690
-
691
- // Auto-open check (logging removed for performance)
692
-
693
- // CRITICAL: Don't auto-open if dialog is already open (user-initiated)
694
- if (open === true) {
695
- hasAutoOpenedRef.current = true;
696
- return;
697
- }
698
-
699
- // CRITICAL: Don't auto-open if userId is not available (prevents unscoped persistence from being restored)
700
- if (!userId) {
701
- hasAutoOpenedRef.current = true;
702
- return;
703
- }
704
-
705
- // Only auto-open if conditions are met
706
- if (persistedOpen === true && open === false && wasRestored && !hasAutoOpenedRef.current && !wasManuallyOpenedRef.current) {
707
- const AUTO_OPEN_LOCK_KEY = 'pace-core:dialog:auto-open-lock';
708
- const lockTimestamp = sessionStorage.getItem(AUTO_OPEN_LOCK_KEY);
709
- const now = Date.now();
710
-
711
- // Check if another dialog is already auto-opening (lock exists and is recent)
712
- if (lockTimestamp) {
713
- const lockAge = now - parseInt(lockTimestamp, 10);
714
- if (lockAge < 1000) {
715
- // Lock is recent - another dialog is auto-opening
716
- // Check if there's already an open dialog with this persistence key
717
- const existingOpenDialog = document.querySelector(`dialog[data-persistence-key="${persistenceKey}"][open]`);
718
- if (existingOpenDialog) {
719
- // Another instance is already open - skip
720
- hasAutoOpenedRef.current = true;
721
- return;
722
- }
723
- // Check if other dialog has persisted state
724
- const otherDialogHasPersistedState = checkOtherDialogsHavePersistedState(persistenceKey);
725
- if (otherDialogHasPersistedState) {
726
- // Another dialog with persisted state is auto-opening - skip this one
727
- clearDraft();
728
- hasAutoOpenedRef.current = true;
729
- return;
730
- }
731
- }
732
- // Clear stale locks
733
- if (lockAge > 2000) {
734
- sessionStorage.removeItem(AUTO_OPEN_LOCK_KEY);
735
- }
736
- }
737
-
738
- // Check if dialog with same key is already open in DOM (synchronous check)
739
- const existingDialog = document.querySelector(`dialog[data-persistence-key="${persistenceKey}"][open]`);
740
- if (existingDialog && existingDialog !== dialogRef.current && existingDialog !== internalRef.current) {
741
- hasAutoOpenedRef.current = true;
742
- return;
743
- }
744
-
745
- // Set lock and mark as auto-opened BEFORE calling onOpenChange
746
- sessionStorage.setItem(AUTO_OPEN_LOCK_KEY, String(now));
747
- hasAutoOpenedRef.current = true;
748
- wasManuallyOpenedRef.current = false;
749
-
750
- logger.debug('[Dialog] 🔄 AUTO-OPEN', { persistenceKey });
751
-
752
- // Use small delay to prevent visual flash
753
- const timeoutId = setTimeout(() => {
754
- // Double-check: if dialog is still closed and no other instance opened it
755
- const stillClosed = !open;
756
- const noOtherInstance = !document.querySelector(`dialog[data-persistence-key="${persistenceKey}"][open]`);
757
-
758
- if (stillClosed && noOtherInstance) {
759
- sessionStorage.removeItem(AUTO_OPEN_LOCK_KEY);
760
- onOpenChange(true);
761
- } else {
762
- sessionStorage.removeItem(AUTO_OPEN_LOCK_KEY);
763
- }
764
- }, 75);
765
-
766
- return () => {
767
- clearTimeout(timeoutId);
768
- sessionStorage.removeItem(AUTO_OPEN_LOCK_KEY);
769
- };
770
- }
771
- }, [persistenceKey, persistOpenState, persistedOpen, open, onOpenChange, wasRestored, clearDraft, dialogRef, userId, logger]);
772
-
773
- // When this dialog auto-opens, clear persisted state of all other dialogs
774
- // This prevents multiple dialogs from being restored simultaneously
775
- useEffect(() => {
776
- if (!persistenceKey || !persistOpenState || !open || !hasAutoOpenedRef.current) {
777
- return;
778
- }
779
-
780
- // Only run once when dialog first auto-opens
781
- if (hasCleanedUpOtherDialogsRef.current) {
782
- return;
783
- }
784
-
785
- // Clear all other dialog persisted states from sessionStorage
786
- // AND close any other dialogs that are currently open in the DOM
787
- // This ensures only the first auto-opened dialog remains open
788
- try {
789
- const keysToRemove: string[] = [];
790
- for (let i = 0; i < sessionStorage.length; i++) {
791
- const key = sessionStorage.key(i);
792
- if (key && key.startsWith('pace-core:draft:dialog:') && key.endsWith(':open')) {
793
- // Don't clear this dialog's own state
794
- if (key !== `pace-core:draft:${persistenceKey}:open`) {
795
- keysToRemove.push(key);
796
- }
797
- }
798
- }
799
-
800
- if (keysToRemove.length > 0) {
801
- logger.debug('[Dialog Persistence] Clearing other dialog persisted states:', keysToRemove);
802
- keysToRemove.forEach(key => sessionStorage.removeItem(key));
803
- }
804
-
805
- // Also close any other dialogs that are currently open in the DOM AND have persisted state
806
- // This prevents dialogs with persisted state from being hidden behind this one
807
- // We only close dialogs that have persisted state, not dialogs opened by app code
808
- // We identify dialogs with persistence using a data attribute
809
- const timeoutId = setTimeout(() => {
810
- // Guard against test environment teardown
811
- if (typeof document === 'undefined' || typeof sessionStorage === 'undefined') {
812
- return;
813
- }
814
-
815
- const otherOpenDialogs = document.querySelectorAll('dialog[open][role="dialog"]');
816
- const currentDialog = dialogRef.current || internalRef.current;
817
- if (otherOpenDialogs.length > 0 && currentDialog) {
818
- let closedCount = 0;
819
- otherOpenDialogs.forEach((dialog) => {
820
- // Don't close this dialog
821
- const dialogElement = dialog as HTMLDialogElement;
822
- if (dialogElement !== currentDialog) {
823
- // Check if this dialog has a data-persistence-key attribute
824
- // This indicates it was auto-opened from persistence
825
- const dialogPersistenceKey = dialogElement.getAttribute('data-persistence-key');
826
- if (dialogPersistenceKey && dialogPersistenceKey !== persistenceKey) {
827
- // Check if this dialog's persisted state is true
828
- let hasPersistedState = false;
829
- try {
830
- const key = `pace-core:draft:${dialogPersistenceKey}:open`;
831
- const stored = sessionStorage.getItem(key);
832
- if (stored) {
833
- const parsed = JSON.parse(stored);
834
- if (parsed && parsed.data === true) {
835
- hasPersistedState = true;
836
- }
837
- }
838
- } catch {
839
- // Invalid data - skip
840
- }
841
-
842
- // Only close if this dialog has persisted state (was auto-opened)
843
- if (hasPersistedState) {
844
- logger.debug('[Dialog Persistence] Closing other dialog with persisted state:', dialogPersistenceKey);
845
- dialogElement.close();
846
- closedCount++;
847
- }
848
- }
849
- // If dialog doesn't have data-persistence-key, it was opened by app code - don't close it
850
- }
851
- });
852
- if (closedCount > 0) {
853
- logger.debug('[Dialog Persistence] Closed', closedCount, 'other dialog(s) with persisted state');
854
- }
855
- }
856
- }, 100);
857
-
858
- hasCleanedUpOtherDialogsRef.current = true;
859
-
860
- // Also clear the auto-open lock
861
- if (typeof sessionStorage !== 'undefined') {
862
- sessionStorage.removeItem('pace-core:dialog:auto-open-lock');
863
- }
864
-
865
- // Cleanup timeout on unmount or dependency change
866
- return () => {
867
- clearTimeout(timeoutId);
868
- };
869
- } catch (error) {
870
- logger.warn('[Dialog Persistence] Failed to clear other dialog states:', error);
871
- }
872
- }, [open, persistenceKey, persistOpenState, dialogRef, logger]);
873
-
874
- // When dialog closes (user action), immediately clear persisted state
875
- // This prevents the dialog from auto-opening again after user explicitly closed it
876
- useEffect(() => {
877
- if (!persistenceKey || !persistOpenState) {
878
- return;
879
- }
880
-
881
- if (!hasInitializedRef.current) {
882
- return;
883
- }
884
-
885
- // If dialog is closed and user closed it, clear persisted state immediately
886
- if (!open && wasClosedByUserRef.current) {
887
- clearDraft();
888
- wasClosedByUserRef.current = false;
889
- }
890
- }, [open, persistenceKey, persistOpenState, clearDraft]);
891
-
892
- // Check lock BEFORE allowing dialog to open (synchronous check)
893
- // This prevents React from even trying to open if another dialog is open
894
- // Track lock acquisition state for rendering decision
895
- const [lockAcquired, setLockAcquired] = React.useState(false);
896
-
897
- useEffect(() => {
898
- if (!open) {
899
- setLockAcquired(false);
900
- return;
901
- }
902
-
903
- // Synchronously check if we can acquire the lock
904
- const acquired = acquireDialogLock(persistenceKey);
905
- setLockAcquired(acquired);
906
-
907
- if (!acquired) {
908
- // Another dialog is open - prevent this one from opening
909
- logger.warn('[Dialog] ⚠️ Cannot open - another dialog holds the lock', {
910
- persistenceKey,
911
- });
912
- // Immediately close this dialog's React state
913
- onOpenChange?.(false);
914
- return;
915
- }
916
-
917
- // Lock acquired successfully - dialog can proceed to open
918
- }, [open, persistenceKey, onOpenChange, logger]);
919
-
920
- // Track when dialog closes via onOpenChange to mark as closed by user
921
- // This handles Cancel buttons and other programmatic closes
922
- const previousOpenRef = useRef(open);
923
- useEffect(() => {
924
- // If dialog was open and is now closed, and it wasn't auto-opened, mark as closed by user
925
- if (previousOpenRef.current === true && open === false && hasInitializedRef.current) {
926
- // Only mark as closed by user if it wasn't an auto-open scenario
927
- // Auto-open sets hasAutoOpenedRef before calling onOpenChange, so we can detect it
928
- if (!hasAutoOpenedRef.current || wasManuallyOpenedRef.current) {
929
- // Dialog was manually opened and then closed - mark as closed by user
930
- wasClosedByUserRef.current = true;
931
- }
932
- }
933
- previousOpenRef.current = open;
934
- }, [open]);
935
-
936
- // Persist open state changes
937
- useEffect(() => {
938
- if (!persistenceKey || !persistOpenState) {
939
- return;
940
- }
941
-
942
- // Only persist after initial mount check is complete
943
- // This prevents overwriting the persisted state before auto-open can read it
944
- if (!hasInitializedRef.current) {
945
- return;
946
- }
406
+ } = props;
407
+
408
+ const { open, onOpenChange, dialogRef, titleId, descriptionId } = useDialogContext();
409
+ const setMarkClosedByUser = React.useContext(DialogMarkClosedContext);
410
+
411
+ const location = useLocation();
412
+ const auth = useUnifiedAuth();
413
+ const userId = auth.user?.id || null;
414
+
415
+ const logger = createLogger('Dialog');
416
+
417
+ const persistenceKey = useMemo(() => {
418
+ if (!persistOpenState) return null;
419
+ if (!userId) return null;
420
+ return deriveDialogKey({ title, description }, location, userId);
421
+ }, [title, description, location, userId, persistOpenState]);
422
+
423
+ const internalRef = useRef<HTMLDialogElement>(null);
424
+
425
+ const { lockAcquired, markClosedByUser, clearDraft } = useDialogPersistence({
426
+ open,
427
+ onOpenChange,
428
+ persistenceKey,
429
+ persistOpenState,
430
+ userId,
431
+ dialogRef,
432
+ internalRef,
433
+ setMarkClosedByUser,
434
+ logger,
435
+ });
947
436
 
948
- // Only persist when dialog is open
949
- if (open) {
950
- // Reset the flag when opening
951
- wasClosedByUserRef.current = false;
952
- // If dialog is manually opened (not via auto-open), mark it so auto-open doesn't interfere
953
- // This prevents auto-open from trying to open an already-open dialog
954
- // We check if hasAutoOpenedRef is false to determine if this is a manual open
955
- // (auto-open sets hasAutoOpenedRef to true before calling onOpenChange)
956
- if (!hasAutoOpenedRef.current) {
957
- // Mark as manually opened to prevent auto-open from interfering
958
- wasManuallyOpenedRef.current = true;
959
- // Also mark as "opened" to prevent auto-open from trying to open it again
960
- hasAutoOpenedRef.current = true;
961
- }
962
- setPersistedOpen(true);
963
- } else {
964
- // Only clear draft if user explicitly closed (not if it was never opened or auto-opened then closed)
965
- if (wasClosedByUserRef.current) {
966
- clearDraft();
967
- wasClosedByUserRef.current = false;
968
- // Reset manual open flag when dialog is closed
969
- wasManuallyOpenedRef.current = false;
970
- }
971
- }
972
- }, [open, persistenceKey, persistOpenState, setPersistedOpen, clearDraft]);
973
-
974
- // Note: We do NOT automatically clear the draft when dialog closes
975
- // The draft should only be cleared on explicit user actions (e.g., form submit success)
976
- // This allows the dialog to restore its state after tab switches
977
- const internalRef = useRef<HTMLDialogElement>(null);
978
-
979
- // Use the dialogRef from context, or fall back to internal ref or forwarded ref
980
- const actualDialogRef = dialogRef.current ? dialogRef : (ref ? (ref as React.RefObject<HTMLDialogElement>) : internalRef);
981
-
982
- // Default to 80% viewport height if no height constraint is provided
983
- // This allows the dialog to grow to 80% before enabling scrolling
984
- const effectiveMaxHeightPercent = maxHeightPercent ?? (maxHeight ? undefined : 80);
985
-
986
- // Determine if we have a height constraint that requires flex layout
987
- const hasHeightConstraint = Boolean(effectiveMaxHeightPercent || maxHeight);
988
-
989
- const smartDimensions = useSmartDimensions({
990
- maxHeightPercent: effectiveMaxHeightPercent,
437
+ const { sizeClass, mergedStyle, hasHeightConstraint } = useDialogDimensions({
438
+ size,
439
+ maxHeightPercent,
991
440
  maxWidthPercent,
992
- maxHeight,
441
+ maxHeight,
993
442
  maxWidth,
994
443
  minHeight,
995
- minWidth
444
+ minWidth,
445
+ enableScrolling,
446
+ style,
996
447
  });
997
448
 
998
449
  // Focus trap
@@ -1003,255 +454,114 @@ const DialogContent = React.forwardRef<HTMLDialogElement, DialogContentProps>(
1003
454
  onEscape: preventCloseOnEscape ? undefined : () => onOpenChange(false),
1004
455
  });
1005
456
 
1006
- // Merge refs
1007
- const mergedRef = useCallback((node: HTMLDialogElement | null) => {
1008
- // Set context dialog ref
1009
- if (dialogRef && 'current' in dialogRef) {
1010
- (dialogRef as React.MutableRefObject<HTMLDialogElement | null>).current = node;
1011
- }
1012
- // Set internal ref
1013
- if (internalRef && 'current' in internalRef) {
1014
- internalRef.current = node;
1015
- }
1016
- // Set focus trap container ref
1017
- if (containerRef && 'current' in containerRef) {
1018
- (containerRef as React.MutableRefObject<HTMLElement | null>).current = node;
1019
- }
1020
- // Handle forwarded ref
1021
- if (typeof ref === 'function') {
1022
- ref(node);
1023
- } else if (ref && 'current' in ref) {
1024
- (ref as React.MutableRefObject<HTMLDialogElement | null>).current = node;
1025
- }
1026
- }, [dialogRef, containerRef, ref]);
1027
-
1028
- // Handle dialog open/close
1029
- useEffect(() => {
1030
- const dialog = dialogRef.current || internalRef.current;
1031
- if (!dialog) return;
1032
-
1033
- if (open) {
1034
- // Log all dialogs in DOM before opening
1035
- const allDialogsBefore = document.querySelectorAll('dialog[role="dialog"]');
1036
- const dialogsBefore = Array.from(allDialogsBefore).map((d) => {
1037
- const dialogEl = d as HTMLDialogElement;
1038
- return {
1039
- persistenceKey: dialogEl.getAttribute('data-persistence-key') || 'NO-KEY',
1040
- open: dialogEl.open,
1041
- isCurrent: d === dialog,
1042
- };
1043
- });
1044
- logger.debug('[Dialog] 🟢 OPENING', {
1045
- persistenceKey,
1046
- dialogsInDOM: dialogsBefore,
1047
- totalDialogs: allDialogsBefore.length,
1048
- });
1049
-
1050
- // Use requestAnimationFrame to ensure DOM is ready
1051
- // Lock was already checked in the earlier useEffect, so we can proceed
1052
- requestAnimationFrame(() => {
1053
- if (dialog && open) {
1054
- // Check if dialog is connected to DOM before attempting to open
1055
- if (!dialog.isConnected) {
1056
- logger.warn('[Dialog] ⚠️ Dialog not connected to DOM, skipping showModal()', { persistenceKey });
1057
- return;
1058
- }
1059
-
1060
- // Check if dialog is already open - if so, skip showModal() call
1061
- // This prevents "Cannot call showModal() on an open non-modal dialog" error
1062
- if (dialog.open) {
1063
- logger.debug('[Dialog] ⏭️ Dialog already open, skipping showModal()', { persistenceKey });
1064
- return;
1065
- }
1066
-
1067
- // Before opening, close any other open dialogs (safety check)
1068
- const allDialogs = document.querySelectorAll('dialog[role="dialog"]');
1069
- allDialogs.forEach((d) => {
1070
- const dialogEl = d as HTMLDialogElement;
1071
- if (dialogEl !== dialog && dialogEl.open) {
1072
- dialogEl.setAttribute('data-duplicate-cleanup', 'true');
1073
- dialogEl.close();
1074
- }
1075
- });
1076
-
1077
- logger.debug('[Dialog] ✅ showModal() called', { persistenceKey });
1078
- dialog.showModal();
1079
- }
1080
- });
1081
- } else {
1082
- // Close dialog before it's removed from DOM
1083
- if (dialog.open) {
1084
- logger.debug('[Dialog] 🔴 CLOSING', { persistenceKey });
1085
- dialog.close();
1086
- // Release the lock
1087
- releaseDialogLock(persistenceKey);
1088
-
1089
- // After closing, check if any other dialogs with persistence are trying to open
1090
- // Only close dialogs that have persistence (data-persistence-key attribute)
1091
- // Non-persistent dialogs should be left alone
1092
- setTimeout(() => {
1093
- const allDialogs = document.querySelectorAll('dialog[role="dialog"]');
1094
- allDialogs.forEach((d) => {
1095
- const dialogEl = d as HTMLDialogElement;
1096
- if (dialogEl !== dialog && dialogEl.open) {
1097
- const otherPersistenceKey = dialogEl.getAttribute('data-persistence-key');
1098
- // Only close dialogs that have persistence (they might auto-open)
1099
- // Non-persistent dialogs are user-controlled and shouldn't be closed
1100
- if (otherPersistenceKey) {
1101
- logger.warn('[Dialog] 🗑️ Closing other persisted dialog after lock release:', {
1102
- persistenceKey,
1103
- otherPersistenceKey,
1104
- });
1105
- dialogEl.setAttribute('data-duplicate-cleanup', 'true');
1106
- dialogEl.close();
1107
- }
1108
- }
1109
- });
1110
- }, 50);
1111
- }
1112
- }
1113
- }, [open, persistenceKey, dialogRef, logger]);
1114
-
1115
- // Handle close event - sync state when dialog is closed externally
1116
- // Also track when dialog is closed by user action (for persistence clearing)
1117
- useEffect(() => {
1118
- const dialog = dialogRef.current || internalRef.current;
1119
- if (!dialog) return;
1120
-
1121
- const handleClose = () => {
1122
- // Check if this close was initiated by the user (via close button)
1123
- const wasUserClosed = dialog.hasAttribute('data-user-closed');
1124
- if (wasUserClosed) {
1125
- dialog.removeAttribute('data-user-closed');
1126
- if (hasInitializedRef.current) {
1127
- wasClosedByUserRef.current = true;
1128
- }
1129
- }
1130
-
1131
- // Ignore duplicate cleanup closes
1132
- const isDuplicateCleanup = dialog.hasAttribute('data-duplicate-cleanup');
1133
- if (isDuplicateCleanup) {
1134
- dialog.removeAttribute('data-duplicate-cleanup');
1135
- return;
1136
- }
1137
-
1138
- if (!dialog.open && open) {
1139
- // Mark as closed by user if this wasn't an auto-open scenario
1140
- if (hasInitializedRef.current && !wasUserClosed) {
1141
- wasClosedByUserRef.current = true;
1142
- }
1143
- onOpenChange(false);
1144
- } else if (!dialog.open && !open && hasInitializedRef.current && wasUserClosed) {
1145
- wasClosedByUserRef.current = true;
1146
- }
1147
- };
1148
-
1149
- dialog.addEventListener('close', handleClose);
1150
- return () => {
1151
- dialog.removeEventListener('close', handleClose);
1152
- };
1153
- }, [open, onOpenChange, dialogRef]);
1154
-
1155
- // Handle cancel event (Escape or backdrop click)
1156
- useEffect(() => {
1157
- const dialog = dialogRef.current || internalRef.current;
1158
- if (!dialog) return;
1159
-
1160
- const handleCancel = (e: Event) => {
1161
- if (preventCloseOnEscape || preventCloseOnOutsideClick) {
1162
- e.preventDefault();
1163
- return;
1164
- }
1165
- // Mark as closed by user and clear persisted state
1166
- wasClosedByUserRef.current = true;
1167
- if (persistenceKey && persistOpenState && clearDraft) {
1168
- clearDraft();
1169
- }
1170
- onOpenChange(false);
1171
- };
1172
-
1173
- dialog.addEventListener('cancel', handleCancel);
1174
- return () => {
1175
- dialog.removeEventListener('cancel', handleCancel);
1176
- };
1177
- }, [preventCloseOnEscape, preventCloseOnOutsideClick, onOpenChange, dialogRef, persistenceKey, persistOpenState, clearDraft]);
1178
-
1179
- // Merge smart dimensions with provided style
1180
- const mergedStyle = React.useMemo(() => {
1181
- if (Object.keys(smartDimensions).length === 0) {
1182
- return style;
1183
- }
457
+ // Merge refs (avoids type assertions; mergeRefs handles RefObject and callback refs)
458
+ const mergedRef = useMemo(
459
+ () => mergeRefs(dialogRef, internalRef, containerRef, ref),
460
+ [dialogRef, containerRef, ref]
461
+ );
1184
462
 
1185
- const finalStyle: React.CSSProperties = { ...smartDimensions, ...style };
1186
-
1187
- // When maxHeightPercent is set and enableScrolling is true, set height to match
1188
- // so the dialog always uses that space (not just as a max constraint)
1189
- if (enableScrolling && maxHeightPercent && typeof maxHeightPercent === 'number' && !maxHeight) {
1190
- const constrainedHeight = Math.min(maxHeightPercent, 95);
1191
- finalStyle.height = `${constrainedHeight}vh`;
1192
- }
1193
-
1194
- if (!maxWidth && !maxWidthPercent) {
1195
- const { maxWidth: _, ...styleWithoutMaxWidth } = finalStyle;
1196
- return styleWithoutMaxWidth;
1197
- }
1198
-
1199
- return finalStyle;
1200
- }, [smartDimensions, style, maxWidth, maxWidthPercent, enableScrolling, maxHeight, maxHeightPercent]);
463
+ useDialogLifecycle({
464
+ dialogRef,
465
+ internalRef,
466
+ open,
467
+ persistenceKey,
468
+ logger,
469
+ onOpenChange,
470
+ markClosedByUser,
471
+ preventCloseOnEscape,
472
+ preventCloseOnOutsideClick,
473
+ persistOpenState,
474
+ clearDraft,
475
+ });
1201
476
 
1202
- // Synchronously check if we can render (must hold lock if open)
1203
477
  const canRender = React.useMemo(() => {
1204
- if (!open) {
1205
- return true; // Can always render when closed
1206
- }
1207
- if (!persistenceKey) {
1208
- return true; // Non-persisted dialogs can always render
1209
- }
1210
- // Use the lockAcquired state which is set by the effect
478
+ if (!open) return true;
479
+ if (!persistenceKey) return true;
1211
480
  return lockAcquired;
1212
481
  }, [open, persistenceKey, lockAcquired]);
1213
482
 
483
+ return {
484
+ mergedRef,
485
+ canRender,
486
+ markClosedByUser,
487
+ sizeClass,
488
+ mergedStyle: mergedStyle ?? {},
489
+ hasHeightConstraint,
490
+ persistenceKey,
491
+ persistOpenState,
492
+ titleId,
493
+ descriptionId,
494
+ open,
495
+ title,
496
+ description,
497
+ };
498
+ }
499
+
500
+ /**
501
+ * DialogContent component
502
+ * The main content container using semantic HTML <dialog> element with enhanced features.
503
+ * Inline style exception (5-styling): viewport-based max/min dimensions from props are applied
504
+ * via the style prop; they cannot be expressed with static Tailwind and are merged with optional consumer style.
505
+ *
506
+ * @param props - Content configuration and styling
507
+ * @param ref - Forwarded ref to the dialog element
508
+ * @returns JSX.Element - The semantic dialog content with overlay and optional close button
509
+ */
510
+ const DialogContent = (React.forwardRef<HTMLDialogElement, DialogContentProps>)(
511
+ function DialogContentInner(props, ref) {
512
+ const {
513
+ className,
514
+ children,
515
+ size = 'md',
516
+ showCloseButton = true,
517
+ maxHeightPercent,
518
+ maxWidthPercent,
519
+ enableScrolling = false,
520
+ maxHeight,
521
+ maxWidth,
522
+ minHeight,
523
+ minWidth,
524
+ style: _styleProp,
525
+ title: _titleProp,
526
+ description: _descriptionProp,
527
+ persistOpenState: _persistOpenStateProp,
528
+ preventCloseOnEscape: _preventCloseOnEscape,
529
+ preventCloseOnOutsideClick: _preventCloseOnOutsideClick,
530
+ ...restProps
531
+ } = props;
532
+
533
+ const state = useDialogContentState(props, ref);
534
+
1214
535
  return (
1215
536
  <DialogPortal>
1216
- {open && canRender && (
537
+ {state.open && state.canRender && (
1217
538
  <dialog
1218
- ref={mergedRef}
539
+ ref={state.mergedRef}
1219
540
  className={cn(
1220
541
  'fixed left-[50%] top-[50%] z-[51] w-full translate-x-[-50%] translate-y-[-50%] border bg-background shadow-lg duration-200',
1221
542
  'animate-in fade-in-0 zoom-in-95 slide-in-from-left-1/2 slide-in-from-top-[48%]',
1222
543
  'sm:rounded-lg',
1223
- // Reset native dialog styles
1224
544
  'm-0 p-0 max-w-none max-h-none border-0 bg-transparent outline-none',
1225
- // When maxWidthPercent is set, use w-full to expand to the constraint (not w-auto)
1226
- // When maxWidthPercent is not set, use w-auto to size to content
1227
545
  (maxWidth || maxWidthPercent) ? 'w-full' : 'w-auto h-auto',
1228
- // Apply our custom styling
1229
546
  'border bg-background shadow-lg',
1230
- // Backdrop styling is handled via core.css only
1231
- // Only apply size classes if not using smart width
1232
- !maxWidth && !maxWidthPercent && sizeClasses[size],
1233
- // Auto size gets special handling
547
+ !maxWidth && !maxWidthPercent && state.sizeClass,
1234
548
  size === 'auto' && 'w-fit max-w-[90vw] sm:max-w-[80vw]',
1235
- // Layout classes: use flex when we have height constraints or enableScrolling is true
1236
- // Flex layout is needed for proper scrolling when height is constrained
1237
- (enableScrolling || hasHeightConstraint) ? 'flex flex-col p-6' : 'grid p-6',
1238
- // Full screen handling
549
+ (enableScrolling || state.hasHeightConstraint) ? 'flex flex-col p-6' : 'grid p-6',
1239
550
  size === 'full' && 'sm:left-[50%] sm:top-[50%] sm:translate-x-[-50%] sm:translate-y-[-50%] left-0 top-0 translate-x-0 translate-y-0 h-full rounded-none sm:h-auto sm:rounded-lg',
1240
- // Overflow handling for scrolling mode or when height is constrained
1241
- (enableScrolling || hasHeightConstraint) && 'overflow-hidden',
551
+ (enableScrolling || state.hasHeightConstraint) && 'overflow-hidden',
1242
552
  className
1243
553
  )}
1244
- style={mergedStyle}
554
+ style={state.mergedStyle}
1245
555
  role="dialog"
1246
556
  aria-modal="true"
1247
- aria-labelledby={titleId}
1248
- aria-describedby={descriptionId}
1249
- title={title}
1250
- aria-description={description}
1251
- data-persistence-key={persistenceKey && persistOpenState ? persistenceKey : undefined}
1252
- {...props}
557
+ aria-labelledby={state.titleId}
558
+ aria-describedby={state.descriptionId}
559
+ title={state.title}
560
+ aria-description={state.description}
561
+ data-persistence-key={state.persistenceKey && state.persistOpenState ? state.persistenceKey : undefined}
562
+ {...restProps}
1253
563
  >
1254
- <DialogCloseContext.Provider value={markClosedByUser}>
564
+ <DialogCloseContext.Provider value={state.markClosedByUser}>
1255
565
  {children}
1256
566
  {showCloseButton && (
1257
567
  <DialogClose />
@@ -1280,48 +590,38 @@ export interface DialogCloseProps extends React.ButtonHTMLAttributes<HTMLButtonE
1280
590
  */
1281
591
  const DialogClose = React.forwardRef<HTMLButtonElement, DialogCloseProps>(
1282
592
  ({ className, asChild = false, children, onClick, ...props }, ref) => {
1283
- // Call all hooks unconditionally at the top level
1284
- // Hooks must be called in the same order on every render
1285
593
  const { onOpenChange, markClosedByUser: contextMarkClosedByUser } = useDialogContext();
1286
- // Prefer DialogContext markClosedByUser (available to all components), fallback to DialogCloseContext (for backwards compatibility)
1287
594
  const dialogCloseContextValue = React.useContext(DialogCloseContext);
1288
- const markClosedByUser = contextMarkClosedByUser || dialogCloseContextValue;
1289
-
1290
- const handleClick = useCallback((e: React.MouseEvent<HTMLElement>) => {
1291
- // Mark dialog as closed by user before calling onOpenChange
1292
- // This ensures the persisted state is cleared when user clicks close button
595
+ const markClosedByUser = contextMarkClosedByUser ?? dialogCloseContextValue;
596
+
597
+ const handleClick = useCallback((e: React.MouseEvent<HTMLButtonElement>) => {
1293
598
  if (markClosedByUser) {
1294
599
  markClosedByUser();
1295
600
  }
1296
-
1297
- onClick?.(e as React.MouseEvent<HTMLButtonElement>);
601
+ onClick?.(e);
1298
602
  onOpenChange(false);
1299
603
  }, [onOpenChange, markClosedByUser, onClick]);
1300
604
 
1301
605
  if (asChild && React.isValidElement(children)) {
1302
- const childElement = children as React.ReactElement<React.HTMLAttributes<HTMLElement>>;
606
+ const childElement = children as React.ReactElement<React.HTMLAttributes<HTMLButtonElement>>;
1303
607
  return React.cloneElement(childElement, {
1304
608
  ref,
1305
609
  onClick: handleClick,
1306
610
  className: cn(className, childElement.props?.className),
1307
611
  ...props,
1308
- } as Partial<React.HTMLAttributes<HTMLElement>>) as React.ReactElement;
612
+ } as React.HTMLAttributes<HTMLButtonElement> & React.RefAttributes<HTMLButtonElement>);
1309
613
  }
1310
614
 
1311
615
  return (
1312
- <button
616
+ <IconButton
1313
617
  ref={ref}
618
+ icon={<X className="size-4" />}
619
+ aria-label="Close"
1314
620
  type="button"
1315
621
  onClick={handleClick}
1316
- className={cn(
1317
- 'absolute right-4 top-4 z-10 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none',
1318
- className
1319
- )}
622
+ className={cn('absolute right-4 top-4 z-10', className)}
1320
623
  {...props}
1321
- >
1322
- <X className="size-4" />
1323
- <span className="sr-only">Close</span>
1324
- </button>
624
+ />
1325
625
  );
1326
626
  }
1327
627
  );
@@ -1337,11 +637,7 @@ const DialogHeader = ({
1337
637
  ...props
1338
638
  }: DialogHeaderProps) => (
1339
639
  <header
1340
- className={cn(
1341
- 'flex flex-col space-y-1.5 text-center sm:text-left mb-4',
1342
- sticky && 'sticky top-0 z-10 bg-background',
1343
- className
1344
- )}
640
+ className={cn('dialog-header', sticky && 'sticky top-0 z-10 bg-background', className)}
1345
641
  {...props}
1346
642
  />
1347
643
  );
@@ -1361,6 +657,7 @@ const DialogBody = ({
1361
657
  children,
1362
658
  ...props
1363
659
  }: DialogBodyProps) => {
660
+ // Inline style exception (5-styling): maxHeight and style from props; no fixed token set.
1364
661
  const mergedStyle = React.useMemo(() => {
1365
662
  return {
1366
663
  ...(maxHeight && { maxHeight }),
@@ -1428,14 +725,14 @@ const DialogBody = ({
1428
725
  {...props}
1429
726
  >
1430
727
  {processedHtmlContent ? (
1431
- <p
728
+ <p
1432
729
  dangerouslySetInnerHTML={{ __html: processedHtmlContent }}
1433
- className="prose prose-sm max-w-none"
730
+ className="dialog-body-html-content"
1434
731
  />
1435
732
  ) : (
1436
733
  <>
1437
734
  {hasHtmlContent && !processedHtmlContent && (
1438
- <p className="text-acc-500 mb-2">
735
+ <p className="dialog-body-fallback">
1439
736
  No HTML content processed. Showing children instead.
1440
737
  </p>
1441
738
  )}
@@ -1457,12 +754,7 @@ const DialogFooter = ({
1457
754
  ...props
1458
755
  }: DialogFooterProps) => (
1459
756
  <footer
1460
- className={cn(
1461
- !className && 'flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2',
1462
- 'mt-4',
1463
- sticky && 'sticky bottom-0 z-10 bg-background',
1464
- className
1465
- )}
757
+ className={cn('dialog-footer', sticky && 'sticky bottom-0 z-10 bg-background', className)}
1466
758
  {...props}
1467
759
  />
1468
760
  );