{"id":13727066,"url":"https://github.com/pmndrs/react-three-a11y","last_synced_at":"2025-05-14T20:02:29.787Z","repository":{"id":40323135,"uuid":"326679539","full_name":"pmndrs/react-three-a11y","owner":"pmndrs","description":"♿️ Accessibility tools for React Three Fiber","archived":false,"fork":false,"pushed_at":"2024-12-01T02:03:18.000Z","size":34207,"stargazers_count":579,"open_issues_count":12,"forks_count":17,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-05-08T19:37:58.164Z","etag":null,"topics":["a11y","accessibility","react-three-fiber","reactjs","threejs"],"latest_commit_sha":null,"homepage":"https://docs.pmnd.rs/a11y/introduction","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/pmndrs.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}},"created_at":"2021-01-04T12:39:31.000Z","updated_at":"2025-05-02T07:33:54.000Z","dependencies_parsed_at":"2024-01-15T01:04:02.791Z","dependency_job_id":"7e0f5653-73f4-416b-b949-869d90a2c8bb","html_url":"https://github.com/pmndrs/react-three-a11y","commit_stats":{"total_commits":157,"total_committers":10,"mean_commits":15.7,"dds":0.2547770700636943,"last_synced_commit":"afa3c73a44bd1b261309dec6a29096fdaee631f2"},"previous_names":[],"tags_count":16,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmndrs%2Freact-three-a11y","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmndrs%2Freact-three-a11y/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmndrs%2Freact-three-a11y/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/pmndrs%2Freact-three-a11y/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/pmndrs","download_url":"https://codeload.github.com/pmndrs/react-three-a11y/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":253879040,"owners_count":21977918,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["a11y","accessibility","react-three-fiber","reactjs","threejs"],"created_at":"2024-08-03T01:03:38.182Z","updated_at":"2025-05-14T20:02:27.823Z","avatar_url":"https://github.com/pmndrs.png","language":"TypeScript","funding_links":[],"categories":["3D","TypeScript"],"sub_categories":[],"readme":"\u003ch1\u003e@react-three/a11y\u003c/h1\u003e\n\n[![Version](https://img.shields.io/npm/v/@react-three/a11y?style=flat\u0026colorA=000000\u0026colorB=000000)](https://www.npmjs.com/package/@react-three/a11y)\n[![Downloads](https://img.shields.io/npm/dt/@react-three/a11y.svg?style=flat\u0026colorA=000000\u0026colorB=000000)](https://www.npmjs.com/package/@react-three/a11y)\n[![Discord Shield](https://img.shields.io/discord/740090768164651008?style=flat\u0026colorA=000000\u0026colorB=000000\u0026label=discord\u0026logo=discord\u0026logoColor=ffffff)](https://discord.gg/ZZjjNvJ)\n\n![Imgur](https://i.imgur.com/sSAD7m7.png)\n\n@react-three/a11y brings accessibility to webGL with easy-to-use react-three-fiber components:\n\n- Focus and focus indication\n- Tab index and keyboard navigation\n- Screen reader support and alt-text\n- Roles and cursor shapes\n- Descriptive links\n\nYou can try a [live demo here](https://n4rzi.csb.app).\n\n```bash\nnpm install @react-three/a11y\n```\n\n## Quick overview to get started\n\nnote: The full documentation can be found on the [pmndrs website](https://docs.pmnd.rs/a11y/introduction).\n\n### The A11yAnnouncer component\n\nFirst, place the A11yAnnouncer component next to the R3F Canvas component. this componant is critical since it manage some screen-reader features.\n\n```jsx\nimport { Canvas } from '@react-three/fiber';\nimport { A11yAnnouncer } from '@react-three/a11y';\n\nfunction App() {\n  return (\n    \u003c\u003e\n      \u003cCanvas /\u003e\n      \u003cA11yAnnouncer /\u003e\n    \u003c/\u003e\n  );\n}\n```\n\n### Then wrap components you want to make accessible with the A11y component\n\nTo add accessibility features to your scene you'll have to wrap components you want to make focusable with the `A11y` component:\n\n```jsx\nimport { A11y } from '@react-three/a11y'\n[...]\n\u003cA11y\u003e\n  \u003cMyComponent /\u003e\n\u003c/A11y\u003e\n```\n\n`MyComponent` can now receive focus. More accurately, the emulated \"focus\" will be handled at the `A11y` components which acts as a provider\nfor children to access its state. But even if objects are focusable, nothing will be displayed or shown by default.\n\n## Call function on focus\n\nThe `focusCall` prop of `A11y` will be called each time this component receives focus (usually through tab navigation).\n\n```jsx\n\u003cA11y role=\"content\" focusCall={()=\u003e console.log(\"in focus\")} ... /\u003e\n```\n\n## Call function on click / keyboard Click\n\nThe `actionCall` prop of `A11y` will be called each time this component gets clicked, focused, keyboard activated etc.\n\n```jsx\n\u003cA11y role=\"button\" actionCall={()=\u003e console.log(\"clicked\")} ... /\u003e\n```\n\n## Provide a description of the currently focused / hovered element\n\nWhen using the `description` prop in combination with the `role` prop, the `A11y` component will provide a description to the screen reader users on focus/hover.\nOptionally, you can also show the description to the user on hover by setting `showAltText={true}`.\n\n```jsx\n// Reads \"A rotating red square\" to screen readers on focus / hover while also showing it on mouseover\n\u003cA11y role=\"content\" description=\"A rotating red square\" showAltText ... /\u003e\n// Reads \"Button, open menu + (description on how to activate depending on the screen reader)\" to screen readers on focus / hover\n\u003cA11y role=\"button\" description=\"open menu\" actionCall={()=\u003e{someFunction()}} ... /\u003e\n```\n\n## The four roles of the A11y component\n\nLike in HTML, you can focus different kind of elements and expect different things depending on what you're focusing.\n\n#### Content\n\n```jsx\n\u003cA11y role=\"content\" ... /\u003e\n```\n\nUses the `default` cursor. This role is meant to provide information to screen readers or to serve as a step for a user to navigate your site using Tab for instance. It's not meant to trigger anything on click or to be activable with the Keyboard. Therefore it won't show a pointer cursor on hover.\n\n[Read more about role content](/a11y/roles/content)\n\n#### Button\n\n```jsx\n\u003cA11y\n  role=\"button\"\n  description=\"Send email\"\n  activationMsg=\"Sending email\" ... /\u003e\n```\n\nUses the `pointer` cursor. Special attributes: `activationMsg`.\n\nThis role is meant to emulate the behaviour of a button or a togglable button. It will display a cursor pointer when your cursor is over the linked 3D object. It will call a function on click but also on any kind of action that would trigger a focused button (Enter, Double-Tap, ...). It is also actionnable by user using a screen reader.\n\n[Read more about role button](https://docs.pmnd.rs/a11y/roles/button)\n\n#### ToggleButton\n\nBy using the role togglebutton, you'll emulate a button with two state that will have the `aria-pressed` attribute.\nYou'll then be able to use the deactivationMsg property in addition to the usual description and activationMsg properties.\n\n```jsx\n\u003cA11y\n  role=\"togglebutton\"\n  description=\"Dark theme \"\n  activationMsg=\"Switched to dark theme\"\n  deactivationMsg=\"Switched to light theme\" ... /\u003e\n```\n\nSpecial attributes: `deactivationMsg`\n\n[Read more about role ToggleButton](https://docs.pmnd.rs/a11y/roles/togglebutton)\n\n#### Link\n\n```jsx\n\u003cA11y role=\"link\" href=\"https://url.com\" ... /\u003e\n```\n\nUses the `pointer` cursor. Special attributes: `href`.\n\nThis role is meant to emulate the behaviour of a regular html link. It should be used in combination with something that will trigger navigation on click.\n\n\u003e [!NOTE]\n\u003e Don't forget to provide the href attribute as he is required for screen readers to read it correctly ! - It will have no effect on the navigation, it's just used as information\n\n[Read more about role link](https://docs.pmnd.rs/a11y/roles/link)\n\n## Screen Reader Support\n\nIn order to provide informations to screen reader users and use this package at its full potential, fill the `description` prop of all your `A11y` components and use the appropriate `role` prop on each of them.\n\n### Use of section\n\nFor screen readears, it might be useful to provide additionnal information on how to use some unconventional UI.\nYou can do it by wrapping the concerned part of your code relative to this UI in the A11ySection like so.\n\n```jsx\n\u003cA11ySection\n  label=\"Shape carousel\"\n  description=\"This carousel contains 5 shapes. Use the Previous and Next buttons to cycle through all the shapes.\"\n\u003e\n  [...]\n\u003c/A11ySection\u003e\n```\n\n## Access user preferences\n\nThe A11yUserPreferences component is available in order to access user preferences such as\n\n- prefers-reduced-motion\n- prefers-color-scheme\n\nTake a look at [the A11yUserPreferences page](https://docs.pmnd.rs/a11y/access-user-preferences) or the [demo](https://n4rzi.csb.app) to see it in action and how to use it. The demo will adapt to your system preferences.\n\n## Additionals Features\n\nUse a custom tabindex with for your A11y components by providing a number to the tabIndex attribute\n\n```jsx\n\u003cA11y tabIndex={-1} ... /\u003e\n```\n\n\u003e [!CAUTION]\n\u003e Avoid using `tabindex` values greater than 0. Doing so makes it difficult for people who rely on assistive technology to navigate and operate page content.\n\u003e Instead, write the document with the elements in a logical sequence. More about the use of tabIndex on [developer.mozilla.org](https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/tabindex)\n\n### Author:\n\n- [`Bluesky 👋 @AlaricBaraou`](https://bsky.app/profile/alaricbaraou.bsky.social)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmndrs%2Freact-three-a11y","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fpmndrs%2Freact-three-a11y","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fpmndrs%2Freact-three-a11y/lists"}