@jmruthers/pace-core 0.5.121 → 0.5.123

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 (254) hide show
  1. package/dist/{AuthService-D4646R4b.d.ts → AuthService-DYuQPJj6.d.ts} +0 -9
  2. package/dist/{DataTable-DGZDJUYM.js → DataTable-WTS4IRF2.js} +7 -8
  3. package/dist/{PublicLoadingSpinner-DgDWTFqn.d.ts → PublicLoadingSpinner-CaoRbHvJ.d.ts} +30 -4
  4. package/dist/{UnifiedAuthProvider-UACKFATV.js → UnifiedAuthProvider-6C47WIML.js} +3 -4
  5. package/dist/{chunk-D6BOFXYR.js → chunk-35ZDPMBM.js} +3 -3
  6. package/dist/{chunk-CGURJ27Z.js → chunk-4MXVZVNS.js} +2 -2
  7. package/dist/{chunk-ZYJ6O5CA.js → chunk-C43QIDN3.js} +2 -2
  8. package/dist/{chunk-VKOCWWVY.js → chunk-CX5M4ZAG.js} +1 -6
  9. package/dist/{chunk-VKOCWWVY.js 3.map → chunk-CX5M4ZAG.js.map} +1 -1
  10. package/dist/{chunk-HFBOFZ3Z.js → chunk-DHMFMXFV.js} +258 -243
  11. package/dist/chunk-DHMFMXFV.js.map +1 -0
  12. package/dist/{chunk-RIEJGKD3.js → chunk-ESJTIADP.js} +15 -6
  13. package/dist/{chunk-RIEJGKD3.js.map → chunk-ESJTIADP.js.map} +1 -1
  14. package/dist/{chunk-SMJZMKYN.js → chunk-GEVIB2UB.js} +43 -10
  15. package/dist/chunk-GEVIB2UB.js.map +1 -0
  16. package/dist/{chunk-TDNI6ZWL.js → chunk-IJOZZOGT.js} +7 -7
  17. package/dist/chunk-IJOZZOGT.js.map +1 -0
  18. package/dist/{chunk-GZRXOUBE.js → chunk-M6DDYFUD.js} +2 -2
  19. package/dist/chunk-M6DDYFUD.js.map +1 -0
  20. package/dist/{chunk-B4GZ2BXO.js → chunk-NZGLXZGP.js} +3 -3
  21. package/dist/{chunk-NZ32EONV.js → chunk-QWNJCQXZ.js} +2 -2
  22. package/dist/{chunk-FKFHZUGF.js → chunk-XN6GWKMV.js} +43 -56
  23. package/dist/chunk-XN6GWKMV.js.map +1 -0
  24. package/dist/{chunk-BHWIUEYH.js → chunk-ZBLK676C.js} +1 -61
  25. package/dist/chunk-ZBLK676C.js.map +1 -0
  26. package/dist/{chunk-QPI2CCBA.js → chunk-ZPJMYGEP.js} +149 -96
  27. package/dist/chunk-ZPJMYGEP.js.map +1 -0
  28. package/dist/components.d.ts +1 -1
  29. package/dist/components.js +11 -11
  30. package/dist/{formatting-B1jSqgl-.d.ts → formatting-DFcCxUEk.d.ts} +1 -1
  31. package/dist/hooks.d.ts +1 -1
  32. package/dist/hooks.js +9 -8
  33. package/dist/hooks.js.map +1 -1
  34. package/dist/index.d.ts +6 -6
  35. package/dist/index.js +19 -17
  36. package/dist/index.js.map +1 -1
  37. package/dist/providers.d.ts +2 -2
  38. package/dist/providers.js +2 -3
  39. package/dist/rbac/index.js +7 -8
  40. package/dist/styles/index.d.ts +1 -1
  41. package/dist/styles/index.js +5 -3
  42. package/dist/theming/runtime.d.ts +73 -1
  43. package/dist/theming/runtime.js +5 -5
  44. package/dist/{usePublicRouteParams-BdF8bZgs.d.ts → usePublicRouteParams-Dyt1tzI9.d.ts} +60 -8
  45. package/dist/utils.d.ts +1 -1
  46. package/dist/utils.js +5 -5
  47. package/docs/api/classes/ColumnFactory.md +1 -1
  48. package/docs/api/classes/ErrorBoundary.md +1 -1
  49. package/docs/api/classes/InvalidScopeError.md +1 -1
  50. package/docs/api/classes/MissingUserContextError.md +1 -1
  51. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  52. package/docs/api/classes/PermissionDeniedError.md +1 -1
  53. package/docs/api/classes/PublicErrorBoundary.md +6 -6
  54. package/docs/api/classes/RBACAuditManager.md +1 -1
  55. package/docs/api/classes/RBACCache.md +1 -1
  56. package/docs/api/classes/RBACEngine.md +1 -1
  57. package/docs/api/classes/RBACError.md +1 -1
  58. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  59. package/docs/api/classes/SecureSupabaseClient.md +6 -6
  60. package/docs/api/classes/StorageUtils.md +1 -1
  61. package/docs/api/enums/FileCategory.md +1 -1
  62. package/docs/api/interfaces/AggregateConfig.md +1 -1
  63. package/docs/api/interfaces/ButtonProps.md +1 -1
  64. package/docs/api/interfaces/CardProps.md +1 -1
  65. package/docs/api/interfaces/ColorPalette.md +1 -1
  66. package/docs/api/interfaces/ColorShade.md +1 -1
  67. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  68. package/docs/api/interfaces/DataRecord.md +1 -1
  69. package/docs/api/interfaces/DataTableAction.md +1 -1
  70. package/docs/api/interfaces/DataTableColumn.md +1 -1
  71. package/docs/api/interfaces/DataTableProps.md +1 -1
  72. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  73. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  74. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  75. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  76. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  77. package/docs/api/interfaces/FileMetadata.md +1 -1
  78. package/docs/api/interfaces/FileReference.md +1 -1
  79. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  80. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  81. package/docs/api/interfaces/FileUploadProps.md +1 -1
  82. package/docs/api/interfaces/FooterProps.md +1 -1
  83. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  84. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  85. package/docs/api/interfaces/InputProps.md +1 -1
  86. package/docs/api/interfaces/LabelProps.md +1 -1
  87. package/docs/api/interfaces/LoginFormProps.md +1 -1
  88. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  89. package/docs/api/interfaces/NavigationContextType.md +1 -1
  90. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  91. package/docs/api/interfaces/NavigationItem.md +1 -1
  92. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  93. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  94. package/docs/api/interfaces/Organisation.md +1 -1
  95. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  96. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  97. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  98. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  99. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  100. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  101. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  102. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  103. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  104. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  105. package/docs/api/interfaces/PaletteData.md +1 -1
  106. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  107. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  108. package/docs/api/interfaces/PublicErrorBoundaryProps.md +7 -7
  109. package/docs/api/interfaces/PublicErrorBoundaryState.md +5 -5
  110. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +7 -7
  111. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  112. package/docs/api/interfaces/PublicPageHeaderProps.md +51 -12
  113. package/docs/api/interfaces/PublicPageLayoutProps.md +72 -12
  114. package/docs/api/interfaces/RBACConfig.md +1 -1
  115. package/docs/api/interfaces/RBACLogger.md +1 -1
  116. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  117. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  118. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  119. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  120. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  121. package/docs/api/interfaces/RouteConfig.md +1 -1
  122. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  123. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  124. package/docs/api/interfaces/StorageConfig.md +1 -1
  125. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  126. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  127. package/docs/api/interfaces/StorageListOptions.md +1 -1
  128. package/docs/api/interfaces/StorageListResult.md +1 -1
  129. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  130. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  131. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  132. package/docs/api/interfaces/StyleImport.md +1 -1
  133. package/docs/api/interfaces/SwitchProps.md +1 -1
  134. package/docs/api/interfaces/ToastActionElement.md +1 -1
  135. package/docs/api/interfaces/ToastProps.md +1 -1
  136. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  137. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  138. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  139. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  140. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  141. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  142. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  143. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  144. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  145. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  146. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  147. package/docs/api/interfaces/UserEventAccess.md +1 -1
  148. package/docs/api/interfaces/UserMenuProps.md +1 -1
  149. package/docs/api/interfaces/UserProfile.md +1 -1
  150. package/docs/api/modules.md +140 -30
  151. package/docs/best-practices/README.md +1 -1
  152. package/docs/implementation-guides/datatable-filtering.md +313 -0
  153. package/docs/implementation-guides/datatable-rbac-usage.md +317 -0
  154. package/docs/implementation-guides/hierarchical-datatable.md +850 -0
  155. package/docs/implementation-guides/large-datasets.md +281 -0
  156. package/docs/implementation-guides/performance.md +403 -0
  157. package/docs/implementation-guides/public-pages.md +4 -4
  158. package/docs/migration/quick-migration-guide.md +320 -0
  159. package/docs/rbac/quick-start.md +16 -16
  160. package/docs/troubleshooting/README.md +4 -4
  161. package/docs/troubleshooting/cake-page-permission-guard-issue-summary.md +1 -1
  162. package/docs/troubleshooting/debugging.md +1117 -0
  163. package/docs/troubleshooting/migration.md +918 -0
  164. package/examples/public-pages/CorrectPublicPageImplementation.tsx +30 -30
  165. package/examples/public-pages/PublicEventPage.tsx +41 -41
  166. package/examples/public-pages/PublicPageApp.tsx +33 -33
  167. package/examples/public-pages/PublicPageUsageExample.tsx +30 -30
  168. package/package.json +4 -4
  169. package/src/__tests__/hooks/usePermissions.test.ts +265 -0
  170. package/src/components/DataTable/DataTable.test.tsx +9 -38
  171. package/src/components/DataTable/DataTable.tsx +0 -7
  172. package/src/components/DataTable/components/DataTableCore.tsx +66 -136
  173. package/src/components/DataTable/components/DataTableModals.tsx +25 -22
  174. package/src/components/DataTable/components/EditableRow.tsx +118 -42
  175. package/src/components/DataTable/components/UnifiedTableBody.tsx +129 -76
  176. package/src/components/DataTable/components/__tests__/DataTableModals.test.tsx +33 -14
  177. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +17 -5
  178. package/src/components/DataTable/utils/exportUtils.ts +3 -2
  179. package/src/components/Dialog/Dialog.tsx +1 -1
  180. package/src/components/Dialog/README.md +24 -24
  181. package/src/components/Dialog/examples/BasicHtmlTest.tsx +2 -2
  182. package/src/components/Dialog/examples/DebugHtmlExample.tsx +6 -6
  183. package/src/components/Dialog/examples/HtmlDialogExample.tsx +2 -2
  184. package/src/components/Dialog/examples/SimpleHtmlTest.tsx +3 -3
  185. package/src/components/Dialog/examples/__tests__/SimpleHtmlTest.test.tsx +4 -4
  186. package/src/components/PaceAppLayout/PaceAppLayout.tsx +12 -1
  187. package/src/components/PublicLayout/EventLogo.tsx +175 -0
  188. package/src/components/PublicLayout/PublicErrorBoundary.tsx +22 -18
  189. package/src/components/PublicLayout/PublicLoadingSpinner.tsx +22 -14
  190. package/src/components/PublicLayout/PublicPageHeader.tsx +133 -40
  191. package/src/components/PublicLayout/PublicPageLayout.tsx +75 -72
  192. package/src/components/PublicLayout/__tests__/PublicErrorBoundary.test.tsx +1 -1
  193. package/src/components/PublicLayout/__tests__/PublicLoadingSpinner.test.tsx +8 -8
  194. package/src/components/PublicLayout/__tests__/PublicPageHeader.test.tsx +23 -16
  195. package/src/components/PublicLayout/__tests__/PublicPageLayout.test.tsx +86 -14
  196. package/src/examples/CorrectPublicPageImplementation.tsx +30 -30
  197. package/src/examples/PublicEventPage.tsx +41 -41
  198. package/src/examples/PublicPageApp.tsx +33 -33
  199. package/src/examples/PublicPageUsageExample.tsx +30 -30
  200. package/src/hooks/__tests__/usePublicEvent.unit.test.ts +583 -0
  201. package/src/hooks/__tests__/usePublicRouteParams.unit.test.ts +10 -3
  202. package/src/hooks/index.ts +1 -1
  203. package/src/hooks/public/usePublicEventLogo.ts +285 -0
  204. package/src/hooks/public/usePublicRouteParams.ts +21 -4
  205. package/src/hooks/useEventTheme.test.ts +119 -43
  206. package/src/hooks/useEventTheme.ts +84 -55
  207. package/src/index.ts +3 -1
  208. package/src/rbac/components/__tests__/EnhancedNavigationMenu.test.tsx +630 -0
  209. package/src/rbac/components/__tests__/NavigationProvider.test.tsx +667 -0
  210. package/src/rbac/components/__tests__/PagePermissionProvider.test.tsx +647 -0
  211. package/src/rbac/components/__tests__/SecureDataProvider.fixed.test.tsx +496 -0
  212. package/src/rbac/components/__tests__/SecureDataProvider.test.tsx +496 -0
  213. package/src/rbac/secureClient.ts +4 -2
  214. package/src/services/EventService.ts +0 -66
  215. package/src/services/__tests__/EventService.eventColours.test.ts +44 -40
  216. package/src/styles/index.ts +1 -1
  217. package/src/theming/__tests__/parseEventColours.test.ts +209 -0
  218. package/src/theming/parseEventColours.ts +123 -0
  219. package/src/theming/runtime.ts +3 -0
  220. package/src/types/__tests__/file-reference.test.ts +447 -0
  221. package/src/utils/formatDate.test.ts +11 -11
  222. package/src/utils/formatting.ts +3 -2
  223. package/dist/chunk-BDZUMRBD.js 3.map +0 -1
  224. package/dist/chunk-BHWIUEYH.js.map +0 -1
  225. package/dist/chunk-CGURJ27Z.js.map +0 -1
  226. package/dist/chunk-FKFHZUGF.js.map +0 -1
  227. package/dist/chunk-GKHF54DI 2.js +0 -619
  228. package/dist/chunk-GKHF54DI.js 2.map +0 -1
  229. package/dist/chunk-GZRXOUBE.js.map +0 -1
  230. package/dist/chunk-HFBOFZ3Z.js.map +0 -1
  231. package/dist/chunk-NZ32EONV.js.map +0 -1
  232. package/dist/chunk-O3NWNXDY 2.js +0 -76
  233. package/dist/chunk-QPI2CCBA.js.map +0 -1
  234. package/dist/chunk-SMJZMKYN.js.map +0 -1
  235. package/dist/chunk-TDNI6ZWL.js 2.map +0 -1
  236. package/dist/chunk-TDNI6ZWL.js.map +0 -1
  237. package/dist/chunk-VKOCWWVY.js.map +0 -1
  238. package/dist/chunk-WP5I5GLN 2.js +0 -1564
  239. package/dist/index 3.js +0 -856
  240. package/dist/providers 3.js +0 -38
  241. package/dist/providers.js 3.map +0 -1
  242. package/dist/types 3.js +0 -128
  243. package/dist/types.js 3.map +0 -1
  244. package/dist/useInactivityTracker-MRUU55XI.js 3.map +0 -1
  245. package/dist/utils.js 3.map +0 -1
  246. package/dist/validation 3.js +0 -479
  247. package/src/styles/semantic.css +0 -24
  248. /package/dist/{DataTable-DGZDJUYM.js.map → DataTable-WTS4IRF2.js.map} +0 -0
  249. /package/dist/{UnifiedAuthProvider-UACKFATV.js.map → UnifiedAuthProvider-6C47WIML.js.map} +0 -0
  250. /package/dist/{chunk-D6BOFXYR.js.map → chunk-35ZDPMBM.js.map} +0 -0
  251. /package/dist/{chunk-CGURJ27Z.js 2.map → chunk-4MXVZVNS.js.map} +0 -0
  252. /package/dist/{chunk-ZYJ6O5CA.js.map → chunk-C43QIDN3.js.map} +0 -0
  253. /package/dist/{chunk-B4GZ2BXO.js.map → chunk-NZGLXZGP.js.map} +0 -0
  254. /package/dist/{chunk-NZ32EONV.js 2.map → chunk-QWNJCQXZ.js.map} +0 -0
