{"id":16402179,"url":"https://github.com/dev-javascript/react-dyn-tabs","last_synced_at":"2025-03-16T16:31:51.311Z","repository":{"id":143905140,"uuid":"342026999","full_name":"dev-javascript/react-dyn-tabs","owner":"dev-javascript","description":"React Dynamic Tabs, React Responsive Tabs","archived":false,"fork":false,"pushed_at":"2024-12-20T00:15:46.000Z","size":6384,"stargazers_count":14,"open_issues_count":0,"forks_count":10,"subscribers_count":1,"default_branch":"master","last_synced_at":"2025-02-27T11:42:08.028Z","etag":null,"topics":["accessibility","accessible-tabs","dynamic-tabs","react","react-dyn-tabs","react-dynamic-tabs","react-hooks","react-responsive-tabs","react-tab-component","react-tabs","react-tabs-component","responsive","tab-management","tab-navigation","tabs"],"latest_commit_sha":null,"homepage":"https://dev-javascript.github.io/react-dyn-tabs/","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/dev-javascript.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2021-02-24T20:29:19.000Z","updated_at":"2024-12-20T00:14:43.000Z","dependencies_parsed_at":"2023-11-09T11:20:06.225Z","dependency_job_id":"b17a567c-7316-48ee-a990-ea5970a85105","html_url":"https://github.com/dev-javascript/react-dyn-tabs","commit_stats":null,"previous_names":[],"tags_count":44,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-javascript%2Freact-dyn-tabs","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-javascript%2Freact-dyn-tabs/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-javascript%2Freact-dyn-tabs/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/dev-javascript%2Freact-dyn-tabs/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/dev-javascript","download_url":"https://codeload.github.com/dev-javascript/react-dyn-tabs/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243822295,"owners_count":20353500,"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":["accessibility","accessible-tabs","dynamic-tabs","react","react-dyn-tabs","react-dynamic-tabs","react-hooks","react-responsive-tabs","react-tab-component","react-tabs","react-tabs-component","responsive","tab-management","tab-navigation","tabs"],"created_at":"2024-10-11T05:45:23.033Z","updated_at":"2025-03-16T16:31:50.884Z","avatar_url":"https://github.com/dev-javascript.png","language":"JavaScript","readme":"# react-dyn-tabs\n\nCreate responsive and dynamic tabs in React. This library supports ARIA accessibility and provides complete control over tab management using hooks.\n\n[![Test coverage](https://codecov.io/gh/dev-javascript/react-dyn-tabs/graph/badge.svg?token=GT1LU074L2)](https://codecov.io/gh/dev-javascript/react-dyn-tabs) [![NPM version](http://img.shields.io/npm/v/react-dyn-tabs.svg?style=flat-square)](https://www.npmjs.com/package/react-dyn-tabs) [![node](https://img.shields.io/badge/node.js-%3E=_8.0-green.svg?style=flat-square)](http://nodejs.org/download/) [![React](https://img.shields.io/badge/React-%3E=_16.8.0-green.svg?style=flat-square)](https://react.dev/) [![License](http://img.shields.io/npm/l/react-dyn-tabs.svg?style=flat-square)](LICENSE) [![npm download](https://img.shields.io/npm/dm/react-dyn-tabs.svg?style=flat-square)](https://npmjs.org/package/react-dyn-tabs) [![Build Status](https://travis-ci.org/ly-components/react-dyn-tabs.png)](https://travis-ci.org/ly-components/react-dyn-tabs)\n\n## Screenshot\n\n![Screenshot](https://github.com/user-attachments/assets/15a0860d-168d-4f21-8b9d-62fcec3f6ccf)\n\n## Demo\n\n- [Online Demo](https://dev-javascript.github.io/react-dyn-tabs/)\n\n## Features\n\n- **Responsive (using `more button`)**\n- **Full API (Open \u0026 Close \u0026 Select \u0026 Refresh \u0026 setOption \u0026 setTab, ...)**\n- **lazy loading and rendering**\n- **Customizable style**\n- **Return to last used tab when closing selected tab**\n- **PanelList can be rendered outside the TabList container**\n- **ARIA accessible**\n- **Customizable Tab component**\n- **Multiple themes**\n- **The core is about 23kb**\n\n## Table of Contents\n\n\u003c!-- toc --\u003e\n\n- [Installation](#installation)\n- [Syntax](#syntax)\n- [Minimal Usage Example](#minimal-usage-example)\n- [Simple Manipulation Example](#simple-manipulation-example)\n- [ready function](#ready-function)\n- [Options](#options)\n  - [tabs](#tabs)\n  - [selectedTabID](#selectedtabid)\n  - [direction](#direction)\n  - [tabComponent](#tabcomponent)\n  - [defaultPanelComponent](#defaultpanelcomponent)\n  - [accessibility](#accessibility)\n  - [isVertical](#isvertical)\n  - [theme](#theme)\n  - [tablistStyle](#tabliststyle)\n  - [onLoad](#onload)\n  - [onInit](#oninit)\n  - [onChange](#onchange)\n  - [beforeSelect](#beforeselect)\n  - [onFirstSelect](#onfirstselect)\n  - [onSelect](#onselect)\n  - [onOpen](#onopen)\n  - [beforeClose](#beforeclose)\n  - [onClose](#onclose)\n  - [onDestroy](#ondestroy)\n- [Instance methods](#instance-methods)\n  - [isOpen](#isopen)\n  - [open](#open)\n  - [isSelected](#isselected)\n  - [select](#select)\n  - [close](#close)\n  - [refresh](#refresh)\n  - [getOption](#getoption)\n  - [setOption](#setoption)\n  - [getTab](#gettab)\n  - [setTab](#settab)\n  - [on](#on)\n  - [one](#one)\n  - [off](#off)\n  - [getData](#getdata)\n  - [getPreviousData](#getpreviousdata)\n  - [sort](#sort)\n- [tabData](#tabdata)\n- [Lazy Loading](#lazy-loading)\n- [Plugins](#plugins)\n  - [More Button Plugin](#more-button-plugin)\n- [Render custom components at the end of the Tablist](#render-custom-components-at-the-end-of-the-tablist)\n- [Themes And Style](#themes-and-style)\n- [Caveats](#caveats)\n- [Test](#test)\n- [License](#license)\n\n\u003c!-- tocstop --\u003e\n\n## Installation\n\n```js\n $ npm install react-dyn-tabs --save\n```\n\nor\n\n```js\n$ yarn add react-dyn-tabs\n```\n\nIf you need to directly include script in your html, use the following link :\n\n```js\n\u003cscript src=\"https://unpkg.com/react-dyn-tabs@latest/dist/react-dyn-tabs.umd.min.js\"\u003e\u003c/script\u003e\n```\n\n## Syntax\n\n```js\n[TabList, PanelList, ready] = useDynTabs(initialOptions, plugins);\n```\n\n## Minimal Usage Example\n\n```js\nimport React from 'react';\nimport 'react-dyn-tabs/style/react-dyn-tabs.css'; // Mandatory CSS required by the react-dyn-tabs\nimport 'react-dyn-tabs/themes/react-dyn-tabs-card.css'; // Optional Theme applied to the react-dyn-tabs\nimport useDynTabs from 'react-dyn-tabs';\n\nconst initialOptions = {\n  tabs: [\n    {\n      id: '1',\n      title: 'tab 1',\n      panelComponent: (props) =\u003e \u003cp\u003e panel 1 \u003c/p\u003e,\n    },\n    {\n      id: '2',\n      title: 'tab 2',\n      panelComponent: (props) =\u003e \u003cp\u003e panel 2 \u003c/p\u003e,\n    },\n  ],\n  selectedTabID: '1',\n};\n\nexport default () =\u003e {\n  const [TabList, PanelList] = useDynTabs(initialOptions);\n  return (\n    \u003cdiv\u003e\n      \u003cTabList\u003e\u003c/TabList\u003e\n      \u003cPanelList\u003e\u003c/PanelList\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n## Simple Manipulation Example\n\n```js\nimport React from 'react';\nimport 'react-dyn-tabs/style/scss/react-dyn-tabs.scss';\nimport 'react-dyn-tabs/themes/scss/react-dyn-tabs-card.scss';\nimport useDynTabs from 'react-dyn-tabs';\n\nconst initialOptions = {\n  tabs: [\n    {\n      id: '1',\n      title: 'tab1',\n      panelComponent: (props) =\u003e \u003cp\u003e panel 1 \u003c/p\u003e,\n    },\n    {\n      id: '2',\n      title: 'tab2',\n      panelComponent: (props) =\u003e \u003cp\u003e panel 2 \u003c/p\u003e,\n    },\n  ],\n  selectedTabID: '1',\n};\n\nexport default () =\u003e {\n  const [TabList, PanelList, ready] = useDynTabs(initialOptions);\n\n  const addTab3 = function () {\n    // use ready function to access the instance object\n    ready((instance) =\u003e {\n      // open tab 3\n      instance.open({id: '3', title: 'Tab 3', panelComponent: (props) =\u003e \u003cp\u003e panel 3 \u003c/p\u003e}).then(() =\u003e {\n        console.log('tab 3 is open');\n      });\n      // switch to tab 3\n      instance.select('3').then(() =\u003e {\n        console.log('tab 3 is selected');\n      });\n    });\n  };\n\n  return (\n    \u003cdiv\u003e\n      \u003cbutton onClick={addTab3}\u003eAdd tab 3\u003c/button\u003e\n      \u003cTabList\u003e\u003c/TabList\u003e\n      \u003cPanelList\u003e\u003c/PanelList\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n## ready function\n\nThe `ready` function in the `react-dyn-tabs` library is part of the array returned by the `useDynTabs` hook, alongside the `TabList` and `PanelList` components. This function allows developers to execute a callback when the `TabList` and `PanelList` components are fully mounted, providing access to the instance object for further manipulation.\n\n### Key Features\n\n- **Multiple Calls**: Developers can invoke the `ready` function multiple times without any issues.\n- **Stable Identity**: The reference to the `ready` function remains stable across component re-renders, ensuring consistent behavior.\n- **Immediate Execution**: If the `ready` function is called after the tabs have already been mounted, the provided callback will be executed immediately.\n\n### Example Usage\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs(initialOptions);\n\nconst addTab3 = function () {\n  ready((instance) =\u003e {\n    // open tab 3\n    instance.open({id: '3', title: 'Tab 3', panelComponent: (props) =\u003e \u003cp\u003e panel 3 \u003c/p\u003e}).then(() =\u003e {\n      console.log('tab 3 is open');\n    });\n    // switch to tab 3\n    instance.select('3').then(() =\u003e {\n      console.log('tab 3 is selected');\n    });\n  });\n};\n```\n\n## Options\n\n### tabs\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003e\n        \u003cp\u003e\u003cspan\u003eArray of\u003c/span\u003e \u003ca href=\"#tabData\"\u003etabData\u003c/a\u003e\u003c/p\u003e\n      \u003c/td\u003e\n      \u003ctd\u003e\u003ccode\u003e[]\u003c/code\u003e\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003einitial opened tabs\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  tabs: [\n    {\n      id: '1',\n      title: 'home',\n      iconClass: 'fa fa-home',\n      closable: true,\n      panelComponent: (props) =\u003e \u003cp\u003e home content \u003c/p\u003e,\n    },\n    {\n      id: '2',\n      title: 'contact',\n      tooltip: 'contact',\n      disable: true,\n      closable: false,\n      panelComponent: (props) =\u003e \u003cp\u003e contact content \u003c/p\u003e,\n    },\n  ],\n});\n```\n\n### selectedTabID\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e' '\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003especifies initial selected tab\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  tabs: [\n    {\n      id: '1',\n      title: 'home',\n      iconClass: 'fa fa-home',\n      closable: true,\n      panelComponent: (props) =\u003e \u003cp\u003e home content \u003c/p\u003e,\n    },\n    {\n      id: '2',\n      title: 'contact',\n      tooltip: 'contact',\n      disable: true,\n      closable: false,\n      panelComponent: (props) =\u003e \u003cp\u003e contact content \u003c/p\u003e,\n    },\n  ],\n  selectedTabID: '2',\n});\n```\n\n### direction\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e'ltr'\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003ecan be either of 'ltr' or 'rtl'\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({direction: 'rtl'});\n```\n\n### tabComponent\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eReact component\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003ecustom tab component\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  tabComponent: (props) =\u003e {\n    const {id, isSelected, api: instance} = props;\n    return (\n      \u003cbutton {...props.tabProps}\u003e\n        {props.children}\n        {props.iconProps \u0026\u0026 \u003cspan {...props.iconProps}\u003e\u003c/span\u003e}\n      \u003c/button\u003e\n    );\n  },\n});\n```\n\n### defaultPanelComponent\n\nDefault value for `panelComponent` option.\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eReact component | React element\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  defaultPanelComponent: (props) =\u003e {\n    const {id, isSelected, api: instance} = props;\n    return \u003cdiv\u003eloading...\u003c/div\u003e;\n  },\n});\n```\n\n### accessibility\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eboolean\u003c/td\u003e\n      \u003ctd\u003etrue\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({accessibility: false});\n```\n\n**NOTE :**\n\nWhen `accessibility` option is `true`, it sets the id attribute of `panel` and `button` elements.\n\n### isVertical\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eboolean\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({isVertical: true});\n```\n\n### theme\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003eno\u003c/td\u003e\n      \u003ctd\u003ethe chosen theme name when you have multiple themes CSS.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Examples**\n\n- in this exmaple, only `bootstrap` theme is applied to the `Tablist`, because value of `theme` option is `bootstrap`\n\n  ```js\n  import 'react-dyn-tabs/themes/react-dyn-tabs-card.css';\n  import 'react-dyn-tabs/themes/react-dyn-tabs-bootstrap.css';\n  import 'react-dyn-tabs/themes/react-dyn-tabs-classic.css';\n  import 'react-dyn-tabs/themes/react-dyn-tabs-basic.css';\n  ...\n  useDynTabs({theme:'bootstrap'});\n  ```\n\n- in this exmaple, only `classic` theme is applied to the `Tablist`, because value of `theme` option is `classic`\n\n  ```js\n  import 'react-dyn-tabs/themes/react-dyn-tabs-card.css';\n  import 'react-dyn-tabs/themes/react-dyn-tabs-bootstrap.css';\n  import 'react-dyn-tabs/themes/react-dyn-tabs-classic.css';\n  import 'react-dyn-tabs/themes/react-dyn-tabs-basic.css';\n  ...\n  useDynTabs({theme:'classic'});\n  ```\n\n#### Notes\n\n- If the `theme` option is not provided then all imported themes CSS will be applied to the `Tablist`.\n\n- If the `theme` option is set to a empty string then imported themes CSS will not be applied to the `Tablist`.\n\n- You can create your own theme CSS and set the `theme` option to your theme class name\n\n### tablistStyle\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eobject\u003c/td\u003e\n      \u003ctd\u003e{}\u003c/td\u003e\n      \u003ctd\u003eno\u003c/td\u003e\n      \u003ctd\u003esets the style object for root element of Tablist\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  tablistStyle: {backgroundColor: 'blue'},\n});\n```\n\n### onLoad\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003eThis event is fired only once, when Tabs are mounted\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onLoad: function () {\n    console.log('[onLoad]');\n  },\n});\n```\n\n**NOTE :**\n\nYou can use `this` keyword inside all callback options. It refers to the `instance` object.\n\n### onInit\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003eThis event is triggered after every render.\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onInit: function () {\n    console.log('[onInit]');\n  },\n});\n```\n\n**NOTE :**\n\nDo not use `setState` inside the `onInit` callback because it leads to an infinite loop.\n\n### onChange\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efires when we open|close|select a tab. this event is not fired initially\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onChange: function ({currentData, previousData, closedTabIDs, openedTabIDs}) {\n    console.log('[onChange]');\n  },\n});\n```\n\n### beforeSelect\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\n        Fires when the user clicks on the tab, but before select them. \n        This event should return boolean true or false, If the event returns false the tab is not selected.\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  beforeSelect: function (e, id) {\n    console.log('[beforeSelect]');\n    return true;\n  },\n});\n```\n\n### onFirstSelect\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efires after selecting a tab for the first time. It is not fired for the initial selected tab\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onFirstSelect: function ({currentSelectedTabId, previousSelectedTabId}) {\n    console.log('[onFirstSelect]');\n  },\n});\n```\n\n### onSelect\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efires after selecting a tab. this event is not fired for the initial selected tab\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onSelect: function ({currentSelectedTabId, previousSelectedTabId}) {\n    console.log('[onSelect]');\n  },\n});\n```\n\n### onOpen\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efires after opening tabs. this event is not fired for initial opened tabs\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onOpen: function (openedTabIDs) {\n    console.log('[onOpen]');\n  },\n});\n```\n\n### beforeClose\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\n        fires when the user clicks on the close icon, but before close them. \n        This event should return boolean true or false,  If the event return false the tab is not closed.\n      \u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  beforeClose: function (e, id) {\n    console.log('[beforeClose]');\n    return true;\n  },\n});\n```\n\n### onClose\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efires after closing tabs\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onClose: function (closedTabIDs) {\n    console.log('[onClose]');\n  },\n});\n```\n\n### onDestroy\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003efunction\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efires before destroying useDynTabs hook\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst [TabList, PanelList, ready] = useDynTabs({\n  onDestroy: function () {\n    console.log('[onDestroy]');\n  },\n});\n```\n\n## Instance methods\n\n### isOpen\n\nReturn value : `boolean`\n\nParameters:\n\n- `id: String`\n\n**Example**\n\n```js\nconst result = instance.isOpen('Your tab ID');\n```\n\n### open\n\nTriggers `onInit`, `onChange` and `onOpen` events.\n\nIt only triggers `onInit` event, if the tab is already open.\n\nReturn value : `Promise`\n\nParameters:\n\n- `tabData: Object`\n\n**Example**\n\n```js\nif (instance.isOpen('contact') == false) {\n  instance\n    .open({\n      id: 'contact',\n      title: 'contact',\n      tooltip: 'contact',\n      disable: false,\n      closable: true,\n      iconClass: '',\n      panelComponent: \u003cContactPanel\u003e\u003c/ContactPanel\u003e,\n    })\n    .then(({currentData, instance}) =\u003e {\n      console.log('contact tab is open');\n    });\n}\n```\n\n### isSelected\n\nReturn value : `boolean`\n\nParameters:\n\n- `id: String`\n\n**Example**\n\n```js\nconst result = instance.isSelected('Your tab ID');\n```\n\n### select\n\nMakes current and previous selected tab to be re-rendered\n\nTriggers `onInit`, `onChange` and `onSelect` events.\n\nIt only triggers `onInit` event, if the tab is already selected.\n\nReturn value : `Promise`\n\nParameters:\n\n- `id: string`\n\n**Example**\n\n```js\nif (instance.isSelected('1') == false) {\n  instance.select('1').then(({currentData, instance}) =\u003e {\n    console.log('tab 1 is selected');\n  });\n}\n```\n\n### close\n\nTriggers `onInit`, `onChange` and `onClose` events.\n\nIt only triggers `onInit` event, if the tab is already closed.\n\nWhen `switching` parameter is `true`, it switches to previous selected tab\n\nReturn value : `Promise`\n\nParameters:\n\n- `id: string`\n- `switching: boolean (default : true)`\n\n**Example**\n\n```js\nif (instance.isOpen('2') == true) {\n  instance.close('2').then(({currentData, instance}) =\u003e {\n    console.log('tab 2 is closed');\n  });\n}\n```\n\n### refresh\n\nMakes all tabs to be re-rendered.\n\ntriggers `onInit` event.\n\nReturn value : `Promise`\n\n**Example**\n\n```js\ninstance.refresh().then(({currentData, instance}) =\u003e {});\n```\n\n### getOption\n\nParameters:\n\n- `optionName : String`\n\n**Example**\n\n```js\nconst direction = instance.getOption('direction');\nconst onSelect = instance.getOption('onSelect');\n```\n\n### setOption\n\nCan be used for setting all options except `selectedTabID` and `tabs` options.\n\nThis function does not re-render Tabs. If you need to re-render Tabs, use `refresh` method after this function.\n\nReturn value : `instance object`\n\nParameters:\n\n- `optionName : String`\n- `optionValue : string|boolean|object|function`\n\n**Example**\n\n```js\ninstance.setOption('direction', 'rtl');\ninstance.setOption('onSelect', () =\u003e {});\ninstance.setOption('beforeSelect', () =\u003e false);\n```\n\n### getTab\n\nGet `tabData` object\n\nReturn value : `tabData object`\n\nParameters:\n\n- `id : String`\n\n**Example**\n\n```js\nconst {id, title, tooltip, disable, lazy, iconClass, closable, panelComponent} = instance.getTab('contactID');\nconsole.log(id); //contactID\n```\n\n### setTab\n\nSet `tabData` object.\n\nThis function does not re-render Tabs. If you need to re-render Tabs, use `refresh` method after this function.\n\nReturn value : `instance object`\n\nParameters:\n\n- `tab id : String`\n- `source object : containing the properties you want to apply`\n\n**Example**\n\n```js\ninstance.setTab('home', {disable: true});\ninstance.setTab('contact', {closable: false, panelComponent: (props) =\u003e \u003cp\u003econtact panel\u003c/p\u003e});\n```\n\n### on\n\nAttach an event handler function for one event.\n\nReturn value : `instance object`\n\nParameters:\n\n- `event Name : String (can be either of onFirstSelect|onSelect|onClose|onOpen|onInit|onChange|onDestroy)`\n- `handler : function`\n\n**Example**\n\n```js\nconst handler = React.useCallback(function (params) {\n  const {currentSelectedTabId, previousSelectedTabId} = params;\n}, []);\ninstance.on('onSelect', handler);\n```\n\n### one\n\nAttach a handler to an event. The handler is executed at most once.\n\nReturn value : `instance object`\n\nParameters:\n\n- `event Name : String (can be either of onFirstSelect|onSelect|onClose|onOpen|onInit|onChange|onDestroy)`\n- `handler : function`\n\n**Example**\n\n```js\ninstance.one('onSelect', function ({currentSelectedTabId, previousSelectedTabId}) {});\n```\n\n### off\n\nRemove an event handler.\n\nReturn value : `instance object`\n\nParameters:\n\n- `event Name : String (can be either of onFirstSelect|onSelect|onClose|onOpen|onInit|onChange|onDestroy)`\n- `handler : function (A handler function previously attached for the event)`\n\n**Example**\n\n```js\nconst handler = React.useCallback(function () {}, []);\nconst attachHandler = () =\u003e {\n  instance.on('onSelect', handler);\n};\nconst deattachHandler = () =\u003e {\n  instance.off('onSelect', handler);\n};\n```\n\n### getData\n\nGet a copy of data\n\nReturn value : `Data` Object\n\n**Example**\n\n```js\nconst {selectedTabID, openTabIDs} = instance.getData();\n```\n\n**NOTE :**\n\n- `getCopyData` function is an older version of `getData` function and it is enabled by default so that existing users do not have to change their code. You are free to use both conventions.\n\n### getPreviousData\n\nGet a copy of data in previous render\n\nReturn value : `Data` Object\n\n**Example**\n\n```js\nconst {selectedTabID, openTabIDs} = instance.getPreviousData();\n```\n\n**NOTE :**\n\n- `getCopyPerviousData` function is an older version of `getPreviousData` function and it is enabled by default so that existing users do not have to change their code. You are free to use both conventions.\n\n### sort\n\nUseful for sorting Tabs manually.\n\nTriggers `onInit` event.\n\nReturn value : `Promise`\n\nParameters:\n\n- `Array of all Tabs IDs`\n\n**Example**\n\n```js\nconst {openTabIDs} = instance.getData();\ninstance.sort(openTabIDs.reverse()).then(({currentData, instance}) =\u003e {\n  console.log('sorting Tabs has finished');\n});\n```\n\n## tabData\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003eproperty name\u003c/th\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edefault value\u003c/th\u003e\n      \u003cth\u003erequired\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eid\u003c/td\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003ean unique identifier for each tab\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003etitle\u003c/td\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e' '\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003etooltip\u003c/td\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e' '\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003epanelComponent\u003c/td\u003e\n      \u003ctd\u003eReact Element | React Component | null\u003c/td\u003e\n      \u003ctd\u003eA function component which returns empty div\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003elazy\u003c/td\u003e\n      \u003ctd\u003eboolean\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\n       If set to false the panel will be rendered initially.\n       if set to true the panel will not be rendered until the tab is activated\n      \u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eclosable\u003c/td\u003e\n      \u003ctd\u003eboolean\u003c/td\u003e\n      \u003ctd\u003etrue\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003eiconClass\u003c/td\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e' '\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003eclass name for the icon\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003edisable\u003c/td\u003e\n      \u003ctd\u003eboolean\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003efalse\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nconst tabData = {\n  id: 'contactID',\n  title: 'contactTitle',\n  tooltip: 'contactTooltip',\n  disable: true,\n  lazy: true,\n  iconClass: 'fa fa-home',\n  closable: false,\n  panelComponent: (props) =\u003e \u003cp\u003e contact content \u003c/p\u003e,\n};\nconst [TabList, PanelList, ready] = useDynTabs({tabs: [tabData]});\n// or\nif (instance.isOpen(tabData.id) == false) {\n  instance.open(tabData).then(() =\u003e {});\n}\n```\n\n## Lazy Loading\n\nDefer loading of tab content until the tab is activated\n\nExample 1\n\n```js\nconst Panel3 = React.lazy(() =\u003e import('./components/panel3.js'));\nfunction LazyLoadingPanel3(props) {\n  return (\n    \u003cSuspense fallback={\u003cdiv\u003eLoading...\u003c/div\u003e}\u003e\n      \u003cPanel3 {...props}\u003e\u003c/Panel3\u003e\n    \u003c/Suspense\u003e\n  );\n}\nuseDynTabs({\n  tabs: [\n    {id: '1', title: 'eager loading tab 1', panelComponent: \u003cp\u003epanel 1\u003c/p\u003e},\n    {id: '2', title: 'eager loading tab 2', lazy: true, panelComponent: \u003cp\u003epanel 2\u003c/p\u003e},\n    {id: '3', title: 'lazy loading tab 3', lazy: true, panelComponent: LazyLoadingPanel3},\n  ],\n  selectedTabID: '1',\n});\n```\n\n**NOTE :**\n\n- panel 1 is eagerly loaded and rendered.\n- panel 2 is eagerly loaded but will not be rendered until tab 2 is activated.\n- panel 3 will not be loaded and rendered until tab 3 is activated.\n\nExample 2 ( using onFirstSelect event )\n\n```js\nuseDynTabs({\n  tabs: [\n    {id: '1', title: 'eager loading tab 1', panelComponent: \u003cp\u003epanel 1\u003c/p\u003e},\n    {id: '2', title: 'eager loading tab 2', lazy: true, panelComponent: \u003cp\u003epanel 2\u003c/p\u003e},\n    {id: '3', title: 'lazy loading tab 3', lazy: true},\n  ],\n  selectedTabID: '1',\n  defaultPanelComponent: function DefaultPanel() {\n    return \u003cdiv\u003eloading...\u003c/div\u003e;\n  },\n  onFirstSelect: function ({currentSelectedTabId}) {\n    const instance = this;\n    if (currentSelectedTabId === '3') {\n      import('path to/panel3.js').then((defaultExportedModule) =\u003e {\n        const Panel3 = defaultExportedModule.default;\n        instance.setTab('3', {panelComponent: Panel3});\n        instance.refresh();\n      });\n    }\n  },\n});\n```\n\n## Plugins\n\n### More Button Plugin\n\nMake Tabs `responsive`\n\n**Usage**\n\n```js\nimport React from 'react';\nimport 'react-dyn-tabs/style/react-dyn-tabs.css';\nimport 'react-dyn-tabs/themes/react-dyn-tabs-card.css';\nimport useDynTabs from 'react-dyn-tabs';\nimport MoreButtonPlugin from 'react-dyn-tabs/plugins/moreButtonPlugin';\n\nexport default () =\u003e {\n  const [TabList, PanelList, ready] = useDynTabs(initialOptions, [MoreButtonPlugin]);\n  return (\n    \u003cdiv\u003e\n      \u003cTabList\u003e\u003c/TabList\u003e\n      \u003cPanelList\u003e\u003c/PanelList\u003e\n    \u003c/div\u003e\n  );\n};\n```\n\n**Options**\n\n\u003ctable\u003e\n  \u003ctbody\u003e\n    \u003ctr\u003e\n      \u003cth\u003eoption name\u003c/th\u003e\n      \u003cth\u003etype\u003c/th\u003e\n      \u003cth\u003edescription\u003c/th\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003emoreButtonPlugin_buttonComponent\u003c/td\u003e\n      \u003ctd\u003eReact Function Component\u003c/td\u003e\n      \u003ctd\u003ecustomize root component of more button\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003emoreButtonPlugin_iconComponent\u003c/td\u003e\n      \u003ctd\u003eReact Function Component\u003c/td\u003e\n      \u003ctd\u003ecustomize icon component of more button\u003c/td\u003e\n    \u003c/tr\u003e\n    \u003ctr\u003e\n      \u003ctd\u003emoreButtonPlugin_buttonTooltip\u003c/td\u003e\n      \u003ctd\u003estring\u003c/td\u003e\n      \u003ctd\u003e\u003c/td\u003e\n    \u003c/tr\u003e\n  \u003c/tbody\u003e\n\u003c/table\u003e\n\n**Example**\n\n```js\nuseDynamicTabs(\n  {\n    tabs: [\n      {id: '1', title: 'tab1', panelComponent: \u003cspan\u003etab content 1\u003c/span\u003e},\n      {id: '2', title: 'tab2', panelComponent: \u003cspan\u003etab content 2\u003c/span\u003e},\n      {id: '3', title: 'tab3', panelComponent: \u003cspan\u003etab content 3\u003c/span\u003e},\n    ],\n    selectedTabID: '1',\n    moreButtonPlugin_iconComponent: ({instance}) =\u003e {\n      return \u003ci className={`fa fa-chevron-${instance.getOption('direction') === 'rtl' ? 'left' : 'right'}`} /\u003e;\n    },\n    moreButtonPlugin_buttonTooltip: 'show more tabs',\n  },\n  [MoreButtonPlugin],\n);\n```\n\n**unpkg Link**\n\n```js\n\u003cscript src=\"https://unpkg.com/react-dyn-tabs@latest/dist/more-button-plugin.umd.min.js\"\u003e\u003c/script\u003e\n```\n\n## Render custom components at the end of the Tablist\n\n- render `new tab` button example :\n\n  ```js\n    const [TabList, PanelList, ready] = useDynTabs(initialOptions, [MoreButtonPlugin]);\n    return (\n      \u003cdiv\u003e\n        \u003cTabList\u003e\n          \u003cbutton onClick={()=\u003e{ ready(instance =\u003e instance.open({title:'new tab'})) }}\u003e\n            NEW\n          \u003c/button\u003e\n        \u003c/TabList\u003e\n        \u003cPanelList\u003e\u003c/PanelList\u003e\n      \u003c/div\u003e\n    );\n  };\n\n  ```\n\n- render `close all` button example :\n\n  ```js\n    const [TabList, PanelList, ready] = useDynTabs(initialOptions, [MoreButtonPlugin]);\n    return (\n      \u003cdiv\u003e\n        \u003cTabList\u003e\n          \u003cbutton onClick={()=\u003e{ ready(instance=\u003e{ instance.getData().openTabIDs.forEach(id=\u003einstance.close(id,false)); })}}\u003e\n            CLOSE ALL\n          \u003c/button\u003e\n        \u003c/TabList\u003e\n        \u003cPanelList\u003e\u003c/PanelList\u003e\n      \u003c/div\u003e\n    );\n  };\n\n  ```\n\n## Themes And Style\n\n`react-dyn-tabs` does not include any style loading by default. Default stylesheets and themes are provided and can be included in your application if desired.\n\n### Import the Style\n\n```js\nimport 'react-dyn-tabs/style/react-dyn-tabs.css';\n// or import 'react-dyn-tabs/style/react-dyn-tabs.min.css';\n// or import 'react-dyn-tabs/style/scss/react-dyn-tabs.scss';\n```\n\nFor `rtl` mode you should also import following file\n\n```js\nimport 'react-dyn-tabs/style/react-dyn-tabs-rtl.css';\n// or import 'react-dyn-tabs/style/react-dyn-tabs-rtl.min.css';\n// or import 'react-dyn-tabs/style/scss/react-dyn-tabs-rtl.scss';\n```\n\n### Themes\n\nThemes define how the Tabs looks. The library comes with Provided Themes such as `card` and `bootstrap`. To use a theme you need to 1) import the themes CSS and 2) apply the chosen theme name to the `theme` option of the `react-dyn-tabs`.\n\n- card theme\n\n  ```js\n  import 'react-dyn-tabs/themes/react-dyn-tabs-card.css';\n  // or import 'react-dyn-tabs/themes/scss/react-dyn-tabs-card.scss';\n  // or import 'react-dyn-tabs/themes/react-dyn-tabs-card.min.css';\n  ...\n  useDynTabs({theme:'card'});\n  ```\n\n- bootstrap theme\n\n  ```js\n  import 'react-dyn-tabs/themes/react-dyn-tabs-bootstrap.css';\n  // or import 'react-dyn-tabs/themes/scss/react-dyn-tabs-bootstrap.scss';\n  // or import 'react-dyn-tabs/themes/react-dyn-tabs-bootstrap.min.css';\n  ...\n  useDynTabs({theme:'bootstrap'});\n  ```\n\n- basic theme\n\n  ```js\n  import 'react-dyn-tabs/themes/react-dyn-tabs-basic.css';\n  // or import 'react-dyn-tabs/themes/scss/react-dyn-tabs-basic.scss';\n  // or import 'react-dyn-tabs/themes/react-dyn-tabs-basic.min.css';\n  ...\n  useDynTabs({theme:'basic'});\n  ```\n\n- classic theme\n\n  ```js\n  import 'react-dyn-tabs/themes/react-dyn-tabs-classic.css';\n  // or import 'react-dyn-tabs/themes/scss/react-dyn-tabs-classic.scss';\n  // or import 'react-dyn-tabs/themes/react-dyn-tabs-classic.min.css';\n  ...\n  useDynTabs({theme:'classic'});\n  ```\n\n## Caveats\n\n- Some actions like open, select, close and refresh cause re-rendering, and using them immediately after calling useDynTabs hook will create an infinite loop and other bugs that most likely you don't want to cause. you should use them inside event listeners or subscriptions.\n\n- Do not use setState inside the onInit callback because it leads to an infinite loop.\n\n## Test\n\n```js\n$ npm run test\n```\n\n## License\n\nMIT\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-javascript%2Freact-dyn-tabs","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdev-javascript%2Freact-dyn-tabs","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdev-javascript%2Freact-dyn-tabs/lists"}