{"id":25431970,"url":"https://github.com/mikechabot/react-tabify","last_synced_at":"2025-10-31T22:30:20.944Z","repository":{"id":57346109,"uuid":"100126749","full_name":"mikechabot/react-tabify","owner":"mikechabot","description":"A dead simple tab component for ReactJS","archived":false,"fork":false,"pushed_at":"2019-04-28T03:27:54.000Z","size":224,"stargazers_count":8,"open_issues_count":0,"forks_count":2,"subscribers_count":1,"default_branch":"master","last_synced_at":"2024-12-23T00:02:56.855Z","etag":null,"topics":["react-tabs","reactjs","tabs"],"latest_commit_sha":null,"homepage":"https://codesandbox.io/s/23x92qvy9n","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mikechabot.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2017-08-12T17:13:00.000Z","updated_at":"2021-04-07T01:02:01.000Z","dependencies_parsed_at":"2022-09-17T06:31:36.375Z","dependency_job_id":null,"html_url":"https://github.com/mikechabot/react-tabify","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikechabot%2Freact-tabify","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikechabot%2Freact-tabify/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikechabot%2Freact-tabify/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mikechabot%2Freact-tabify/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mikechabot","download_url":"https://codeload.github.com/mikechabot/react-tabify/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":239236400,"owners_count":19604901,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["react-tabs","reactjs","tabs"],"created_at":"2025-02-17T04:31:24.861Z","updated_at":"2025-10-31T22:30:20.824Z","avatar_url":"https://github.com/mikechabot.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"[![Build Status](https://travis-ci.org/mikechabot/react-tabify.svg?branch=master)](https://travis-ci.org/mikechabot/react-tabify)\n[![Dependency Status](https://david-dm.org/mikechabot/react-tabify.svg)](https://david-dm.org/mikechabot/react-tabify)\n[![devDependencies Status](https://david-dm.org/mikechabot/react-tabify/dev-status.svg)](https://david-dm.org/mikechabot/react-tabify?type=dev)\n\n[![NPM](https://nodei.co/npm/react-tabify.png)](https://nodei.co/npm/react-tabify/)\n\n[![GitHub stars](https://img.shields.io/github/stars/mikechabot/react-tabify.svg?style=social\u0026label=Star)](https://github.com/mikechabot/react-tabify)\n[![GitHub forks](https://img.shields.io/github/forks/mikechabot/react-tabify.svg?style=social\u0026label=Fork)](https://github.com/mikechabot/react-tabify)\n\n# react-tabify\n\nA dead simple tab component for ReactJS.\n\n- [Installation](#installation)\n- [Basic Example](#basic-example)\n- [Components](#components)\n- [Controlled vs Uncontrolled Mode](#controlled-vs-uncontrolled-mode)\n- [Other Examples](#other-examples)\n  - [Stacked](#stacked)\n  - [Nested](#nested)\n  - [Sticky](#sticky)\n  - [Container Overflow](#container-overflow)\n  - [Hiding Tabs](#hiding-tabs)\n- [Color Theme](#color-theme)\n\n## \u003ca name=\"react-tabify#installation\"\u003eInstallation\u003c/a\u003e\n\nYarn or npm:\n\n* `$ yarn add react-tabify`\n* `$ npm install --save react-tabify`\n\n----\n\n## \u003ca name=\"react-tabify#basic-example\"\u003eBasic Example\u003c/a\u003e\n\n```js\nimport { Tab, Tabs } from 'react-tabify';\n\nexport default () =\u003e (\n  \u003cTabs\u003e\n    \u003cTab label=\"Tab 1\"\u003eFirst Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003eSecond Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003eThird Content\u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n\n[![Edit 23x92qvy9n](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/23x92qvy9n)\n\n----\n\n## \u003ca name=\"react-tabify#components\"\u003eComponents\u003c/a\u003e\n\n`react-tabify` consists of two (2) components which need to be used together.\n\n### `\u003cTabs /\u003e`\n\n| Name               | Type                 | Default             | Description                                             | \n| ------------------ |----------------------| --------------------|---------------------------------------------------------|\n| `id`               | `string`             | `__tabify__`        | Id of the `\u003cTabs /\u003e` component                          |\n| `defaultActiveKey` | `string` / `number`  | `0`                 | `eventKey` of the initial `\u003cTab /\u003e` to render           |\n| `activeKey`        | `string` / `number`  |                     | `eventKey` of the current `\u003cTab /\u003e`                     |\n| `theme  `          | `object`             |                     | Optional color theme                                    |\n| `stacked`          | `bool`               | `false`             | Whether to display `\u003cTabs /\u003e` vertically                |\n| `sticky`           | `bool`               | `false`             | Enable sticky tabs\n| `onSelect`         | `func`               |                     | Callback fired when a `\u003cTab /\u003e` is selected             |\n| `style`            | `object`             |                     | style forwarded to the `\u003cTab /\u003e` containing `\u003cdiv /\u003e`   |\n| `children`         | `node`               |                     | `\u003cTab /\u003e` components                                    |\n\n----\n\n### `\u003cTab /\u003e`\n\n| Name               | Type                 | Default             | Description                                             | \n| ------------------ |----------------------| --------------------|---------------------------------------------------------|\n| `eventKey `        | `string` / `number`  | `index`             | Unique key of the `\u003cTab /\u003e`                             |\n| `label`            | `string` / `node`    |                     | Label of the `\u003cTab/\u003e`                                   |\n| `hide `            | `bool`               | false               | Whether to hide the `\u003cTab/\u003e`                            |\n| `style`            | `object`             |                     | style forwarded to the `\u003cTab /\u003e` containing `\u003cdiv /\u003e`   |  \n| `children`         | `node`               |                     | Any abritary React node                                 |\n\n----\n\n## \u003ca name=\"react-tabify#controlled-vs-uncontrolled-mode\"\u003eControlled vs Uncontrolled Mode\u003c/a\u003e\n\n### Uncontrolled Mode\n\nBy default, `\u003cTabs /\u003e` are uncontrolled, and will display the first `\u003cTab /\u003e` child during initial render. Use `defaultActiveKey` to default to another `\u003cTab /\u003e` instead.\n\nIf `\u003cTab /\u003e` components are not passed an `eventKey`, they will default to their order index. In the example below, we're defaulting `\u003cTabs /\u003e` to display \"Tab 3\" since it sits at the second index (`defaultActiveKey={2}`).\n\n```js\nexport default () =\u003e (\n  \u003cTabs defaultActiveKey={2}\u003e\n    \u003cTab label=\"Tab 1\"\u003eFirst Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003eSecond Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003eThird Content\u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n[![Edit k9zlwno4zv](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/k9zlwno4zv)\n\n----\n\n### Controlled Mode\n\nAlternatively, to control the component, pass an `activeKey`, however you must pass an `onSelect` callback to handle the event. `onSelect` passes the `eventKey` of the selected `\u003cTab /\u003e`.\n\nAgain, if your `\u003cTab /\u003e` components are not passed an `eventKey`, they will default to their order index.\n\n```js\nimport { Tab, Tabs } from 'react-tabify';\n\nclass App extends React.Component {\n  constructor(props) {\n    super(props);\n    this.state = {\n      activeKey: 0\n    };\n  }\n\n  handleTabSelect = activeKey =\u003e {\n    this.setState({ activeKey });\n  };\n\n  render() {\n    return (\n      \u003cTabs activeKey={this.state.activeKey} onSelect={this.handleTabSelect}\u003e\n        \u003cTab label=\"Tab 1\"\u003eFirst Content\u003c/Tab\u003e\n        \u003cTab label=\"Tab 2\"\u003eSecond Content\u003c/Tab\u003e\n        \u003cTab label=\"Tab 3\"\u003eThird Content\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n    );\n  }\n}\n```\n\n[![Edit 30zw8qz25p](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/30zw8qz25p)\n\n----\n\n## \u003ca name=\"react-tabify#other-examples\"\u003eOther Examples\u003c/a\u003e\n\n### \u003ca name=\"react-tabify#stacked\"\u003eStacked\u003c/a\u003e\n\nAdd the `stacked` prop to render the tabs vertically.\n\n```js\nexport default () =\u003e (\n  \u003cTabs stacked\u003e\n    \u003cTab label=\"Tab 1\"\u003eFirst Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003eSecond Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003eThird Content\u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n[![Edit p5y4mpxowq](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/p5y4mpxowq)\n\n----\n\n### \u003ca name=\"react-tabify#sticky\"\u003eSticky\u003c/a\u003e\n\nIf `\u003cTabs /\u003e` is uncontrolled, pass `sticky` to \"remember\" the last active `\u003cTab /\u003e` between page refreshes. When `sticky` is enabled, you must pass you own `id` to `\u003cTabs /\u003e`. This will be used within `LocalStorage` to distinguish between multiple `\u003cTabs /\u003e` instances.\n\n\u003e `LocalStorage` must be enabled in the browser.\n\n```js\nexport default () =\u003e (\n  \u003cTabs sticky\u003e\n    \u003cTab label=\"Tab 1\"\u003eFirst Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003eSecond Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003eThird Content\u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n[![Edit ovqynq18k9](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/ovqynq18k9)\n\n----\n\n### \u003ca name=\"react-tabify#nested\"\u003eNested\u003c/a\u003e\n\nEasily nest tabs to create a section/subsection layout.\n\n```js\nexport default () =\u003e (\n  \u003cTabs stacked\u003e\n    \u003cTab label=\"Tab 1\"\u003e\n      \u003cTabs\u003e\n        \u003cTab label=\"Subtab 1.1\"\u003eTab 1 Content 1\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 1.2\"\u003eTab 1 Content 2\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 1.3\"\u003eTab 1 Content 3\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n    \u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003e\n      \u003cTabs\u003e\n        \u003cTab label=\"Subtab 2.1\"\u003eTab 2 Content 1\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 2.2\"\u003eTab 2 Content 2\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 2.3\"\u003eTab 2 Content 3\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n      \u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003e\n      \u003cTabs\u003e\n        \u003cTab label=\"Subtab 3.1\"\u003eTab 3 Content 1\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 3.2\"\u003eTab 3 Content 2\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 3.3\"\u003eTab 3 Content 3\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n    \u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n\n[![Edit 2pvlwjzp60](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/2pvlwjzp60)\n\n----\n\n### \u003ca name=\"react-tabify#container-overflow\"\u003eContainer Overflow\u003c/a\u003e\n\nTo ensure that scrolling (i.e. `overflow`) is only visible within the `\u003cTab /\u003e` component, we'll want to wrap `\u003cTabs /\u003e` with a Flexbox whose height is set to `100%`. Otherwise, if our `\u003cTab /\u003e` had enough content to induce a scrollbar, our entire `\u003cTabs /\u003e` component would be subject to scrolling, which means the clickable tab links (horizontal and stacked) could scroll out of view.    \n\n```js\nconst tabsContainer = {\n  display: \"flex\",\n  height: \"100%\"\n};\n\nconst App = () =\u003e (\n  \u003cdiv style={tabsContainer}\u003e\n    \u003cTabs stacked\u003e\n      \u003cTab label=\"Tab 1\" style={tabStyle}\u003e\n       {__getLorumIpsum()}\n      \u003c/Tab\u003e\n      \u003cTab label=\"Tab 2\" style={tabStyle}\u003e\n       {__getLorumIpsum()}\n      \u003c/Tab\u003e\n      \u003cTab label=\"Tab 3\" style={tabStyle}\u003e\n        {__getLorumIpsum()}\n      \u003c/Tab\u003e\n    \u003c/Tabs\u003e\n  \u003c/div\u003e\n);\n```\n\n[![Edit w2wzlnqyw](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/w2wzlnqyw)\n\n----\n\n### \u003ca name=\"react-tabify#hiding-tabs\"\u003eHiding Tabs\u003c/a\u003e\n\nUse the `hide` prop to dynmically hide/show `\u003cTab /\u003e` components. Pass a `bool`, or evaluate a function that returns a `bool`.\n\n```js\n// Dummy rejection\nconst __hasAccess = user =\u003e false;\n\nconst App = ({ user }) =\u003e (\n  \u003cdiv style={styles}\u003e\n    \u003cTabs\u003e\n      \u003cTab label=\"Super Admin Tab\" hide\u003e\n        Super Admin Content\n      \u003c/Tab\u003e\n      \u003cTab label=\"Admin Tab\" hide={() =\u003e !__hasAccess(user)}\u003e\n        Admin Content\n      \u003c/Tab\u003e\n      \u003cTab label=\"User Tab\"\u003eUser Content\u003c/Tab\u003e\n    \u003c/Tabs\u003e\n  \u003c/div\u003e\n);\n```\n\n[![Edit 1y19m2q7mj](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/1y19m2q7mj)\n\n----\n\n## \u003ca name=\"react-tabify#color-theme\"\u003eColor Theme\u003c/a\u003e\n\n`react-tabify` leverages `\u003cThemeManager /\u003e` from [glamorous](https://github.com/paypal/glamorous) to expose an optional `theme` object. The `tabs` property of the `theme` controls the horizontal styling, while `menu` controls the stacked view. \n\n\u003e Accepts any valid color (e.g. \"red\", \"#FF0000\", \"hsl(0, 100%, 50%)\", \"rgb(255, 0, 0)\", etc).\n\n\n##### Theme object\n```js\nconst theme = {\n  tabs: {\n    color: \u003ccolor\u003e,\n    borderBottomColor: \u003ccolor\u003e,\n    active: {\n      borderBottomColor: \u003ccolor\u003e,\n      color: \u003ccolor\u003e\n    },\n    hover: {\n      borderBottomColor: \u003ccolor\u003e,\n      color: \u003ccolor\u003e\n    }\n  },\n  menu: {\n    color: \u003ccolor\u003e,\n    borderRight: \u003ccolor\u003e,\n    active: {\n        backgroundColor: \u003ccolor\u003e,\n        color: \u003ccolor\u003e\n    },\n    hover: {\n        color: \u003ccolor\u003e,\n        backgroundColor: \u003ccolor\u003e\n    }\n  }\n};\n```\n\n----\n\nOverride any of the properties above. Here's a simple example:\n\n```js\nconst theme = {\n  tabs: {\n    color: \"red\",\n    active: {\n      color: \"green\"\n    }\n  }\n}\n\nconst App = () =\u003e (\n  \u003cTabs theme={theme}\u003e\n    \u003cTab label=\"Tab 1\"\u003eFirst Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003eSecond Content\u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003eThird Content\u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n\n[![Edit jjw53xqn69](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/jjw53xqn69)\n\n----\n\nA more complex, yet very ugly example theme:\n\n```js\nconst theme = {\n  tabs: {\n    color: \"#FF000\",\n    active: {\n      color: \"green\"\n    }\n  },\n  menu: {\n    color: \"hsl(248, 39%, 39%)\",\n    borderRight: \"darkmagenta\",\n    active: {\n      backgroundColor: \"rgb(165,42,42)\"\n    },\n    hover: {\n      color: \"hsl(240, 100%, 50%)\"\n    }\n  }\n};\n\nconst App = () =\u003e (\n  \u003cTabs stacked theme={theme}\u003e\n    \u003cTab label=\"Tab 1\"\u003e\n      \u003cTabs theme={theme}\u003e\n        \u003cTab label=\"Subtab 1.1\"\u003eTab 1 Content 1\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 1.2\"\u003eTab 1 Content 2\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 1.3\"\u003eTab 1 Content 3\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n    \u003c/Tab\u003e\n    \u003cTab label=\"Tab 2\"\u003e\n      \u003cTabs theme={theme}\u003e\n        \u003cTab label=\"Subtab 2.1\"\u003eTab 2 Content 1\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 2.2\"\u003eTab 2 Content 2\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 2.3\"\u003eTab 2 Content 3\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n    \u003c/Tab\u003e\n    \u003cTab label=\"Tab 3\"\u003e\n      \u003cTabs theme={theme}\u003e\n        \u003cTab label=\"Subtab 3.1\"\u003eTab 3 Content 1\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 3.2\"\u003eTab 3 Content 2\u003c/Tab\u003e\n        \u003cTab label=\"Subtab 3.3\"\u003eTab 3 Content 3\u003c/Tab\u003e\n      \u003c/Tabs\u003e\n    \u003c/Tab\u003e\n  \u003c/Tabs\u003e\n);\n```\n\n[![Edit nkk5550ox4](https://codesandbox.io/static/img/play-codesandbox.svg)](https://codesandbox.io/s/nkk5550ox4)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikechabot%2Freact-tabify","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmikechabot%2Freact-tabify","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmikechabot%2Freact-tabify/lists"}