@a13y/devtools 0.1.0

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.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2024-2026 Diego Aneli and contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,278 @@
1
+ <div align="center">
2
+ <img src="https://raw.githubusercontent.com/DiegoAneli/a13y/main/assets/logo.svg" alt="A13Y Logo" width="150" />
3
+
4
+ <h1>@a13y/devtools</h1>
5
+
6
+ <p><strong>Development-time validators and runtime checks for @a13y</strong></p>
7
+ <p>Helpful warnings and error messages during development, automatically stripped in production.</p>
8
+
9
+ [![npm version](https://img.shields.io/npm/v/@a13y/devtools.svg)](https://www.npmjs.com/package/@a13y/devtools)
10
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
11
+ </div>
12
+
13
+ <br />
14
+
15
+ ## Features
16
+
17
+ - **Development-only** - Zero overhead in production (tree-shakeable)
18
+ - **WCAG references** - Every warning includes WCAG 2.2 criterion
19
+ - **Fix suggestions** - Actionable fixes with code examples
20
+ - **Runtime validation** - Catches accessibility issues during development
21
+ - **Type-safe** - Full TypeScript support
22
+
23
+ ## Installation
24
+
25
+ ```bash
26
+ npm install -D @a13y/devtools
27
+ ```
28
+
29
+ ## Usage
30
+
31
+ Devtools are automatically integrated when you use `@a13y/react` or `@a13y/core`. Simply install the package and warnings will appear in development.
32
+
33
+ ### Automatic Integration
34
+
35
+ ```typescript
36
+ import { useAccessibleButton } from '@a13y/react';
37
+
38
+ function Button() {
39
+ const { buttonProps } = useAccessibleButton({ onPress: () => {} });
40
+
41
+ // ⚠️ Warning in console if devtools installed:
42
+ // "Element is missing accessible label (WCAG 4.1.2)"
43
+ return <button {...buttonProps}></button>;
44
+ }
45
+ ```
46
+
47
+ ### Manual Validation
48
+
49
+ You can also use validators directly:
50
+
51
+ ```typescript
52
+ import { validateFocus, validateAria } from '@a13y/devtools/runtime/validators';
53
+
54
+ const button = document.querySelector('button');
55
+
56
+ // Validate focus management
57
+ validateFocus(button, {
58
+ hasFocusableElements: true,
59
+ isVisible: true,
60
+ });
61
+
62
+ // Validate ARIA attributes
63
+ validateAria(button, {
64
+ role: 'button',
65
+ requiredAttrs: ['aria-label'],
66
+ });
67
+ ```
68
+
69
+ ## Validators
70
+
71
+ ### Focus Validator
72
+
73
+ ```typescript
74
+ import { validateFocus } from '@a13y/devtools/runtime/validators';
75
+
76
+ validateFocus(element, {
77
+ hasFocusableElements: true,
78
+ isVisible: true,
79
+ isInert: false,
80
+ });
81
+ ```
82
+
83
+ Checks:
84
+ - Element has focusable children
85
+ - Focus trap contains interactive elements
86
+ - Elements are visible
87
+ - No inert ancestors
88
+
89
+ ### ARIA Validator
90
+
91
+ ```typescript
92
+ import { validateAria } from '@a13y/devtools/runtime/validators';
93
+
94
+ validateAria(element, {
95
+ role: 'dialog',
96
+ requiredAttrs: ['aria-labelledby', 'aria-describedby'],
97
+ allowedRoles: ['dialog', 'alertdialog'],
98
+ });
99
+ ```
100
+
101
+ Checks:
102
+ - Valid ARIA roles
103
+ - Required ARIA attributes present
104
+ - Attribute values are valid
105
+ - No conflicting attributes
106
+
107
+ ### Keyboard Validator
108
+
109
+ ```typescript
110
+ import { validateKeyboard } from '@a13y/devtools/runtime/validators';
111
+
112
+ validateKeyboard(element, {
113
+ supportsKeys: ['Enter', ' ', 'Escape'],
114
+ hasKeyboardHandler: true,
115
+ });
116
+ ```
117
+
118
+ Checks:
119
+ - Keyboard event handlers present
120
+ - Required keys supported
121
+ - Focus visible on keyboard navigation
122
+
123
+ ## Warning System
124
+
125
+ ### Warning Levels
126
+
127
+ ```typescript
128
+ import { warn, error } from '@a13y/devtools/runtime/warnings';
129
+
130
+ // Polite warning (logged to console)
131
+ warn('accessibility-issue', {
132
+ message: 'Missing accessible label',
133
+ wcagCriterion: '4.1.2',
134
+ fixes: [
135
+ 'Add aria-label attribute',
136
+ 'Add aria-labelledby reference',
137
+ 'Add visible text content',
138
+ ],
139
+ });
140
+
141
+ // Error (thrown in dev, silent in prod)
142
+ error('critical-accessibility-issue', {
143
+ message: 'Dialog missing required title',
144
+ wcagCriterion: '2.4.6',
145
+ });
146
+ ```
147
+
148
+ ### Warning Categories
149
+
150
+ - `focus` - Focus management issues
151
+ - `keyboard` - Keyboard navigation problems
152
+ - `aria` - ARIA attribute errors
153
+ - `structure` - DOM structure issues
154
+ - `semantics` - Semantic HTML problems
155
+
156
+ ## Invariants
157
+
158
+ Runtime checks that throw errors in development:
159
+
160
+ ```typescript
161
+ import { invariant } from '@a13y/devtools/runtime/invariants';
162
+
163
+ invariant(
164
+ element.hasAttribute('aria-label'),
165
+ 'Button must have accessible label',
166
+ 'WCAG 4.1.2'
167
+ );
168
+ ```
169
+
170
+ ## Production Builds
171
+
172
+ All devtools code is automatically removed in production:
173
+
174
+ ```typescript
175
+ // Development build
176
+ if (process.env.NODE_ENV !== 'production') {
177
+ validateFocus(element);
178
+ }
179
+
180
+ // Production build - entire block removed by bundler
181
+ // No runtime overhead!
182
+ ```
183
+
184
+ ## Configuration
185
+
186
+ Configure warning behavior:
187
+
188
+ ```typescript
189
+ import { configureWarnings } from '@a13y/devtools';
190
+
191
+ configureWarnings({
192
+ // Disable specific warnings
193
+ ignore: ['focus-trap-no-elements'],
194
+
195
+ // Throw errors instead of warnings
196
+ strict: true,
197
+
198
+ // Custom warning handler
199
+ onWarn: (warning) => {
200
+ console.log(`[A13Y] ${warning.message}`);
201
+ // Send to error tracking service
202
+ },
203
+ });
204
+ ```
205
+
206
+ ## TypeScript Support
207
+
208
+ Full TypeScript support with type definitions:
209
+
210
+ ```typescript
211
+ import type {
212
+ WarningType,
213
+ ValidationOptions,
214
+ WCAGCriterion,
215
+ } from '@a13y/devtools';
216
+ ```
217
+
218
+ ## Example Warnings
219
+
220
+ ### Missing Label
221
+
222
+ ```
223
+ ⚠️ A13Y Warning: Missing accessible label
224
+ Element: <button>Save</button>
225
+ WCAG: 4.1.2 Name, Role, Value
226
+
227
+ Suggested fixes:
228
+ 1. Add aria-label: <button aria-label="Save document">
229
+ 2. Add aria-labelledby: <button aria-labelledby="save-label">
230
+ 3. Ensure visible text is descriptive
231
+ ```
232
+
233
+ ### Invalid ARIA
234
+
235
+ ```
236
+ ⚠️ A13Y Warning: Invalid ARIA attribute value
237
+ Element: <div role="dialog" aria-expanded="yes">
238
+ WCAG: 4.1.2 Name, Role, Value
239
+
240
+ Issue: aria-expanded must be "true" or "false", not "yes"
241
+
242
+ Fix: <div role="dialog" aria-expanded="true">
243
+ ```
244
+
245
+ ### Focus Trap
246
+
247
+ ```
248
+ ⚠️ A13Y Warning: Focus trap has no focusable elements
249
+ Element: <div role="dialog">...</div>
250
+ WCAG: 2.1.1 Keyboard
251
+
252
+ Issue: Focus trap activated but contains no focusable elements
253
+
254
+ Suggested fixes:
255
+ 1. Add focusable elements (button, input, a, etc.)
256
+ 2. Add tabindex="0" to make element focusable
257
+ 3. Check if elements are hidden or disabled
258
+ ```
259
+
260
+ ## Tree Shaking
261
+
262
+ Import validators individually for optimal bundle size:
263
+
264
+ ```typescript
265
+ // ✅ Good - imports only focus validator
266
+ import { validateFocus } from '@a13y/devtools/runtime/validators';
267
+
268
+ // ❌ Avoid - imports all validators
269
+ import { validateFocus } from '@a13y/devtools';
270
+ ```
271
+
272
+ ## Author
273
+
274
+ Created and maintained by **Diego Aneli** ([@DiegoAneli](https://github.com/DiegoAneli))
275
+
276
+ ## License
277
+
278
+ MIT © Diego Aneli and contributors
@@ -0,0 +1,24 @@
1
+ import { WarningSystemConfig } from './runtime/warnings/index.js';
2
+ export { AccessibilityWarning, FixSuggestion, WCAGLevel, WCAGUrls, WarningCategory, WarningCodes, WarningSeverity, WarningSystem, createWarning } from './runtime/warnings/index.js';
3
+ export { assertFocusVisible, assertHasAccessibleName, assertKeyboardAccessible, assertValidAriaAttributes, assertValidTabindex, invariant } from './runtime/invariants/index.js';
4
+ export { AriaValidator, FocusValidator, KeyboardValidator, ariaValidator, focusValidator, keyboardValidator } from './runtime/validators/index.js';
5
+
6
+ /**
7
+ * @a13y/devtools - Development Tools
8
+ * Runtime validation and warnings for accessibility
9
+ * @packageDocumentation
10
+ */
11
+ declare const VERSION: "0.0.0";
12
+
13
+ /**
14
+ * Initialize devtools
15
+ * Starts all validators and warning system
16
+ */
17
+ declare const initDevtools: (config?: WarningSystemConfig) => void;
18
+ /**
19
+ * Destroy devtools
20
+ * Stops all validators
21
+ */
22
+ declare const destroyDevtools: () => void;
23
+
24
+ export { VERSION, WarningSystemConfig, destroyDevtools, initDevtools };