@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,604 +0,0 @@
1
- ---
2
- lastUpdated: 2025-11-18T17:00:00+11:00
3
- version: 0.5.181
4
- reviewedBy: documentation-standards-audit
5
- ---
6
-
7
- # Best Practices: Accessibility
8
-
9
- > **📚 Best Practices**: Accessibility & WCAG Compliance | [← Back](./README.md) | [Implementation Guides](../implementation-guides/README.md)
10
-
11
- Accessibility best practices for creating inclusive PACE Core applications that work for all users.
12
-
13
- ---
14
-
15
- **Last Updated**: 2025-02-08 | **Version**: v0.5.65+
16
-
17
- ## Overview
18
-
19
- 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.
20
-
21
- ## Core Principles
22
-
23
- ### Principle 1: Semantic HTML
24
-
25
- **Why**: Screen readers rely on semantic HTML to understand page structure and content meaning.
26
-
27
- **Implementation**:
28
- ```tsx
29
- // ✅ Good - Use semantic HTML
30
- import { Button } from '@jmruthers/pace-core';
31
-
32
- function MyComponent() {
33
- return (
34
- <main>
35
- <h1>Page Title</h1>
36
- <section>
37
- <h2>Section Title</h2>
38
- <p>Content here</p>
39
- </section>
40
- <Button aria-label="Submit form">Submit</Button>
41
- </main>
42
- );
43
- }
44
- ```
45
-
46
- **Avoid**:
47
- ```tsx
48
- // ❌ Bad - Overuse of divs
49
- <div>
50
- <div className="title">Page Title</div>
51
- <div>
52
- <div className="section">Content</div>
53
- </div>
54
- </div>
55
- ```
56
-
57
- ### Principle 2: Keyboard Navigation
58
-
59
- **Why**: Users who cannot use a mouse or prefer keyboard navigation must be able to access all interactive elements.
60
-
61
- **Implementation**:
62
- ```tsx
63
- import { Button, DataTable } from '@jmruthers/pace-core';
64
-
65
- // PACE Core components handle keyboard navigation automatically
66
- function AccessibleTable() {
67
- return (
68
- <DataTable
69
- data={data}
70
- columns={columns}
71
- features={{
72
- // Keyboard navigation enabled by default
73
- pagination: true,
74
- sorting: true,
75
- }}
76
- />
77
- );
78
- }
79
- ```
80
-
81
- ### Principle 3: ARIA Labels and Roles
82
-
83
- **Why**: Provide clear context for screen readers when visible text isn't sufficient.
84
-
85
- **Implementation**:
86
- ```tsx
87
- import { Button, Icon } from '@jmruthers/pace-core';
88
-
89
- function ActionButton({ onDelete }) {
90
- return (
91
- <Button
92
- onClick={onDelete}
93
- aria-label="Delete user"
94
- aria-describedby="delete-help-text"
95
- >
96
- <Icon name="trash" aria-hidden="true" />
97
- Delete
98
- </Button>
99
- );
100
- }
101
- ```
102
-
103
- **Avoid**:
104
- ```tsx
105
- // ❌ Bad - Icon without label
106
- <Button onClick={onDelete}>
107
- <Icon name="trash" />
108
- </Button>
109
- ```
110
-
111
- ## PACE Core Component Accessibility Features
112
-
113
- ### DataTable Component
114
-
115
- **Built-in accessibility**:
116
- - ✅ Keyboard navigation (Tab, Enter, Arrow keys)
117
- - ✅ ARIA roles and labels
118
- - ✅ Screen reader announcements
119
- - ✅ Focus management
120
-
121
- **Example**:
122
- ```tsx
123
- import { DataTable } from '@jmruthers/pace-core';
124
-
125
- function AccessibleDataTable() {
126
- return (
127
- <DataTable
128
- data={data}
129
- columns={columns}
130
- aria-label="User data table"
131
- features={{
132
- search: true,
133
- pagination: true,
134
- }}
135
- />
136
- );
137
- }
138
- ```
139
-
140
- ### Button Component
141
-
142
- **Built-in accessibility**:
143
- - ✅ Keyboard focusable via native HTML `<button>` element
144
- - ✅ Native keyboard support: `Enter` and `Space` keys automatically activate buttons (standard browser behavior)
145
- - ✅ Proper focus indicators via `focus-visible` styles
146
- - ✅ ARIA attributes support via `React.ButtonHTMLAttributes`
147
-
148
- **Keyboard Navigation**: The Button component uses native HTML `<button>` elements, which provide automatic keyboard accessibility. When a button is focused, pressing `Enter` or `Space` will trigger the button's `onClick` handler without requiring any custom keyboard event handlers. This is standard browser behavior and works out of the box.
149
-
150
- **Example**:
151
- ```tsx
152
- import { Button } from '@jmruthers/pace-core';
153
-
154
- function AccessibleButton() {
155
- return (
156
- <Button
157
- aria-label="Close dialog"
158
- aria-describedby="close-help"
159
- >
160
- Close
161
- <span id="close-help" className="sr-only">
162
- Closes the current dialog
163
- </span>
164
- </Button>
165
- );
166
- }
167
- ```
168
-
169
- ### Form Components
170
-
171
- **Built-in accessibility**:
172
- - ✅ Label associations
173
- - ✅ Error announcements
174
- - ✅ Required field indicators
175
- - ✅ Validation feedback
176
-
177
- **Example**:
178
- ```tsx
179
- import { Input, Label, FormError } from '@jmruthers/pace-core';
180
-
181
- function AccessibleForm() {
182
- return (
183
- <form aria-labelledby="form-title">
184
- <h2 id="form-title">User Information</h2>
185
-
186
- <div>
187
- <Label htmlFor="email">Email Address</Label>
188
- <Input
189
- id="email"
190
- type="email"
191
- required
192
- aria-required="true"
193
- aria-describedby="email-error"
194
- />
195
- <FormError id="email-error" role="alert">
196
- Please enter a valid email
197
- </FormError>
198
- </div>
199
- </form>
200
- );
201
- }
202
- ```
203
-
204
- ### Dialog/Modal Components
205
-
206
- **Built-in accessibility**:
207
- - ✅ Focus trap management
208
- - ✅ ESC key support
209
- - ✅ ARIA roles and properties
210
- - ✅ Screen reader announcements
211
-
212
- **Example**:
213
- ```tsx
214
- import { Dialog, DialogTrigger, DialogContent } from '@jmruthers/pace-core';
215
-
216
- function AccessibleDialog() {
217
- return (
218
- <Dialog>
219
- <DialogTrigger aria-label="Open user settings">
220
- Settings
221
- </DialogTrigger>
222
- <DialogContent
223
- aria-labelledby="dialog-title"
224
- aria-describedby="dialog-description"
225
- >
226
- <h2 id="dialog-title">User Settings</h2>
227
- <p id="dialog-description">
228
- Configure your account preferences
229
- </p>
230
- {/* Dialog content */}
231
- </DialogContent>
232
- </Dialog>
233
- );
234
- }
235
- ```
236
-
237
- ## Common Patterns
238
-
239
- ### Pattern 1: Loading States with Announcements
240
-
241
- **Use when**: Data is loading asynchronously
242
-
243
- **Example**:
244
- ```tsx
245
- import { useUnifiedAuth } from '@jmruthers/pace-core';
246
-
247
- function AccessibleUserProfile() {
248
- const { user, loading, error } = useUnifiedAuth();
249
-
250
- return (
251
- <div role="status" aria-live="polite">
252
- {loading && (
253
- <div aria-busy="true">
254
- <span className="sr-only">Loading user data</span>
255
- Loading...
256
- </div>
257
- )}
258
- {error && (
259
- <div role="alert">
260
- <span className="sr-only">Error loading user data</span>
261
- Error: {error.message}
262
- </div>
263
- )}
264
- {user && (
265
- <div>
266
- <h1>Welcome, {user.email}</h1>
267
- </div>
268
- )}
269
- </div>
270
- );
271
- }
272
- ```
273
-
274
- ### Pattern 2: Skip Links
275
-
276
- **Use when**: Creating long pages with repetitive navigation
277
-
278
- **Example**:
279
- ```tsx
280
- function AccessibleLayout() {
281
- return (
282
- <div>
283
- {/* Skip link */}
284
- <a href="#main-content" className="skip-link">
285
- Skip to main content
286
- </a>
287
-
288
- <Navigation />
289
-
290
- <main id="main-content" tabIndex="-1">
291
- <h1>Main Content</h1>
292
- </main>
293
-
294
- <Footer />
295
- </div>
296
- );
297
- }
298
- ```
299
-
300
- ### Pattern 3: Focus Management
301
-
302
- **Use when**: Opening modals or changing page context
303
-
304
- **Example**:
305
- ```tsx
306
- import { useEffect, useRef } from 'react';
307
- import { Dialog, DialogContent } from '@jmruthers/pace-core';
308
-
309
- function AccessibleDialog({ isOpen, onClose }) {
310
- const titleRef = useRef<HTMLHeadingElement>(null);
311
-
312
- useEffect(() => {
313
- if (isOpen && titleRef.current) {
314
- // Focus the dialog title when it opens
315
- titleRef.current.focus();
316
- }
317
- }, [isOpen]);
318
-
319
- return (
320
- <Dialog isOpen={isOpen} onClose={onClose}>
321
- <DialogContent
322
- aria-labelledby="dialog-title"
323
- role="dialog"
324
- aria-modal="true"
325
- >
326
- <h2 id="dialog-title" ref={titleRef} tabIndex={-1}>
327
- Important Information
328
- </h2>
329
- {/* Dialog content */}
330
- </DialogContent>
331
- </Dialog>
332
- );
333
- }
334
- ```
335
-
336
- ### Pattern 4: Error Messages
337
-
338
- **Use when**: Form validation errors or error states
339
-
340
- **Example**:
341
- ```tsx
342
- import { Input, FormError } from '@jmruthers/pace-core';
343
-
344
- function AccessibleForm() {
345
- const [email, setEmail] = useState('');
346
- const [error, setError] = useState('');
347
-
348
- return (
349
- <div>
350
- <Label htmlFor="email">Email</Label>
351
- <Input
352
- id="email"
353
- type="email"
354
- value={email}
355
- onChange={(e) => setEmail(e.target.value)}
356
- aria-invalid={!!error}
357
- aria-describedby={error ? "email-error" : undefined}
358
- />
359
- {error && (
360
- <FormError id="email-error" role="alert">
361
- {error}
362
- </FormError>
363
- )}
364
- </div>
365
- );
366
- }
367
- ```
368
-
369
- ## Advanced Usage
370
-
371
- ### Custom Accessibility Attributes
372
-
373
- When PACE Core components need additional accessibility attributes:
374
-
375
- ```tsx
376
- import { Button, DataTable } from '@jmruthers/pace-core';
377
-
378
- function AdvancedAccessibility() {
379
- return (
380
- <>
381
- {/* Custom ARIA attributes */}
382
- <Button
383
- aria-label="Save changes"
384
- aria-describedby="save-status"
385
- aria-busy={isSaving}
386
- >
387
- Save
388
- </Button>
389
- <span id="save-status" className="sr-only">
390
- {isSaving ? 'Saving' : 'Save'}
391
- </span>
392
-
393
- {/* DataTable with custom accessibility */}
394
- <DataTable
395
- data={data}
396
- columns={columns}
397
- aria-label="User management table"
398
- aria-describedby="table-description"
399
- />
400
- <p id="table-description" className="sr-only">
401
- Interactive table for managing users with sorting and filtering
402
- </p>
403
- </>
404
- );
405
- }
406
- ```
407
-
408
- ### Screen Reader Only Content
409
-
410
- Use the `.sr-only` class for content that should only be visible to screen readers:
411
-
412
- ```tsx
413
- function ScreenReaderExample() {
414
- return (
415
- <Button aria-label="Download file">
416
- <Icon name="download" aria-hidden="true" />
417
- Download
418
- <span className="sr-only">PDF document</span>
419
- </Button>
420
- );
421
- }
422
- ```
423
-
424
- ### Live Regions for Dynamic Content
425
-
426
- Use live regions for dynamic content updates:
427
-
428
- ```tsx
429
- import { useUnifiedAuth } from '@jmruthers/pace-core';
430
-
431
- function LiveRegionExample() {
432
- const { user } = useUnifiedAuth();
433
-
434
- return (
435
- <div role="region" aria-live="polite" aria-label="User status">
436
- {user && (
437
- <p>
438
- Logged in as {user.email}
439
- </p>
440
- )}
441
- </div>
442
- );
443
- }
444
- ```
445
-
446
- ## Testing Accessibility
447
-
448
- ### Manual Testing Checklist
449
-
450
- - [ ] **Keyboard Navigation**: All interactive elements accessible via keyboard
451
- - [ ] **Focus Indicators**: Visible focus indicators on all interactive elements
452
- - [ ] **Screen Reader**: Test with screen reader (NVDA, JAWS, VoiceOver)
453
- - [ ] **Color Contrast**: Meet WCAG AA contrast ratios (4.5:1 for text, 3:1 for UI)
454
- - [ ] **ARIA Labels**: All icons and images have appropriate labels
455
- - [ ] **Semantic HTML**: Using proper HTML elements
456
- - [ ] **Error Messages**: Properly associated with form fields
457
-
458
- ### Automated Testing Tools
459
-
460
- **Recommended tools**:
461
- - **axe DevTools**: Browser extension for accessibility testing
462
- - **WAVE**: Web accessibility evaluation tool
463
- - **Lighthouse**: Accessibility auditing
464
- - **Pa11y**: Command-line accessibility testing
465
-
466
- **Example setup**:
467
- ```bash
468
- # Install Pa11y
469
- npm install -g pa11y
470
-
471
- # Run accessibility tests
472
- pa11y http://localhost:3000
473
- ```
474
-
475
- ### Color Contrast
476
-
477
- Ensure text meets contrast requirements:
478
-
479
- ```tsx
480
- // ✅ Good contrast
481
- <p className="text-sec-800 bg-sec-50">
482
- High contrast text
483
- </p>
484
-
485
- // ❌ Poor contrast
486
- <p className="text-sec-300 bg-sec-400">
487
- Low contrast text (hard to read)
488
- </p>
489
- ```
490
-
491
- ## Common Issues and Solutions
492
-
493
- ### Issue 1: Missing Focus Indicators
494
-
495
- **Problem**: Interactive elements don't show visible focus state
496
-
497
- **Solution**: Use PACE Core components which include focus styles, or add custom focus styles
498
-
499
- ```css
500
- /* Custom focus styles */
501
- button:focus-visible {
502
- outline: 2px solid var(--color-main-600);
503
- outline-offset: 2px;
504
- }
505
- ```
506
-
507
- ### Issue 2: Missing Alt Text
508
-
509
- **Problem**: Images without alt text
510
-
511
- **Solution**: Always provide meaningful alt text
512
-
513
- ```tsx
514
- // ✅ Good
515
- <img src="user-avatar.jpg" alt="User profile picture" />
516
-
517
- // ❌ Bad
518
- <img src="user-avatar.jpg" />
519
- ```
520
-
521
- ### Issue 3: Form Labels Not Associated
522
-
523
- **Problem**: Input fields without associated labels
524
-
525
- **Solution**: Use proper label associations
526
-
527
- ```tsx
528
- // ✅ Good
529
- <Label htmlFor="email">Email</Label>
530
- <Input id="email" type="email" />
531
-
532
- // ❌ Bad
533
- <div>Email</div>
534
- <Input type="email" />
535
- ```
536
-
537
- ## WCAG Compliance
538
-
539
- ### Level AA Compliance
540
-
541
- PACE Core components are designed to meet WCAG 2.1 Level AA standards:
542
-
543
- - ✅ **Perceivable**: All information must be perceivable to users
544
- - ✅ **Operable**: Interface components must be operable
545
- - ✅ **Understandable**: Information and UI operation must be understandable
546
- - ✅ **Robust**: Content must be robust enough to work with assistive technologies
547
-
548
- ### Compliance Checklist
549
-
550
- - [ ] **Color Contrast**: All text meets 4.5:1 contrast ratio
551
- - [ ] **Keyboard Access**: All functionality available via keyboard
552
- - [ ] **Focus Indicators**: Visible focus on all interactive elements
553
- - [ ] **ARIA Labels**: Proper labels for all icons and images
554
- - [ ] **Semantic HTML**: Using appropriate HTML elements
555
- - [ ] **Error Messages**: Properly announced to screen readers
556
- - [ ] **Live Regions**: Dynamic content properly announced
557
-
558
- ## Related Documentation
559
-
560
- - [Component API Reference](../api-reference/components.md)
561
- - [Form Implementation Guide](../implementation-guides/forms.md)
562
- - [DataTable Guide](../implementation-guides/data-tables.md)
563
- - [Security Best Practices](./security.md)
564
- - [Testing Best Practices](./testing.md)
565
-
566
- ## Additional Resources
567
-
568
- - [WCAG 2.1 Guidelines](https://www.w3.org/WAI/WCAG21/quickref/)
569
- - [ARIA Authoring Practices](https://www.w3.org/WAI/ARIA/apg/)
570
- - [WebAIM Resources](https://webaim.org/)
571
- - [MDN Accessibility Guide](https://developer.mozilla.org/en-US/docs/Web/Accessibility)
572
-
573
- ---
574
-
575
- **Next Steps**: Review your application's accessibility, implement missing ARIA attributes, and test with screen readers.
576
-
577
- ## ⚠️ Edge Cases
578
-
579
- ### Accessibility vs Performance
580
-
581
- When accessibility features impact performance:
582
- - Optimize ARIA live regions to reduce re-renders
583
- - Use efficient focus management techniques
584
- - Balance screen reader announcements with performance
585
- - Test performance with assistive technologies enabled
586
- - Profile accessibility features for bottlenecks
587
-
588
- ### Complex Accessibility Scenarios
589
-
590
- When dealing with complex accessibility requirements:
591
- - Test with multiple screen reader combinations
592
- - Verify keyboard navigation in complex UIs
593
- - Ensure focus management in dynamic content
594
- - Test with different assistive technology configurations
595
- - Document accessibility patterns for complex components
596
-
597
- ### Third-Party Component Accessibility
598
-
599
- When using third-party components:
600
- - Verify third-party components meet accessibility standards
601
- - Add wrapper components for accessibility improvements
602
- - Test third-party integrations with assistive technologies
603
- - Document accessibility limitations
604
- - Provide alternatives when components aren't accessible