@jmruthers/pace-core 0.2.4

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 (1009) hide show
  1. package/CHANGELOG.md +202 -0
  2. package/README.md +299 -0
  3. package/dist/DataTable-BHlzyKZP.d.ts +116 -0
  4. package/dist/DataTable-GEY5U7OI.js +100 -0
  5. package/dist/DataTable-GEY5U7OI.js.map +1 -0
  6. package/dist/PublicLoadingSpinner-DztrzuJr.d.ts +3430 -0
  7. package/dist/UnifiedAuthProvider-w66zSCUf.d.ts +160 -0
  8. package/dist/api-GZHIDA4X.js +41 -0
  9. package/dist/api-GZHIDA4X.js.map +1 -0
  10. package/dist/appConfig-BVGyuvI7.d.ts +71 -0
  11. package/dist/appNameResolver-7GHF5ED2.js +22 -0
  12. package/dist/appNameResolver-7GHF5ED2.js.map +1 -0
  13. package/dist/audit-BUW3LMJB.js +16 -0
  14. package/dist/audit-BUW3LMJB.js.map +1 -0
  15. package/dist/chunk-22KLBHPS.js +29 -0
  16. package/dist/chunk-22KLBHPS.js.map +1 -0
  17. package/dist/chunk-24MKLB7U.js +81 -0
  18. package/dist/chunk-24MKLB7U.js.map +1 -0
  19. package/dist/chunk-2MKP6IYD.js +388 -0
  20. package/dist/chunk-2MKP6IYD.js.map +1 -0
  21. package/dist/chunk-2V3Y6YBC.js +114 -0
  22. package/dist/chunk-2V3Y6YBC.js.map +1 -0
  23. package/dist/chunk-5CDJCTOO.js +190 -0
  24. package/dist/chunk-5CDJCTOO.js.map +1 -0
  25. package/dist/chunk-6ZQVSHKL.js +1345 -0
  26. package/dist/chunk-6ZQVSHKL.js.map +1 -0
  27. package/dist/chunk-74C6SNEC.js +77 -0
  28. package/dist/chunk-74C6SNEC.js.map +1 -0
  29. package/dist/chunk-7BNPOCLL.js +178 -0
  30. package/dist/chunk-7BNPOCLL.js.map +1 -0
  31. package/dist/chunk-7JL3T7BO.js +3344 -0
  32. package/dist/chunk-7JL3T7BO.js.map +1 -0
  33. package/dist/chunk-CDQ3PX7L.js +18 -0
  34. package/dist/chunk-CDQ3PX7L.js.map +1 -0
  35. package/dist/chunk-DY5E3AT7.js +1734 -0
  36. package/dist/chunk-DY5E3AT7.js.map +1 -0
  37. package/dist/chunk-ETEJVKYK.js +6032 -0
  38. package/dist/chunk-ETEJVKYK.js.map +1 -0
  39. package/dist/chunk-I5Z3QH5X.js +32 -0
  40. package/dist/chunk-I5Z3QH5X.js.map +1 -0
  41. package/dist/chunk-MZBUOP4P.js +119 -0
  42. package/dist/chunk-MZBUOP4P.js.map +1 -0
  43. package/dist/chunk-N2EUGZRW.js +98 -0
  44. package/dist/chunk-N2EUGZRW.js.map +1 -0
  45. package/dist/chunk-NQ4TOOO6.js +20 -0
  46. package/dist/chunk-NQ4TOOO6.js.map +1 -0
  47. package/dist/chunk-OHXGNT3K.js +21 -0
  48. package/dist/chunk-OHXGNT3K.js.map +1 -0
  49. package/dist/chunk-OKXMUYIB.js +522 -0
  50. package/dist/chunk-OKXMUYIB.js.map +1 -0
  51. package/dist/chunk-PFRRIDYA.js +382 -0
  52. package/dist/chunk-PFRRIDYA.js.map +1 -0
  53. package/dist/chunk-PLDDJCW6.js +49 -0
  54. package/dist/chunk-PLDDJCW6.js.map +1 -0
  55. package/dist/chunk-SS3E6QLB.js +695 -0
  56. package/dist/chunk-SS3E6QLB.js.map +1 -0
  57. package/dist/chunk-TMRLB2LA.js +326 -0
  58. package/dist/chunk-TMRLB2LA.js.map +1 -0
  59. package/dist/chunk-WYB6MBZA.js +5533 -0
  60. package/dist/chunk-WYB6MBZA.js.map +1 -0
  61. package/dist/chunk-YDJW5XTN.js +84 -0
  62. package/dist/chunk-YDJW5XTN.js.map +1 -0
  63. package/dist/components.d.ts +1308 -0
  64. package/dist/components.js +3759 -0
  65. package/dist/components.js.map +1 -0
  66. package/dist/database-C3Szpi5J.d.ts +470 -0
  67. package/dist/hooks.d.ts +449 -0
  68. package/dist/hooks.js +612 -0
  69. package/dist/hooks.js.map +1 -0
  70. package/dist/index.d.ts +385 -0
  71. package/dist/index.js +569 -0
  72. package/dist/index.js.map +1 -0
  73. package/dist/organisation-CO3Sh3_D.d.ts +99 -0
  74. package/dist/providers.d.ts +45 -0
  75. package/dist/providers.js +36 -0
  76. package/dist/providers.js.map +1 -0
  77. package/dist/rbac/eslint-rules.d.ts +52 -0
  78. package/dist/rbac/eslint-rules.js +252 -0
  79. package/dist/rbac/eslint-rules.js.map +1 -0
  80. package/dist/rbac/index.d.ts +1918 -0
  81. package/dist/rbac/index.js +2212 -0
  82. package/dist/rbac/index.js.map +1 -0
  83. package/dist/styles/core.css +401 -0
  84. package/dist/styles/fonts/georama-italic.woff2 +0 -0
  85. package/dist/styles/fonts/georama.woff2 +0 -0
  86. package/dist/styles/fonts/open-sans-italic.woff2 +0 -0
  87. package/dist/styles/fonts/open-sans.woff2 +0 -0
  88. package/dist/styles/fonts/reddit-mono.woff2 +0 -0
  89. package/dist/styles/index.d.ts +36 -0
  90. package/dist/styles/index.js +24 -0
  91. package/dist/styles/index.js.map +1 -0
  92. package/dist/theming/runtime.d.ts +73 -0
  93. package/dist/theming/runtime.js +16 -0
  94. package/dist/theming/runtime.js.map +1 -0
  95. package/dist/types-CInEi-ng.d.ts +316 -0
  96. package/dist/types.d.ts +196 -0
  97. package/dist/types.js +83 -0
  98. package/dist/types.js.map +1 -0
  99. package/dist/unified-CM7T0aTK.d.ts +198 -0
  100. package/dist/useComponentPerformance-DE9l5RkL.d.ts +11 -0
  101. package/dist/usePublicRouteParams-B6i0KtXW.d.ts +477 -0
  102. package/dist/utils.d.ts +639 -0
  103. package/dist/utils.js +1103 -0
  104. package/dist/utils.js.map +1 -0
  105. package/dist/validation-PM_iOaTI.d.ts +159 -0
  106. package/dist/validation.d.ts +138 -0
  107. package/dist/validation.js +477 -0
  108. package/dist/validation.js.map +1 -0
  109. package/docs/INDEX.md +192 -0
  110. package/docs/README.md +165 -0
  111. package/docs/api/.nojekyll +1 -0
  112. package/docs/api/README.md +301 -0
  113. package/docs/api/classes/ErrorBoundary.md +144 -0
  114. package/docs/api/classes/PublicErrorBoundary.md +132 -0
  115. package/docs/api/interfaces/AggregateConfig.md +43 -0
  116. package/docs/api/interfaces/ButtonProps.md +53 -0
  117. package/docs/api/interfaces/CardProps.md +40 -0
  118. package/docs/api/interfaces/ColorPalette.md +7 -0
  119. package/docs/api/interfaces/ColorShade.md +41 -0
  120. package/docs/api/interfaces/DataTableAction.md +200 -0
  121. package/docs/api/interfaces/DataTableColumn.md +300 -0
  122. package/docs/api/interfaces/DataTableProps.md +517 -0
  123. package/docs/api/interfaces/DataTableToolbarButton.md +96 -0
  124. package/docs/api/interfaces/EmptyStateConfig.md +61 -0
  125. package/docs/api/interfaces/EventContextType.md +96 -0
  126. package/docs/api/interfaces/EventLogoProps.md +152 -0
  127. package/docs/api/interfaces/EventProviderProps.md +19 -0
  128. package/docs/api/interfaces/FileSizeLimits.md +7 -0
  129. package/docs/api/interfaces/FileUploadProps.md +154 -0
  130. package/docs/api/interfaces/FooterProps.md +105 -0
  131. package/docs/api/interfaces/InactivityWarningModalProps.md +115 -0
  132. package/docs/api/interfaces/InputProps.md +53 -0
  133. package/docs/api/interfaces/LabelProps.md +107 -0
  134. package/docs/api/interfaces/LoginFormProps.md +184 -0
  135. package/docs/api/interfaces/NavigationItem.md +176 -0
  136. package/docs/api/interfaces/NavigationMenuProps.md +236 -0
  137. package/docs/api/interfaces/Organisation.md +140 -0
  138. package/docs/api/interfaces/OrganisationContextType.md +377 -0
  139. package/docs/api/interfaces/OrganisationMembership.md +140 -0
  140. package/docs/api/interfaces/OrganisationProviderProps.md +19 -0
  141. package/docs/api/interfaces/OrganisationSecurityError.md +62 -0
  142. package/docs/api/interfaces/PaceAppLayoutProps.md +393 -0
  143. package/docs/api/interfaces/PaceLoginPageProps.md +34 -0
  144. package/docs/api/interfaces/PaletteData.md +41 -0
  145. package/docs/api/interfaces/PublicErrorBoundaryProps.md +94 -0
  146. package/docs/api/interfaces/PublicErrorBoundaryState.md +68 -0
  147. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +86 -0
  148. package/docs/api/interfaces/PublicPageFooterProps.md +112 -0
  149. package/docs/api/interfaces/PublicPageHeaderProps.md +138 -0
  150. package/docs/api/interfaces/PublicPageLayoutProps.md +138 -0
  151. package/docs/api/interfaces/StorageConfig.md +41 -0
  152. package/docs/api/interfaces/StorageFileInfo.md +74 -0
  153. package/docs/api/interfaces/StorageFileMetadata.md +140 -0
  154. package/docs/api/interfaces/StorageListOptions.md +86 -0
  155. package/docs/api/interfaces/StorageListResult.md +41 -0
  156. package/docs/api/interfaces/StorageUploadOptions.md +88 -0
  157. package/docs/api/interfaces/StorageUploadResult.md +63 -0
  158. package/docs/api/interfaces/StorageUrlOptions.md +47 -0
  159. package/docs/api/interfaces/StyleImport.md +19 -0
  160. package/docs/api/interfaces/ToastActionElement.md +9 -0
  161. package/docs/api/interfaces/ToastProps.md +9 -0
  162. package/docs/api/interfaces/UnifiedAuthContextType.md +1108 -0
  163. package/docs/api/interfaces/UnifiedAuthProviderProps.md +171 -0
  164. package/docs/api/interfaces/UseInactivityTrackerOptions.md +136 -0
  165. package/docs/api/interfaces/UseInactivityTrackerReturn.md +123 -0
  166. package/docs/api/interfaces/UsePublicEventLogoOptions.md +87 -0
  167. package/docs/api/interfaces/UsePublicEventLogoReturn.md +81 -0
  168. package/docs/api/interfaces/UsePublicEventOptions.md +34 -0
  169. package/docs/api/interfaces/UsePublicEventReturn.md +68 -0
  170. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +94 -0
  171. package/docs/api/interfaces/UserEventAccess.md +118 -0
  172. package/docs/api/interfaces/UserMenuProps.md +86 -0
  173. package/docs/api/interfaces/UserProfile.md +63 -0
  174. package/docs/api/modules.md +4153 -0
  175. package/docs/api-reference/components.md +1623 -0
  176. package/docs/api-reference/hooks.md +627 -0
  177. package/docs/api-reference/providers.md +487 -0
  178. package/docs/api-reference/types.md +1005 -0
  179. package/docs/api-reference/utilities.md +1104 -0
  180. package/docs/app.css.example +53 -0
  181. package/docs/architecture/README.md +577 -0
  182. package/docs/best-practices/README.md +400 -0
  183. package/docs/best-practices/deployment.md +1042 -0
  184. package/docs/best-practices/performance.md +789 -0
  185. package/docs/best-practices/security.md +881 -0
  186. package/docs/best-practices/testing.md +981 -0
  187. package/docs/consuming-app-example.md +290 -0
  188. package/docs/consuming-app-vite-config.md +233 -0
  189. package/docs/core-concepts/authentication.md +98 -0
  190. package/docs/core-concepts/events.md +756 -0
  191. package/docs/core-concepts/organisations.md +790 -0
  192. package/docs/core-concepts/permissions.md +729 -0
  193. package/docs/core-concepts/rbac-system.md +233 -0
  194. package/docs/database-schema-requirements.md +172 -0
  195. package/docs/documentation-style-checklist.md +294 -0
  196. package/docs/examples/navigation-menu-auth-fix.md +344 -0
  197. package/docs/getting-started/examples/README.md +106 -0
  198. package/docs/getting-started/examples/basic-auth-app.md +521 -0
  199. package/docs/getting-started/examples/full-featured-app.md +616 -0
  200. package/docs/getting-started/installation.md +269 -0
  201. package/docs/getting-started/quick-start.md +401 -0
  202. package/docs/implementation-guides/app-layout.md +983 -0
  203. package/docs/implementation-guides/data-tables.md +1898 -0
  204. package/docs/implementation-guides/dynamic-colors.md +195 -0
  205. package/docs/implementation-guides/forms.md +578 -0
  206. package/docs/implementation-guides/hierarchical-datatable.md +850 -0
  207. package/docs/implementation-guides/large-datasets.md +281 -0
  208. package/docs/implementation-guides/navigation.md +844 -0
  209. package/docs/implementation-guides/performance.md +403 -0
  210. package/docs/implementation-guides/permission-enforcement.md +764 -0
  211. package/docs/implementation-guides/public-pages.md +752 -0
  212. package/docs/migration/README.md +493 -0
  213. package/docs/migration/organisation-context-timing-fix.md +217 -0
  214. package/docs/migration/quick-migration-guide.md +320 -0
  215. package/docs/migration/rbac-migration.md +571 -0
  216. package/docs/migration/v0.4.15-tailwind-scanning.md +272 -0
  217. package/docs/migration/v0.4.16-css-first-approach.md +306 -0
  218. package/docs/migration/v0.4.17-source-path-fix.md +229 -0
  219. package/docs/migration-guide.md +168 -0
  220. package/docs/performance/README.md +551 -0
  221. package/docs/print-components/README.md +258 -0
  222. package/docs/print-components/api-reference.md +636 -0
  223. package/docs/print-components/examples/README.md +204 -0
  224. package/docs/print-components/examples/basic-report.tsx +92 -0
  225. package/docs/print-components/examples/card-catalog.tsx +149 -0
  226. package/docs/print-components/examples/cover-page-report.tsx +163 -0
  227. package/docs/print-components/quick-start.md +363 -0
  228. package/docs/quick-reference.md +576 -0
  229. package/docs/rbac/README.md +265 -0
  230. package/docs/rbac/advanced-patterns.md +776 -0
  231. package/docs/rbac/api-reference.md +1033 -0
  232. package/docs/rbac/examples.md +883 -0
  233. package/docs/rbac/getting-started.md +679 -0
  234. package/docs/rbac/quick-start.md +619 -0
  235. package/docs/rbac/super-admin-guide.md +592 -0
  236. package/docs/rbac/troubleshooting.md +316 -0
  237. package/docs/security/README.md +680 -0
  238. package/docs/security/checklist.md +343 -0
  239. package/docs/style-guide.md +522 -0
  240. package/docs/styles/README.md +319 -0
  241. package/docs/testing/README.md +874 -0
  242. package/docs/troubleshooting/README.md +497 -0
  243. package/docs/troubleshooting/common-issues.md +1563 -0
  244. package/docs/troubleshooting/database-view-compatibility.md +119 -0
  245. package/docs/troubleshooting/debugging.md +1117 -0
  246. package/docs/troubleshooting/migration.md +918 -0
  247. package/docs/troubleshooting/organisation-context-setup.md +277 -0
  248. package/docs/troubleshooting/react-hooks-issue-analysis.md +166 -0
  249. package/docs/troubleshooting/styling-issues.md +219 -0
  250. package/docs/troubleshooting/tailwind-content-scanning.md +213 -0
  251. package/docs/usage.md +175 -0
  252. package/docs/visual-testing.md +114 -0
  253. package/package.json +211 -0
  254. package/src/__mocks__/lucide-react.ts +181 -0
  255. package/src/__tests__/README.md +404 -0
  256. package/src/__tests__/debug-provider.unit.test.tsx +67 -0
  257. package/src/__tests__/e2e/workflows.test.tsx +373 -0
  258. package/src/__tests__/hybridPermissions.unit.test.tsx +474 -0
  259. package/src/__tests__/index.integration.test.ts +491 -0
  260. package/src/__tests__/mocks/MockAuthProvider-standalone.tsx +47 -0
  261. package/src/__tests__/mocks/MockAuthProvider.tsx +63 -0
  262. package/src/__tests__/mocks/enhancedSupabaseMock.ts +252 -0
  263. package/src/__tests__/mocks/index.test.ts +23 -0
  264. package/src/__tests__/mocks/index.ts +16 -0
  265. package/src/__tests__/mocks/mockAuth.ts +155 -0
  266. package/src/__tests__/mocks/mockSupabase.ts +83 -0
  267. package/src/__tests__/mocks/mockSupabaseClient.ts +63 -0
  268. package/src/__tests__/mocks/providers.tsx +22 -0
  269. package/src/__tests__/patterns/__tests__/testPatterns.test.ts +394 -0
  270. package/src/__tests__/patterns/testPatterns.ts +124 -0
  271. package/src/__tests__/performance/componentPerformance.performance.test.ts +27 -0
  272. package/src/__tests__/performance/index.ts +24 -0
  273. package/src/__tests__/performance/performanceValidation.performance.test.ts +15 -0
  274. package/src/__tests__/security/security.unit.test.tsx +7 -0
  275. package/src/__tests__/security/securityValidation.security.test.tsx +153 -0
  276. package/src/__tests__/setup.ts +259 -0
  277. package/src/__tests__/setupTests.d.ts +1 -0
  278. package/src/__tests__/shared/componentTestUtils.tsx +475 -0
  279. package/src/__tests__/shared/errorHandlingTestUtils.ts +107 -0
  280. package/src/__tests__/shared/index.ts +81 -0
  281. package/src/__tests__/shared/integrationTestUtils.tsx +375 -0
  282. package/src/__tests__/shared/performanceTestUtils.tsx +476 -0
  283. package/src/__tests__/shared/testUtils.optimized.tsx +627 -0
  284. package/src/__tests__/simple.test.tsx +20 -0
  285. package/src/__tests__/templates/accessibility.test.template.tsx +279 -0
  286. package/src/__tests__/templates/component.test.template.tsx +122 -0
  287. package/src/__tests__/templates/integration.test.template.tsx +199 -0
  288. package/src/__tests__/test-utils/dataFactories.ts +60 -0
  289. package/src/__tests__/test-utils/index.ts +6 -0
  290. package/src/__tests__/typeSafety.unit.test.ts +65 -0
  291. package/src/__tests__/unifiedAuth.unit.test.tsx +151 -0
  292. package/src/__tests__/utils/accessibilityHelpers.ts +254 -0
  293. package/src/__tests__/utils/assertions.ts +50 -0
  294. package/src/__tests__/utils/deterministicHelpers.ts +31 -0
  295. package/src/__tests__/utils/edgeCaseConfig.test.ts +75 -0
  296. package/src/__tests__/utils/edgeCaseConfig.ts +98 -0
  297. package/src/__tests__/utils/mockHelpers.ts +149 -0
  298. package/src/__tests__/utils/mockLoader.ts +101 -0
  299. package/src/__tests__/utils/performanceHelpers.ts +55 -0
  300. package/src/__tests__/utils/performanceTestHelpers.ts +68 -0
  301. package/src/__tests__/utils/testDataFactories.ts +28 -0
  302. package/src/__tests__/utils/testIsolation.ts +67 -0
  303. package/src/__tests__/utils/visualTestHelpers.ts +20 -0
  304. package/src/__tests__/visual/__snapshots__/componentSnapshots.visual.test.tsx.snap +68 -0
  305. package/src/__tests__/visual/__snapshots__/componentVisuals.visual.test.tsx.snap +14 -0
  306. package/src/__tests__/visual/__snapshots__/visualRegression.test.tsx.snap +217 -0
  307. package/src/__tests__/visual/__snapshots__/visualRegression.visual.test.tsx.snap +24 -0
  308. package/src/__tests__/visual/componentSnapshots.visual.test.tsx +33 -0
  309. package/src/__tests__/visual/componentVisuals.visual.test.tsx +12 -0
  310. package/src/__tests__/visual/visualRegression.visual.test.tsx +20 -0
  311. package/src/components/Alert/Alert.tsx +134 -0
  312. package/src/components/Alert/__tests__/Alert.unit.test.tsx +381 -0
  313. package/src/components/Alert/index.ts +2 -0
  314. package/src/components/Avatar/Avatar.tsx +84 -0
  315. package/src/components/Avatar/__tests__/Avatar.unit.test.tsx +232 -0
  316. package/src/components/Avatar/index.ts +2 -0
  317. package/src/components/Button/Button.tsx +270 -0
  318. package/src/components/Button/__tests__/Button.accessibility.test.tsx +131 -0
  319. package/src/components/Button/__tests__/Button.comprehensive.test.tsx +721 -0
  320. package/src/components/Button/__tests__/Button.unit.test.tsx +189 -0
  321. package/src/components/Button/__tests__/EventSelector.integration.test.tsx +285 -0
  322. package/src/components/Button/index.ts +2 -0
  323. package/src/components/Card/Card.tsx +271 -0
  324. package/src/components/Card/__tests__/Card.accessibility.test.tsx +394 -0
  325. package/src/components/Card/__tests__/Card.comprehensive.test.tsx +599 -0
  326. package/src/components/Card/__tests__/Card.integration.test.tsx +673 -0
  327. package/src/components/Card/__tests__/Card.performance.test.tsx +546 -0
  328. package/src/components/Card/__tests__/Card.unit.test.tsx +330 -0
  329. package/src/components/Card/__tests__/Card.visual.test.tsx +599 -0
  330. package/src/components/Card/__tests__/README.md +211 -0
  331. package/src/components/Card/index.ts +1 -0
  332. package/src/components/Checkbox/Checkbox.tsx +75 -0
  333. package/src/components/Checkbox/__mocks__/Checkbox.tsx +2 -0
  334. package/src/components/Checkbox/__tests__/Checkbox.unit.test.tsx +520 -0
  335. package/src/components/Checkbox/index.ts +2 -0
  336. package/src/components/DataTable/DataTable.tsx +440 -0
  337. package/src/components/DataTable/__tests__/DataTable.autoSizing.test.tsx +526 -0
  338. package/src/components/DataTable/__tests__/DataTable.errorHandling.test.tsx +259 -0
  339. package/src/components/DataTable/__tests__/DataTable.hierarchical.test.tsx +675 -0
  340. package/src/components/DataTable/__tests__/DataTable.infinite-loop.test.tsx +324 -0
  341. package/src/components/DataTable/__tests__/DataTable.integration.test.tsx +724 -0
  342. package/src/components/DataTable/__tests__/DataTable.performance.test.tsx +597 -0
  343. package/src/components/DataTable/__tests__/DataTable.permissions.test.tsx +306 -0
  344. package/src/components/DataTable/__tests__/DataTable.regressionFixes.test.tsx +546 -0
  345. package/src/components/DataTable/__tests__/DataTable.selection.controlled.test.tsx +386 -0
  346. package/src/components/DataTable/__tests__/DataTable.selection.test.tsx +338 -0
  347. package/src/components/DataTable/__tests__/DataTable.userWorkflows.test.tsx +310 -0
  348. package/src/components/DataTable/__tests__/DataTable.workflowValidation.test.tsx +489 -0
  349. package/src/components/DataTable/__tests__/DataTable.workflows.test.tsx +701 -0
  350. package/src/components/DataTable/__tests__/README.md +136 -0
  351. package/src/components/DataTable/__tests__/mocks/MockRBACProvider.tsx +66 -0
  352. package/src/components/DataTable/__tests__/performance-regression.test.tsx +788 -0
  353. package/src/components/DataTable/__tests__/performance.test.tsx +365 -0
  354. package/src/components/DataTable/__tests__/test-utils/dataFactories.ts +103 -0
  355. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +382 -0
  356. package/src/components/DataTable/__tests__/test-utils.ts +94 -0
  357. package/src/components/DataTable/components/ActionButtons.tsx +177 -0
  358. package/src/components/DataTable/components/BulkOperationsDropdown.tsx +160 -0
  359. package/src/components/DataTable/components/ColumnFilter.tsx +114 -0
  360. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +100 -0
  361. package/src/components/DataTable/components/DataTableBody.tsx +462 -0
  362. package/src/components/DataTable/components/DataTableCore.tsx +869 -0
  363. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +214 -0
  364. package/src/components/DataTable/components/DataTableHeader.tsx +31 -0
  365. package/src/components/DataTable/components/DataTableModals.tsx +87 -0
  366. package/src/components/DataTable/components/DataTableToolbar.tsx +251 -0
  367. package/src/components/DataTable/components/DraggableColumnHeader.tsx +148 -0
  368. package/src/components/DataTable/components/EditableRow.tsx +160 -0
  369. package/src/components/DataTable/components/EmptyState.tsx +64 -0
  370. package/src/components/DataTable/components/ExpandButton.tsx +113 -0
  371. package/src/components/DataTable/components/FilterRow.tsx +101 -0
  372. package/src/components/DataTable/components/GroupHeader.tsx +42 -0
  373. package/src/components/DataTable/components/GroupingDropdown.tsx +96 -0
  374. package/src/components/DataTable/components/ImportModal.tsx +345 -0
  375. package/src/components/DataTable/components/LoadingState.tsx +12 -0
  376. package/src/components/DataTable/components/PaginationControls.tsx +332 -0
  377. package/src/components/DataTable/components/UnifiedTableBody.tsx +911 -0
  378. package/src/components/DataTable/components/ViewRowModal.tsx +68 -0
  379. package/src/components/DataTable/components/VirtualizedDataTable.tsx +593 -0
  380. package/src/components/DataTable/components/__tests__/ActionButtons.unit.test.tsx +150 -0
  381. package/src/components/DataTable/components/__tests__/BulkOperationsDropdown.test.tsx +224 -0
  382. package/src/components/DataTable/components/__tests__/ColumnVisibilityDropdown.unit.test.tsx +244 -0
  383. package/src/components/DataTable/components/__tests__/DataTable.accessibility.test.tsx +523 -0
  384. package/src/components/DataTable/components/__tests__/DataTable.integration.test.tsx +401 -0
  385. package/src/components/DataTable/components/__tests__/DataTable.performance.test.tsx +161 -0
  386. package/src/components/DataTable/components/__tests__/DataTable.real.test.tsx +251 -0
  387. package/src/components/DataTable/components/__tests__/DataTable.security.test.tsx +172 -0
  388. package/src/components/DataTable/components/__tests__/DataTable.unit.test.tsx +290 -0
  389. package/src/components/DataTable/components/__tests__/DataTableBody.unit.test.tsx +147 -0
  390. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.unit.test.tsx +182 -0
  391. package/src/components/DataTable/components/__tests__/DataTableHeader.unit.test.tsx +143 -0
  392. package/src/components/DataTable/components/__tests__/DataTableModals.unit.test.tsx +123 -0
  393. package/src/components/DataTable/components/__tests__/EditableRow.unit.test.tsx +660 -0
  394. package/src/components/DataTable/components/__tests__/EmptyState.unit.test.tsx +256 -0
  395. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +498 -0
  396. package/src/components/DataTable/components/__tests__/FilterRow.unit.test.tsx +112 -0
  397. package/src/components/DataTable/components/__tests__/FilteringToggle.unit.test.tsx +130 -0
  398. package/src/components/DataTable/components/__tests__/GroupHeader.unit.test.tsx +172 -0
  399. package/src/components/DataTable/components/__tests__/GroupingDropdown.unit.test.tsx +222 -0
  400. package/src/components/DataTable/components/__tests__/ImportModal.unit.test.tsx +780 -0
  401. package/src/components/DataTable/components/__tests__/LoadingState.unit.test.tsx +65 -0
  402. package/src/components/DataTable/components/__tests__/PaginationControls.unit.test.tsx +634 -0
  403. package/src/components/DataTable/components/__tests__/StateComponents.unit.test.tsx +48 -0
  404. package/src/components/DataTable/components/__tests__/UnifiedTableBody.hierarchical.test.tsx +541 -0
  405. package/src/components/DataTable/components/__tests__/ViewRowModal.unit.test.tsx +228 -0
  406. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.unit.test.tsx +568 -0
  407. package/src/components/DataTable/components/index.ts +17 -0
  408. package/src/components/DataTable/context/DataTableContext.tsx +97 -0
  409. package/src/components/DataTable/core/ActionManager.ts +235 -0
  410. package/src/components/DataTable/core/ColumnFactory.ts +268 -0
  411. package/src/components/DataTable/core/ColumnManager.ts +205 -0
  412. package/src/components/DataTable/core/DataManager.ts +188 -0
  413. package/src/components/DataTable/core/DataTableContext.tsx +182 -0
  414. package/src/components/DataTable/core/LocalDataAdapter.ts +264 -0
  415. package/src/components/DataTable/core/PluginRegistry.ts +229 -0
  416. package/src/components/DataTable/core/StateManager.ts +311 -0
  417. package/src/components/DataTable/core/__tests__/ActionManager.unit.test.ts +405 -0
  418. package/src/components/DataTable/core/__tests__/ArchitectureIntegration.unit.test.tsx +445 -0
  419. package/src/components/DataTable/core/__tests__/ColumnFactory.unit.test.ts +288 -0
  420. package/src/components/DataTable/core/__tests__/ColumnManager.unit.test.ts +623 -0
  421. package/src/components/DataTable/core/__tests__/DataManager.unit.test.ts +431 -0
  422. package/src/components/DataTable/core/__tests__/DataTableContext.unit.test.tsx +433 -0
  423. package/src/components/DataTable/core/__tests__/LocalDataAdapter.unit.test.ts +422 -0
  424. package/src/components/DataTable/core/__tests__/PluginRegistry.unit.test.tsx +207 -0
  425. package/src/components/DataTable/core/__tests__/StateManager.unit.test.ts +278 -0
  426. package/src/components/DataTable/core/index.ts +8 -0
  427. package/src/components/DataTable/core/interfaces.ts +338 -0
  428. package/src/components/DataTable/examples/AutoSizingExample.tsx +180 -0
  429. package/src/components/DataTable/examples/ColumnSizingComparison.tsx +235 -0
  430. package/src/components/DataTable/examples/HierarchicalActionsExample.tsx +418 -0
  431. package/src/components/DataTable/examples/HierarchicalExample.tsx +472 -0
  432. package/src/components/DataTable/examples/InitialPageSizeExample.tsx +173 -0
  433. package/src/components/DataTable/examples/PerformanceExample.tsx +502 -0
  434. package/src/components/DataTable/examples/__tests__/PerformanceExample.unit.test.tsx +281 -0
  435. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.unit.test.ts +407 -0
  436. package/src/components/DataTable/hooks/__tests__/useColumnReordering.unit.test.ts +679 -0
  437. package/src/components/DataTable/hooks/useColumnOrderPersistence.ts +95 -0
  438. package/src/components/DataTable/hooks/useColumnReordering.ts +110 -0
  439. package/src/components/DataTable/hooks/useDataTableState.ts +325 -0
  440. package/src/components/DataTable/hooks/useHierarchicalState.ts +174 -0
  441. package/src/components/DataTable/index.ts +70 -0
  442. package/src/components/DataTable/styles.ts +171 -0
  443. package/src/components/DataTable/types.ts +475 -0
  444. package/src/components/DataTable/utils/__tests__/columnSizing.test.ts +237 -0
  445. package/src/components/DataTable/utils/__tests__/debugTools.unit.test.ts +267 -0
  446. package/src/components/DataTable/utils/__tests__/errorHandling.unit.test.ts +467 -0
  447. package/src/components/DataTable/utils/__tests__/exportUtils.unit.test.ts +380 -0
  448. package/src/components/DataTable/utils/__tests__/flexibleImport.unit.test.ts +233 -0
  449. package/src/components/DataTable/utils/__tests__/performanceUtils.unit.test.ts +414 -0
  450. package/src/components/DataTable/utils/columnSizing.ts +125 -0
  451. package/src/components/DataTable/utils/debugTools.ts +583 -0
  452. package/src/components/DataTable/utils/errorHandling.ts +494 -0
  453. package/src/components/DataTable/utils/exportUtils.ts +126 -0
  454. package/src/components/DataTable/utils/flexibleImport.ts +510 -0
  455. package/src/components/DataTable/utils/hierarchicalSorting.ts +151 -0
  456. package/src/components/DataTable/utils/hierarchicalUtils.ts +218 -0
  457. package/src/components/DataTable/utils/index.ts +1 -0
  458. package/src/components/DataTable/utils/performanceUtils.ts +351 -0
  459. package/src/components/Dialog/Dialog.tsx +782 -0
  460. package/src/components/Dialog/README.md +804 -0
  461. package/src/components/Dialog/__tests__/Dialog.accessibility.test.tsx +521 -0
  462. package/src/components/Dialog/__tests__/Dialog.auto-size.example.tsx +157 -0
  463. package/src/components/Dialog/__tests__/Dialog.enhanced.test.tsx +538 -0
  464. package/src/components/Dialog/__tests__/Dialog.unit.test.tsx +1373 -0
  465. package/src/components/Dialog/examples/BasicHtmlTest.tsx +55 -0
  466. package/src/components/Dialog/examples/DebugHtmlExample.tsx +68 -0
  467. package/src/components/Dialog/examples/HtmlDialogExample.tsx +202 -0
  468. package/src/components/Dialog/examples/SimpleHtmlTest.tsx +61 -0
  469. package/src/components/Dialog/examples/SmartDialogExample.tsx +322 -0
  470. package/src/components/Dialog/examples/__tests__/SmartDialogExample.unit.test.tsx +151 -0
  471. package/src/components/Dialog/index.ts +12 -0
  472. package/src/components/Dialog/utils/__tests__/safeHtml.unit.test.ts +611 -0
  473. package/src/components/Dialog/utils/safeHtml.ts +185 -0
  474. package/src/components/ErrorBoundary/ErrorBoundary.tsx +312 -0
  475. package/src/components/ErrorBoundary/__tests__/ErrorBoundary.accessibility.test.tsx +517 -0
  476. package/src/components/ErrorBoundary/__tests__/ErrorBoundary.integration.test.tsx +572 -0
  477. package/src/components/ErrorBoundary/__tests__/ErrorBoundary.unit.test.tsx +579 -0
  478. package/src/components/ErrorBoundary/index.ts +8 -0
  479. package/src/components/EventSelector/EventSelector.tsx +360 -0
  480. package/src/components/EventSelector/__tests__/EventSelector.test.tsx +528 -0
  481. package/src/components/EventSelector/index.ts +3 -0
  482. package/src/components/EventSelector/types.ts +79 -0
  483. package/src/components/FileUpload/FileUpload.example.tsx +218 -0
  484. package/src/components/FileUpload/FileUpload.tsx +237 -0
  485. package/src/components/FileUpload/__tests__/FileUpload.integration.test.tsx +992 -0
  486. package/src/components/FileUpload/__tests__/FileUpload.real.test.tsx +927 -0
  487. package/src/components/FileUpload/__tests__/FileUpload.test.tsx +855 -0
  488. package/src/components/FileUpload/__tests__/FileUpload.unit.test.tsx +1311 -0
  489. package/src/components/FileUpload/__tests__/FileUpload.unmocked.test.tsx +937 -0
  490. package/src/components/FileUpload/index.ts +6 -0
  491. package/src/components/Footer/Footer.tsx +197 -0
  492. package/src/components/Footer/__tests__/Footer.accessibility.test.tsx +359 -0
  493. package/src/components/Footer/__tests__/Footer.integration.test.tsx +353 -0
  494. package/src/components/Footer/__tests__/Footer.performance.test.tsx +309 -0
  495. package/src/components/Footer/__tests__/Footer.unit.test.tsx +309 -0
  496. package/src/components/Footer/__tests__/Footer.visual.test.tsx +335 -0
  497. package/src/components/Footer/index.ts +17 -0
  498. package/src/components/Form/Form.tsx +166 -0
  499. package/src/components/Form/FormErrorSummary.tsx +113 -0
  500. package/src/components/Form/FormField.tsx +249 -0
  501. package/src/components/Form/FormFieldset.tsx +127 -0
  502. package/src/components/Form/FormLiveRegion.tsx +198 -0
  503. package/src/components/Form/__tests__/Form.accessibility.test.tsx +820 -0
  504. package/src/components/Form/__tests__/Form.unit.test.tsx +305 -0
  505. package/src/components/Form/__tests__/FormErrorSummary.unit.test.tsx +285 -0
  506. package/src/components/Form/__tests__/FormFieldset.unit.test.tsx +241 -0
  507. package/src/components/Form/index.ts +26 -0
  508. package/src/components/Header/Header.tsx +301 -0
  509. package/src/components/Header/__tests__/Header.accessibility.test.tsx +382 -0
  510. package/src/components/Header/__tests__/Header.comprehensive.test.tsx +509 -0
  511. package/src/components/Header/__tests__/Header.unit.test.tsx +335 -0
  512. package/src/components/Header/index.ts +4 -0
  513. package/src/components/InactivityWarningModal/InactivityWarningModal.test.tsx +196 -0
  514. package/src/components/InactivityWarningModal/InactivityWarningModal.tsx +164 -0
  515. package/src/components/InactivityWarningModal/__tests__/InactivityWarningModal.unit.test.tsx +224 -0
  516. package/src/components/InactivityWarningModal/index.ts +9 -0
  517. package/src/components/Input/Input.tsx +201 -0
  518. package/src/components/Input/__mocks__/Input.tsx +2 -0
  519. package/src/components/Input/__tests__/Input.accessibility.test.tsx +632 -0
  520. package/src/components/Input/__tests__/Input.unit.test.tsx +1121 -0
  521. package/src/components/Input/index.ts +9 -0
  522. package/src/components/Label/Label.tsx +186 -0
  523. package/src/components/Label/__tests__/Label.accessibility.test.tsx +239 -0
  524. package/src/components/Label/__tests__/Label.unit.test.tsx +331 -0
  525. package/src/components/Label/index.ts +2 -0
  526. package/src/components/LoadingSpinner/LoadingSpinner.tsx +98 -0
  527. package/src/components/LoadingSpinner/__tests__/LoadingSpinner.accessibility.test.tsx +116 -0
  528. package/src/components/LoadingSpinner/__tests__/LoadingSpinner.unit.test.tsx +144 -0
  529. package/src/components/LoadingSpinner/index.ts +3 -0
  530. package/src/components/LoginForm/LoginForm.tsx +273 -0
  531. package/src/components/LoginForm/__tests__/LoginForm.accessibility.test.tsx +201 -0
  532. package/src/components/LoginForm/__tests__/LoginForm.unit.test.tsx +119 -0
  533. package/src/components/LoginForm/index.ts +3 -0
  534. package/src/components/NavigationMenu/NavigationMenu.tsx +698 -0
  535. package/src/components/NavigationMenu/__tests__/NavigationMenu.accessibility.test.tsx +378 -0
  536. package/src/components/NavigationMenu/__tests__/NavigationMenu.enhanced.test.tsx +768 -0
  537. package/src/components/NavigationMenu/__tests__/NavigationMenu.integration.test.tsx +576 -0
  538. package/src/components/NavigationMenu/__tests__/NavigationMenu.performance.test.tsx +585 -0
  539. package/src/components/NavigationMenu/__tests__/NavigationMenu.real.component.test.tsx +783 -0
  540. package/src/components/NavigationMenu/__tests__/NavigationMenu.security.enhanced.test.tsx +810 -0
  541. package/src/components/NavigationMenu/__tests__/NavigationMenu.security.test.tsx +494 -0
  542. package/src/components/NavigationMenu/__tests__/NavigationMenu.unit.test.tsx +331 -0
  543. package/src/components/NavigationMenu/__tests__/NavigationMenu.userWorkflows.test.tsx +347 -0
  544. package/src/components/NavigationMenu/__tests__/NavigationMenu.workflows.test.tsx +584 -0
  545. package/src/components/NavigationMenu/index.ts +10 -0
  546. package/src/components/NavigationMenu/types.ts +85 -0
  547. package/src/components/OrganisationSelector/OrganisationSelector.tsx +304 -0
  548. package/src/components/OrganisationSelector/__tests__/OrganisationSelector.unit.test.tsx +664 -0
  549. package/src/components/OrganisationSelector/index.ts +9 -0
  550. package/src/components/PaceAppLayout/PaceAppLayout.tsx +699 -0
  551. package/src/components/PaceAppLayout/README.md +278 -0
  552. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.accessibility.test.tsx +288 -0
  553. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.integration.test.tsx +889 -0
  554. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.performance.test.tsx +629 -0
  555. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.security.test.tsx +782 -0
  556. package/src/components/PaceAppLayout/__tests__/PaceAppLayout.unit.test.tsx +904 -0
  557. package/src/components/PaceAppLayout/index.ts +1 -0
  558. package/src/components/PaceLoginPage/PaceLoginPage.tsx +221 -0
  559. package/src/components/PaceLoginPage/__tests__/PaceLoginPage.accessibility.test.tsx +463 -0
  560. package/src/components/PaceLoginPage/__tests__/PaceLoginPage.integration.test.tsx +586 -0
  561. package/src/components/PaceLoginPage/__tests__/PaceLoginPage.unit.test.tsx +533 -0
  562. package/src/components/PaceLoginPage/index.ts +1 -0
  563. package/src/components/PasswordReset/PasswordChangeForm.tsx +186 -0
  564. package/src/components/PasswordReset/PasswordResetForm.tsx +201 -0
  565. package/src/components/PasswordReset/__tests__/PasswordChangeForm.accessibility.test.tsx +408 -0
  566. package/src/components/PasswordReset/__tests__/PasswordChangeForm.unit.test.tsx +561 -0
  567. package/src/components/PasswordReset/__tests__/PasswordReset.integration.test.tsx +304 -0
  568. package/src/components/PasswordReset/__tests__/PasswordResetForm.accessibility.test.tsx +20 -0
  569. package/src/components/PasswordReset/__tests__/PasswordResetForm.unit.test.tsx +523 -0
  570. package/src/components/PasswordReset/__tests__/__mocks__/UnifiedAuthProvider.ts +29 -0
  571. package/src/components/PasswordReset/index.ts +4 -0
  572. package/src/components/Print/__tests__/Print.comprehensive.test.tsx +331 -0
  573. package/src/components/PrintButton/PrintButton.tsx +321 -0
  574. package/src/components/PrintButton/PrintButtonGroup.tsx +84 -0
  575. package/src/components/PrintButton/PrintToolbar.tsx +94 -0
  576. package/src/components/PrintButton/__tests__/PrintButton.unit.test.tsx +429 -0
  577. package/src/components/PrintButton/__tests__/PrintButtonGroup.unit.test.tsx +277 -0
  578. package/src/components/PrintButton/__tests__/PrintToolbar.unit.test.tsx +264 -0
  579. package/src/components/PrintButton/examples/PrintButtonShowcase.tsx +438 -0
  580. package/src/components/PrintButton/index.ts +33 -0
  581. package/src/components/PrintButton/types.ts +173 -0
  582. package/src/components/PrintCard/PrintCard.tsx +154 -0
  583. package/src/components/PrintCard/PrintCardContent.tsx +57 -0
  584. package/src/components/PrintCard/PrintCardFooter.tsx +60 -0
  585. package/src/components/PrintCard/PrintCardGrid.tsx +91 -0
  586. package/src/components/PrintCard/PrintCardHeader.tsx +78 -0
  587. package/src/components/PrintCard/PrintCardImage.tsx +81 -0
  588. package/src/components/PrintCard/__tests__/PrintCard.unit.test.tsx +233 -0
  589. package/src/components/PrintCard/__tests__/PrintCardContent.test.tsx +284 -0
  590. package/src/components/PrintCard/__tests__/PrintCardGrid.unit.test.tsx +214 -0
  591. package/src/components/PrintCard/__tests__/PrintCardImage.unit.test.tsx +264 -0
  592. package/src/components/PrintCard/examples/PrintCardShowcase.tsx +239 -0
  593. package/src/components/PrintCard/index.ts +34 -0
  594. package/src/components/PrintCard/types.ts +171 -0
  595. package/src/components/PrintDataTable/PrintDataTable.tsx +215 -0
  596. package/src/components/PrintDataTable/PrintTableGroup.tsx +90 -0
  597. package/src/components/PrintDataTable/PrintTableRow.tsx +76 -0
  598. package/src/components/PrintDataTable/__tests__/PrintDataTable.unit.test.tsx +361 -0
  599. package/src/components/PrintDataTable/__tests__/PrintTableGroup.unit.test.tsx +314 -0
  600. package/src/components/PrintDataTable/__tests__/PrintTableRow.unit.test.tsx +362 -0
  601. package/src/components/PrintDataTable/index.ts +25 -0
  602. package/src/components/PrintDataTable/types.ts +67 -0
  603. package/src/components/PrintFooter/PrintFooter.tsx +183 -0
  604. package/src/components/PrintFooter/PrintFooterContent.tsx +71 -0
  605. package/src/components/PrintFooter/PrintFooterInfo.tsx +86 -0
  606. package/src/components/PrintFooter/PrintPageNumber.tsx +90 -0
  607. package/src/components/PrintFooter/__tests__/PrintFooter.unit.test.tsx +500 -0
  608. package/src/components/PrintFooter/__tests__/PrintFooterContent.unit.test.tsx +321 -0
  609. package/src/components/PrintFooter/__tests__/PrintFooterInfo.unit.test.tsx +335 -0
  610. package/src/components/PrintFooter/__tests__/PrintPageNumber.unit.test.tsx +340 -0
  611. package/src/components/PrintFooter/examples/PrintFooterShowcase.tsx +390 -0
  612. package/src/components/PrintFooter/index.ts +30 -0
  613. package/src/components/PrintFooter/types.ts +149 -0
  614. package/src/components/PrintGrid/PrintGrid.tsx +180 -0
  615. package/src/components/PrintGrid/PrintGridBreakpoint.tsx +109 -0
  616. package/src/components/PrintGrid/PrintGridContainer.tsx +128 -0
  617. package/src/components/PrintGrid/PrintGridItem.tsx +220 -0
  618. package/src/components/PrintGrid/__tests__/PrintGrid.unit.test.tsx +340 -0
  619. package/src/components/PrintGrid/__tests__/PrintGridBreakpoint.unit.test.tsx +261 -0
  620. package/src/components/PrintGrid/__tests__/PrintGridContainer.unit.test.tsx +338 -0
  621. package/src/components/PrintGrid/__tests__/PrintGridItem.unit.test.tsx +338 -0
  622. package/src/components/PrintGrid/examples/PrintGridShowcase.tsx +359 -0
  623. package/src/components/PrintGrid/index.ts +31 -0
  624. package/src/components/PrintGrid/types.ts +159 -0
  625. package/src/components/PrintHeader/PrintCoverHeader.tsx +230 -0
  626. package/src/components/PrintHeader/PrintHeader.tsx +150 -0
  627. package/src/components/PrintHeader/__tests__/PrintCoverHeader.unit.test.tsx +309 -0
  628. package/src/components/PrintHeader/__tests__/PrintHeader.unit.test.tsx +202 -0
  629. package/src/components/PrintHeader/index.ts +17 -0
  630. package/src/components/PrintHeader/types.ts +42 -0
  631. package/src/components/PrintLayout/PrintLayout.tsx +122 -0
  632. package/src/components/PrintLayout/PrintLayoutContext.tsx +66 -0
  633. package/src/components/PrintLayout/PrintPageBreak.tsx +52 -0
  634. package/src/components/PrintLayout/__tests__/PrintLayout.unit.test.tsx +238 -0
  635. package/src/components/PrintLayout/examples/PrintShowcase.tsx +230 -0
  636. package/src/components/PrintLayout/index.ts +19 -0
  637. package/src/components/PrintLayout/types.ts +37 -0
  638. package/src/components/PrintPageBreak/PrintPageBreak.tsx +120 -0
  639. package/src/components/PrintPageBreak/PrintPageBreakGroup.tsx +90 -0
  640. package/src/components/PrintPageBreak/PrintPageBreakIndicator.tsx +112 -0
  641. package/src/components/PrintPageBreak/__tests__/PrintPageBreak.unit.test.tsx +263 -0
  642. package/src/components/PrintPageBreak/__tests__/PrintPageBreakGroup.unit.test.tsx +239 -0
  643. package/src/components/PrintPageBreak/__tests__/PrintPageBreakIndicator.unit.test.tsx +235 -0
  644. package/src/components/PrintPageBreak/examples/PrintPageBreakShowcase.tsx +279 -0
  645. package/src/components/PrintPageBreak/index.ts +23 -0
  646. package/src/components/PrintPageBreak/types.ts +94 -0
  647. package/src/components/PrintSection/PrintColumn.tsx +104 -0
  648. package/src/components/PrintSection/PrintDivider.tsx +101 -0
  649. package/src/components/PrintSection/PrintSection.tsx +129 -0
  650. package/src/components/PrintSection/PrintSectionContent.tsx +75 -0
  651. package/src/components/PrintSection/PrintSectionHeader.tsx +97 -0
  652. package/src/components/PrintSection/__tests__/PrintColumn.unit.test.tsx +385 -0
  653. package/src/components/PrintSection/__tests__/PrintDivider.unit.test.tsx +373 -0
  654. package/src/components/PrintSection/__tests__/PrintSection.unit.test.tsx +390 -0
  655. package/src/components/PrintSection/__tests__/PrintSectionContent.unit.test.tsx +321 -0
  656. package/src/components/PrintSection/__tests__/PrintSectionHeader.unit.test.tsx +334 -0
  657. package/src/components/PrintSection/examples/PrintSectionShowcase.tsx +258 -0
  658. package/src/components/PrintSection/index.ts +33 -0
  659. package/src/components/PrintSection/types.ts +155 -0
  660. package/src/components/PrintText/PrintText.tsx +116 -0
  661. package/src/components/PrintText/__tests__/PrintText.unit.test.tsx +351 -0
  662. package/src/components/PrintText/index.ts +16 -0
  663. package/src/components/PrintText/types.ts +24 -0
  664. package/src/components/Progress/Progress.tsx +116 -0
  665. package/src/components/Progress/__tests__/Progress.accessibility.test.tsx +240 -0
  666. package/src/components/Progress/__tests__/Progress.unit.test.tsx +242 -0
  667. package/src/components/Progress/index.ts +3 -0
  668. package/src/components/PublicLayout/EventLogo.tsx +287 -0
  669. package/src/components/PublicLayout/PublicErrorBoundary.tsx +279 -0
  670. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +208 -0
  671. package/src/components/PublicLayout/PublicPageContextChecker.tsx +130 -0
  672. package/src/components/PublicLayout/PublicPageDebugger.tsx +104 -0
  673. package/src/components/PublicLayout/PublicPageDiagnostic.tsx +162 -0
  674. package/src/components/PublicLayout/PublicPageFooter.tsx +124 -0
  675. package/src/components/PublicLayout/PublicPageHeader.tsx +178 -0
  676. package/src/components/PublicLayout/PublicPageLayout.tsx +232 -0
  677. package/src/components/PublicLayout/PublicPageProvider.tsx +137 -0
  678. package/src/components/PublicLayout/__tests__/EventLogo.test.tsx +761 -0
  679. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.simplified.test.tsx +228 -0
  680. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +228 -0
  681. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +459 -0
  682. package/src/components/PublicLayout/__tests__/PublicPageFooter.test.tsx +362 -0
  683. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +522 -0
  684. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +599 -0
  685. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +513 -0
  686. package/src/components/PublicLayout/index.ts +51 -0
  687. package/src/components/RBAC/PagePermissionGuard.tsx +274 -0
  688. package/src/components/RBAC/RBACGuard.tsx +143 -0
  689. package/src/components/RBAC/RBACProvider.tsx +186 -0
  690. package/src/components/RBAC/RoleBasedContent.tsx +129 -0
  691. package/src/components/RBAC/__tests__/PagePermissionGuard.unit.test.tsx +674 -0
  692. package/src/components/RBAC/__tests__/RBAC.integration.test.tsx +573 -0
  693. package/src/components/RBAC/__tests__/RBACGuard.unit.test.tsx +467 -0
  694. package/src/components/RBAC/__tests__/RBACProvider.accessibility.test.tsx +475 -0
  695. package/src/components/RBAC/__tests__/RBACProvider.advanced.test.tsx +569 -0
  696. package/src/components/RBAC/__tests__/RBACProvider.integration.test.tsx +352 -0
  697. package/src/components/RBAC/__tests__/RBACProvider.unit.test.tsx +128 -0
  698. package/src/components/RBAC/__tests__/RoleBasedContent.unit.test.tsx +657 -0
  699. package/src/components/RBAC/index.ts +23 -0
  700. package/src/components/Select/Select.tsx +654 -0
  701. package/src/components/Select/__tests__/SearchableSelect.unit.test.tsx +437 -0
  702. package/src/components/Select/__tests__/Select.accessibility.test.tsx +1202 -0
  703. package/src/components/Select/__tests__/Select.actual.test.tsx +774 -0
  704. package/src/components/Select/__tests__/Select.comprehensive.test.tsx +837 -0
  705. package/src/components/Select/__tests__/Select.enhanced.test.tsx +1101 -0
  706. package/src/components/Select/__tests__/Select.integration.test.tsx +772 -0
  707. package/src/components/Select/__tests__/Select.performance.test.tsx +695 -0
  708. package/src/components/Select/__tests__/Select.real-world.test.tsx +1046 -0
  709. package/src/components/Select/__tests__/Select.search-algorithms.test.tsx +968 -0
  710. package/src/components/Select/__tests__/Select.unit.test.tsx +647 -0
  711. package/src/components/Select/__tests__/Select.utils.test.tsx +890 -0
  712. package/src/components/Select/index.ts +1 -0
  713. package/src/components/SuperAdminGuard.tsx +116 -0
  714. package/src/components/Table/Table.tsx +222 -0
  715. package/src/components/Table/__tests__/Table.accessibility.test.tsx +233 -0
  716. package/src/components/Table/__tests__/Table.unit.test.tsx +235 -0
  717. package/src/components/Table/index.ts +11 -0
  718. package/src/components/Toast/Toast.tsx +339 -0
  719. package/src/components/Toast/__tests__/Toast.accessibility.test.tsx +238 -0
  720. package/src/components/Toast/__tests__/Toast.integration.test.tsx +699 -0
  721. package/src/components/Toast/__tests__/Toast.unit.test.tsx +750 -0
  722. package/src/components/Toast/index.ts +14 -0
  723. package/src/components/Tooltip/Tooltip.tsx +167 -0
  724. package/src/components/Tooltip/__tests__/Tooltip.accessibility.test.tsx +121 -0
  725. package/src/components/Tooltip/__tests__/Tooltip.unit.test.tsx +185 -0
  726. package/src/components/Tooltip/index.ts +7 -0
  727. package/src/components/UserMenu/UserMenu.tsx +243 -0
  728. package/src/components/UserMenu/__tests__/UserMenu.accessibility.test.tsx +139 -0
  729. package/src/components/UserMenu/__tests__/UserMenu.integration.test.tsx +188 -0
  730. package/src/components/UserMenu/__tests__/UserMenu.unit.test.tsx +458 -0
  731. package/src/components/UserMenu/index.ts +3 -0
  732. package/src/components/__tests__/EdgeCaseTesting.enhanced.test.tsx +523 -0
  733. package/src/components/__tests__/ErrorTesting.enhanced.test.tsx +455 -0
  734. package/src/components/__tests__/SuperAdminGuard.test.tsx +456 -0
  735. package/src/components/__tests__/SuperAdminGuard.unit.test.tsx +456 -0
  736. package/src/components/examples/PermissionExample.tsx +150 -0
  737. package/src/components/examples/__tests__/PermissionExample.unit.test.tsx +360 -0
  738. package/src/components/index.ts +434 -0
  739. package/src/components.ts +19 -0
  740. package/src/constants/performance.ts +14 -0
  741. package/src/examples/CorrectPublicPageImplementation.tsx +301 -0
  742. package/src/examples/PublicEventPage.tsx +274 -0
  743. package/src/examples/PublicPageApp.tsx +308 -0
  744. package/src/examples/PublicPageUsageExample.tsx +216 -0
  745. package/src/fonts/georama-italic.woff2 +0 -0
  746. package/src/fonts/georama.woff2 +0 -0
  747. package/src/fonts/open-sans-italic.woff2 +0 -0
  748. package/src/fonts/open-sans.woff2 +0 -0
  749. package/src/fonts/reddit-mono.woff2 +0 -0
  750. package/src/hooks/__tests__/hooks.integration.test.tsx +575 -0
  751. package/src/hooks/__tests__/useApiFetch.unit.test.ts +115 -0
  752. package/src/hooks/__tests__/useComponentPerformance.unit.test.tsx +133 -0
  753. package/src/hooks/__tests__/useDebounce.unit.test.ts +82 -0
  754. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +293 -0
  755. package/src/hooks/__tests__/useInactivityTracker.unit.test.ts +385 -0
  756. package/src/hooks/__tests__/useOrganisationPermissions.unit.test.tsx +286 -0
  757. package/src/hooks/__tests__/useOrganisationSecurity.unit.test.tsx +838 -0
  758. package/src/hooks/__tests__/usePermissionCache.unit.test.ts +627 -0
  759. package/src/hooks/__tests__/useRBAC.unit.test.ts +903 -0
  760. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +537 -0
  761. package/src/hooks/__tests__/useToast.unit.test.tsx +62 -0
  762. package/src/hooks/__tests__/useZodForm.unit.test.tsx +37 -0
  763. package/src/hooks/index.ts +56 -0
  764. package/src/hooks/public/__tests__/usePublicEvent.test.tsx +397 -0
  765. package/src/hooks/public/__tests__/usePublicEventLogo.test.tsx +690 -0
  766. package/src/hooks/public/__tests__/usePublicRouteParams.test.tsx +449 -0
  767. package/src/hooks/public/index.ts +34 -0
  768. package/src/hooks/public/usePublicEvent.ts +261 -0
  769. package/src/hooks/public/usePublicEventLogo.ts +285 -0
  770. package/src/hooks/public/usePublicRouteParams.ts +259 -0
  771. package/src/hooks/useAppConfig.ts +94 -0
  772. package/src/hooks/useComponentPerformance.ts +39 -0
  773. package/src/hooks/useDataTablePerformance.ts +387 -0
  774. package/src/hooks/useDataTableState.ts +110 -0
  775. package/src/hooks/useDebounce.ts +18 -0
  776. package/src/hooks/useFocusManagement.ts +161 -0
  777. package/src/hooks/useFocusTrap.ts +155 -0
  778. package/src/hooks/useInactivityTracker.ts +372 -0
  779. package/src/hooks/useIsMobile.ts +42 -0
  780. package/src/hooks/useKeyboardShortcuts.ts +237 -0
  781. package/src/hooks/useOrganisationPermissions.ts +208 -0
  782. package/src/hooks/useOrganisationSecurity.ts +262 -0
  783. package/src/hooks/usePerformanceMonitor.ts +128 -0
  784. package/src/hooks/usePermissionCache.ts +455 -0
  785. package/src/hooks/useRBAC.ts +262 -0
  786. package/src/hooks/useSecureDataAccess.ts +586 -0
  787. package/src/hooks/useStorage.ts +274 -0
  788. package/src/hooks/useToast.ts +242 -0
  789. package/src/hooks/useZodForm.ts +28 -0
  790. package/src/index.ts +200 -0
  791. package/src/providers/AuthProvider.tsx +369 -0
  792. package/src/providers/EventProvider.tsx +324 -0
  793. package/src/providers/InactivityProvider.tsx +238 -0
  794. package/src/providers/OrganisationProvider.tsx +588 -0
  795. package/src/providers/RBACProvider.tsx +622 -0
  796. package/src/providers/UnifiedAuthProvider.tsx +327 -0
  797. package/src/providers/__tests__/EventProvider.unit.test.tsx +768 -0
  798. package/src/providers/__tests__/OrganisationProvider.basic.test.tsx +116 -0
  799. package/src/providers/__tests__/OrganisationProvider.unit.test.tsx +1312 -0
  800. package/src/providers/__tests__/UnifiedAuthProvider.inactivity.test.tsx +601 -0
  801. package/src/providers/__tests__/UnifiedAuthProvider.unit.test.tsx +675 -0
  802. package/src/providers/__tests__/index.unit.test.ts +78 -0
  803. package/src/providers/index.ts +15 -0
  804. package/src/rbac/README.md +885 -0
  805. package/src/rbac/__tests__/PagePermissionGuard.test.tsx +673 -0
  806. package/src/rbac/__tests__/README.md +170 -0
  807. package/src/rbac/__tests__/RoleBasedRouter.test.tsx +709 -0
  808. package/src/rbac/__tests__/TestContext.tsx +72 -0
  809. package/src/rbac/__tests__/__mocks__/cache.ts +144 -0
  810. package/src/rbac/__tests__/__mocks__/supabase.ts +152 -0
  811. package/src/rbac/__tests__/adapters-hooks-comprehensive.test.tsx +782 -0
  812. package/src/rbac/__tests__/adapters-hooks.test.tsx +561 -0
  813. package/src/rbac/__tests__/adapters.comprehensive.test.tsx +963 -0
  814. package/src/rbac/__tests__/adapters.test.tsx +444 -0
  815. package/src/rbac/__tests__/api.test.ts +620 -0
  816. package/src/rbac/__tests__/audit-observability-comprehensive.test.ts +792 -0
  817. package/src/rbac/__tests__/audit-observability.test.ts +549 -0
  818. package/src/rbac/__tests__/audit.test.ts +616 -0
  819. package/src/rbac/__tests__/build-contract-compliance-simple.test.ts +230 -0
  820. package/src/rbac/__tests__/cache-invalidation-comprehensive.test.ts +889 -0
  821. package/src/rbac/__tests__/cache-invalidation.test.ts +457 -0
  822. package/src/rbac/__tests__/cache.test.ts +458 -0
  823. package/src/rbac/__tests__/components-navigation-guard.enhanced.test.tsx +859 -0
  824. package/src/rbac/__tests__/components-navigation-guard.test.tsx +895 -0
  825. package/src/rbac/__tests__/components-navigation-provider.test.tsx +692 -0
  826. package/src/rbac/__tests__/components-page-permission-guard.test.tsx +673 -0
  827. package/src/rbac/__tests__/components-page-permission-provider.test.tsx +614 -0
  828. package/src/rbac/__tests__/components-permission-enforcer.enhanced.fixed.test.tsx +836 -0
  829. package/src/rbac/__tests__/components-permission-enforcer.enhanced.test.tsx +837 -0
  830. package/src/rbac/__tests__/components-permission-enforcer.test.tsx +825 -0
  831. package/src/rbac/__tests__/components-role-based-router.test.tsx +709 -0
  832. package/src/rbac/__tests__/components-secure-data-provider.test.tsx +607 -0
  833. package/src/rbac/__tests__/config.test.ts +583 -0
  834. package/src/rbac/__tests__/core-logic-unit.test.ts +190 -0
  835. package/src/rbac/__tests__/core-permission-logic-comprehensive.test.ts +1467 -0
  836. package/src/rbac/__tests__/core-permission-logic-fixed.test.ts +151 -0
  837. package/src/rbac/__tests__/core-permission-logic-simple.test.ts +968 -0
  838. package/src/rbac/__tests__/core-permission-logic.test.ts +966 -0
  839. package/src/rbac/__tests__/edge-cases-comprehensive.test.ts +988 -0
  840. package/src/rbac/__tests__/edge-cases.test.ts +654 -0
  841. package/src/rbac/__tests__/engine.test.ts +361 -0
  842. package/src/rbac/__tests__/engine.unit.test.ts +361 -0
  843. package/src/rbac/__tests__/hooks.enhanced.test.tsx +979 -0
  844. package/src/rbac/__tests__/hooks.fixed.test.tsx +475 -0
  845. package/src/rbac/__tests__/hooks.test.tsx +385 -0
  846. package/src/rbac/__tests__/index.test.ts +269 -0
  847. package/src/rbac/__tests__/integration.enhanced.test.tsx +824 -0
  848. package/src/rbac/__tests__/page-permission-guard-super-admin.test.tsx +261 -0
  849. package/src/rbac/__tests__/performance.enhanced.test.tsx +724 -0
  850. package/src/rbac/__tests__/permissions.test.ts +383 -0
  851. package/src/rbac/__tests__/requires-event.test.ts +330 -0
  852. package/src/rbac/__tests__/scope-isolation-comprehensive.test.ts +1349 -0
  853. package/src/rbac/__tests__/scope-isolation.test.ts +755 -0
  854. package/src/rbac/__tests__/secure-client-rls-comprehensive.test.ts +592 -0
  855. package/src/rbac/__tests__/secure-client-rls.test.ts +377 -0
  856. package/src/rbac/__tests__/security.test.ts +296 -0
  857. package/src/rbac/__tests__/setup.ts +228 -0
  858. package/src/rbac/__tests__/test-utils-enhanced.tsx +400 -0
  859. package/src/rbac/__tests__/types.test.ts +685 -0
  860. package/src/rbac/adapters.tsx +726 -0
  861. package/src/rbac/api.ts +337 -0
  862. package/src/rbac/audit-enhanced.ts +339 -0
  863. package/src/rbac/audit.ts +338 -0
  864. package/src/rbac/cache.ts +213 -0
  865. package/src/rbac/components/EnhancedNavigationMenu.tsx +294 -0
  866. package/src/rbac/components/NavigationGuard.tsx +294 -0
  867. package/src/rbac/components/NavigationProvider.tsx +314 -0
  868. package/src/rbac/components/PagePermissionGuard.tsx +430 -0
  869. package/src/rbac/components/PagePermissionProvider.tsx +274 -0
  870. package/src/rbac/components/PermissionEnforcer.tsx +307 -0
  871. package/src/rbac/components/RoleBasedRouter.tsx +425 -0
  872. package/src/rbac/components/SecureDataProvider.tsx +319 -0
  873. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +631 -0
  874. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +667 -0
  875. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +647 -0
  876. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +496 -0
  877. package/src/rbac/components/index.ts +64 -0
  878. package/src/rbac/config.ts +133 -0
  879. package/src/rbac/docs/event-based-apps.md +285 -0
  880. package/src/rbac/engine.ts +1026 -0
  881. package/src/rbac/eslint-rules.js +285 -0
  882. package/src/rbac/examples/CompleteRBACExample.tsx +323 -0
  883. package/src/rbac/examples/EventBasedApp.tsx +238 -0
  884. package/src/rbac/hooks.ts +555 -0
  885. package/src/rbac/index.ts +114 -0
  886. package/src/rbac/permissions.ts +293 -0
  887. package/src/rbac/secureClient.ts +244 -0
  888. package/src/rbac/security.ts +346 -0
  889. package/src/rbac/testing/__tests__/index.test.tsx +342 -0
  890. package/src/rbac/testing/index.tsx +340 -0
  891. package/src/rbac/types.ts +341 -0
  892. package/src/rbac/utils/__tests__/eventContext.test.ts +428 -0
  893. package/src/rbac/utils/__tests__/eventContext.unit.test.ts +428 -0
  894. package/src/rbac/utils/eventContext.ts +83 -0
  895. package/src/styles/__tests__/styles.unit.test.ts +164 -0
  896. package/src/styles/core.css +401 -0
  897. package/src/styles/index.ts +51 -0
  898. package/src/test-dom-cleanup.test.tsx +38 -0
  899. package/src/theming/__tests__/README.md +335 -0
  900. package/src/theming/__tests__/runtime.accessibility.test.ts +474 -0
  901. package/src/theming/__tests__/runtime.error.test.ts +616 -0
  902. package/src/theming/__tests__/runtime.integration.test.ts +376 -0
  903. package/src/theming/__tests__/runtime.performance.test.ts +411 -0
  904. package/src/theming/__tests__/runtime.unit.test.ts +470 -0
  905. package/src/theming/runtime.ts +187 -0
  906. package/src/types/__tests__/database.unit.test.ts +489 -0
  907. package/src/types/__tests__/guards.unit.test.ts +146 -0
  908. package/src/types/__tests__/index.unit.test.ts +77 -0
  909. package/src/types/__tests__/organisation.unit.test.ts +713 -0
  910. package/src/types/__tests__/rbac.unit.test.ts +621 -0
  911. package/src/types/__tests__/security.unit.test.ts +347 -0
  912. package/src/types/__tests__/supabase.unit.test.ts +658 -0
  913. package/src/types/__tests__/theme.unit.test.ts +218 -0
  914. package/src/types/__tests__/unified.unit.test.ts +537 -0
  915. package/src/types/__tests__/validation.unit.test.ts +616 -0
  916. package/src/types/database.ts +472 -0
  917. package/src/types/guards.ts +30 -0
  918. package/src/types/index.ts +25 -0
  919. package/src/types/organisation.ts +184 -0
  920. package/src/types/security.ts +70 -0
  921. package/src/types/supabase.ts +166 -0
  922. package/src/types/theme.ts +6 -0
  923. package/src/types/unified.ts +262 -0
  924. package/src/types/validation.ts +164 -0
  925. package/src/types/vitest-globals.d.ts +43 -0
  926. package/src/utils/__mocks__/supabaseMock.ts +75 -0
  927. package/src/utils/__mocks__/supabaseMock.tsx +198 -0
  928. package/src/utils/__tests__/appConfig.unit.test.ts +55 -0
  929. package/src/utils/__tests__/appNameResolver.unit.test.ts +137 -0
  930. package/src/utils/__tests__/audit.unit.test.ts +69 -0
  931. package/src/utils/__tests__/auth-utils.unit.test.ts +70 -0
  932. package/src/utils/__tests__/bundleAnalysis.unit.test.ts +317 -0
  933. package/src/utils/__tests__/cn.unit.test.ts +34 -0
  934. package/src/utils/__tests__/deviceFingerprint.unit.test.ts +480 -0
  935. package/src/utils/__tests__/dynamicUtils.unit.test.ts +322 -0
  936. package/src/utils/__tests__/formatDate.unit.test.ts +109 -0
  937. package/src/utils/__tests__/formatting.unit.test.ts +66 -0
  938. package/src/utils/__tests__/index.unit.test.ts +251 -0
  939. package/src/utils/__tests__/lazyLoad.unit.test.tsx +309 -0
  940. package/src/utils/__tests__/organisationContext.unit.test.ts +192 -0
  941. package/src/utils/__tests__/performanceBudgets.unit.test.ts +259 -0
  942. package/src/utils/__tests__/permissionTypes.unit.test.ts +250 -0
  943. package/src/utils/__tests__/permissionUtils.unit.test.ts +362 -0
  944. package/src/utils/__tests__/sanitization.unit.test.ts +346 -0
  945. package/src/utils/__tests__/schemaUtils.unit.test.ts +441 -0
  946. package/src/utils/__tests__/secureDataAccess.unit.test.ts +334 -0
  947. package/src/utils/__tests__/secureErrors.unit.test.ts +377 -0
  948. package/src/utils/__tests__/secureStorage.unit.test.ts +293 -0
  949. package/src/utils/__tests__/security.unit.test.ts +127 -0
  950. package/src/utils/__tests__/securityMonitor.unit.test.ts +280 -0
  951. package/src/utils/__tests__/sessionTracking.unit.test.ts +370 -0
  952. package/src/utils/__tests__/validation.unit.test.ts +84 -0
  953. package/src/utils/__tests__/validationUtils.unit.test.ts +571 -0
  954. package/src/utils/appConfig.ts +47 -0
  955. package/src/utils/appIdResolver.ts +130 -0
  956. package/src/utils/appNameResolver.ts +190 -0
  957. package/src/utils/audit.ts +127 -0
  958. package/src/utils/auth-utils.ts +96 -0
  959. package/src/utils/bundleAnalysis.ts +129 -0
  960. package/src/utils/cn.ts +7 -0
  961. package/src/utils/debugLogger.ts +46 -0
  962. package/src/utils/deviceFingerprint.ts +215 -0
  963. package/src/utils/dynamicUtils.ts +105 -0
  964. package/src/utils/formatting.ts +77 -0
  965. package/src/utils/index.ts +145 -0
  966. package/src/utils/lazyLoad.tsx +44 -0
  967. package/src/utils/organisationContext.ts +135 -0
  968. package/src/utils/performanceBenchmark.ts +64 -0
  969. package/src/utils/performanceBudgets.ts +111 -0
  970. package/src/utils/permissionTypes.ts +37 -0
  971. package/src/utils/permissionUtils.ts +31 -0
  972. package/src/utils/print/PrintDataProcessor.ts +390 -0
  973. package/src/utils/print/__tests__/PrintDataProcessor.unit.test.ts +219 -0
  974. package/src/utils/print/__tests__/usePrintOptimization.unit.test.tsx +353 -0
  975. package/src/utils/print/examples/PrintUtilitiesShowcase.tsx +397 -0
  976. package/src/utils/print/index.ts +29 -0
  977. package/src/utils/print/types.ts +196 -0
  978. package/src/utils/print/usePrintOptimization.ts +272 -0
  979. package/src/utils/sanitization.ts +264 -0
  980. package/src/utils/schemaUtils.ts +37 -0
  981. package/src/utils/secureDataAccess.ts +361 -0
  982. package/src/utils/secureErrors.ts +79 -0
  983. package/src/utils/secureStorage.ts +244 -0
  984. package/src/utils/security.ts +156 -0
  985. package/src/utils/securityMonitor.ts +45 -0
  986. package/src/utils/sessionTracking.ts +170 -0
  987. package/src/utils/storage/README.md +348 -0
  988. package/src/utils/storage/__tests__/config.unit.test.ts +206 -0
  989. package/src/utils/storage/__tests__/helpers.unit.test.ts +646 -0
  990. package/src/utils/storage/__tests__/index.unit.test.ts +167 -0
  991. package/src/utils/storage/__tests__/types.unit.test.ts +441 -0
  992. package/src/utils/storage/config.ts +100 -0
  993. package/src/utils/storage/helpers.ts +359 -0
  994. package/src/utils/storage/index.ts +36 -0
  995. package/src/utils/storage/types.ts +90 -0
  996. package/src/utils/validation.ts +111 -0
  997. package/src/utils/validationUtils.ts +120 -0
  998. package/src/validation/__tests__/common.unit.test.ts +101 -0
  999. package/src/validation/__tests__/csrf.unit.test.ts +302 -0
  1000. package/src/validation/__tests__/passwordSchema.unit.test.ts +98 -0
  1001. package/src/validation/__tests__/sqlInjectionProtection.unit.test.ts +466 -0
  1002. package/src/validation/common.ts +53 -0
  1003. package/src/validation/csrf.ts +214 -0
  1004. package/src/validation/index.ts +43 -0
  1005. package/src/validation/passwordSchema.ts +125 -0
  1006. package/src/validation/sanitization.ts +96 -0
  1007. package/src/validation/schemaUtils.ts +42 -0
  1008. package/src/validation/sqlInjectionProtection.ts +242 -0
  1009. package/src/validation/user.ts +34 -0
