@jmruthers/pace-core 0.5.193 → 0.6.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (577) hide show
  1. package/CHANGELOG.md +62 -0
  2. package/README.md +7 -1
  3. package/cursor-rules/00-pace-core-compliance.mdc +299 -0
  4. package/cursor-rules/01-standards-compliance.mdc +244 -0
  5. package/cursor-rules/02-project-structure.mdc +200 -0
  6. package/cursor-rules/03-solid-principles.mdc +222 -0
  7. package/cursor-rules/04-testing-standards.mdc +268 -0
  8. package/cursor-rules/05-bug-reports-and-features.mdc +246 -0
  9. package/cursor-rules/06-code-quality.mdc +309 -0
  10. package/cursor-rules/07-tech-stack-compliance.mdc +214 -0
  11. package/cursor-rules/08-markup-quality.mdc +452 -0
  12. package/cursor-rules/CHANGELOG.md +119 -0
  13. package/cursor-rules/README.md +192 -0
  14. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-BPvc3Ka0.d.ts} +54 -0
  15. package/dist/{DataTable-Be6dH_dR.d.ts → DataTable-BMRU8a1j.d.ts} +34 -2
  16. package/dist/{DataTable-5FU7IESH.js → DataTable-TPTKCX4D.js} +10 -9
  17. package/dist/{PublicPageProvider-C0Sm_e5k.d.ts → PublicPageProvider-DC6kCaqf.d.ts} +385 -261
  18. package/dist/{UnifiedAuthProvider-RGJTDE2C.js → UnifiedAuthProvider-CH6Z342H.js} +3 -3
  19. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CVcTjx-d.d.ts} +29 -0
  20. package/dist/{api-N774RPUA.js → api-MVVQZLJI.js} +2 -2
  21. package/dist/{chunk-KNC55RTG.js → chunk-24UVZUZG.js} +90 -54
  22. package/dist/chunk-24UVZUZG.js.map +1 -0
  23. package/dist/{chunk-HWIIPPNI.js → chunk-2UOI2FG5.js} +20 -20
  24. package/dist/chunk-2UOI2FG5.js.map +1 -0
  25. package/dist/{chunk-E3SPN4VZ 5.js → chunk-3XC4CPTD.js} +4345 -3986
  26. package/dist/chunk-3XC4CPTD.js.map +1 -0
  27. package/dist/{chunk-7EQTDTTJ.js → chunk-6J4GEEJR.js} +172 -45
  28. package/dist/chunk-6J4GEEJR.js.map +1 -0
  29. package/dist/{chunk-6C4YBBJM 5.js → chunk-6SOIHG6Z.js} +1 -1
  30. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  31. package/dist/{chunk-7FLMSG37.js → chunk-EHMR7VYL.js} +25 -25
  32. package/dist/chunk-EHMR7VYL.js.map +1 -0
  33. package/dist/{chunk-I7PSE6JW.js → chunk-F2IMUDXZ.js} +2 -75
  34. package/dist/chunk-F2IMUDXZ.js.map +1 -0
  35. package/dist/{chunk-QWWZ5CAQ.js → chunk-FFQEQTNW.js} +7 -9
  36. package/dist/chunk-FFQEQTNW.js.map +1 -0
  37. package/dist/chunk-FMUCXFII.js +76 -0
  38. package/dist/chunk-FMUCXFII.js.map +1 -0
  39. package/dist/{chunk-HW3OVDUF.js → chunk-J36DSWQK.js} +1 -1
  40. package/dist/{chunk-HW3OVDUF.js.map → chunk-J36DSWQK.js.map} +1 -1
  41. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  42. package/dist/chunk-L4OXEN46.js.map +1 -0
  43. package/dist/{chunk-R77UEZ4E 3.js → chunk-M43Y4SSO.js} +1 -1
  44. package/dist/chunk-M43Y4SSO.js.map +1 -0
  45. package/dist/{chunk-IIELH4DL.js → chunk-MMZ7JXPU.js} +60 -223
  46. package/dist/chunk-MMZ7JXPU.js.map +1 -0
  47. package/dist/{chunk-NOAYCWCX 5.js → chunk-NECFR5MM.js} +394 -312
  48. package/dist/chunk-NECFR5MM.js.map +1 -0
  49. package/dist/{chunk-BC4IJKSL.js → chunk-SFZUDBL5.js} +40 -4
  50. package/dist/chunk-SFZUDBL5.js.map +1 -0
  51. package/dist/{chunk-XNXXZ43G.js → chunk-XWQCNGTQ.js} +748 -364
  52. package/dist/chunk-XWQCNGTQ.js.map +1 -0
  53. package/dist/components.d.ts +6 -6
  54. package/dist/components.js +15 -12
  55. package/dist/components.js.map +1 -1
  56. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  57. package/dist/hooks.d.ts +59 -126
  58. package/dist/hooks.js +19 -28
  59. package/dist/hooks.js.map +1 -1
  60. package/dist/index.d.ts +63 -16
  61. package/dist/index.js +23 -24
  62. package/dist/index.js.map +1 -1
  63. package/dist/providers.d.ts +21 -3
  64. package/dist/providers.js +2 -2
  65. package/dist/rbac/index.d.ts +146 -115
  66. package/dist/rbac/index.js +8 -11
  67. package/dist/theming/runtime.d.ts +1 -13
  68. package/dist/theming/runtime.js +1 -1
  69. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  70. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  71. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  72. package/dist/types.d.ts +2 -2
  73. package/dist/{usePublicRouteParams-TZe0gy-4.d.ts → usePublicRouteParams-1oMokgLF.d.ts} +34 -4
  74. package/dist/{useToast-C8gR5ir4.d.ts → useToast-AyaT-x7p.d.ts} +2 -2
  75. package/dist/utils.d.ts +4 -5
  76. package/dist/utils.js +15 -15
  77. package/dist/utils.js.map +1 -1
  78. package/docs/api/README.md +7 -1
  79. package/docs/api/classes/ColumnFactory.md +8 -8
  80. package/docs/api/classes/InvalidScopeError.md +4 -4
  81. package/docs/api/classes/Logger.md +1 -1
  82. package/docs/api/classes/MissingUserContextError.md +4 -4
  83. package/docs/api/classes/OrganisationContextRequiredError.md +4 -4
  84. package/docs/api/classes/PermissionDeniedError.md +4 -4
  85. package/docs/api/classes/RBACAuditManager.md +1 -1
  86. package/docs/api/classes/RBACCache.md +1 -1
  87. package/docs/api/classes/RBACEngine.md +1 -1
  88. package/docs/api/classes/RBACError.md +4 -4
  89. package/docs/api/classes/RBACNotInitializedError.md +4 -4
  90. package/docs/api/classes/SecureSupabaseClient.md +18 -15
  91. package/docs/api/classes/StorageUtils.md +1 -1
  92. package/docs/api/enums/FileCategory.md +1 -1
  93. package/docs/api/enums/LogLevel.md +1 -1
  94. package/docs/api/enums/RBACErrorCode.md +1 -1
  95. package/docs/api/enums/RPCFunction.md +1 -1
  96. package/docs/api/interfaces/AddressFieldProps.md +1 -1
  97. package/docs/api/interfaces/AddressFieldRef.md +1 -1
  98. package/docs/api/interfaces/AggregateConfig.md +4 -4
  99. package/docs/api/interfaces/AutocompleteOptions.md +1 -1
  100. package/docs/api/interfaces/AvatarProps.md +1 -1
  101. package/docs/api/interfaces/BadgeProps.md +9 -2
  102. package/docs/api/interfaces/ButtonProps.md +7 -4
  103. package/docs/api/interfaces/CalendarProps.md +8 -5
  104. package/docs/api/interfaces/CardProps.md +8 -5
  105. package/docs/api/interfaces/ColorPalette.md +1 -1
  106. package/docs/api/interfaces/ColorShade.md +1 -1
  107. package/docs/api/interfaces/ComplianceResult.md +1 -1
  108. package/docs/api/interfaces/DataAccessRecord.md +9 -9
  109. package/docs/api/interfaces/DataRecord.md +1 -1
  110. package/docs/api/interfaces/DataTableAction.md +24 -21
  111. package/docs/api/interfaces/DataTableColumn.md +31 -31
  112. package/docs/api/interfaces/DataTableProps.md +1 -1
  113. package/docs/api/interfaces/DataTableToolbarButton.md +7 -7
  114. package/docs/api/interfaces/DatabaseComplianceResult.md +1 -1
  115. package/docs/api/interfaces/DatabaseIssue.md +1 -1
  116. package/docs/api/interfaces/EmptyStateConfig.md +5 -5
  117. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  118. package/docs/api/interfaces/ErrorBoundaryProps.md +147 -0
  119. package/docs/api/interfaces/ErrorBoundaryProviderProps.md +36 -0
  120. package/docs/api/interfaces/ErrorBoundaryState.md +75 -0
  121. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  122. package/docs/api/interfaces/ExportColumn.md +1 -1
  123. package/docs/api/interfaces/ExportOptions.md +8 -8
  124. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  125. package/docs/api/interfaces/FileMetadata.md +1 -1
  126. package/docs/api/interfaces/FileReference.md +1 -1
  127. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  128. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  129. package/docs/api/interfaces/FileUploadProps.md +26 -23
  130. package/docs/api/interfaces/FooterProps.md +10 -8
  131. package/docs/api/interfaces/FormFieldProps.md +10 -10
  132. package/docs/api/interfaces/FormProps.md +1 -1
  133. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  134. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  135. package/docs/api/interfaces/InputProps.md +7 -4
  136. package/docs/api/interfaces/LabelProps.md +1 -1
  137. package/docs/api/interfaces/LoggerConfig.md +1 -1
  138. package/docs/api/interfaces/LoginFormProps.md +14 -11
  139. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  140. package/docs/api/interfaces/NavigationContextType.md +1 -1
  141. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  142. package/docs/api/interfaces/NavigationItem.md +11 -11
  143. package/docs/api/interfaces/NavigationMenuProps.md +15 -15
  144. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  145. package/docs/api/interfaces/Organisation.md +1 -1
  146. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  147. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  148. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  149. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  150. package/docs/api/interfaces/PaceAppLayoutProps.md +30 -27
  151. package/docs/api/interfaces/PaceLoginPageProps.md +6 -4
  152. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  153. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  154. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  155. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  156. package/docs/api/interfaces/PaletteData.md +1 -1
  157. package/docs/api/interfaces/ParsedAddress.md +1 -1
  158. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  159. package/docs/api/interfaces/ProgressProps.md +1 -1
  160. package/docs/api/interfaces/ProtectedRouteProps.md +7 -26
  161. package/docs/api/interfaces/PublicPageFooterProps.md +9 -9
  162. package/docs/api/interfaces/PublicPageHeaderProps.md +10 -10
  163. package/docs/api/interfaces/PublicPageLayoutProps.md +7 -20
  164. package/docs/api/interfaces/QuickFix.md +1 -1
  165. package/docs/api/interfaces/RBACAccessValidateParams.md +1 -1
  166. package/docs/api/interfaces/RBACAccessValidateResult.md +1 -1
  167. package/docs/api/interfaces/RBACAuditLogParams.md +1 -1
  168. package/docs/api/interfaces/RBACAuditLogResult.md +1 -1
  169. package/docs/api/interfaces/RBACConfig.md +1 -1
  170. package/docs/api/interfaces/RBACContext.md +1 -1
  171. package/docs/api/interfaces/RBACLogger.md +1 -1
  172. package/docs/api/interfaces/RBACPageAccessCheckParams.md +1 -1
  173. package/docs/api/interfaces/RBACPerformanceMetrics.md +1 -1
  174. package/docs/api/interfaces/RBACPermissionCheckParams.md +1 -1
  175. package/docs/api/interfaces/RBACPermissionCheckResult.md +1 -1
  176. package/docs/api/interfaces/RBACPermissionsGetParams.md +1 -1
  177. package/docs/api/interfaces/RBACPermissionsGetResult.md +1 -1
  178. package/docs/api/interfaces/RBACResult.md +1 -1
  179. package/docs/api/interfaces/RBACRoleGrantParams.md +1 -1
  180. package/docs/api/interfaces/RBACRoleGrantResult.md +1 -1
  181. package/docs/api/interfaces/RBACRoleRevokeParams.md +1 -1
  182. package/docs/api/interfaces/RBACRoleRevokeResult.md +1 -1
  183. package/docs/api/interfaces/RBACRoleValidateParams.md +1 -1
  184. package/docs/api/interfaces/RBACRoleValidateResult.md +1 -1
  185. package/docs/api/interfaces/RBACRolesListParams.md +1 -1
  186. package/docs/api/interfaces/RBACRolesListResult.md +1 -1
  187. package/docs/api/interfaces/RBACSessionTrackParams.md +1 -1
  188. package/docs/api/interfaces/RBACSessionTrackResult.md +1 -1
  189. package/docs/api/interfaces/ResourcePermissions.md +1 -1
  190. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  191. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  192. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  193. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  194. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  195. package/docs/api/interfaces/RouteConfig.md +1 -1
  196. package/docs/api/interfaces/RuntimeComplianceResult.md +1 -1
  197. package/docs/api/interfaces/SecureDataContextType.md +9 -9
  198. package/docs/api/interfaces/SecureDataProviderProps.md +8 -8
  199. package/docs/api/interfaces/SessionRestorationLoaderProps.md +3 -3
  200. package/docs/api/interfaces/SetupIssue.md +1 -1
  201. package/docs/api/interfaces/StorageConfig.md +1 -1
  202. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  203. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  204. package/docs/api/interfaces/StorageListOptions.md +1 -1
  205. package/docs/api/interfaces/StorageListResult.md +1 -1
  206. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  207. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  208. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  209. package/docs/api/interfaces/StyleImport.md +1 -1
  210. package/docs/api/interfaces/SwitchProps.md +1 -1
  211. package/docs/api/interfaces/TabsContentProps.md +1 -1
  212. package/docs/api/interfaces/TabsListProps.md +1 -1
  213. package/docs/api/interfaces/TabsProps.md +1 -1
  214. package/docs/api/interfaces/TabsTriggerProps.md +3 -3
  215. package/docs/api/interfaces/TextareaProps.md +1 -1
  216. package/docs/api/interfaces/ToastActionElement.md +4 -1
  217. package/docs/api/interfaces/ToastProps.md +1 -1
  218. package/docs/api/interfaces/UnifiedAuthContextType.md +58 -55
  219. package/docs/api/interfaces/UnifiedAuthProviderProps.md +15 -13
  220. package/docs/api/interfaces/UseFormDialogOptions.md +1 -1
  221. package/docs/api/interfaces/UseFormDialogReturn.md +1 -1
  222. package/docs/api/interfaces/UseInactivityTrackerOptions.md +11 -9
  223. package/docs/api/interfaces/UseInactivityTrackerReturn.md +8 -8
  224. package/docs/api/interfaces/UsePublicEventLogoOptions.md +6 -6
  225. package/docs/api/interfaces/UsePublicEventLogoReturn.md +9 -6
  226. package/docs/api/interfaces/UsePublicEventOptions.md +3 -3
  227. package/docs/api/interfaces/UsePublicEventReturn.md +8 -5
  228. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +4 -4
  229. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +12 -9
  230. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +10 -7
  231. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  232. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  233. package/docs/api/interfaces/UseResourcePermissionsOptions.md +1 -1
  234. package/docs/api/interfaces/UserEventAccess.md +14 -11
  235. package/docs/api/interfaces/UserMenuProps.md +8 -6
  236. package/docs/api/interfaces/UserProfile.md +1 -1
  237. package/docs/api/modules.md +575 -634
  238. package/docs/architecture/database-schema-requirements.md +161 -0
  239. package/docs/core-concepts/rbac-system.md +3 -3
  240. package/docs/documentation-index.md +2 -4
  241. package/docs/getting-started/cursor-rules.md +263 -0
  242. package/docs/getting-started/installation-guide.md +6 -1
  243. package/docs/getting-started/quick-start.md +6 -1
  244. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  245. package/docs/migration/MIGRATION_GUIDE.md +6 -28
  246. package/docs/migration/README.md +52 -6
  247. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  248. package/docs/migration/V0.6.0_REACT_19_MIGRATION.md +227 -0
  249. package/docs/migration/database-changes-december-2025.md +3 -3
  250. package/docs/rbac/event-based-apps.md +1 -1
  251. package/docs/rbac/getting-started.md +1 -1
  252. package/docs/rbac/quick-start.md +1 -1
  253. package/docs/standards/README.md +40 -0
  254. package/docs/troubleshooting/migration.md +4 -4
  255. package/examples/PublicPages/PublicEventPage.tsx +1 -1
  256. package/package.json +12 -6
  257. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  258. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  259. package/scripts/audit/core/checks/bundle.cjs +142 -0
  260. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +737 -691
  261. package/scripts/audit/core/checks/config.cjs +54 -0
  262. package/scripts/audit/core/checks/coverage.cjs +84 -0
  263. package/scripts/audit/core/checks/dependencies.cjs +454 -0
  264. package/scripts/audit/core/checks/documentation.cjs +203 -0
  265. package/scripts/audit/core/checks/environment.cjs +128 -0
  266. package/scripts/audit/core/checks/error-handling.cjs +299 -0
  267. package/scripts/audit/core/checks/forms.cjs +172 -0
  268. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  269. package/scripts/audit/core/checks/hooks.cjs +334 -0
  270. package/scripts/audit/core/checks/imports.cjs +244 -0
  271. package/scripts/audit/core/checks/performance.cjs +325 -0
  272. package/scripts/audit/core/checks/routes.cjs +117 -0
  273. package/scripts/audit/core/checks/state.cjs +130 -0
  274. package/scripts/audit/core/checks/structure.cjs +65 -0
  275. package/scripts/audit/core/checks/style.cjs +584 -0
  276. package/scripts/audit/core/checks/testing.cjs +122 -0
  277. package/scripts/audit/core/checks/typescript.cjs +61 -0
  278. package/scripts/audit/core/scanner.cjs +199 -0
  279. package/scripts/audit/core/utils.cjs +137 -0
  280. package/scripts/audit/index.cjs +223 -0
  281. package/scripts/audit/reporters/console.cjs +151 -0
  282. package/scripts/audit/reporters/json.cjs +54 -0
  283. package/scripts/audit/reporters/markdown.cjs +124 -0
  284. package/scripts/audit-consuming-app.cjs +86 -0
  285. package/scripts/build-docs/build-decision.js +240 -0
  286. package/scripts/build-docs/cache-utils.js +105 -0
  287. package/scripts/build-docs/content-normalization.js +150 -0
  288. package/scripts/build-docs/file-utils.js +105 -0
  289. package/scripts/build-docs/git-utils.js +86 -0
  290. package/scripts/build-docs/hash-utils.js +116 -0
  291. package/scripts/build-docs/typedoc-runner.js +220 -0
  292. package/scripts/build-docs-incremental.js +77 -913
  293. package/scripts/install-cursor-rules.cjs +236 -0
  294. package/scripts/utils/command-runner.js +16 -11
  295. package/scripts/validate-formats.js +61 -56
  296. package/scripts/validate-master.js +74 -69
  297. package/scripts/validate-pre-publish.js +70 -65
  298. package/src/__tests__/helpers/test-providers.tsx +1 -1
  299. package/src/__tests__/helpers/test-utils.tsx +1 -1
  300. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  301. package/src/components/Alert/Alert.test.tsx +12 -18
  302. package/src/components/Alert/Alert.tsx +5 -7
  303. package/src/components/Avatar/Avatar.test.tsx +4 -4
  304. package/src/components/Badge/Badge.tsx +16 -4
  305. package/src/components/Button/Button.tsx +27 -4
  306. package/src/components/Calendar/Calendar.tsx +9 -3
  307. package/src/components/Card/Card.tsx +4 -0
  308. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  309. package/src/components/Checkbox/Checkbox.tsx +2 -2
  310. package/src/components/DataTable/DataTable.test.tsx +57 -93
  311. package/src/components/DataTable/DataTable.tsx +40 -6
  312. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  313. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +29 -7
  314. package/src/components/DataTable/__tests__/ssr.strict-mode.test.tsx +12 -12
  315. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  316. package/src/components/DataTable/components/AccessDeniedPage.tsx +17 -26
  317. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  318. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +2 -2
  319. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  320. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  321. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  322. package/src/components/DataTable/components/DataTableCore.tsx +200 -561
  323. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  324. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  325. package/src/components/DataTable/components/DataTableModals.tsx +9 -1
  326. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  327. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  328. package/src/components/DataTable/components/EditFields.tsx +307 -0
  329. package/src/components/DataTable/components/EditableRow.tsx +9 -1
  330. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  331. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  332. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  333. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  334. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  335. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  336. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  337. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  338. package/src/components/DataTable/components/UnifiedTableBody.tsx +62 -852
  339. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  340. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  341. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +23 -23
  342. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +11 -11
  343. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +36 -36
  344. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +27 -27
  345. package/src/components/DataTable/components/__tests__/ImportModal.test.tsx +39 -39
  346. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +33 -33
  347. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +29 -29
  348. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  349. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  350. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  351. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  352. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  353. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  354. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  355. package/src/components/DataTable/hooks/useColumnReordering.ts +14 -2
  356. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  357. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  358. package/src/components/DataTable/hooks/useDataTablePermissions.ts +124 -32
  359. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  360. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  361. package/src/components/DataTable/hooks/useKeyboardNavigation.ts +2 -2
  362. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  363. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  364. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  365. package/src/components/DataTable/styles.ts +6 -6
  366. package/src/components/DataTable/types.ts +6 -10
  367. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  368. package/src/components/DataTable/utils/debugTools.ts +18 -113
  369. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  370. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  371. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  372. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  373. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  374. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +8 -14
  375. package/src/components/Dialog/Dialog.tsx +8 -7
  376. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  377. package/src/components/ErrorBoundary/ErrorBoundary.tsx +46 -6
  378. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  379. package/src/components/ErrorBoundary/index.ts +27 -2
  380. package/src/components/EventSelector/EventSelector.tsx +4 -1
  381. package/src/components/FileDisplay/FileDisplay.test.tsx +2 -2
  382. package/src/components/FileDisplay/FileDisplay.tsx +32 -18
  383. package/src/components/FileUpload/FileUpload.tsx +22 -2
  384. package/src/components/Footer/Footer.test.tsx +16 -16
  385. package/src/components/Footer/Footer.tsx +15 -12
  386. package/src/components/Form/Form.test.tsx +36 -15
  387. package/src/components/Form/Form.tsx +31 -26
  388. package/src/components/Header/Header.tsx +22 -11
  389. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +40 -40
  390. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +1 -1
  391. package/src/components/Input/Input.test.tsx +2 -2
  392. package/src/components/Input/Input.tsx +36 -34
  393. package/src/components/Label/Label.tsx +1 -1
  394. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  395. package/src/components/LoadingSpinner/LoadingSpinner.tsx +1 -1
  396. package/src/components/LoginForm/LoginForm.test.tsx +42 -42
  397. package/src/components/LoginForm/LoginForm.tsx +12 -8
  398. package/src/components/NavigationMenu/NavigationMenu.tsx +15 -514
  399. package/src/components/NavigationMenu/types.ts +56 -0
  400. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  401. package/src/components/OrganisationSelector/OrganisationSelector.tsx +3 -0
  402. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +1 -1
  403. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +54 -52
  404. package/src/components/PaceAppLayout/PaceAppLayout.tsx +33 -12
  405. package/src/components/PaceAppLayout/README.md +1 -1
  406. package/src/components/PaceAppLayout/test-setup.tsx +1 -2
  407. package/src/components/PaceLoginPage/PaceLoginPage.tsx +4 -1
  408. package/src/components/PasswordChange/PasswordChangeForm.test.tsx +33 -33
  409. package/src/components/PasswordChange/PasswordChangeForm.tsx +10 -1
  410. package/src/components/Progress/Progress.tsx +1 -1
  411. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  412. package/src/components/PublicLayout/PublicPageLayout.tsx +3 -6
  413. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  414. package/src/components/Select/Select.tsx +95 -438
  415. package/src/components/Select/context.ts +23 -0
  416. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  417. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  418. package/src/components/Select/hooks/useSelectState.ts +104 -0
  419. package/src/components/Select/index.ts +9 -1
  420. package/src/components/Select/types.ts +123 -0
  421. package/src/components/Select/utils/text.ts +26 -0
  422. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +5 -6
  423. package/src/components/Switch/Switch.tsx +4 -4
  424. package/src/components/Table/Table.tsx +1 -1
  425. package/src/components/Tabs/Tabs.tsx +1 -1
  426. package/src/components/Textarea/Textarea.tsx +27 -29
  427. package/src/components/Toast/Toast.tsx +5 -1
  428. package/src/components/Tooltip/Tooltip.tsx +3 -3
  429. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  430. package/src/components/UserMenu/UserMenu.tsx +22 -19
  431. package/src/components/index.ts +2 -2
  432. package/src/hooks/__tests__/hooks.integration.test.tsx +80 -55
  433. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  434. package/src/hooks/__tests__/useStorage.unit.test.ts +36 -36
  435. package/src/hooks/index.ts +1 -2
  436. package/src/hooks/public/usePublicEvent.ts +5 -1
  437. package/src/hooks/public/usePublicEventLogo.ts +5 -1
  438. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  439. package/src/hooks/public/usePublicRouteParams.ts +5 -1
  440. package/src/hooks/services/useAuth.ts +32 -0
  441. package/src/hooks/services/useCurrentEvent.ts +6 -0
  442. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  443. package/src/hooks/useDataTableState.ts +8 -18
  444. package/src/hooks/useDebounce.ts +9 -0
  445. package/src/hooks/useEventTheme.ts +6 -0
  446. package/src/hooks/useFileDisplay.ts +4 -0
  447. package/src/hooks/useFileReference.ts +25 -7
  448. package/src/hooks/useFileUrl.ts +11 -1
  449. package/src/hooks/useFocusManagement.ts +16 -2
  450. package/src/hooks/useFocusTrap.ts +7 -4
  451. package/src/hooks/useFormDialog.ts +8 -7
  452. package/src/hooks/useInactivityTracker.ts +4 -1
  453. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  454. package/src/hooks/useOrganisationPermissions.ts +4 -0
  455. package/src/hooks/useOrganisationSecurity.ts +4 -0
  456. package/src/hooks/usePerformanceMonitor.ts +4 -0
  457. package/src/hooks/usePermissionCache.ts +8 -1
  458. package/src/hooks/useQueryCache.ts +12 -1
  459. package/src/hooks/useSessionRestoration.ts +4 -0
  460. package/src/hooks/useStorage.ts +4 -0
  461. package/src/hooks/useToast.ts +3 -3
  462. package/src/index.ts +2 -1
  463. package/src/providers/__tests__/OrganisationProvider.test.tsx +115 -49
  464. package/src/providers/__tests__/ProviderLifecycle.test.tsx +21 -6
  465. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +10 -10
  466. package/src/providers/services/AuthServiceProvider.tsx +18 -0
  467. package/src/providers/services/EventServiceProvider.tsx +18 -0
  468. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  469. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  470. package/src/providers/services/UnifiedAuthProvider.tsx +58 -22
  471. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +33 -7
  472. package/src/rbac/README.md +1 -1
  473. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +26 -26
  474. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  475. package/src/rbac/adapters.tsx +14 -5
  476. package/src/rbac/api.ts +100 -67
  477. package/src/rbac/components/EnhancedNavigationMenu.tsx +1 -1
  478. package/src/rbac/components/NavigationGuard.tsx +1 -1
  479. package/src/rbac/components/NavigationProvider.tsx +5 -2
  480. package/src/rbac/components/PagePermissionGuard.tsx +158 -18
  481. package/src/rbac/components/PagePermissionProvider.tsx +1 -1
  482. package/src/rbac/components/PermissionEnforcer.tsx +1 -1
  483. package/src/rbac/components/RoleBasedRouter.tsx +6 -2
  484. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  485. package/src/rbac/components/SecureDataProvider.tsx +21 -6
  486. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  487. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  488. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  489. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  490. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  491. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  492. package/src/rbac/engine.ts +38 -14
  493. package/src/rbac/hooks/permissions/index.ts +7 -0
  494. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  495. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  496. package/src/rbac/hooks/permissions/useCan.ts +347 -0
  497. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  498. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  499. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  500. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  501. package/src/rbac/hooks/useCan.test.ts +71 -64
  502. package/src/rbac/hooks/usePermissions.ts +14 -995
  503. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  504. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  505. package/src/rbac/hooks/useSecureSupabase.ts +33 -13
  506. package/src/rbac/permissions.ts +0 -30
  507. package/src/rbac/secureClient.ts +212 -61
  508. package/src/rbac/types.ts +8 -0
  509. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  510. package/src/theming/parseEventColours.ts +5 -19
  511. package/src/types/vitest-globals.d.ts +51 -26
  512. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  513. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  514. package/src/utils/__tests__/index.unit.test.ts +2 -2
  515. package/src/utils/audit/audit.ts +0 -3
  516. package/src/utils/core/cn.ts +1 -1
  517. package/src/utils/file-reference/index.ts +53 -1
  518. package/src/utils/formatting/formatting.ts +8 -18
  519. package/src/utils/index.ts +0 -1
  520. package/src/utils/security/secureDataAccess.test.ts +31 -20
  521. package/src/utils/security/secureDataAccess.ts +4 -3
  522. package/dist/chunk-6C4YBBJM.js +0 -628
  523. package/dist/chunk-6C4YBBJM.js.map +0 -1
  524. package/dist/chunk-7D4SUZUM.js 2.map +0 -1
  525. package/dist/chunk-7EQTDTTJ.js 2.map +0 -1
  526. package/dist/chunk-7EQTDTTJ.js.map +0 -1
  527. package/dist/chunk-7FLMSG37.js 2.map +0 -1
  528. package/dist/chunk-7FLMSG37.js.map +0 -1
  529. package/dist/chunk-BC4IJKSL.js.map +0 -1
  530. package/dist/chunk-E3SPN4VZ.js +0 -12917
  531. package/dist/chunk-E3SPN4VZ.js.map +0 -1
  532. package/dist/chunk-E66EQZE6 5.js +0 -37
  533. package/dist/chunk-E66EQZE6.js 2.map +0 -1
  534. package/dist/chunk-HWIIPPNI.js.map +0 -1
  535. package/dist/chunk-I7PSE6JW 5.js +0 -191
  536. package/dist/chunk-I7PSE6JW.js 2.map +0 -1
  537. package/dist/chunk-I7PSE6JW.js.map +0 -1
  538. package/dist/chunk-IIELH4DL.js.map +0 -1
  539. package/dist/chunk-KNC55RTG.js 5.map +0 -1
  540. package/dist/chunk-KNC55RTG.js.map +0 -1
  541. package/dist/chunk-KQCRWDSA.js 5.map +0 -1
  542. package/dist/chunk-LFNCN2SP.js +0 -412
  543. package/dist/chunk-LFNCN2SP.js 2.map +0 -1
  544. package/dist/chunk-LFNCN2SP.js.map +0 -1
  545. package/dist/chunk-LMC26NLJ 2.js +0 -84
  546. package/dist/chunk-NOAYCWCX.js +0 -4993
  547. package/dist/chunk-NOAYCWCX.js.map +0 -1
  548. package/dist/chunk-QWWZ5CAQ.js 3.map +0 -1
  549. package/dist/chunk-QWWZ5CAQ.js.map +0 -1
  550. package/dist/chunk-QXHPKYJV 3.js +0 -113
  551. package/dist/chunk-R77UEZ4E.js +0 -68
  552. package/dist/chunk-R77UEZ4E.js.map +0 -1
  553. package/dist/chunk-SQGMNID3.js.map +0 -1
  554. package/dist/chunk-VBXEHIUJ.js 6.map +0 -1
  555. package/dist/chunk-XNXXZ43G.js.map +0 -1
  556. package/dist/chunk-ZSAAAMVR 6.js +0 -25
  557. package/dist/components.js 5.map +0 -1
  558. package/dist/styles/index 2.js +0 -12
  559. package/dist/styles/index.js 5.map +0 -1
  560. package/dist/theming/runtime 5.js +0 -19
  561. package/dist/theming/runtime.js 5.map +0 -1
  562. package/docs/api/classes/ErrorBoundary.md +0 -144
  563. package/docs/migration/quick-migration-guide.md +0 -356
  564. package/docs/migration/service-architecture.md +0 -281
  565. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  566. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  567. package/src/hooks/useSecureDataAccess.ts +0 -666
  568. /package/dist/{DataTable-5FU7IESH.js.map → DataTable-TPTKCX4D.js.map} +0 -0
  569. /package/dist/{UnifiedAuthProvider-RGJTDE2C.js.map → UnifiedAuthProvider-CH6Z342H.js.map} +0 -0
  570. /package/dist/{api-N774RPUA.js.map → api-MVVQZLJI.js.map} +0 -0
  571. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  572. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  573. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  574. /package/examples/{rbac → RBAC}/CompleteRBACExample.tsx +0 -0
  575. /package/examples/{rbac → RBAC}/EventBasedApp.tsx +0 -0
  576. /package/examples/{rbac → RBAC}/PermissionExample.tsx +0 -0
  577. /package/examples/{rbac → RBAC}/index.ts +0 -0
