@jmruthers/pace-core 0.5.75 → 0.5.76

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 (226) hide show
  1. package/dist/{DataTable-HWZQGASI.js → DataTable-4GAVPIEG.js} +48 -30
  2. package/dist/{PublicLoadingSpinner-BKNBT6b6.d.ts → PublicLoadingSpinner-BiNER8F5.d.ts} +28 -17
  3. package/dist/{chunk-33PHABLB.js → chunk-AFGTSUAD.js} +10 -127
  4. package/dist/chunk-AFGTSUAD.js.map +1 -0
  5. package/dist/{chunk-2DFZ432F.js → chunk-K34IM5CT.js} +3 -5
  6. package/dist/{chunk-2DFZ432F.js.map → chunk-K34IM5CT.js.map} +1 -1
  7. package/dist/{chunk-2CHATWBF.js → chunk-KHJS6VIA.js} +199 -35
  8. package/dist/chunk-KHJS6VIA.js.map +1 -0
  9. package/dist/{chunk-ZTT2AXMX.js → chunk-KK73ZB4E.js} +2 -2
  10. package/dist/{chunk-CY3AHGO4.js → chunk-M5IWZRBT.js} +1750 -2815
  11. package/dist/chunk-M5IWZRBT.js.map +1 -0
  12. package/dist/{chunk-DAXLNIDY.js → chunk-Y6TXWPJO.js} +6 -4
  13. package/dist/{chunk-DAXLNIDY.js.map → chunk-Y6TXWPJO.js.map} +1 -1
  14. package/dist/{chunk-YNUBMSMV.js → chunk-YCKPEMJA.js} +186 -263
  15. package/dist/chunk-YCKPEMJA.js.map +1 -0
  16. package/dist/components.d.ts +1 -1
  17. package/dist/components.js +7 -6
  18. package/dist/components.js.map +1 -1
  19. package/dist/hooks.d.ts +17 -40
  20. package/dist/hooks.js +6 -6
  21. package/dist/index.d.ts +3 -3
  22. package/dist/index.js +12 -10
  23. package/dist/index.js.map +1 -1
  24. package/dist/rbac/index.d.ts +54 -1
  25. package/dist/rbac/index.js +5 -4
  26. package/dist/utils.js +1 -1
  27. package/docs/TERMINOLOGY.md +231 -0
  28. package/docs/api/classes/ColumnFactory.md +1 -1
  29. package/docs/api/classes/ErrorBoundary.md +1 -1
  30. package/docs/api/classes/InvalidScopeError.md +1 -1
  31. package/docs/api/classes/MissingUserContextError.md +1 -1
  32. package/docs/api/classes/OrganisationContextRequiredError.md +1 -1
  33. package/docs/api/classes/PermissionDeniedError.md +1 -1
  34. package/docs/api/classes/PublicErrorBoundary.md +1 -1
  35. package/docs/api/classes/RBACAuditManager.md +1 -1
  36. package/docs/api/classes/RBACCache.md +1 -1
  37. package/docs/api/classes/RBACEngine.md +1 -1
  38. package/docs/api/classes/RBACError.md +1 -1
  39. package/docs/api/classes/RBACNotInitializedError.md +1 -1
  40. package/docs/api/classes/SecureSupabaseClient.md +1 -1
  41. package/docs/api/classes/StorageUtils.md +1 -1
  42. package/docs/api/enums/FileCategory.md +1 -1
  43. package/docs/api/interfaces/AggregateConfig.md +1 -1
  44. package/docs/api/interfaces/ButtonProps.md +1 -1
  45. package/docs/api/interfaces/CardProps.md +1 -1
  46. package/docs/api/interfaces/ColorPalette.md +1 -1
  47. package/docs/api/interfaces/ColorShade.md +1 -1
  48. package/docs/api/interfaces/DataAccessRecord.md +1 -1
  49. package/docs/api/interfaces/DataTableAction.md +1 -1
  50. package/docs/api/interfaces/DataTableColumn.md +1 -1
  51. package/docs/api/interfaces/DataTableProps.md +1 -1
  52. package/docs/api/interfaces/DataTableToolbarButton.md +1 -1
  53. package/docs/api/interfaces/EmptyStateConfig.md +1 -1
  54. package/docs/api/interfaces/EnhancedNavigationMenuProps.md +1 -1
  55. package/docs/api/interfaces/EventLogoProps.md +1 -1
  56. package/docs/api/interfaces/FileDisplayProps.md +1 -1
  57. package/docs/api/interfaces/FileMetadata.md +1 -1
  58. package/docs/api/interfaces/FileReference.md +1 -1
  59. package/docs/api/interfaces/FileSizeLimits.md +1 -1
  60. package/docs/api/interfaces/FileUploadOptions.md +1 -1
  61. package/docs/api/interfaces/FileUploadProps.md +1 -1
  62. package/docs/api/interfaces/FooterProps.md +1 -1
  63. package/docs/api/interfaces/InactivityWarningModalProps.md +1 -1
  64. package/docs/api/interfaces/InputProps.md +1 -1
  65. package/docs/api/interfaces/LabelProps.md +1 -1
  66. package/docs/api/interfaces/LoginFormProps.md +1 -1
  67. package/docs/api/interfaces/NavigationAccessRecord.md +1 -1
  68. package/docs/api/interfaces/NavigationContextType.md +1 -1
  69. package/docs/api/interfaces/NavigationGuardProps.md +1 -1
  70. package/docs/api/interfaces/NavigationItem.md +1 -1
  71. package/docs/api/interfaces/NavigationMenuProps.md +1 -1
  72. package/docs/api/interfaces/NavigationProviderProps.md +1 -1
  73. package/docs/api/interfaces/Organisation.md +1 -1
  74. package/docs/api/interfaces/OrganisationContextType.md +1 -1
  75. package/docs/api/interfaces/OrganisationMembership.md +1 -1
  76. package/docs/api/interfaces/OrganisationProviderProps.md +1 -1
  77. package/docs/api/interfaces/OrganisationSecurityError.md +1 -1
  78. package/docs/api/interfaces/PaceAppLayoutProps.md +1 -1
  79. package/docs/api/interfaces/PaceLoginPageProps.md +1 -1
  80. package/docs/api/interfaces/PageAccessRecord.md +1 -1
  81. package/docs/api/interfaces/PagePermissionContextType.md +1 -1
  82. package/docs/api/interfaces/PagePermissionGuardProps.md +1 -1
  83. package/docs/api/interfaces/PagePermissionProviderProps.md +1 -1
  84. package/docs/api/interfaces/PaletteData.md +1 -1
  85. package/docs/api/interfaces/PermissionEnforcerProps.md +1 -1
  86. package/docs/api/interfaces/PublicErrorBoundaryProps.md +1 -1
  87. package/docs/api/interfaces/PublicErrorBoundaryState.md +1 -1
  88. package/docs/api/interfaces/PublicLoadingSpinnerProps.md +1 -1
  89. package/docs/api/interfaces/PublicPageFooterProps.md +1 -1
  90. package/docs/api/interfaces/PublicPageHeaderProps.md +1 -1
  91. package/docs/api/interfaces/PublicPageLayoutProps.md +1 -1
  92. package/docs/api/interfaces/RBACConfig.md +1 -1
  93. package/docs/api/interfaces/RBACContextType.md +1 -1
  94. package/docs/api/interfaces/RBACLogger.md +1 -1
  95. package/docs/api/interfaces/RBACProviderProps.md +1 -1
  96. package/docs/api/interfaces/RoleBasedRouterContextType.md +1 -1
  97. package/docs/api/interfaces/RoleBasedRouterProps.md +1 -1
  98. package/docs/api/interfaces/RouteAccessRecord.md +1 -1
  99. package/docs/api/interfaces/RouteConfig.md +1 -1
  100. package/docs/api/interfaces/SecureDataContextType.md +1 -1
  101. package/docs/api/interfaces/SecureDataProviderProps.md +1 -1
  102. package/docs/api/interfaces/StorageConfig.md +1 -1
  103. package/docs/api/interfaces/StorageFileInfo.md +1 -1
  104. package/docs/api/interfaces/StorageFileMetadata.md +1 -1
  105. package/docs/api/interfaces/StorageListOptions.md +1 -1
  106. package/docs/api/interfaces/StorageListResult.md +1 -1
  107. package/docs/api/interfaces/StorageUploadOptions.md +1 -1
  108. package/docs/api/interfaces/StorageUploadResult.md +1 -1
  109. package/docs/api/interfaces/StorageUrlOptions.md +1 -1
  110. package/docs/api/interfaces/StyleImport.md +1 -1
  111. package/docs/api/interfaces/SwitchProps.md +1 -1
  112. package/docs/api/interfaces/ToastActionElement.md +1 -1
  113. package/docs/api/interfaces/ToastProps.md +1 -1
  114. package/docs/api/interfaces/UnifiedAuthContextType.md +1 -1
  115. package/docs/api/interfaces/UnifiedAuthProviderProps.md +1 -1
  116. package/docs/api/interfaces/UseInactivityTrackerOptions.md +1 -1
  117. package/docs/api/interfaces/UseInactivityTrackerReturn.md +1 -1
  118. package/docs/api/interfaces/UsePublicEventLogoOptions.md +1 -1
  119. package/docs/api/interfaces/UsePublicEventLogoReturn.md +1 -1
  120. package/docs/api/interfaces/UsePublicEventOptions.md +1 -1
  121. package/docs/api/interfaces/UsePublicEventReturn.md +1 -1
  122. package/docs/api/interfaces/UsePublicRouteParamsReturn.md +1 -1
  123. package/docs/api/interfaces/UseResolvedScopeOptions.md +47 -0
  124. package/docs/api/interfaces/UseResolvedScopeReturn.md +47 -0
  125. package/docs/api/interfaces/UserEventAccess.md +1 -1
  126. package/docs/api/interfaces/UserMenuProps.md +1 -1
  127. package/docs/api/interfaces/UserProfile.md +1 -1
  128. package/docs/api/modules.md +57 -11
  129. package/docs/api-reference/providers.md +26 -7
  130. package/docs/best-practices/README.md +20 -0
  131. package/docs/best-practices/accessibility.md +566 -0
  132. package/docs/best-practices/performance-expansion.md +473 -0
  133. package/docs/core-concepts/authentication.md +15 -7
  134. package/docs/documentation-index.md +1 -1
  135. package/docs/documentation-templates.md +539 -0
  136. package/docs/getting-started/quick-start.md +16 -66
  137. package/docs/implementation-guides/component-styling.md +410 -0
  138. package/docs/implementation-guides/data-tables.md +1 -1
  139. package/docs/style-guide.md +39 -0
  140. package/package.json +1 -1
  141. package/src/__tests__/TEST_GUIDE_CURSOR.md +290 -0
  142. package/src/__tests__/helpers/supabaseMock.ts +48 -2
  143. package/src/components/DataTable/__tests__/DataTable.default-state.test.tsx +17 -6
  144. package/src/components/DataTable/__tests__/DataTableCore.test.tsx +73 -9
  145. package/src/components/DataTable/components/DataTableCore.tsx +280 -475
  146. package/src/components/DataTable/components/UnifiedTableBody.tsx +120 -153
  147. package/src/components/DataTable/components/index.ts +1 -2
  148. package/src/components/DataTable/context/__tests__/DataTableContext.test.tsx +208 -275
  149. package/src/components/DataTable/core/index.ts +1 -8
  150. package/src/components/DataTable/hooks/__tests__/useColumnOrderPersistence.test.ts +525 -0
  151. package/src/components/DataTable/hooks/__tests__/useColumnReordering.test.ts +570 -0
  152. package/src/components/DataTable/hooks/__tests__/useHierarchicalState.test.ts +214 -0
  153. package/src/components/DataTable/hooks/__tests__/useTableColumns.test.ts +224 -0
  154. package/src/components/DataTable/hooks/index.ts +6 -0
  155. package/src/components/DataTable/hooks/useColumnReordering.ts +1 -0
  156. package/src/components/DataTable/hooks/useDataTablePermissions.ts +149 -0
  157. package/src/components/DataTable/hooks/useDataTableState.ts +12 -6
  158. package/src/components/DataTable/hooks/useHierarchicalState.ts +26 -8
  159. package/src/components/DataTable/hooks/useTableColumns.ts +153 -0
  160. package/src/components/DataTable/index.ts +1 -9
  161. package/src/components/DataTable/utils/__tests__/COVERAGE_NOTE.md +89 -0
  162. package/src/components/DataTable/utils/__tests__/exportUtils.test.ts +3 -6
  163. package/src/components/DataTable/utils/__tests__/flexibleImport.test.ts +462 -0
  164. package/src/components/DataTable/utils/__tests__/hierarchicalSorting.test.ts +247 -0
  165. package/src/components/DataTable/utils/__tests__/hierarchicalUtils.test.ts +8 -6
  166. package/src/components/DataTable/utils/__tests__/performanceUtils.test.ts +466 -0
  167. package/src/components/DataTable/utils/__tests__/rowUtils.test.ts +265 -0
  168. package/src/components/DataTable/utils/errorHandling.ts +52 -460
  169. package/src/components/DataTable/utils/exportUtils.ts +46 -15
  170. package/src/components/DataTable/utils/hierarchicalSorting.ts +50 -3
  171. package/src/components/DataTable/utils/hierarchicalUtils.ts +167 -34
  172. package/src/components/DataTable/utils/index.ts +5 -0
  173. package/src/components/DataTable/utils/rowUtils.ts +68 -0
  174. package/src/components/EventSelector/EventSelector.test.tsx +672 -0
  175. package/src/components/Label/__tests__/Label.test.tsx +434 -0
  176. package/src/components/PublicLayout/__tests__/PublicPageContextChecker.test.tsx +190 -0
  177. package/src/components/PublicLayout/__tests__/PublicPageDebugger.test.tsx +185 -0
  178. package/src/components/PublicLayout/__tests__/PublicPageProvider.test.tsx +313 -0
  179. package/src/components/Select/Select.test.tsx +143 -120
  180. package/src/components/Select/Select.tsx +47 -212
  181. package/src/components/Select/hooks.ts +36 -1
  182. package/src/components/Select/index.ts +2 -1
  183. package/src/hooks/services/__tests__/useServiceHooks.test.tsx +137 -0
  184. package/src/hooks/useSecureDataAccess.test.ts +32 -29
  185. package/src/providers/__tests__/ProviderLifecycle.test.tsx +341 -0
  186. package/src/rbac/hooks/__tests__/usePermissions.integration.test.ts +437 -0
  187. package/src/rbac/hooks/index.ts +2 -0
  188. package/src/rbac/hooks/useResolvedScope.ts +232 -0
  189. package/src/services/__tests__/InactivityService.lifecycle.test.ts +411 -0
  190. package/src/services/__tests__/OrganisationService.pagination.test.ts +375 -0
  191. package/src/types/__tests__/README.md +114 -0
  192. package/src/types/__tests__/validation.test.ts +731 -0
  193. package/src/utils/__tests__/file-reference.test.ts +383 -0
  194. package/src/utils/__tests__/performanceBenchmark.test.ts +175 -0
  195. package/src/utils/appNameResolver.test.ts +54 -0
  196. package/src/validation/__tests__/csrf.unit.test.ts +63 -0
  197. package/src/validation/__tests__/passwordSchema.unit.test.ts +105 -0
  198. package/dist/chunk-2CHATWBF.js.map +0 -1
  199. package/dist/chunk-33PHABLB.js.map +0 -1
  200. package/dist/chunk-CY3AHGO4.js.map +0 -1
  201. package/dist/chunk-TYHR5X4W.js +0 -33
  202. package/dist/chunk-TYHR5X4W.js.map +0 -1
  203. package/dist/chunk-YNUBMSMV.js.map +0 -1
  204. package/dist/eventContext-BBA42P6G.js +0 -14
  205. package/dist/eventContext-BBA42P6G.js.map +0 -1
  206. package/docs/documentation-style-checklist.md +0 -294
  207. package/src/components/DataTable/components/DataTableBody.tsx +0 -488
  208. package/src/components/DataTable/components/DraggableColumnHeader.tsx +0 -144
  209. package/src/components/DataTable/components/VirtualizedDataTable.tsx +0 -515
  210. package/src/components/DataTable/core/ActionManager.ts +0 -235
  211. package/src/components/DataTable/core/ColumnManager.ts +0 -215
  212. package/src/components/DataTable/core/DataManager.ts +0 -188
  213. package/src/components/DataTable/core/DataTableContext.tsx +0 -181
  214. package/src/components/DataTable/core/LocalDataAdapter.ts +0 -264
  215. package/src/components/DataTable/core/PluginRegistry.ts +0 -229
  216. package/src/components/DataTable/core/StateManager.ts +0 -311
  217. package/src/components/DataTable/core/__tests__/ActionManager.test.ts +0 -634
  218. package/src/components/DataTable/core/__tests__/ColumnManager.test.ts +0 -193
  219. package/src/components/DataTable/core/__tests__/DataManager.test.ts +0 -519
  220. package/src/components/DataTable/core/__tests__/StateManager.test.ts +0 -714
  221. package/src/components/DataTable/core/interfaces.ts +0 -338
  222. package/src/components/DataTable/utils/debugTools.ts +0 -583
  223. package/src/components/Select/Select.bug-test.tsx +0 -69
  224. package/src/components/Select/Select.refactored.tsx +0 -497
  225. /package/dist/{DataTable-HWZQGASI.js.map → DataTable-4GAVPIEG.js.map} +0 -0
  226. /package/dist/{chunk-ZTT2AXMX.js.map → chunk-KK73ZB4E.js.map} +0 -0
