@jmruthers/pace-core 0.5.118 → 0.5.119

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 (166) hide show
  1. package/dist/{DataTable-ZOAKQ3SU.js → DataTable-BQYGKVHR.js} +6 -6
  2. package/dist/{UnifiedAuthProvider-YFN7YGVN.js → UnifiedAuthProvider-UACKFATV.js} +3 -3
  3. package/dist/{chunk-7OTQLFVI.js → chunk-B4GZ2BXO.js} +3 -3
  4. package/dist/{chunk-KA3PSVNV.js → chunk-BHWIUEYH.js} +2 -1
  5. package/dist/chunk-BHWIUEYH.js.map +1 -0
  6. package/dist/{chunk-LFS45U62.js → chunk-CGURJ27Z.js} +2 -2
  7. package/dist/{chunk-PHDAXDHB.js → chunk-D6BOFXYR.js} +3 -3
  8. package/dist/{chunk-2LM4QQGH.js → chunk-F7COHU5B.js} +8 -8
  9. package/dist/{chunk-P3PUOL6B.js → chunk-FKFHZUGF.js} +4 -4
  10. package/dist/{chunk-UKZWNQMB.js → chunk-NP5VABFV.js} +4 -4
  11. package/dist/{chunk-O3FTRYEU.js → chunk-NZ32EONV.js} +2 -2
  12. package/dist/{chunk-ECOVPXYS.js → chunk-RIEJGKD3.js} +4 -4
  13. package/dist/{chunk-HIWXXDXO.js → chunk-TDNI6ZWL.js} +5 -5
  14. package/dist/{chunk-VN3OOE35.js → chunk-ZYJ6O5CA.js} +2 -2
  15. package/dist/components.js +8 -8
  16. package/dist/hooks.js +7 -7
  17. package/dist/index.js +11 -11
  18. package/dist/providers.js +2 -2
  19. package/dist/rbac/index.js +7 -7
  20. package/dist/utils.js +1 -1
  21. package/docs/api/classes/ColumnFactory.md +1 -1
  22. package/docs/api/classes/ErrorBoundary.md +1 -1
  23. package/docs/api/classes/InvalidScopeError.md +1 -1
  24. package/docs/api/classes/MissingUserContextError.md +1 -1
  25. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  26. package/docs/api/classes/PermissionDeniedError.md +1 -1
  27. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  28. package/docs/api/classes/RBACAuditManager.md +1 -1
  29. package/docs/api/classes/RBACCache.md +1 -1
  30. package/docs/api/classes/RBACEngine.md +1 -1
  31. package/docs/api/classes/RBACError.md +1 -1
  32. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  33. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  34. package/docs/api/classes/StorageUtils.md +1 -1
  35. package/docs/api/enums/FileCategory.md +1 -1
  36. package/docs/api/interfaces/AggregateConfig.md +1 -1
  37. package/docs/api/interfaces/ButtonProps.md +1 -1
  38. package/docs/api/interfaces/CardProps.md +1 -1
  39. package/docs/api/interfaces/ColorPalette.md +1 -1
  40. package/docs/api/interfaces/ColorShade.md +1 -1
  41. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  42. package/docs/api/interfaces/DataRecord.md +1 -1
  43. package/docs/api/interfaces/DataTableAction.md +1 -1
  44. package/docs/api/interfaces/DataTableColumn.md +1 -1
  45. package/docs/api/interfaces/DataTableProps.md +1 -1
  46. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  47. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  48. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  49. package/docs/api/interfaces/EventAppRoleData.md +1 -1
  50. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  51. package/docs/api/interfaces/FileMetadata.md +1 -1
  52. package/docs/api/interfaces/FileReference.md +1 -1
  53. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  54. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  55. package/docs/api/interfaces/FileUploadProps.md +1 -1
  56. package/docs/api/interfaces/FooterProps.md +1 -1
  57. package/docs/api/interfaces/GrantEventAppRoleParams.md +1 -1
  58. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  59. package/docs/api/interfaces/InputProps.md +1 -1
  60. package/docs/api/interfaces/LabelProps.md +1 -1
  61. package/docs/api/interfaces/LoginFormProps.md +1 -1
  62. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  63. package/docs/api/interfaces/NavigationContextType.md +1 -1
  64. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  65. package/docs/api/interfaces/NavigationItem.md +1 -1
  66. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  67. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  68. package/docs/api/interfaces/Organisation.md +1 -1
  69. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  70. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  71. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  72. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  73. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  74. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  75. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  76. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  77. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  78. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  79. package/docs/api/interfaces/PaletteData.md +1 -1
  80. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  81. package/docs/api/interfaces/ProtectedRouteProps.md +1 -1
  82. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  83. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  84. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  85. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  86. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  87. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  88. package/docs/api/interfaces/RBACConfig.md +1 -1
  89. package/docs/api/interfaces/RBACLogger.md +1 -1
  90. package/docs/api/interfaces/RevokeEventAppRoleParams.md +1 -1
  91. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  92. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  93. package/docs/api/interfaces/RoleManagementResult.md +1 -1
  94. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  95. package/docs/api/interfaces/RouteConfig.md +1 -1
  96. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  97. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  98. package/docs/api/interfaces/StorageConfig.md +1 -1
  99. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  100. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  101. package/docs/api/interfaces/StorageListOptions.md +1 -1
  102. package/docs/api/interfaces/StorageListResult.md +1 -1
  103. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  104. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  105. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  106. package/docs/api/interfaces/StyleImport.md +1 -1
  107. package/docs/api/interfaces/SwitchProps.md +1 -1
  108. package/docs/api/interfaces/ToastActionElement.md +1 -1
  109. package/docs/api/interfaces/ToastProps.md +1 -1
  110. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  111. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  112. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  113. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  114. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  115. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  116. package/docs/api/interfaces/UsePublicFileDisplayOptions.md +1 -1
  117. package/docs/api/interfaces/UsePublicFileDisplayReturn.md +1 -1
  118. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  119. package/docs/api/interfaces/UseResolvedScopeOptions.md +1 -1
  120. package/docs/api/interfaces/UseResolvedScopeReturn.md +1 -1
  121. package/docs/api/interfaces/UserEventAccess.md +1 -1
  122. package/docs/api/interfaces/UserMenuProps.md +1 -1
  123. package/docs/api/interfaces/UserProfile.md +1 -1
  124. package/docs/api/modules.md +2 -2
  125. package/package.json +1 -1
  126. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +697 -0
  127. package/src/components/DataTable/components/__tests__/EditableRow.test.tsx +544 -9
  128. package/src/components/DataTable/components/__tests__/UnifiedTableBody.test.tsx +1004 -0
  129. package/src/components/DataTable/utils/__tests__/a11yUtils.test.ts +612 -0
  130. package/src/components/DataTable/utils/__tests__/errorHandling.test.ts +266 -0
  131. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +455 -1
  132. package/src/hooks/__tests__/index.unit.test.ts +223 -0
  133. package/src/hooks/__tests__/useDataTablePerformance.unit.test.ts +748 -0
  134. package/src/hooks/__tests__/useEvents.unit.test.ts +249 -0
  135. package/src/hooks/__tests__/useFileDisplay.unit.test.ts +1060 -0
  136. package/src/hooks/__tests__/useFileUrl.unit.test.ts +958 -0
  137. package/src/hooks/__tests__/useFocusTrap.unit.test.tsx +540 -1
  138. package/src/hooks/__tests__/useIsMobile.unit.test.ts +205 -5
  139. package/src/hooks/__tests__/useKeyboardShortcuts.unit.test.ts +616 -1
  140. package/src/hooks/__tests__/useOrganisations.unit.test.ts +369 -0
  141. package/src/hooks/__tests__/usePerformanceMonitor.unit.test.ts +608 -0
  142. package/src/hooks/__tests__/useSecureDataAccess.unit.test.tsx +2 -0
  143. package/src/hooks/__tests__/useSessionRestoration.unit.test.tsx +372 -0
  144. package/src/hooks/__tests__/useToast.unit.test.tsx +431 -30
  145. package/src/hooks/useSecureDataAccess.test.ts +1 -0
  146. package/src/rbac/audit-enhanced.ts +339 -0
  147. package/src/services/EventService.ts +1 -0
  148. package/src/services/__tests__/AuthService.test.ts +473 -0
  149. package/src/services/__tests__/EventService.test.ts +390 -0
  150. package/src/services/__tests__/InactivityService.test.ts +217 -0
  151. package/src/services/__tests__/OrganisationService.test.ts +371 -0
  152. package/dist/chunk-KA3PSVNV.js.map +0 -1
  153. package/src/components/DataTable/utils/debugTools.ts +0 -609
  154. package/src/rbac/testing/index.tsx +0 -340
  155. /package/dist/{DataTable-ZOAKQ3SU.js.map → DataTable-BQYGKVHR.js.map} +0 -0
  156. /package/dist/{UnifiedAuthProvider-YFN7YGVN.js.map → UnifiedAuthProvider-UACKFATV.js.map} +0 -0
  157. /package/dist/{chunk-7OTQLFVI.js.map → chunk-B4GZ2BXO.js.map} +0 -0
  158. /package/dist/{chunk-LFS45U62.js.map → chunk-CGURJ27Z.js.map} +0 -0
  159. /package/dist/{chunk-PHDAXDHB.js.map → chunk-D6BOFXYR.js.map} +0 -0
  160. /package/dist/{chunk-2LM4QQGH.js.map → chunk-F7COHU5B.js.map} +0 -0
  161. /package/dist/{chunk-P3PUOL6B.js.map → chunk-FKFHZUGF.js.map} +0 -0
  162. /package/dist/{chunk-UKZWNQMB.js.map → chunk-NP5VABFV.js.map} +0 -0
  163. /package/dist/{chunk-O3FTRYEU.js.map → chunk-NZ32EONV.js.map} +0 -0
  164. /package/dist/{chunk-ECOVPXYS.js.map → chunk-RIEJGKD3.js.map} +0 -0
  165. /package/dist/{chunk-HIWXXDXO.js.map → chunk-TDNI6ZWL.js.map} +0 -0
  166. /package/dist/{chunk-VN3OOE35.js.map → chunk-ZYJ6O5CA.js.map} +0 -0