@@ -0,0 +1,307 @@
1
+ import React from 'react';
2
+ import { type Column } from '@tanstack/react-table';
3
+ import { Input } from '../../Input/Input';
4
+ import {
5
+ Select,
6
+ SelectContent,
7
+ SelectGroup,
8
+ SelectItem,
9
+ SelectLabel,
10
+ SelectSeparator,
11
+ SelectTrigger,
12
+ SelectValue,
13
+ } from '../../Select/Select';
14
+ import { createLogger } from '../../../utils/core/logger';
15
+ import type { CellValue, DataRecord, EditableColumnDef } from '../types';
16
+
17
+ /**
18
+ * Component for select fields with searchable and creatable support
19
+ */
20
+ export function SelectEditField<TData extends DataRecord>({
21
+ columnDef,
22
+ accessorKey,
23
+ currentValue,
24
+ placeholder,
25
+ onChange,
26
+ }: {
27
+ columnDef: EditableColumnDef<TData>;
28
+ accessorKey: string;
29
+ currentValue: CellValue;
30
+ placeholder?: string;
31
+ onChange: (value: CellValue) => void;
32
+ }) {
33
+ const logger = createLogger('SelectEditField');
34
+ const isSearchable = columnDef.selectSearchable !== false;
35
+ const isCreatable = columnDef.creatable === true;
36
+ const selectRef = React.useRef<HTMLFormElement>(null);
37
+ const [searchTerm, setSearchTerm] = React.useState('');
38
+ const [isOpen, setIsOpen] = React.useState(false);
39
+ const [showCreateOption, setShowCreateOption] = React.useState(false);
40
+
41
+ React.useEffect(() => {
42
+ if (!isOpen || !isSearchable || !isCreatable || !columnDef.onCreateNew) {
43
+ if (!isOpen || !isCreatable || !columnDef.onCreateNew) {
44
+ setShowCreateOption(false);
45
+ }
46
+ return;
47
+ }
48
+
49
+ const findAndAttachSearchInput = (): (() => void) | null => {
50
+ let searchInput: HTMLInputElement | null = null;
51
+
52
+ if (selectRef.current) {
53
+ searchInput = selectRef.current.querySelector<HTMLInputElement>('[data-testid="select-search-input"]');
54
+ }
55
+
56
+ if (!searchInput) {
57
+ const allSearchInputs = document.querySelectorAll<HTMLInputElement>('[data-testid="select-search-input"]');
58
+ for (const input of Array.from(allSearchInputs)) {
59
+ const content = input.closest('[data-testid="select-content"]');
60
+ if (content && content.getAttribute('aria-hidden') !== 'true') {
61
+ searchInput = input;
62
+ break;
63
+ }
64
+ }
65
+ }
66
+
67
+ if (!searchInput) return null;
68
+
69
+ const handleInput = (e: Event) => {
70
+ const target = e.target as HTMLInputElement;
71
+ const currentSearch = target.value;
72
+ setSearchTerm(currentSearch);
73
+
74
+ if (currentSearch.trim()) {
75
+ const searchLower = currentSearch.toLowerCase().trim();
76
+
77
+ type FieldOption =
78
+ | { value: string | number; label: string }
79
+ | { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }
80
+ | { type: 'separator' };
81
+
82
+ const checkMatch = (opt: FieldOption): boolean => {
83
+ if ('value' in opt && !('type' in opt)) {
84
+ return opt.label.toLowerCase().includes(searchLower);
85
+ }
86
+ if ('type' in opt && opt.type === 'group') {
87
+ return (
88
+ (opt as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }).items.some(
89
+ (item: { value: string | number; label: string }) => item.label.toLowerCase().includes(searchLower)
90
+ )
91
+ );
92
+ }
93
+ return false;
94
+ };
95
+
96
+ const shouldShow = isCreatable && !!columnDef.onCreateNew;
97
+
98
+ setShowCreateOption(shouldShow);
99
+ } else {
100
+ setShowCreateOption(false);
101
+ }
102
+ };
103
+
104
+ const initialValue = searchInput.value;
105
+ if (initialValue) {
106
+ const currentSearch = initialValue;
107
+ setSearchTerm(currentSearch);
108
+
109
+ if (currentSearch.trim()) {
110
+ const searchLower = currentSearch.toLowerCase().trim();
111
+
112
+ type FieldOption =
113
+ | { value: string | number; label: string }
114
+ | { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }
115
+ | { type: 'separator' };
116
+
117
+ const checkMatch = (opt: FieldOption): boolean => {
118
+ if ('value' in opt && !('type' in opt)) {
119
+ return opt.label.toLowerCase().includes(searchLower);
120
+ }
121
+ if ('type' in opt && opt.type === 'group') {
122
+ return (
123
+ (opt as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> }).items.some(
124
+ (item: { value: string | number; label: string }) => item.label.toLowerCase().includes(searchLower)
125
+ )
126
+ );
127
+ }
128
+ return false;
129
+ };
130
+
131
+ const shouldShow = isCreatable && !!columnDef.onCreateNew;
132
+ setShowCreateOption(shouldShow);
133
+ } else {
134
+ setShowCreateOption(false);
135
+ }
136
+ }
137
+
138
+ searchInput.addEventListener('input', handleInput);
139
+
140
+ return () => {
141
+ searchInput?.removeEventListener('input', handleInput);
142
+ };
143
+ };
144
+
145
+ let cleanup: (() => void) | null = findAndAttachSearchInput();
146
+
147
+ if (!cleanup) {
148
+ let timeoutCleanup: (() => void) | null = null;
149
+ const timeoutId = setTimeout(() => {
150
+ timeoutCleanup = findAndAttachSearchInput();
151
+ }, 50);
152
+
153
+ return () => {
154
+ clearTimeout(timeoutId);
155
+ timeoutCleanup?.();
156
+ };
157
+ }
158
+
159
+ return cleanup;
160
+ }, [isOpen, isSearchable, isCreatable, columnDef.fieldOptions, columnDef.onCreateNew]);
161
+
162
+ const handleCreateNew = React.useCallback(async () => {
163
+ if (!isCreatable || !columnDef.onCreateNew || !searchTerm.trim()) return;
164
+
165
+ try {
166
+ const newValue = await columnDef.onCreateNew(searchTerm.trim());
167
+ onChange(newValue);
168
+ setSearchTerm('');
169
+ setShowCreateOption(false);
170
+ } catch (error) {
171
+ logger.error('Error creating new item:', error);
172
+ }
173
+ }, [isCreatable, columnDef.onCreateNew, searchTerm, onChange, logger]);
174
+
175
+ return (
176
+ <Select
177
+ ref={selectRef}
178
+ value={String(currentValue)}
179
+ onValueChange={(newValue) => {
180
+ if (newValue.startsWith('__create_new__')) {
181
+ handleCreateNew();
182
+ } else {
183
+ onChange(newValue as CellValue);
184
+ }
185
+ }}
186
+ onOpenChange={(open) => {
187
+ setIsOpen(open);
188
+ if (!open) {
189
+ setSearchTerm('');
190
+ setShowCreateOption(false);
191
+ }
192
+ }}
193
+ >
194
+ <SelectTrigger className="h-8">
195
+ <SelectValue placeholder={placeholder || `Select ${columnDef.header || 'option'}...`} />
196
+ </SelectTrigger>
197
+ <SelectContent
198
+ searchable={Boolean(isSearchable)}
199
+ searchPlaceholder={`Search ${columnDef.header || 'options'}...`}
200
+ maxHeight={columnDef.selectMaxHeight}
201
+ className={columnDef.selectContentClassName}
202
+ style={columnDef.selectContentStyle}
203
+ >
204
+ {columnDef.fieldOptions?.map((option, index) => {
205
+ if ('value' in option && !('type' in option)) {
206
+ return (
207
+ <SelectItem key={`${option.value}-${index}`} value={String(option.value)}>
208
+ {option.label}
209
+ </SelectItem>
210
+ );
211
+ }
212
+
213
+ if ('type' in option && option.type === 'separator') {
214
+ return <SelectSeparator key={`separator-${index}`} />;
215
+ }
216
+
217
+ if ('type' in option && option.type === 'group') {
218
+ const groupOption = option as { type: 'group'; label: string; items: Array<{ value: string | number; label: string }> };
219
+ return (
220
+ <SelectGroup key={`group-${groupOption.label}-${index}`}>
221
+ <SelectLabel>{groupOption.label}</SelectLabel>
222
+ {groupOption.items.map((item: { value: string | number; label: string }) => (
223
+ <SelectItem key={`${item.value}-${index}`} value={String(item.value)}>
224
+ {item.label}
225
+ </SelectItem>
226
+ ))}
227
+ </SelectGroup>
228
+ );
229
+ }
230
+
231
+ return null;
232
+ })}
233
+ {showCreateOption && isCreatable && searchTerm.trim() && columnDef.onCreateNew && (
234
+ <SelectItem key="__create_new__" value={`__create_new__${searchTerm}`} className="bg-main-100 font-medium border-t border-main-200">
235
+ Create "{searchTerm}"
236
+ </SelectItem>
237
+ )}
238
+ </SelectContent>
239
+ </Select>
240
+ );
241
+ }
242
+
243
+ /**
244
+ * Helper function to render the appropriate input type based on column configuration
245
+ */
246
+ export const renderEditField = <TData extends DataRecord>(
247
+ column: Column<TData, unknown>,
248
+ value: CellValue,
249
+ onChange: (value: CellValue | Record<string, CellValue>) => void,
250
+ editingData: Record<string, CellValue> = {},
251
+ placeholder?: string
252
+ ): React.ReactElement => {
253
+ const columnDef = column.columnDef as EditableColumnDef<TData>;
254
+
255
+ if (columnDef.editable === false) {
256
+ return <span className="text-sm text-sec-600">{String(value ?? '')}</span>;
257
+ }
258
+
259
+ if (columnDef.fieldType === 'select' && columnDef.fieldOptions) {
260
+ const accessorKey = columnDef.editAccessorKey || column.id;
261
+ const currentValue = editingData[accessorKey] ?? value ?? '';
262
+
263
+ return (
264
+ <SelectEditField
265
+ columnDef={columnDef}
266
+ accessorKey={accessorKey}
267
+ currentValue={currentValue}
268
+ placeholder={placeholder}
269
+ onChange={(newValue) => onChange({ [accessorKey]: newValue })}
270
+ />
271
+ );
272
+ }
273
+
274
+ if (columnDef.fieldType === 'number') {
275
+ const hideSpinners = columnDef.hideNumberSpinners !== false;
276
+ return (
277
+ <Input
278
+ type="number"
279
+ value={String(value ?? '')}
280
+ onChange={(e) => onChange(e.target.value as unknown as CellValue)}
281
+ placeholder={placeholder || `Enter ${columnDef.header || column.id}...`}
282
+ className={`h-8 ${hideSpinners ? 'datatable-number-no-spinners' : ''}`}
283
+ />
284
+ );
285
+ }
286
+
287
+ if (columnDef.fieldType === 'date') {
288
+ return (
289
+ <Input
290
+ type="date"
291
+ value={String(value ?? '')}
292
+ onChange={(e) => onChange(e.target.value as unknown as CellValue)}
293
+ className="h-8"
294
+ />
295
+ );
296
+ }
297
+
298
+ return (
299
+ <Input
300
+ type="text"
301
+ value={String(value ?? '')}
302
+ onChange={(e) => onChange(e.target.value as unknown as CellValue)}
303
+ placeholder={placeholder || `Enter ${columnDef.header || column.id}...`}
304
+ className="h-8"
305
+ />
306
+ );
307
+ };
@@ -45,7 +45,7 @@ function SelectEditField<TData extends DataRecord>({
45
45
  onChange: (value: CellValue) => void;
46
46
  className?: string;
47
47
  }) {
48
- const logger = React.useMemo(() => createLogger('SelectEditField'), []);
48
+ const logger = createLogger('SelectEditField');
49
49
  // Determine if searchable - explicitly check for true to ensure visible search input appears
50
50
  // When selectSearchable is true or undefined, show the visible search input box
51
51
  // When selectSearchable is false, hide the search input (type-to-search still works via SelectContent internals)
@@ -337,6 +337,14 @@ const renderEditField = <TData extends DataRecord>(
337
337
  );
338
338
  };
