@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/dist/manager.js CHANGED
@@ -1,407 +1,416 @@
1
- import React, { useMemo, useState, useRef, useCallback } from 'react';
2
- import * as managerApi from 'storybook/manager-api';
3
- import { useChannel } from 'storybook/manager-api';
4
- import { styled, useTheme } from 'storybook/theming';
5
- import { STORY_CHANGED } from 'storybook/internal/core-events';
6
-
7
- var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, {
8
- get: (a, b) => (typeof require !== "undefined" ? require : a)[b]
9
- }) : x)(function(x) {
10
- if (typeof require !== "undefined") return require.apply(this, arguments);
11
- throw Error('Dynamic require of "' + x + '" is not supported');
1
+ import React, { useCallback, useMemo, useRef, useState } from "react";
2
+ import * as managerApi from "storybook/manager-api";
3
+ import { useChannel } from "storybook/manager-api";
4
+ import { styled, useTheme } from "storybook/theming";
5
+ import { STORY_CHANGED } from "storybook/internal/core-events";
6
+ //#region \0rolldown/runtime.js
7
+ var __require = /* @__PURE__ */ ((x) => typeof require !== "undefined" ? require : typeof Proxy !== "undefined" ? new Proxy(x, { get: (a, b) => (typeof require !== "undefined" ? require : a)[b] }) : x)(function(x) {
8
+ if (typeof require !== "undefined") return require.apply(this, arguments);
9
+ throw Error("Calling `require` for \"" + x + "\" in an environment that doesn't expose the `require` function. See https://rolldown.rs/in-depth/bundling-cjs#require-external-modules for more details.");
12
10
  });
13
-
14
- // src/constants.ts
15
- var ADDON_ID = "accesslint/a11y";
16
- var PARAM_KEY = "accesslint";
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`;
22
- var IMPACT_COLOR = {
23
- critical: "#d32f2f",
24
- serious: "#d32f2f",
25
- moderate: "#c43e00",
26
- minor: "#999999"
11
+ //#endregion
12
+ //#region src/constants.ts
13
+ const ADDON_ID = "accesslint/a11y";
14
+ const PARAM_KEY = "accesslint";
15
+ const STATUS_TYPE_ID = "accesslint/a11y";
16
+ const RESULT_EVENT = `${ADDON_ID}/result`;
17
+ const HIGHLIGHT_ADDON_ID = "storybook/highlight";
18
+ const HIGHLIGHT = `${HIGHLIGHT_ADDON_ID}/add`;
19
+ const REMOVE_HIGHLIGHT = `${HIGHLIGHT_ADDON_ID}/remove`;
20
+ //#endregion
21
+ //#region src/Panel.tsx
22
+ const IMPACT_COLOR = {
23
+ critical: "#d32f2f",
24
+ serious: "#d32f2f",
25
+ moderate: "#c43e00",
26
+ minor: "#999999"
27
27
  };
28
- var IMPACT_ICON = {
29
- critical: "\u2716",
30
- serious: "\u2716",
31
- moderate: "\u26A0",
32
- minor: "\xB7"
28
+ const IMPACT_ICON = {
29
+ critical: "",
30
+ serious: "",
31
+ moderate: "",
32
+ minor: "·"
33
33
  };
34
- var IMPACT_ORDER = {
35
- critical: 0,
36
- serious: 1,
37
- moderate: 2,
38
- minor: 3
34
+ const IMPACT_ORDER = {
35
+ critical: 0,
36
+ serious: 1,
37
+ moderate: 2,
38
+ minor: 3
39
39
  };
40
- var LEVEL_COLOR = {
41
- A: "#2e7d32",
42
- AA: "#1565c0",
43
- AAA: "#6a1b9a"
40
+ const LEVEL_COLOR = {
41
+ A: "#2e7d32",
42
+ AA: "#1565c0",
43
+ AAA: "#6a1b9a"
44
44
  };
45
- var Panel = ({ active }) => {
46
- const theme = useTheme();
47
- const isDark = theme.base === "dark";
48
- const colors = useMemo(() => ({
49
- text: theme.textColor || (isDark ? "#e0e0e0" : "#424242"),
50
- textMuted: theme.textMutedColor || (isDark ? "#999" : "#616161"),
51
- bg: theme.appContentBg || (isDark ? "#1a1a1a" : "#fff"),
52
- bgDetails: isDark ? "#2a2a2a" : "#f5f5f5",
53
- bgSelected: isDark ? "#1a3a5c" : "#e3f2fd",
54
- border: theme.appBorderColor || (isDark ? "#444" : "#f0f0f0"),
55
- codeBg: isDark ? "#333" : "#fff",
56
- codeBorder: isDark ? "#555" : "#e0e0e0",
57
- tagBg: isDark ? "#444" : "#e0e0e0",
58
- tagText: isDark ? "#ccc" : "#616161",
59
- ruleId: isDark ? "#64b5f6" : "#1565c0"
60
- }), [isDark, theme]);
61
- const [violations, setViolations] = useState([]);
62
- const [ruleCount, setRuleCount] = useState(0);
63
- const [skippedReason, setSkippedReason] = useState(null);
64
- const [expandedIndex, setExpandedIndex] = useState(null);
65
- const [highlightedIndex, setHighlightedIndex] = useState(null);
66
- const buttonRefs = useRef([]);
67
- const emit = useChannel({
68
- [RESULT_EVENT]: ({ result }) => {
69
- if (result.skipped) {
70
- setViolations([]);
71
- setRuleCount(0);
72
- setSkippedReason(result.reason ?? "skipped");
73
- setExpandedIndex(null);
74
- setHighlightedIndex(null);
75
- return;
76
- }
77
- setViolations(result.violations ?? []);
78
- setRuleCount(result.ruleCount ?? 0);
79
- setSkippedReason(null);
80
- setExpandedIndex(null);
81
- setHighlightedIndex(null);
82
- },
83
- [STORY_CHANGED]: () => {
84
- setViolations([]);
85
- setRuleCount(0);
86
- setSkippedReason(null);
87
- setExpandedIndex(null);
88
- setHighlightedIndex(null);
89
- }
90
- });
91
- const sorted = useMemo(
92
- () => [...violations].sort((a, b) => (IMPACT_ORDER[a.impact] ?? 4) - (IMPACT_ORDER[b.impact] ?? 4)),
93
- [violations]
94
- );
95
- const handleKeyDown = useCallback((e, index) => {
96
- let next = null;
97
- switch (e.key) {
98
- case "ArrowDown":
99
- next = Math.min(index + 1, sorted.length - 1);
100
- break;
101
- case "ArrowUp":
102
- next = Math.max(index - 1, 0);
103
- break;
104
- case "Home":
105
- next = 0;
106
- break;
107
- case "End":
108
- next = sorted.length - 1;
109
- break;
110
- default:
111
- return;
112
- }
113
- e.preventDefault();
114
- buttonRefs.current[next]?.focus();
115
- }, [sorted.length]);
116
- if (!active) return null;
117
- const passed = ruleCount - new Set(violations.map((v) => v.ruleId)).size;
118
- return /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column", height: "100%", fontFamily: "system-ui, sans-serif" } }, ruleCount > 0 && /* @__PURE__ */ React.createElement("div", { style: {
119
- display: "flex",
120
- gap: "12px",
121
- padding: "8px 12px",
122
- fontSize: "11px",
123
- color: colors.textMuted,
124
- borderBottom: `1px solid ${colors.border}`,
125
- flexShrink: 0
126
- } }, /* @__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 } }, skippedReason ? `Accessibility audit skipped (${skippedReason} tag).` : "No accessibility violations found.") : /* @__PURE__ */ React.createElement("div", { style: { flex: 1, overflow: "auto", minHeight: 0 } }, /* @__PURE__ */ React.createElement(
127
- "ul",
128
- {
129
- style: { listStyle: "none", padding: 0, margin: 0 },
130
- "aria-label": "Accessibility violations"
131
- },
132
- sorted.map((v, i) => {
133
- const isOpen = expandedIndex === i;
134
- return /* @__PURE__ */ React.createElement("li", { key: i, style: { borderBottom: `1px solid ${colors.border}` } }, /* @__PURE__ */ React.createElement(
135
- "button",
136
- {
137
- ref: (el) => {
138
- buttonRefs.current[i] = el;
139
- },
140
- type: "button",
141
- onClick: () => {
142
- setExpandedIndex(isOpen ? null : i);
143
- if (highlightedIndex !== null) {
144
- emit(REMOVE_HIGHLIGHT);
145
- setHighlightedIndex(null);
146
- }
147
- },
148
- onKeyDown: (e) => handleKeyDown(e, i),
149
- "aria-expanded": isOpen,
150
- style: {
151
- width: "100%",
152
- padding: "8px 12px",
153
- background: isOpen ? colors.bgSelected : "transparent",
154
- border: "none",
155
- font: "inherit",
156
- fontSize: "12px",
157
- textAlign: "left",
158
- cursor: "pointer",
159
- color: colors.text
160
- }
161
- },
162
- /* @__PURE__ */ React.createElement("div", { style: { display: "flex", alignItems: "center", gap: "6px" } }, /* @__PURE__ */ React.createElement(
163
- "span",
164
- {
165
- "aria-hidden": "true",
166
- style: {
167
- color: IMPACT_COLOR[v.impact],
168
- fontWeight: "bold",
169
- fontSize: "12px"
170
- }
171
- },
172
- IMPACT_ICON[v.impact]
173
- ), /* @__PURE__ */ React.createElement("span", { style: { color: IMPACT_COLOR[v.impact], fontSize: "11px" } }, v.impact), /* @__PURE__ */ React.createElement("code", { style: { fontSize: "11px", color: colors.ruleId } }, v.ruleId)),
174
- /* @__PURE__ */ React.createElement("div", { style: { marginTop: "2px", color: colors.text, fontSize: "12px" } }, v.message)
175
- ), isOpen && /* @__PURE__ */ React.createElement("div", { style: { padding: "4px 12px 12px", background: colors.bgDetails } }, v.description && /* @__PURE__ */ React.createElement("p", { style: { margin: "4px 0 8px", fontSize: "12px", color: colors.text } }, v.description), /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: "6px", flexWrap: "wrap", marginBottom: "8px" } }, v.level && /* @__PURE__ */ React.createElement("span", { style: {
176
- display: "inline-block",
177
- padding: "0 5px",
178
- fontSize: "10px",
179
- fontWeight: 600,
180
- borderRadius: "3px",
181
- color: "#fff",
182
- background: LEVEL_COLOR[v.level] || "#666",
183
- lineHeight: "18px"
184
- } }, "WCAG ", v.level), v.wcag?.map((ref) => /* @__PURE__ */ React.createElement(
185
- "span",
186
- {
187
- key: ref,
188
- style: {
189
- display: "inline-block",
190
- padding: "0 5px",
191
- fontSize: "10px",
192
- fontWeight: 500,
193
- borderRadius: "3px",
194
- color: colors.tagText,
195
- background: colors.tagBg,
196
- lineHeight: "18px"
197
- }
198
- },
199
- ref
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(
232
- "pre",
233
- {
234
- style: {
235
- margin: 0,
236
- padding: "6px 8px",
237
- fontSize: "11px",
238
- color: colors.text,
239
- background: colors.codeBg,
240
- border: `1px solid ${colors.codeBorder}`,
241
- borderRadius: "4px",
242
- overflow: "auto",
243
- whiteSpace: "pre-wrap",
244
- wordBreak: "break-all"
245
- }
246
- },
247
- v.html
248
- ))));
249
- })
250
- )));
45
+ const Panel = ({ active }) => {
46
+ const theme = useTheme();
47
+ const isDark = theme.base === "dark";
48
+ const colors = useMemo(() => ({
49
+ text: theme.textColor || (isDark ? "#e0e0e0" : "#424242"),
50
+ textMuted: theme.textMutedColor || (isDark ? "#999" : "#616161"),
51
+ bg: theme.appContentBg || (isDark ? "#1a1a1a" : "#fff"),
52
+ bgDetails: isDark ? "#2a2a2a" : "#f5f5f5",
53
+ bgSelected: isDark ? "#1a3a5c" : "#e3f2fd",
54
+ border: theme.appBorderColor || (isDark ? "#444" : "#f0f0f0"),
55
+ codeBg: isDark ? "#333" : "#fff",
56
+ codeBorder: isDark ? "#555" : "#e0e0e0",
57
+ tagBg: isDark ? "#444" : "#e0e0e0",
58
+ tagText: isDark ? "#ccc" : "#616161",
59
+ ruleId: isDark ? "#64b5f6" : "#1565c0"
60
+ }), [isDark, theme]);
61
+ const [violations, setViolations] = useState([]);
62
+ const [ruleCount, setRuleCount] = useState(0);
63
+ const [skippedReason, setSkippedReason] = useState(null);
64
+ const [expandedIndex, setExpandedIndex] = useState(null);
65
+ const [highlightedIndex, setHighlightedIndex] = useState(null);
66
+ const buttonRefs = useRef([]);
67
+ const emit = useChannel({
68
+ [RESULT_EVENT]: ({ result }) => {
69
+ if (result.skipped) {
70
+ setViolations([]);
71
+ setRuleCount(0);
72
+ setSkippedReason(result.reason ?? "skipped");
73
+ setExpandedIndex(null);
74
+ setHighlightedIndex(null);
75
+ return;
76
+ }
77
+ setViolations(result.violations ?? []);
78
+ setRuleCount(result.ruleCount ?? 0);
79
+ setSkippedReason(null);
80
+ setExpandedIndex(null);
81
+ setHighlightedIndex(null);
82
+ },
83
+ [STORY_CHANGED]: () => {
84
+ setViolations([]);
85
+ setRuleCount(0);
86
+ setSkippedReason(null);
87
+ setExpandedIndex(null);
88
+ setHighlightedIndex(null);
89
+ }
90
+ });
91
+ const sorted = useMemo(() => [...violations].sort((a, b) => (IMPACT_ORDER[a.impact] ?? 4) - (IMPACT_ORDER[b.impact] ?? 4)), [violations]);
92
+ const handleKeyDown = useCallback((e, index) => {
93
+ let next = null;
94
+ switch (e.key) {
95
+ case "ArrowDown":
96
+ next = Math.min(index + 1, sorted.length - 1);
97
+ break;
98
+ case "ArrowUp":
99
+ next = Math.max(index - 1, 0);
100
+ break;
101
+ case "Home":
102
+ next = 0;
103
+ break;
104
+ case "End":
105
+ next = sorted.length - 1;
106
+ break;
107
+ default: return;
108
+ }
109
+ e.preventDefault();
110
+ buttonRefs.current[next]?.focus();
111
+ }, [sorted.length]);
112
+ if (!active) return null;
113
+ const passed = ruleCount - new Set(violations.map((v) => v.ruleId)).size;
114
+ return /* @__PURE__ */ React.createElement("div", { style: {
115
+ display: "flex",
116
+ flexDirection: "column",
117
+ height: "100%",
118
+ fontFamily: "system-ui, sans-serif"
119
+ } }, ruleCount > 0 && /* @__PURE__ */ React.createElement("div", { style: {
120
+ display: "flex",
121
+ gap: "12px",
122
+ padding: "8px 12px",
123
+ fontSize: "11px",
124
+ color: colors.textMuted,
125
+ borderBottom: `1px solid ${colors.border}`,
126
+ flexShrink: 0
127
+ } }, /* @__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: {
128
+ padding: "12px",
129
+ margin: 0,
130
+ fontSize: "13px",
131
+ color: colors.textMuted
132
+ } }, skippedReason ? `Accessibility audit skipped (${skippedReason} tag).` : "No accessibility violations found.") : /* @__PURE__ */ React.createElement("div", { style: {
133
+ flex: 1,
134
+ overflow: "auto",
135
+ minHeight: 0
136
+ } }, /* @__PURE__ */ React.createElement("ul", {
137
+ style: {
138
+ listStyle: "none",
139
+ padding: 0,
140
+ margin: 0
141
+ },
142
+ "aria-label": "Accessibility violations"
143
+ }, sorted.map((v, i) => {
144
+ const isOpen = expandedIndex === i;
145
+ return /* @__PURE__ */ React.createElement("li", {
146
+ key: i,
147
+ style: { borderBottom: `1px solid ${colors.border}` }
148
+ }, /* @__PURE__ */ React.createElement("button", {
149
+ ref: (el) => {
150
+ buttonRefs.current[i] = el;
151
+ },
152
+ type: "button",
153
+ onClick: () => {
154
+ setExpandedIndex(isOpen ? null : i);
155
+ if (highlightedIndex !== null) {
156
+ emit(REMOVE_HIGHLIGHT);
157
+ setHighlightedIndex(null);
158
+ }
159
+ },
160
+ onKeyDown: (e) => handleKeyDown(e, i),
161
+ "aria-expanded": isOpen,
162
+ style: {
163
+ width: "100%",
164
+ padding: "8px 12px",
165
+ background: isOpen ? colors.bgSelected : "transparent",
166
+ border: "none",
167
+ font: "inherit",
168
+ fontSize: "12px",
169
+ textAlign: "left",
170
+ cursor: "pointer",
171
+ color: colors.text
172
+ }
173
+ }, /* @__PURE__ */ React.createElement("div", { style: {
174
+ display: "flex",
175
+ alignItems: "center",
176
+ gap: "6px"
177
+ } }, /* @__PURE__ */ React.createElement("span", {
178
+ "aria-hidden": "true",
179
+ style: {
180
+ color: IMPACT_COLOR[v.impact],
181
+ fontWeight: "bold",
182
+ fontSize: "12px"
183
+ }
184
+ }, IMPACT_ICON[v.impact]), /* @__PURE__ */ React.createElement("span", { style: {
185
+ color: IMPACT_COLOR[v.impact],
186
+ fontSize: "11px"
187
+ } }, v.impact), /* @__PURE__ */ React.createElement("code", { style: {
188
+ fontSize: "11px",
189
+ color: colors.ruleId
190
+ } }, v.ruleId)), /* @__PURE__ */ React.createElement("div", { style: {
191
+ marginTop: "2px",
192
+ color: colors.text,
193
+ fontSize: "12px"
194
+ } }, v.message)), isOpen && /* @__PURE__ */ React.createElement("div", { style: {
195
+ padding: "4px 12px 12px",
196
+ background: colors.bgDetails
197
+ } }, v.description && /* @__PURE__ */ React.createElement("p", { style: {
198
+ margin: "4px 0 8px",
199
+ fontSize: "12px",
200
+ color: colors.text
201
+ } }, v.description), /* @__PURE__ */ React.createElement("div", { style: {
202
+ display: "flex",
203
+ gap: "6px",
204
+ flexWrap: "wrap",
205
+ marginBottom: "8px"
206
+ } }, v.level && /* @__PURE__ */ React.createElement("span", { style: {
207
+ display: "inline-block",
208
+ padding: "0 5px",
209
+ fontSize: "10px",
210
+ fontWeight: 600,
211
+ borderRadius: "3px",
212
+ color: "#fff",
213
+ background: LEVEL_COLOR[v.level] || "#666",
214
+ lineHeight: "18px"
215
+ } }, "WCAG ", v.level), v.wcag?.map((ref) => /* @__PURE__ */ React.createElement("span", {
216
+ key: ref,
217
+ style: {
218
+ display: "inline-block",
219
+ padding: "0 5px",
220
+ fontSize: "10px",
221
+ fontWeight: 500,
222
+ borderRadius: "3px",
223
+ color: colors.tagText,
224
+ background: colors.tagBg,
225
+ lineHeight: "18px"
226
+ }
227
+ }, ref))), v.guidance && /* @__PURE__ */ React.createElement("div", { style: { marginBottom: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: {
228
+ fontSize: "11px",
229
+ fontWeight: 500,
230
+ color: colors.textMuted,
231
+ marginBottom: "4px"
232
+ } }, "How to fix"), /* @__PURE__ */ React.createElement("p", { style: {
233
+ margin: 0,
234
+ fontSize: "12px",
235
+ color: colors.text,
236
+ whiteSpace: "pre-wrap"
237
+ } }, v.guidance)), v.html && /* @__PURE__ */ React.createElement("div", { style: { marginBottom: "8px" } }, /* @__PURE__ */ React.createElement("div", { style: {
238
+ display: "flex",
239
+ alignItems: "center",
240
+ justifyContent: "space-between",
241
+ marginBottom: "4px"
242
+ } }, /* @__PURE__ */ React.createElement("div", { style: {
243
+ fontSize: "11px",
244
+ fontWeight: 500,
245
+ color: colors.textMuted
246
+ } }, "Element"), /* @__PURE__ */ React.createElement("button", {
247
+ type: "button",
248
+ onClick: () => {
249
+ if (highlightedIndex === i) {
250
+ emit(REMOVE_HIGHLIGHT);
251
+ setHighlightedIndex(null);
252
+ } else {
253
+ const color = v.impact === "critical" || v.impact === "serious" ? "#d32f2f" : "#c43e00";
254
+ emit(HIGHLIGHT, {
255
+ elements: [v.selector.replace(/^.*>>>\s*iframe>\s*/, "")],
256
+ color,
257
+ style: "solid"
258
+ });
259
+ setHighlightedIndex(i);
260
+ }
261
+ },
262
+ style: {
263
+ padding: "2px 8px",
264
+ fontSize: "11px",
265
+ fontWeight: 500,
266
+ border: `1px solid ${colors.codeBorder}`,
267
+ borderRadius: "4px",
268
+ background: highlightedIndex === i ? IMPACT_COLOR[v.impact] : colors.codeBg,
269
+ color: highlightedIndex === i ? "#fff" : colors.text,
270
+ cursor: "pointer"
271
+ }
272
+ }, "Highlight")), /* @__PURE__ */ React.createElement("pre", { style: {
273
+ margin: 0,
274
+ padding: "6px 8px",
275
+ fontSize: "11px",
276
+ color: colors.text,
277
+ background: colors.codeBg,
278
+ border: `1px solid ${colors.codeBorder}`,
279
+ borderRadius: "4px",
280
+ overflow: "auto",
281
+ whiteSpace: "pre-wrap",
282
+ wordBreak: "break-all"
283
+ } }, v.html))));
284
+ }))));
251
285
  };
252
-
253
- // src/manager.tsx
254
- var { addons, types, useChannel: useChannel2, useStorybookApi } = managerApi;
255
- var PANEL_ID = `${ADDON_ID}/panel`;
256
- var TEST_PROVIDER_ID = `${ADDON_ID}/test-provider`;
257
- var _getStatusStore = managerApi.experimental_getStatusStore;
258
- var _getTestProviderStore = managerApi.experimental_getTestProviderStore;
259
- var _useTestProviderStore = managerApi.experimental_useTestProviderStore ?? null;
260
- var hasTestProvider = !!(_getStatusStore && _getTestProviderStore);
261
- var statusStore = hasTestProvider ? _getStatusStore(STATUS_TYPE_ID) : null;
262
- var testProviderStore = hasTestProvider ? _getTestProviderStore(TEST_PROVIDER_ID) : null;
263
- if (testProviderStore && statusStore) {
264
- testProviderStore.onClearAll(() => {
265
- statusStore.unset();
266
- });
267
- }
268
- var ActionList = null;
269
- var Form = null;
286
+ //#endregion
287
+ //#region src/manager.tsx
288
+ const { addons, types, useChannel: useChannel$1, useStorybookApi } = managerApi;
289
+ const PANEL_ID = `${ADDON_ID}/panel`;
290
+ const TEST_PROVIDER_ID = `${ADDON_ID}/test-provider`;
291
+ const _getStatusStore = managerApi.experimental_getStatusStore;
292
+ const _getTestProviderStore = managerApi.experimental_getTestProviderStore;
293
+ const _useTestProviderStore = managerApi.experimental_useTestProviderStore ?? null;
294
+ const hasTestProvider = !!(_getStatusStore && _getTestProviderStore);
295
+ const statusStore = hasTestProvider ? _getStatusStore(STATUS_TYPE_ID) : null;
296
+ const testProviderStore = hasTestProvider ? _getTestProviderStore(TEST_PROVIDER_ID) : null;
297
+ if (testProviderStore && statusStore) testProviderStore.onClearAll(() => {
298
+ statusStore.unset();
299
+ });
300
+ let ActionList = null;
301
+ let Form = null;
270
302
  try {
271
- const components = __require("storybook/internal/components");
272
- ActionList = components.ActionList ?? null;
273
- Form = components.Form ?? null;
274
- } catch {
275
- }
276
- var Title = () => {
277
- const [count, setCount] = React.useState(0);
278
- useChannel2({
279
- [RESULT_EVENT]: ({ result }) => {
280
- setCount(result.skipped ? 0 : result.violations?.length ?? 0);
281
- }
282
- });
283
- return /* @__PURE__ */ React.createElement(React.Fragment, null, "AccessLint", count > 0 && /* @__PURE__ */ React.createElement("span", { style: {
284
- display: "inline-block",
285
- marginLeft: "8px",
286
- minWidth: "18px",
287
- padding: "0 5px",
288
- lineHeight: "18px",
289
- borderRadius: "9px",
290
- fontSize: "11px",
291
- fontWeight: "bold",
292
- textAlign: "center",
293
- background: "currentColor",
294
- color: "inherit"
295
- } }, /* @__PURE__ */ React.createElement("span", { style: { color: "#fff" } }, count)));
303
+ const components = __require("storybook/internal/components");
304
+ ActionList = components.ActionList ?? null;
305
+ Form = components.Form ?? null;
306
+ } catch {}
307
+ const Title = () => {
308
+ const [count, setCount] = React.useState(0);
309
+ useChannel$1({ [RESULT_EVENT]: ({ result }) => {
310
+ setCount(result.skipped ? 0 : result.violations?.length ?? 0);
311
+ } });
312
+ return /* @__PURE__ */ React.createElement(React.Fragment, null, "AccessLint", count > 0 && /* @__PURE__ */ React.createElement("span", { style: {
313
+ display: "inline-block",
314
+ marginLeft: "8px",
315
+ minWidth: "18px",
316
+ padding: "0 5px",
317
+ lineHeight: "18px",
318
+ borderRadius: "9px",
319
+ fontSize: "11px",
320
+ fontWeight: "bold",
321
+ textAlign: "center",
322
+ background: "currentColor",
323
+ color: "inherit"
324
+ } }, /* @__PURE__ */ React.createElement("span", { style: { color: "#fff" } }, count)));
296
325
  };
297
- var StyledActionList = ActionList ? styled(ActionList)({ padding: 0 }) : styled.div({ padding: 0 });
298
- var StatusDot = styled.div(
299
- {
300
- width: 6,
301
- height: 6,
302
- margin: 4,
303
- borderRadius: "50%",
304
- background: "var(--status-color)"
305
- },
306
- ({ status, theme }) => status === "positive" && {
307
- "--status-color": theme.color.positive
308
- },
309
- ({ status, theme }) => status === "negative" && {
310
- "--status-color": theme.color.negative
311
- },
312
- ({ status, theme }) => status === "unknown" && {
313
- "--status-color": theme.textMutedColor
314
- }
315
- );
316
- var TestProviderWidget = () => {
317
- const [violationCount, setViolationCount] = React.useState(null);
318
- const api = useStorybookApi();
319
- const providerState = _useTestProviderStore ? _useTestProviderStore((state) => state[TEST_PROVIDER_ID]) : null;
320
- React.useEffect(() => {
321
- if (!statusStore) return;
322
- const unsub = statusStore.onSelect(() => {
323
- api.setSelectedPanel(PANEL_ID);
324
- api.togglePanel(true);
325
- });
326
- return unsub;
327
- }, [api]);
328
- useChannel2({
329
- [RESULT_EVENT]: ({ storyId, result, status: status2 }) => {
330
- const violations = result.skipped ? [] : result.violations ?? [];
331
- setViolationCount(violations.length);
332
- if (statusStore && storyId) {
333
- const hasViolations2 = violations.length > 0;
334
- const isWarning = status2 === "warning";
335
- statusStore.set([{
336
- value: result.skipped ? "status-value:unknown" : hasViolations2 ? isWarning ? "status-value:warning" : "status-value:error" : "status-value:success",
337
- typeId: STATUS_TYPE_ID,
338
- storyId,
339
- title: "AccessLint",
340
- description: result.skipped ? "Skipped" : hasViolations2 ? `${violations.length} violation${violations.length === 1 ? "" : "s"}` : "No violations",
341
- sidebarContextMenu: true
342
- }]);
343
- }
344
- if (testProviderStore && providerState === "test-provider-state:running") {
345
- testProviderStore.setState("test-provider-state:succeeded");
346
- }
347
- }
348
- });
349
- const hasViolations = violationCount !== null && violationCount > 0;
350
- const status = violationCount === null ? "unknown" : hasViolations ? "negative" : "positive";
351
- const openPanel = () => {
352
- api.setSelectedPanel(PANEL_ID);
353
- api.togglePanel(true);
354
- };
355
- if (ActionList && Form) {
356
- return /* @__PURE__ */ React.createElement(StyledActionList, null, /* @__PURE__ */ React.createElement(ActionList.Item, null, /* @__PURE__ */ React.createElement(ActionList.Action, { as: "label", readOnly: true }, /* @__PURE__ */ React.createElement(ActionList.Icon, null, /* @__PURE__ */ React.createElement(Form.Checkbox, { name: "AccessLint", checked: true, disabled: true })), /* @__PURE__ */ React.createElement(ActionList.Text, null, "AccessLint")), /* @__PURE__ */ React.createElement(
357
- ActionList.Button,
358
- {
359
- ariaLabel: violationCount === null ? "AccessLint: not run yet" : hasViolations ? `AccessLint: ${violationCount} violation${violationCount === 1 ? "" : "s"}` : "AccessLint: no violations",
360
- disabled: violationCount === null,
361
- onClick: openPanel
362
- },
363
- hasViolations ? violationCount : null,
364
- /* @__PURE__ */ React.createElement(StatusDot, { status })
365
- )));
366
- }
367
- return /* @__PURE__ */ React.createElement(
368
- StyledActionList,
369
- {
370
- style: { display: "flex", alignItems: "center", gap: 8, padding: "6px 8px", cursor: "pointer" },
371
- onClick: openPanel
372
- },
373
- /* @__PURE__ */ React.createElement(StatusDot, { status }),
374
- /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12 } }, "AccessLint"),
375
- hasViolations && /* @__PURE__ */ React.createElement("span", { style: { fontSize: 11, fontWeight: "bold" } }, violationCount)
376
- );
326
+ const StyledActionList = ActionList ? styled(ActionList)({ padding: 0 }) : styled.div({ padding: 0 });
327
+ const StatusDot = styled.div({
328
+ width: 6,
329
+ height: 6,
330
+ margin: 4,
331
+ borderRadius: "50%",
332
+ background: "var(--status-color)"
333
+ }, ({ status, theme }) => status === "positive" && { "--status-color": theme.color.positive }, ({ status, theme }) => status === "negative" && { "--status-color": theme.color.negative }, ({ status, theme }) => status === "unknown" && { "--status-color": theme.textMutedColor });
334
+ const TestProviderWidget = () => {
335
+ const [violationCount, setViolationCount] = React.useState(null);
336
+ const api = useStorybookApi();
337
+ const providerState = _useTestProviderStore ? _useTestProviderStore((state) => state[TEST_PROVIDER_ID]) : null;
338
+ React.useEffect(() => {
339
+ if (!statusStore) return;
340
+ return statusStore.onSelect(() => {
341
+ api.setSelectedPanel(PANEL_ID);
342
+ api.togglePanel(true);
343
+ });
344
+ }, [api]);
345
+ useChannel$1({ [RESULT_EVENT]: ({ storyId, result, status }) => {
346
+ const violations = result.skipped ? [] : result.violations ?? [];
347
+ setViolationCount(violations.length);
348
+ if (statusStore && storyId) {
349
+ const hasViolations = violations.length > 0;
350
+ const isWarning = status === "warning";
351
+ statusStore.set([{
352
+ value: result.skipped ? "status-value:unknown" : hasViolations ? isWarning ? "status-value:warning" : "status-value:error" : "status-value:success",
353
+ typeId: STATUS_TYPE_ID,
354
+ storyId,
355
+ title: "AccessLint",
356
+ description: result.skipped ? "Skipped" : hasViolations ? `${violations.length} violation${violations.length === 1 ? "" : "s"}` : "No violations",
357
+ sidebarContextMenu: true
358
+ }]);
359
+ }
360
+ if (testProviderStore && providerState === "test-provider-state:running") testProviderStore.setState("test-provider-state:succeeded");
361
+ } });
362
+ const hasViolations = violationCount !== null && violationCount > 0;
363
+ const status = violationCount === null ? "unknown" : hasViolations ? "negative" : "positive";
364
+ const openPanel = () => {
365
+ api.setSelectedPanel(PANEL_ID);
366
+ api.togglePanel(true);
367
+ };
368
+ if (ActionList && Form) return /* @__PURE__ */ React.createElement(StyledActionList, null, /* @__PURE__ */ React.createElement(ActionList.Item, null, /* @__PURE__ */ React.createElement(ActionList.Action, {
369
+ as: "label",
370
+ readOnly: true
371
+ }, /* @__PURE__ */ React.createElement(ActionList.Icon, null, /* @__PURE__ */ React.createElement(Form.Checkbox, {
372
+ name: "AccessLint",
373
+ checked: true,
374
+ disabled: true
375
+ })), /* @__PURE__ */ React.createElement(ActionList.Text, null, "AccessLint")), /* @__PURE__ */ React.createElement(ActionList.Button, {
376
+ ariaLabel: violationCount === null ? "AccessLint: not run yet" : hasViolations ? `AccessLint: ${violationCount} violation${violationCount === 1 ? "" : "s"}` : "AccessLint: no violations",
377
+ disabled: violationCount === null,
378
+ onClick: openPanel
379
+ }, hasViolations ? violationCount : null, /* @__PURE__ */ React.createElement(StatusDot, { status }))));
380
+ return /* @__PURE__ */ React.createElement(StyledActionList, {
381
+ style: {
382
+ display: "flex",
383
+ alignItems: "center",
384
+ gap: 8,
385
+ padding: "6px 8px",
386
+ cursor: "pointer"
387
+ },
388
+ onClick: openPanel
389
+ }, /* @__PURE__ */ React.createElement(StatusDot, { status }), /* @__PURE__ */ React.createElement("span", { style: { fontSize: 12 } }, "AccessLint"), hasViolations && /* @__PURE__ */ React.createElement("span", { style: {
390
+ fontSize: 11,
391
+ fontWeight: "bold"
392
+ } }, violationCount));
377
393
  };
378
- var SidebarContextMenu = ({ context }) => {
379
- const api = useStorybookApi();
380
- if (context.type !== "story" || !ActionList) return null;
381
- return /* @__PURE__ */ React.createElement(
382
- ActionList.Item,
383
- {
384
- onClick: () => {
385
- api.selectStory(context.id);
386
- api.setSelectedPanel(PANEL_ID);
387
- api.togglePanel(true);
388
- }
389
- },
390
- /* @__PURE__ */ React.createElement(ActionList.Text, null, "View AccessLint results")
391
- );
394
+ const SidebarContextMenu = ({ context }) => {
395
+ const api = useStorybookApi();
396
+ if (context.type !== "story" || !ActionList) return null;
397
+ return /* @__PURE__ */ React.createElement(ActionList.Item, { onClick: () => {
398
+ api.selectStory(context.id);
399
+ api.setSelectedPanel(PANEL_ID);
400
+ api.togglePanel(true);
401
+ } }, /* @__PURE__ */ React.createElement(ActionList.Text, null, "View AccessLint results"));
392
402
  };
393
403
  addons.register(ADDON_ID, () => {
394
- addons.add(PANEL_ID, {
395
- title: Title,
396
- type: types.PANEL,
397
- render: Panel,
398
- paramKey: PARAM_KEY
399
- });
400
- if (hasTestProvider && types.experimental_TEST_PROVIDER) {
401
- addons.add(TEST_PROVIDER_ID, {
402
- type: types.experimental_TEST_PROVIDER,
403
- render: () => /* @__PURE__ */ React.createElement(TestProviderWidget, null),
404
- sidebarContextMenu: ({ context }) => /* @__PURE__ */ React.createElement(SidebarContextMenu, { context })
405
- });
406
- }
404
+ addons.add(PANEL_ID, {
405
+ title: Title,
406
+ type: types.PANEL,
407
+ render: Panel,
408
+ paramKey: PARAM_KEY
409
+ });
410
+ if (hasTestProvider && types.experimental_TEST_PROVIDER) addons.add(TEST_PROVIDER_ID, {
411
+ type: types.experimental_TEST_PROVIDER,
412
+ render: () => /* @__PURE__ */ React.createElement(TestProviderWidget, null),
413
+ sidebarContextMenu: ({ context }) => /* @__PURE__ */ React.createElement(SidebarContextMenu, { context })
414
+ });
407
415
  });
416
+ //#endregion