@jmruthers/pace-core 0.6.6 → 0.6.7

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 (246) hide show
  1. package/{scripts/audit/audit-dependencies.cjs → audit-tool/00-dependencies.cjs} +12 -13
  2. package/audit-tool/audits/01-pace-core-compliance.cjs +556 -0
  3. package/audit-tool/audits/02-project-structure.cjs +255 -0
  4. package/audit-tool/audits/03-architecture.cjs +196 -0
  5. package/audit-tool/audits/04-code-quality.cjs +149 -0
  6. package/audit-tool/audits/05-styling.cjs +224 -0
  7. package/audit-tool/audits/06-security-rbac.cjs +544 -0
  8. package/audit-tool/audits/07-api-tech-stack.cjs +301 -0
  9. package/audit-tool/audits/08-testing-documentation.cjs +202 -0
  10. package/audit-tool/audits/09-operations.cjs +208 -0
  11. package/audit-tool/index.cjs +291 -0
  12. package/audit-tool/utils/code-utils.cjs +218 -0
  13. package/audit-tool/utils/file-utils.cjs +230 -0
  14. package/audit-tool/utils/report-utils.cjs +241 -0
  15. package/cursor-rules/00-standards-overview.mdc +156 -0
  16. package/cursor-rules/{00-pace-core-compliance.mdc → 01-pace-core-compliance.mdc} +187 -34
  17. package/cursor-rules/02-project-structure.mdc +37 -5
  18. package/cursor-rules/{03-solid-principles.mdc → 03-architecture.mdc} +125 -11
  19. package/cursor-rules/04-code-quality.mdc +419 -0
  20. package/cursor-rules/{08-markup-quality.mdc → 05-styling.mdc} +55 -10
  21. package/cursor-rules/{09-rbac-compliance.mdc → 06-security-rbac.mdc} +62 -6
  22. package/cursor-rules/07-api-tech-stack.mdc +377 -0
  23. package/cursor-rules/08-testing-documentation.mdc +324 -0
  24. package/cursor-rules/09-operations.mdc +365 -0
  25. package/dist/DataTable-7PMH7XN7.js +15 -0
  26. package/dist/{DataTable-2N_tqbfq.d.ts → DataTable-DRUIgtUH.d.ts} +1 -1
  27. package/dist/{PublicPageProvider-BBH6Vqg7.d.ts → PublicPageProvider-DlsCaR5v.d.ts} +26 -16
  28. package/dist/{chunk-FENMYN2U.js → chunk-5X4QLXRG.js} +1 -3
  29. package/dist/{chunk-4T7OBVTU.js → chunk-6F3IILHI.js} +1 -1
  30. package/dist/{chunk-SD6WQY43.js → chunk-7ILTDCL2.js} +9 -1
  31. package/dist/{chunk-3QC3KRHK.js → chunk-A3W6LW53.js} +16 -1
  32. package/dist/{chunk-7TYHROIV.js → chunk-BM4CQ5P3.js} +50 -8
  33. package/dist/{chunk-2HGJFNAH.js → chunk-FEJLJNWA.js} +1 -15
  34. package/dist/{chunk-OHIK3MIO.js → chunk-GHYHJTYV.js} +2 -2
  35. package/dist/{chunk-UIYSCEV7.js → chunk-IUBRCBSY.js} +1 -1
  36. package/dist/{chunk-LAZMKTTF.js → chunk-JGWDVX64.js} +281 -347
  37. package/dist/{chunk-MAGBIDNS.js → chunk-L4XMVJKY.js} +2 -2
  38. package/dist/{chunk-A55DK444.js → chunk-OJ4SKRSV.js} +1 -7
  39. package/dist/{chunk-ZS5VO5JB.js → chunk-Q7Q7V5NV.js} +406 -451
  40. package/dist/{chunk-3O3WHILE.js → chunk-VBCS3DUA.js} +236 -60
  41. package/dist/{chunk-BVP2BCJF.js → chunk-ZKAWKYT4.js} +8 -8
  42. package/dist/components.d.ts +5 -4
  43. package/dist/components.js +27 -32
  44. package/dist/eslint-rules/index.cjs +22 -9
  45. package/{src/eslint-rules/rules/compliance.cjs → dist/eslint-rules/rules/01-pace-core-compliance.cjs} +184 -23
  46. package/dist/eslint-rules/rules/04-code-quality.cjs +290 -0
  47. package/dist/eslint-rules/rules/05-styling.cjs +61 -0
  48. package/dist/eslint-rules/rules/{rbac.cjs → 06-security-rbac.cjs} +26 -10
  49. package/dist/eslint-rules/rules/07-api-tech-stack.cjs +263 -0
  50. package/dist/eslint-rules/rules/08-testing.cjs +94 -0
  51. package/dist/hooks.d.ts +5 -5
  52. package/dist/hooks.js +6 -6
  53. package/dist/index.d.ts +6 -6
  54. package/dist/index.js +18 -17
  55. package/dist/rbac/index.js +6 -6
  56. package/dist/theming/runtime.d.ts +14 -1
  57. package/dist/theming/runtime.js +1 -1
  58. package/dist/{types-B-K_5VnO.d.ts → types-DXstZpNI.d.ts} +0 -17
  59. package/dist/{usePublicRouteParams-COZ28Mvq.d.ts → usePublicRouteParams-MamNgwqe.d.ts} +19 -19
  60. package/dist/utils.d.ts +2 -2
  61. package/dist/utils.js +8 -8
  62. package/docs/README.md +1 -1
  63. package/docs/api/modules.md +47 -31
  64. package/docs/api-reference/components.md +18 -20
  65. package/docs/api-reference/hooks.md +80 -80
  66. package/docs/api-reference/types.md +1 -1
  67. package/docs/api-reference/utilities.md +1 -1
  68. package/docs/architecture/README.md +1 -1
  69. package/docs/core-concepts/events.md +3 -3
  70. package/docs/core-concepts/organisations.md +6 -6
  71. package/docs/core-concepts/permissions.md +6 -6
  72. package/docs/documentation-index.md +12 -18
  73. package/docs/getting-started/documentation-index.md +1 -1
  74. package/docs/getting-started/examples/README.md +4 -4
  75. package/docs/getting-started/examples/full-featured-app.md +1 -1
  76. package/docs/getting-started/faq.md +2 -2
  77. package/docs/getting-started/quick-reference.md +4 -4
  78. package/docs/implementation-guides/authentication.md +15 -15
  79. package/docs/implementation-guides/component-styling.md +1 -1
  80. package/docs/implementation-guides/data-tables.md +126 -33
  81. package/docs/implementation-guides/datatable-rbac-usage.md +1 -1
  82. package/docs/implementation-guides/dynamic-colors.md +3 -3
  83. package/docs/implementation-guides/file-upload-storage.md +2 -2
  84. package/docs/implementation-guides/hierarchical-datatable.md +40 -60
  85. package/docs/implementation-guides/inactivity-tracking.md +3 -3
  86. package/docs/implementation-guides/large-datasets.md +3 -2
  87. package/docs/implementation-guides/organisation-security.md +2 -2
  88. package/docs/implementation-guides/performance.md +2 -2
  89. package/docs/implementation-guides/permission-enforcement.md +1 -1
  90. package/docs/migration/V0.3.44_organisation-context-timing-fix.md +1 -1
  91. package/docs/migration/V0.4.0_rbac-migration.md +6 -6
  92. package/docs/rbac/README.md +5 -5
  93. package/docs/rbac/advanced-patterns.md +6 -6
  94. package/docs/rbac/api-reference.md +20 -20
  95. package/docs/rbac/event-based-apps.md +3 -3
  96. package/docs/rbac/examples.md +41 -41
  97. package/docs/rbac/getting-started.md +37 -37
  98. package/docs/rbac/performance.md +1 -1
  99. package/docs/rbac/quick-start.md +52 -52
  100. package/docs/rbac/secure-client-protection.md +1 -1
  101. package/docs/rbac/troubleshooting.md +1 -1
  102. package/docs/security/README.md +5 -5
  103. package/docs/standards/0-standards-overview.md +220 -0
  104. package/docs/standards/{00-pace-core-compliance.md → 1-pace-core-compliance-standards.md} +204 -185
  105. package/docs/standards/{02-project-structure.md → 2-project-structure-standards.md} +11 -47
  106. package/docs/standards/3-architecture-standards.md +606 -0
  107. package/docs/standards/4-code-quality-standards.md +728 -0
  108. package/docs/standards/{08-markup-quality.md → 5-styling-standards.md} +12 -9
  109. package/docs/standards/{09-rbac-compliance.md → 6-security-rbac-standards.md} +126 -18
  110. package/docs/standards/7-api-tech-stack-standards.md +662 -0
  111. package/docs/standards/8-testing-documentation-standards.md +401 -0
  112. package/docs/standards/9-operations-standards.md +1102 -0
  113. package/docs/standards/README.md +203 -104
  114. package/docs/troubleshooting/README.md +4 -4
  115. package/docs/troubleshooting/common-issues.md +2 -2
  116. package/docs/troubleshooting/debugging.md +9 -9
  117. package/docs/troubleshooting/migration.md +4 -4
  118. package/eslint-config-pace-core.cjs +21 -10
  119. package/package.json +6 -5
  120. package/scripts/install-cursor-rules.cjs +11 -243
  121. package/scripts/install-eslint-config.cjs +284 -0
  122. package/src/__tests__/helpers/__tests__/component-test-utils.test.tsx +2 -2
  123. package/src/__tests__/helpers/__tests__/test-providers.test.tsx +2 -2
  124. package/src/__tests__/helpers/__tests__/test-utils.test.tsx +10 -10
  125. package/src/__tests__/integration/UserProfile.test.tsx +14 -14
  126. package/src/__tests__/rbac/PagePermissionGuard.test.tsx +6 -6
  127. package/src/__tests__/templates/accessibility.test.template.tsx +9 -9
  128. package/src/__tests__/templates/component.test.template.tsx +18 -15
  129. package/src/components/Calendar/Calendar.tsx +201 -47
  130. package/src/components/ContextSelector/ContextSelector.tsx +137 -153
  131. package/src/components/DataTable/AUDIT_REPORT.md +293 -0
  132. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +10 -2
  133. package/src/components/DataTable/__tests__/a11y.basic.test.tsx +10 -4
  134. package/src/components/DataTable/__tests__/test-utils/sharedTestUtils.tsx +9 -9
  135. package/src/components/DataTable/components/ColumnFilter.tsx +63 -74
  136. package/src/components/DataTable/components/ColumnVisibilityDropdown.tsx +43 -41
  137. package/src/components/DataTable/components/DataTableErrorBoundary.tsx +9 -11
  138. package/src/components/DataTable/components/DataTableLayout.tsx +5 -16
  139. package/src/components/DataTable/components/EditableRow.tsx +5 -7
  140. package/src/components/DataTable/components/EmptyState.tsx +10 -9
  141. package/src/components/DataTable/components/FilterRow.tsx +2 -4
  142. package/src/components/DataTable/components/ImportModal.tsx +124 -126
  143. package/src/components/DataTable/components/LoadingState.tsx +5 -6
  144. package/src/components/DataTable/components/SortIndicator.tsx +50 -0
  145. package/src/components/DataTable/components/__tests__/COVERAGE_NOTE.md +4 -4
  146. package/src/components/DataTable/components/__tests__/ColumnFilter.test.tsx +23 -82
  147. package/src/components/DataTable/components/__tests__/DataTableErrorBoundary.test.tsx +37 -9
  148. package/src/components/DataTable/components/__tests__/EmptyState.test.tsx +7 -4
  149. package/src/components/DataTable/components/__tests__/FilterRow.test.tsx +12 -4
  150. package/src/components/DataTable/components/__tests__/LoadingState.test.tsx +41 -27
  151. package/src/components/DataTable/components/index.ts +2 -1
  152. package/src/components/DataTable/types.ts +0 -18
  153. package/src/components/DataTable/utils/a11yUtils.ts +17 -0
  154. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.test.tsx +2 -1
  155. package/src/components/DatePickerWithTimezone/DatePickerWithTimezone.tsx +11 -15
  156. package/src/components/DateTimeField/DateTimeField.tsx +7 -8
  157. package/src/components/Dialog/Dialog.test.tsx +1 -0
  158. package/src/components/Dialog/Dialog.tsx +25 -8
  159. package/src/components/ErrorBoundary/ErrorBoundary.tsx +77 -79
  160. package/src/components/FileUpload/FileUpload.test.tsx +52 -14
  161. package/src/components/FileUpload/FileUpload.tsx +112 -130
  162. package/src/components/Progress/Progress.tsx +2 -4
  163. package/src/components/ProtectedRoute/ProtectedRoute.tsx +8 -8
  164. package/src/components/Select/Select.tsx +86 -77
  165. package/src/components/Select/types.ts +3 -0
  166. package/src/hooks/__tests__/ServiceHooks.test.tsx +16 -16
  167. package/src/hooks/__tests__/hooks.integration.test.tsx +49 -49
  168. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +97 -97
  169. package/src/hooks/public/usePublicEvent.ts +5 -5
  170. package/src/hooks/public/usePublicEventLogo.ts +5 -5
  171. package/src/hooks/public/usePublicFileDisplay.ts +2 -2
  172. package/src/hooks/public/usePublicRouteParams.ts +5 -5
  173. package/src/hooks/useAppConfig.ts +2 -2
  174. package/src/hooks/useEventTheme.test.ts +7 -7
  175. package/src/hooks/useEventTheme.ts +1 -4
  176. package/src/hooks/useFileDisplay.ts +2 -2
  177. package/src/providers/UnifiedAuthProvider.smoke.test.tsx +21 -21
  178. package/src/providers/__tests__/AuthProvider.test.tsx +21 -21
  179. package/src/providers/__tests__/EventProvider.test.tsx +61 -61
  180. package/src/providers/__tests__/InactivityProvider.test.tsx +56 -56
  181. package/src/providers/__tests__/OrganisationProvider.test.tsx +75 -75
  182. package/src/providers/__tests__/ProviderLifecycle.test.tsx +37 -37
  183. package/src/providers/__tests__/UnifiedAuthProvider.test.tsx +103 -103
  184. package/src/providers/services/__tests__/AuthServiceProvider.integration.test.tsx +7 -7
  185. package/src/providers/services/__tests__/UnifiedAuthProvider.integration.test.tsx +10 -10
  186. package/src/styles/core.css +7 -0
  187. package/src/theming/__tests__/parseEventColours.test.ts +9 -3
  188. package/src/theming/parseEventColours.ts +22 -10
  189. package/src/utils/__tests__/lazyLoad.unit.test.tsx +42 -39
  190. package/src/utils/storage/README.md +1 -1
  191. package/cursor-rules/01-standards-compliance.mdc +0 -285
  192. package/cursor-rules/04-testing-standards.mdc +0 -270
  193. package/cursor-rules/05-bug-reports-and-features.mdc +0 -248
  194. package/cursor-rules/06-code-quality.mdc +0 -311
  195. package/cursor-rules/07-tech-stack-compliance.mdc +0 -216
  196. package/cursor-rules/10-error-handling-patterns.mdc +0 -179
  197. package/cursor-rules/11-performance-optimization.mdc +0 -169
  198. package/cursor-rules/12-ci-cd-integration.mdc +0 -150
  199. package/dist/DataTable-LRJL4IRV.js +0 -15
  200. package/dist/eslint-rules/rules/compliance.cjs +0 -348
  201. package/dist/eslint-rules/rules/components.cjs +0 -113
  202. package/dist/eslint-rules/rules/imports.cjs +0 -102
  203. package/docs/best-practices/README.md +0 -472
  204. package/docs/best-practices/accessibility.md +0 -604
  205. package/docs/best-practices/common-patterns.md +0 -516
  206. package/docs/best-practices/deployment.md +0 -1103
  207. package/docs/best-practices/performance.md +0 -1328
  208. package/docs/best-practices/security.md +0 -940
  209. package/docs/best-practices/testing.md +0 -1034
  210. package/docs/rbac/compliance/compliance-guide.md +0 -544
  211. package/docs/standards/01-standards-compliance.md +0 -188
  212. package/docs/standards/03-solid-principles.md +0 -39
  213. package/docs/standards/04-testing-standards.md +0 -36
  214. package/docs/standards/05-bug-reports-and-features.md +0 -27
  215. package/docs/standards/06-code-quality.md +0 -34
  216. package/docs/standards/07-tech-stack-compliance.md +0 -30
  217. package/docs/standards/10-error-handling-patterns.md +0 -401
  218. package/docs/standards/11-performance-optimization.md +0 -348
  219. package/docs/standards/12-ci-cd-integration.md +0 -370
  220. package/docs/standards/ALIGNMENT_REVIEW_SUMMARY.md +0 -192
  221. package/scripts/audit/audit-compliance.cjs +0 -1295
  222. package/scripts/audit/audit-components.cjs +0 -260
  223. package/scripts/audit/audit-rbac.cjs +0 -954
  224. package/scripts/audit/audit-standards.cjs +0 -1268
  225. package/scripts/audit/index.cjs +0 -1927
  226. package/src/components/DataTable/components/DataTableBody.tsx +0 -478
  227. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -156
  228. package/src/components/DataTable/components/ExpandButton.tsx +0 -113
  229. package/src/components/DataTable/components/GroupHeader.tsx +0 -54
  230. package/src/components/DataTable/components/ViewRowModal.tsx +0 -68
  231. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -525
  232. package/src/components/DataTable/components/__tests__/ExpandButton.test.tsx +0 -462
  233. package/src/components/DataTable/components/__tests__/GroupHeader.test.tsx +0 -393
  234. package/src/components/DataTable/components/__tests__/ViewRowModal.test.tsx +0 -476
  235. package/src/components/DataTable/components/__tests__/VirtualizedDataTable.test.tsx +0 -128
  236. package/src/components/DataTable/core/DataTableContext.tsx +0 -216
  237. package/src/components/DataTable/core/__tests__/DataTableContext.test.tsx +0 -136
  238. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +0 -570
  239. package/src/components/DataTable/hooks/useColumnReordering.ts +0 -123
  240. package/src/components/DataTable/utils/debugTools.ts +0 -514
  241. package/src/eslint-rules/index.cjs +0 -22
  242. package/src/eslint-rules/rules/components.cjs +0 -113
  243. package/src/eslint-rules/rules/imports.cjs +0 -102
  244. package/src/eslint-rules/rules/rbac.cjs +0 -790
  245. package/src/eslint-rules/utils/helpers.cjs +0 -42
  246. package/src/eslint-rules/utils/manifest-loader.cjs +0 -75
