@accesslint/storybook-addon 0.6.5 → 0.6.8

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/dist/manager.js CHANGED
@@ -1,13 +1,13 @@
1
- import React, { useMemo, useState, useRef, useEffect, useCallback } from 'react';
2
- import { addons, types, useAddonState, useChannel } from 'storybook/internal/manager-api';
1
+ import React, { useMemo, useState, useRef, useCallback } from 'react';
2
+ import { addons, types, useChannel } from 'storybook/internal/manager-api';
3
+ import { STORY_CHANGED, STORY_FINISHED } from 'storybook/internal/core-events';
3
4
  import { useTheme } from 'storybook/internal/theming';
4
- import { AddonPanel } from 'storybook/internal/components';
5
5
 
6
6
  // src/manager.tsx
7
7
 
8
8
  // src/constants.ts
9
9
  var ADDON_ID = "accesslint/a11y";
10
- var PANEL_ID = `${ADDON_ID}/panel`;
10
+ var PARAM_KEY = "accesslint";
11
11
  var IMPACT_COLOR = {
12
12
  critical: "#d32f2f",
13
13
  serious: "#d32f2f",
@@ -31,8 +31,7 @@ var LEVEL_COLOR = {
31
31
  AA: "#1565c0",
32
32
  AAA: "#6a1b9a"
33
33
  };
34
- var HIGHLIGHT_ID = `${ADDON_ID}/highlight`;
35
- var Panel = ({ active, ...rest }) => {
34
+ var Panel = ({ active }) => {
36
35
  const theme = useTheme();
37
36
  const isDark = theme.base === "dark";
38
37
  const colors = useMemo(() => ({
@@ -48,41 +47,29 @@ var Panel = ({ active, ...rest }) => {
48
47
  tagText: isDark ? "#ccc" : "#616161",
49
48
  ruleId: isDark ? "#64b5f6" : "#1565c0"
50
49
  }), [isDark, theme]);
51
- const [violations, setViolations] = useAddonState(
52
- ADDON_ID,
53
- []
54
- );
55
- const [meta, setMeta] = useState(null);
50
+ const [violations, setViolations] = useState([]);
51
+ const [ruleCount, setRuleCount] = useState(0);
56
52
  const [expandedIndex, setExpandedIndex] = useState(null);
57
53
  const buttonRefs = useRef([]);
58
- const emit = useChannel({
59
- [`${ADDON_ID}/results`]: (results) => {
60
- setViolations(results);
54
+ useChannel({
55
+ [STORY_FINISHED]: ({ reporters }) => {
56
+ const report = reporters.find((r) => r.type === "accesslint");
57
+ if (!report) return;
58
+ const result = report.result;
59
+ setViolations(result.violations ?? []);
60
+ setRuleCount(result.ruleCount ?? 0);
61
61
  setExpandedIndex(null);
62
62
  },
63
- [`${ADDON_ID}/meta`]: (data) => {
64
- setMeta(data);
63
+ [STORY_CHANGED]: () => {
64
+ setViolations([]);
65
+ setRuleCount(0);
66
+ setExpandedIndex(null);
65
67
  }
66
68
  });
67
- const sorted = [...violations].sort(
68
- (a, b) => (IMPACT_ORDER[a.impact] ?? 4) - (IMPACT_ORDER[b.impact] ?? 4)
69
+ const sorted = useMemo(
70
+ () => [...violations].sort((a, b) => (IMPACT_ORDER[a.impact] ?? 4) - (IMPACT_ORDER[b.impact] ?? 4)),
71
+ [violations]
69
72
  );
70
- const expanded = expandedIndex !== null ? sorted[expandedIndex] : null;
71
- useEffect(() => {
72
- if (expanded?.selector) {
73
- const local = expanded.selector.replace(/^.*>>>\s*iframe>\s*/, "");
74
- emit("storybook/highlight/add", {
75
- id: HIGHLIGHT_ID,
76
- selectors: [local],
77
- styles: {
78
- outline: `2px solid ${IMPACT_COLOR[expanded.impact] || "#1565c0"}`,
79
- outlineOffset: "2px"
80
- }
81
- });
82
- } else {
83
- emit("storybook/highlight/remove", { id: HIGHLIGHT_ID });
84
- }
85
- }, [expandedIndex]);
86
73
  const handleKeyDown = useCallback((e, index) => {
87
74
  let next = null;
88
75
  switch (e.key) {
@@ -105,7 +92,8 @@ var Panel = ({ active, ...rest }) => {
105
92
  buttonRefs.current[next]?.focus();
106
93
  }, [sorted.length]);
107
94
  if (!active) return null;
108
- return /* @__PURE__ */ React.createElement(AddonPanel, { active, ...rest }, /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", height: "100%", fontFamily: "system-ui, sans-serif" } }, meta && /* @__PURE__ */ React.createElement("div", { style: {
95
+ const passed = ruleCount - new Set(violations.map((v) => v.ruleId)).size;
96
+ return /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", height: "100%", fontFamily: "system-ui, sans-serif" } }, ruleCount > 0 && /* @__PURE__ */ React.createElement("div", { style: {
109
97
  display: "flex",
110
98
  gap: "12px",
111
99
  padding: "8px 12px",
@@ -113,7 +101,7 @@ var Panel = ({ active, ...rest }) => {
113
101
  color: colors.textMuted,
114
102
  borderBottom: `1px solid ${colors.border}`,
115
103
  flexShrink: 0
116
- } }, /* @__PURE__ */ React.createElement("span", null, meta.ruleCount, " rules"), /* @__PURE__ */ React.createElement("span", { style: { color: "#2e7d32" } }, meta.passed, " passed"), /* @__PURE__ */ React.createElement("span", { style: { color: meta.failed > 0 ? "#d32f2f" : colors.textMuted } }, meta.failed, " failed"), /* @__PURE__ */ React.createElement("span", null, meta.duration, "ms")), violations.length === 0 ? /* @__PURE__ */ React.createElement("p", { style: { padding: "12px", margin: 0, fontSize: "13px", color: colors.textMuted } }, "No accessibility violations found.") : /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", minHeight: 0 } }, /* @__PURE__ */ React.createElement(
104
+ } }, /* @__PURE__ */ React.createElement("span", null, ruleCount, " rules"), /* @__PURE__ */ React.createElement("span", { style: { color: "#2e7d32" } }, passed, " passed"), /* @__PURE__ */ React.createElement("span", { style: { color: violations.length > 0 ? "#d32f2f" : colors.textMuted } }, new Set(violations.map((v) => v.ruleId)).size, " failed")), violations.length === 0 ? /* @__PURE__ */ React.createElement("p", { style: { padding: "12px", margin: 0, fontSize: "13px", color: colors.textMuted } }, "No accessibility violations found.") : /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", minHeight: 0 } }, /* @__PURE__ */ React.createElement(
117
105
  "ul",
118
106
  {
119
107
  style: { listStyle: "none", padding: 0, margin: 0 },
@@ -200,13 +188,20 @@ var Panel = ({ active, ...rest }) => {
200
188
  v.html
201
189
  ))));
202
190
  })
203
- ))));
191
+ )));
204
192
  };