@@ -0,0 +1,1898 @@
1
+ # Data Tables
2
+
3
+ This guide covers implementing data tables with PACE Core's DataTable component, including basic usage, advanced features, and best practices.
4
+
5
+ ## Overview
6
+
7
+ The PACE Core DataTable is an enterprise-grade data table component built on TanStack Table that provides:
8
+
9
+ - **🚀 Performance Optimized** - Virtual scrolling, intelligent chunking, and automatic mode detection
10
+ - **📊 Data Management** - Sorting, filtering, pagination, search, export/import
11
+ - **🌳 Hierarchical Rows** - Parent/child row relationships with expand/collapse all and smart sorting ([Detailed Guide](./hierarchical-datatable.md))
12
+ - **✏️ Inline Editing** - Row editing, creation, and deletion
13
+ - **🎯 Actions** - Custom row actions and toolbar buttons
14
+ - **📈 Grouping** - Data grouping with aggregation functions
15
+ - **📏 Auto Column Sizing** - Automatic column width adjustment based on content
16
+ - **🎨 Customizable** - Column visibility, responsive design, accessibility
17
+ - **🔧 TypeScript** - Full TypeScript support with strict typing
18
+
19
+ ## Basic Usage
20
+
21
+ ### Simple Data Table
22
+
23
+ ```tsx
24
+ import { DataTable, type DataTableColumn } from '@jmruthers/pace-core';
25
+
26
+ interface User {
27
+ id: string;
28
+ name: string;
29
+ email: string;
30
+ role: string;
31
+ status: 'active' | 'inactive';
32
+ }
33
+
34
+ const columns: DataTableColumn<User>[] = [
35
+ {
36
+ accessorKey: 'name',
37
+ header: 'Name',
38
+ sortable: true,
39
+ features: { search: true },
40
+ },
41
+ {
42
+ accessorKey: 'email',
43
+ header: 'Email',
44
+ sortable: true,
45
+ features: { search: true },
46
+ },
47
+ {
48
+ accessorKey: 'role',
49
+ header: 'Role',
50
+ sortable: true,
51
+ enableGrouping: true,
52
+ },
53
+ {
54
+ accessorKey: 'status',
55
+ header: 'Status',
56
+ sortable: true,
57
+ cell: ({ row }) => (
58
+ <span className={`px-2 py-1 rounded text-xs ${
59
+ row.original.status === 'active'
60
+ ? 'bg-main-100 text-main-800'
61
+ : 'bg-acc-100 text-acc-800'
62
+ }`}>
63
+ {row.original.status}
64
+ </span>
65
+ ),
66
+ },
67
+ ];
68
+
69
+ const data: User[] = [
70
+ { id: '1', name: 'John Doe', email: 'john@example.com', role: 'Admin', status: 'active' },
71
+ { id: '2', name: 'Jane Smith', email: 'jane@example.com', role: 'User', status: 'active' },
72
+ ];
73
+
74
+ function UserTable() {
75
+ return (
76
+ <DataTable
77
+ data={data}
78
+ columns={columns}
79
+ title="Users"
80
+ description="Manage your users"
81
+ features={{
82
+ search: true,
83
+ pagination: true,
84
+ sorting: true,
85
+ filtering: true,
86
+ }}
87
+ columnOrder={['name', 'email', 'role', 'status']} // Control column order
88
+ // Performance and other settings can be configured via performance prop
89
+ />
90
+ );
91
+ }
92
+ ```
93
+
94
+ ### With Permission Enforcement
95
+
96
+ ```tsx
97
+ import { DataTable, PagePermissionGuard, PAGE_IDS } from '@jmruthers/pace-core';
98
+
99
+ function UsersPage() {
100
+ return (
101
+ <PagePermissionGuard pageId={PAGE_IDS.USER_MANAGEMENT}>
102
+ {(permissions) => (
103
+ <DataTable
104
+ data={users}
105
+ columns={columns}
106
+ title="User Management"
107
+ description="Manage system users"
108
+ features={{
109
+ search: true,
110
+ pagination: true,
111
+ creation: permissions.canCreate,
112
+ editing: permissions.canUpdate,
113
+ deletion: permissions.canDelete,
114
+ }}
115
+ onEditRow={permissions.canUpdate ? (row) => navigate(`/users/${row.id}/edit`) : undefined}
116
+ onDeleteRow={permissions.canDelete ? handleDeleteUser : undefined}
117
+ // Custom actions can be added via the deprecated actions prop
118
+ actions={
119
+ permissions.canUpdate || permissions.canDelete ? [
120
+ ...(permissions.canUpdate ? [{
121
+ label: 'View Details',
122
+ onClick: (row) => navigate(`/users/${row.id}`),
123
+ }] : [])
124
+ ] : []
125
+ }
126
+ />
127
+ )}
128
+ </PagePermissionGuard>
129
+ );
130
+ }
131
+ ```
132
+
133
+ ## DataTable Props Interface
134
+
135
+ The DataTable component has a comprehensive prop interface. Here are the key properties:
136
+
137
+ ### Core Props
138
+ - `data: TData[]` - Array of data records to display
139
+ - `columns: any[]` - Column definitions (supports TanStack Table format)
140
+ - `features: DataTableFeatureConfig` - **Required** - Feature configuration object
141
+
142
+ ### Display Props
143
+ - `title?: string` - Table title
144
+ - `description?: string` - Table description
145
+ - `variant?: 'default' | 'compact' | 'spacious'` - Visual variant
146
+ - `className?: string` - Additional CSS classes
147
+ - `columnOrder?: string[]` - **Column ordering** - Array of column IDs in desired order
148
+
149
+ ### Event Handlers
150
+ - `onEditRow?: (row: TData, data: Partial<TData>) => void` - Row edit handler
151
+ - `onDeleteRow?: (row: TData) => void` - Row deletion handler (also used as fallback for bulk delete)
152
+ - `onCreateRow?: (data: Partial<TData>) => void` - Row creation handler
153
+ - `onImport?: (data: TData[]) => void | Promise<void>` - Import handler
154
+ - `onRowSelectionChange?: (selection: Record<string, boolean>) => void` - Row selection change handler
155
+ - `onDeleteSelected?: (selectedRows: Record<string, boolean>) => void` - **Bulk delete handler** - Called when delete selected button is clicked
156
+
157
+ ### Performance Props
158
+ - `performance?: PerformanceConfig` - Performance optimization settings
159
+ - `serverSide?: ServerSideConfig<TData>` - Server-side data fetching
160
+ - `virtualHeight?: number` - Virtual scrolling height (default: 600)
161
+ - `showPerformanceMetrics?: boolean` - Show performance metrics
162
+ - `initialPageSize?: number` - Initial page size for pagination (default: 10)
163
+
164
+ ### Feature-Specific Configuration
165
+ - `bulkOperationsConfig?: BulkOperationsConfig` - Bulk operations config
166
+
167
+ ### Row Actions
168
+ - `actions?: any[]` - Custom row actions for each row
169
+
170
+ ## Feature Configuration
171
+
172
+ The DataTable component uses a unified `features` prop to control all table functionality. This provides a consistent and intuitive way to enable or disable features.
173
+
174
+ ### DataTableFeatureConfig Properties
175
+
176
+ | Property | Type | Default | Description |
177
+ |----------|------|---------|-------------|
178
+ | **Core Features** |
179
+ | `search` | `boolean` | `false` | Enable global search functionality |
180
+ | `pagination` | `boolean` | `false` | Enable pagination controls |
181
+ | `sorting` | `boolean` | `false` | Enable column sorting |
182
+ | `filtering` | `boolean` | `false` | Enable column filtering |
183
+ | **Data Management** |
184
+ | `import` | `boolean` | `false` | Enable data import functionality |
185
+ | `export` | `boolean` | `false` | Enable data export functionality |
186
+ | **Row Operations** |
187
+ | `selection` | `boolean` | `false` | Enable row selection for bulk operations |
188
+ | `creation` | `boolean` | `false` | Enable row creation |
189
+ | `editing` | `boolean` | `false` | Enable row editing |
190
+ | `deletion` | `boolean` | `false` | Enable row deletion |
191
+ | `deleteSelected` | `boolean` | `false` | Enable bulk deletion of selected rows |
192
+ | **Table Customization** |
193
+ | `grouping` | `boolean` | `false` | Enable data grouping |
194
+ | `columnVisibility` | `boolean` | `false` | Enable column visibility controls |
195
+ | `columnReordering` | `boolean` | `false` | Enable column reordering |
196
+ | `autoColumnSizing` | `boolean` | `false` | Enable automatic column width adjustment based on content |
197
+
198
+ ### Basic Feature Configuration
199
+
200
+ ```tsx
201
+ <DataTable
202
+ data={data}
203
+ columns={columns}
204
+ features={{
205
+ // Core Features
206
+ search: true,
207
+ pagination: true,
208
+ sorting: true,
209
+ filtering: true,
210
+
211
+ // Data Management
212
+ import: true,
213
+ export: true,
214
+
215
+ // Row Operations
216
+ selection: true, // Required for row selection
217
+ creation: true,
218
+ editing: true,
219
+ deletion: true, // Required for delete functionality
220
+ deleteSelected: true, // Required for delete selected button
221
+
222
+ // Table Customization
223
+ grouping: true,
224
+ columnVisibility: true,
225
+ columnReordering: true,
226
+ autoColumnSizing: true, // Enable automatic column width adjustment
227
+ }}
228
+ />
229
+ ```
230
+
231
+ ### Minimal Configuration
232
+
233
+ For a simple read-only table:
234
+
235
+ ```tsx
236
+ <DataTable
237
+ data={data}
238
+ columns={columns}
239
+ features={{
240
+ search: true,
241
+ pagination: true,
242
+ sorting: true,
243
+ }}
244
+ />
245
+ ```
246
+
247
+ ### Advanced Configuration
248
+
249
+ For a full-featured data management table:
250
+
251
+ ```tsx
252
+ <DataTable
253
+ data={data}
254
+ columns={columns}
255
+ features={{
256
+ search: true,
257
+ pagination: true,
258
+ sorting: true,
259
+ filtering: true,
260
+ selection: true,
261
+ creation: true,
262
+ editing: true,
263
+ deletion: true,
264
+ deleteSelected: true, // Enable delete selected functionality
265
+ export: true,
266
+ import: true,
267
+ grouping: true,
268
+ columnVisibility: true,
269
+ bulkOperations: true,
270
+ }}
271
+ columnOrder={['select', 'name', 'email', 'role', 'status', 'actions']} // Custom column order
272
+ onEditRow={handleEdit}
273
+ onDeleteRow={handleDelete}
274
+ onCreateRow={handleCreate}
275
+ onImport={handleImport}
276
+ onRowSelectionChange={handleSelectionChange}
277
+ onDeleteSelected={handleBulkDelete}
278
+ getRowId={(row) => row.id} // Important: Required for selection and delete operations
279
+ />
280
+ ```
281
+
282
+ ## Auto Column Sizing
283
+
284
+ The DataTable component includes automatic column width adjustment based on content, which helps optimize space usage and improve readability.
285
+
286
+ ### How Auto-Sizing Works
287
+
288
+ When `autoColumnSizing: true` is enabled:
289
+
290
+ 1. **Content Analysis**: Analyzes both header text and data content to determine optimal widths
291
+ 2. **Smart Calculation**: Uses character count estimation (8px per character + padding)
292
+ 3. **Constraints**: Respects min-width (80px) and max-width (400px) limits
293
+ 4. **Performance**: Only samples first 100 rows for large datasets
294
+ 5. **Table Layout**: Switches from `tableLayout: 'fixed'` to `tableLayout: 'auto'`
295
+
296
+ ### Benefits
297
+
298
+ - **Better Space Utilization**: Columns automatically adjust to content width
299
+ - **Improved Readability**: Long text gets more space, short text takes less space
300
+ - **No Text Wrapping**: Prevents unnecessary text wrapping in narrow columns
301
+ - **Consistent Layout**: Maintains proper spacing and alignment
302
+
303
+ ### Enabling Auto-Sizing
304
+
305
+ ```tsx
306
+ <DataTable
307
+ data={data}
308
+ columns={columns}
309
+ features={{
310
+ search: true,
311
+ pagination: true,
312
+ sorting: true,
313
+ autoColumnSizing: true, // Enable automatic column width adjustment
314
+ }}
315
+ />
316
+ ```
317
+
318
+ ### Auto-Sizing vs Fixed Widths
319
+
320
+ **With Auto-Sizing (Recommended):**
321
+ - Columns automatically adjust to content width
322
+ - Long text gets more space, short text takes less space
323
+ - Better space utilization
324
+ - Improved readability
325
+
326
+ **Without Auto-Sizing:**
327
+ - All columns have equal width
328
+ - Long text may wrap unnecessarily
329
+ - Short columns have wasted space
330
+ - Consistent but potentially inefficient layout
331
+
332
+ ### Example: Content-Based Sizing
333
+
334
+ ```tsx
335
+ const data = [
336
+ { id: '1', name: 'John', description: 'A short description' },
337
+ { id: '2', name: 'Jane', description: 'A very long description that should make this column wider' },
338
+ { id: '3', name: 'Bob', description: 'Medium length description' }
339
+ ];
340
+
341
+ const columns = [
342
+ { accessorKey: 'name', header: 'Name' },
343
+ { accessorKey: 'description', header: 'Description' }
344
+ ];
345
+
346
+ // With auto-sizing: Description column will be wider than Name column
347
+ <DataTable
348
+ data={data}
349
+ columns={columns}
350
+ features={{ autoColumnSizing: true }}
351
+ />
352
+ ```
353
+
354
+ ### Feature-Based Conditional Rendering
355
+
356
+ When features are disabled, the corresponding UI elements are automatically hidden:
357
+
358
+ ```tsx
359
+ // This will show only search and pagination controls
360
+ // No edit, delete, or action buttons will appear
361
+ <DataTable
362
+ data={data}
363
+ columns={columns}
364
+ features={{
365
+ search: true,
366
+ pagination: true,
367
+ // All other features disabled by default
368
+ }}
369
+ />
370
+ ```
371
+
372
+ ## Column Configuration
373
+
374
+ ### Basic Column Properties
375
+
376
+ ```tsx
377
+ const columns: DataTableColumn<User>[] = [
378
+ {
379
+ accessorKey: 'name', // Data field to access
380
+ header: 'Name', // Column header
381
+ sortable: true, // Enable sorting
382
+ features: { search: true }, // Enable search
383
+ enableGrouping: true, // Enable grouping
384
+ size: 200, // Column width
385
+ minSize: 100, // Minimum width
386
+ maxSize: 300, // Maximum width
387
+ },
388
+ ];
389
+ ```
390
+
391
+ ### Custom Cell Rendering
392
+
393
+ ```tsx
394
+ const columns: DataTableColumn<User>[] = [
395
+ {
396
+ accessorKey: 'avatar',
397
+ header: 'Avatar',
398
+ cell: ({ row }) => (
399
+ <Avatar>
400
+ <AvatarImage src={row.original.avatarUrl} />
401
+ <AvatarFallback>
402
+ {row.original.name.charAt(0).toUpperCase()}
403
+ </AvatarFallback>
404
+ </Avatar>
405
+ ),
406
+ },
407
+ {
408
+ accessorKey: 'status',
409
+ header: 'Status',
410
+ cell: ({ row }) => (
411
+ <Badge variant={row.original.status === 'active' ? 'default' : 'secondary'}>
412
+ {row.original.status}
413
+ </Badge>
414
+ ),
415
+ },
416
+ {
417
+ accessorKey: 'lastLogin',
418
+ header: 'Last Login',
419
+ cell: ({ row }) => (
420
+ <span className="text-sm text-muted-foreground">
421
+ {formatDate(row.original.lastLogin)}
422
+ </span>
423
+ ),
424
+ },
425
+ ];
426
+ ```
427
+
428
+ ### Advanced Column Features
429
+
430
+ ```tsx
431
+ const columns: DataTableColumn<User>[] = [
432
+ {
433
+ accessorKey: 'name',
434
+ header: 'Name',
435
+ sortable: true,
436
+ features: { search: true },
437
+ enableColumnFilter: true,
438
+ filterFn: 'includesString',
439
+ },
440
+ {
441
+ accessorKey: 'role',
442
+ header: 'Role',
443
+ enableGrouping: true,
444
+ enableColumnFilter: true,
445
+ filterFn: 'equals',
446
+ cell: ({ row }) => (
447
+ <Select value={row.original.role} onValueChange={(value) => handleRoleChange(row.original.id, value)}>
448
+ <SelectTrigger>
449
+ <SelectValue />
450
+ </SelectTrigger>
451
+ <SelectContent>
452
+ <SelectItem value="admin">Admin</SelectItem>
453
+ <SelectItem value="user">User</SelectItem>
454
+ <SelectItem value="guest">Guest</SelectItem>
455
+ </SelectContent>
456
+ </Select>
457
+ ),
458
+ },
459
+ ];
460
+ ```
461
+
462
+ ## Column Ordering
463
+
464
+ The DataTable component supports custom column ordering through the `columnOrder` prop, allowing you to control the exact position of columns including selection and actions columns.
465
+
466
+ ### Basic Column Ordering
467
+
468
+ ```tsx
469
+ <DataTable
470
+ data={data}
471
+ columns={columns}
472
+ features={{
473
+ selection: true,
474
+ sorting: true,
475
+ filtering: true,
476
+ }}
477
+ columnOrder={['select', 'name', 'email', 'role', 'status']}
478
+ />
479
+ ```
480
+
481
+ ### Column Order Behavior
482
+
483
+ #### When `columnOrder` is provided:
484
+ - **Exact positioning**: Columns appear in the exact order specified
485
+ - **Selection column**: Include `'select'` in the array to position the selection column
486
+ - **Actions column**: Include `'actions'` in the array to position the actions column
487
+ - **Data columns**: Use the column's `accessorKey` or `id` to reference data columns
488
+
489
+ #### When `columnOrder` is not provided:
490
+ - **Default behavior**: Selection column first (if enabled), then data columns, then actions column
491
+ - **Automatic ordering**: Columns appear in the order they're defined in the `columns` array
492
+
493
+ ### Selection Column Positioning
494
+
495
+ The selection column can be positioned anywhere in the column order:
496
+
497
+ ```tsx
498
+ // Selection column first (default when not in columnOrder)
499
+ <DataTable
500
+ data={data}
501
+ columns={columns}
502
+ features={{ selection: true }}
503
+ columnOrder={['select', 'name', 'email', 'role']}
504
+ />
505
+
506
+ // Selection column in the middle
507
+ <DataTable
508
+ data={data}
509
+ columns={columns}
510
+ features={{ selection: true }}
511
+ columnOrder={['name', 'select', 'email', 'role']}
512
+ />
513
+
514
+ // Selection column last
515
+ <DataTable
516
+ data={data}
517
+ columns={columns}
518
+ features={{ selection: true }}
519
+ columnOrder={['name', 'email', 'role', 'select']}
520
+ />
521
+
522
+ // Selection column not in columnOrder - defaults to first position
523
+ <DataTable
524
+ data={data}
525
+ columns={columns}
526
+ features={{ selection: true }}
527
+ columnOrder={['name', 'email', 'role']} // selection will be first
528
+ />
529
+ ```
530
+
531
+ ### Actions Column Positioning
532
+
533
+ The actions column can also be positioned anywhere:
534
+
535
+ ```tsx
536
+ // Actions column last (default when not in columnOrder)
537
+ <DataTable
538
+ data={data}
539
+ columns={columns}
540
+ features={{ editing: true, deletion: true }}
541
+ columnOrder={['name', 'email', 'role', 'actions']}
542
+ />
543
+
544
+ // Actions column first
545
+ <DataTable
546
+ data={data}
547
+ columns={columns}
548
+ features={{ editing: true, deletion: true }}
549
+ columnOrder={['actions', 'name', 'email', 'role']}
550
+ />
551
+
552
+ // Actions column in the middle
553
+ <DataTable
554
+ data={data}
555
+ columns={columns}
556
+ features={{ editing: true, deletion: true }}
557
+ columnOrder={['name', 'actions', 'email', 'role']}
558
+ />
559
+ ```
560
+
561
+ ### Complete Column Ordering Example
562
+
563
+ ```tsx
564
+ interface User {
565
+ id: string;
566
+ name: string;
567
+ email: string;
568
+ role: string;
569
+ status: 'active' | 'inactive';
570
+ createdAt: Date;
571
+ }
572
+
573
+ const columns: DataTableColumn<User>[] = [
574
+ {
575
+ accessorKey: 'name',
576
+ header: 'Name',
577
+ sortable: true,
578
+ },
579
+ {
580
+ accessorKey: 'email',
581
+ header: 'Email',
582
+ sortable: true,
583
+ },
584
+ {
585
+ accessorKey: 'role',
586
+ header: 'Role',
587
+ sortable: true,
588
+ enableGrouping: true,
589
+ },
590
+ {
591
+ accessorKey: 'status',
592
+ header: 'Status',
593
+ sortable: true,
594
+ },
595
+ {
596
+ accessorKey: 'createdAt',
597
+ header: 'Created',
598
+ sortable: true,
599
+ },
600
+ ];
601
+
602
+ function UserTable() {
603
+ return (
604
+ <DataTable
605
+ data={users}
606
+ columns={columns}
607
+ title="User Management"
608
+ features={{
609
+ selection: true,
610
+ sorting: true,
611
+ filtering: true,
612
+ editing: true,
613
+ deletion: true,
614
+ }}
615
+ // Custom column order: selection first, then name, email, role, status, actions, created last
616
+ columnOrder={['select', 'name', 'email', 'role', 'status', 'actions', 'createdAt']}
617
+ onEditRow={handleEdit}
618
+ onDeleteRow={handleDelete}
619
+ />
620
+ );
621
+ }
622
+ ```
623
+
624
+ ### Column Ordering with Hierarchical Data
625
+
626
+ When using hierarchical data, column ordering works the same way:
627
+
628
+ ```tsx
629
+ <DataTable
630
+ data={hierarchicalData}
631
+ columns={columns}
632
+ features={{
633
+ hierarchical: true,
634
+ selection: true,
635
+ editing: true,
636
+ deletion: true,
637
+ }}
638
+ hierarchical={{
639
+ enabled: true,
640
+ defaultExpanded: false,
641
+ }}
642
+ // Custom order for hierarchical table
643
+ columnOrder={['select', 'name', 'ingredient', 'quantity', 'actions']}
644
+ />
645
+ ```
646
+
647
+ ### Dynamic Column Ordering
648
+
649
+ You can dynamically change column order based on user preferences or application state:
650
+
651
+ ```tsx
652
+ function DynamicUserTable() {
653
+ const [columnOrder, setColumnOrder] = useState(['select', 'name', 'email', 'role', 'status']);
654
+
655
+ const handleColumnReorder = (newOrder: string[]) => {
656
+ setColumnOrder(newOrder);
657
+ // Save to localStorage or user preferences
658
+ localStorage.setItem('userTableColumnOrder', JSON.stringify(newOrder));
659
+ };
660
+
661
+ return (
662
+ <DataTable
663
+ data={users}
664
+ columns={columns}
665
+ features={{
666
+ selection: true,
667
+ sorting: true,
668
+ columnReordering: true, // Enable drag-and-drop reordering
669
+ }}
670
+ columnOrder={columnOrder}
671
+ onColumnOrderChange={handleColumnReorder}
672
+ />
673
+ );
674
+ }
675
+ ```
676
+
677
+ ### Column Ordering Best Practices
678
+
679
+ #### 1. **Consistent Ordering**
680
+ ```tsx
681
+ // ✅ Good - Consistent ordering across similar tables
682
+ const userTableOrder = ['select', 'name', 'email', 'role', 'status', 'actions'];
683
+ const productTableOrder = ['select', 'name', 'sku', 'price', 'status', 'actions'];
684
+
685
+ // ❌ Avoid - Inconsistent ordering
686
+ const userTableOrder = ['select', 'name', 'email', 'role', 'status', 'actions'];
687
+ const productTableOrder = ['name', 'select', 'sku', 'actions', 'price', 'status'];
688
+ ```
689
+
690
+ #### 2. **Logical Grouping**
691
+ ```tsx
692
+ // ✅ Good - Logical grouping of related columns
693
+ columnOrder={[
694
+ 'select', // Selection controls
695
+ 'name', 'email', // Identity information
696
+ 'role', 'status', // Access and state
697
+ 'createdAt', // Metadata
698
+ 'actions' // Actions
699
+ ]}
700
+
701
+ // ❌ Avoid - Random column order
702
+ columnOrder={['email', 'actions', 'name', 'select', 'status', 'role', 'createdAt']}
703
+ ```
704
+
705
+ #### 3. **User Experience Considerations**
706
+ ```tsx
707
+ // ✅ Good - Most important columns first
708
+ columnOrder={['select', 'name', 'email', 'role', 'status', 'actions']}
709
+
710
+ // ✅ Good - Actions column last (standard pattern)
711
+ columnOrder={['select', 'name', 'email', 'role', 'status', 'actions']}
712
+
713
+ // ❌ Avoid - Actions column in the middle (confusing)
714
+ columnOrder={['select', 'name', 'actions', 'email', 'role', 'status']}
715
+ ```
716
+
717
+ #### 4. **Responsive Considerations**
718
+ ```tsx
719
+ // For mobile-first design, put most important columns first
720
+ const mobileColumnOrder = ['select', 'name', 'status', 'actions'];
721
+ const desktopColumnOrder = ['select', 'name', 'email', 'role', 'status', 'createdAt', 'actions'];
722
+
723
+ <DataTable
724
+ data={users}
725
+ columns={columns}
726
+ features={{ selection: true, sorting: true }}
727
+ columnOrder={isMobile ? mobileColumnOrder : desktopColumnOrder}
728
+ />
729
+ ```
730
+
731
+ ## Data Management
732
+
733
+ ### Sorting
734
+
735
+ ```tsx
736
+ <DataTable
737
+ data={data}
738
+ columns={columns}
739
+ features={{ sorting: true }}
740
+ defaultSorting={[
741
+ { id: 'name', desc: false },
742
+ { id: 'createdAt', desc: true }
743
+ ]}
744
+ />
745
+ ```
746
+
747
+ ### Filtering
748
+
749
+ ```tsx
750
+ <DataTable
751
+ data={data}
752
+ columns={columns}
753
+ features={{ filtering: true }}
754
+ globalFilterFn="includesString"
755
+ columnFilters={[
756
+ { id: 'status', value: 'active' },
757
+ { id: 'role', value: 'admin' }
758
+ ]}
759
+ />
760
+ ```
761
+
762
+ ### Pagination
763
+
764
+ ```tsx
765
+ <DataTable
766
+ data={data}
767
+ columns={columns}
768
+ features={{ pagination: true }}
769
+ />
770
+ ```
771
+
772
+ #### Custom Initial Page Size
773
+
774
+ ```tsx
775
+ <DataTable
776
+ data={data}
777
+ columns={columns}
778
+ features={{ pagination: true }}
779
+ initialPageSize={25} // Start with 25 items per page instead of default 10
780
+ />
781
+ ```
782
+
783
+ #### Page Size Validation
784
+
785
+ The DataTable automatically validates the `initialPageSize` against available page size options:
786
+
787
+ ```tsx
788
+ <DataTable
789
+ data={data}
790
+ columns={columns}
791
+ features={{ pagination: true }}
792
+ initialPageSize={15} // Will fallback to closest valid option (10) with console warning
793
+ />
794
+ ```
795
+
796
+ **Available page size options by mode:**
797
+ - **Client mode**: `[10, 25, 50]` or `[10, 25, 50, 100]` (depending on data size)
798
+ - **Hybrid mode**: `[50, 100, 250, 500]`
799
+ - **Server mode**: `[25, 50, 100, 250]`
800
+
801
+ ### Search
802
+
803
+ ```tsx
804
+ <DataTable
805
+ data={data}
806
+ columns={columns}
807
+ features={{ search: true }}
808
+ searchKey="name" // Default search field
809
+ searchPlaceholder="Search users..."
810
+ searchDebounceMs={300}
811
+ />
812
+ ```
813
+
814
+ ## Advanced Features
815
+
816
+ ### Row Actions
817
+
818
+ Row actions are handled through the `actions` prop, which provides full flexibility for custom action buttons:
819
+
820
+ ```tsx
821
+ <DataTable
822
+ data={data}
823
+ columns={columns}
824
+ features={{
825
+ editing: true,
826
+ deletion: true,
827
+ }}
828
+ onEditRow={handleEdit}
829
+ onDeleteRow={handleDelete}
830
+ // Custom actions using the actions prop
831
+ actions={[
832
+ {
833
+ label: 'View Details',
834
+ onClick: (row) => navigate(`/users/${row.original.id}`),
835
+ icon: EyeIcon,
836
+ variant: 'default',
837
+ },
838
+ {
839
+ label: 'Edit',
840
+ onClick: (row) => editUser(row.original.id),
841
+ icon: EditIcon,
842
+ variant: 'outline',
843
+ },
844
+ {
845
+ label: 'Share',
846
+ onClick: (row) => shareUser(row.original.id),
847
+ icon: ShareIcon,
848
+ variant: 'secondary',
849
+ },
850
+ {
851
+ label: 'More Options',
852
+ onClick: (row) => showMoreOptions(row.original.id),
853
+ icon: MoreHorizontalIcon,
854
+ variant: 'ghost',
855
+ },
856
+ {
857
+ label: 'Archive',
858
+ onClick: (row) => archiveUser(row.original.id),
859
+ icon: ArchiveIcon,
860
+ variant: 'destructive',
861
+ disabled: (row) => row.original.status === 'archived',
862
+ },
863
+ ]}
864
+ />
865
+ ```
866
+
867
+ #### Action Configuration
868
+
869
+ Each action supports the following properties:
870
+
871
+ - `label: string` - Display label for the action
872
+ - `onClick: (row: TData) => void` - Action handler function
873
+ - `icon?: ComponentType` - Optional icon component
874
+ - `variant?: 'default' | 'destructive' | 'outline' | 'secondary' | 'ghost'` - Button variant
875
+ - `disabled?: (row: TData) => boolean` - Function to determine if action is disabled
876
+ - `testId?: string` - Test ID for testing
877
+ - `visible?: boolean | (row: TData) => boolean` - Control visibility
878
+ - `showInEditMode?: boolean` - Show in edit mode (default: true)
879
+ - `hideInViewMode?: boolean` - Hide in view mode (default: false)
880
+
881
+ #### Action Variants Guide
882
+
883
+ The DataTable supports 5 action variants, each designed for specific use cases:
884
+
885
+ ```tsx
886
+ const actions = [
887
+ // DEFAULT - Primary actions (most important)
888
+ {
889
+ label: 'View Details',
890
+ onClick: (row) => viewDetails(row.original.id),
891
+ icon: EyeIcon,
892
+ variant: 'default', // Solid background, primary color
893
+ },
894
+
895
+ // OUTLINE - Secondary actions (important but not primary)
896
+ {
897
+ label: 'Edit',
898
+ onClick: (row) => editItem(row.original.id),
899
+ icon: EditIcon,
900
+ variant: 'outline', // Bordered, transparent background
901
+ },
902
+
903
+ // SECONDARY - Supporting actions (less prominent)
904
+ {
905
+ label: 'Share',
906
+ onClick: (row) => shareItem(row.original.id),
907
+ icon: ShareIcon,
908
+ variant: 'secondary', // Muted background, subtle styling
909
+ },
910
+
911
+ // GHOST - Subtle actions (minimal visual impact)
912
+ {
913
+ label: 'More Options',
914
+ onClick: (row) => showMoreOptions(row.original.id),
915
+ icon: MoreHorizontalIcon,
916
+ variant: 'ghost', // No background, minimal styling
917
+ },
918
+
919
+ // DESTRUCTIVE - Dangerous actions (require caution)
920
+ {
921
+ label: 'Delete',
922
+ onClick: (row) => deleteItem(row.original.id),
923
+ icon: TrashIcon,
924
+ variant: 'destructive', // Red styling to indicate danger
925
+ disabled: (row) => row.original.status === 'locked',
926
+ },
927
+ ];
928
+ ```
929
+
930
+ **Variant Usage Guidelines:**
931
+
932
+ - **`default`**: Use for the most important action (e.g., "View Details", "Open")
933
+ - **`outline`**: Use for important secondary actions (e.g., "Edit", "Download")
934
+ - **`secondary`**: Use for supporting actions (e.g., "Share", "Copy", "Export")
935
+ - **`ghost`**: Use for subtle actions (e.g., "More Options", "Settings")
936
+ - **`destructive`**: Use for dangerous actions (e.g., "Delete", "Archive", "Remove")
937
+
938
+ #### Hierarchical Actions
939
+
940
+ When using hierarchical rows, you can define different action icons and labels for parent vs child rows:
941
+
942
+ ```tsx
943
+ <DataTable
944
+ data={hierarchicalData}
945
+ columns={columns}
946
+ features={{
947
+ hierarchical: true,
948
+ editing: true,
949
+ deletion: true,
950
+ }}
951
+ hierarchical={{
952
+ enabled: true,
953
+ defaultExpanded: false,
954
+ }}
955
+ actions={[
956
+ {
957
+ label: 'View Details',
958
+ icon: EyeIcon,
959
+ // Different icons for parent vs child rows
960
+ parentIcon: EyeIcon,
961
+ childIcon: InfoIcon,
962
+ // Different labels for parent vs child rows
963
+ parentLabel: 'View Recipe',
964
+ childLabel: 'View Ingredient',
965
+ onClick: (row) => {
966
+ console.log('Viewing:', row.isParent ? 'Recipe' : 'Ingredient', row.name);
967
+ },
968
+ variant: 'default',
969
+ },
970
+ {
971
+ label: 'Edit',
972
+ icon: PencilIcon,
973
+ parentIcon: SettingsIcon,
974
+ childIcon: PencilIcon,
975
+ parentLabel: 'Edit Recipe',
976
+ childLabel: 'Edit Ingredient',
977
+ onClick: (row) => {
978
+ console.log('Editing:', row.isParent ? 'Recipe' : 'Ingredient', row.name);
979
+ },
980
+ variant: 'default',
981
+ },
982
+ {
983
+ label: 'Copy Recipe',
984
+ icon: CopyIcon,
985
+ parentIcon: CopyIcon,
986
+ parentLabel: 'Duplicate Recipe',
987
+ onClick: (row) => {
988
+ console.log('Copying recipe:', row.name);
989
+ },
990
+ variant: 'outline',
991
+ // Only show for parent rows
992
+ showForParent: true,
993
+ },
994
+ {
995
+ label: 'Export',
996
+ icon: DownloadIcon,
997
+ childIcon: DownloadIcon,
998
+ childLabel: 'Export Ingredient',
999
+ onClick: (row) => {
1000
+ console.log('Exporting ingredient:', row.item);
1001
+ },
1002
+ variant: 'ghost',
1003
+ // Only show for child rows
1004
+ showForChild: true,
1005
+ },
1006
+ ]}
1007
+ />
1008
+ ```
1009
+
1010
+ ##### Hierarchical Action Properties
1011
+
1012
+ When using hierarchical rows, actions support additional properties:
1013
+
1014
+ - `showForParent?: boolean` - Only show this action for parent rows
1015
+ - `showForChild?: boolean` - Only show this action for child rows
1016
+ - `parentIcon?: ComponentType` - Icon to use for parent rows (overrides `icon`)
1017
+ - `childIcon?: ComponentType` - Icon to use for child rows (overrides `icon`)
1018
+ - `parentLabel?: string` - Label to use for parent rows (overrides `label`)
1019
+ - `childLabel?: string` - Label to use for child rows (overrides `label`)
1020
+
1021
+ ##### Action Visibility Logic
1022
+
1023
+ The action visibility is determined by the following logic:
1024
+
1025
+ 1. **Hierarchical filtering**: If `showForParent` is true, action only shows for parent rows
1026
+ 2. **Hierarchical filtering**: If `showForChild` is true, action only shows for child rows
1027
+ 3. **Standard filtering**: Uses `visible`, `showInEditMode`, `hideInViewMode` properties
1028
+ 4. **Disabled state**: Uses `disabled` function to determine if action is disabled
1029
+
1030
+ ### Toolbar Actions
1031
+
1032
+ Toolbar actions are automatically generated based on the enabled features. Custom toolbar buttons are not directly supported in the current interface, but you can implement them outside the DataTable component:
1033
+
1034
+ ```tsx
1035
+ // Toolbar actions are handled through feature configuration
1036
+ <div>
1037
+ {/* Custom toolbar */}
1038
+ <div className="flex gap-2 mb-4">
1039
+ <Button onClick={() => navigate('/users/create')}>
1040
+ <PlusIcon className="h-4 w-4 mr-2" />
1041
+ Add User
1042
+ </Button>
1043
+ </div>
1044
+
1045
+ <DataTable
1046
+ data={data}
1047
+ columns={columns}
1048
+ features={{
1049
+ search: true,
1050
+ pagination: true,
1051
+ export: true,
1052
+ import: true,
1053
+ creation: true, // Enables built-in create functionality if onCreateRow is provided
1054
+ }}
1055
+ onCreateRow={handleCreate}
1056
+ onImport={handleImport}
1057
+ exportFilename="users"
1058
+ />
1059
+ </div>
1060
+ ```
1061
+
1062
+ ### Hierarchical Parent/Child Rows
1063
+
1064
+ The DataTable supports hierarchical parent/child row relationships with built-in expand/collapse functionality, expand/collapse all controls, and proper column rendering for different row types.
1065
+
1066
+ #### Data Structure
1067
+
1068
+ Your data must conform to the `HierarchicalDataRow` interface:
1069
+
1070
+ ```typescript
1071
+ interface HierarchicalDataRow extends DataRecord {
1072
+ /** Whether this row is a parent row */
1073
+ isParent: boolean;
1074
+ /** For child rows, references the parent row ID */
1075
+ parentId?: string;
1076
+ /** Unique identifier for this row */
1077
+ id: string;
1078
+ // ... your actual data properties
1079
+ }
1080
+ ```
1081
+
1082
+ #### Configuration
1083
+
1084
+ Enable hierarchical functionality through the `features` prop and configure it with the `hierarchical` prop:
1085
+
1086
+ ```tsx
1087
+ <DataTable
1088
+ data={hierarchicalData}
1089
+ columns={columns}
1090
+ features={{
1091
+ // ... other features
1092
+ hierarchical: true, // Enable hierarchical functionality
1093
+ }}
1094
+ hierarchical={{
1095
+ enabled: true,
1096
+ defaultExpanded: false, // true = all expanded, false = all collapsed, array = specific IDs
1097
+ onExpandedChange: (expandedIds) => console.log('Expanded:', expandedIds),
1098
+ expandButton: CustomExpandButton, // Optional custom expand button
1099
+ indentSize: 24, // Indentation for child rows in pixels
1100
+ parentRowClassName: 'bg-main-50 font-medium', // Custom styling for parent rows
1101
+ childRowClassName: 'bg-sec-25', // Custom styling for child rows
1102
+ }}
1103
+ ```
1104
+
1105
+ **Default Collapsed State:**
1106
+ To make parent rows collapsed by default (recommended for better UX), set `defaultExpanded: false`. This ensures users see only parent rows initially and must click to expand and view child rows.
1107
+
1108
+ #### Column Configuration
1109
+
1110
+ Configure how columns render for different row types:
1111
+
1112
+ ```tsx
1113
+ const columns: DataTableColumn<YourDataType>[] = [
1114
+ {
1115
+ accessorKey: 'code',
1116
+ header: 'Code',
1117
+ // Render differently for parent vs child rows
1118
+ renderForParent: (row) => (
1119
+ <div className="flex items-center gap-2">
1120
+ <strong>{row.code}</strong>
1121
+ </div>
1122
+ ),
1123
+ renderForChild: () => '', // Blank for child rows
1124
+ hideForChild: true, // Hide this column for child rows
1125
+ },
1126
+ {
1127
+ accessorKey: 'name',
1128
+ header: 'Name',
1129
+ renderForParent: (row) => <strong>{row.name}</strong>,
1130
+ renderForChild: () => '', // Blank for child rows
1131
+ hideForChild: true,
1132
+ },
1133
+ {
1134
+ accessorKey: 'ingredient',
1135
+ header: 'Ingredient',
1136
+ renderForParent: () => '', // Blank for parent rows
1137
+ renderForChild: (row) => <span className="ml-4">{row.ingredient}</span>,
1138
+ hideForParent: true, // Hide this column for parent rows
1139
+ },
1140
+ ];
1141
+ ```
1142
+
1143
+ #### Column Properties
1144
+
1145
+ - `renderForParent?: (row: TData) => React.ReactNode` - Custom renderer for parent rows
1146
+ - `renderForChild?: (row: TData) => React.ReactNode` - Custom renderer for child rows
1147
+ - `hideForParent?: boolean` - Hide this column for parent rows
1148
+ - `hideForChild?: boolean` - Hide this column for child rows
1149
+
1150
+ #### Expand/Collapse All Controls
1151
+
1152
+ The DataTable automatically adds an expand/collapse all button in the header when hierarchical mode is enabled:
1153
+
1154
+ **Features:**
1155
+ - **Expand All Button (▶️)**: Expands all parent rows to show their children
1156
+ - **Collapse All Button (🔽)**: Collapses all parent rows to hide their children
1157
+ - **Smart State Detection**: Button automatically updates based on current expansion state
1158
+ - **Accessibility**: Proper ARIA labels and keyboard navigation support
1159
+
1160
+ **Usage:**
1161
+ ```tsx
1162
+ <DataTable
1163
+ data={hierarchicalData}
1164
+ columns={columns}
1165
+ features={{ hierarchical: true }}
1166
+ hierarchical={{
1167
+ enabled: true,
1168
+ defaultExpanded: false, // Start with all collapsed
1169
+ onExpandedChange: (expandedIds) => {
1170
+ console.log('Expanded rows:', expandedIds);
1171
+ },
1172
+ }}
1173
+ />
1174
+ ```
1175
+
1176
+ **Button Behavior:**
1177
+ - Shows ▶️ when some or all parent rows are collapsed
1178
+ - Shows 🔽 when all parent rows are expanded
1179
+ - Only appears when there are parent rows with children
1180
+ - Positioned in the first column of the table header
1181
+
1182
+ #### Hierarchical Sorting
1183
+
1184
+ When hierarchical mode is enabled, sorting behavior is optimized to preserve the parent-child relationship structure:
1185
+
1186
+ **Parent Row Sorting:**
1187
+ - Parent rows maintain their original order and are not affected by sorting
1188
+ - Only child rows within each parent group are sorted
1189
+ - This prevents parent rows from being moved to unexpected positions
1190
+
1191
+ **Child Row Sorting:**
1192
+ - Child rows are sorted within their parent group only
1193
+ - Sorting by a child-specific column (e.g., "Diet", "Ingredient") will sort children within each parent
1194
+ - The parent row remains at the top of its group
1195
+
1196
+ **Example:**
1197
+ ```tsx
1198
+ // When sorting by "Diet" column:
1199
+ // ✅ Correct behavior:
1200
+ // Parent: Caesar Salad
1201
+ // ├─ Child: Dairy Free (Sour cream)
1202
+ // ├─ Child: Egg Free (Mayonnaise)
1203
+ // └─ Child: GF & Vegan (Lettuce)
1204
+ // Parent: Beef Stir Fry
1205
+ // ├─ Child: GF & Vegan (Vegetables)
1206
+ // └─ Child: Halal (Beef)
1207
+
1208
+ // ❌ Incorrect behavior (what we prevent):
1209
+ // Child: Dairy Free (Sour cream)
1210
+ // Child: Egg Free (Mayonnaise)
1211
+ // Child: GF & Vegan (Lettuce)
1212
+ // Child: GF & Vegan (Vegetables)
1213
+ // Child: Halal (Beef)
1214
+ // Parent: Caesar Salad (moved to end)
1215
+ // Parent: Beef Stir Fry (moved to end)
1216
+ ```
1217
+
1218
+ **Sorting Configuration:**
1219
+ - All existing sorting features work with hierarchical data
1220
+ - Multi-column sorting is supported
1221
+ - Server-side sorting is compatible
1222
+ - Column-specific sorting behavior is preserved
1223
+
1224
+ #### Example Use Case
1225
+
1226
+ ```tsx
1227
+ // Dishes and ingredients example
1228
+ const dishData = [
1229
+ // Parent rows (dishes)
1230
+ { id: 'dish-1', isParent: true, code: 'D001', name: 'Caesar Salad', type: 'Salad' },
1231
+ { id: 'dish-2', isParent: true, code: 'D002', name: 'Beef Stir Fry', type: 'Main Course' },
1232
+
1233
+ // Child rows (ingredients) for Caesar Salad
1234
+ { id: 'ing-1-1', isParent: false, parentId: 'dish-1', ingredient: 'Lettuce', quantity: '200g' },
1235
+ { id: 'ing-1-2', isParent: false, parentId: 'dish-1', ingredient: 'Chicken', quantity: '150g' },
1236
+
1237
+ // Child rows (ingredients) for Beef Stir Fry
1238
+ { id: 'ing-2-1', isParent: false, parentId: 'dish-2', ingredient: 'Beef Strips', quantity: '250g' },
1239
+ { id: 'ing-2-2', isParent: false, parentId: 'dish-2', ingredient: 'Mixed Vegetables', quantity: '200g' },
1240
+ ];
1241
+ ```
1242
+
1243
+ ### Row Selection and Bulk Operations
1244
+
1245
+ ```tsx
1246
+ function SelectableUserTable() {
1247
+ const [selectedRows, setSelectedRows] = useState<Record<string, boolean>>({});
1248
+ const [data, setData] = useState<User[]>(initialData);
1249
+
1250
+ const handleBulkDelete = (selectedRows: Record<string, boolean>) => {
1251
+ // Get the selected row IDs
1252
+ const selectedRowIds = Object.keys(selectedRows).filter(id => selectedRows[id]);
1253
+
1254
+ // Get the actual data for selected rows
1255
+ const selectedData = data.filter(row => {
1256
+ const rowId = getRowId ? getRowId(row, data.indexOf(row)) : row.id;
1257
+ return selectedRowIds.includes(rowId);
1258
+ });
1259
+
1260
+ // Perform your deletion logic
1261
+ console.log('Deleting selected rows:', selectedData);
1262
+
1263
+ // Update your data state
1264
+ setData(prevData =>
1265
+ prevData.filter(row => {
1266
+ const rowId = getRowId ? getRowId(row, prevData.indexOf(row)) : row.id;
1267
+ return !selectedRowIds.includes(rowId);
1268
+ })
1269
+ );
1270
+
1271
+ // Clear selection after deletion
1272
+ setSelectedRows({});
1273
+ };
1274
+
1275
+ return (
1276
+ <DataTable
1277
+ data={data}
1278
+ columns={columns}
1279
+ features={{
1280
+ selection: true,
1281
+ deletion: true, // Required for delete functionality
1282
+ deleteSelected: true, // Enables the delete selected button
1283
+ bulkOperations: true,
1284
+ }}
1285
+ onRowSelectionChange={setSelectedRows}
1286
+ onDeleteSelected={handleBulkDelete}
1287
+ getRowId={(row) => row.id} // Important: provide getRowId for proper row identification
1288
+ />
1289
+ );
1290
+ }
1291
+ ```
1292
+
1293
+ #### Alternative: Using Individual onDeleteRow (Fallback)
1294
+
1295
+ If you don't provide `onDeleteSelected`, the DataTable will automatically fall back to calling `onDeleteRow` for each selected row:
1296
+
1297
+ ```tsx
1298
+ function SelectableUserTable() {
1299
+ const [data, setData] = useState<User[]>(initialData);
1300
+
1301
+ const handleDeleteRow = (row: User) => {
1302
+ console.log('Deleting row:', row);
1303
+
1304
+ // Update your data state
1305
+ setData(prevData => prevData.filter(item => item.id !== row.id));
1306
+ };
1307
+
1308
+ return (
1309
+ <DataTable
1310
+ data={data}
1311
+ columns={columns}
1312
+ features={{
1313
+ selection: true,
1314
+ deletion: true,
1315
+ deleteSelected: true,
1316
+ }}
1317
+ onDeleteRow={handleDeleteRow} // This will be called for each selected row
1318
+ getRowId={(row) => row.id}
1319
+ />
1320
+ );
1321
+ }
1322
+ ```
1323
+
1324
+ ### Column Visibility
1325
+
1326
+ ```tsx
1327
+ <DataTable
1328
+ data={data}
1329
+ columns={columns}
1330
+ features={{ columnVisibility: true }}
1331
+ defaultColumnVisibility={{
1332
+ id: false,
1333
+ createdAt: false,
1334
+ }}
1335
+ />
1336
+ ```
1337
+
1338
+ ### Data Grouping
1339
+
1340
+ ```tsx
1341
+ <DataTable
1342
+ data={data}
1343
+ columns={columns}
1344
+ features={{ grouping: true }}
1345
+ grouping={['role', 'status']}
1346
+ />
1347
+ ```
1348
+
1349
+ ## Performance Optimization
1350
+
1351
+ ### Virtual Scrolling
1352
+
1353
+ ```tsx
1354
+ <DataTable
1355
+ data={largeDataset}
1356
+ columns={columns}
1357
+ features={{ virtualization: true }}
1358
+ virtualHeight={600} // Height of the virtual scrolling container
1359
+ performance={{
1360
+ virtualScrolling: true,
1361
+ memoryOptimization: true,
1362
+ }}
1363
+ />
1364
+ ```
1365
+
1366
+ ### Lazy Loading
1367
+
1368
+ ```tsx
1369
+ function LazyLoadingTable() {
1370
+ const [data, setData] = useState<User[]>([]);
1371
+ const [loading, setLoading] = useState(false);
1372
+ const [hasMore, setHasMore] = useState(true);
1373
+
1374
+ const loadMoreData = async () => {
1375
+ setLoading(true);
1376
+ const newData = await fetchUsers(data.length, 50);
1377
+ setData(prev => [...prev, ...newData]);
1378
+ setHasMore(newData.length === 50);
1379
+ setLoading(false);
1380
+ };
1381
+
1382
+ return (
1383
+ <DataTable
1384
+ data={data}
1385
+ columns={columns}
1386
+ loading={loading}
1387
+ onLoadMore={hasMore ? loadMoreData : undefined}
1388
+ hasMore={hasMore}
1389
+ />
1390
+ );
1391
+ }
1392
+ ```
1393
+
1394
+ ### Optimized Rendering
1395
+
1396
+ ```tsx
1397
+ <DataTable
1398
+ data={data}
1399
+ columns={columns}
1400
+ features={{
1401
+ virtualization: true,
1402
+ performanceMetrics: true,
1403
+ }}
1404
+ performance={{
1405
+ virtualScrolling: true,
1406
+ memoryOptimization: true,
1407
+ renderOptimization: true,
1408
+ }}
1409
+ showPerformanceMetrics={true}
1410
+ virtualHeight={600}
1411
+ />
1412
+ ```
1413
+
1414
+ ## Integration with RBAC
1415
+
1416
+ ### Permission-Based Actions
1417
+
1418
+ ```tsx
1419
+ function SecureUserTable() {
1420
+ const { checkPermission } = usePermissionCache();
1421
+
1422
+ const [permissions, setPermissions] = useState({
1423
+ canCreate: false,
1424
+ canUpdate: false,
1425
+ canDelete: false,
1426
+ });
1427
+
1428
+ useEffect(() => {
1429
+ const loadPermissions = async () => {
1430
+ const results = await Promise.all([
1431
+ checkPermission('create', 'user-management'),
1432
+ checkPermission('update', 'user-management'),
1433
+ checkPermission('delete', 'user-management'),
1434
+ ]);
1435
+
1436
+ setPermissions({
1437
+ canCreate: results[0],
1438
+ canUpdate: results[1],
1439
+ canDelete: results[2],
1440
+ });
1441
+ };
1442
+
1443
+ loadPermissions();
1444
+ }, [checkPermission]);
1445
+
1446
+ return (
1447
+ <DataTable
1448
+ data={users}
1449
+ columns={columns}
1450
+ features={{
1451
+ search: true,
1452
+ pagination: true,
1453
+ creation: permissions.canCreate,
1454
+ editing: permissions.canUpdate,
1455
+ deletion: permissions.canDelete,
1456
+ rowActions: permissions.canUpdate || permissions.canDelete,
1457
+ }}
1458
+ onEditRow={permissions.canUpdate ? (row) => navigate(`/users/${row.original.id}/edit`) : undefined}
1459
+ onDeleteRow={permissions.canDelete ? (row) => handleDelete(row.original.id) : undefined}
1460
+ // Custom actions using deprecated actions prop (still supported)
1461
+ actions={
1462
+ permissions.canUpdate || permissions.canDelete ? [
1463
+ {
1464
+ label: 'View Details',
1465
+ onClick: (row) => navigate(`/users/${row.original.id}`),
1466
+ }
1467
+ ] : []
1468
+ }
1469
+ />
1470
+ );
1471
+ }
1472
+ ```
1473
+
1474
+ ## Practical Examples
1475
+
1476
+ ### Custom Page Size Configuration
1477
+
1478
+ Here's a complete example showing how to configure a DataTable with custom initial page size:
1479
+
1480
+ ```tsx
1481
+ import { DataTable, type DataTableColumn } from '@jmruthers/pace-core';
1482
+
1483
+ interface User {
1484
+ id: string;
1485
+ name: string;
1486
+ email: string;
1487
+ role: string;
1488
+ status: 'active' | 'inactive';
1489
+ }
1490
+
1491
+ const columns: DataTableColumn<User>[] = [
1492
+ {
1493
+ accessorKey: 'name',
1494
+ header: 'Name',
1495
+ sortable: true,
1496
+ searchable: true,
1497
+ },
1498
+ {
1499
+ accessorKey: 'email',
1500
+ header: 'Email',
1501
+ sortable: true,
1502
+ searchable: true,
1503
+ },
1504
+ {
1505
+ accessorKey: 'role',
1506
+ header: 'Role',
1507
+ sortable: true,
1508
+ enableGrouping: true,
1509
+ },
1510
+ {
1511
+ accessorKey: 'status',
1512
+ header: 'Status',
1513
+ sortable: true,
1514
+ cell: ({ row }) => (
1515
+ <span className={`px-2 py-1 rounded text-xs ${
1516
+ row.original.status === 'active'
1517
+ ? 'bg-main-100 text-main-800'
1518
+ : 'bg-acc-100 text-acc-800'
1519
+ }`}>
1520
+ {row.original.status}
1521
+ </span>
1522
+ ),
1523
+ },
1524
+ ];
1525
+
1526
+ function UserManagementTable() {
1527
+ const [users, setUsers] = useState<User[]>([]);
1528
+ const [loading, setLoading] = useState(true);
1529
+
1530
+ useEffect(() => {
1531
+ // Load users data
1532
+ loadUsers().then(setUsers).finally(() => setLoading(false));
1533
+ }, []);
1534
+
1535
+ return (
1536
+ <DataTable
1537
+ data={users}
1538
+ columns={columns}
1539
+ title="User Management"
1540
+ description="Manage system users with custom page size"
1541
+ features={{
1542
+ search: true,
1543
+ pagination: true,
1544
+ sorting: true,
1545
+ filtering: true,
1546
+ selection: true,
1547
+ creation: true,
1548
+ editing: true,
1549
+ deletion: true,
1550
+ deleteSelected: true,
1551
+ export: true,
1552
+ import: true,
1553
+ grouping: true,
1554
+ columnVisibility: true,
1555
+ columnReordering: true,
1556
+ autoColumnSizing: true,
1557
+ }}
1558
+ initialPageSize={25} // Start with 25 users per page
1559
+ isLoading={loading}
1560
+ onEditRow={(row, data) => {
1561
+ console.log('Editing user:', row.id, data);
1562
+ // Handle user edit
1563
+ }}
1564
+ onDeleteRow={(row) => {
1565
+ console.log('Deleting user:', row.id);
1566
+ // Handle user deletion
1567
+ }}
1568
+ onCreateRow={(data) => {
1569
+ console.log('Creating user:', data);
1570
+ // Handle user creation
1571
+ }}
1572
+ onImport={(data) => {
1573
+ console.log('Importing users:', data);
1574
+ // Handle user import
1575
+ }}
1576
+ onRowSelectionChange={(selection) => {
1577
+ console.log('Selection changed:', selection);
1578
+ // Handle selection changes
1579
+ }}
1580
+ onDeleteSelected={(selectedRows) => {
1581
+ console.log('Bulk deleting users:', selectedRows);
1582
+ // Handle bulk deletion
1583
+ }}
1584
+ />
1585
+ );
1586
+ }
1587
+ ```
1588
+
1589
+ ### Page Size Validation Example
1590
+
1591
+ ```tsx
1592
+ // This will show a console warning and use the closest valid option
1593
+ <DataTable
1594
+ data={largeDataset}
1595
+ columns={columns}
1596
+ features={{ pagination: true }}
1597
+ initialPageSize={15} // Invalid - will fallback to 10 with warning
1598
+ paginationMode="client" // Uses [10, 25, 50] options
1599
+ />
1600
+
1601
+ // This will work correctly
1602
+ <DataTable
1603
+ data={largeDataset}
1604
+ columns={columns}
1605
+ features={{ pagination: true }}
1606
+ initialPageSize={25} // Valid option
1607
+ paginationMode="client"
1608
+ />
1609
+ ```
1610
+
1611
+ ## Best Practices
1612
+
1613
+ ### Data Processing Best Practices
1614
+ - **Stable Data References**: Ensure your data processing doesn't create new object references on every render
1615
+ - **Memoization**: Use `useMemo` with proper dependency arrays to prevent unnecessary re-computations
1616
+ - **Avoid Complex Transformations in useMemo**: Move complex data transformations to the backend or data fetching layer when possible
1617
+ - **Data Comparison**: Use shallow comparison to detect actual data changes before updating state
1618
+
1619
+ #### ✅ Good Data Processing Patterns
1620
+ ```tsx
1621
+ // Simple, stable data processing
1622
+ const processedData = useMemo(() => {
1623
+ if (!data || data.length === 0) return [];
1624
+ return data; // Direct usage, no transformations
1625
+ }, [data]);
1626
+
1627
+ // Complex processing with stable references
1628
+ const processedData = useMemo(() => {
1629
+ if (!data || data.length === 0) return [];
1630
+
1631
+ // Use stable references and avoid creating new objects unnecessarily
1632
+ return data.map(item => ({
1633
+ ...item,
1634
+ // Simple transformations only
1635
+ displayName: item.firstName + ' ' + item.lastName,
1636
+ }));
1637
+ }, [data]); // Single dependency
1638
+ ```
1639
+
1640
+ #### ❌ Avoid These Patterns
1641
+ ```tsx
1642
+ // This can cause infinite loops
1643
+ const processedData = useMemo(() => {
1644
+ return data.map(item => ({
1645
+ ...item,
1646
+ // Complex transformations that create new objects
1647
+ computed_field: relatedData?.find(rel => rel.id === item.relation_id)?.name || 'Unknown',
1648
+ formatted_date: item.date ? format(new Date(item.date), 'MMM dd, yyyy') : 'No date',
1649
+ }));
1650
+ }, [data, relatedData]); // Multiple dependencies with complex processing
1651
+ ```
1652
+
1653
+ #### 🔧 Recommended Solutions for Complex Data
1654
+ 1. **Backend Processing**: Move complex transformations to your API layer
1655
+ 2. **Supabase Relations**: Use database relations instead of client-side lookups
1656
+ 3. **Separate Hooks**: Create dedicated hooks for data processing
1657
+ 4. **Stable References**: Use `useCallback` and `useMemo` with proper dependencies
1658
+
1659
+ ### 1. Use the Features Configuration Properly
1660
+
1661
+ ```tsx
1662
+ // ✅ Good - Clear feature configuration
1663
+ <DataTable
1664
+ data={data}
1665
+ columns={columns}
1666
+ features={{
1667
+ search: true,
1668
+ pagination: true,
1669
+ editing: userCanEdit,
1670
+ deletion: userCanDelete,
1671
+ }}
1672
+ onEditRow={handleEdit}
1673
+ onDeleteRow={handleDelete}
1674
+ />
1675
+
1676
+ // ❌ Avoid - Don't enable features without handlers
1677
+ <DataTable
1678
+ data={data}
1679
+ columns={columns}
1680
+ features={{
1681
+ editing: true, // But no onEditRow handler
1682
+ deletion: true, // But no onDeleteRow handler
1683
+ }}
1684
+ />
1685
+
1686
+ // ❌ Avoid - Don't use deprecated individual props
1687
+ <DataTable
1688
+ data={data}
1689
+ columns={columns}
1690
+ // These props are deprecated and should not be used
1691
+ // Use the features prop instead
1692
+ />
1693
+ ```
1694
+
1695
+ ### 2. Use Proper TypeScript Types
1696
+
1697
+ ```tsx
1698
+ // ✅ Good - Strong typing
1699
+ interface User {
1700
+ id: string;
1701
+ name: string;
1702
+ email: string;
1703
+ role: UserRole;
1704
+ status: UserStatus;
1705
+ createdAt: Date;
1706
+ }
1707
+
1708
+ const columns: DataTableColumn<User>[] = [
1709
+ {
1710
+ accessorKey: 'name',
1711
+ header: 'Name',
1712
+ sortable: true,
1713
+ },
1714
+ ];
1715
+
1716
+ // ❌ Avoid - Weak typing
1717
+ const columns = [
1718
+ {
1719
+ accessorKey: 'name',
1720
+ header: 'Name',
1721
+ },
1722
+ ];
1723
+ ```
1724
+
1725
+ ### 2. Optimize for Performance
1726
+
1727
+ ```tsx
1728
+ // ✅ Good - Memoized components with performance optimization
1729
+ const UserTable = React.memo(() => {
1730
+ const [data, setData] = useState<User[]>([]);
1731
+
1732
+ return (
1733
+ <DataTable
1734
+ data={data}
1735
+ columns={columns}
1736
+ features={{ virtualization: true }}
1737
+ performance={{
1738
+ memoryOptimization: true,
1739
+ renderOptimization: true,
1740
+ }}
1741
+ />
1742
+ );
1743
+ });
1744
+
1745
+ // ❌ Avoid - Unnecessary re-renders
1746
+ function UserTable() {
1747
+ return (
1748
+ <DataTable
1749
+ data={data}
1750
+ columns={columns}
1751
+ />
1752
+ );
1753
+ }
1754
+ ```
1755
+
1756
+ ### 3. Handle Loading States
1757
+
1758
+ ```tsx
1759
+ // ✅ Good - Proper loading states
1760
+ function UserTable() {
1761
+ const [loading, setLoading] = useState(true);
1762
+ const [data, setData] = useState<User[]>([]);
1763
+
1764
+ useEffect(() => {
1765
+ loadUsers().then(setData).finally(() => setLoading(false));
1766
+ }, []);
1767
+
1768
+ return (
1769
+ <DataTable
1770
+ data={data}
1771
+ columns={columns}
1772
+ isLoading={loading}
1773
+ // loadingText is not directly supported - use custom loadingComponent if needed
1774
+ />
1775
+ );
1776
+ }
1777
+ ```
1778
+
1779
+ ### 4. Implement Error Handling
1780
+
1781
+ ```tsx
1782
+ // ✅ Good - Error handling
1783
+ function UserTable() {
1784
+ const [error, setError] = useState<string | null>(null);
1785
+
1786
+ const handleDelete = async (userId: string) => {
1787
+ try {
1788
+ await deleteUser(userId);
1789
+ // Refresh data
1790
+ } catch (err) {
1791
+ setError('Failed to delete user');
1792
+ }
1793
+ };
1794
+
1795
+ return (
1796
+ <div>
1797
+ {error && (
1798
+ <Alert variant="destructive">
1799
+ <AlertDescription>{error}</AlertDescription>
1800
+ </Alert>
1801
+ )}
1802
+ <DataTable
1803
+ data={data}
1804
+ columns={columns}
1805
+ features={{
1806
+ search: true,
1807
+ pagination: true,
1808
+ deletion: true,
1809
+ rowActions: true,
1810
+ }}
1811
+ onDeleteRow={(row) => handleDelete(row.id)}
1812
+ />
1813
+ </div>
1814
+ );
1815
+ }
1816
+ ```
1817
+
1818
+ ### 5. Use Consistent Styling
1819
+
1820
+ ```tsx
1821
+ // ✅ Good - Consistent styling
1822
+ const columns: DataTableColumn<User>[] = [
1823
+ {
1824
+ accessorKey: 'status',
1825
+ header: 'Status',
1826
+ cell: ({ row }) => (
1827
+ <Badge
1828
+ variant={row.original.status === 'active' ? 'default' : 'secondary'}
1829
+ className="capitalize"
1830
+ >
1831
+ {row.original.status}
1832
+ </Badge>
1833
+ ),
1834
+ },
1835
+ ];
1836
+ ```
1837
+
1838
+ ## Troubleshooting
1839
+
1840
+ ### Common Issues
1841
+
1842
+ #### 1. Performance issues with large datasets
1843
+ - Enable virtualization: `features={{ virtualization: true }}`
1844
+ - Use performance optimization: `performance={{ memoryOptimization: true }}`
1845
+ - Set appropriate virtual height: `virtualHeight={600}`
1846
+ - Consider server-side sorting/filtering with `serverSide` prop
1847
+
1848
+ #### 2. TypeScript errors
1849
+ - Ensure proper column typing: `DataTableColumn<YourType>[]`
1850
+ - Use proper accessor keys that match your data structure
1851
+ - Check that custom cell components return valid JSX
1852
+
1853
+ #### 3. Sorting not working
1854
+ - Enable sorting: `features={{ sorting: true }}`
1855
+ - Set `sortable: true` on columns
1856
+ - Ensure data types are consistent for sorting
1857
+
1858
+ #### 4. Search not working
1859
+ - Enable search: `features={{ search: true }}`
1860
+ - Set `searchable: true` on columns
1861
+ - Check `searchKey` matches your data structure
1862
+
1863
+ #### 5. Actions not appearing
1864
+ - Enable row actions: `features={{ rowActions: true }}`
1865
+ - Check permissions if using RBAC
1866
+ - Ensure action arrays are properly structured
1867
+ - Verify onClick handlers are defined
1868
+
1869
+ #### 6. Features not working
1870
+ - Ensure features are enabled in the `features` prop
1871
+ - Check that required event handlers are provided (e.g., `onEditRow` for editing)
1872
+ - Verify that the feature configuration matches your use case
1873
+
1874
+ #### 7. Delete selected rows not working
1875
+ - **Check feature configuration**: Ensure `features={{ selection: true, deletion: true, deleteSelected: true }}`
1876
+ - **Provide onDeleteSelected callback**: Implement the callback to handle bulk deletion
1877
+ - **Verify getRowId function**: Ensure you provide a `getRowId` function that returns unique IDs
1878
+ - **Check button visibility**: The delete button only appears when all three features are enabled and rows are selected
1879
+ - **Debug selection state**: Add console logs to verify `onRowSelectionChange` is being called with correct data
1880
+ - **Fallback option**: If you don't provide `onDeleteSelected`, the table will fall back to calling `onDeleteRow` for each selected row
1881
+
1882
+ ### Debug Mode
1883
+
1884
+ Enable debug logging for DataTable issues:
1885
+
1886
+ ```tsx
1887
+ <DataTable
1888
+ data={data}
1889
+ columns={columns}
1890
+ features={{ performanceMetrics: true }}
1891
+ showPerformanceMetrics={true}
1892
+ onPerformanceMetrics={(metrics) => {
1893
+ console.log('Performance metrics:', metrics);
1894
+ }}
1895
+ />
1896
+ ```
1897
+
1898
+ This comprehensive DataTable guide provides everything you need to build powerful, performant data interfaces with PACE Core.