@accesslint/storybook-addon 0.8.3 → 0.8.4

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 CHANGED
@@ -5,7 +5,8 @@
5
5
 
6
6
  Catch accessibility violations in your Storybook stories as you develop. Powered by [@accesslint/core](https://accesslint.com/core).
7
7
 
8
- <img width="637" height="414" alt="Storybook screenshot with alt text violation in the details of the AccessLint tab" src="https://github.com/user-attachments/assets/01d2de92-0769-4564-8971-f6edc1986010" />
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
 
10
11
  ## Getting Started
11
12
 
@@ -25,6 +26,8 @@ export default config;
25
26
 
26
27
  Restart Storybook and an **AccessLint** panel will appear in the addon bar. Every story is audited automatically after it renders.
27
28
 
29
+ Expand any violation to see the failing element, WCAG criteria, and remediation guidance. Click **Highlight** to outline the element in the preview.
30
+
28
31
  ## Vitest integration
29
32
 
30
33
  If you use [`@storybook/addon-vitest`](https://storybook.js.org/docs/writing-tests/vitest-plugin), add the AccessLint plugin next to `storybookTest()` in your Vite config:
@@ -187,18 +190,18 @@ configureRules({
187
190
 
188
191
  ### Skipping stories with tags
189
192
 
190
- Tag individual stories or entire components with `"no-a11y"` to skip auditing:
193
+ Tag individual stories or entire components with `"skip-accesslint"` to skip auditing:
191
194
 
192
195
  ```ts
193
196
  // Skip a single story
194
197
  export const Prototype = {
195
- tags: ["no-a11y"],
198
+ tags: ["skip-accesslint"],
196
199
  };
197
200
 
198
201
  // Skip all stories for a component
199
202
  export default {
200
203
  component: ExperimentalWidget,
201
- tags: ["no-a11y"],
204
+ tags: ["skip-accesslint"],
202
205
  };
203
206
  ```
204
207
 
@@ -206,7 +209,7 @@ With the Vitest plugin, you can also define custom skip tags:
206
209
 
207
210
  ```ts
208
211
  accesslintTest({
209
- tags: { skip: ["no-a11y", "wip"] },
212
+ tags: { skip: ["skip-accesslint", "wip"] },
210
213
  });
211
214
  ```
212
215
 
package/dist/manager.js CHANGED
@@ -2,7 +2,7 @@ import React, { useMemo, useState, useRef, useCallback } from 'react';
2
2
  import * as managerApi from 'storybook/internal/manager-api';
3
3
  import { useChannel } from 'storybook/internal/manager-api';
4
4
  import { styled, useTheme } from 'storybook/internal/theming';
5
- import { STORY_CHANGED, STORY_FINISHED } from 'storybook/internal/core-events';
5
+ import { STORY_CHANGED } from 'storybook/internal/core-events';
6
6
 
7
7
  var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
8
  get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
@@ -15,6 +15,10 @@ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require
15
15
  var ADDON_ID = "accesslint/a11y";
16
16
  var PARAM_KEY = "accesslint";
17
17
  var STATUS_TYPE_ID = "accesslint/a11y";
18
+ var RESULT_EVENT = `${ADDON_ID}/result`;
19
+ var HIGHLIGHT_ADDON_ID = "storybook/highlight";
20
+ var HIGHLIGHT = `${HIGHLIGHT_ADDON_ID}/add`;
21
+ var REMOVE_HIGHLIGHT = `${HIGHLIGHT_ADDON_ID}/remove`;
18
22
  var IMPACT_COLOR = {
19
23
  critical: "#d32f2f",
20
24
  serious: "#d32f2f",
@@ -58,29 +62,30 @@ var Panel = ({ active }) => {
58
62
  const [ruleCount, setRuleCount] = useState(0);
59
63
  const [skippedReason, setSkippedReason] = useState(null);
60
64
  const [expandedIndex, setExpandedIndex] = useState(null);
65
+ const [highlightedIndex, setHighlightedIndex] = useState(null);
61
66
  const buttonRefs = useRef([]);
62
- useChannel({
63
- [STORY_FINISHED]: ({ reporters }) => {
64
- const report = reporters.find((r) => r.type === "accesslint");
65
- if (!report) return;
66
- const result = report.result;
67
+ const emit = useChannel({
68
+ [RESULT_EVENT]: ({ result }) => {
67
69
  if (result.skipped) {
68
70
  setViolations([]);
69
71
  setRuleCount(0);
70
72
  setSkippedReason(result.reason ?? "skipped");
71
73
  setExpandedIndex(null);
74
+ setHighlightedIndex(null);
72
75
  return;
73
76
  }
74
77
  setViolations(result.violations ?? []);
75
78
  setRuleCount(result.ruleCount ?? 0);
76
79
  setSkippedReason(null);
77
80
  setExpandedIndex(null);
81
+ setHighlightedIndex(null);
78
82
  },
79
83
  [STORY_CHANGED]: () => {
80
84
  setViolations([]);
81
85
  setRuleCount(0);
82
86
  setSkippedReason(null);
83
87
  setExpandedIndex(null);
88
+ setHighlightedIndex(null);
84
89
  }
85
90
  });
86
91
  const sorted = useMemo(
@@ -133,7 +138,13 @@ var Panel = ({ active }) => {
133
138
  buttonRefs.current[i] = el;
134
139
  },
135
140
  type: "button",
136
- onClick: () => setExpandedIndex(isOpen ? null : i),
141
+ onClick: () => {
142
+ setExpandedIndex(isOpen ? null : i);
143
+ if (highlightedIndex !== null) {
144
+ emit(REMOVE_HIGHLIGHT);
145
+ setHighlightedIndex(null);
146
+ }
147
+ },
137
148
  onKeyDown: (e) => handleKeyDown(e, i),
138
149
  "aria-expanded": isOpen,
139
150
  style: {
@@ -186,7 +197,38 @@ var Panel = ({ active }) => {
186
197
  }
187
198
  },
188
199
  ref
189
- ))), v.guidance && /* @__PURE__ */ React.createElement("div", { style: { marginBottom: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: { fontSize: "11px", fontWeight: 500, color: colors.textMuted, marginBottom: "4px" } }, "How to fix"), /* @__PURE__ */ React.createElement("p", { style: { margin: 0, fontSize: "12px", color: colors.text, whiteSpace: "pre-wrap" } }, v.guidance)), v.html && /* @__PURE__ */ React.createElement("div", { style: { marginBottom: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: { fontSize: "11px", fontWeight: 500, color: colors.textMuted, marginBottom: "4px" } }, "Element"), /* @__PURE__ */ React.createElement(
200
+ ))), v.guidance && /* @__PURE__ */ React.createElement("div", { style: { marginBottom: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: { fontSize: "11px", fontWeight: 500, color: colors.textMuted, marginBottom: "4px" } }, "How to fix"), /* @__PURE__ */ React.createElement("p", { style: { margin: 0, fontSize: "12px", color: colors.text, whiteSpace: "pre-wrap" } }, v.guidance)), v.html && /* @__PURE__ */ React.createElement("div", { style: { marginBottom: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", marginBottom: "4px" } }, /* @__PURE__ */ React.createElement("div", { style: { fontSize: "11px", fontWeight: 500, color: colors.textMuted } }, "Element"), /* @__PURE__ */ React.createElement(
201
+ "button",
202
+ {
203
+ type: "button",
204
+ onClick: () => {
205
+ if (highlightedIndex === i) {
206
+ emit(REMOVE_HIGHLIGHT);
207
+ setHighlightedIndex(null);
208
+ } else {
209
+ const color = v.impact === "critical" || v.impact === "serious" ? "#d32f2f" : "#c43e00";
210
+ const localSelector = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
211
+ emit(HIGHLIGHT, {
212
+ elements: [localSelector],
213
+ color,
214
+ style: "solid"
215
+ });
216
+ setHighlightedIndex(i);
217
+ }
218
+ },
219
+ style: {
220
+ padding: "2px 8px",
221
+ fontSize: "11px",
222
+ fontWeight: 500,
223
+ border: `1px solid ${colors.codeBorder}`,
224
+ borderRadius: "4px",
225
+ background: highlightedIndex === i ? IMPACT_COLOR[v.impact] : colors.codeBg,
226
+ color: highlightedIndex === i ? "#fff" : colors.text,
227
+ cursor: "pointer"
228
+ }
229
+ },
230
+ "Highlight"
231
+ )), /* @__PURE__ */ React.createElement(
190
232
  "pre",
191
233
  {
192
234
  style: {
@@ -234,10 +276,8 @@ try {
234
276
  var Title = () => {
235
277
  const [count, setCount] = React.useState(0);
236
278
  useChannel2({
237
- [STORY_FINISHED]: ({ reporters }) => {
238
- const report = reporters.find((r) => r.type === "accesslint");
239
- const violations = report?.result?.violations;
240
- setCount(violations?.length ?? 0);
279
+ [RESULT_EVENT]: ({ result }) => {
280
+ setCount(result.skipped ? 0 : result.violations?.length ?? 0);
241
281
  }
242
282
  });
243
283
  return /* @__PURE__ */ React.createElement(React.Fragment, null, "AccessLint", count > 0 && /* @__PURE__ */ React.createElement("span", { style: {
@@ -286,20 +326,18 @@ var TestProviderWidget = () => {
286
326
  return unsub;
287
327
  }, [api]);
288
328
  useChannel2({
289
- [STORY_FINISHED]: ({ storyId, reporters }) => {
290
- const report = reporters.find((r) => r.type === "accesslint");
291
- if (!report) return;
292
- const violations = report.result?.violations ?? [];
329
+ [RESULT_EVENT]: ({ storyId, result, status: status2 }) => {
330
+ const violations = result.skipped ? [] : result.violations ?? [];
293
331
  setViolationCount(violations.length);
294
- if (statusStore) {
332
+ if (statusStore && storyId) {
295
333
  const hasViolations2 = violations.length > 0;
296
- const isWarning = report.status === "warning";
334
+ const isWarning = status2 === "warning";
297
335
  statusStore.set([{
298
- value: hasViolations2 ? isWarning ? "status-value:warning" : "status-value:error" : "status-value:success",
336
+ value: result.skipped ? "status-value:unknown" : hasViolations2 ? isWarning ? "status-value:warning" : "status-value:error" : "status-value:success",
299
337
  typeId: STATUS_TYPE_ID,
300
338
  storyId,
301
339
  title: "AccessLint",
302
- description: hasViolations2 ? `${violations.length} violation${violations.length === 1 ? "" : "s"}` : "No violations",
340
+ description: result.skipped ? "Skipped" : hasViolations2 ? `${violations.length} violation${violations.length === 1 ? "" : "s"}` : "No violations",
303
341
  sidebarContextMenu: true
304
342
  }]);
305
343
  }
package/dist/portable.cjs CHANGED
@@ -1,6 +1,7 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@accesslint/core');
4
+ var previewApi = require('storybook/preview-api');
4
5
 
5
6
  var __defProp = Object.defineProperty;
6
7
  var __export = (target, all) => {
@@ -13,6 +14,12 @@ var preview_exports = {};
13
14
  __export(preview_exports, {
14
15
  afterEach: () => afterEach
15
16
  });
17
+
18
+ // src/constants.ts
19
+ var ADDON_ID = "accesslint/a11y";
20
+ var RESULT_EVENT = `${ADDON_ID}/result`;
21
+
22
+ // src/preview.ts
16
23
  core.configureRules({
17
24
  disabledRules: ["accesslint-045"]
18
25
  });
@@ -51,19 +58,22 @@ var afterEach = async ({
51
58
  reporting,
52
59
  parameters,
53
60
  viewMode,
54
- tags
61
+ tags,
62
+ id
55
63
  }) => {
56
64
  const accesslintParam = parameters?.accesslint;
57
65
  if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
58
66
  if (viewMode !== "story") return;
59
67
  const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
60
- const allSkipTags = ["no-a11y", ...skipTags];
68
+ const allSkipTags = ["skip-accesslint", ...skipTags];
61
69
  const matchedTag = tags?.find((t) => allSkipTags.includes(t));
62
70
  if (matchedTag) {
71
+ const result2 = { skipped: true, reason: matchedTag };
72
+ previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
63
73
  reporting.addReport({
64
74
  type: "accesslint",
65
75
  version: 1,
66
- result: { skipped: true, reason: matchedTag },
76
+ result: result2,
67
77
  status: "passed"
68
78
  });
69
79
  return;
@@ -77,14 +87,17 @@ var afterEach = async ({
77
87
  const enriched = enrichViolations(scoped);
78
88
  const hasViolations = enriched.length > 0;
79
89
  const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
90
+ const status = hasViolations ? mode : "passed";
91
+ const result = {
92
+ violations: enriched,
93
+ ruleCount: core.getActiveRules().length
94
+ };
95
+ previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
80
96
  reporting.addReport({
81
97
  type: "accesslint",
82
98
  version: 1,
83
- result: {
84
- violations: enriched,
85
- ruleCount: core.getActiveRules().length
86
- },
87
- status: hasViolations ? mode : "passed"
99
+ result,
100
+ status
88
101
  });
89
102
  };
90
103
 
@@ -1,10 +1,11 @@
1
- declare const afterEach: ({ reporting, parameters, viewMode, tags, }: {
1
+ declare const afterEach: ({ reporting, parameters, viewMode, tags, id, }: {
2
2
  reporting: {
3
3
  addReport: (report: Record<string, unknown>) => void;
4
4
  };
5
5
  parameters: Record<string, unknown>;
6
6
  viewMode: string;
7
7
  tags?: string[];
8
+ id?: string;
8
9
  }) => Promise<void>;
9
10
 
10
11
  declare const accesslintAnnotations_afterEach: typeof afterEach;
@@ -1,10 +1,11 @@
1
- declare const afterEach: ({ reporting, parameters, viewMode, tags, }: {
1
+ declare const afterEach: ({ reporting, parameters, viewMode, tags, id, }: {
2
2
  reporting: {
3
3
  addReport: (report: Record<string, unknown>) => void;
4
4
  };
5
5
  parameters: Record<string, unknown>;
6
6
  viewMode: string;
7
7
  tags?: string[];
8
+ id?: string;
8
9
  }) => Promise<void>;
9
10
 
10
11
  declare const accesslintAnnotations_afterEach: typeof afterEach;
package/dist/portable.js CHANGED
@@ -1,4 +1,5 @@
1
1
  import { configureRules, createChunkedAudit, getActiveRules, getRuleById } from '@accesslint/core';
2
+ import { addons } from 'storybook/preview-api';
2
3
 
3
4
  var __defProp = Object.defineProperty;
4
5
  var __export = (target, all) => {
@@ -11,6 +12,12 @@ var preview_exports = {};
11
12
  __export(preview_exports, {
12
13
  afterEach: () => afterEach
13
14
  });
15
+
16
+ // src/constants.ts
17
+ var ADDON_ID = "accesslint/a11y";
18
+ var RESULT_EVENT = `${ADDON_ID}/result`;
19
+
20
+ // src/preview.ts
14
21
  configureRules({
15
22
  disabledRules: ["accesslint-045"]
16
23
  });
@@ -49,19 +56,22 @@ var afterEach = async ({
49
56
  reporting,
50
57
  parameters,
51
58
  viewMode,
52
- tags
59
+ tags,
60
+ id
53
61
  }) => {
54
62
  const accesslintParam = parameters?.accesslint;
55
63
  if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
56
64
  if (viewMode !== "story") return;
57
65
  const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
58
- const allSkipTags = ["no-a11y", ...skipTags];
66
+ const allSkipTags = ["skip-accesslint", ...skipTags];
59
67
  const matchedTag = tags?.find((t) => allSkipTags.includes(t));
60
68
  if (matchedTag) {
69
+ const result2 = { skipped: true, reason: matchedTag };
70
+ addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
61
71
  reporting.addReport({
62
72
  type: "accesslint",
63
73
  version: 1,
64
- result: { skipped: true, reason: matchedTag },
74
+ result: result2,
65
75
  status: "passed"
66
76
  });
67
77
  return;
@@ -75,14 +85,17 @@ var afterEach = async ({
75
85
  const enriched = enrichViolations(scoped);
76
86
  const hasViolations = enriched.length > 0;
77
87
  const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
88
+ const status = hasViolations ? mode : "passed";
89
+ const result = {
90
+ violations: enriched,
91
+ ruleCount: getActiveRules().length
92
+ };
93
+ addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
78
94
  reporting.addReport({
79
95
  type: "accesslint",
80
96
  version: 1,
81
- result: {
82
- violations: enriched,
83
- ruleCount: getActiveRules().length
84
- },
85
- status: hasViolations ? mode : "passed"
97
+ result,
98
+ status
86
99
  });
87
100
  };
88
101
 
package/dist/preview.cjs CHANGED
@@ -1,6 +1,13 @@
1
1
  'use strict';
2
2
 
3
3
  var core = require('@accesslint/core');
4
+ var previewApi = require('storybook/preview-api');
5
+
6
+ // src/preview.ts
7
+
8
+ // src/constants.ts
9
+ var ADDON_ID = "accesslint/a11y";
10
+ var RESULT_EVENT = `${ADDON_ID}/result`;
4
11
 
5
12
  // src/preview.ts
6
13
  core.configureRules({
@@ -41,19 +48,22 @@ var afterEach = async ({
41
48
  reporting,
42
49
  parameters,
43
50
  viewMode,
44
- tags
51
+ tags,
52
+ id
45
53
  }) => {
46
54
  const accesslintParam = parameters?.accesslint;
47
55
  if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
48
56
  if (viewMode !== "story") return;
49
57
  const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
50
- const allSkipTags = ["no-a11y", ...skipTags];
58
+ const allSkipTags = ["skip-accesslint", ...skipTags];
51
59
  const matchedTag = tags?.find((t) => allSkipTags.includes(t));
52
60
  if (matchedTag) {
61
+ const result2 = { skipped: true, reason: matchedTag };
62
+ previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
53
63
  reporting.addReport({
54
64
  type: "accesslint",
55
65
  version: 1,
56
- result: { skipped: true, reason: matchedTag },
66
+ result: result2,
57
67
  status: "passed"
58
68
  });
59
69
  return;
@@ -67,14 +77,17 @@ var afterEach = async ({
67
77
  const enriched = enrichViolations(scoped);
68
78
  const hasViolations = enriched.length > 0;
69
79
  const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
80
+ const status = hasViolations ? mode : "passed";
81
+ const result = {
82
+ violations: enriched,
83
+ ruleCount: core.getActiveRules().length
84
+ };
85
+ previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
70
86
  reporting.addReport({
71
87
  type: "accesslint",
72
88
  version: 1,
73
- result: {
74
- violations: enriched,
75
- ruleCount: core.getActiveRules().length
76
- },
77
- status: hasViolations ? mode : "passed"
89
+ result,
90
+ status
78
91
  });
79
92
  };
80
93
 
@@ -1,10 +1,11 @@
1
- declare const afterEach: ({ reporting, parameters, viewMode, tags, }: {
1
+ declare const afterEach: ({ reporting, parameters, viewMode, tags, id, }: {
2
2
  reporting: {
3
3
  addReport: (report: Record<string, unknown>) => void;
4
4
  };
5
5
  parameters: Record<string, unknown>;
6
6
  viewMode: string;
7
7
  tags?: string[];
8
+ id?: string;
8
9
  }) => Promise<void>;
9
10
 
10
11
  export { afterEach };
package/dist/preview.d.ts CHANGED
@@ -1,10 +1,11 @@
1
- declare const afterEach: ({ reporting, parameters, viewMode, tags, }: {
1
+ declare const afterEach: ({ reporting, parameters, viewMode, tags, id, }: {
2
2
  reporting: {
3
3
  addReport: (report: Record<string, unknown>) => void;
4
4
  };
5
5
  parameters: Record<string, unknown>;
6
6
  viewMode: string;
7
7
  tags?: string[];
8
+ id?: string;
8
9
  }) => Promise<void>;
9
10
 
10
11
  export { afterEach };
package/dist/preview.js CHANGED
@@ -1,4 +1,11 @@
1
1
  import { configureRules, createChunkedAudit, getActiveRules, getRuleById } from '@accesslint/core';
2
+ import { addons } from 'storybook/preview-api';
3
+
4
+ // src/preview.ts
5
+
6
+ // src/constants.ts
7
+ var ADDON_ID = "accesslint/a11y";
8
+ var RESULT_EVENT = `${ADDON_ID}/result`;
2
9
 
3
10
  // src/preview.ts
4
11
  configureRules({
@@ -39,19 +46,22 @@ var afterEach = async ({
39
46
  reporting,
40
47
  parameters,
41
48
  viewMode,
42
- tags
49
+ tags,
50
+ id
43
51
  }) => {
44
52
  const accesslintParam = parameters?.accesslint;
45
53
  if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
46
54
  if (viewMode !== "story") return;
47
55
  const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
48
- const allSkipTags = ["no-a11y", ...skipTags];
56
+ const allSkipTags = ["skip-accesslint", ...skipTags];
49
57
  const matchedTag = tags?.find((t) => allSkipTags.includes(t));
50
58
  if (matchedTag) {
59
+ const result2 = { skipped: true, reason: matchedTag };
60
+ addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
51
61
  reporting.addReport({
52
62
  type: "accesslint",
53
63
  version: 1,
54
- result: { skipped: true, reason: matchedTag },
64
+ result: result2,
55
65
  status: "passed"
56
66
  });
57
67
  return;
@@ -65,14 +75,17 @@ var afterEach = async ({
65
75
  const enriched = enrichViolations(scoped);
66
76
  const hasViolations = enriched.length > 0;
67
77
  const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
78
+ const status = hasViolations ? mode : "passed";
79
+ const result = {
80
+ violations: enriched,
81
+ ruleCount: getActiveRules().length
82
+ };
83
+ addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
68
84
  reporting.addReport({
69
85
  type: "accesslint",
70
86
  version: 1,
71
- result: {
72
- violations: enriched,
73
- ruleCount: getActiveRules().length
74
- },
75
- status: hasViolations ? mode : "passed"
87
+ result,
88
+ status
76
89
  });
77
90
  };
78
91
 
@@ -15,7 +15,7 @@ interface AccessLintTestOptions {
15
15
  /**
16
16
  * Tags-based filtering for which stories to audit.
17
17
  *
18
- * accesslintTest({ tags: { skip: ["no-a11y"] } })
18
+ * accesslintTest({ tags: { skip: ["skip-accesslint"] } })
19
19
  *
20
20
  * Stories with any of the `skip` tags will not be audited.
21
21
  */
@@ -15,7 +15,7 @@ interface AccessLintTestOptions {
15
15
  /**
16
16
  * Tags-based filtering for which stories to audit.
17
17
  *
18
- * accesslintTest({ tags: { skip: ["no-a11y"] } })
18
+ * accesslintTest({ tags: { skip: ["skip-accesslint"] } })
19
19
  *
20
20
  * Stories with any of the `skip` tags will not be audited.
21
21
  */
@@ -17,6 +17,12 @@ var preview_exports = {};
17
17
  __export(preview_exports, {
18
18
  afterEach: () => afterEach
19
19
  });
20
+
21
+ // src/constants.ts
22
+ var ADDON_ID = "accesslint/a11y";
23
+ var RESULT_EVENT = `${ADDON_ID}/result`;
24
+
25
+ // src/preview.ts
20
26
  core.configureRules({
21
27
  disabledRules: ["accesslint-045"]
22
28
  });
@@ -55,19 +61,22 @@ var afterEach = async ({
55
61
  reporting,
56
62
  parameters,
57
63
  viewMode,
58
- tags
64
+ tags,
65
+ id
59
66
  }) => {
60
67
  const accesslintParam = parameters?.accesslint;
61
68
  if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
62
69
  if (viewMode !== "story") return;
63
70
  const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
64
- const allSkipTags = ["no-a11y", ...skipTags];
71
+ const allSkipTags = ["skip-accesslint", ...skipTags];
65
72
  const matchedTag = tags?.find((t) => allSkipTags.includes(t));
66
73
  if (matchedTag) {
74
+ const result2 = { skipped: true, reason: matchedTag };
75
+ previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
67
76
  reporting.addReport({
68
77
  type: "accesslint",
69
78
  version: 1,
70
- result: { skipped: true, reason: matchedTag },
79
+ result: result2,
71
80
  status: "passed"
72
81
  });
73
82
  return;
@@ -81,14 +90,17 @@ var afterEach = async ({
81
90
  const enriched = enrichViolations(scoped);
82
91
  const hasViolations = enriched.length > 0;
83
92
  const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
93
+ const status = hasViolations ? mode : "passed";
94
+ const result = {
95
+ violations: enriched,
96
+ ruleCount: core.getActiveRules().length
97
+ };
98
+ previewApi.addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
84
99
  reporting.addReport({
85
100
  type: "accesslint",
86
101
  version: 1,
87
- result: {
88
- violations: enriched,
89
- ruleCount: core.getActiveRules().length
90
- },
91
- status: hasViolations ? mode : "passed"
102
+ result,
103
+ status
92
104
  });
93
105
  };
94
106
  test.expect.extend(matchers.accesslintMatchers);
@@ -1,6 +1,6 @@
1
1
  import { expect } from 'storybook/test';
2
2
  import { expect as expect$1 } from 'vitest';
3
- import { composeConfigs } from 'storybook/preview-api';
3
+ import { composeConfigs, addons } from 'storybook/preview-api';
4
4
  import { configureRules, createChunkedAudit, getActiveRules, getRuleById } from '@accesslint/core';
5
5
  import { accesslintMatchers } from '@accesslint/vitest/matchers';
6
6
 
@@ -15,6 +15,12 @@ var preview_exports = {};
15
15
  __export(preview_exports, {
16
16
  afterEach: () => afterEach
17
17
  });
18
+
19
+ // src/constants.ts
20
+ var ADDON_ID = "accesslint/a11y";
21
+ var RESULT_EVENT = `${ADDON_ID}/result`;
22
+
23
+ // src/preview.ts
18
24
  configureRules({
19
25
  disabledRules: ["accesslint-045"]
20
26
  });
@@ -53,19 +59,22 @@ var afterEach = async ({
53
59
  reporting,
54
60
  parameters,
55
61
  viewMode,
56
- tags
62
+ tags,
63
+ id
57
64
  }) => {
58
65
  const accesslintParam = parameters?.accesslint;
59
66
  if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
60
67
  if (viewMode !== "story") return;
61
68
  const skipTags = typeof __ACCESSLINT_SKIP_TAGS__ !== "undefined" ? __ACCESSLINT_SKIP_TAGS__ : [];
62
- const allSkipTags = ["no-a11y", ...skipTags];
69
+ const allSkipTags = ["skip-accesslint", ...skipTags];
63
70
  const matchedTag = tags?.find((t) => allSkipTags.includes(t));
64
71
  if (matchedTag) {
72
+ const result2 = { skipped: true, reason: matchedTag };
73
+ addons.getChannel().emit(RESULT_EVENT, { storyId: id, result: result2 });
65
74
  reporting.addReport({
66
75
  type: "accesslint",
67
76
  version: 1,
68
- result: { skipped: true, reason: matchedTag },
77
+ result: result2,
69
78
  status: "passed"
70
79
  });
71
80
  return;
@@ -79,14 +88,17 @@ var afterEach = async ({
79
88
  const enriched = enrichViolations(scoped);
80
89
  const hasViolations = enriched.length > 0;
81
90
  const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
91
+ const status = hasViolations ? mode : "passed";
92
+ const result = {
93
+ violations: enriched,
94
+ ruleCount: getActiveRules().length
95
+ };
96
+ addons.getChannel().emit(RESULT_EVENT, { storyId: id, result, status });
82
97
  reporting.addReport({
83
98
  type: "accesslint",
84
99
  version: 1,
85
- result: {
86
- violations: enriched,
87
- ruleCount: getActiveRules().length
88
- },
89
- status: hasViolations ? mode : "passed"
100
+ result,
101
+ status
90
102
  });
91
103
  };
92
104
  expect.extend(accesslintMatchers);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@accesslint/storybook-addon",
3
- "version": "0.8.3",
3
+ "version": "0.8.4",
4
4
  "description": "Catch accessibility violations in your Storybook stories as you develop",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -59,7 +59,7 @@
59
59
  },
60
60
  "dependencies": {
61
61
  "@accesslint/core": "^0.6.5",
62
- "@accesslint/vitest": "^0.1.3"
62
+ "@accesslint/vitest": "^0.1.4"
63
63
  },
64
64
  "devDependencies": {
65
65
  "react": "^18.2.0",