@techsio/storybook-better-a11y 0.0.1 → 0.0.3
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/699.js +15 -2
- package/dist/a11yRunner.d.ts.map +1 -1
- package/dist/apcaChecker.d.ts +1 -1
- package/dist/apcaChecker.d.ts.map +1 -1
- package/dist/components/Tabs.d.ts.map +1 -1
- package/dist/components/VisionSimulator.d.ts.map +1 -1
- package/dist/manager.js +58 -30
- package/package.json +16 -2
package/dist/699.js
CHANGED
|
@@ -191,7 +191,7 @@ function isVisible(element) {
|
|
|
191
191
|
const computed = global.getComputedStyle(element);
|
|
192
192
|
return 'none' !== computed.display && 'hidden' !== computed.visibility && '0' !== computed.opacity;
|
|
193
193
|
}
|
|
194
|
-
async function runAPCACheck(context = apcaChecker_document, options = DEFAULT_APCA_OPTIONS) {
|
|
194
|
+
async function runAPCACheck(context = apcaChecker_document, options = DEFAULT_APCA_OPTIONS, excludeSelectors = []) {
|
|
195
195
|
const { APCAcontrast, sRGBtoY, fontLookupAPCA } = await import("apca-w3");
|
|
196
196
|
const apcaOptions = {
|
|
197
197
|
...DEFAULT_APCA_OPTIONS,
|
|
@@ -201,6 +201,16 @@ async function runAPCACheck(context = apcaChecker_document, options = DEFAULT_AP
|
|
|
201
201
|
const root = context instanceof Document ? context.body : context;
|
|
202
202
|
const textElements = root.querySelectorAll('p, span, div, h1, h2, h3, h4, h5, h6, a, button, label, td, th, li, input, textarea');
|
|
203
203
|
textElements.forEach((element)=>{
|
|
204
|
+
if (excludeSelectors.length > 0) {
|
|
205
|
+
const isExcluded = excludeSelectors.some((selector)=>{
|
|
206
|
+
try {
|
|
207
|
+
return null !== element.closest(selector);
|
|
208
|
+
} catch {
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
});
|
|
212
|
+
if (isExcluded) return;
|
|
213
|
+
}
|
|
204
214
|
if (!isVisible(element) || !hasReadableText(element)) return;
|
|
205
215
|
const foreground = getComputedColor(element, 'color');
|
|
206
216
|
const background = getEffectiveBackgroundColor(element);
|
|
@@ -381,7 +391,10 @@ const run = async (input = DEFAULT_PARAMETERS, storyId)=>{
|
|
|
381
391
|
if (first instanceof Element) contextElement = first;
|
|
382
392
|
else if ('string' == typeof first) contextElement = a11yRunner_document.querySelector(first) || a11yRunner_document;
|
|
383
393
|
} else if ('string' == typeof context.include) contextElement = a11yRunner_document.querySelector(context.include) || a11yRunner_document;
|
|
384
|
-
const
|
|
394
|
+
const excludeSelectors = Array.isArray(context.exclude) ? context.exclude.filter((value)=>'string' == typeof value) : 'string' == typeof context.exclude ? [
|
|
395
|
+
context.exclude
|
|
396
|
+
] : [];
|
|
397
|
+
const apcaResult = await runAPCACheck(contextElement, input.apca, excludeSelectors);
|
|
385
398
|
if (apcaResult.nodes.length > 0) result.violations.push(apcaResult);
|
|
386
399
|
else result.passes.push(apcaResult);
|
|
387
400
|
const resultWithLinks = withLinkPaths(result, storyId);
|
package/dist/a11yRunner.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"a11yRunner.d.ts","sourceRoot":"","sources":["../src/a11yRunner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,UAAU,CAAC;AAMrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAiC/C,eAAO,MAAM,GAAG,GAAU,OAAO,cAAc,YAAqB,EAAE,SAAS,MAAM,
|
|
1
|
+
{"version":3,"file":"a11yRunner.d.ts","sourceRoot":"","sources":["../src/a11yRunner.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,UAAU,EAA4B,MAAM,UAAU,CAAC;AAMrE,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,UAAU,CAAC;AAiC/C,eAAO,MAAM,GAAG,GAAU,OAAO,cAAc,YAAqB,EAAE,SAAS,MAAM,wBAkHpF,CAAC"}
|
package/dist/apcaChecker.d.ts
CHANGED
|
@@ -8,6 +8,6 @@ interface ApcaOptions {
|
|
|
8
8
|
/**
|
|
9
9
|
* Run APCA contrast checks on the document
|
|
10
10
|
*/
|
|
11
|
-
export declare function runAPCACheck(context?: Element | Document, options?: ApcaOptions): Promise<Result>;
|
|
11
|
+
export declare function runAPCACheck(context?: Element | Document, options?: ApcaOptions, excludeSelectors?: string[]): Promise<Result>;
|
|
12
12
|
export {};
|
|
13
13
|
//# sourceMappingURL=apcaChecker.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"apcaChecker.d.ts","sourceRoot":"","sources":["../src/apcaChecker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,UAAU,CAAC;AAYnD,KAAK,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACzD,KAAK,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAC;AAEnE,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AA8OD;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,GAAE,OAAO,GAAG,QAAmB,EACtC,OAAO,GAAE,WAAkC,
|
|
1
|
+
{"version":3,"file":"apcaChecker.d.ts","sourceRoot":"","sources":["../src/apcaChecker.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,MAAM,EAAc,MAAM,UAAU,CAAC;AAYnD,KAAK,oBAAoB,GAAG,QAAQ,GAAG,QAAQ,GAAG,MAAM,CAAC;AACzD,KAAK,WAAW,GAAG,MAAM,GAAG,QAAQ,GAAG,YAAY,GAAG,YAAY,CAAC;AAEnE,UAAU,WAAW;IACnB,KAAK,CAAC,EAAE,oBAAoB,CAAC;IAC7B,OAAO,CAAC,EAAE,WAAW,CAAC;CACvB;AA8OD;;GAEG;AACH,wBAAsB,YAAY,CAChC,OAAO,GAAE,OAAO,GAAG,QAAmB,EACtC,OAAO,GAAE,WAAkC,EAC3C,gBAAgB,GAAE,MAAM,EAAO,GAC9B,OAAO,CAAC,MAAM,CAAC,CA+KjB"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/components/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAkBzC,UAAU,SAAS;IACjB,IAAI,EAAE;QACJ,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;QAC1B,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;QAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,QAAQ,CAAC;KAChB,EAAE,CAAC;CACL;
|
|
1
|
+
{"version":3,"file":"Tabs.d.ts","sourceRoot":"","sources":["../../src/components/Tabs.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAC;AAM/B,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,UAAU,CAAC;AAGvC,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAC;AAkBzC,UAAU,SAAS;IACjB,IAAI,EAAE;QACJ,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;QAC1B,KAAK,EAAE,KAAK,CAAC,YAAY,CAAC;QAC1B,KAAK,EAAE,MAAM,EAAE,CAAC;QAChB,IAAI,EAAE,QAAQ,CAAC;KAChB,EAAE,CAAC;CACL;AAQD,eAAO,MAAM,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC,SAAS,CA8DpC,CAAC"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"VisionSimulator.d.ts","sourceRoot":"","sources":["../../src/components/VisionSimulator.tsx"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"VisionSimulator.d.ts","sourceRoot":"","sources":["../../src/components/VisionSimulator.tsx"],"names":[],"mappings":"AA8DA,eAAO,MAAM,eAAe,+CAuC3B,CAAC"}
|
package/dist/manager.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import react, { Fragment, createContext, createElement, useCallback, useContext, useEffect, useMemo, useState } from "react";
|
|
2
|
-
import { Badge, Button, EmptyTabContent, Link,
|
|
2
|
+
import { Badge, Button, EmptyTabContent, Link, SyntaxHighlighter, Tabs } from "storybook/internal/components";
|
|
3
3
|
import { addons, experimental_getStatusStore, experimental_useStatusStore, types, useAddonState, useChannel, useGlobals, useParameter, useStorybookApi, useStorybookState } from "storybook/manager-api";
|
|
4
4
|
import { AccessibilityIcon, CheckIcon, ChevronSmallDownIcon, CollapseIcon, CopyIcon, ExpandAltIcon, EyeCloseIcon, EyeIcon, LocationIcon, SyncIcon } from "@storybook/icons";
|
|
5
5
|
import { convert, styled, themes, useTheme } from "storybook/theming";
|
|
@@ -1246,21 +1246,18 @@ const ActionsWrapper = styled.div({
|
|
|
1246
1246
|
justifyContent: 'flex-end',
|
|
1247
1247
|
gap: 6
|
|
1248
1248
|
});
|
|
1249
|
-
const
|
|
1249
|
+
const TabPanel = ({ id, children })=>/*#__PURE__*/ createElement("div", {
|
|
1250
|
+
id: id
|
|
1251
|
+
}, children);
|
|
1252
|
+
const Tabs_Tabs = ({ tabs })=>{
|
|
1250
1253
|
const { tab, setTab, toggleHighlight, highlighted, handleManual, allExpanded, handleCollapseAll, handleExpandAll } = useA11yContext();
|
|
1251
1254
|
const theme = useTheme();
|
|
1252
|
-
return /*#__PURE__*/ createElement(Container, null, /*#__PURE__*/ createElement(
|
|
1255
|
+
return /*#__PURE__*/ createElement(Container, null, /*#__PURE__*/ createElement(Tabs, {
|
|
1253
1256
|
backgroundColor: theme.background.app,
|
|
1254
|
-
panelProps: {
|
|
1255
|
-
hasScrollbar: true
|
|
1256
|
-
},
|
|
1257
|
-
tabs: tabs.map((tab)=>({
|
|
1258
|
-
id: tab.type,
|
|
1259
|
-
title: tab.label,
|
|
1260
|
-
children: tab.panel
|
|
1261
|
-
})),
|
|
1262
1257
|
selected: tab,
|
|
1263
|
-
|
|
1258
|
+
actions: {
|
|
1259
|
+
onSelect: (id)=>setTab(id)
|
|
1260
|
+
},
|
|
1264
1261
|
tools: /*#__PURE__*/ createElement(ActionsWrapper, null, /*#__PURE__*/ createElement(Button, {
|
|
1265
1262
|
variant: "ghost",
|
|
1266
1263
|
padding: "small",
|
|
@@ -1278,7 +1275,11 @@ const Tabs = ({ tabs })=>{
|
|
|
1278
1275
|
onClick: handleManual,
|
|
1279
1276
|
ariaLabel: "Rerun accessibility scan"
|
|
1280
1277
|
}, /*#__PURE__*/ createElement(SyncIcon, null)))
|
|
1281
|
-
})
|
|
1278
|
+
}, tabs.map((tabItem)=>/*#__PURE__*/ createElement(TabPanel, {
|
|
1279
|
+
key: tabItem.type,
|
|
1280
|
+
id: tabItem.type,
|
|
1281
|
+
title: tabItem.label
|
|
1282
|
+
}, tabItem.panel))));
|
|
1282
1283
|
};
|
|
1283
1284
|
const TestDiscrepancyMessage_Wrapper = styled.div(({ theme: { color, typography, background } })=>({
|
|
1284
1285
|
textAlign: 'start',
|
|
@@ -1434,7 +1435,7 @@ const A11YPanel = ()=>{
|
|
|
1434
1435
|
if (parameters.disable || 'off' === parameters.test) return /*#__PURE__*/ react.createElement(Centered, null, /*#__PURE__*/ react.createElement("div", null, /*#__PURE__*/ react.createElement("strong", null, "Accessibility tests are disabled for this story"), /*#__PURE__*/ react.createElement("p", null, "Update", ' ', /*#__PURE__*/ react.createElement("code", null, parameters.disable ? 'parameters.a11y.disable' : 'parameters.a11y.test'), ' ', "to enable accessibility tests.")));
|
|
1435
1436
|
return /*#__PURE__*/ react.createElement(react.Fragment, null, discrepancy && /*#__PURE__*/ react.createElement(TestDiscrepancyMessage, {
|
|
1436
1437
|
discrepancy: discrepancy
|
|
1437
|
-
}), 'ready' === status || 'ran' === status ? /*#__PURE__*/ react.createElement(
|
|
1438
|
+
}), 'ready' === status || 'ran' === status ? /*#__PURE__*/ react.createElement(Tabs_Tabs, {
|
|
1438
1439
|
key: "tabs",
|
|
1439
1440
|
tabs: tabs
|
|
1440
1441
|
}) : /*#__PURE__*/ react.createElement(Centered, {
|
|
@@ -1478,30 +1479,57 @@ const ColorIcon = styled.span({
|
|
|
1478
1479
|
}), ({ theme })=>({
|
|
1479
1480
|
boxShadow: `${theme.appBorderColor} 0 0 0 1px inset`
|
|
1480
1481
|
}));
|
|
1482
|
+
const SelectRow = styled.div(({ theme })=>({
|
|
1483
|
+
display: 'flex',
|
|
1484
|
+
alignItems: 'center',
|
|
1485
|
+
gap: 8,
|
|
1486
|
+
padding: '6px 10px',
|
|
1487
|
+
border: `1px solid ${theme.appBorderColor}`,
|
|
1488
|
+
borderRadius: theme.appBorderRadius,
|
|
1489
|
+
background: theme.background.content
|
|
1490
|
+
}));
|
|
1491
|
+
const SelectInput = styled.select(({ theme })=>({
|
|
1492
|
+
flex: 1,
|
|
1493
|
+
minWidth: 0,
|
|
1494
|
+
padding: '4px 6px',
|
|
1495
|
+
border: `1px solid ${theme.appBorderColor}`,
|
|
1496
|
+
borderRadius: theme.appBorderRadius,
|
|
1497
|
+
background: theme.background.app,
|
|
1498
|
+
color: theme.color.defaultText,
|
|
1499
|
+
fontSize: theme.typography.size.s2
|
|
1500
|
+
}));
|
|
1501
|
+
const ResetButton = styled(Button)({
|
|
1502
|
+
whiteSpace: 'nowrap'
|
|
1503
|
+
});
|
|
1481
1504
|
const VisionSimulator = ()=>{
|
|
1482
1505
|
const [globals, updateGlobals] = useGlobals();
|
|
1483
1506
|
const value = globals["vision"];
|
|
1484
1507
|
const options = Object.entries(filters).map(([key, { label, percentage }])=>({
|
|
1485
|
-
|
|
1486
|
-
description: percentage ? `${percentage}% of users` : void 0,
|
|
1487
|
-
icon: /*#__PURE__*/ react.createElement(ColorIcon, {
|
|
1488
|
-
$filter: key
|
|
1489
|
-
}),
|
|
1508
|
+
label: percentage ? `${label} (${percentage}% of users)` : label,
|
|
1490
1509
|
value: key
|
|
1491
1510
|
}));
|
|
1492
|
-
return /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(
|
|
1493
|
-
|
|
1494
|
-
|
|
1511
|
+
return /*#__PURE__*/ react.createElement(react.Fragment, null, /*#__PURE__*/ react.createElement(SelectRow, {
|
|
1512
|
+
"aria-label": "Vision simulator"
|
|
1513
|
+
}, /*#__PURE__*/ react.createElement(AccessibilityIcon, null), /*#__PURE__*/ react.createElement(ColorIcon, {
|
|
1514
|
+
$filter: String(value || 'none')
|
|
1515
|
+
}), /*#__PURE__*/ react.createElement(SelectInput, {
|
|
1516
|
+
value: value ?? '',
|
|
1517
|
+
onChange: (event)=>updateGlobals({
|
|
1518
|
+
["vision"]: event.target.value || void 0
|
|
1519
|
+
})
|
|
1520
|
+
}, /*#__PURE__*/ react.createElement("option", {
|
|
1521
|
+
value: ""
|
|
1522
|
+
}, "No filter"), options.map((option)=>/*#__PURE__*/ react.createElement("option", {
|
|
1523
|
+
key: option.value,
|
|
1524
|
+
value: option.value
|
|
1525
|
+
}, option.label))), /*#__PURE__*/ react.createElement(ResetButton, {
|
|
1526
|
+
variant: "ghost",
|
|
1527
|
+
padding: "small",
|
|
1528
|
+
onClick: ()=>updateGlobals({
|
|
1495
1529
|
["vision"]: void 0
|
|
1496
1530
|
}),
|
|
1497
|
-
|
|
1498
|
-
|
|
1499
|
-
defaultOptions: value,
|
|
1500
|
-
options: options,
|
|
1501
|
-
onSelect: (selected)=>updateGlobals({
|
|
1502
|
-
["vision"]: selected
|
|
1503
|
-
})
|
|
1504
|
-
}), /*#__PURE__*/ react.createElement(Hidden, {
|
|
1531
|
+
ariaLabel: "Reset color filter"
|
|
1532
|
+
}, "Reset")), /*#__PURE__*/ react.createElement(Hidden, {
|
|
1505
1533
|
dangerouslySetInnerHTML: {
|
|
1506
1534
|
__html: filterDefs
|
|
1507
1535
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@techsio/storybook-better-a11y",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.3",
|
|
4
4
|
"description": "Storybook Accessibility addon with APCA (WCAG 3) support",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"storybook",
|
|
@@ -12,6 +12,11 @@
|
|
|
12
12
|
],
|
|
13
13
|
"license": "MIT",
|
|
14
14
|
"type": "module",
|
|
15
|
+
"repository": {
|
|
16
|
+
"type": "git",
|
|
17
|
+
"url": "https://github.com/NMIT-WR/storybook-addons",
|
|
18
|
+
"directory": "packages/addon-a11y-apca"
|
|
19
|
+
},
|
|
15
20
|
"exports": {
|
|
16
21
|
".": {
|
|
17
22
|
"types": "./dist/index.d.ts",
|
|
@@ -33,7 +38,8 @@
|
|
|
33
38
|
"scripts": {
|
|
34
39
|
"build": "rslib build",
|
|
35
40
|
"lint": "eslint .",
|
|
36
|
-
"test": "vitest run"
|
|
41
|
+
"test": "vitest run",
|
|
42
|
+
"semantic-release": "semantic-release"
|
|
37
43
|
},
|
|
38
44
|
"dependencies": {
|
|
39
45
|
"@storybook/global": "^5.0.0",
|
|
@@ -43,10 +49,18 @@
|
|
|
43
49
|
"devDependencies": {
|
|
44
50
|
"@types/react": "^18.2.66",
|
|
45
51
|
"@types/react-dom": "^18.2.21",
|
|
52
|
+
"@semantic-release/changelog": "^6.0.3",
|
|
53
|
+
"@semantic-release/commit-analyzer": "^13.0.1",
|
|
54
|
+
"@semantic-release/git": "^10.0.1",
|
|
55
|
+
"@semantic-release/github": "^12.0.2",
|
|
56
|
+
"@semantic-release/npm": "^13.1.2",
|
|
57
|
+
"@semantic-release/release-notes-generator": "^14.1.0",
|
|
46
58
|
"@radix-ui/react-tabs": "^1.0.4",
|
|
47
59
|
"@storybook/icons": "^2.0.1",
|
|
60
|
+
"rsbuild-plugin-publint": "^0.3.3",
|
|
48
61
|
"react": "^18.2.0",
|
|
49
62
|
"react-dom": "^18.2.0",
|
|
63
|
+
"semantic-release": "^25.0.2",
|
|
50
64
|
"storybook": "^10.0.0",
|
|
51
65
|
"vitest-axe": "^0.1.0"
|
|
52
66
|
},
|