339
339
 
340
+ /**
341
+ * Editable row component for DataTable.
342
+ * Renders a row in edit mode with input fields for each editable column.
343
+ *
344
+ * @template TData - The type of data records in the table
345
+ * @param props - Editable row configuration
346
+ * @returns The rendered editable row
347
+ */
340
348
  export function EditableRow<TData extends DataRecord>({
341
349
  row,
342
350
  editingData,
@@ -2,6 +2,9 @@ import React from 'react';
2
2
  import { Database, Search, Plus, User } from 'lucide-react';
3
3
  import { Button } from '../../Button/Button';
4
4
 
5
+ /**
6
+ * Props for the EmptyState component.
7
+ */
5
8
  interface EmptyStateProps {
6
9
  title?: string;
7
10
  description?: string;
@@ -14,6 +17,13 @@ interface EmptyStateProps {
14
17
  onClearFilters?: () => void;
15
18
  }
16
19
 
20
+ /**
21
+ * Empty state component for DataTable.
22
+ * Displays a message when the table has no data or no filtered results.
23
+ *
24
+ * @param props - Empty state configuration
25
+ * @returns The rendered empty state UI
26
+ */
17
27
  export function EmptyState({
18
28
  title,
19
29
  description,
@@ -5,11 +5,23 @@ import { getColumnHeaderText } from '../utils/columnUtils';
5
5
  import type { Column } from '@tanstack/react-table';
6
6
  import type { DataRecord } from '../types';
7
7
 
8
+ /**
9
+ * Props for the FilterRow component.
10
+ * @template TData - The type of data records in the table
11
+ */
8
12
  interface FilterRowProps<TData> {
9
13
  table: Table<TData>;
10
14
  visibleColumns: Header<TData, unknown>[];
11
15
  }
12
16
 
17
+ /**
18
+ * Filter row component for DataTable.
19
+ * Renders filter inputs for each visible column.
20
+ *
21
+ * @template TData - The type of data records in the table
22
+ * @param props - Filter row configuration
23
+ * @returns The rendered filter row
24
+ */
13
25
  export function FilterRow<TData>({ table, visibleColumns }: FilterRowProps<TData>) {
14
26
  const { getState } = table;
15
27
  const { columnFilters } = getState();
@@ -3,6 +3,10 @@ import { Row } from '@tanstack/react-table';
3
3
  import { Button } from '../../Button/Button';
4
4
  import { ChevronDown, ChevronRight } from 'lucide-react';
5
5
 
6
+ /**
7
+ * Props for the GroupHeader component.
8
+ * @template TData - The type of data records in the table
9
+ */
6
10
  interface GroupHeaderProps<TData> {
7
11
  row: Row<TData>;
8
12
  groupByColumn: string;
@@ -11,6 +15,14 @@ interface GroupHeaderProps<TData> {
11
15
  subRowsCount: number;
12
16
  }
13
17
 
18
+ /**
19
+ * Group header component for DataTable.
20
+ * Displays the group label and toggle button for expanding/collapsing grouped rows.
21
+ *
22
+ * @template TData - The type of data records in the table
23
+ * @param props - Group header configuration
24
+ * @returns The rendered group header
25
+ */
14
26
  export function GroupHeader<TData>({
15
27
  row,
16
28
  groupByColumn,
@@ -10,6 +10,10 @@ import {
10
10
  import { Group } from 'lucide-react';
11
11
  import type { DataTableColumn, DataRecord, SimpleColumn } from '../types';
12
12
 
13
+ /**
14
+ * Props for the GroupingDropdown component.
15
+ * @template TData - The type of data records in the table
16
+ */
13
17
  interface GroupingDropdownProps<TData extends DataRecord = DataRecord> {
14
18
  columns: (DataTableColumn<TData> | SimpleColumn<TData>)[];
15
19
  currentGroupBy: string | null;
@@ -17,6 +21,14 @@ interface GroupingDropdownProps<TData extends DataRecord = DataRecord> {
17
21
  className?: string;
18
22
  }
19
23
 
24
+ /**
25
+ * Dropdown component for selecting grouping column in DataTable.
26
+ * Allows users to group table rows by a specific column.
27
+ *
28
+ * @template TData - The type of data records in the table
29
+ * @param props - Grouping dropdown configuration
30
+ * @returns The rendered grouping dropdown
31
+ */
20
32
  export function GroupingDropdown<TData extends DataRecord>({
21
33
  columns,
22
34
  currentGroupBy,
@@ -108,6 +108,13 @@ interface ImportModalProps {
108
108
  * />
109
109
  * ```
110
110
  */
111
+ /**
112
+ * Import modal component for DataTable.
113
+ * Provides CSV file upload, preview, and import functionality.
114
+ *
115
+ * @param props - Import modal configuration
116
+ * @returns The rendered import modal dialog
117
+ */
111
118
  export function ImportModal({ isOpen, onClose, onImport, config = {} }: ImportModalProps) {
112
119
  const logger = createLogger('ImportModal');
113
120
  const [file, setFile] = useState<File | null>(null);
@@ -1,5 +1,11 @@
1
1
  import React from 'react';
2
2
 
3
+ /**
4
+ * Loading state component for DataTable.
5
+ * Displays a loading spinner and message while data is being fetched.
6
+ *
7
+ * @returns The rendered loading state UI
8
+ */
3
9
  export function LoadingState() {
4
10
  return (
5
11
  <div className="p-8 text-center">
@@ -16,6 +16,10 @@ import { Select, SelectContent, SelectItem, SelectTrigger, SelectValue } from '.
16
16
  import { getPaginationBinding, getPageSizeOptions } from '../utils/paginationUtils';
17
17
  import type { PaginationMode, ServerSideResponse, DataRecord } from '../types';
18
18
 
19
+ /**
20
+ * Props for the PaginationControls component.
21
+ * @template TData - The type of data records in the table
22
+ */
19
23
  interface PaginationControlsProps<TData extends DataRecord> {
20
24
  table: Table<TData>;
21
25
  pageSizeOptions?: number[];
@@ -28,6 +32,14 @@ interface PaginationControlsProps<TData extends DataRecord> {
28
32
  totalCount?: number;
29
33
  }
30
34
 
35
+ /**
36
+ * Pagination controls component for DataTable.
37
+ * Provides page navigation, page size selection, and performance information.
38
+ *
39
+ * @template TData - The type of data records in the table
40
+ * @param props - Pagination configuration
41
+ * @returns The rendered pagination controls
42
+ */
31
43
  export function PaginationControls<TData extends DataRecord>({
32
44
  table,
33
45
  pageSizeOptions = [10, 20, 30, 40, 50],
@@ -253,8 +265,10 @@ export function EnhancedPaginationControls<TData extends DataRecord>({
253
265
  <>
254
266
  {/* Jump to Page */}
255
267
  <form onSubmit={handleJumpToPage} className="flex items-center space-x-2">
256
- <span>Jump to page:</span>
268
+ <label htmlFor="jump-to-page-input" className="sr-only">Jump to page</label>
269
+ <span aria-hidden="true">Jump to page:</span>
257
270
  <input
271
+ id="jump-to-page-input"
258
272
  type="number"
259
273
  min="1"
260
274
  max={pageCount}
@@ -262,6 +276,7 @@ export function EnhancedPaginationControls<TData extends DataRecord>({
262
276
  onChange={(e) => setJumpToPage(e.target.value)}
263
277
  className="w-16 h-6 px-2 border rounded text-xs datatable-number-no-spinners"
264
278
  placeholder="1"
279
+ aria-label="Page number"
265
280
  />
266
281
  <Button type="submit" size="sm" variant="outline" className="h-6 px-2 text-xs">
267
282
  Go