import {ExampleCodeBlock, SymbolDoc} from '@workday/canvas-kit-docs';

import StartIcon from './examples/StartIcon';
import EndIcon from './examples/EndIcon';
import Avatar from './examples/Avatar';
import Depth from './examples/Depth';
import RTL from './examples/RTL';
import LongTitle from './examples/LongTitle';
import HoistedModel from './examples/HoistedModel';


# Canvas Kit Expandable

`Expandable` is a compound component that creates a header to expand or collapse related content.

## Installation

```sh
yarn add @workday/canvas-kit-react
```

## Usage

### Start Icon

For a basic expandable container with a chevron icon before the title, place`Expandable.Icon` before
`Expandable.Title` as children of `Expandable.Target` and pass the `iconPosition` prop to
`Expandable.Icon` with a value of `start`. `Expandable.Icon` will use a right chevron icon when
collapsed and a down chevron icon when expanded.

<ExampleCodeBlock code={StartIcon} />

### End Icon

For an expandable container with a chevron icon after the title, place `Expandable.Title` before
`Expandable.Icon` as children of `Expandable.Target` and pass the `iconPosition` prop to
`Expandable.Icon` with a value of `end`. `Expandable.Icon` will use a down chevron icon when
collapsed and an up chevron icon when expanded.

<ExampleCodeBlock code={EndIcon} />

### With Avatar

To include an avatar image, `Expandable.Avatar` should be placed between `Expandable.Icon` and
`Expandable.Title`. An `iconPosition` prop with a value of either `start` or `end` should be passed
to `Expandable.Icon` depending on whether the `Expandable.Icon` is placed before or after
`Expandable.Title`.

**Note:** If using an avatar image, do not also include an Icon component in addition to the Expandable.Icon.
This component is meant to have either an avatar image or an icon in addition to the Expandable.Icon, or neither
an avatar image nor an extra icon.


<ExampleCodeBlock code={Avatar} />

> **Accessibility Note:** In this situation, the Avatar is decorative and should not be announced to
> screen readers. The `<Expandable.Avatar>` component has `isDecorative` set to `true` by default to
> hide it from screen readers, as avatars in expandable headers are typically decorative when paired
> with adjacent text.

### Right to Left (RTL)

Expandable container has bidirectional support and should function as expected with RTL languages as
long as the content direction is set in your Canvas theme.

<ExampleCodeBlock code={RTL} />

### Depth

The `depth` prop passed to `Expandable` allows you to adjust the visual elevation of a component
using our depth tokens.

<ExampleCodeBlock code={Depth} />

### Title Wrap

Long titles will wrap to the next line and increase the height of the container.

<ExampleCodeBlock code={LongTitle} />

You can also have direct access to the model if

### Hoisted Model

If you need direct access to the model, you can hoist it with the `useExpandableModel` hook. In the
example below, we're hoisting the models to expand and collapse all three containers at once.

<ExampleCodeBlock code={HoistedModel} />

> **Accessibility Note:** When using multiple Expandable Containers on a page, use the `as` prop to
> render the `<Expandable.Content>` sub-component as an HTML `<section>` element. Then, use
> `aria-labelledby` to reference the unique `id` of the `<Expandable.Title>` element. This practice
> can be useful to screen reader users when multiple Expandable Containers are opened at one time
> for uniquely describing the boundaries of the expandable content.

## Accessibility

Our Expandable component renders a semantic HTML `<button>` element to the DOM, with an optional
parent heading element as defined by the `headingLevel` prop. The `aria-expanded` property is
included on the button to indicate the state of the content to screen readers.

[Accordion Pattern | APG | WAI | W3C](https://www.w3.org/WAI/ARIA/apg/patterns/accordion/)

- Use the `headingLevel` prop to assign an appropriate heading level based on the context of the
  page content.
- When using Expandable Container for navigation elements, then we don't recommend using the
  `headingLevel` prop. This will render only expandable buttons to the DOM, reserving headings for
  organizing content in the main body of the page.
- The `as` prop may also be used on `<Expandable.Content>` to render an HTML `<ul>` element for
  displaying a list of items. For example, check out
  [Side Panel with Navigation](https://workday.github.io/canvas-kit/?path=/docs/guides-accessibility-examples-side-panel-navigation--docs).

### Navigation

- **Tab key**: Moves focus to the next expandable button or focusable element
- **Shift + Tab**: Moves focus to the previous focusable element
- **Enter or Space**: Toggles the expanded/collapsed state

### Screen Reader Experience

- The expandable button will be announced with its title text followed by the button role
- The current state will be announced as either "collapsed" or "expanded" (For example: "Usage
  Guidance, button, collapsed" or "Usage Guidance, button, expanded")
- **State Changes:** When activating the button to expand content, screen readers will announce the
  new "expanded" state and vice versa when collapsing content.
- **Content Regions:** Screen reader users can use landmark navigation to jump between sections and
  each section will be announced with its associated title (For example: "Usage Guidance, landmark
  region")
- **Heading Structure:** Using heading levels with expandable buttons allows screen reader users to
  navigate by headings, making the document structure and hierarchy easier to understand.

## Component API

<SymbolDoc name="Expandable" fileName="/react/" />