@@ -0,0 +1,566 @@
1
+ # Best Practices: Accessibility
2
+
3
+ > **📚 Best Practices**: Accessibility & WCAG Compliance | [← Back](./README.md) | [Implementation Guides](../implementation-guides/README.md)
4
+
5
+ Accessibility best practices for creating inclusive PACE Core applications that work for all users.
6
+
7
+ ---
8
+
9
+ **Last Updated**: 2025-02-08 | **Version**: v0.5.65+
10
+
11
+ ## Overview
12
+
13
+ PACE Core components are designed with accessibility in mind, following WCAG 2.1 AA standards. This guide helps you build accessible applications using PACE Core components.
14
+
15
+ ## Core Principles
16
+
17
+ ### Principle 1: Semantic HTML
18
+
19
+ **Why**: Screen readers rely on semantic HTML to understand page structure and content meaning.
20
+
21
+ **Implementation**:
22
+ ```tsx
23
+ // ✅ Good - Use semantic HTML
24
+ import { Button } from '@jmruthers/pace-core';
25
+
26
+ function MyComponent() {
27
+ return (
28
+ <main>
29
+ <h1>Page Title</h1>
30
+ <section>
31
+ <h2>Section Title</h2>
32
+ <p>Content here</p>
33
+ </section>
34
+ <Button aria-label="Submit form">Submit</Button>
35
+ </main>
36
+ );
37
+ }
38
+ ```
39
+
40
+ **Avoid**:
41
+ ```tsx
42
+ // ❌ Bad - Overuse of divs
43
+ <div>
44
+ <div className="title">Page Title</div>
45
+ <div>
46
+ <div className="section">Content</div>
47
+ </div>
48
+ </div>
49
+ ```
50
+
51
+ ### Principle 2: Keyboard Navigation
52
+
53
+ **Why**: Users who cannot use a mouse or prefer keyboard navigation must be able to access all interactive elements.
54
+
55
+ **Implementation**:
56
+ ```tsx
57
+ import { Button, DataTable } from '@jmruthers/pace-core';
58
+
59
+ // PACE Core components handle keyboard navigation automatically
60
+ function AccessibleTable() {
61
+ return (
62
+ <DataTable
63
+ data={data}
64
+ columns={columns}
65
+ features={{
66
+ // Keyboard navigation enabled by default
67
+ pagination: true,
68
+ sorting: true,
69
+ }}
70
+ />
71
+ );
72
+ }
73
+ ```
74
+
75
+ ### Principle 3: ARIA Labels and Roles
76
+
77
+ **Why**: Provide clear context for screen readers when visible text isn't sufficient.
78
+
79
+ **Implementation**:
80
+ ```tsx
81
+ import { Button, Icon } from '@jmruthers/pace-core';
82
+
83
+ function ActionButton({ onDelete }) {
84
+ return (
85
+ <Button
86
+ onClick={onDelete}
87
+ aria-label="Delete user"
88
+ aria-describedby="delete-help-text"
89
+ >
90
+ <Icon name="trash" aria-hidden="true" />
91
+ Delete
92
+ </Button>
93
+ );
94
+ }
95
+ ```
96
+
97
+ **Avoid**:
98
+ ```tsx
99
+ // ❌ Bad - Icon without label
100
+ <Button onClick={onDelete}>
101
+ <Icon name="trash" />
102
+ </Button>
103
+ ```
104
+
105
+ ## PACE Core Component Accessibility Features
106
+
107
+ ### DataTable Component
108
+
109
+ **Built-in accessibility**:
110
+ - ✅ Keyboard navigation (Tab, Enter, Arrow keys)
111
+ - ✅ ARIA roles and labels
112
+ - ✅ Screen reader announcements
113
+ - ✅ Focus management
114
+
115
+ **Example**:
116
+ ```tsx
117
+ import { DataTable } from '@jmruthers/pace-core';
118
+
119
+ function AccessibleDataTable() {
120
+ return (
121
+ <DataTable
122
+ data={data}
123
+ columns={columns}
124
+ aria-label="User data table"
125
+ features={{
126
+ search: true,
127
+ pagination: true,
128
+ }}
129
+ />
130
+ );
131
+ }
132
+ ```
133
+
134
+ ### Button Component
135
+
136
+ **Built-in accessibility**:
137
+ - ✅ Keyboard focusable
138
+ - ✅ Proper focus indicators
139
+ - ✅ ARIA attributes support
140
+
141
+ **Example**:
142
+ ```tsx
143
+ import { Button } from '@jmruthers/pace-core';
144
+
145
+ function AccessibleButton() {
146
+ return (
147
+ <Button
148
+ aria-label="Close dialog"
149
+ aria-describedby="close-help"
150
+ >
151
+ Close
152
+ <span id="close-help" className="sr-only">
153
+ Closes the current dialog
154
+ </span>
155
+ </Button>
156
+ );
157
+ }
158
+ ```
159
+
160
+ ### Form Components
161
+
162
+ **Built-in accessibility**:
163
+ - ✅ Label associations
164
+ - ✅ Error announcements
165
+ - ✅ Required field indicators
166
+ - ✅ Validation feedback
167
+
168
+ **Example**:
169
+ ```tsx
170
+ import { Input, Label, FormError } from '@jmruthers/pace-core';
171
+
172
+ function AccessibleForm() {
173
+ return (
174
+ <form aria-labelledby="form-title">
175
+ <h2 id="form-title">User Information</h2>
176
+
177
+ <div>
178
+ <Label htmlFor="email">Email Address</Label>
179
+ <Input
180
+ id="email"
181
+ type="email"
182
+ required
183
+ aria-required="true"
184
+ aria-describedby="email-error"
185
+ />
186
+ <FormError id="email-error" role="alert">
187
+ Please enter a valid email
188
+ </FormError>
189
+ </div>
190
+ </form>
191
+ );
192
+ }
193
+ ```
194
+
195
+ ### Dialog/Modal Components
196
+
197
+ **Built-in accessibility**:
198
+ - ✅ Focus trap management
199
+ - ✅ ESC key support
200
+ - ✅ ARIA roles and properties
201
+ - ✅ Screen reader announcements
202
+
203
+ **Example**:
204
+ ```tsx
205
+ import { Dialog, DialogTrigger, DialogContent } from '@jmruthers/pace-core';
206
+
207
+ function AccessibleDialog() {
208
+ return (
209
+ <Dialog>
210
+ <DialogTrigger aria-label="Open user settings">
211
+ Settings
212
+ </DialogTrigger>
213
+ <DialogContent
214
+ aria-labelledby="dialog-title"
215
+ aria-describedby="dialog-description"
216
+ >
217
+ <h2 id="dialog-title">User Settings</h2>
218
+ <p id="dialog-description">
219
+ Configure your account preferences
220
+ </p>
221
+ {/* Dialog content */}
222
+ </DialogContent>
223
+ </Dialog>
224
+ );
225
+ }
226
+ ```
227
+
228
+ ## Common Patterns
229
+
230
+ ### Pattern 1: Loading States with Announcements
231
+
232
+ **Use when**: Data is loading asynchronously
233
+
234
+ **Example**:
235
+ ```tsx
236
+ import { useUnifiedAuth } from '@jmruthers/pace-core';
237
+
238
+ function AccessibleUserProfile() {
239
+ const { user, loading, error } = useUnifiedAuth();
240
+
241
+ return (
242
+ <div role="status" aria-live="polite">
243
+ {loading && (
244
+ <div aria-busy="true">
245
+ <span className="sr-only">Loading user data</span>
246
+ Loading...
247
+ </div>
248
+ )}
249
+ {error && (
250
+ <div role="alert">
251
+ <span className="sr-only">Error loading user data</span>
252
+ Error: {error.message}
253
+ </div>
254
+ )}
255
+ {user && (
256
+ <div>
257
+ <h1>Welcome, {user.email}</h1>
258
+ </div>
259
+ )}
260
+ </div>
261
+ );
262
+ }
263
+ ```
264
+
265
+ ### Pattern 2: Skip Links
266
+
267
+ **Use when**: Creating long pages with repetitive navigation
268
+
269
+ **Example**:
270
+ ```tsx
271
+ function AccessibleLayout() {
272
+ return (
273
+ <div>
274
+ {/* Skip link */}
275
+ <a href="#main-content" className="skip-link">
276
+ Skip to main content
277
+ </a>
278
+
279
+ <Navigation />
280
+
281
+ <main id="main-content" tabIndex="-1">
282
+ <h1>Main Content</h1>
283
+ </main>
284
+
285
+ <Footer />
286
+ </div>
287
+ );
288
+ }
289
+ ```
290
+
291
+ ### Pattern 3: Focus Management
292
+
293
+ **Use when**: Opening modals or changing page context
294
+
295
+ **Example**:
296
+ ```tsx
297
+ import { useEffect, useRef } from 'react';
298
+ import { Dialog, DialogContent } from '@jmruthers/pace-core';
299
+
300
+ function AccessibleDialog({ isOpen, onClose }) {
301
+ const titleRef = useRef<HTMLHeadingElement>(null);
302
+
303
+ useEffect(() => {
304
+ if (isOpen && titleRef.current) {
305
+ // Focus the dialog title when it opens
306
+ titleRef.current.focus();
307
+ }
308
+ }, [isOpen]);
309
+
310
+ return (
311
+ <Dialog isOpen={isOpen} onClose={onClose}>
312
+ <DialogContent
313
+ aria-labelledby="dialog-title"
314
+ role="dialog"
315
+ aria-modal="true"
316
+ >
317
+ <h2 id="dialog-title" ref={titleRef} tabIndex={-1}>
318
+ Important Information
319
+ </h2>
320
+ {/* Dialog content */}
321
+ </DialogContent>
322
+ </Dialog>
323
+ );
324
+ }
325
+ ```
326
+
327
+ ### Pattern 4: Error Messages
328
+
329
+ **Use when**: Form validation errors or error states
330
+
331
+ **Example**:
332
+ ```tsx
333
+ import { Input, FormError } from '@jmruthers/pace-core';
334
+
335
+ function AccessibleForm() {
336
+ const [email, setEmail] = useState('');
337
+ const [error, setError] = useState('');
338
+
339
+ return (
340
+ <div>
341
+ <Label htmlFor="email">Email</Label>
342
+ <Input
343
+ id="email"
344
+ type="email"
345
+ value={email}
346
+ onChange={(e) => setEmail(e.target.value)}
347
+ aria-invalid={!!error}
348
+ aria-describedby={error ? "email-error" : undefined}
349
+ />
350
+ {error && (
351
+ <FormError id="email-error" role="alert">
352
+ {error}
353
+ </FormError>
354
+ )}
355
+ </div>
356
+ );
357
+ }
358
+ ```
359
+
360
+ ## Advanced Usage
361
+
362
+ ### Custom Accessibility Attributes
363
+
364
+ When PACE Core components need additional accessibility attributes:
365
+
366
+ ```tsx
367
+ import { Button, DataTable } from '@jmruthers/pace-core';
368
+
369
+ function AdvancedAccessibility() {
370
+ return (
371
+ <>
372
+ {/* Custom ARIA attributes */}
373
+ <Button
374
+ aria-label="Save changes"
375
+ aria-describedby="save-status"
376
+ aria-busy={isSaving}
377
+ >
378
+ Save
379
+ </Button>
380
+ <span id="save-status" className="sr-only">
381
+ {isSaving ? 'Saving' : 'Save'}
382
+ </span>
383
+
384
+ {/* DataTable with custom accessibility */}
385
+ <DataTable
386
+ data={data}
387
+ columns={columns}
388
+ aria-label="User management table"
389
+ aria-describedby="table-description"
390
+ />
391
+ <p id="table-description" className="sr-only">
392
+ Interactive table for managing users with sorting and filtering
393
+ </p>
394
+ </>
395
+ );
396
+ }
397
+ ```
398
+
399
+ ### Screen Reader Only Content
400
+
401
+ Use the `.sr-only` class for content that should only be visible to screen readers:
402
+
403
+ ```tsx
404
+ function ScreenReaderExample() {
405
+ return (
406
+ <Button aria-label="Download file">
407
+ <Icon name="download" aria-hidden="true" />
408
+ Download
409
+ <span className="sr-only">PDF document</span>
410
+ </Button>
411
+ );
412
+ }
413
+ ```
414
+
415
+ ### Live Regions for Dynamic Content
416
+
417
+ Use live regions for dynamic content updates:
418
+
419
+ ```tsx
420
+ import { useUnifiedAuth } from '@jmruthers/pace-core';
421
+
422
+ function LiveRegionExample() {
423
+ const { user } = useUnifiedAuth();
424
+
425
+ return (
426
+ <div role="region" aria-live="polite" aria-label="User status">
427
+ {user && (
428
+ <p>
429
+ Logged in as {user.email}
430
+ </p>
431
+ )}
432
+ </div>
433
+ );
434
+ }
435
+ ```
436
+
437
+ ## Testing Accessibility
438
+
439
+ ### Manual Testing Checklist
440
+
441
+ - [ ] **Keyboard Navigation**: All interactive elements accessible via keyboard
442
+ - [ ] **Focus Indicators**: Visible focus indicators on all interactive elements
443
+ - [ ] **Screen Reader**: Test with screen reader (NVDA, JAWS, VoiceOver)
444
+ - [ ] **Color Contrast**: Meet WCAG AA contrast ratios (4.5:1 for text, 3:1 for UI)
445
+ - [ ] **ARIA Labels**: All icons and images have appropriate labels
446
+ - [ ] **Semantic HTML**: Using proper HTML elements
447
+ - [ ] **Error Messages**: Properly associated with form fields
448
+
449
+ ### Automated Testing Tools
450
+
451
+ **Recommended tools**:
452
+ - **axe DevTools**: Browser extension for accessibility testing
453
+ - **WAVE**: Web accessibility evaluation tool
454
+ - **Lighthouse**: Accessibility auditing
455
+ - **Pa11y**: Command-line accessibility testing
456
+
457
+ **Example setup**:
458
+ ```bash
459
+ # Install Pa11y
460
+ npm install -g pa11y
461
+
462
+ # Run accessibility tests
463
+ pa11y http://localhost:3000
464
+ ```
465
+
466
+ ### Color Contrast
467
+
468
+ Ensure text meets contrast requirements:
469
+
470
+ ```tsx
471
+ // ✅ Good contrast
472
+ <p className="text-sec-800 bg-sec-50">
473
+ High contrast text
474
+ </p>
475
+
476
+ // ❌ Poor contrast
477
+ <p className="text-sec-300 bg-sec-400">
478
+ Low contrast text (hard to read)
479
+ </p>
480
+ ```
481
+
482
+ ## Common Issues and Solutions
483
+
484
+ ### Issue 1: Missing Focus Indicators
485
+
486
+ **Problem**: Interactive elements don't show visible focus state
487
+
488
+ **Solution**: Use PACE Core components which include focus styles, or add custom focus styles
489
+
490
+ ```css
491
+ /* Custom focus styles */
492
+ button:focus-visible {
493
+ outline: 2px solid var(--color-main-600);
494
+ outline-offset: 2px;
495
+ }
496
+ ```
497
+
498
+ ### Issue 2: Missing Alt Text
499
+
500
+ **Problem**: Images without alt text
501
+
502
+ **Solution**: Always provide meaningful alt text
503
+
504
+ ```tsx
505
+ // ✅ Good
506
+ <img src="user-avatar.jpg" alt="User profile picture" />
507
+
508
+ // ❌ Bad
509
+ <img src="user-avatar.jpg" />
510
+ ```
511
+
512
+ ### Issue 3: Form Labels Not Associated
513
+
514
+ **Problem**: Input fields without associated labels
515
+
516
+ **Solution**: Use proper label associations
517
+
518
+ ```tsx
519
+ // ✅ Good
520
+ <Label htmlFor="email">Email</Label>
521
+ <Input id="email" type="email" />
522
+
523
+ // ❌ Bad
524
+ <div>Email</div>
525
+ <Input type="email" />
526
+ ```
527
+
528
+ ## WCAG Compliance
529
+
530
+ ### Level AA Compliance
531
+
532
+ PACE Core components are designed to meet WCAG 2.1 Level AA standards:
533
+
534
+ - ✅ **Perceivable**: All information must be perceivable to users
535
+ - ✅ **Operable**: Interface components must be operable
536
+ - ✅ **Understandable**: Information and UI operation must be understandable
537
+ - ✅ **Robust**: Content must be robust enough to work with assistive technologies
538
+
539
+ ### Compliance Checklist
540
+
541
+ - [ ] **Color Contrast**: All text meets 4.5:1 contrast ratio
542
+ - [ ] **Keyboard Access**: All functionality available via keyboard
543
+ - [ ] **Focus Indicators**: Visible focus on all interactive elements
544
+ - [ ] **ARIA Labels**: Proper labels for all icons and images
545
+ - [ ] **Semantic HTML**: Using appropriate HTML elements
546
+ - [ ] **Error Messages**: Properly announced to screen readers
547
+ - [ ] **Live Regions**: Dynamic content properly announced
548
+
549
+ ## Related Documentation
550
+
551
+ - [Component API Reference](../api-reference/components.md)
552
+ - [Form Implementation Guide](../implementation-guides/forms.md)
553
+ - [DataTable Guide](../implementation-guides/data-tables.md)
554
+ - [Security Best Practices](./security.md)
555
+ - [Testing Best Practices](./testing.md)
556
+
557
+ ## Additional Resources
558
+
559
+ - [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
560
+ - [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
561
+ - [WebAIM Resources](https://webaim.org/)
562
+ - [MDN Accessibility Guide](https://developer.mozilla.org/en-US/docs/Web/Accessibility)
563
+
564
+ ---
565
+
566
+ **Next Steps**: Review your application's accessibility, implement missing ARIA attributes, and test with screen readers.