import { Meta, Story, Canvas } from '@storybook/addon-docs/blocks';
import {
  Button,
  FilterIcon,
  Text,
  Link,
  Box,
  Head1,
  UnstyledButton,
} from '../../src';

<Meta title="Manual/4 - Accessibility" />

# Building Accessible Applications with Patchwork

Preface: There are a few things to consider when building an entirely accessible application. We've outlined <a href="https://wealthsimple.quip.com/SOTJAKAU2wQA/A11y-Manual-Testing-Guide-Web-Edition">some of those accessibility testing rules here</a>

Patchwork is designed to be completely accessible when used properly. Generally all of the components within patchwork are _accessible in isolation_. We've outlined a few components below that have some accessibility implications as you build pages.

## Interactive components

### Never put an `onClick` on arbitrary DOM elements

As soon as you give something an `onClick` callback, it becomes an "interactive component". There is a whole bunch of things that interactive components need to do right in order to be considered accessible:

- a screen reader has to be able to find some meaningful text to read out for the component
- the component has to be accessible via the keyboard, and render a UI cue when it has the keyboard focus
- it has to have a focus state, respond to `onFocus` and `onBlur` events,
- etc.

The good news is that patchwork exposes a component called "UnstyledButton". If you wrap the thing you want to make clickable in an `UnstyledButton`, you get all the things above for free:

**Bad:** not accessible: the clickable icon below can't be accessed via the keyboard. It also doesn't have any text the screen reader can read.

<Canvas>
  <Box onClick={() => alert("You can't activate me with the keyboard")}>
    <FilterIcon />
  </Box>
</Canvas>

**Good:** Wrapping it in an unstyled button gives you keyboard events/focus state for free. Assigning an `aria-label` tells the screen reader what to read.

<Canvas>
  <UnstyledButton
    onClick={() => alert('You can activate me with the keyboard')}
    aria-label="Filter results"
  >
    <FilterIcon />
  </UnstyledButton>
</Canvas>

**Best:** Having visible button text is better for sighted users as well.

<Canvas>
  <UnstyledButton
    onClick={() => alert('You can activate me with the keyboard')}
    stacked="row"
    align="center"
  >
    <FilterIcon />
    Filter results
  </UnstyledButton>
</Canvas>

### The Button/Link Duality

We often use buttons and links interchangeably from a design perspective. However from a screen reader point of view they behave differently and have different implications for navigating around the document.

The rule of thumb is that if it uses an `href` prop, it should render an `<a>` tag. If it uses an `onClick` prop, it should render a `<button>` tag.

The good news is patchwork's `Link`, `Button`, `SecondaryButton`, `TertiaryButton`, and `TextButtonWithIcon` components handle this under the hood for you. Specify an `href`, and you get an `<a>` under the hood. Specify an `onClick` and you get a `<button>` under the hood. Specify both, and the `href` takes precedence. This is useful for cases where you want to record an analytics hit before following a link.

## Semantic Headers

Screen readers like Apple Voice Over scan your screen's DOM for `h1` ... `h6` level headers. These are used to generate a kind of "table of contents" that low-vision users can use to navigate around the different sections of your page.

Typically our design team's designs are well structured visually with titles for the different sets of UI on the page. As long as you use the correct patchwork components to implement them, the screen reader functionality descrived above should "just work".

We export several components that generate semantic headers in React's DOM output:

`Head1` ... `Head5`: These components render h1 and h5 headers with default typographic styling. Make sure that all the elements on a given screen come together in an overall outline structure that makes sense. If you need visual size to be different than the organizational importance, the `HeadN` compontents accept a `fontSize` property that lets you override the visual importance without changing the header's place in the document's conceptual outline.

`SectionHeader`: SectionHeader is available in small and large variants. By default, the small variant renders a level 3 header (`h3`) and the large variant renders a level 2 header (`h2`). You can override this using the `headerLevel` prop from the `SemanticHeaderLevel` mixin:

<Canvas>
  <SectionHeader headerLevel={5}>L5 SectionHeader</SectionHeader>
</Canvas>

`PageTitle`: By default, PageTitle acts semantically as a level 1 header (`h1`). However, it too supports the `SemanticHeaderLevel` mixin, for cases where you need the same visual impact but a lower semantic level:

<Canvas>
  <PageTitle headerLevel={5}>L5 PageTitle</PageTitle>
</Canvas>

`Text`: Text is our general purpose typography component. By default it is semantically equivalent to a `p`, but you can "promote" it semantically:

<Canvas>
  <Text headerLevel={2}>Really important text!</Text>
</Canvas>

Finally, for rare cases where you want the visual impact of a header but want to exclude it from the semantic page outline, you cah use `headerLevel={none}`:

<Canvas>
  <PageTitle headerLevel="none">Non-title PageTitle</PageTitle>
  <PageTitle headerLevel="none">Non-title SectionHeader</PageTitle>
</Canvas>
