import {ExampleCodeBlock, Specifications, SymbolDoc} from '@workday/canvas-kit-docs';
import Basic from './examples/Basic';
import NamedTabs from './examples/NamedTabs';
import RightToLeft from './examples/RightToLeft';
import OverflowTabs from './examples/OverflowTabs';
import DisabledTab from './examples/DisabledTab';
import Icons from './examples/Icons';
import SinglePanel from './examples/SinglePanel';
import AlternativeTabStop from './examples/AlternativeTabStop';
import HoistedModel from './examples/HoistedModel';
import DynamicTabs from './examples/DynamicTabs';

# Canvas Kit Tabs

`Tabs` is a [compound component](/getting-started/for-developers/resources/compound-components/)
that allows users to navigate between related views of content while remaining in context of the
page.

[> Workday Design Reference](https://design.workday.com/components/navigation/tabs)

## Installation

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

## Usage

### Basic Example

`Tabs` includes a container `Tabs` component and the following subcomponents which can be composed
in a variety of ways: `Tabs.List`, `Tabs.Item` and `Tabs.Panel`. It follows the
[W3 Tabs specification](https://www.w3.org/WAI/ARIA/apg/patterns/tabs/).

In this example, we set up a basic `Tabs` component with five tabs. This example uses a static API
that does not support overflow.

<ExampleCodeBlock code={Basic} />

### Overflow Tabs

Tabs is a responsive component based on the width of its container. If the rendered tabs exceed the
width of the `Tabs.List`, an overflow menu will be rendered. This only works against the dynamic API
where you give the `TabsModel` an array of items to be rendered. The dynamic API handles the React
`key` for you based on the item's identifier. The dynamic API requires either an `id` on each item
object or a `getId` function that returns an identifier based on the item. The below example uses an
`id` property on each item.

The dynamic API takes in any object, but since nothing is known about your object, a
[render prop](https://reactjs.org/docs/render-props.html) is necessary to instruct a list how it
should render.

<ExampleCodeBlock code={OverflowTabs} />

### Hoisted Model

By default, `Tabs` will create and use its own [model](#model) internally. Alternatively, you may
configure your own model with `useTabsModel` and pass it to `Tabs` via the `model` prop. This
pattern is referred to as
[hoisting the model](/getting-started/for-developers/resources/compound-components/#configuring-a-model)
and provides direct access to its `state` and `events` outside of the `Tabs` component.

In this example, we set up external observation of the model state and create an external button to
trigger an event to change the active tab.

<ExampleCodeBlock code={HoistedModel} />

### Named Tabs

`Tabs.Item` and `Tabs.Panel` both take an optional `data-id` attribute that is used for the
`onActivate` callback. This example is identical to the Basic Example, but with tabs named using
`data-id` for the `Tabs.Item` and `Tabs.Panel` subcomponents.

<ExampleCodeBlock code={NamedTabs} />

### Right-to-Left (RTL)

`Tabs` supports right-to-left languages when specified in the `CanvasProvider` `theme`.

<ExampleCodeBlock code={RightToLeft} />

### Disabled Tab

Set the `disabled` prop of a `Tabs.Item` to `true` to disable it.

<ExampleCodeBlock code={DisabledTab} />

### Tab Icons

Tabs can have icons. Use the `Icon` and `Text` subcomponents.

<ExampleCodeBlock code={Icons} />

### Alternative Tab Stop

By default, tab panels are focusable for accessibility. If the contents of a tab panel have a
focusable element, you may disable this default behavior by setting the `tabIndex` prop of
`Tabs.Panel` to `undefined`. This example has a tab panel with a focusable button.

<ExampleCodeBlock code={AlternativeTabStop} />

### Single Tab Panel

The compound component pattern allows for advanced composition. For example, `Tabs` can be composed
to have only a single `Tabs.Panel` using attribute overrides and callbacks. More information about
attributes and callbacks can be found in the prop tables below for each subcomponent.

In this example, we use a hoisted model and the `activeTab` property of the state to show content
from the `contents` object.

<ExampleCodeBlock code={SinglePanel} />

### Dynamic Tabs

The `Tabs.Item` component takes in an optional `index` property if you want to specify the position
of a tab. If not defined, by default it will append tabs to the end. In this example, our tabs are
stored as an array in the state, and we have a fixed tab at the end that can add new tabs to that
array.

<ExampleCodeBlock code={DynamicTabs} />

## Component API

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

## Specifications

<Specifications file="Tabs.spec.ts" name="Tabs" />