# ContentSwitcher

![npm](https://img.shields.io/npm/dt/@asphalt-react/content-switcher?style=flat-square)
[![npm version](https://badge.fury.io/js/@asphalt-react%2Fcontent-switcher.svg)](https://badge.fury.io/js/@asphalt-react%2Fcontent-switcher)

Component to switch between alternate views of a content within the same page or screen. Only one view is visible at a time. For instance, use ContentSwticher to switch between tabular view and graphical view of a dataset. It's a controlled component where you control which content view should be visible.

ContentSwitcher exports another component named [Switch](#switch). Switch creates the tabs for each view. Switches come in 2 sizes: small and medium (default). Each Switch has three types of caption:

* text only
* text with an icon; icon adds more context to the text
* icon only

Switch accepts most of the [button element's attributes](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/button) such as `id` & `name` and supports [data-\* attributes](https://developer.mozilla.org/en-US/docs/Learn/HTML/Howto/Use_data_attributes).

## Accessibility

1. ContentSwitcher has a `role="tablist"` and the Switches have `role="tab"`.
2. The selected Switch has "aria-selected" set to `true`.
3. The Switches are focusable using <kbd>tab</kbd>.
4. ContentSwitcher accepts aria-\* attributes for [role="tablist"](https://www.w3.org/TR/wai-aria-1.1/#tablist).
5. Switch accepts aria-\* attributes for [role="tab"](https://www.w3.org/TR/wai-aria-1.1/#tab).

## Accessibility must-haves

1. Add `role="tabpanel"` to the content section.
2. Add an `id` to a Switch. Pass the "id"'s value to `aria-labelledby` attribute to the element of the content section.
3. Add an `id` to the view section element. Pass the "id"'s value to `aria-controls` attribute of its Switch.
4. Add `aria-label` or `aria-labelledby` in Switch with icon as caption.

Check examples to see these in action.

## Usage

```jsx
import React, { useState } from "react"
import { ContentSwitcher, Switch } from "@asphalt-react/content-switcher"

function App() {
  const [active, setActive] = useState(0)
  const clickHandler = (value) => setActive(value)
  return (
    <main>
      <ContentSwitcher>
        <Switch value={0} onAction={clickHandler} active={active === 0}>
          First
        </Switch>
        <Switch value={1} onAction={clickHandler} active={active === 1}>
          Second
        </Switch>
      </ContentSwitcher>
      <div>
        {active === 0 && (<div>First Section</div)}
        {active === 1 && (<div>Second Section</div>)}
      </div>
    </main>
  )
}

export default App
```

[comment]: # "ContentSwitcher Props"

## Props

### children

Switch components.

| type | required | default |
| ---- | -------- | ------- |
| node | true     | N/A     |

# Switch

[comment]: # "Switch Props"

## Props

### children

Switch caption.

| type | required | default |
| ---- | -------- | ------- |
| node | true     | N/A     |

### value

Index of the Switch.

| type   | required | default |
| ------ | -------- | ------- |
| number | true     | N/A     |

### active

Adds styles to show the Switch is active.

| type | required | default |
| ---- | -------- | ------- |
| bool | false    | N/A     |

### onAction

Callback to handle Switch selection.

The function accepts 2 arguments:

* value: `value` prop of the Switch.
* options: object containing the React synthetic event.

```js
onAction(value, { event }) {
 console.log(value)
}
```

| type | required | default |
| ---- | -------- | ------- |
| func | false    | N/A     |

### size

Size of the Switches. Accepts one of "s" or "m" for small & medium.

| type | required | default |
| ---- | -------- | ------- |
| enum | false    | "m"     |

### icon

Renders icon as caption.

| type | required | default |
| ---- | -------- | ------- |
| bool | false    | false   |

### qualifier

Icons to add more context to the textual caption.

Accepts SVG or SVG wrapped React component. Checkout `@asphalt-react/iconpack` for SVG wrapped React components.

> ⚠️ Do not use `qualifier` to render a Switch with icon as caption; use `icon` prop instead.

| type    | required | default |
| ------- | -------- | ------- |
| element | false    | N/A     |

### qualifierEnd

Appends qualifier to the text in caption. Switch prepends the qualifier by default.

| type | required | default |
| ---- | -------- | ------- |
| bool | false    | false   |

### accent

Applies accent intent when Switch is active.

| type | required | default |
| ---- | -------- | ------- |
| bool | false    | false   |