205
193
 
206
194
  // src/manager.tsx
195
+ var PANEL_ID = `${ADDON_ID}/panel`;
207
196
  var Title = () => {
208
- const [violations] = useAddonState(ADDON_ID, []);
209
- const count = violations.length;
197
+ const [count, setCount] = React.useState(0);
198
+ useChannel({
199
+ [STORY_FINISHED]: ({ reporters }) => {
200
+ const report = reporters.find((r) => r.type === "accesslint");
201
+ const violations = report?.result?.violations;
202
+ setCount(violations?.length ?? 0);
203
+ }
204
+ });
210
205
  return /* @__PURE__ */ React.createElement(React.Fragment, null, "AccessLint", count > 0 && /* @__PURE__ */ React.createElement("span", { style: {
211
206
  display: "inline-block",
212
207
  marginLeft: "8px",
@@ -223,8 +218,9 @@ var Title = () => {
223
218
  };
224
219
  addons.register(ADDON_ID, () => {
225
220
  addons.add(PANEL_ID, {
226
- type: types.PANEL,
227
221
  title: Title,
228
- render: Panel
222
+ type: types.PANEL,
223
+ render: Panel,
224
+ paramKey: PARAM_KEY
229
225
  });
230
226
  });
package/dist/preview.cjs CHANGED
@@ -1,58 +1,60 @@
1
1
  'use strict';
2
2
 
3
- var previewApi = require('storybook/internal/preview-api');
4
3
  var core = require('@accesslint/core');
5
4
 
6
- // src/preview.ts
7
-
8
- // src/constants.ts
9
- var ADDON_ID = "accesslint/a11y";
10
-
11
5
  // src/preview.ts
12
6
  core.configureRules({
13
7
  disabledRules: ["accesslint-045"]
14
8
  });
15
- var decorator = (storyFn) => {
16
- const story = storyFn();
17
- setTimeout(async () => {
18
- const start = performance.now();
19
- const results = core.runAudit(document);
20
- const duration = Math.round(performance.now() - start);
21
- const root = document.getElementById("storybook-root");
22
- const scoped = root ? results.violations.filter((v) => {
23
- const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
24
- try {
25
- const el = document.querySelector(local);
26
- return el && root.contains(el);
27
- } catch {
28
- return false;
29
- }
30
- }) : results.violations;
31
- const enriched = scoped.map((v) => {
32
- const rule = core.getRuleById(v.ruleId);
33
- return {
34
- ...v,
35
- element: void 0,
36
- // not serializable
37
- description: rule?.description,
38
- wcag: rule?.wcag,
39
- level: rule?.level,
40
- guidance: rule?.guidance
41
- };
42
- });
43
- const failedRuleIds = new Set(scoped.map((v) => v.ruleId));
44
- const channel = previewApi.addons.getChannel();
45
- channel.emit(`${ADDON_ID}/results`, enriched);
46
- channel.emit(`${ADDON_ID}/meta`, {
47
- duration,
48
- ruleCount: results.ruleCount,
49
- failed: failedRuleIds.size,
50
- passed: results.ruleCount - failedRuleIds.size,
51
- violations: scoped.length
52
- });
53
- }, 0);
54
- return story;
9
+ function scopeViolations(violations) {
10
+ const root = document.getElementById("storybook-root");
11
+ if (!root) return violations;
12
+ return violations.filter((v) => {
13
+ const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
14
+ try {
15
+ const el = document.querySelector(local);
16
+ return el && root.contains(el);
17
+ } catch {
18
+ return false;
19
+ }
20
+ });
21
+ }
22
+ function enrichViolations(violations) {
23
+ return violations.map((v) => {
24
+ const rule = core.getRuleById(v.ruleId);
25
+ return {
26
+ ...v,
27
+ element: void 0,
28
+ // not serializable
29
+ description: rule?.description,
30
+ wcag: rule?.wcag,
31
+ level: rule?.level,
32
+ guidance: rule?.guidance
33
+ };
34
+ });
35
+ }
36
+ var afterEach = async ({
37
+ reporting,
38
+ parameters,
39
+ viewMode
40
+ }) => {
41
+ const accesslintParam = parameters?.accesslint;
42
+ if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
43
+ if (viewMode !== "story") return;
44
+ const result = core.runAudit(document);
45
+ const scoped = scopeViolations(result.violations);
46
+ const enriched = enrichViolations(scoped);
47
+ const hasViolations = enriched.length > 0;
48
+ const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
49
+ reporting.addReport({
50
+ type: "accesslint",
51
+ version: 1,
52
+ result: {
53
+ violations: enriched,
54
+ ruleCount: result.ruleCount
55
+ },
56
+ status: hasViolations ? mode : "passed"
57
+ });
55
58
  };
56
- var decorators = [decorator];
57
59
 
58
- exports.decorators = decorators;
60
+ exports.afterEach = afterEach;
@@ -1,3 +1,9 @@
1
- declare const decorators: ((storyFn: () => unknown) => unknown)[];
1
+ declare const afterEach: ({ reporting, parameters, viewMode, }: {
2
+ reporting: {
3
+ addReport: (report: Record<string, unknown>) => void;
4
+ };
5
+ parameters: Record<string, unknown>;
6
+ viewMode: string;
7
+ }) => Promise<void>;
2
8
 
3
- export { decorators };
9
+ export { afterEach };
package/dist/preview.d.ts CHANGED
@@ -1,3 +1,9 @@
1
- declare const decorators: ((storyFn: () => unknown) => unknown)[];
1
+ declare const afterEach: ({ reporting, parameters, viewMode, }: {
2
+ reporting: {
3
+ addReport: (report: Record<string, unknown>) => void;
4
+ };
5
+ parameters: Record<string, unknown>;
6
+ viewMode: string;
7
+ }) => Promise<void>;
2
8
 
3
- export { decorators };
9
+ export { afterEach };
package/dist/preview.js CHANGED
@@ -1,56 +1,58 @@
1
- import { addons } from 'storybook/internal/preview-api';
2
1
  import { configureRules, runAudit, getRuleById } from '@accesslint/core';
3
2
 
4
- // src/preview.ts
5
-
6
- // src/constants.ts
7
- var ADDON_ID = "accesslint/a11y";
8
-
9
3
  // src/preview.ts
10
4
  configureRules({
11
5
  disabledRules: ["accesslint-045"]
12
6
  });
13
- var decorator = (storyFn) => {
14
- const story = storyFn();
15
- setTimeout(async () => {
16
- const start = performance.now();
17
- const results = runAudit(document);
18
- const duration = Math.round(performance.now() - start);
19
- const root = document.getElementById("storybook-root");
20
- const scoped = root ? results.violations.filter((v) => {
21
- const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
22
- try {
23
- const el = document.querySelector(local);
24
- return el && root.contains(el);
25
- } catch {
26
- return false;
27
- }
28
- }) : results.violations;
29
- const enriched = scoped.map((v) => {
30
- const rule = getRuleById(v.ruleId);
31
- return {
32
- ...v,
33
- element: void 0,
34
- // not serializable
35
- description: rule?.description,
36
- wcag: rule?.wcag,
37
- level: rule?.level,
38
- guidance: rule?.guidance
39
- };
40
- });
41
- const failedRuleIds = new Set(scoped.map((v) => v.ruleId));
42
- const channel = addons.getChannel();
43
- channel.emit(`${ADDON_ID}/results`, enriched);
44
- channel.emit(`${ADDON_ID}/meta`, {
45
- duration,
46
- ruleCount: results.ruleCount,
47
- failed: failedRuleIds.size,
48
- passed: results.ruleCount - failedRuleIds.size,
49
- violations: scoped.length
50
- });
51
- }, 0);
52
- return story;
7
+ function scopeViolations(violations) {
8
+ const root = document.getElementById("storybook-root");
9
+ if (!root) return violations;
10
+ return violations.filter((v) => {
11
+ const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
12
+ try {
13
+ const el = document.querySelector(local);
14
+ return el && root.contains(el);
15
+ } catch {
16
+ return false;
17
+ }
18
+ });
19
+ }
20
+ function enrichViolations(violations) {
21
+ return violations.map((v) => {
22
+ const rule = getRuleById(v.ruleId);
23
+ return {
24
+ ...v,
25
+ element: void 0,
26
+ // not serializable
27
+ description: rule?.description,
28
+ wcag: rule?.wcag,
29
+ level: rule?.level,
30
+ guidance: rule?.guidance
31
+ };
32
+ });
33
+ }
34
+ var afterEach = async ({
35
+ reporting,
36
+ parameters,
37
+ viewMode
38
+ }) => {
39
+ const accesslintParam = parameters?.accesslint;
40
+ if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
41
+ if (viewMode !== "story") return;
42
+ const result = runAudit(document);
43
+ const scoped = scopeViolations(result.violations);
44
+ const enriched = enrichViolations(scoped);
45
+ const hasViolations = enriched.length > 0;
46
+ const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
47
+ reporting.addReport({
48
+ type: "accesslint",
49
+ version: 1,
50
+ result: {
51
+ violations: enriched,
52
+ ruleCount: result.ruleCount
53
+ },
54
+ status: hasViolations ? mode : "passed"
55
+ });
53
56
  };
54
- var decorators = [decorator];
55
57
 
56
- export { decorators };
58
+ export { afterEach };
@@ -0,0 +1,24 @@
1
+ 'use strict';
2
+
3
+ var _documentCurrentScript = typeof document !== 'undefined' ? document.currentScript : null;
4
+ // src/vitest-plugin.ts
5
+ function accesslintTest() {
6
+ const distDir = new URL(".", (typeof document === 'undefined' ? require('u' + 'rl').pathToFileURL(__filename).href : (_documentCurrentScript && _documentCurrentScript.tagName.toUpperCase() === 'SCRIPT' && _documentCurrentScript.src || new URL('vitest-plugin.cjs', document.baseURI).href))).pathname;
7
+ return {
8
+ name: "@accesslint/storybook-addon",
9
+ config() {
10
+ return {
11
+ server: {
12
+ fs: {
13
+ allow: [distDir]
14
+ }
15
+ },
16
+ test: {
17
+ setupFiles: ["@accesslint/storybook-addon/vitest-setup"]
18
+ }
19
+ };
20
+ }
21
+ };
22
+ }
23
+
24
+ exports.accesslintTest = accesslintTest;
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Vitest plugin that automatically registers AccessLint's afterEach annotation
3
+ * so that running component tests produces per-story accessibility badges.
4
+ *
5
+ * Usage in vitest.config.ts (or the storybook vitest workspace):
6
+ *
7
+ * import { storybookTest } from "@storybook/addon-vitest/vitest-plugin";
8
+ * import { accesslintTest } from "@accesslint/storybook-addon/vitest-plugin";
9
+ *
10
+ * export default defineConfig({
11
+ * plugins: [storybookTest(), accesslintTest()],
12
+ * });
13
+ */
14
+ declare function accesslintTest(): {
15
+ name: string;
16
+ config: () => Record<string, unknown>;
17
+ };
18
+
19
+ export { accesslintTest };
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Vitest plugin that automatically registers AccessLint's afterEach annotation
3
+ * so that running component tests produces per-story accessibility badges.
4
+ *
5
+ * Usage in vitest.config.ts (or the storybook vitest workspace):
6
+ *
7
+ * import { storybookTest } from "@storybook/addon-vitest/vitest-plugin";
8
+ * import { accesslintTest } from "@accesslint/storybook-addon/vitest-plugin";
9
+ *
10
+ * export default defineConfig({
11
+ * plugins: [storybookTest(), accesslintTest()],
12
+ * });
13
+ */
14
+ declare function accesslintTest(): {
15
+ name: string;
16
+ config: () => Record<string, unknown>;
17
+ };
18
+
19
+ export { accesslintTest };
@@ -0,0 +1,21 @@
1
+ // src/vitest-plugin.ts
2
+ function accesslintTest() {
3
+ const distDir = new URL(".", import.meta.url).pathname;
4
+ return {
5
+ name: "@accesslint/storybook-addon",
6
+ config() {
7
+ return {
8
+ server: {
9
+ fs: {
10
+ allow: [distDir]
11
+ }
12
+ },
13
+ test: {
14
+ setupFiles: ["@accesslint/storybook-addon/vitest-setup"]
15
+ }
16
+ };
17
+ }
18
+ };
19
+ }
20
+
21
+ export { accesslintTest };
@@ -0,0 +1,74 @@
1
+ 'use strict';
2
+
3
+ var previewApi = require('storybook/preview-api');
4
+ var core = require('@accesslint/core');
5
+
6
+ var __defProp = Object.defineProperty;
7
+ var __export = (target, all) => {
8
+ for (var name in all)
9
+ __defProp(target, name, { get: all[name], enumerable: true });
10
+ };
11
+
12
+ // src/preview.ts
13
+ var preview_exports = {};
14
+ __export(preview_exports, {
15
+ afterEach: () => afterEach
16
+ });
17
+ core.configureRules({
18
+ disabledRules: ["accesslint-045"]
19
+ });
20
+ function scopeViolations(violations) {
21
+ const root = document.getElementById("storybook-root");
22
+ if (!root) return violations;
23
+ return violations.filter((v) => {
24
+ const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
25
+ try {
26
+ const el = document.querySelector(local);
27
+ return el && root.contains(el);
28
+ } catch {
29
+ return false;
30
+ }
31
+ });
32
+ }
33
+ function enrichViolations(violations) {
34
+ return violations.map((v) => {
35
+ const rule = core.getRuleById(v.ruleId);
36
+ return {
37
+ ...v,
38
+ element: void 0,
39
+ // not serializable
40
+ description: rule?.description,
41
+ wcag: rule?.wcag,
42
+ level: rule?.level,
43
+ guidance: rule?.guidance
44
+ };
45
+ });
46
+ }
47
+ var afterEach = async ({
48
+ reporting,
49
+ parameters,
50
+ viewMode
51
+ }) => {
52
+ const accesslintParam = parameters?.accesslint;
53
+ if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
54
+ if (viewMode !== "story") return;
55
+ const result = core.runAudit(document);
56
+ const scoped = scopeViolations(result.violations);
57
+ const enriched = enrichViolations(scoped);
58
+ const hasViolations = enriched.length > 0;
59
+ const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
60
+ reporting.addReport({
61
+ type: "accesslint",
62
+ version: 1,
63
+ result: {
64
+ violations: enriched,
65
+ ruleCount: result.ruleCount
66
+ },
67
+ status: hasViolations ? mode : "passed"
68
+ });
69
+ };
70
+
71
+ // src/vitest-setup.ts
72
+ var g = globalThis;
73
+ var existing = g.globalProjectAnnotations;
74
+ g.globalProjectAnnotations = existing ? previewApi.composeConfigs([existing, preview_exports]) : previewApi.composeConfigs([preview_exports]);
@@ -0,0 +1,72 @@
1
+ import { composeConfigs } from 'storybook/preview-api';
2
+ import { configureRules, runAudit, getRuleById } from '@accesslint/core';
3
+
4
+ var __defProp = Object.defineProperty;
5
+ var __export = (target, all) => {
6
+ for (var name in all)
7
+ __defProp(target, name, { get: all[name], enumerable: true });
8
+ };
9
+
10
+ // src/preview.ts
11
+ var preview_exports = {};
12
+ __export(preview_exports, {
13
+ afterEach: () => afterEach
14
+ });
15
+ configureRules({
16
+ disabledRules: ["accesslint-045"]
17
+ });
18
+ function scopeViolations(violations) {
19
+ const root = document.getElementById("storybook-root");
20
+ if (!root) return violations;
21
+ return violations.filter((v) => {
22
+ const local = v.selector.replace(/^.*>>>\s*iframe>\s*/, "");
23
+ try {
24
+ const el = document.querySelector(local);
25
+ return el && root.contains(el);
26
+ } catch {
27
+ return false;
28
+ }
29
+ });
30
+ }
31
+ function enrichViolations(violations) {
32
+ return violations.map((v) => {
33
+ const rule = getRuleById(v.ruleId);
34
+ return {
35
+ ...v,
36
+ element: void 0,
37
+ // not serializable
38
+ description: rule?.description,
39
+ wcag: rule?.wcag,
40
+ level: rule?.level,
41
+ guidance: rule?.guidance
42
+ };
43
+ });
44
+ }
45
+ var afterEach = async ({
46
+ reporting,
47
+ parameters,
48
+ viewMode
49
+ }) => {
50
+ const accesslintParam = parameters?.accesslint;
51
+ if (accesslintParam?.disable === true || accesslintParam?.test === "off") return;
52
+ if (viewMode !== "story") return;
53
+ const result = runAudit(document);
54
+ const scoped = scopeViolations(result.violations);
55
+ const enriched = enrichViolations(scoped);
56
+ const hasViolations = enriched.length > 0;
57
+ const mode = accesslintParam?.test === "todo" ? "warning" : "failed";
58
+ reporting.addReport({
59
+ type: "accesslint",
60
+ version: 1,
61
+ result: {
62
+ violations: enriched,
63
+ ruleCount: result.ruleCount
64
+ },
65
+ status: hasViolations ? mode : "passed"
66
+ });
67
+ };
68
+
69
+ // src/vitest-setup.ts
70
+ var g = globalThis;
71
+ var existing = g.globalProjectAnnotations;
72
+ g.globalProjectAnnotations = existing ? composeConfigs([existing, preview_exports]) : composeConfigs([preview_exports]);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@accesslint/storybook-addon",
3
- "version": "0.6.5",
3
+ "version": "0.6.8",
4
4
  "description": "Catch accessibility violations in your Storybook stories as you develop",
5
5
  "license": "MIT",
6
6
  "publishConfig": {
@@ -24,6 +24,14 @@
24
24
  "./preview": {
25
25
  "import": "./dist/preview.js",
26
26
  "require": "./dist/preview.cjs"
27
+ },
28
+ "./vitest-plugin": {
29
+ "import": "./dist/vitest-plugin.js",
30
+ "require": "./dist/vitest-plugin.cjs"
31
+ },
32
+ "./vitest-setup": {
33
+ "import": "./dist/vitest-setup.js",
34
+ "require": "./dist/vitest-setup.cjs"
27
35
  }
28
36
  },
29
37
  "main": "dist/index.cjs",
@@ -37,7 +45,6 @@
37
45
  ],
38
46
  "scripts": {
39
47
  "build": "tsup",
40
- "prepublishOnly": "node -e \"const fs = require('fs'); const v = JSON.parse(fs.readFileSync('node_modules/@accesslint/core/package.json','utf8')).version; const pkg = JSON.parse(fs.readFileSync('package.json','utf8')); pkg.version = v; fs.writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\\n');\"",
41
48
  "build:watch": "tsup --watch",
42
49
  "typecheck": "tsc --noEmit"
43
50
  },