{"id":16695285,"url":"https://github.com/georgeosddev/react-draggable-tab","last_synced_at":"2025-04-06T04:09:04.628Z","repository":{"id":32969732,"uuid":"36588483","full_name":"georgeOsdDev/react-draggable-tab","owner":"georgeOsdDev","description":"Atom like draggable tab react component","archived":false,"fork":false,"pushed_at":"2023-12-15T20:26:25.000Z","size":9925,"stargazers_count":144,"open_issues_count":19,"forks_count":31,"subscribers_count":9,"default_branch":"master","last_synced_at":"2025-03-30T03:05:00.316Z","etag":null,"topics":["draggable","react","tabs"],"latest_commit_sha":null,"homepage":"http://georgeosddev.github.io/react-draggable-tab/","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":"symfony/lts","license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/georgeOsdDev.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"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":"2015-05-31T04:54:18.000Z","updated_at":"2024-06-22T16:11:53.000Z","dependencies_parsed_at":"2024-06-18T21:21:21.919Z","dependency_job_id":"15383513-44d5-4842-b713-d9f415428ea1","html_url":"https://github.com/georgeOsdDev/react-draggable-tab","commit_stats":{"total_commits":149,"total_committers":13,"mean_commits":"11.461538461538462","dds":0.3691275167785235,"last_synced_commit":"1f16ea4c8085822f1da7b19bba91f055ce2fe0a1"},"previous_names":[],"tags_count":20,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgeOsdDev%2Freact-draggable-tab","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgeOsdDev%2Freact-draggable-tab/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgeOsdDev%2Freact-draggable-tab/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/georgeOsdDev%2Freact-draggable-tab/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/georgeOsdDev","download_url":"https://codeload.github.com/georgeOsdDev/react-draggable-tab/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247430868,"owners_count":20937874,"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":["draggable","react","tabs"],"created_at":"2024-10-12T17:06:20.298Z","updated_at":"2025-04-06T04:09:04.605Z","avatar_url":"https://github.com/georgeOsdDev.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# React-draggable-tab [![Build Status](https://travis-ci.org/georgeOsdDev/react-draggable-tab.svg?branch=develop)](https://travis-ci.org/georgeOsdDev/react-draggable-tab) [![npm version](https://badge.fury.io/js/react-draggable-tab.svg)](http://badge.fury.io/js/react-draggable-tab)\n\n\n[![Gyazo](http://i.gyazo.com/42d408d288292f62fbb8d650897acbc4.gif)](http://gyazo.com/42d408d288292f62fbb8d650897acbc4)\n\nAtom like draggable tab react component.\n\n## Demo\n\n[View Demo](http://georgeosddev.github.io/react-draggable-tab/example/)\n\n## Installation\n\n```bash\nnpm install --save react-draggable-tab\n```\nReact v0.14 is supported from react-draggable-tab v0.4.0.\nFor React v0.13.x, please use react-draggable-tab v0.3.3.\n\n## API\n\n### `Tab`\n\n`Tab` is just a case class to check props.\n`props.children` will rendered into content area.\n\n#### Props\n\n  * `key`: *unique* key in `TabList`.\n    `PropTypes.string.isRequired`\n\n  * `beforeTitle`: element to show in tab. eg icon.\n    `PropTypes.element`\n\n  * `title`: string or element to show in tab.\n    `PropTypes.oneOfType([PropTypes.string, PropTypes.element]).isRequired`\n\n  * `afterTitle`: element to show in tab. eg: notification badge\n    `PropTypes.element`\n\n  * `uncloseable`: If `true`, closeButton will not be appeared in tab.\n    `PropTypes.bool` (Default `false`)\n\n###### Style (for each tab)\n\n  * `tabClassNames`: classNames which will be **added** to rendered elements.\n   * `tab`: base `li` element of tab (defult: `rdTab`)\n   * `tabBefore`: before element of `li` which emulate `:Before` selector (defult: `rdTabBefore`)\n   * `tabAfter`: after element of `li` which emulate `:After` selector (defult: `rdTabAfter`)\n   * `tabTitle`: `span` element of tab title (defult: `rdTabTitle`)\n   * `tabBeforeTitle`: `span` element of tab before title (defult: `tabBeforeTitle`)\n   * `tabAfterTitle`: `span` element of tab after title (defult: `tabAfterTitle`)\n   * `tabCloseIcon`: base `span` element of close icon (defult: `rdCloseIcon`)\n   * `tabActive`: selected tab's `li`, before, after (defult: `rdTabActive`)\n   * `tabHover`: selected tab's `li`, before, after (defult: `rdTabHover`)\n\n  * `tabStyles`: Inline styles which will be **overwritten** default and common-tabs inline styles.\n   * `tab`: base `li` element of tab\n   * `tabBefore`: before element of `li` which emulate `:Before` selector.\n   * `tabAfter`: after element of `li` which emulate `:After` selector.\n   * `tabTitle`: `span` element of tab title\n   * `tabActive`: selected tab's `li`\n   * `tabBeforeActive`: selected tab's `li` before\n   * `tabAfterActive`: selected tab's `li` after\n   * `tabTitleActive`: selected tab's title\n   * `tabOnHover`: hovered tab's `li`\n   * `tabBeforeOnHover`: hovered tab's `li` before\n   * `tabAfterOnHover`: hovered tab's `li` after\n   * `tabTitleOnHover`: hovered tab's title\n   * `tabCloseIcon`: base `span` element of close icon\n   * `tabCloseIconOnHover`: base `span` element of close icon when hover\n\n  * `containerStyle`: style object which will be apply to container of rendered tab.\n\n  * `hiddenContainerStyle`: style object which will be apply to container of hidden tab.\n\n\n##### Events\n\n  All other props like `onXX` handler set to `Tab` will be passed to rendered element except `onClick`\n  You can use any `onXX` for [Supported events](https://facebook.github.io/react/docs/events.html#supported-events) for tab element.\n\n### `Tabs`\n\n`Tabs` is container for tab. it will render tabBar and content of selected element.\n\n#### Props\n\n  * `tabs`: Array of `Tab` elements.\n    `PropTypes.arrayOf(PropTypes.element)`\n\n  * `selectedTab`: key for selectedTab.\n    `PropTypes.string` default to first tab.\n\n  * `disableDrag`: disables the ability to drag the tabs.\n    `React.PropTypes.bool` default is false.\n\n  * `tabAddButton`: element for add button.\n    `PropTypes.element`\n\n  * `keepSelectedTab`: Prevent tab select on drag/move behind tab.\n    `PropTypes.bool` default `false`.\n\n  * `unclosable`: Disable tab to close.\n    `PropTypes.bool` default `false`.\n\n  * `shouldTabClose(e, key)`: will be called before tab close event, return false if you want to stop tab close process, default `true`;\n\n###### Shortcut key binding\n  * `shortCutKeys`: Short cut key bindings as [Mousetrap](https://craig.is/killing/mice) style.\n   * `close`: key binding to close current tab (`onTabClose` will be called)\n   * `create`: key binding to create tab (`onTabAddButtonClick` will be called)\n   * `moveRight`: key binding to move right (`onTabSelect` will be called)\n   * `moveLeft`: key binding to move left (`onTabSelect` will be called)\n\n###### Style (All tabs will be apply these styles)\n\n  * `tabsClassNames`: classNames which will be **added** to rendered elements.\n   * `tabWrapper`: root wrapper `div` element (defult: `rdTabWrapper`)\n   * `tabBar`: base `ul` element of tab bar (defult: `rdTabBar`)\n   * `tabBarAfter`: after `span` element of tab bar which emulate `:After` selector (defult: `rdTabBarAfter`)\n   * `tab`: base `li` element of tab (defult: `rdTab`)\n   * `tabBefore`: before element of `li` which emulate `:Before` selector (defult: `rdTabBefore`)\n   * `tabAfter`: after element of `li` which emulate `:After` selector (defult: `rdTabAfter`)\n   * `tabTitle`: `span` element of tab title (defult: `rdTabTitle`)\n   * `tabBeforeTitle`: `span` element of tab before title (defult: `rdTabBeforeTitle`)\n   * `tabBeforeTitle`: `span` element of tab after title (defult: `rdTabAfterTitle`)\n   * `tabCloseIcon`: base `span` element of close icon (defult: `rdCloseIcon`)\n   * `tabActive`: selected tab's `li`, before, after (defult: `rdTabActive`)\n\n  * `tabsStyles`: Inline styles which will be **overwritten** default inline styles.\n   * `tabWrapper`: root wrapper `div` element\n   * `tabBar`: base `ul` element of tab bar\n   * `tabBarAfter`: after `span` element of tab bar which emulate `:After` selector\n   * `tab`: base `li` element of tab\n   * `tabBefore`: before element of `li` which emulate `:Before` selector.\n   * `tabAfter`: after element of `li` which emulate `:After` selector.\n   * `tabTitle`: `span` element of tab title\n   * `tabActive`: selected tab's `li`\n   * `tabBeforeActive`: selected tab's `li` before\n   * `tabAfterActive`: selected tab's `li` after\n   * `tabTitleActive`: selected tab's title\n   * `tabCloseIcon`: base `span` element of close icon\n   * `tabCloseIconOnHover`: base `span` element of close icon when hover\n\n##### Events\n\n  * `onTabSelect(e, key, currentTabs)`: Called when tab of key was selected.\n    `currentTabs` is array of tabs elements sorted with current order.\n\n  * `onTabClose(e, key, currentTabs)`: Called when tab of key was closed.\n    `currentTabs` is array of tabs elements sorted with current order.\n\n  * `onTabPositionChange(e, key, currentTabs)`: Called when tab of key was moved.\n    `currentTabs` is array of tabs elements sorted with current order.\n\n  * `onTabAddButtonClick(e, currentTabs)`: Called when `tab add button` was clicked.\n    `currentTabs` is array of tabs elements sorted with current order.\n    Basically you will concat `currentTabs` with new empty tab.\n\n    ```javascript\n    let newTabs = currentTabs.concat([newTab]);\n    ```\n\n  ~~* `onTabDoubleClick(e, key)`: Called when `title` was double clicked.~~ Removed from v0.5.0\n\n  ~~* `onTabMouseEnter(e, key)`: Called when mouse enter to `tab`.~~ Removed from v0.5.0\n\n  ~~* `onTabMouseLeave(e, key)`: Called when mouse leave from `tab`.~~ Removed from v0.5.0\n\n## Usage example\n\n```javascript\nclass App extends React.Component {\n  constructor(props) {\n    super(props);\n    let icon = (\u003cimage src='icon.png' style={{height:'13px'}}/\u003e);\n    let fonticon = (\u003cicon className='icon-html5'/\u003e);\n    let badge = (\u003cDynamicTabBadge /\u003e);\n\n    this.state = {\n      tabs:[\n        (\u003cTab key={'tab0'} title={'unclosable tab'} unclosable={true} \u003e\n          \u003cdiv\u003e\n            \u003ch1\u003eThis tab cannot close\u003c/h1\u003e\n          \u003c/div\u003e\n        \u003c/Tab\u003e),\n        (\u003cTab key={'tab1'} title={'1stTab'} beforeTitle={icon} \u003e\n          \u003cdiv\u003e\n            \u003ch1\u003eThis is tab1\u003c/h1\u003e\n          \u003c/div\u003e\n        \u003c/Tab\u003e),\n        (\u003cTab key={'tab2'} title={'2ndTab Too long Toooooooooooooooooo long'} beforeTitle={fonticon} \u003e\n          \u003cdiv\u003e\n            \u003cpre\u003eLorem ipsum dolor sit amet, consectetur adipisicing elit,\n            \u003c/pre\u003e\n          \u003c/div\u003e\n        \u003c/Tab\u003e),\n        (\u003cTab key={'tab3'} title={'Dynamic tab'} afterTitle={badge}\u003e\n          \u003cDynamicTabContent/\u003e\n        \u003c/Tab\u003e)\n      ],\n      badgeCount: 0\n    };\n  }\n\n  handleTabSelect(e, key, currentTabs) {\n    console.log('handleTabSelect key:', key);\n    this.setState({selectedTab: key, tabs: currentTabs});\n  }\n\n  handleTabClose(e, key, currentTabs) {\n    console.log('tabClosed key:', key);\n    this.setState({tabs: currentTabs});\n  }\n\n  handleTabPositionChange(e, key, currentTabs) {\n    console.log('tabPositionChanged key:', key);\n    this.setState({tabs: currentTabs});\n  }\n\n  handleTabAddButtonClick(e, currentTabs) {\n    // key must be unique\n    const key = 'newTab_' + Date.now();\n    let newTab = (\u003cTab key={key} title='untitled'\u003e\n                    \u003cdiv\u003e\n                      \u003ch1\u003eNew Empty Tab\u003c/h1\u003e\n                    \u003c/div\u003e\n                  \u003c/Tab\u003e);\n    let newTabs = currentTabs.concat([newTab]);\n\n    this.setState({\n      tabs: newTabs,\n      selectedTab: key\n    });\n  }\n\n  render() {\n\n    return (\n      \u003cTabs\n        tabsClassNames={tabsClassNames}\n        tabsStyles={tabsStyles}\n        selectedTab={this.state.selectedTab ? this.state.selectedTab : \"tab2\"}\n        onTabSelect={this.handleTabSelect.bind(this)}\n        onTabClose={this.handleTabClose.bind(this)}\n        onTabAddButtonClick={this.handleTabAddButtonClick.bind(this)}\n        onTabPositionChange={this.handleTabPositionChange.bind(this)}\n        tabs={this.state.tabs}\n        shortCutKeys={\n          {\n            'close': ['alt+command+w', 'alt+ctrl+w'],\n            'create': ['alt+command+t', 'alt+ctrl+t'],\n            'moveRight': ['alt+command+tab', 'alt+ctrl+tab'],\n            'moveLeft': ['shift+alt+command+tab', 'shift+alt+ctrl+tab']\n          }\n        }\n      /\u003e\n    )\n  }\n};\n```\n\nSee also [example](https://github.com/georgeOsdDev/react-draggable-tab/tree/develop/example)\n\n\n```bash\nnpm install\nnpm run start:example\n```\n\n## Tests\n\n```bash\nnpm test\n```\n\n## Contributors\n\n See [list](https://github.com/georgeOsdDev/react-draggable-tab/graphs/contributors)\n\n## Known Issue\n\n* Dynamic tab content.\n\n`Tabs` do not care any change in `Tab` content.\ncontent needs update by your application side.\nSee `3rdTab` in example.\n\n\n* `flex` style should be define in CSS for safari.\nSee https://github.com/facebook/react/issues/2020\n\nIn application, class `rdTabBar` or your custom class of `TabBar` needs `display: -webkit-flex` in CSS like below.\n```css\n.myTabBar {\n  display: -webkit-flex;\n}\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorgeosddev%2Freact-draggable-tab","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fgeorgeosddev%2Freact-draggable-tab","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fgeorgeosddev%2Freact-draggable-tab/lists"}