@accesslint/storybook-addon 0.8.10 → 0.8.12
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/README.md +32 -34
- package/dist/chunk-pbuEa-1d.js +13 -0
- package/dist/index.cjs +6 -116
- package/dist/index.d.cts +4 -4
- package/dist/index.d.ts +5 -4
- package/dist/index.js +6 -6
- package/dist/manager.d.ts +1 -0
- package/dist/manager.js +404 -395
- package/dist/matchers.cjs +10 -10
- package/dist/matchers.d.cts +2 -1
- package/dist/matchers.d.ts +2 -1
- package/dist/matchers.js +2 -1
- package/dist/portable.cjs +146 -105
- package/dist/portable.d.cts +37 -54
- package/dist/portable.d.ts +37 -54
- package/dist/portable.js +130 -104
- package/dist/preview-B3suakeJ.js +118 -0
- package/dist/preview-B8cvp9pY.cjs +148 -0
- package/dist/preview.cjs +6 -102
- package/dist/preview.d.cts +32 -17
- package/dist/preview.d.ts +32 -17
- package/dist/preview.js +2 -1
- package/dist/vitest-plugin.cjs +15 -27
- package/dist/vitest-plugin.d.cts +15 -14
- package/dist/vitest-plugin.d.ts +15 -14
- package/dist/vitest-plugin.js +14 -24
- package/dist/vitest-setup.cjs +131 -108
- package/dist/vitest-setup.d.cts +1 -2
- package/dist/vitest-setup.d.ts +1 -2
- package/dist/vitest-setup.js +127 -103
- package/package.json +86 -24
- package/dist/chunk-XTEGJNR3.js +0 -110
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
[](https://www.npmjs.com/package/@accesslint/storybook-addon)
|
|
2
|
-
[](https://github.com/AccessLint/accesslint/blob/main/storybook-addon/LICENSE)
|
|
3
3
|
|
|
4
4
|
# @accesslint/storybook-addon
|
|
5
5
|
|
|
@@ -7,13 +7,14 @@ Catch accessibility violations in your Storybook stories as you develop. Powered
|
|
|
7
7
|
|
|
8
8
|
<img height="414" alt="Storybook screenshot with alt text violation in the details of the AccessLint tab" src="https://github.com/user-attachments/assets/42bb12ee-3a07-4443-8b60-35c2c9c735a9" />
|
|
9
9
|
|
|
10
|
-
|
|
11
10
|
## Getting Started
|
|
12
11
|
|
|
13
12
|
```sh
|
|
14
13
|
npm install @accesslint/storybook-addon
|
|
15
14
|
```
|
|
16
15
|
|
|
16
|
+
`storybook` 9+ and `vitest` 3+ are required as peer dependencies.
|
|
17
|
+
|
|
17
18
|
Add the addon to your `.storybook/main.ts` (or `.storybook/main.js`):
|
|
18
19
|
|
|
19
20
|
```ts
|
|
@@ -104,7 +105,7 @@ test("LoginForm is accessible", () => {
|
|
|
104
105
|
|
|
105
106
|
```ts
|
|
106
107
|
await expect(canvasElement).toBeAccessible({
|
|
107
|
-
disabledRules: ["
|
|
108
|
+
disabledRules: ["landmarks/region"],
|
|
108
109
|
});
|
|
109
110
|
```
|
|
110
111
|
|
|
@@ -115,10 +116,10 @@ When the assertion fails, the error message lists each violation with its rule I
|
|
|
115
116
|
```
|
|
116
117
|
Expected element to have no accessibility violations, but found 2:
|
|
117
118
|
|
|
118
|
-
|
|
119
|
+
text-alternatives/img-alt [A] (1.1.1): Image is missing alt text
|
|
119
120
|
img[src="hero.png"]
|
|
120
121
|
|
|
121
|
-
|
|
122
|
+
labels-and-names/form-label [A] (1.3.1): Form input is missing a label
|
|
122
123
|
input[type="email"]
|
|
123
124
|
```
|
|
124
125
|
|
|
@@ -159,11 +160,11 @@ const preview = {
|
|
|
159
160
|
export default preview;
|
|
160
161
|
```
|
|
161
162
|
|
|
162
|
-
| Mode
|
|
163
|
-
|
|
|
164
|
-
| `"error"` | Violations fail the test (default)
|
|
165
|
-
| `"todo"`
|
|
166
|
-
| `"off"`
|
|
163
|
+
| Mode | Behavior |
|
|
164
|
+
| --------- | --------------------------------------------------------------------- |
|
|
165
|
+
| `"error"` | Violations fail the test (default) |
|
|
166
|
+
| `"todo"` | Violations show as warnings — yellow sidebar dots, non-blocking in CI |
|
|
167
|
+
| `"off"` | Skip auditing entirely |
|
|
167
168
|
|
|
168
169
|
Override per-story:
|
|
169
170
|
|
|
@@ -177,14 +178,14 @@ export const Experimental = {
|
|
|
177
178
|
|
|
178
179
|
### Disabling rules
|
|
179
180
|
|
|
180
|
-
|
|
181
|
+
Extend the addon's audit options from your preview file:
|
|
181
182
|
|
|
182
183
|
```ts
|
|
183
184
|
// .storybook/preview.ts
|
|
184
|
-
import {
|
|
185
|
+
import { setAuditOptions } from "@accesslint/storybook-addon/preview";
|
|
185
186
|
|
|
186
|
-
|
|
187
|
-
disabledRules: ["
|
|
187
|
+
setAuditOptions({
|
|
188
|
+
disabledRules: ["landmarks/region"], // e.g. disable landmark region rule
|
|
188
189
|
});
|
|
189
190
|
```
|
|
190
191
|
|
|
@@ -225,10 +226,7 @@ import { setProjectAnnotations } from "@storybook/react";
|
|
|
225
226
|
import { enableAccessLint } from "@accesslint/storybook-addon/portable";
|
|
226
227
|
import * as previewAnnotations from "./.storybook/preview";
|
|
227
228
|
|
|
228
|
-
const project = setProjectAnnotations([
|
|
229
|
-
previewAnnotations,
|
|
230
|
-
enableAccessLint(),
|
|
231
|
-
]);
|
|
229
|
+
const project = setProjectAnnotations([previewAnnotations, enableAccessLint()]);
|
|
232
230
|
|
|
233
231
|
beforeAll(project.beforeAll);
|
|
234
232
|
```
|
|
@@ -251,36 +249,36 @@ test("Primary button is accessible", async () => {
|
|
|
251
249
|
|
|
252
250
|
### Exports
|
|
253
251
|
|
|
254
|
-
| Entry point
|
|
255
|
-
|
|
|
256
|
-
| `@accesslint/storybook-addon`
|
|
252
|
+
| Entry point | Description |
|
|
253
|
+
| ------------------------------------------- | ----------------------------------------------------- |
|
|
254
|
+
| `@accesslint/storybook-addon` | Main addon registration (manager + preview) |
|
|
257
255
|
| `@accesslint/storybook-addon/vitest-plugin` | `accesslintTest()` Vite plugin for Vitest integration |
|
|
258
|
-
| `@accesslint/storybook-addon/vitest-setup`
|
|
259
|
-
| `@accesslint/storybook-addon/matchers`
|
|
260
|
-
| `@accesslint/storybook-addon/portable`
|
|
261
|
-
| `@accesslint/storybook-addon/preview`
|
|
256
|
+
| `@accesslint/storybook-addon/vitest-setup` | Setup file registered by the Vite plugin |
|
|
257
|
+
| `@accesslint/storybook-addon/matchers` | `toBeAccessible()` custom matcher |
|
|
258
|
+
| `@accesslint/storybook-addon/portable` | `enableAccessLint()` for portable stories |
|
|
259
|
+
| `@accesslint/storybook-addon/preview` | Preview annotations (afterEach hook) |
|
|
262
260
|
|
|
263
261
|
### `accesslintTest(options?)`
|
|
264
262
|
|
|
265
263
|
Vite plugin that registers AccessLint's `afterEach` annotation and the `toBeAccessible()` matcher for Vitest story tests.
|
|
266
264
|
|
|
267
|
-
| Option
|
|
268
|
-
|
|
|
265
|
+
| Option | Type | Description |
|
|
266
|
+
| ----------- | ---------- | -------------------------------------------------- |
|
|
269
267
|
| `tags.skip` | `string[]` | Stories with any of these tags will not be audited |
|
|
270
268
|
|
|
271
269
|
### `parameters.accesslint`
|
|
272
270
|
|
|
273
|
-
| Parameter | Type
|
|
274
|
-
|
|
|
275
|
-
| `test`
|
|
276
|
-
| `disable` | `boolean`
|
|
271
|
+
| Parameter | Type | Default | Description |
|
|
272
|
+
| --------- | ---------------------------- | --------- | ------------------------------------------------------ |
|
|
273
|
+
| `test` | `"todo" \| "error" \| "off"` | `"error"` | Controls how violations are reported |
|
|
274
|
+
| `disable` | `boolean` | `false` | Set to `true` to skip auditing (same as `test: "off"`) |
|
|
277
275
|
|
|
278
276
|
### `toBeAccessible(options?)`
|
|
279
277
|
|
|
280
278
|
Custom matcher for asserting an element has no accessibility violations.
|
|
281
279
|
|
|
282
|
-
| Option
|
|
283
|
-
|
|
|
280
|
+
| Option | Type | Description |
|
|
281
|
+
| --------------- | ---------- | ----------------------------------- |
|
|
284
282
|
| `disabledRules` | `string[]` | Rule IDs to skip for this assertion |
|
|
285
283
|
|
|
286
284
|
### `enableAccessLint()`
|
|
@@ -296,7 +294,7 @@ Returns AccessLint's preview annotations for use with `setProjectAnnotations` in
|
|
|
296
294
|
|
|
297
295
|
## Issues
|
|
298
296
|
|
|
299
|
-
Please report issues in the [AccessLint
|
|
297
|
+
Please report issues in the [AccessLint monorepo](https://github.com/AccessLint/accesslint/issues).
|
|
300
298
|
|
|
301
299
|
## License
|
|
302
300
|
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
//#region \0rolldown/runtime.js
|
|
2
|
+
var __defProp = Object.defineProperty;
|
|
3
|
+
var __exportAll = (all, no_symbols) => {
|
|
4
|
+
let target = {};
|
|
5
|
+
for (var name in all) __defProp(target, name, {
|
|
6
|
+
get: all[name],
|
|
7
|
+
enumerable: true
|
|
8
|
+
});
|
|
9
|
+
if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
|
|
10
|
+
return target;
|
|
11
|
+
};
|
|
12
|
+
//#endregion
|
|
13
|
+
export { __exportAll as t };
|
package/dist/index.cjs
CHANGED
|
@@ -1,116 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
var __defProp = Object.defineProperty;
|
|
8
|
-
var __export = (target, all) => {
|
|
9
|
-
for (var name in all)
|
|
10
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
11
|
-
};
|
|
12
|
-
|
|
13
|
-
// src/preview.ts
|
|
14
|
-
var preview_exports = {};
|
|
15
|
-
__export(preview_exports, {
|
|
16
|
-
afterEach: () => afterEach,
|
|
17
|
-
initialGlobals: () => initialGlobals,
|
|
18
|
-
parameters: () => parameters
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
// src/constants.ts
|
|
22
|
-
var ADDON_ID = "accesslint/a11y";
|
|
23
|
-
var RESULT_EVENT = `${ADDON_ID}/result`;
|
|
24
|
-
|
|
25
|
-
// src/preview.ts
|
|
26
|
-
var initialGlobals = {
|
|
27
|
-
accesslint: {}
|
|
28
|
-
};
|
|
29
|
-
var parameters = {
|
|
30
|
-
accesslint: {}
|
|
31
|
-
};
|
|
32
|
-
core.configureRules({
|
|
33
|
-
disabledRules: ["accesslint-045"]
|
|
34
|
-
});
|
|
35
|
-
var BUDGET_MS = 12;
|
|
36
|
-
function yieldToMain() {
|
|
37
|
-
return new Promise((resolve) => setTimeout(resolve, 0));
|
|
38
|
-
}
|
|
39
|
-
function scopeViolations(violations) {
|
|
40
|
-
const root = document.getElementById("storybook-root");
|
|
41
|
-
if (!root) return violations;
|
|
42
|
-
return violations.filter((v) => {
|
|
43
|
-
const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
|
|
44
|
-
try {
|
|
45
|
-
const el = document.querySelector(local);
|
|
46
|
-
return el && root.contains(el);
|
|
47
|
-
} catch {
|
|
48
|
-
return false;
|
|
49
|
-
}
|
|
50
|
-
});
|
|
51
|
-
}
|
|
52
|
-
function enrichViolations(violations) {
|
|
53
|
-
return violations.map((v) => {
|
|
54
|
-
const rule = core.getRuleById(v.ruleId);
|
|
55
|
-
return {
|
|
56
|
-
...v,
|
|
57
|
-
element: void 0,
|
|
58
|
-
// not serializable
|
|
59
|
-
description: rule?.description,
|
|
60
|
-
wcag: rule?.wcag,
|
|
61
|
-
level: rule?.level,
|
|
62
|
-
guidance: rule?.guidance
|
|
63
|
-
};
|
|
64
|
-
});
|
|
65
|
-
}
|
|
66
|
-
var afterEach = async ({
|
|
67
|
-
reporting,
|
|
68
|
-
parameters: parameters2,
|
|
69
|
-
viewMode,
|
|
70
|
-
tags,
|
|
71
|
-
id
|
|
72
|
-
}) => {
|
|
73
|
-
const accesslintParam = parameters2?.accesslint;
|
|
74
|
-
if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
|
|
75
|
-
if (viewMode !== "story") return;
|
|
76
|
-
const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
|
|
77
|
-
const allSkipTags = ["skip-accesslint", ...skipTags];
|
|
78
|
-
const matchedTag = tags?.find((t) => allSkipTags.includes(t));
|
|
79
|
-
if (matchedTag) {
|
|
80
|
-
const result2 = { skipped: true, reason: matchedTag };
|
|
81
|
-
previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
|
|
82
|
-
reporting.addReport({
|
|
83
|
-
type: "accesslint",
|
|
84
|
-
version: 1,
|
|
85
|
-
result: result2,
|
|
86
|
-
status: "passed"
|
|
87
|
-
});
|
|
88
|
-
return;
|
|
89
|
-
}
|
|
90
|
-
const audit = core.createChunkedAudit(document);
|
|
91
|
-
while (audit.processChunk(BUDGET_MS)) {
|
|
92
|
-
await yieldToMain();
|
|
93
|
-
}
|
|
94
|
-
const violations = audit.getViolations();
|
|
95
|
-
const scoped = scopeViolations(violations);
|
|
96
|
-
const enriched = enrichViolations(scoped);
|
|
97
|
-
const hasViolations = enriched.length > 0;
|
|
98
|
-
const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
|
|
99
|
-
const status = hasViolations ? mode : "passed";
|
|
100
|
-
const result = {
|
|
101
|
-
violations: enriched,
|
|
102
|
-
ruleCount: core.getActiveRules().length
|
|
103
|
-
};
|
|
104
|
-
previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
|
|
105
|
-
reporting.addReport({
|
|
106
|
-
type: "accesslint",
|
|
107
|
-
version: 1,
|
|
108
|
-
result,
|
|
109
|
-
status
|
|
110
|
-
});
|
|
111
|
-
};
|
|
112
|
-
|
|
113
|
-
// src/index.ts
|
|
114
|
-
var index_default = () => csf.definePreviewAddon(preview_exports);
|
|
115
|
-
|
|
116
|
-
module.exports = index_default;
|
|
1
|
+
const require_preview = require("./preview-B8cvp9pY.cjs");
|
|
2
|
+
let storybook_internal_csf = require("storybook/internal/csf");
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
var src_default = () => (0, storybook_internal_csf.definePreviewAddon)(require_preview.preview_exports);
|
|
5
|
+
//#endregion
|
|
6
|
+
module.exports = src_default;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _$storybook_internal_csf0 from "storybook/internal/csf";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
export
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
declare const _default: () => _$storybook_internal_csf0.PreviewAddon<_$storybook_internal_csf0.AddonTypes>;
|
|
5
|
+
export = _default;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
|
-
import * as
|
|
1
|
+
import * as _$storybook_internal_csf0 from "storybook/internal/csf";
|
|
2
2
|
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
3
|
+
//#region src/index.d.ts
|
|
4
|
+
declare const _default: () => _$storybook_internal_csf0.PreviewAddon<_$storybook_internal_csf0.AddonTypes>;
|
|
5
|
+
//#endregion
|
|
6
|
+
export { _default as default };
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { preview_exports } from
|
|
2
|
-
import { definePreviewAddon } from
|
|
3
|
-
|
|
4
|
-
var
|
|
5
|
-
|
|
6
|
-
export {
|
|
1
|
+
import { i as preview_exports } from "./preview-B3suakeJ.js";
|
|
2
|
+
import { definePreviewAddon } from "storybook/internal/csf";
|
|
3
|
+
//#region src/index.ts
|
|
4
|
+
var src_default = () => definePreviewAddon(preview_exports);
|
|
5
|
+
//#endregion
|
|
6
|
+
export { src_default as default };
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export { };
|