@@ -1,6 +1,6 @@
1
- [@jmruthers/pace-core - v0.5.121](README.md) / Exports
1
+ [@jmruthers/pace-core - v0.5.123](README.md) / Exports
2
2
 
3
- # @jmruthers/pace-core - v0.5.121
3
+ # @jmruthers/pace-core - v0.5.123
4
4
 
5
5
  **`File`**
6
6
 
@@ -359,6 +359,7 @@ import { Dialog, NavigationMenu } from '@jmruthers/pace-core/components';
359
359
  - [fromSupabaseClient](modules.md#fromsupabaseclient)
360
360
  - [getStylePath](modules.md#getstylepath)
361
361
  - [getAllStylePaths](modules.md#getallstylepaths)
362
+ - [parseAndNormalizeEventColours](modules.md#parseandnormalizeeventcolours)
362
363
  - [applyPalette](modules.md#applypalette)
363
364
  - [clearPalette](modules.md#clearpalette)
364
365
  - [generateSSRThemeCSS](modules.md#generatessrthemecss)
@@ -2612,7 +2613,7 @@ Useful for components that need to know if they're inside an error boundary
2612
2613
 
2613
2614
  #### Defined in
2614
2615
 
2615
- [packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx:216](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx#L216)
2616
+ [packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx:220](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx#L220)
2616
2617
 
2617
2618
  ___
2618
2619
 
@@ -2634,7 +2635,7 @@ Default error fallback component
2634
2635
 
2635
2636
  #### Defined in
2636
2637
 
2637
- [packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx:238](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx#L238)
2638
+ [packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx:242](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicErrorBoundary.tsx#L242)
2638
2639
 
2639
2640
  ___
2640
2641
 
@@ -2661,7 +2662,7 @@ React element with loading spinner
2661
2662
 
2662
2663
  #### Defined in
2663
2664
 
2664
- [packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx:75](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx#L75)
2665
+ [packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx:76](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx#L76)
2665
2666
 
2666
2667
  ___
2667
2668
 
@@ -2683,7 +2684,7 @@ Full page loading spinner with event branding
2683
2684
 
2684
2685
  #### Defined in
2685
2686
 
2686
- [packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx:135](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx#L135)
2687
+ [packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx:139](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx#L139)
2687
2688
 
2688
2689
  ___
2689
2690
 
@@ -2707,7 +2708,7 @@ Skeleton loading component for content placeholders
2707
2708
 
2708
2709
  #### Defined in
2709
2710
 
2710
- [packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx:189](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx#L189)
2711
+ [packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx:196](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicLoadingSpinner.tsx#L196)
2711
2712
 
2712
2713
  ___
2713
2714
 
@@ -2822,6 +2823,15 @@ Header component for public pages with event-specific branding
2822
2823
  This component displays the app logo, event logo, and event information
2823
2824
  in a clean, accessible layout suitable for public pages.
2824
2825
 
2826
+ Logo handling follows a priority order:
2827
+ 1. customAppLogo prop (if provided) - highest priority
2828
+ 2. logoUrl prop (if provided) - direct URL override
2829
+ 3. Auto-generated path from appName via useAppConfig() - convention-based
2830
+ 4. Default SVG fallback - lowest priority
2831
+
2832
+ The logo can be made clickable by providing the logoHref prop, which will
2833
+ wrap the logo in a Link component for navigation.
2834
+
2825
2835
  #### Parameters
2826
2836
 
2827
2837
  | Name | Type | Description |
@@ -2836,7 +2846,7 @@ React element with public page header
2836
2846
 
2837
2847
  #### Defined in
2838
2848
 
2839
- [packages/core/src/components/PublicLayout/PublicPageHeader.tsx:86](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageHeader.tsx#L86)
2849
+ [packages/core/src/components/PublicLayout/PublicPageHeader.tsx:124](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageHeader.tsx#L124)
2840
2850
 
2841
2851
  ___
2842
2852
 
@@ -2849,6 +2859,9 @@ Layout component for public pages that don't require authentication
2849
2859
  This component provides a consistent structure for public event pages
2850
2860
  with event-specific branding, error handling, and loading states.
2851
2861
 
2862
+ Automatically applies event colors from the event's event_colours field
2863
+ when an event is provided, ensuring consistent theming across public pages.
2864
+
2852
2865
  #### Parameters
2853
2866
 
2854
2867
  | Name | Type | Description |
@@ -2863,7 +2876,7 @@ React element with complete public page layout
2863
2876
 
2864
2877
  #### Defined in
2865
2878
 
2866
- [packages/core/src/components/PublicLayout/PublicPageLayout.tsx:101](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageLayout.tsx#L101)
2879
+ [packages/core/src/components/PublicLayout/PublicPageLayout.tsx:119](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageLayout.tsx#L119)
2867
2880
 
2868
2881
  ___
2869
2882
 
@@ -2894,7 +2907,7 @@ directly in your components instead.
2894
2907
 
2895
2908
  #### Defined in
2896
2909
 
2897
- [packages/core/src/components/PublicLayout/PublicPageLayout.tsx:221](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageLayout.tsx#L221)
2910
+ [packages/core/src/components/PublicLayout/PublicPageLayout.tsx:224](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/components/PublicLayout/PublicPageLayout.tsx#L224)
2898
2911
 
2899
2912
  ___
2900
2913
 
@@ -3894,7 +3907,7 @@ Object containing route parameters, event data, loading state, error, and refetc
3894
3907
 
3895
3908
  #### Defined in
3896
3909
 
3897
- [packages/core/src/hooks/public/usePublicRouteParams.ts:121](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L121)
3910
+ [packages/core/src/hooks/public/usePublicRouteParams.ts:129](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L129)
3898
3911
 
3899
3912
  ___
3900
3913
 
@@ -3922,7 +3935,7 @@ Useful when you only need the event code and will fetch data separately
3922
3935
 
3923
3936
  #### Defined in
3924
3937
 
3925
- [packages/core/src/hooks/public/usePublicRouteParams.ts:216](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L216)
3938
+ [packages/core/src/hooks/public/usePublicRouteParams.ts:224](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L224)
3926
3939
 
3927
3940
  ___
3928
3941
 
@@ -3945,7 +3958,7 @@ Utility function to generate public route paths
3945
3958
 
3946
3959
  #### Defined in
3947
3960
 
3948
- [packages/core/src/hooks/public/usePublicRouteParams.ts:252](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L252)
3961
+ [packages/core/src/hooks/public/usePublicRouteParams.ts:260](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L260)
3949
3962
 
3950
3963
  ___
3951
3964
 
@@ -3954,6 +3967,7 @@ ___
3954
3967
  ▸ **extractEventCodeFromPath**(`path`): `string` \| ``null``
3955
3968
 
3956
3969
  Utility function to extract event code from a public route path
3970
+ Supports 2-50 character event codes
3957
3971
 
3958
3972
  #### Parameters
3959
3973
 
@@ -3967,7 +3981,7 @@ Utility function to extract event code from a public route path
3967
3981
 
3968
3982
  #### Defined in
3969
3983
 
3970
- [packages/core/src/hooks/public/usePublicRouteParams.ts:266](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L266)
3984
+ [packages/core/src/hooks/public/usePublicRouteParams.ts:275](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/public/usePublicRouteParams.ts#L275)
3971
3985
 
3972
3986
  ___
3973
3987
 
@@ -4048,16 +4062,33 @@ ___
4048
4062
 
4049
4063
  ### useEventTheme
4050
4064
 
4051
- ▸ **useEventTheme**(): `void`
4065
+ ▸ **useEventTheme**(`event?`): `void`
4052
4066
 
4053
4067
  Hook that automatically applies event-specific theming
4054
4068
 
4055
- This hook watches the selected event and applies its colors using the theming system.
4056
- It will:
4057
- - Apply event colors when an event with `event_colours` is selected
4058
- - Clear theming when no event is selected
4059
- - Skip theme application when on the login route to prevent login screen styling
4060
- - Handle cleanup when the component unmounts
4069
+ This hook applies event colors using the theming system. It works in two modes:
4070
+
4071
+ **Authenticated Mode (default):**
4072
+ - Uses EventProvider context via useEvents() hook
4073
+ - Automatically watches selectedEvent changes
4074
+ - Used in authenticated pages with EventProvider
4075
+
4076
+ **Public Page Mode:**
4077
+ - Accepts event prop directly
4078
+ - No EventProvider required
4079
+ - Used in public pages without authentication context
4080
+
4081
+ Behavior:
4082
+ - Applies event colors when an event with `event_colours` is provided
4083
+ - Clears theming when no event is provided
4084
+ - Skips theme application when on the login route to prevent login screen styling
4085
+ - Handles cleanup and error cases gracefully
4086
+
4087
+ #### Parameters
4088
+
4089
+ | Name | Type | Description |
4090
+ | :------ | :------ | :------ |
4091
+ | `event?` | ``null`` \| `Event` | Optional event object. If provided, uses this event directly (public page mode). If not provided, uses EventProvider context via useEvents() (authenticated mode). |
4061
4092
 
4062
4093
  #### Returns
4063
4094
 
@@ -4065,9 +4096,29 @@ It will:
4065
4096
 
4066
4097
  void - This is an effect hook with no return value
4067
4098
 
4099
+ **`Example`**
4100
+
4101
+ ```tsx
4102
+ // Authenticated mode - uses EventProvider
4103
+ function MyApp() {
4104
+ useEventTheme(); // Watches selectedEvent from EventProvider
4105
+ return <div>App content</div>;
4106
+ }
4107
+ ```
4108
+
4109
+ **`Example`**
4110
+
4111
+ ```tsx
4112
+ // Public page mode - uses event prop
4113
+ function PublicPageLayout({ event }) {
4114
+ useEventTheme(event); // Uses event prop directly
4115
+ return <div>Public content</div>;
4116
+ }
4117
+ ```
4118
+
4068
4119
  #### Defined in
4069
4120
 
4070
- [packages/core/src/hooks/useEventTheme.ts:85](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventTheme.ts#L85)
4121
+ [packages/core/src/hooks/useEventTheme.ts:92](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/hooks/useEventTheme.ts#L92)
4071
4122
 
4072
4123
  ___
4073
4124
 
@@ -6297,7 +6348,7 @@ const client = createSecureClient(
6297
6348
 
6298
6349
  #### Defined in
6299
6350
 
6300
- [packages/core/src/rbac/secureClient.ts:216](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/secureClient.ts#L216)
6351
+ [packages/core/src/rbac/secureClient.ts:218](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/secureClient.ts#L218)
6301
6352
 
6302
6353
  ___
6303
6354
 
@@ -6324,7 +6375,7 @@ SecureSupabaseClient instance
6324
6375
 
6325
6376
  #### Defined in
6326
6377
 
6327
- [packages/core/src/rbac/secureClient.ts:235](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/secureClient.ts#L235)
6378
+ [packages/core/src/rbac/secureClient.ts:237](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/rbac/secureClient.ts#L237)
6328
6379
 
6329
6380
  ___
6330
6381
 
@@ -6362,6 +6413,65 @@ ___
6362
6413
 
6363
6414
  ___
6364
6415
 
6416
+ ### parseAndNormalizeEventColours
6417
+
6418
+ ▸ **parseAndNormalizeEventColours**(`input`): \{ `main`: `any` ; `sec`: `any` ; `acc`: `any` } \| ``null``
6419
+
6420
+ Parse and normalize event_colours to PaletteData
6421
+
6422
+ Supports multiple input formats:
6423
+ - Object with 'main', 'sec', 'acc' keys
6424
+ - Object with 'ev-main', 'ev-sec', 'ev-acc' keys (legacy)
6425
+ - JSON string that will be parsed
6426
+
6427
+ Only includes explicitly defined color values. Does not fill
6428
+ missing shades - only shades that are present in the input will
6429
+ be included in the output.
6430
+
6431
+ #### Parameters
6432
+
6433
+ | Name | Type | Description |
6434
+ | :------ | :------ | :------ |
6435
+ | `input` | `unknown` | Event colours from database (JSONB field) |
6436
+
6437
+ #### Returns
6438
+
6439
+ \{ `main`: `any` ; `sec`: `any` ; `acc`: `any` } \| ``null``
6440
+
6441
+ Normalized palette data with main, sec, acc palettes, or null if invalid
6442
+
6443
+ **`Example`**
6444
+
6445
+ ```ts
6446
+ // Standard format
6447
+ const colours = {
6448
+ main: { 500: { L: 0.5, C: 0.2, H: 0 }, raw: { L: 0.5, C: 0.2, H: 0 } },
6449
+ sec: { 500: { L: 0.5, C: 0.2, H: 120 } },
6450
+ acc: { 500: { L: 0.5, C: 0.2, H: 240 } }
6451
+ };
6452
+ const palette = parseAndNormalizeEventColours(colours);
6453
+ // Returns: { main: { 500: {...}, raw: {...} }, sec: { 500: {...} }, acc: { 500: {...} } }
6454
+ ```
6455
+
6456
+ **`Example`**
6457
+
6458
+ ```ts
6459
+ // Legacy format with ev-* keys
6460
+ const colours = {
6461
+ "ev-main": { 500: { L: 0.5, C: 0.2, H: 0 } },
6462
+ "ev-sec": { 500: { L: 0.5, C: 0.2, H: 120 } },
6463
+ "ev-acc": { 500: { L: 0.5, C: 0.2, H: 240 } }
6464
+ };
6465
+ const palette = parseAndNormalizeEventColours(colours);
6466
+ // Returns normalized palette with only defined shades included
6467
+ ```
6468
+
6469
+ #### Defined in
6470
+
6471
+ [packages/core/src/theming/parseEventColours.ts:68](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/theming/parseEventColours.ts#L68)
6472
+
6473
+ ___
6474
+
6365
6475
  ### applyPalette
6366
6476
 
6367
6477
  ▸ **applyPalette**(`palette`): `void`
@@ -6552,7 +6662,7 @@ ___
6552
6662
 
6553
6663
  ▸ **formatDate**(`date`): `string`
6554
6664
 
6555
- Format a date as a readable string
6665
+ Format a date as a readable string in "dd mmm yyyy" format (e.g., "15 Jun 2024")
6556
6666
 
6557
6667
  #### Parameters
6558
6668
 
@@ -6590,7 +6700,7 @@ Format a number as a currency
6590
6700
 
6591
6701
  #### Defined in
6592
6702
 
6593
- [packages/core/src/utils/formatting.ts:23](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L23)
6703
+ [packages/core/src/utils/formatting.ts:24](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L24)
6594
6704
 
6595
6705
  ___
6596
6706
 
@@ -6614,7 +6724,7 @@ Format a number with custom options
6614
6724
 
6615
6725
  #### Defined in
6616
6726
 
6617
- [packages/core/src/utils/formatting.ts:33](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L33)
6727
+ [packages/core/src/utils/formatting.ts:34](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L34)
6618
6728
 
6619
6729
  ___
6620
6730
 
@@ -6659,7 +6769,7 @@ formatPercent(0.8123, 'en-US', { preserveDecimals: true, maxDecimals: 2 }) // '0
6659
6769
 
6660
6770
  #### Defined in
6661
6771
 
6662
- [packages/core/src/utils/formatting.ts:70](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L70)
6772
+ [packages/core/src/utils/formatting.ts:71](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L71)
6663
6773
 
6664
6774
  ___
6665
6775
 
@@ -6682,7 +6792,7 @@ Format a large number with abbreviations (K, M, B)
6682
6792
 
6683
6793
  #### Defined in
6684
6794
 
6685
- [packages/core/src/utils/formatting.ts:114](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L114)
6795
+ [packages/core/src/utils/formatting.ts:115](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L115)
6686
6796
 
6687
6797
  ___
6688
6798
 
@@ -6704,7 +6814,7 @@ Format a file size in bytes to a human-readable string
6704
6814
 
6705
6815
  #### Defined in
6706
6816
 
6707
- [packages/core/src/utils/formatting.ts:124](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L124)
6817
+ [packages/core/src/utils/formatting.ts:125](https://github.com/jmruthers/pace-core/blob/main/packages/core/src/utils/formatting.ts#L125)
6708
6818
 
6709
6819
  ___
6710
6820
 
@@ -344,7 +344,7 @@ import { z } from 'zod';
344
344
  <button
345
345
  aria-label="Close dialog"
346
346
  onClick={onClose}
347
- className="p-2 rounded-md hover:bg-gray-100"
347
+ className="p-2 rounded-md hover:bg-sec-100"
348
348
  >
349
349
  <XIcon className="h-4 w-4" />
350
350
  </button>
@@ -0,0 +1,313 @@
1
+ # DataTable Filtering Guide
2
+
3
+ ## Overview
4
+
5
+ The DataTable component supports multiple types of column filtering, including text, select dropdowns, number, and date filters. This guide explains how to configure each filter type and provides examples for common use cases.
6
+
7
+ ## Filter Types
8
+
9
+ ### 1. Text Filters (Default)
10
+ Text filters allow users to type and search for values in a column.
11
+
12
+ ```typescript
13
+ const columns = [
14
+ {
15
+ id: 'name',
16
+ accessorKey: 'name',
17
+ header: 'Name',
18
+ enableColumnFilter: true,
19
+ // No filterType specified - defaults to 'text'
20
+ }
21
+ ];
22
+ ```
23
+
24
+ ### 2. Select Filters
25
+ Select filters provide dropdown menus with predefined options, perfect for categorical data.
26
+
27
+ #### Method 1: Using `filterSelectOptions` (Recommended)
28
+ ```typescript
29
+ const columns = [
30
+ {
31
+ id: 'meal_type',
32
+ accessorFn: (row) => row.mealtype?.mealtype_name || 'N/A',
33
+ header: 'Type',
34
+ enableColumnFilter: true,
35
+ filterType: 'select',
36
+ filterSelectOptions: [
37
+ { value: 'breakfast', label: 'Breakfast' },
38
+ { value: 'lunch', label: 'Lunch' },
39
+ { value: 'dinner', label: 'Dinner' },
40
+ { value: 'morning_tea', label: 'Morning Tea' },
41
+ { value: 'afternoon_tea', label: 'Afternoon Tea' },
42
+ { value: 'pantry', label: 'Pantry' }
43
+ ],
44
+ filterFn: (row, id, value) => {
45
+ return value.includes(row.original.mealtype?.mealtype_id);
46
+ }
47
+ }
48
+ ];
49
+ ```
50
+
51
+ #### Method 2: Using `fieldOptions`
52
+ ```typescript
53
+ const columns = [
54
+ {
55
+ id: 'status',
56
+ accessorKey: 'status',
57
+ header: 'Status',
58
+ enableColumnFilter: true,
59
+ filterType: 'select',
60
+ fieldOptions: [
61
+ { value: 'active', label: 'Active' },
62
+ { value: 'inactive', label: 'Inactive' },
63
+ { value: 'pending', label: 'Pending' }
64
+ ]
65
+ }
66
+ ];
67
+ ```
68
+
69
+ #### Method 3: Auto-detection
70
+ The DataTable automatically detects select filters when a column has limited unique values (≤10):
71
+
72
+ ```typescript
73
+ const columns = [
74
+ {
75
+ id: 'priority',
76
+ accessorKey: 'priority',
77
+ header: 'Priority',
78
+ enableColumnFilter: true,
79
+ // No filterType specified - will auto-detect as 'select' if ≤10 unique values
80
+ }
81
+ ];
82
+ ```
83
+
84
+ ### 3. Number Filters
85
+ Number filters provide numeric input with comparison operators.
86
+
87
+ ```typescript
88
+ const columns = [
89
+ {
90
+ id: 'price',
91
+ accessorKey: 'price',
92
+ header: 'Price',
93
+ enableColumnFilter: true,
94
+ filterType: 'number'
95
+ }
96
+ ];
97
+ ```
98
+
99
+ ### 4. Date Filters
100
+ Date filters provide date picker inputs.
101
+
102
+ ```typescript
103
+ const columns = [
104
+ {
105
+ id: 'created_date',
106
+ accessorKey: 'created_date',
107
+ header: 'Created Date',
108
+ enableColumnFilter: true,
109
+ filterType: 'date'
110
+ }
111
+ ];
112
+ ```
113
+
114
+ ## Complete Example
115
+
116
+ Here's a complete example showing different filter types:
117
+
118
+ ```typescript
119
+ import { DataTable } from '@jmruthers/pace-core';
120
+
121
+ function MealsTable() {
122
+ const meals = [
123
+ {
124
+ id: '1',
125
+ meal_code: '28py',
126
+ mealtype: { mealtype_id: 'breakfast', mealtype_name: 'Breakfast' },
127
+ meal_date: '2024-12-28',
128
+ price: 15.50
129
+ },
130
+ // ... more data
131
+ ];
132
+
133
+ const mealTypes = [
134
+ { mealtype_id: 'breakfast', mealtype_name: 'Breakfast' },
135
+ { mealtype_id: 'lunch', mealtype_name: 'Lunch' },
136
+ { mealtype_id: 'dinner', mealtype_name: 'Dinner' },
137
+ { mealtype_id: 'morning_tea', mealtype_name: 'Morning Tea' },
138
+ { mealtype_id: 'afternoon_tea', mealtype_name: 'Afternoon Tea' },
139
+ { mealtype_id: 'pantry', mealtype_name: 'Pantry' }
140
+ ];
141
+
142
+ const columns = [
143
+ {
144
+ id: 'meal_code',
145
+ accessorKey: 'meal_code',
146
+ header: 'Meal Code',
147
+ enableColumnFilter: true,
148
+ // Text filter (default)
149
+ },
150
+ {
151
+ id: 'meal_type',
152
+ accessorFn: (row) => row.mealtype?.mealtype_name || 'N/A',
153
+ header: 'Type',
154
+ enableColumnFilter: true,
155
+ filterType: 'select',
156
+ filterSelectOptions: mealTypes.map(mt => ({
157
+ value: mt.mealtype_id,
158
+ label: mt.mealtype_name
159
+ })),
160
+ filterFn: (row, id, value) => {
161
+ return value.includes(row.original.mealtype?.mealtype_id);
162
+ }
163
+ },
164
+ {
165
+ id: 'meal_date',
166
+ accessorKey: 'meal_date',
167
+ header: 'Date',
168
+ enableColumnFilter: true,
169
+ filterType: 'date'
170
+ },
171
+ {
172
+ id: 'price',
173
+ accessorKey: 'price',
174
+ header: 'Price',
175
+ enableColumnFilter: true,
176
+ filterType: 'number'
177
+ }
178
+ ];
179
+
180
+ return (
181
+ <DataTable
182
+ data={meals}
183
+ columns={columns}
184
+ features={{
185
+ filtering: true, // Enable filtering
186
+ search: true,
187
+ pagination: true,
188
+ sorting: true
189
+ }}
190
+ rbac={{
191
+ pageName: 'meals'
192
+ }}
193
+ />
194
+ );
195
+ }
196
+ ```
197
+
198
+ ## Filter Configuration Options
199
+
200
+ ### Column Properties
201
+
202
+ | Property | Type | Description |
203
+ |----------|------|-------------|
204
+ | `enableColumnFilter` | `boolean` | Enable filtering for this column |
205
+ | `filterType` | `'text' \| 'select' \| 'number' \| 'date'` | Type of filter to render |
206
+ | `filterSelectOptions` | `Array<{value: string\|number, label: string}>` | Options for select filters |
207
+ | `fieldOptions` | `Array<{value: string\|number, label: string}>` | Alternative options for select filters |
208
+ | `filterFn` | `(row, id, value) => boolean` | Custom filter function |
209
+
210
+ ### DataTable Features
211
+
212
+ ```typescript
213
+ features={{
214
+ filtering: true, // Enable column filtering
215
+ search: true, // Enable global search
216
+ showFilterRow: true, // Show filter row by default
217
+ }}
218
+ ```
219
+
220
+ ## Advanced Filtering
221
+
222
+ ### Custom Filter Functions
223
+
224
+ For complex filtering logic, you can provide a custom `filterFn`:
225
+
226
+ ```typescript
227
+ {
228
+ id: 'meal_type',
229
+ accessorFn: (row) => row.mealtype?.mealtype_name || 'N/A',
230
+ header: 'Type',
231
+ enableColumnFilter: true,
232
+ filterType: 'select',
233
+ filterSelectOptions: mealTypes.map(mt => ({
234
+ value: mt.mealtype_id,
235
+ label: mt.mealtype_name
236
+ })),
237
+ filterFn: (row, id, value) => {
238
+ // Custom logic: filter by mealtype_id but display mealtype_name
239
+ const mealtypeId = row.original.mealtype?.mealtype_id;
240
+ return value.includes(mealtypeId);
241
+ }
242
+ }
243
+ ```
244
+
245
+ ### Multiple Value Selection
246
+
247
+ Select filters support multiple value selection by default:
248
+
249
+ ```typescript
250
+ // Users can select multiple meal types
251
+ filterSelectOptions: [
252
+ { value: 'breakfast', label: 'Breakfast' },
253
+ { value: 'lunch', label: 'Lunch' },
254
+ { value: 'dinner', label: 'Dinner' }
255
+ ]
256
+ // When user selects "Breakfast" and "Lunch",
257
+ // filterFn receives: ['breakfast', 'lunch']
258
+ ```
259
+
260
+ ## Troubleshooting
261
+
262
+ ### Common Issues
263
+
264
+ 1. **Select filter not showing dropdown:**
265
+ - Ensure `filterType: 'select'` is set
266
+ - Verify `filterSelectOptions` or `fieldOptions` is provided
267
+ - Check that `enableColumnFilter: true` is set
268
+
269
+ 2. **Filter not working with foreign key data:**
270
+ - Use `accessorFn` to extract the display value
271
+ - Provide custom `filterFn` to match against the actual ID
272
+ - Ensure `filterSelectOptions` uses the ID values
273
+
274
+ 3. **Auto-detection not working:**
275
+ - Ensure column has ≤10 unique values
276
+ - Check that values are not null/undefined
277
+ - Verify `enableColumnFilter: true` is set
278
+
279
+ ### Debug Tips
280
+
281
+ Enable debug logging to see filter behavior:
282
+
283
+ ```typescript
284
+ // In your app setup
285
+ <UnifiedAuthProvider
286
+ supabaseClient={supabase}
287
+ appName="your-app"
288
+ enableRBAC={true}
289
+ debug={true} // Enable debug logging
290
+ >
291
+ <YourApp />
292
+ </UnifiedAuthProvider>
293
+ ```
294
+
295
+ ## Best Practices
296
+
297
+ 1. **Use `filterSelectOptions` for predefined options** - More explicit and clear
298
+ 2. **Provide meaningful labels** - Use human-readable labels, not IDs
299
+ 3. **Use custom `filterFn` for foreign keys** - Match against IDs, display names
300
+ 4. **Limit select options** - Keep dropdowns manageable (≤20 options)
301
+ 5. **Test with real data** - Ensure filters work with actual data values
302
+ 6. **Consider performance** - Large datasets may need server-side filtering
303
+
304
+ ## Migration from Old Filtering
305
+
306
+ If you're upgrading from an older version:
307
+
308
+ 1. **Replace `meta.filterOptions`** with `filterSelectOptions`
309
+ 2. **Add `filterType: 'select'`** for explicit select filters
310
+ 3. **Update `filterFn`** to work with new filter value format
311
+ 4. **Test all filter combinations** to ensure they work correctly
312
+
313
+ This comprehensive filtering system provides a great user experience for data exploration and analysis.