|
1 |
| -# react-tabs [](https://travis-ci.org/reactjs/react-tabs) [](https://badge.fury.io/js/react-tabs) |
| 1 | +# react-tabs [](https://travis-ci.org/reactjs/react-tabs) [](https://www.npmjs.com/package/react-tabs) |
2 | 2 |
|
3 |
| -React tabs component |
| 3 | +Accessible react tab component |
4 | 4 |
|
5 |
| -> Supports React ^0.14.0 or ^15.0.0 |
| 5 | +> Supports React 0.14 and 15 |
6 | 6 |
|
7 | 7 | ## Installing
|
8 | 8 |
|
9 | 9 | ```bash
|
10 |
| -$ npm install react-tabs --save |
| 10 | +$ yarn add react-tabs |
| 11 | +``` |
| 12 | + |
| 13 | +You can also still use npm |
| 14 | + |
| 15 | +```bash |
| 16 | +npm install react-tabs --save |
| 17 | +``` |
| 18 | + |
| 19 | +Or use directly in your html as UMD component |
| 20 | + |
| 21 | +```html |
| 22 | +< script src= "https://unpkg.com/[email protected]/dist/react-tabs.min.js" /> |
11 | 23 | ```
|
12 | 24 |
|
13 | 25 | ## Demo
|
14 | 26 |
|
15 | 27 | https://reactcommunity.org/react-tabs/example/
|
16 | 28 |
|
17 |
| -## Example |
| 29 | +(TODO: This demos are outdated and use super old versions of react and react-tabs) |
| 30 | +
|
| 31 | +## Usage |
| 32 | +
|
| 33 | +### Basic Example |
18 | 34 |
|
19 | 35 | ```js
|
20 |
| -import React, { Component } from 'react'; |
21 |
| -import { render } from 'react-dom'; |
22 | 36 | import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
|
23 | 37 |
|
24 |
| -class App extends Component { |
25 |
| - handleSelect(index, last) { |
26 |
| - console.log('Selected tab: ' + index + ', Last tab: ' + last); |
27 |
| - } |
| 38 | +export default () => ( |
| 39 | + <Tabs> |
| 40 | + <TabList> |
| 41 | + <Tab>Title 1</Tab> |
| 42 | + <Tab>Title 2</Tab> |
| 43 | + </TabList> |
28 | 44 |
|
29 |
| - render() { |
30 |
| - return ( |
31 |
| - {/* |
32 |
| - <Tabs/> is a composite component and acts as the main container. |
| 45 | + <TabPanel> |
| 46 | + <h2>Any content 1</h2> |
| 47 | + </TabPanel> |
| 48 | + <TabPanel> |
| 49 | + <h2>Any content 2</h2> |
| 50 | + </TabPanel> |
| 51 | + </Tabs> |
| 52 | +); |
| 53 | +``` |
33 | 54 |
|
34 |
| - `onSelect` is called whenever a tab is selected. The handler for |
35 |
| - this function will be passed the current index as well as the last index. |
| 55 | +### Components |
36 | 56 |
|
37 |
| - `selectedIndex` is the tab to select when first rendered. By default |
38 |
| - the first (index 0) tab will be selected. |
| 57 | +react-tabs consists of 4 components which all need to be used together. |
39 | 58 |
|
40 |
| - `forceRenderTabPanel` By default this react-tabs will only render the selected |
41 |
| - tab's contents. Setting `forceRenderTabPanel` to `true` allows you to override the |
42 |
| - default behavior, which may be useful in some circumstances (such as animating between tabs). |
| 59 | +### <Tabs /> |
43 | 60 |
|
44 |
| - */} |
| 61 | +If you specify additional props on the `<Tabs />` component they will be forwarded to the rendered `<div />`. |
45 | 62 |
|
46 |
| - <Tabs |
47 |
| - onSelect={this.handleSelect} |
48 |
| - selectedIndex={2} |
49 |
| - > |
| 63 | +#### className: `string | Array<string> | { [string]: boolean }` |
50 | 64 |
|
51 |
| - {/* |
52 |
| - <TabList/> is a composite component and is the container for the <Tab/>s. |
53 |
| - */} |
| 65 | +> default: `"PropTypes"` |
54 | 66 |
|
55 |
| - <TabList> |
| 67 | +Provide a custom class name for the outer `<div />` of the tabs. |
56 | 68 |
|
57 |
| - {/* |
58 |
| - <Tab/> is the actual tab component that users will interact with. |
| 69 | +> You can also supply an array of class names or an object where the class names are the key and the value is a boolean indicating if the name should be added. See the docs of [classnames](https://github.com/JedWatson/classnames#usage) on how to supply different class names. |
59 | 70 |
|
60 |
| - Selecting a tab can be done by either clicking with the mouse, |
61 |
| - or by using the keyboard tab to give focus then navigating with |
62 |
| - the arrow keys (right/down to select tab to the right of selected, |
63 |
| - left/up to select tab to the left of selected). |
| 71 | +#### defaultFocus: `boolean` |
64 | 72 |
|
65 |
| - The content of the <Tab/> (this.props.children) will be shown as the label. |
66 |
| - */} |
| 73 | +> default: `false` |
67 | 74 |
|
68 |
| - <Tab>Foo</Tab> |
69 |
| - <Tab>Bar</Tab> |
70 |
| - <Tab>Baz</Tab> |
71 |
| - </TabList> |
| 75 | +If set to `true` the tabs will be focused on initial render. This allows immediate use of keyboard keys to switch tabs after the first render. |
| 76 | +
|
| 77 | +#### defaultIndex: `number` |
| 78 | +
|
| 79 | +> default: `0` |
| 80 | +
|
| 81 | +This allows changing the tab that should be open on initial render. This is a zero-based index, so first tab is `0`, second tab is `1`, ... |
| 82 | +
|
| 83 | +> This can only be used in uncontrolled mode when react-tabs handles the current selected tab internally and for this reason cannot be used together with `selectedIndex`. See [here](#controlled-vs-uncontrolled-mode) for more info on modes. |
| 84 | +
|
| 85 | +#### disabledTabClassName: `string` |
| 86 | +
|
| 87 | +> default: `"ReactTabs__Tab--disabled"` |
| 88 | +
|
| 89 | +Provide a custom class name for disabled tabs. |
| 90 | +
|
| 91 | +> This option can also be set directly at the `<Tab />` component. |
| 92 | +
|
| 93 | +#### forceRenderTabPanel: `boolean` |
| 94 | +
|
| 95 | +> default: `false` |
| 96 | +
|
| 97 | +By default only the current active tab will be rendered to DOM. If set to `true` all tabs will be rendered to the DOM always. |
| 98 | +
|
| 99 | +> This can also be enabled for each individual `<TabPanel />` component with its prop `forceRender`. |
| 100 | +
|
| 101 | +#### onSelect: `(index: number, lastIndex: number, event: Event) => ?boolean` |
| 102 | +
|
| 103 | +> default: `undefined` |
| 104 | +
|
| 105 | +This event handler is called every time a tab is changed. It will be called with the `index` that will be changed to, the `lastIndex` which was selected before and the underlying `event` which is usually either a `keydown` or `click` event. |
| 106 | +
|
| 107 | +The callback can optionally return `true` to cancel the change to the new tab. |
| 108 | +
|
| 109 | +> Returning `true` when the change to the new tab should be canceled is also important in controlled mode, as react-tabs still internally handles the focus of the tabs. (Really? maybe find a better way) |
| 110 | +
|
| 111 | +> In controlled mode ths `onSelect` handler is required prop. |
| 112 | +
|
| 113 | +#### selectedIndex: `number` |
| 114 | +
|
| 115 | +> default: `null` |
| 116 | +
|
| 117 | +Set the currently selected tab. This is a zero-based index, so first tab is `0`, second tab is `1`, ... |
| 118 | +
|
| 119 | +This enables controlled mode, which also requires `onSelect` to be set. See [here](#controlled-vs-uncontrolled-mode) for more info on modes. |
| 120 | +
|
| 121 | +#### selectedTabClassName: `string` |
| 122 | +
|
| 123 | +> default: `"ReactTabs__Tab--selected"` |
| 124 | +
|
| 125 | +Provide a custom class name for the active tab. |
| 126 | +
|
| 127 | +> This option can also be set directly at the `<Tab />` component. |
| 128 | +
|
| 129 | +#### selectedTabPanelClassName: `string` |
| 130 | +
|
| 131 | +> default: `"ReactTabs__TabPanel--selected"` |
| 132 | +
|
| 133 | +Provide a custom class name for the active tab panel. |
| 134 | +
|
| 135 | +> This option can also be set directly at the `<TabPanel />` component. |
| 136 | +
|
| 137 | +### <TabList /> |
| 138 | +
|
| 139 | +If you specify additional props on the `<TabList />` component they will be forwarded to the rendered `<ul />`. |
| 140 | +
|
| 141 | +#### className: `string | Array<string> | { [string]: boolean }` |
| 142 | +
|
| 143 | +> default: `"PropTypes__TabList"` |
| 144 | +
|
| 145 | +Provide a custom class name for the `<ul />`. |
| 146 | +
|
| 147 | +> You can also supply an array of class names or an object where the class names are the key and the value is a boolean indicating if the name should be added. See the docs of [classnames](https://github.com/JedWatson/classnames#usage) on how to supply different class names. |
| 148 | +
|
| 149 | +### <Tab /> |
| 150 | +
|
| 151 | +If you specify additional props on the `<Tab />` component they will be forwarded to the rendered `<li />`. |
| 152 | +
|
| 153 | +#### disabledClassName: `string` |
72 | 154 |
|
73 |
| - {/* |
74 |
| - <TabPanel/> is the content for the tab. |
75 |
| -
|
76 |
| - There should be an equal number of <Tab/> and <TabPanel/> components. |
77 |
| - <Tab/> and <TabPanel/> components are tied together by the order in |
78 |
| - which they appear. The first (index 0) <Tab/> will be associated with |
79 |
| - the <TabPanel/> of the same index. When you run this example with |
80 |
| - `selectedIndex` equal to 0, the tab with the label "Foo" will be selected |
81 |
| - and the content shown will be "Hello from Foo". |
82 |
| -
|
83 |
| - As with <Tab/> the content of <TabPanel/> will be shown as the content. |
84 |
| - */} |
85 |
| - |
86 |
| - <TabPanel> |
87 |
| - <h2>Hello from Foo</h2> |
88 |
| - </TabPanel> |
89 |
| - <TabPanel> |
90 |
| - <h2>Hello from Bar</h2> |
91 |
| - </TabPanel> |
92 |
| - <TabPanel> |
93 |
| - <h2>Hello from Baz</h2> |
94 |
| - </TabPanel> |
| 155 | +> default: `"ReactTabs__Tab--disabled"` |
| 156 | +
|
| 157 | +Provide a custom class name for disabled tabs. |
| 158 | +
|
| 159 | +#### className: `string | Array<string> | { [string]: boolean }` |
| 160 | +
|
| 161 | +> default: `"PropTypes__Tab"` |
| 162 | +
|
| 163 | +Provide a custom class name for the `<li />`. |
| 164 | +
|
| 165 | +> You can also supply an array of class names or an object where the class names are the key and the value is a boolean indicating if the name should be added. See the docs of [classnames](https://github.com/JedWatson/classnames#usage) on how to supply different class names. |
| 166 | +
|
| 167 | +#### selectedClassName: `string` |
| 168 | +
|
| 169 | +> default: `"ReactTabs__Tab--selected"` |
| 170 | +
|
| 171 | +Provide a custom class name for the active tab. |
| 172 | +
|
| 173 | +### <TabPanel /> |
| 174 | +
|
| 175 | +If you specify additional props on the `<TabPanel />` component they will be forwarded to the rendered `<dev />`. |
| 176 | +
|
| 177 | +#### className: `string | Array<string> | { [string]: boolean }` |
| 178 | +
|
| 179 | +> default: `"PropTypes__TabPanel"` |
| 180 | +
|
| 181 | +Provide a custom class name for the `<div />` containing the tab content. |
| 182 | +
|
| 183 | +> You can also supply an array of class names or an object where the class names are the key and the value is a boolean indicating if the name should be added. See the docs of [classnames](https://github.com/JedWatson/classnames#usage) on how to supply different class names. |
| 184 | +
|
| 185 | +#### forceRender: `boolean` |
| 186 | +
|
| 187 | +> default: `false` |
| 188 | +
|
| 189 | +By default the tab content will only be rendered when the tab is active. If set to `true` the tab will also be rendered if inactive. |
| 190 | +
|
| 191 | +> This can also be enabled for all `<TabPanel />` components with the prop `forceRenderTabPanel` on `<Tabs />`. |
| 192 | +
|
| 193 | +#### selectedClassName: `string` |
| 194 | +
|
| 195 | +> default: `"ReactTabs__TabPanel--selected"` |
| 196 | +
|
| 197 | +Provide a custom class name for the active tab panel. |
| 198 | +
|
| 199 | +## Controlled vs Uncontrolled mode |
| 200 | +
|
| 201 | +React tabs has two different modes it can operate in, which change the way how much you need to take care about the state yourself. |
| 202 | +
|
| 203 | +### Uncontrolled mode |
| 204 | +
|
| 205 | +This is the default mode of react-tabs and makes the react-tabs components handle its state internally. You can change the starting tab with `defaultIndex` and you can listen for changes with `onSelect`. |
| 206 | +
|
| 207 | +In this mode you cannot force a tab change during runtime. |
| 208 | +
|
| 209 | +```js |
| 210 | +<Tabs defaultIndex={1} onSelect={index => console.log(index)}> |
| 211 | + <TabList> |
| 212 | + <Tab>Title 1</Tab> |
| 213 | + <Tab>Title 2</Tab> |
| 214 | + </TabList> |
| 215 | + <TabPanel></TabPanel> |
| 216 | + <TabPanel></TabPanel> |
| 217 | +</Tabs> |
| 218 | +``` |
| 219 | +
|
| 220 | +### Controlled mode |
| 221 | +
|
| 222 | +This mode has to be enabled by supplying `selectedIndex` to the `<Tabs />` component. |
| 223 | +
|
| 224 | +In this mode react-tabs does not handle any tab selection state internally and leaves all the state management up to the outer application. |
| 225 | +
|
| 226 | +This mode als enforces you to set a handler for `onSelect`. `defaultIndex` does not have any effect. |
| 227 | +
|
| 228 | +```js |
| 229 | +class App extends Component { |
| 230 | + constructor() { |
| 231 | + this.state = { tabIndex: 0 }; |
| 232 | + } |
| 233 | + render() { |
| 234 | + return ( |
| 235 | + <Tabs selectedIndex={this.state.tabIndex} onSelect={tabIndex => this.setState({ tabIndex })}> |
| 236 | + <TabList> |
| 237 | + <Tab>Title 1</Tab> |
| 238 | + <Tab>Title 2</Tab> |
| 239 | + </TabList> |
| 240 | + <TabPanel></TabPanel> |
| 241 | + <TabPanel></TabPanel> |
95 | 242 | </Tabs>
|
96 | 243 | );
|
97 | 244 | }
|
98 | 245 | }
|
99 |
| - |
100 |
| -render(<App/>, document.getElementById('container')); |
101 | 246 | ```
|
102 | 247 |
|
103 | 248 | ## Styling
|
104 | 249 |
|
105 |
| -You can disable the default styling by calling this method once: |
| 250 | +react-tabs does not include any style loading by default. Default stylesheets are provided and can be included in your application if desired. |
| 251 | +
|
| 252 | +### Webpack |
106 | 253 |
|
| 254 | +When using webpack and a appropriate loader (`css-loader`, `sass-loader`, `less-loader` or `style-loader`) you can simply import the default stylesheet. |
| 255 | +
|
| 256 | +```js |
| 257 | +import 'react-tabs/style/react-tabs.css'; |
| 258 | +// or |
| 259 | +import 'react-tabs/style/react-tabs.scss'; |
| 260 | +// or |
| 261 | +import 'react-tabs/style/react-tabs.less'; |
107 | 262 | ```
|
108 |
| -Tabs.setUseDefaultStyles(false); |
| 263 | +
|
| 264 | +### SASS |
| 265 | +
|
| 266 | +When using SASS you can easily import the default styles |
| 267 | +
|
| 268 | +```scss |
| 269 | +@import '../../path/to/node_modules/react-tabs/style/react-tabs.scss'; |
109 | 270 | ```
|
110 | 271 |
|
| 272 | +### LESS |
| 273 | +
|
| 274 | +When using LESS you can easily import the default styles |
| 275 | +
|
| 276 | +```scss |
| 277 | +@import '../../path/to/node_modules/react-tabs/style/react-tabs.less'; |
| 278 | +``` |
| 279 | +
|
| 280 | +### Custom |
| 281 | +
|
| 282 | +You can also always just simply copy the default style to your own css/scss/less and modify it to your own needs. The changelog will always tell you when classes change and we also consider changes that break the styling as semver major. |
| 283 | +
|
111 | 284 | ## License
|
112 | 285 |
|
113 | 286 | MIT
|
0 commit comments