{"id":45167855,"url":"https://github.com/accesslint/storybook-addon","last_synced_at":"2026-02-22T09:01:04.831Z","repository":{"id":338722123,"uuid":"1158866387","full_name":"AccessLint/storybook-addon","owner":"AccessLint","description":"Storybook addon for accessibility auditing powered by AccessLint","archived":false,"fork":false,"pushed_at":"2026-02-20T00:44:28.000Z","size":122,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-02-20T09:33:39.557Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"TypeScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/AccessLint.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-02-16T02:37:42.000Z","updated_at":"2026-02-20T00:44:32.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/AccessLint/storybook-addon","commit_stats":null,"previous_names":["accesslint/storybook-addon"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/AccessLint/storybook-addon","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccessLint%2Fstorybook-addon","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccessLint%2Fstorybook-addon/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccessLint%2Fstorybook-addon/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccessLint%2Fstorybook-addon/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/AccessLint","download_url":"https://codeload.github.com/AccessLint/storybook-addon/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/AccessLint%2Fstorybook-addon/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29676971,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-21T06:23:40.028Z","status":"ssl_error","status_checked_at":"2026-02-21T06:23:39.222Z","response_time":107,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2026-02-20T07:30:38.370Z","updated_at":"2026-02-21T08:00:49.053Z","avatar_url":"https://github.com/AccessLint.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![npm version](https://img.shields.io/npm/v/@accesslint/storybook-addon)](https://www.npmjs.com/package/@accesslint/storybook-addon)\n[![license](https://img.shields.io/github/license/AccessLint/storybook-addon)](https://github.com/AccessLint/storybook-addon/blob/main/LICENSE)\n\n# @accesslint/storybook-addon\n\nCatch accessibility violations in your Storybook stories as you develop. Powered by [@accesslint/core](https://www.accesslint.com/core?ref=readme_storybook).\n\n\u003cimg 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\" /\u003e\n\n\n## Getting Started\n\n```sh\nnpm install @accesslint/storybook-addon\n```\n\nAdd the addon to your `.storybook/main.ts` (or `.storybook/main.js`):\n\n```ts\nconst config = {\n  addons: [\"@accesslint/storybook-addon\"],\n};\n\nexport default config;\n```\n\nRestart Storybook and an **AccessLint** panel will appear in the addon bar. Every story is audited automatically after it renders.\n\nExpand any violation to see the failing element, WCAG criteria, and remediation guidance. Click **Highlight** to outline the element in the preview.\n\n## Vitest integration\n\nIf 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:\n\n```ts\nimport { accesslintTest } from \"@accesslint/storybook-addon/vitest-plugin\";\n\n// Inside your Storybook test project:\nplugins: [\n  storybookTest({ configDir: \".storybook\" }),\n  accesslintTest(),\n],\n```\n\nThis gives you:\n\n- Per-story status dots in the sidebar (green/yellow/red)\n- A test widget in the sidebar's testing module\n- The `toBeAccessible()` matcher registered automatically\n- Accessibility results in CI alongside your component tests\n\n## Accessibility assertions\n\nUse `toBeAccessible()` to make accessibility a first-class assertion in your tests and play functions.\n\n### With the Vitest plugin\n\nIf you added `accesslintTest()` above, the matcher is already registered. Use it directly in play functions:\n\n```ts\nimport { expect } from \"storybook/test\";\n\nexport const Default = {\n  play: async ({ canvasElement }) =\u003e {\n    await expect(canvasElement).toBeAccessible();\n  },\n};\n```\n\n### Without the Vitest plugin\n\nFor play functions or standalone tests without the plugin, import the matchers entry point to register `toBeAccessible()`:\n\n```ts\nimport \"@accesslint/storybook-addon/matchers\";\n```\n\nThen use it in a play function:\n\n```ts\nimport { expect } from \"storybook/test\";\nimport \"@accesslint/storybook-addon/matchers\";\n\nexport const Default = {\n  play: async ({ canvasElement }) =\u003e {\n    await expect(canvasElement).toBeAccessible();\n  },\n};\n```\n\nOr in a standalone Vitest/Jest test:\n\n```ts\nimport \"@accesslint/storybook-addon/matchers\";\nimport { render } from \"@testing-library/react\";\n\ntest(\"LoginForm is accessible\", () =\u003e {\n  const { container } = render(\u003cLoginForm /\u003e);\n  expect(container).toBeAccessible();\n});\n```\n\n### Disabling rules per assertion\n\n```ts\nawait expect(canvasElement).toBeAccessible({\n  disabledRules: [\"accesslint-045\"],\n});\n```\n\n### Failure output\n\nWhen the assertion fails, the error message lists each violation with its rule ID, WCAG criteria, conformance level, message, and the CSS selector of the failing element:\n\n```\nExpected element to have no accessibility violations, but found 2:\n\n  accesslint-001 [A] (1.1.1): Image is missing alt text\n    img[src=\"hero.png\"]\n\n  accesslint-012 [A] (1.3.1): Form input is missing a label\n    input[type=\"email\"]\n```\n\n### TypeScript support\n\nAdd the type reference to your `tsconfig.json`:\n\n```json\n{\n  \"compilerOptions\": {\n    \"types\": [\"@accesslint/storybook-addon/matchers\"]\n  }\n}\n```\n\nOr add a triple-slash reference in a `.d.ts` file:\n\n```ts\n/// \u003creference types=\"@accesslint/storybook-addon/matchers\" /\u003e\n```\n\n## Configuration\n\n### Test mode\n\nControl how violations are reported via `parameters.accesslint`:\n\n```ts\n// .storybook/preview.ts — applies to all stories\nconst preview = {\n  parameters: {\n    accesslint: {\n      test: \"todo\", // \"error\" (default) | \"todo\" | \"off\"\n    },\n  },\n};\n\nexport default preview;\n```\n\n| Mode | Behavior |\n| --- | --- |\n| `\"error\"` | Violations fail the test (default) |\n| `\"todo\"` | Violations show as warnings — yellow sidebar dots, non-blocking in CI |\n| `\"off\"` | Skip auditing entirely |\n\nOverride per-story:\n\n```ts\nexport const Experimental = {\n  parameters: {\n    accesslint: { test: \"off\" },\n  },\n};\n```\n\n### Disabling rules\n\nDisable specific rules globally in your preview file:\n\n```ts\n// .storybook/preview.ts\nimport { configureRules } from \"@accesslint/core\";\n\nconfigureRules({\n  disabledRules: [\"accesslint-045\"], // e.g. disable landmark region rule\n});\n```\n\n### Skipping stories with tags\n\nTag individual stories or entire components with `\"skip-accesslint\"` to skip auditing:\n\n```ts\n// Skip a single story\nexport const Prototype = {\n  tags: [\"skip-accesslint\"],\n};\n\n// Skip all stories for a component\nexport default {\n  component: ExperimentalWidget,\n  tags: [\"skip-accesslint\"],\n};\n```\n\nWith the Vitest plugin, you can also define custom skip tags:\n\n```ts\naccesslintTest({\n  tags: { skip: [\"skip-accesslint\", \"wip\"] },\n});\n```\n\n## Portable stories\n\nUse AccessLint with [`composeStories`](https://storybook.js.org/docs/api/portable-stories/portable-stories-vitest) outside of Storybook (plain Vitest, Jest, or Playwright CT).\n\nIn your test setup file, pass the AccessLint annotations to `setProjectAnnotations`:\n\n```ts\n// vitest.setup.ts\nimport { setProjectAnnotations } from \"@storybook/react\";\nimport { enableAccessLint } from \"@accesslint/storybook-addon/portable\";\nimport * as previewAnnotations from \"./.storybook/preview\";\n\nconst project = setProjectAnnotations([\n  previewAnnotations,\n  enableAccessLint(),\n]);\n\nbeforeAll(project.beforeAll);\n```\n\nThen in your tests:\n\n```ts\nimport { composeStories } from \"@storybook/react\";\nimport * as stories from \"./Button.stories\";\n\nconst { Primary } = composeStories(stories);\n\ntest(\"Primary button is accessible\", async () =\u003e {\n  await Primary.run();\n  // AccessLint afterEach runs automatically via the annotations\n});\n```\n\n## API reference\n\n### Exports\n\n| Entry point | Description |\n| --- | --- |\n| `@accesslint/storybook-addon` | Main addon registration (manager + preview) |\n| `@accesslint/storybook-addon/vitest-plugin` | `accesslintTest()` Vite plugin for Vitest integration |\n| `@accesslint/storybook-addon/vitest-setup` | Setup file registered by the Vite plugin |\n| `@accesslint/storybook-addon/matchers` | `toBeAccessible()` custom matcher |\n| `@accesslint/storybook-addon/portable` | `enableAccessLint()` for portable stories |\n| `@accesslint/storybook-addon/preview` | Preview annotations (afterEach hook) |\n\n### `accesslintTest(options?)`\n\nVite plugin that registers AccessLint's `afterEach` annotation and the `toBeAccessible()` matcher for Vitest story tests.\n\n| Option | Type | Description |\n| --- | --- | --- |\n| `tags.skip` | `string[]` | Stories with any of these tags will not be audited |\n\n### `parameters.accesslint`\n\n| Parameter | Type | Default | Description |\n| --- | --- | --- | --- |\n| `test` | `\"todo\" \\| \"error\" \\| \"off\"` | `\"error\"` | Controls how violations are reported |\n| `disable` | `boolean` | `false` | Set to `true` to skip auditing (same as `test: \"off\"`) |\n\n### `toBeAccessible(options?)`\n\nCustom matcher for asserting an element has no accessibility violations.\n\n| Option | Type | Description |\n| --- | --- | --- |\n| `disabledRules` | `string[]` | Rule IDs to skip for this assertion |\n\n### `enableAccessLint()`\n\nReturns AccessLint's preview annotations for use with `setProjectAnnotations` in portable stories setups.\n\n## Compatibility\n\n| Addon version | Storybook version |\n| ------------- | ----------------- |\n| 0.7.x         | 10.x              |\n| 0.6.x         | 10.x              |\n\n## Issues\n\nPlease report issues in the [AccessLint core repository](https://github.com/AccessLint/core/issues).\n\n## License\n\nMIT\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccesslint%2Fstorybook-addon","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faccesslint%2Fstorybook-addon","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faccesslint%2Fstorybook-addon/lists"}