An open API service indexing awesome lists of open source software.

https://github.com/accessible-ui/tabs

🅰 An accessible and versatile tabs component for React with keyboard navigation and labeling features taught in w3.org's WAI-ARIA tabs example
https://github.com/accessible-ui/tabs

a11y a11y-tabs accessible-tabs accessiblity aria react tabs

Last synced: 4 months ago
JSON representation

🅰 An accessible and versatile tabs component for React with keyboard navigation and labeling features taught in w3.org's WAI-ARIA tabs example

Awesome Lists containing this project

README

        


# @accessible/tabs

> 🅰 An accessible and versatile tabs component for React with keyboard navigation and labeling features taught in w3.org's WAI-ARIA tabs example

```sh
npm i @accessible/tabs
```



Bundlephobia


Types


Code coverage


Build status


NPM Version


MIT License

---

An accessible and versatile tabs component for React modeled after
the [WAI-ARIA example taught here](https://www.w3.org/TR/wai-aria-practices/examples/tabs/tabs-1/tabs.html).

## Quick Start

[Check out the example on **CodeSandbox**](https://codesandbox.io/s/accessibletabs-example-0dw15)

```jsx harmony
import {Tabs, TabList, Tab, Panel} from '@accessible/tabs'

const Component = () => (




Abstract


References



Abstract body



References body



)
```

## API

### Components

| Component | Description |
| ----------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| [``](#tabs) | This component creates the context for your tabs and contains some configuration options. You'll need to add [``](#tab) and [``](#panel) as children in order to actually create tabs. |
| [``](#tablist) | The component adds `role='tablist'` to its child component. |
| [``](#tab) | This component clones any React element and turns it into a tab that controls the visible state of a [``](#panel). It must be a child of [``](#tabs) and all tabs must be adjacent in the tree. Each tab has a corresponding [``](#panel) that shares the same index. |
| [``](#panel) | This component clones its child and turns it into a panel that corresponds to a [``](#tab) with the same index. All panels must be adjacent in the tree unless an `index` prop is defined. |

### Hooks

| Hook | Description |
| --------------------------------- | --------------------------------------------------------------------------- |
| [`useTabs()`](#usetabs) | This hook returns the value of the [TabsContext object](#tabscontextvalue). |
| [`useTab()`](#usetabindex-number) | This hook returns the value of the [TabContext object](#tabcontextvalue). |

### <Tabs>

This component creates the context for your tabs and contains some configuration options. You'll need to add
[``](#tab) and [``](#panel) as children in order to actually create tabs.

#### Props

| Prop | Type | Default | Required? | Description |
| ---------------- | -------------------------- | ----------- | --------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| defaultActive | `number` | `0` | No | The [``](#tab) index you want active by default. |
| active | `number` | `undefined` | No | Makes this a controlled component where the `activate` control has no effect. The tab index defined here is always the one that is active. |
| manualActivation | `boolean` | `false` | No | By default this component opens tabs automatically when using keyboard navigation to switch between tabs. By setting this to `true`, the user will have to use the `space` or `enter` key to activate the tab after the tab is focused. |
| preventScroll | `boolean` | `false` | No | When `true` this will prevent your browser from scrolling the document to bring the newly-focused tab into view. |
| onChange | `(active: number) => void` | `undefined` | No | Called each time the active tab changes. It provides the active tab `index` as its only argument. |
| children | `React.ReactNode[]` | `undefined` | Yes | You can define any children here with some caveats listed elsewhere. |

### <TabList>

#### Props

| Prop | Type | Default | Required? | Description |
| -------- | -------------------- | ----------- | --------- | -------------------------------------------------------------------------------- |
| children | `React.ReactElement` | `undefined` | Yes | The child is cloned by this component and given a property for `role='tablist'`. |

### <Tab>

This component clones any React element and turns it into a tab that controls the visible state of a [``](#panel). It must be a child of [``](#tabs) and all
tabs must be adjacent in the tree. Each tab has a corresponding [``](#panel) that shares the same index.

```jsx harmony
// YES
const MyTabs = () => (


{/* index: 0 */}



{/* index: 1 */}




{/* index: 0 */}



{/* index: 1 */}




)

// ABSOLUTELY NOT
const MyTabs = () => (


{/* The Tab components here are not adjacent in the tree. */}



















)
```

#### Props

| Prop | Type | Default | Required? | Description |
| ------------- | -------------------------------- | ----------- | --------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| activeClass | `string` | `undefined` | No | Adds this class to the child component when the tab is in an active state. |
| inactiveClass | `string` | `undefined` | No | Adds this class to the child component when the tab is in an inactive state. |
| activeStyle | `React.CSSProperties` | `undefined` | No | Adds these styles to the child component when the tab is in an active state. |
| inactiveStyle | `React.CSSProperties` | `undefined` | No | Adds these styles to the child component when the tab is in an inactive state. |
| id | `string` | `undefined` | No | Defining an ID here overrides the auto id generated for aria attributes. |
| disabled | `boolean` | `false` | No | Setting this to `true` will prevent the tab from activating if it isn't already active. |
| index | `number` | `undefined` | No | Setting an index here overrides the default index created when this component mounts. Indexes are used to match tabs to their corresponding [``](#panel). I would recommend not setting this property and letting the library handle it automatically. |
| onDelete | `(event: KeyboardEvent) => void` | `undefined` | No | This callback will fire if a user presses the `Delete` key on their keyboard when this tab (not the panel) is focused. |
| children | `React.ReactElement` | `undefined` | Yes | The child is cloned by this component and has aria attributes injected into its props as well as keyboard event handlers for navigating between tabs. |

### <Panel>

This component clones its child and turns it into a panel that corresponds to a [``](#tab) with the same
index. All panels must be adjacent in the tree unless an `index` prop is defined. For example:

```


[0]
[1]

[0]
[1]

```

#### Props

| Prop | Type | Default | Required? | Description |
| ------------- | --------------------- | ----------- | --------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| activeClass | `string` | `undefined` | No | Adds this class to the child component when the panel's [``](#tab) is in an active state. |
| inactiveClass | `string` | `undefined` | No | Adds this class to the child component when the panel's [``](#tab) is in an inactive state. |
| activeStyle | `React.CSSProperties` | `undefined` | No | Adds these styles to the child component when the panel's [``](#tab) is in an active state. |
| inactiveStyle | `React.CSSProperties` | `undefined` | No | Adds these styles to the child component when the panel's [``](#tab) is in an inactive state. |
| index | `number` | `undefined` | No | Setting an index here overrides the default index created when this component mounts. Indexes are used to match panels to their corresponding [``](#tab). I would recommend not setting this property and letting the library handle it automatically. |
| children | `React.ReactElement` | `undefined` | Yes | The child is cloned by this component and has aria attributes injected into its props and will have its visible state controlled by the [``](#tab) component with the same index. |

### useTab(index: number)

Returns [`TabContext object`](#tabcontextvalue) for the [``](#tab) corresponding to the provided `index`.
It must be used within a child of [``](#tabs).

### TabContextValue

```typescript
interface TabContextValue {
// The ID used for aria attributes
id?: string
// A ref to the tab's underlying element
tabRef?: HTMLElement
// The index of the tab
index: number
// Activates this tab unless `disabled` is `true`
activate: () => void
// Is this tab active?
isActive: boolean
// Is this tab disabled?
disabled: boolean
}
```

### useTabs()

This hook returns the value of the [TabsContext object](#tabscontextvalue). This hook must be within a child of [``](#tabs).

### TabsContextValue

```typescript
interface TabsContextValue {
// An array of tabs that have been registered
tabs: TabState[]
// Registers a new tab
registerTab: (
index: number,
element: HTMLElement,
id?: string,
disabled?: boolean
) => () => void
// The tab that is currently active
active: number | undefined
// Activates the tab at `index`
activate: (index: number | undefined) => void
// Is manual activation configured?
manualActivation: boolean
}

type TabState =
| {
element?: HTMLElement
id?: string
disabled?: boolean
}
| undefined
```

## LICENSE

MIT