@jmruthers/pace-core 0.6.1 → 0.6.3

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 (549) hide show
  1. package/CHANGELOG.md +88 -10
  2. package/cursor-rules/00-pace-core-compliance.mdc +46 -87
  3. package/cursor-rules/01-standards-compliance.mdc +16 -47
  4. package/cursor-rules/02-project-structure.mdc +4 -4
  5. package/cursor-rules/03-solid-principles.mdc +45 -164
  6. package/cursor-rules/04-testing-standards.mdc +22 -69
  7. package/cursor-rules/05-bug-reports-and-features.mdc +2 -2
  8. package/cursor-rules/06-code-quality.mdc +42 -125
  9. package/cursor-rules/07-tech-stack-compliance.mdc +33 -128
  10. package/cursor-rules/08-markup-quality.mdc +452 -0
  11. package/cursor-rules/CHANGELOG.md +18 -0
  12. package/cursor-rules/README.md +2 -1
  13. package/dist/{AuthService-DjnJHDtC.d.ts → AuthService-Cb34EQs3.d.ts} +63 -1
  14. package/dist/{DataTable-CH1U5Tpy.d.ts → DataTable-BMRU8a1j.d.ts} +33 -1
  15. package/dist/{DataTable-DQ7RSOHE.js → DataTable-THFPBKTP.js} +12 -10
  16. package/dist/{PublicPageProvider-ce4xlHYA.d.ts → PublicPageProvider-DEMpysFR.d.ts} +394 -171
  17. package/dist/{UnifiedAuthProvider-185Ih4dj.d.ts → UnifiedAuthProvider-CKvHP1MK.d.ts} +30 -8
  18. package/dist/{UnifiedAuthProvider-ATAP5UTR.js → UnifiedAuthProvider-KAGUYQ4J.js} +5 -4
  19. package/dist/{api-N774RPUA.js → api-IAGWF3ZG.js} +10 -10
  20. package/dist/{audit-B5P6FFIR.js → audit-V53FV5AG.js} +2 -2
  21. package/dist/{chunk-JBKQ3SAO.js → chunk-2T2IG7T7.js} +107 -57
  22. package/dist/chunk-2T2IG7T7.js.map +1 -0
  23. package/dist/{chunk-3QRJFVBR.js → chunk-6SOIHG6Z.js} +1 -1
  24. package/dist/chunk-6SOIHG6Z.js.map +1 -0
  25. package/dist/{chunk-3XTALGJF.js → chunk-6Z7LTB3D.js} +69 -240
  26. package/dist/chunk-6Z7LTB3D.js.map +1 -0
  27. package/dist/{chunk-4ZC4GX36.js → chunk-CNCQDFLN.js} +199 -46
  28. package/dist/chunk-CNCQDFLN.js.map +1 -0
  29. package/dist/chunk-DGUM43GV.js +11 -0
  30. package/dist/{chunk-BYFSK72L.js → chunk-DWUBLJJM.js} +361 -187
  31. package/dist/chunk-DWUBLJJM.js.map +1 -0
  32. package/dist/{chunk-LXQLPRQ2.js → chunk-FFQEQTNW.js} +6 -8
  33. package/dist/chunk-FFQEQTNW.js.map +1 -0
  34. package/dist/chunk-FMUCXFII.js +76 -0
  35. package/dist/chunk-FMUCXFII.js.map +1 -0
  36. package/dist/{chunk-4N5C5XZU.js → chunk-HFZBI76P.js} +4 -4
  37. package/dist/chunk-HFZBI76P.js.map +1 -0
  38. package/dist/{chunk-SQGMNID3.js → chunk-L4OXEN46.js} +4 -5
  39. package/dist/chunk-L4OXEN46.js.map +1 -0
  40. package/dist/{chunk-R77UEZ4E.js → chunk-M43Y4SSO.js} +1 -1
  41. package/dist/chunk-M43Y4SSO.js.map +1 -0
  42. package/dist/{chunk-I7PSE6JW.js → chunk-M7MPQISP.js} +3 -76
  43. package/dist/chunk-M7MPQISP.js.map +1 -0
  44. package/dist/chunk-PQBSKX33.js +7793 -0
  45. package/dist/chunk-PQBSKX33.js.map +1 -0
  46. package/dist/chunk-QRPVRXYT.js +226 -0
  47. package/dist/chunk-QRPVRXYT.js.map +1 -0
  48. package/dist/{chunk-KNC55RTG.js → chunk-RWEBCB47.js} +194 -416
  49. package/dist/chunk-RWEBCB47.js.map +1 -0
  50. package/dist/{chunk-XM25TVIE.js → chunk-YDQHOZNA.js} +843 -388
  51. package/dist/chunk-YDQHOZNA.js.map +1 -0
  52. package/dist/{chunk-GLK6VM3F.js → chunk-ZNIWI3UC.js} +739 -737
  53. package/dist/chunk-ZNIWI3UC.js.map +1 -0
  54. package/dist/components.d.ts +5 -5
  55. package/dist/components.js +18 -16
  56. package/dist/components.js.map +1 -1
  57. package/dist/contextValidator-3JNZKUTX.js +9 -0
  58. package/dist/contextValidator-3JNZKUTX.js.map +1 -0
  59. package/dist/eslint-rules/pace-core-compliance.cjs +106 -0
  60. package/dist/{functions-D_kgHktt.d.ts → functions-DHebl8-F.d.ts} +1 -1
  61. package/dist/hooks.d.ts +55 -122
  62. package/dist/hooks.js +10 -13
  63. package/dist/hooks.js.map +1 -1
  64. package/dist/index.d.ts +60 -13
  65. package/dist/index.js +30 -25
  66. package/dist/index.js.map +1 -1
  67. package/dist/providers.d.ts +21 -3
  68. package/dist/providers.js +4 -3
  69. package/dist/rbac/index.d.ts +210 -139
  70. package/dist/rbac/index.js +17 -13
  71. package/dist/styles/index.js +1 -1
  72. package/dist/theming/runtime.d.ts +1 -13
  73. package/dist/theming/runtime.js +2 -2
  74. package/dist/{timezone-_pgH8qrY.d.ts → timezone-CHhWg6b4.d.ts} +3 -10
  75. package/dist/{types-UU913iLA.d.ts → types-BeoeWV5I.d.ts} +8 -0
  76. package/dist/{types-CEpcvwwF.d.ts → types-CkbwOr4Y.d.ts} +6 -0
  77. package/dist/types.d.ts +2 -2
  78. package/dist/types.js +1 -1
  79. package/dist/{usePublicRouteParams-BJAlWfuJ.d.ts → usePublicRouteParams-i3qtoBgg.d.ts} +38 -17
  80. package/dist/utils.d.ts +4 -5
  81. package/dist/utils.js +17 -19
  82. package/dist/utils.js.map +1 -1
  83. package/docs/api/README.md +21 -17
  84. package/docs/api/modules.md +4191 -2967
  85. package/docs/architecture/database-schema-requirements.md +161 -0
  86. package/docs/components/context-selector.md +126 -0
  87. package/docs/core-concepts/rbac-system.md +3 -3
  88. package/docs/documentation-index.md +2 -4
  89. package/docs/getting-started/cursor-rules.md +2 -1
  90. package/docs/migration/DOCUMENTATION_STRUCTURE.md +441 -0
  91. package/docs/migration/MIGRATION_GUIDE.md +2 -24
  92. package/docs/migration/RBAC_SCOPE_MIGRATION.md +385 -0
  93. package/docs/migration/README.md +52 -6
  94. package/docs/migration/V0.5.190_TO_V0.6.1_MIGRATION.md +1153 -0
  95. package/docs/migration/database-changes-december-2025.md +3 -3
  96. package/docs/pace-mint-fix-auto-selection.md +218 -0
  97. package/docs/pace-mint-rbac-setup.md +391 -0
  98. package/docs/rbac/event-based-apps.md +1 -1
  99. package/docs/rbac/getting-started.md +1 -1
  100. package/docs/rbac/quick-start.md +1 -1
  101. package/docs/rbac/secure-client-protection.md +330 -0
  102. package/docs/standards/README.md +1 -0
  103. package/package.json +4 -3
  104. package/scripts/audit/core/checks/accessibility.cjs +197 -0
  105. package/scripts/audit/core/checks/api-usage.cjs +191 -0
  106. package/scripts/audit/core/checks/bundle.cjs +142 -0
  107. package/scripts/{check-pace-core-compliance.cjs → audit/core/checks/compliance.cjs} +784 -685
  108. package/scripts/audit/core/checks/config.cjs +54 -0
  109. package/scripts/audit/core/checks/coverage.cjs +84 -0
  110. package/scripts/audit/core/checks/dependencies.cjs +985 -0
  111. package/scripts/audit/core/checks/documentation.cjs +268 -0
  112. package/scripts/audit/core/checks/environment.cjs +116 -0
  113. package/scripts/audit/core/checks/error-handling.cjs +340 -0
  114. package/scripts/audit/core/checks/forms.cjs +172 -0
  115. package/scripts/audit/core/checks/heuristics.cjs +68 -0
  116. package/scripts/audit/core/checks/hooks.cjs +334 -0
  117. package/scripts/audit/core/checks/imports.cjs +244 -0
  118. package/scripts/audit/core/checks/performance.cjs +325 -0
  119. package/scripts/audit/core/checks/routes.cjs +117 -0
  120. package/scripts/audit/core/checks/state.cjs +130 -0
  121. package/scripts/audit/core/checks/structure.cjs +65 -0
  122. package/scripts/audit/core/checks/style.cjs +584 -0
  123. package/scripts/audit/core/checks/testing.cjs +122 -0
  124. package/scripts/audit/core/checks/typescript.cjs +61 -0
  125. package/scripts/audit/core/scanner.cjs +199 -0
  126. package/scripts/audit/core/utils.cjs +137 -0
  127. package/scripts/audit/index.cjs +223 -0
  128. package/scripts/audit/reporters/console.cjs +151 -0
  129. package/scripts/audit/reporters/json.cjs +54 -0
  130. package/scripts/audit/reporters/markdown.cjs +124 -0
  131. package/scripts/audit-consuming-app.cjs +61 -936
  132. package/scripts/build-docs/build-decision.js +240 -0
  133. package/scripts/build-docs/cache-utils.js +105 -0
  134. package/scripts/build-docs/content-normalization.js +150 -0
  135. package/scripts/build-docs/file-utils.js +105 -0
  136. package/scripts/build-docs/git-utils.js +86 -0
  137. package/scripts/build-docs/hash-utils.js +116 -0
  138. package/scripts/build-docs/typedoc-runner.js +220 -0
  139. package/scripts/build-docs-incremental.js +77 -913
  140. package/scripts/utils/command-runner.js +16 -11
  141. package/scripts/validate-formats.js +61 -56
  142. package/scripts/validate-master.js +74 -69
  143. package/scripts/validate-pre-publish.js +70 -65
  144. package/src/__tests__/hooks/usePermissions.test.ts +2 -2
  145. package/src/components/Alert/Alert.test.tsx +12 -18
  146. package/src/components/Alert/Alert.tsx +5 -7
  147. package/src/components/Avatar/Avatar.test.tsx +4 -4
  148. package/src/components/Badge/Badge.tsx +14 -0
  149. package/src/components/Button/Button.tsx +22 -0
  150. package/src/components/Calendar/Calendar.tsx +8 -2
  151. package/src/components/Card/Card.tsx +4 -0
  152. package/src/components/Checkbox/Checkbox.test.tsx +12 -12
  153. package/src/components/Checkbox/Checkbox.tsx +2 -2
  154. package/src/components/ContextSelector/ContextSelector.tsx +384 -0
  155. package/src/components/ContextSelector/index.ts +3 -0
  156. package/src/components/DataTable/DataTable.tsx +38 -4
  157. package/src/components/DataTable/__tests__/DataTableCore.test-setup.ts +5 -6
  158. package/src/components/DataTable/__tests__/pagination.modes.test.tsx +18 -4
  159. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +2 -3
  160. package/src/components/DataTable/components/AccessDeniedPage.tsx +16 -25
  161. package/src/components/DataTable/components/ActionButtons.tsx +10 -7
  162. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +1 -1
  163. package/src/components/DataTable/components/ColumnFilter.tsx +10 -0
  164. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +12 -0
  165. package/src/components/DataTable/components/DataTableBody.tsx +8 -0
  166. package/src/components/DataTable/components/DataTableCore.tsx +196 -554
  167. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +11 -0
  168. package/src/components/DataTable/components/DataTableLayout.tsx +559 -0
  169. package/src/components/DataTable/components/DataTableModals.tsx +8 -0
  170. package/src/components/DataTable/components/DataTableToolbar.tsx +8 -0
  171. package/src/components/DataTable/components/DraggableColumnHeader.tsx +12 -0
  172. package/src/components/DataTable/components/EditFields.tsx +307 -0
  173. package/src/components/DataTable/components/EditableRow.tsx +8 -0
  174. package/src/components/DataTable/components/EmptyState.tsx +10 -0
  175. package/src/components/DataTable/components/FilterRow.tsx +12 -0
  176. package/src/components/DataTable/components/GroupHeader.tsx +12 -0
  177. package/src/components/DataTable/components/GroupingDropdown.tsx +12 -0
  178. package/src/components/DataTable/components/ImportModal.tsx +7 -0
  179. package/src/components/DataTable/components/LoadingState.tsx +6 -0
  180. package/src/components/DataTable/components/PaginationControls.tsx +16 -1
  181. package/src/components/DataTable/components/RowComponent.tsx +391 -0
  182. package/src/components/DataTable/components/UnifiedTableBody.tsx +63 -851
  183. package/src/components/DataTable/components/VirtualizedDataTable.tsx +16 -4
  184. package/src/components/DataTable/components/__tests__/AccessDeniedPage.test.tsx +4 -2
  185. package/src/components/DataTable/components/cellValueUtils.ts +40 -0
  186. package/src/components/DataTable/components/hooks/useImportModalFocus.ts +53 -0
  187. package/src/components/DataTable/components/hooks/usePermissionTracking.ts +126 -0
  188. package/src/components/DataTable/context/DataTableContext.tsx +50 -0
  189. package/src/components/DataTable/core/ColumnFactory.ts +31 -0
  190. package/src/components/DataTable/core/DataTableContext.tsx +32 -1
  191. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +10 -0
  192. package/src/components/DataTable/hooks/useColumnReordering.ts +12 -0
  193. package/src/components/DataTable/hooks/useColumnVisibilityPersistence.ts +10 -0
  194. package/src/components/DataTable/hooks/useDataTableDataPipeline.ts +16 -0
  195. package/src/components/DataTable/hooks/useDataTablePermissions.ts +127 -33
  196. package/src/components/DataTable/hooks/useDataTableState.ts +35 -1
  197. package/src/components/DataTable/hooks/useEffectiveColumnOrder.ts +12 -0
  198. package/src/components/DataTable/hooks/useServerSideDataEffect.ts +11 -0
  199. package/src/components/DataTable/hooks/useTableColumns.ts +8 -0
  200. package/src/components/DataTable/hooks/useTableHandlers.ts +14 -0
  201. package/src/components/DataTable/styles.ts +6 -6
  202. package/src/components/DataTable/types.ts +6 -10
  203. package/src/components/DataTable/utils/a11yUtils.ts +7 -0
  204. package/src/components/DataTable/utils/debugTools.ts +18 -113
  205. package/src/components/DataTable/utils/errorHandling.ts +12 -0
  206. package/src/components/DataTable/utils/exportUtils.ts +9 -0
  207. package/src/components/DataTable/utils/flexibleImport.ts +12 -48
  208. package/src/components/DataTable/utils/paginationUtils.ts +8 -0
  209. package/src/components/DataTable/utils/performanceUtils.ts +5 -1
  210. package/src/components/Dialog/Dialog.tsx +31 -3
  211. package/src/components/ErrorBoundary/ErrorBoundary.test.tsx +180 -1
  212. package/src/components/ErrorBoundary/ErrorBoundary.tsx +45 -5
  213. package/src/components/ErrorBoundary/ErrorBoundaryContext.tsx +129 -0
  214. package/src/components/ErrorBoundary/index.ts +27 -2
  215. package/src/components/FileDisplay/FileDisplay.tsx +74 -28
  216. package/src/components/FileUpload/FileUpload.tsx +22 -2
  217. package/src/components/Footer/Footer.test.tsx +16 -16
  218. package/src/components/Footer/Footer.tsx +14 -11
  219. package/src/components/Form/Form.tsx +1 -0
  220. package/src/components/Header/Header.test.tsx +43 -73
  221. package/src/components/Header/Header.tsx +59 -49
  222. package/src/components/Input/Input.test.tsx +2 -2
  223. package/src/components/Input/Input.tsx +8 -4
  224. package/src/components/LoadingSpinner/LoadingSpinner.test.tsx +4 -4
  225. package/src/components/LoginForm/LoginForm.tsx +4 -0
  226. package/src/components/NavigationMenu/NavigationMenu.tsx +14 -513
  227. package/src/components/NavigationMenu/types.ts +56 -0
  228. package/src/components/NavigationMenu/useNavigationFiltering.ts +390 -0
  229. package/src/components/PaceAppLayout/PaceAppLayout.integration.test.tsx +10 -19
  230. package/src/components/PaceAppLayout/PaceAppLayout.performance.test.tsx +2 -2
  231. package/src/components/PaceAppLayout/PaceAppLayout.security.test.tsx +5 -5
  232. package/src/components/PaceAppLayout/PaceAppLayout.test.tsx +13 -11
  233. package/src/components/PaceAppLayout/PaceAppLayout.tsx +167 -44
  234. package/src/components/PaceAppLayout/README.md +14 -17
  235. package/src/components/PaceAppLayout/test-setup.tsx +3 -4
  236. package/src/components/PaceLoginPage/PaceLoginPage.tsx +3 -0
  237. package/src/components/PasswordChange/PasswordChangeForm.tsx +9 -0
  238. package/src/components/ProtectedRoute/ProtectedRoute.tsx +3 -9
  239. package/src/components/PublicLayout/PublicPageLayout.tsx +2 -5
  240. package/src/components/PublicLayout/PublicPageProvider.tsx +4 -0
  241. package/src/components/Select/Select.tsx +80 -434
  242. package/src/components/Select/context.ts +23 -0
  243. package/src/components/Select/hooks/useSelectEvents.ts +87 -0
  244. package/src/components/Select/hooks/useSelectSearch.ts +91 -0
  245. package/src/components/Select/hooks/useSelectState.ts +104 -0
  246. package/src/components/Select/index.ts +9 -1
  247. package/src/components/Select/types.ts +123 -0
  248. package/src/components/Select/utils/text.ts +26 -0
  249. package/src/components/SessionRestorationLoader/SessionRestorationLoader.tsx +4 -5
  250. package/src/components/Switch/Switch.tsx +4 -4
  251. package/src/components/Tabs/Tabs.tsx +1 -1
  252. package/src/components/Toast/Toast.tsx +4 -0
  253. package/src/components/Tooltip/Tooltip.tsx +2 -2
  254. package/src/components/UserMenu/UserMenu.test.tsx +24 -11
  255. package/src/components/UserMenu/UserMenu.tsx +21 -18
  256. package/src/components/index.ts +7 -7
  257. package/src/eslint-rules/pace-core-compliance.cjs +106 -0
  258. package/src/hooks/__tests__/index.unit.test.ts +2 -5
  259. package/src/hooks/__tests__/useAppConfig.unit.test.ts +4 -98
  260. package/src/hooks/index.ts +1 -2
  261. package/src/hooks/public/usePublicEvent.ts +4 -0
  262. package/src/hooks/public/usePublicEventLogo.ts +4 -0
  263. package/src/hooks/public/usePublicFileDisplay.ts +4 -0
  264. package/src/hooks/public/usePublicRouteParams.ts +4 -0
  265. package/src/hooks/services/useAuth.ts +32 -0
  266. package/src/hooks/services/useCurrentEvent.ts +6 -0
  267. package/src/hooks/services/useCurrentOrganisation.ts +6 -0
  268. package/src/hooks/useAppConfig.ts +15 -30
  269. package/src/hooks/useDebounce.ts +9 -0
  270. package/src/hooks/useEventTheme.ts +6 -0
  271. package/src/hooks/useFileDisplay.ts +81 -50
  272. package/src/hooks/useFileReference.ts +25 -7
  273. package/src/hooks/useFileUrl.ts +11 -1
  274. package/src/hooks/useFocusManagement.ts +14 -0
  275. package/src/hooks/useFocusTrap.ts +3 -0
  276. package/src/hooks/useInactivityTracker.ts +3 -0
  277. package/src/hooks/useKeyboardShortcuts.ts +4 -0
  278. package/src/hooks/useOrganisationPermissions.ts +4 -0
  279. package/src/hooks/useOrganisationSecurity.ts +4 -0
  280. package/src/hooks/usePerformanceMonitor.ts +4 -0
  281. package/src/hooks/usePermissionCache.ts +7 -0
  282. package/src/hooks/useQueryCache.ts +12 -1
  283. package/src/hooks/useSessionRestoration.ts +4 -0
  284. package/src/hooks/useStorage.ts +4 -0
  285. package/src/hooks/useToast.ts +1 -1
  286. package/src/index.ts +6 -6
  287. package/src/providers/__tests__/OrganisationProvider.test.tsx +92 -70
  288. package/src/providers/services/AuthServiceProvider.tsx +35 -7
  289. package/src/providers/services/EventServiceProvider.tsx +51 -5
  290. package/src/providers/services/InactivityServiceProvider.tsx +18 -0
  291. package/src/providers/services/OrganisationServiceProvider.tsx +18 -0
  292. package/src/providers/services/UnifiedAuthProvider.tsx +126 -134
  293. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +29 -13
  294. package/src/rbac/README.md +1 -1
  295. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +1 -1
  296. package/src/rbac/__tests__/scenarios.user-role.test.tsx +4 -5
  297. package/src/rbac/adapters.tsx +12 -3
  298. package/src/rbac/api.test.ts +59 -51
  299. package/src/rbac/api.ts +246 -167
  300. package/src/rbac/components/NavigationProvider.tsx +4 -1
  301. package/src/rbac/components/PagePermissionGuard.tsx +185 -17
  302. package/src/rbac/components/RoleBasedRouter.tsx +5 -1
  303. package/src/rbac/components/SecureDataProvider.test.tsx +84 -49
  304. package/src/rbac/components/SecureDataProvider.tsx +20 -5
  305. package/src/rbac/components/__tests__/PagePermissionGuard.race-condition.test.tsx +24 -14
  306. package/src/rbac/components/__tests__/PagePermissionGuard.test.tsx +7 -0
  307. package/src/rbac/components/__tests__/PagePermissionGuard.verification.test.tsx +14 -6
  308. package/src/rbac/components/__tests__/RoleBasedRouter.test.tsx +15 -4
  309. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +148 -24
  310. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +81 -15
  311. package/src/rbac/engine.ts +38 -14
  312. package/src/rbac/hooks/__tests__/useSecureSupabase.test.ts +32 -21
  313. package/src/rbac/hooks/permissions/index.ts +7 -0
  314. package/src/rbac/hooks/permissions/useAccessLevel.ts +105 -0
  315. package/src/rbac/hooks/permissions/useCachedPermissions.ts +79 -0
  316. package/src/rbac/hooks/permissions/useCan.ts +377 -0
  317. package/src/rbac/hooks/permissions/useHasAllPermissions.ts +90 -0
  318. package/src/rbac/hooks/permissions/useHasAnyPermission.ts +90 -0
  319. package/src/rbac/hooks/permissions/useMultiplePermissions.ts +93 -0
  320. package/src/rbac/hooks/permissions/usePermissions.ts +253 -0
  321. package/src/rbac/hooks/useCan.test.ts +64 -66
  322. package/src/rbac/hooks/usePermissions.ts +14 -995
  323. package/src/rbac/hooks/useRBAC.test.ts +1 -5
  324. package/src/rbac/hooks/useRBAC.ts +36 -37
  325. package/src/rbac/hooks/useResolvedScope.test.ts +120 -35
  326. package/src/rbac/hooks/useResolvedScope.ts +35 -40
  327. package/src/rbac/hooks/useResourcePermissions.test.ts +54 -18
  328. package/src/rbac/hooks/useResourcePermissions.ts +14 -4
  329. package/src/rbac/hooks/useSecureSupabase.ts +27 -7
  330. package/src/rbac/index.ts +7 -0
  331. package/src/rbac/permissions.ts +0 -30
  332. package/src/rbac/secureClient.test.ts +22 -18
  333. package/src/rbac/secureClient.ts +294 -68
  334. package/src/rbac/security.ts +0 -17
  335. package/src/rbac/types.ts +9 -0
  336. package/src/rbac/utils/__tests__/contextValidator.test.ts +64 -86
  337. package/src/rbac/utils/clientSecurity.ts +93 -0
  338. package/src/rbac/utils/contextValidator.ts +77 -168
  339. package/src/services/AuthService.ts +39 -7
  340. package/src/services/EventService.ts +186 -54
  341. package/src/services/OrganisationService.ts +81 -14
  342. package/src/services/__tests__/EventService.test.ts +1 -2
  343. package/src/services/base/BaseService.ts +3 -0
  344. package/src/theming/__tests__/parseEventColours.test.ts +6 -9
  345. package/src/theming/parseEventColours.ts +5 -19
  346. package/src/types/vitest-globals.d.ts +51 -26
  347. package/src/utils/__mocks__/supabaseMock.ts +1 -3
  348. package/src/utils/__tests__/formatting.unit.test.ts +4 -4
  349. package/src/utils/__tests__/index.unit.test.ts +2 -2
  350. package/src/utils/audit/audit.ts +0 -3
  351. package/src/utils/core/cn.ts +1 -1
  352. package/src/utils/dynamic/dynamicUtils.ts +7 -4
  353. package/src/utils/file-reference/index.ts +53 -1
  354. package/src/utils/formatting/formatting.ts +8 -18
  355. package/src/utils/index.ts +0 -1
  356. package/dist/chunk-3QRJFVBR.js.map +0 -1
  357. package/dist/chunk-3XTALGJF.js.map +0 -1
  358. package/dist/chunk-4N5C5XZU.js.map +0 -1
  359. package/dist/chunk-4ZC4GX36.js.map +0 -1
  360. package/dist/chunk-7D4SUZUM.js +0 -38
  361. package/dist/chunk-BYFSK72L.js.map +0 -1
  362. package/dist/chunk-EXUD6RNJ.js +0 -451
  363. package/dist/chunk-EXUD6RNJ.js.map +0 -1
  364. package/dist/chunk-GLK6VM3F.js.map +0 -1
  365. package/dist/chunk-I7PSE6JW.js.map +0 -1
  366. package/dist/chunk-JBKQ3SAO.js.map +0 -1
  367. package/dist/chunk-KNC55RTG.js.map +0 -1
  368. package/dist/chunk-LXQLPRQ2.js.map +0 -1
  369. package/dist/chunk-R77UEZ4E.js.map +0 -1
  370. package/dist/chunk-SQGMNID3.js.map +0 -1
  371. package/dist/chunk-T33XF5ZC.js +0 -12922
  372. package/dist/chunk-T33XF5ZC.js.map +0 -1
  373. package/dist/chunk-XM25TVIE.js.map +0 -1
  374. package/docs/api/classes/ColumnFactory.md +0 -243
  375. package/docs/api/classes/ErrorBoundary.md +0 -144
  376. package/docs/api/classes/InvalidScopeError.md +0 -73
  377. package/docs/api/classes/Logger.md +0 -178
  378. package/docs/api/classes/MissingUserContextError.md +0 -66
  379. package/docs/api/classes/OrganisationContextRequiredError.md +0 -66
  380. package/docs/api/classes/PermissionDeniedError.md +0 -73
  381. package/docs/api/classes/RBACAuditManager.md +0 -297
  382. package/docs/api/classes/RBACCache.md +0 -322
  383. package/docs/api/classes/RBACEngine.md +0 -171
  384. package/docs/api/classes/RBACError.md +0 -76
  385. package/docs/api/classes/RBACNotInitializedError.md +0 -66
  386. package/docs/api/classes/SecureSupabaseClient.md +0 -160
  387. package/docs/api/classes/StorageUtils.md +0 -328
  388. package/docs/api/enums/FileCategory.md +0 -184
  389. package/docs/api/enums/LogLevel.md +0 -54
  390. package/docs/api/enums/RBACErrorCode.md +0 -228
  391. package/docs/api/enums/RPCFunction.md +0 -118
  392. package/docs/api/interfaces/AddressFieldProps.md +0 -241
  393. package/docs/api/interfaces/AddressFieldRef.md +0 -94
  394. package/docs/api/interfaces/AggregateConfig.md +0 -43
  395. package/docs/api/interfaces/AutocompleteOptions.md +0 -75
  396. package/docs/api/interfaces/AvatarProps.md +0 -128
  397. package/docs/api/interfaces/BadgeProps.md +0 -27
  398. package/docs/api/interfaces/ButtonProps.md +0 -53
  399. package/docs/api/interfaces/CalendarProps.md +0 -70
  400. package/docs/api/interfaces/CardProps.md +0 -66
  401. package/docs/api/interfaces/ColorPalette.md +0 -7
  402. package/docs/api/interfaces/ColorShade.md +0 -66
  403. package/docs/api/interfaces/ComplianceResult.md +0 -30
  404. package/docs/api/interfaces/DataAccessRecord.md +0 -96
  405. package/docs/api/interfaces/DataRecord.md +0 -11
  406. package/docs/api/interfaces/DataTableAction.md +0 -249
  407. package/docs/api/interfaces/DataTableColumn.md +0 -504
  408. package/docs/api/interfaces/DataTableProps.md +0 -625
  409. package/docs/api/interfaces/DataTableToolbarButton.md +0 -96
  410. package/docs/api/interfaces/DatabaseComplianceResult.md +0 -85
  411. package/docs/api/interfaces/DatabaseIssue.md +0 -41
  412. package/docs/api/interfaces/EmptyStateConfig.md +0 -61
  413. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +0 -235
  414. package/docs/api/interfaces/EventAppRoleData.md +0 -71
  415. package/docs/api/interfaces/ExportColumn.md +0 -90
  416. package/docs/api/interfaces/ExportOptions.md +0 -126
  417. package/docs/api/interfaces/FileDisplayProps.md +0 -249
  418. package/docs/api/interfaces/FileMetadata.md +0 -129
  419. package/docs/api/interfaces/FileReference.md +0 -118
  420. package/docs/api/interfaces/FileSizeLimits.md +0 -7
  421. package/docs/api/interfaces/FileUploadOptions.md +0 -139
  422. package/docs/api/interfaces/FileUploadProps.md +0 -293
  423. package/docs/api/interfaces/FooterProps.md +0 -105
  424. package/docs/api/interfaces/FormFieldProps.md +0 -166
  425. package/docs/api/interfaces/FormProps.md +0 -113
  426. package/docs/api/interfaces/GrantEventAppRoleParams.md +0 -122
  427. package/docs/api/interfaces/InactivityWarningModalProps.md +0 -115
  428. package/docs/api/interfaces/InputProps.md +0 -53
  429. package/docs/api/interfaces/LabelProps.md +0 -107
  430. package/docs/api/interfaces/LoggerConfig.md +0 -62
  431. package/docs/api/interfaces/LoginFormProps.md +0 -184
  432. package/docs/api/interfaces/NavigationAccessRecord.md +0 -107
  433. package/docs/api/interfaces/NavigationContextType.md +0 -164
  434. package/docs/api/interfaces/NavigationGuardProps.md +0 -139
  435. package/docs/api/interfaces/NavigationItem.md +0 -120
  436. package/docs/api/interfaces/NavigationMenuProps.md +0 -221
  437. package/docs/api/interfaces/NavigationProviderProps.md +0 -117
  438. package/docs/api/interfaces/Organisation.md +0 -140
  439. package/docs/api/interfaces/OrganisationContextType.md +0 -388
  440. package/docs/api/interfaces/OrganisationMembership.md +0 -140
  441. package/docs/api/interfaces/OrganisationProviderProps.md +0 -76
  442. package/docs/api/interfaces/OrganisationSecurityError.md +0 -62
  443. package/docs/api/interfaces/PaceAppLayoutProps.md +0 -406
  444. package/docs/api/interfaces/PaceLoginPageProps.md +0 -47
  445. package/docs/api/interfaces/PageAccessRecord.md +0 -85
  446. package/docs/api/interfaces/PagePermissionContextType.md +0 -140
  447. package/docs/api/interfaces/PagePermissionGuardProps.md +0 -153
  448. package/docs/api/interfaces/PagePermissionProviderProps.md +0 -119
  449. package/docs/api/interfaces/PaletteData.md +0 -41
  450. package/docs/api/interfaces/ParsedAddress.md +0 -120
  451. package/docs/api/interfaces/PermissionEnforcerProps.md +0 -153
  452. package/docs/api/interfaces/ProgressProps.md +0 -42
  453. package/docs/api/interfaces/ProtectedRouteProps.md +0 -97
  454. package/docs/api/interfaces/PublicPageFooterProps.md +0 -112
  455. package/docs/api/interfaces/PublicPageHeaderProps.md +0 -125
  456. package/docs/api/interfaces/PublicPageLayoutProps.md +0 -198
  457. package/docs/api/interfaces/QuickFix.md +0 -52
  458. package/docs/api/interfaces/RBACAccessValidateParams.md +0 -52
  459. package/docs/api/interfaces/RBACAccessValidateResult.md +0 -41
  460. package/docs/api/interfaces/RBACAuditLogParams.md +0 -85
  461. package/docs/api/interfaces/RBACAuditLogResult.md +0 -52
  462. package/docs/api/interfaces/RBACConfig.md +0 -133
  463. package/docs/api/interfaces/RBACContext.md +0 -52
  464. package/docs/api/interfaces/RBACLogger.md +0 -112
  465. package/docs/api/interfaces/RBACPageAccessCheckParams.md +0 -74
  466. package/docs/api/interfaces/RBACPerformanceMetrics.md +0 -138
  467. package/docs/api/interfaces/RBACPermissionCheckParams.md +0 -74
  468. package/docs/api/interfaces/RBACPermissionCheckResult.md +0 -52
  469. package/docs/api/interfaces/RBACPermissionsGetParams.md +0 -63
  470. package/docs/api/interfaces/RBACPermissionsGetResult.md +0 -63
  471. package/docs/api/interfaces/RBACResult.md +0 -58
  472. package/docs/api/interfaces/RBACRoleGrantParams.md +0 -63
  473. package/docs/api/interfaces/RBACRoleGrantResult.md +0 -52
  474. package/docs/api/interfaces/RBACRoleRevokeParams.md +0 -63
  475. package/docs/api/interfaces/RBACRoleRevokeResult.md +0 -52
  476. package/docs/api/interfaces/RBACRoleValidateParams.md +0 -52
  477. package/docs/api/interfaces/RBACRoleValidateResult.md +0 -63
  478. package/docs/api/interfaces/RBACRolesListParams.md +0 -52
  479. package/docs/api/interfaces/RBACRolesListResult.md +0 -74
  480. package/docs/api/interfaces/RBACSessionTrackParams.md +0 -74
  481. package/docs/api/interfaces/RBACSessionTrackResult.md +0 -52
  482. package/docs/api/interfaces/ResourcePermissions.md +0 -155
  483. package/docs/api/interfaces/RevokeEventAppRoleParams.md +0 -100
  484. package/docs/api/interfaces/RoleBasedRouterContextType.md +0 -151
  485. package/docs/api/interfaces/RoleBasedRouterProps.md +0 -156
  486. package/docs/api/interfaces/RoleManagementResult.md +0 -52
  487. package/docs/api/interfaces/RouteAccessRecord.md +0 -107
  488. package/docs/api/interfaces/RouteConfig.md +0 -134
  489. package/docs/api/interfaces/RuntimeComplianceResult.md +0 -55
  490. package/docs/api/interfaces/SecureDataContextType.md +0 -168
  491. package/docs/api/interfaces/SecureDataProviderProps.md +0 -132
  492. package/docs/api/interfaces/SessionRestorationLoaderProps.md +0 -34
  493. package/docs/api/interfaces/SetupIssue.md +0 -41
  494. package/docs/api/interfaces/StorageConfig.md +0 -41
  495. package/docs/api/interfaces/StorageFileInfo.md +0 -74
  496. package/docs/api/interfaces/StorageFileMetadata.md +0 -151
  497. package/docs/api/interfaces/StorageListOptions.md +0 -99
  498. package/docs/api/interfaces/StorageListResult.md +0 -41
  499. package/docs/api/interfaces/StorageUploadOptions.md +0 -101
  500. package/docs/api/interfaces/StorageUploadResult.md +0 -63
  501. package/docs/api/interfaces/StorageUrlOptions.md +0 -60
  502. package/docs/api/interfaces/StyleImport.md +0 -19
  503. package/docs/api/interfaces/SwitchProps.md +0 -34
  504. package/docs/api/interfaces/TabsContentProps.md +0 -9
  505. package/docs/api/interfaces/TabsListProps.md +0 -9
  506. package/docs/api/interfaces/TabsProps.md +0 -9
  507. package/docs/api/interfaces/TabsTriggerProps.md +0 -50
  508. package/docs/api/interfaces/TextareaProps.md +0 -53
  509. package/docs/api/interfaces/ToastActionElement.md +0 -9
  510. package/docs/api/interfaces/ToastProps.md +0 -9
  511. package/docs/api/interfaces/UnifiedAuthContextType.md +0 -820
  512. package/docs/api/interfaces/UnifiedAuthProviderProps.md +0 -171
  513. package/docs/api/interfaces/UseFormDialogOptions.md +0 -62
  514. package/docs/api/interfaces/UseFormDialogReturn.md +0 -117
  515. package/docs/api/interfaces/UseInactivityTrackerOptions.md +0 -136
  516. package/docs/api/interfaces/UseInactivityTrackerReturn.md +0 -123
  517. package/docs/api/interfaces/UsePublicEventLogoOptions.md +0 -87
  518. package/docs/api/interfaces/UsePublicEventLogoReturn.md +0 -81
  519. package/docs/api/interfaces/UsePublicEventOptions.md +0 -34
  520. package/docs/api/interfaces/UsePublicEventReturn.md +0 -68
  521. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +0 -47
  522. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +0 -120
  523. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +0 -94
  524. package/docs/api/interfaces/UseResolvedScopeOptions.md +0 -47
  525. package/docs/api/interfaces/UseResolvedScopeReturn.md +0 -47
  526. package/docs/api/interfaces/UseResourcePermissionsOptions.md +0 -34
  527. package/docs/api/interfaces/UserEventAccess.md +0 -118
  528. package/docs/api/interfaces/UserMenuProps.md +0 -86
  529. package/docs/api/interfaces/UserProfile.md +0 -63
  530. package/docs/migration/quick-migration-guide.md +0 -356
  531. package/docs/migration/service-architecture.md +0 -281
  532. package/src/components/EventSelector/EventSelector.test.tsx +0 -720
  533. package/src/components/EventSelector/EventSelector.tsx +0 -420
  534. package/src/components/EventSelector/index.ts +0 -3
  535. package/src/components/OrganisationSelector/OrganisationSelector.test.tsx +0 -784
  536. package/src/components/OrganisationSelector/OrganisationSelector.tsx +0 -324
  537. package/src/components/OrganisationSelector/index.ts +0 -9
  538. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +0 -680
  539. package/src/hooks/useSecureDataAccess.test.ts +0 -559
  540. package/src/hooks/useSecureDataAccess.ts +0 -681
  541. /package/dist/{DataTable-DQ7RSOHE.js.map → DataTable-THFPBKTP.js.map} +0 -0
  542. /package/dist/{UnifiedAuthProvider-ATAP5UTR.js.map → UnifiedAuthProvider-KAGUYQ4J.js.map} +0 -0
  543. /package/dist/{api-N774RPUA.js.map → api-IAGWF3ZG.js.map} +0 -0
  544. /package/dist/{audit-B5P6FFIR.js.map → audit-V53FV5AG.js.map} +0 -0
  545. /package/dist/{chunk-7D4SUZUM.js.map → chunk-DGUM43GV.js.map} +0 -0
  546. /package/docs/migration/{organisation-context-timing-fix.md → V0.3.44_organisation-context-timing-fix.md} +0 -0
  547. /package/docs/migration/{rbac-migration.md → V0.4.0_rbac-migration.md} +0 -0
  548. /package/docs/migration/{person-scoped-profiles-migration-guide.md → V0.5.190_person-scoped-profiles-migration-guide.md} +0 -0
  549. /package/docs/migration/{REACT_19_MIGRATION.md → V0.6.0_REACT_19_MIGRATION.md} +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
+ };
@@ -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