@@ -15,11 +15,13 @@ describe('useIsMobile', () => {
15
15
  beforeEach(() => {
16
16
  vi.clearAllMocks();
17
17
  // Reset window properties for each test
18
- Object.defineProperty(window, 'innerWidth', {
19
- writable: true,
20
- configurable: true,
21
- value: 1024
22
- });
18
+ if (typeof window !== 'undefined') {
19
+ Object.defineProperty(window, 'innerWidth', {
20
+ writable: true,
21
+ configurable: true,
22
+ value: 1024
23
+ });
24
+ }
23
25
  });
24
26
 
25
27
  describe('Initial detection', () => {
@@ -94,8 +96,183 @@ describe('useIsMobile', () => {
94
96
  });
95
97
  });
96
98
 
99
+ describe('SSR Handling', () => {
100
+ // Note: SSR test is skipped because we cannot properly test typeof window === 'undefined'
101
+ // in jsdom environment where window is always defined. This behavior is tested in
102
+ // actual SSR environments (Next.js, Remix, etc.)
103
+ it.skip('returns false when window is undefined (SSR)', () => {
104
+ // This test cannot run in jsdom - window is always defined
105
+ // SSR behavior is validated in actual SSR environments
106
+ });
107
+ });
108
+
109
+ describe('Media Query Change Handler', () => {
110
+ it('updates state when media query changes to mobile', () => {
111
+ if (typeof window === 'undefined') return;
112
+
113
+ let changeHandler: (() => void) | null = null;
114
+ const addEventListener = vi.fn((event: string, handler: () => void) => {
115
+ if (event === 'change') {
116
+ changeHandler = handler;
117
+ }
118
+ });
119
+ const removeEventListener = vi.fn();
120
+
121
+ window.innerWidth = 1200; // Desktop initially
122
+
123
+ const mql = {
124
+ matches: false,
125
+ media: '(max-width: 767px)',
126
+ onchange: null,
127
+ addEventListener,
128
+ removeEventListener,
129
+ addListener: vi.fn(),
130
+ removeListener: vi.fn(),
131
+ dispatchEvent: vi.fn()
132
+ };
133
+
134
+ window.matchMedia = vi.fn(() => mql) as any;
135
+
136
+ const { result } = renderHook(() => useIsMobile());
137
+
138
+ // Initially desktop
139
+ expect(result.current).toBe(false);
140
+ expect(addEventListener).toHaveBeenCalledWith('change', expect.any(Function));
141
+
142
+ // Simulate change to mobile
143
+ window.innerWidth = 500;
144
+ if (changeHandler) {
145
+ changeHandler();
146
+ }
147
+
148
+ // Hook should update on next render (in real usage, React would re-render)
149
+ // This test verifies the handler is set up correctly
150
+ expect(changeHandler).toBeDefined();
151
+ });
152
+
153
+ it('updates state when media query changes to desktop', () => {
154
+ if (typeof window === 'undefined') return;
155
+
156
+ let changeHandler: (() => void) | null = null;
157
+ const addEventListener = vi.fn((event: string, handler: () => void) => {
158
+ if (event === 'change') {
159
+ changeHandler = handler;
160
+ }
161
+ });
162
+ const removeEventListener = vi.fn();
163
+
164
+ window.innerWidth = 500; // Mobile initially
165
+
166
+ const mql = {
167
+ matches: true,
168
+ media: '(max-width: 767px)',
169
+ onchange: null,
170
+ addEventListener,
171
+ removeEventListener,
172
+ addListener: vi.fn(),
173
+ removeListener: vi.fn(),
174
+ dispatchEvent: vi.fn()
175
+ };
176
+
177
+ window.matchMedia = vi.fn(() => mql) as any;
178
+
179
+ const { result } = renderHook(() => useIsMobile());
180
+
181
+ // Initially mobile
182
+ expect(result.current).toBe(true);
183
+ expect(addEventListener).toHaveBeenCalledWith('change', expect.any(Function));
184
+
185
+ // Simulate change to desktop
186
+ window.innerWidth = 1200;
187
+ if (changeHandler) {
188
+ changeHandler();
189
+ }
190
+
191
+ // Verify handler is set up
192
+ expect(changeHandler).toBeDefined();
193
+ });
194
+ });
195
+
196
+ describe('Breakpoint Edge Cases', () => {
197
+ it('handles viewport exactly at breakpoint (767px)', () => {
198
+ if (typeof window === 'undefined') return;
199
+ window.innerWidth = 767;
200
+
201
+ const mql = {
202
+ matches: true, // 767px matches max-width: 767px
203
+ media: '(max-width: 767px)',
204
+ onchange: null,
205
+ addEventListener: vi.fn(),
206
+ removeEventListener: vi.fn(),
207
+ addListener: vi.fn(),
208
+ removeListener: vi.fn(),
209
+ dispatchEvent: vi.fn()
210
+ };
211
+
212
+ window.matchMedia = vi.fn(() => mql) as any;
213
+
214
+ const { result } = renderHook(() => useIsMobile());
215
+
216
+ // 767px is mobile (767 < 768, hook uses < MOBILE_BREAKPOINT where MOBILE_BREAKPOINT = 768)
217
+ expect(result.current).toBe(true);
218
+ });
219
+
220
+ it('handles viewport just below breakpoint (766px)', () => {
221
+ if (typeof window === 'undefined') return;
222
+ window.innerWidth = 766;
223
+
224
+ const mql = {
225
+ matches: true,
226
+ media: '(max-width: 767px)',
227
+ onchange: null,
228
+ addEventListener: vi.fn(),
229
+ removeEventListener: vi.fn(),
230
+ addListener: vi.fn(),
231
+ removeListener: vi.fn(),
232
+ dispatchEvent: vi.fn()
233
+ };
234
+
235
+ window.matchMedia = vi.fn(() => mql) as any;
236
+
237
+ const { result } = renderHook(() => useIsMobile());
238
+
239
+ expect(result.current).toBe(true);
240
+ });
241
+ });
242
+
243
+ describe('Cleanup', () => {
244
+ it('removes event listener on unmount', () => {
245
+ if (typeof window === 'undefined') return;
246
+ const addEventListener = vi.fn();
247
+ const removeEventListener = vi.fn();
248
+
249
+ const mql = {
250
+ matches: false,
251
+ media: '(max-width: 767px)',
252
+ onchange: null,
253
+ addEventListener,
254
+ removeEventListener,
255
+ addListener: vi.fn(),
256
+ removeListener: vi.fn(),
257
+ dispatchEvent: vi.fn()
258
+ };
259
+
260
+ window.matchMedia = vi.fn(() => mql) as any;
261
+
262
+ const { unmount } = renderHook(() => useIsMobile());
263
+
264
+ expect(addEventListener).toHaveBeenCalledWith('change', expect.any(Function));
265
+
266
+ unmount();
267
+
268
+ expect(removeEventListener).toHaveBeenCalledWith('change', expect.any(Function));
269
+ expect(removeEventListener).toHaveBeenCalledTimes(1);
270
+ });
271
+ });
272
+
97
273
  describe('Hook returns boolean', () => {
98
274
  it('returns a boolean value', () => {
275
+ if (typeof window === 'undefined') return;
99
276
  const mql = {
100
277
  matches: false,
101
278
  media: '(max-width: 767px)',
@@ -113,5 +290,28 @@ describe('useIsMobile', () => {
113
290
 
114
291
  expect(typeof result.current).toBe('boolean');
115
292
  });
293
+
294
+ it('returns false when isMobile is undefined initially', () => {
295
+ if (typeof window === 'undefined') return;
296
+ // This tests the !!isMobile conversion
297
+ const mql = {
298
+ matches: false,
299
+ media: '(max-width: 767px)',
300
+ onchange: null,
301
+ addEventListener: vi.fn(),
302
+ removeEventListener: vi.fn(),
303
+ addListener: vi.fn(),
304
+ removeListener: vi.fn(),
305
+ dispatchEvent: vi.fn()
306
+ };
307
+
308
+ window.matchMedia = vi.fn(() => mql) as any;
309
+
310
+ const { result } = renderHook(() => useIsMobile());
311
+
312
+ // Should convert undefined to false
313
+ expect(result.current).toBe(false);
314
+ expect(typeof result.current).toBe('boolean');
315
+ });
116
316
  });
117
317
  });