|
1 | 1 | # Accessibility |
2 | 2 |
|
| 3 | +## Accessible name {#accessible-name} |
| 4 | + |
| 5 | +The **accessible name** is the text that assistive technologies (like screen readers) announce for an element. It answers the question: _"what would a screen reader call this element?"_. For instance, a button showing a trash icon might have the accessible name `"Delete"`, so a screen reader user knows what it does. |
| 6 | + |
| 7 | +Testing Library uses the accessible name in the [`*ByRole`](/docs/api/queries#by-role) queries `name` option and in the [`toHaveAccessibleName()`](/docs/api/jest-matchers#tohaveaccessiblename) matcher. Combining a role with an accessible name is a **semantic query**: it finds an element by what it is (`button`) and what it is called (`"Delete"`), rather than by its implementation details. This matches how users experience your UI. |
| 8 | + |
| 9 | +### How the accessible name is computed {#how-it-is-computed} |
| 10 | + |
| 11 | +The accessible name is the **first** of these sources to produce a non-empty value. The sources are ordered from highest to lowest importance. An explicit accessibility label that the developer assigned always takes precedence, and the element's own text content is only used when no such label is present. |
| 12 | + |
| 13 | +1. **`aria-labelledby` / `accessibilityLabelledBy`**: the [`nativeID`](https://reactnative.dev/docs/view#nativeid) (or array of IDs) of other elements, whose text content is joined with spaces in the referenced order. |
| 14 | +2. **`aria-label` / `accessibilityLabel`**: an explicit label string on the element. |
| 15 | +3. **`alt`** (`Image` only): the image's alternative text. |
| 16 | +4. **`placeholder`** (`TextInput` only). |
| 17 | +5. **Text content**: the element's own text, collected recursively from its children (see [Text content](#text-content) below). This is the fallback when none of the label sources above are set. |
| 18 | + |
| 19 | +### Text content {#text-content} |
| 20 | + |
| 21 | +When falling back to text content, child text is joined as follows: |
| 22 | + |
| 23 | +- Adjacent inline text (directly inside `Text` elements) is concatenated **without** a separator, matching how it renders on screen. |
| 24 | +- Text from separate, non-inline elements, such as sibling `View`s, is joined with a **single space**. |
| 25 | + |
| 26 | +For example: |
| 27 | + |
| 28 | +```jsx |
| 29 | +render( |
| 30 | + <Pressable accessibilityRole="button"> |
| 31 | + <Text>Hello</Text> |
| 32 | + <Text> World</Text> |
| 33 | + </Pressable>, |
| 34 | +); |
| 35 | +// Accessible name: "Hello World" |
| 36 | +``` |
| 37 | + |
| 38 | +### Examples {#accessible-name-examples} |
| 39 | + |
| 40 | +```jsx |
| 41 | +// Explicit label wins over text content |
| 42 | +<Pressable accessibilityRole="button" accessibilityLabel="Close dialog"> |
| 43 | + <Text>X</Text> |
| 44 | +</Pressable> |
| 45 | +// Accessible name: "Close dialog" |
| 46 | + |
| 47 | +// Text content is used when no explicit label is set |
| 48 | +<Pressable accessibilityRole="button"> |
| 49 | + <Text>Submit</Text> |
| 50 | +</Pressable> |
| 51 | +// Accessible name: "Submit" |
| 52 | +``` |
| 53 | + |
3 | 54 | ## `isHiddenFromAccessibility` |
4 | 55 |
|
5 | 56 | ```ts |
|
0 commit comments