@@ -1,216 +0,0 @@
1
- /**
2
- * @file DataTable Context
3
- * @package @jmruthers/pace-core
4
- * @module Components/DataTable/Architecture
5
- * @since 0.3.0
6
- */
7
-
8
- import React, { createContext, useContext, useMemo, useCallback, useRef, useEffect } from 'react';
9
- import { useReactTable, getCoreRowModel, getFilteredRowModel, getSortedRowModel, getPaginationRowModel } from '@tanstack/react-table';
10
- import { ChevronDown, ChevronUp, ChevronsUpDown, Filter, MoreHorizontal, Plus, Search, Settings, Trash2, Upload, Download, Eye, Edit, Copy } from 'lucide-react';
11
- import { Button } from '../../Button/Button';
12
- import { Input } from '../../Input/Input';
13
- import { Checkbox } from '../../Checkbox/Checkbox';
14
- // DropdownMenu components have been merged into Select components
15
- import { Dialog, DialogContent, DialogHeader, DialogTrigger } from '../../Dialog/Dialog';
16
- import type { DataTableContext as IDataTableContext, DataTableConfig, DataTableUtils } from './interfaces';
17
- import type { DataRecord, DataTableAction } from '../types';
18
- import type { ColumnDef } from '@tanstack/react-table';
19
- import { DataManager } from './DataManager';
20
- import { ColumnManagerImpl } from './ColumnManager';
21
- import { ActionManagerImpl } from './ActionManager';
22
- import { StateManagerImpl } from './StateManager';
23
- import { PluginRegistryImpl } from './PluginRegistry';
24
- import { LocalDataAdapter } from './LocalDataAdapter';
25
-
26
- // Create the context
27
- const DataTableContext = createContext<IDataTableContext<DataRecord> | null>(null);
28
-
29
- /**
30
- * Props for the DataTableProvider component.
31
- * @template TData - The type of data records in the table
32
- */
33
- export interface DataTableProviderProps<TData extends DataRecord> {
34
- children: React.ReactNode;
35
- config: DataTableConfig<TData>;
36
- data?: TData[];
37
- columns?: ColumnDef<TData>[];
38
- actions?: DataTableAction<TData>[];
39
- pageSize?: number;
40
- }
41
-
42
- export function DataTableProvider<TData extends DataRecord>({
43
- children,
44
- config,
45
- data = [],
46
- columns = [],
47
- actions = [],
48
- pageSize = 10,
49
- }: DataTableProviderProps<TData>) {
50
- // Create managers
51
- const adapter = useMemo(() => new LocalDataAdapter<TData>(data), [data]);
52
- const dataManager = useMemo(() => new DataManager<TData>(adapter), [adapter]);
53
- const columnManager = useMemo(() => new ColumnManagerImpl<TData>(columns), [columns]);
54
- const actionManager = useMemo(() => new ActionManagerImpl<TData>(actions), [actions]);
55
- const stateManager = useMemo(() => new StateManagerImpl<TData>({
56
- ui: {
57
- globalFilter: '',
58
- columnFilters: [],
59
- sorting: [],
60
- grouping: [],
61
- expanded: {},
62
- pagination: {
63
- pageIndex: 0,
64
- pageSize: pageSize,
65
- },
66
- rowSelection: {},
67
- editing: {
68
- rowId: null,
69
- data: {},
70
- isCreating: false,
71
- creationData: {},
72
- },
73
- modals: {
74
- import: false,
75
- export: false,
76
- view: false,
77
- viewData: null,
78
- },
79
- }
80
- }), [pageSize]);
81
- const pluginRegistry = useMemo(() => new PluginRegistryImpl<TData>(), []);
82
-
83
- // Create utilities
84
- const utils: DataTableUtils<TData> = useMemo(() => ({
85
- getRowId: (row: TData, index: number) => {
86
- const record = row as Record<string, unknown>;
87
- return (record.id ? String(record.id) : String(index));
88
- },
89
- formatValue: (value: unknown, column: ColumnDef<TData>) => String(value),
90
- validateData: (data: Partial<TData>) => null,
91
- debounce: <T extends (...args: unknown[]) => unknown>(func: T, delay: number) => {
92
- let timeoutId: NodeJS.Timeout;
93
- return ((...args: unknown[]) => {
94
- clearTimeout(timeoutId);
95
- timeoutId = setTimeout(() => func(...args), delay);
96
- }) as T;
97
- },
98
- }), []);
99
-
100
- // Create context value
101
- const contextValue: IDataTableContext<TData> = useMemo(() => ({
102
- dataManager,
103
- columnManager,
104
- actionManager,
105
- stateManager,
106
- pluginRegistry,
107
- adapter,
108
- observable: stateManager,
109
- config,
110
- utils,
111
- }), [dataManager, columnManager, actionManager, stateManager, pluginRegistry, adapter, config, utils]);
112
-
113
- // Initialize data
114
- useEffect(() => {
115
- // Update the adapter with new data
116
- adapter.setData(data);
117
-
118
- if (data.length > 0) {
119
- stateManager.updateData(data);
120
- } else {
121
- // Handle empty data case
122
- stateManager.updateData([]);
123
- }
124
- }, [data, dataManager, stateManager, adapter]);
125
-
126
- // Initialize columns
127
- useEffect(() => {
128
- if (columns.length > 0) {
129
- columnManager.setColumns(columns);
130
- stateManager.updateColumns(columns);
131
- }
132
- }, [columns, columnManager, stateManager]);
133
-
134
- // Initialize actions
135
- useEffect(() => {
136
- if (actions.length > 0) {
137
- actionManager.setActions(actions);
138
- stateManager.updateActions(actions);
139
- }
140
- }, [actions, actionManager, stateManager]);
141
-
142
- return (
143
- <DataTableContext.Provider value={contextValue as unknown as IDataTableContext<DataRecord>}>
144
- {children}
145
- </DataTableContext.Provider>
146
- );
147
- }
148
-
149
- /**
150
- * Hook to use DataTable context
151
- */
152
- export function useDataTableContext<TData extends DataRecord = DataRecord>(): IDataTableContext<TData> {
153
- const context = useContext(DataTableContext);
154
- if (!context) {
155
- throw new Error('useDataTableContext must be used within a DataTableProvider');
156
- }
157
- return context as unknown as IDataTableContext<TData>;
158
- }
159
-
160
- /**
161
- * Hook to use specific managers
162
- */
163
- /**
164
- * Hook to access DataTable data manager.
165
- *
166
- * @template TData - The type of data records in the table
167
- * @returns Data manager instance
168
- */
169
- export function useDataManager<TData extends DataRecord = DataRecord>() {
170
- const context = useDataTableContext<TData>();
171
- return context.dataManager;
172
- }
173
-
174
- /**
175
- * Hook to access DataTable column manager.
176
- *
177
- * @template TData - The type of data records in the table
178
- * @returns Column manager instance
179
- */
180
- export function useColumnManager<TData extends DataRecord = DataRecord>() {
181
- const context = useDataTableContext<TData>();
182
- return context.columnManager;
183
- }
184
-
185
- /**
186
- * Hook to access DataTable action manager.
187
- *
188
- * @template TData - The type of data records in the table
189
- * @returns Action manager instance
190
- */
191
- export function useActionManager<TData extends DataRecord = DataRecord>() {
192
- const context = useDataTableContext<TData>();
193
- return context.actionManager;
194
- }
195
-
196
- /**
197
- * Hook to access DataTable state manager.
198
- *
199
- * @template TData - The type of data records in the table
200
- * @returns State manager instance
201
- */
202
- export function useStateManager<TData extends DataRecord = DataRecord>() {
203
- const context = useDataTableContext<TData>();
204
- return context.stateManager;
205
- }
206
-
207
- /**
208
- * Hook to access DataTable plugin registry.
209
- *
210
- * @template TData - The type of data records in the table
211
- * @returns Plugin registry instance
212
- */
213
- export function usePluginRegistry<TData extends DataRecord = DataRecord>() {
214
- const context = useDataTableContext<TData>();
215
- return context.pluginRegistry;
216
- }
@@ -1,136 +0,0 @@
1
- import React from 'react';
2
- import { render, renderHook, waitFor, act } from '@testing-library/react';
3
- import { describe, it, expect, vi } from 'vitest';
4
- import { DataTableProvider, useActionManager, useColumnManager, useDataManager, useDataTableContext, usePluginRegistry, useStateManager } from '../DataTableContext';
5
- import type { DataTableConfig, DataTableContext as IDataTableContext } from '../interfaces';
6
- import type { DataRecord, DataTableAction } from '../../types';
7
- import type { ColumnDef } from '@tanstack/react-table';
8
-
9
- interface TestRecord extends DataRecord {
10
- id: string;
11
- name: string;
12
- }
13
-
14
- const baseConfig: DataTableConfig<TestRecord> = {
15
- features: {},
16
- enableVirtualization: false,
17
- enableCaching: false,
18
- cacheTimeout: 0,
19
- enableKeyboardNavigation: true,
20
- enableScreenReaderSupport: true,
21
- };
22
-
23
- const columns: ColumnDef<TestRecord>[] = [
24
- { id: 'name', header: 'Name', accessorKey: 'name' },
25
- ];
26
-
27
- const actions: DataTableAction<TestRecord>[] = [
28
- { label: 'View', testId: 'view', onClick: vi.fn() },
29
- ];
30
-
31
- describe('DataTableContext', () => {
32
- it('throws when hooks are used outside of the provider', () => {
33
- expect(() => renderHook(() => useDataTableContext<TestRecord>())).toThrow(
34
- 'useDataTableContext must be used within a DataTableProvider'
35
- );
36
- });
37
-
38
- it('exposes initialized managers populated from props', async () => {
39
- const onContext = vi.fn();
40
- const data: TestRecord[] = [{ id: '1', name: 'Alpha' }];
41
-
42
- render(
43
- <DataTableProvider config={baseConfig} data={data} columns={columns} actions={actions}>
44
- <TestConsumer onContext={onContext} />
45
- </DataTableProvider>
46
- );
47
-
48
- await waitFor(() => expect(onContext).toHaveBeenCalled());
49
- const ctx = onContext.mock.calls.at(-1)?.[0];
50
-
51
- expect(ctx.dataManager.getAdapter().name).toBe('local');
52
- expect(ctx.stateManager.getState().data).toEqual(data);
53
- expect(ctx.columnManager.getColumns()).toHaveLength(1);
54
- expect(ctx.actionManager.getActions()).toHaveLength(1);
55
- });
56
-
57
- it('reacts to prop changes and updates managed state', async () => {
58
- const onContext = vi.fn();
59
- const initialData: TestRecord[] = [{ id: '1', name: 'Alpha' }];
60
- const updatedData: TestRecord[] = [{ id: '2', name: 'Beta' }];
61
- const updatedColumns: ColumnDef<TestRecord>[] = [
62
- { id: 'name', header: 'Name', accessorKey: 'name' },
63
- { id: 'id', header: 'Identifier', accessorKey: 'id' },
64
- ];
65
-
66
- const { rerender } = render(
67
- <DataTableProvider config={baseConfig} data={initialData} columns={columns} actions={actions}>
68
- <TestConsumer onContext={onContext} />
69
- </DataTableProvider>
70
- );
71
-
72
- await waitFor(() => expect(onContext).toHaveBeenCalled());
73
- onContext.mockClear();
74
-
75
- rerender(
76
- <DataTableProvider config={baseConfig} data={updatedData} columns={updatedColumns} actions={[...actions]}>
77
- <TestConsumer onContext={onContext} />
78
- </DataTableProvider>
79
- );
80
-
81
- await waitFor(() => expect(onContext).toHaveBeenCalled());
82
- const ctx = onContext.mock.calls.at(-1)?.[0];
83
-
84
- expect(ctx.stateManager.getState().data).toEqual(updatedData);
85
- expect(ctx.columnManager.getColumns()).toHaveLength(2);
86
- expect(ctx.actionManager.getActions()).toHaveLength(actions.length);
87
- });
88
-
89
- it('exposes hook shorthands and utility helpers', async () => {
90
- vi.useFakeTimers();
91
- const wrapper = ({ children }: { children: React.ReactNode }) => (
92
- <DataTableProvider config={baseConfig} data={[{ id: '1', name: 'Alpha' }]} columns={columns} actions={actions}>
93
- {children}
94
- </DataTableProvider>
95
- );
96
-
97
- const { result: managerResult } = renderHook(
98
- () => ({
99
- data: useDataManager<TestRecord>(),
100
- columns: useColumnManager<TestRecord>(),
101
- actions: useActionManager<TestRecord>(),
102
- state: useStateManager<TestRecord>(),
103
- plugins: usePluginRegistry<TestRecord>(),
104
- context: useDataTableContext<TestRecord>(),
105
- }),
106
- { wrapper }
107
- );
108
-
109
- expect(managerResult.current.data.getAdapter().name).toBe('local');
110
- expect(managerResult.current.columns.getColumns()).toHaveLength(1);
111
- expect(managerResult.current.actions.getActionCount()).toBe(1);
112
- expect(managerResult.current.state.getObserverCount()).toBe(0);
113
- expect(managerResult.current.plugins.getPluginCount()).toBe(0);
114
-
115
- const debounced = managerResult.current.context.utils.debounce(vi.fn(), 50);
116
- debounced();
117
- debounced();
118
- expect(managerResult.current.context.utils.getRowId?.({} as any, 3)).toBe('3');
119
-
120
- await act(async () => {
121
- vi.advanceTimersByTime(60);
122
- });
123
-
124
- expect(managerResult.current.context.utils.debounce).toBeDefined();
125
- expect((managerResult.current.context.utils.debounce as any).mock).toBeUndefined();
126
- vi.useRealTimers();
127
- });
128
- });
129
-
130
- function TestConsumer({ onContext }: { onContext: (ctx: IDataTableContext<TestRecord>) => void }) {
131
- const ctx = useDataTableContext<TestRecord>();
132
- React.useEffect(() => {
133
- onContext(ctx);
134
- }, [ctx, onContext]);
135
- return null;
136
- }