Coder Social home page Coder Social logo

react-tabs's Introduction

react-tabs npm version codecov

An accessible and easy tab component for ReactJS.

https://reactcommunity.org/react-tabs/

Version 5 or newer of react-tabs needs react version 18 or newer

Version 4 of react-tabs needs react version 16.8 or newer

react-tabs was tested on real mobile devices and browsers with
Browserstack

Installing

yarn add react-tabs

or

npm install --save react-tabs

Basic Example

import { Tab, Tabs, TabList, TabPanel } from 'react-tabs';
import 'react-tabs/style/react-tabs.css';

export default () => (
  <Tabs>
    <TabList>
      <Tab>Title 1</Tab>
      <Tab>Title 2</Tab>
    </TabList>

    <TabPanel>
      <h2>Any content 1</h2>
    </TabPanel>
    <TabPanel>
      <h2>Any content 2</h2>
    </TabPanel>
  </Tabs>
);

API

Components

react-tabs consists of 4 components which all need to be used together.

<Tabs />

If you specify additional props on the <Tabs /> component they will be forwarded to the rendered <div />.

className: string | Array<string> | { [string]: boolean }

default: "react-tabs"

Provide a custom class name for the outer <div /> of the tabs.

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 on how to supply different class names.

defaultFocus: boolean

default: false

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.

defaultIndex: number

default: 0

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, ...

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 for more info on modes.

direction: string

default: "ltr"

Provide the direction of the component, can be either rtl or ltr.

disabledTabClassName: string

default: "react-tabs__tab--disabled"

Provide a custom class name for disabled tabs.

This option can also be set directly at the <Tab /> component.

disableUpDownKeys: bool

default: false

Disable up & down arrow keys to change tabs.

domRef: (node: ?HTMLElement) => void

default: null

Register a callback that will receive the underlying DOM node for every mount. It will also receive null on unmount.

environment: Window

If you're rendering react-tabs within a different window context than the default one; for example, an iframe.

focusTabOnClick: boolean

default: true

By default the tab that is clicked will also be focused in the DOM. If set to false the tab will not be focused anymore.

Be aware that keyboard navigation will not work after click if set to false. Though one can still focus the tabs by pressing tab and then keyboard navigation will work.

forceRenderTabPanel: boolean

default: false

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.

This can also be enabled for each individual <TabPanel /> component with its prop forceRender.

onSelect: (index: number, lastIndex: number, event: Event) => ?boolean

default: undefined

This event handler is called every time a tab is about to change. It will be called with the index that it will be changed to, the lastIndex which was selected before and the underlying event which is usually either a keydown or click event. When index and lastIndex are equal it means the user clicked on the currently active tab.

The callback can optionally return false to cancel the change to the new tab.

Returning false 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.

In controlled mode the onSelect handler is a required prop.

selectedIndex: number

default: null

Set the currently selected tab. This is a zero-based index, so first tab is 0, second tab is 1, ...

This enables controlled mode, which also requires onSelect to be set. See here for more info on modes.

selectedTabClassName: string

default: "react-tabs__tab--selected"

Provide a custom class name for the active tab.

This option can also be set directly at the <Tab /> component.

selectedTabPanelClassName: string

default: "react-tabs__tab-panel--selected"

Provide a custom class name for the active tab panel.

This option can also be set directly at the <TabPanel /> component.

<TabList />

If you specify additional props on the <TabList /> component they will be forwarded to the rendered <ul />.

className: string | Array<string> | { [string]: boolean }

default: "react-tabs__tab-list"

Provide a custom class name for the <ul />.

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 on how to supply different class names.

<Tab />

If you specify additional props on the <Tab /> component they will be forwarded to the rendered <li />.

className: string | Array<string> | { [string]: boolean }

default: "react-tabs__tab"

Provide a custom class name for the <li />.

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 on how to supply different class names.

disabled: boolean

default: false

Disable this tab which will make it not do anything when clicked. Also a disabled class name will be added (see disabledClassName)

disabledClassName: string

default: "react-tabs__tab--disabled"

Provide a custom class name for disabled tabs.

This option can also be set for all <Tab /> components with the prop disabledTabClassName on <Tabs />.

selectedClassName: string

default: "react-tabs__tab--selected"

Provide a custom class name for the active tab.

This option can also be set for all <Tab /> components with the prop selectedTabClassName on <Tabs />.

tabIndex: string

default: if selected "0" otherwise null

Overrides the tabIndex to enabled tabbing between tabs.

<TabPanel />

If you specify additional props on the <TabPanel /> component they will be forwarded to the rendered <div />.

className: string | Array<string> | { [string]: boolean }

default: "react-tabs__tab-panel"

Provide a custom class name for the <div /> containing the tab content.

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 on how to supply different class names.

forceRender: boolean

default: false

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.

This can also be enabled for all <TabPanel /> components with the prop forceRenderTabPanel on <Tabs />.

selectedClassName: string

default: "react-tabs__tab-panel--selected"

Provide a custom class name for the active tab panel.

This option can also be set for all <TabPanel /> components with the prop selectedTabPanelClassName on <Tabs />.

Controlled vs Uncontrolled mode

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.

Uncontrolled mode

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.

In this mode you cannot force a tab change during runtime.

<Tabs defaultIndex={1} onSelect={(index) => console.log(index)}>
  <TabList>
    <Tab>Title 1</Tab>
    <Tab>Title 2</Tab>
  </TabList>
  <TabPanel></TabPanel>
  <TabPanel></TabPanel>
</Tabs>

Controlled mode

This mode has to be enabled by supplying selectedIndex to the <Tabs /> component.

In this mode react-tabs does not handle any tab selection state internally and leaves all the state management up to the outer application.

This mode also enforces you to set a handler for onSelect. defaultIndex does not have any effect and will therefore throw an error.

const App = () => {
  const [tabIndex, setTabIndex] = useState(0);

  return (
    <Tabs selectedIndex={tabIndex} onSelect={(index) => setTabIndex(index)}>
      <TabList>
        <Tab>Title 1</Tab>
        <Tab>Title 2</Tab>
      </TabList>
      <TabPanel></TabPanel>
      <TabPanel></TabPanel>
    </Tabs>
  );
};

Styling

react-tabs does not include any style loading by default. Default stylesheets are provided and can be included in your application if desired.

Webpack

When using webpack and an appropriate loader (css-loader, sass-loader, less-loader or style-loader) you can simply import the default stylesheet.

import 'react-tabs/style/react-tabs.css';
// or
import 'react-tabs/style/react-tabs.scss';
// or
import 'react-tabs/style/react-tabs.less';

SASS

When using SASS you can easily import the default styles

@import '../../path/to/node_modules/react-tabs/style/react-tabs.scss';

LESS

When using LESS you can easily import the default styles

@import '../../path/to/node_modules/react-tabs/style/react-tabs.less';

Custom Style

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.

Custom Components

Set tabsRole

In case you want to create your own component wrapping the ones that the library provides, you have to set its tabsRole. This value is used inside react-tabs to check the role of a component inside <Tabs />.

Possible values for tabsRole are:

  • Tab
  • TabPanel
  • TabList
  • Tabs

Pass through properties

Note: Because of how react-tabs works internally (it uses cloning to opaquely control various parts of the tab state), you need to pass any incoming props to the component you're wrapping. The easiest way to do this is to use the rest and spread operators, e.g. see {...otherProps} below.

import { Tabs, TabList, Tab, TabPanel } from 'react-tabs';
import type { ReactTabsFunctionComponent, TabProps } from 'react-tabs';

// All custom elements should pass through other props
const CustomTab: ReactTabsFunctionComponent<TabProps> = ({
  children,
  ...otherProps
}) => (
  <Tab {...otherProps}>
    <h1>{children}</h1>
  </Tab>
);

CustomTab.tabsRole = 'Tab'; // Required field to use your custom Tab

const App = () => (
  <Tabs>
    <TabList>
      <CustomTab>Custom Tab 1</CustomTab>
      <CustomTab>Custom Tab 2</CustomTab>
    </TabList>
    <TabPanel>Panel 1</TabPanel>
    <TabPanel>Panel 2</TabPanel>
  </Tabs>
);

License

MIT

react-tabs's People

Contributors

austinpray avatar codincat avatar csilivestru avatar danez avatar dependabot[bot] avatar dpkrolak avatar ebrentnelson avatar elecweb avatar emasuriano avatar emilpalsson avatar existentialism avatar georgette avatar hum4n01d avatar husnimun avatar iamdustan avatar imanmh avatar ioprea avatar joepvl avatar meirish avatar mzabriskie avatar newyork-anthonyng avatar patrick91 avatar rendez avatar renovate-bot avatar renovate[bot] avatar rosko avatar timdorr avatar tuxrace avatar voluntadpear avatar yandavid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

react-tabs's Issues

`setAttribute` error when using with Typekit in Safari

I found an extreme edge case bug but nevertheless it's something I believe could effect many users of this project.

It turns out Typekit's code snippet overrides Element.prototype.setAttribute as follows:

t.setAttribute = function(e, r, i, l) {
        r.match(s) && (i = new XMLHttpRequest,
        i.open("GET", r, !0),
        i.onreadystatechange = function() {
            4 === i.readyState && (l = i.responseText,
            l !== o && (n[a] = l))
        }
        ,
        i.send(null ),
        t.setAttribute = u,
        o) || u.apply(this, arguments)
    }

And in the Tab.js component we have this:

node.setAttribute('tabindex', 0);

Which is causing the following error, only in Safari:

TypeError: r.match is not a function. (In 'r.match(s)', 'r.match' is undefined)

This is happening because the "r" argument of Typekit's custom setAttribute is expected to be a string, however it's receiving an integer 0, which has no match function.

So the fix is just change the line above to:

node.setAttribute('tabindex', '0');

React is being included twice

Need to move React to peerDependencies. This solves the following error:

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's render method). Try rendering this component inside of a new top-level component which will hold the ref.

Reduce specificity of default styles

The BEM classes added to each component are super useful for applying custom styling. However, because the default styles have a high specificity (e.g. .react-tabs [role=tab][aria-selected=true]:hover), the purpose of adopting BEM is defeated slightly.

I propose using low specificity BEM classes for the default styles, so that they may be overridden more easily

TypeError: Cannot read property 'visitClass' of undefined at monkeypatch

I just forked the repository. However, when execute npm test , it failed.
The log out of npm-debu.log listed below.

0 info it worked if it ends with ok
1 verbose cli [ '/usr/local/bin/node', '/usr/local/bin/npm', 'run', 'test' ]
2 info using [email protected]
3 info using [email protected]
4 verbose run-script [ 'pretest', 'test', 'posttest' ]
5 info pretest [email protected]
6 info test [email protected]
7 verbose unsafe-perm in lifecycle true
8 info [email protected] Failed to exec test script
9 verbose stack Error: [email protected] test: `rackt test --single-run --browsers Firefox`
9 verbose stack Exit status 1
9 verbose stack     at EventEmitter.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/lifecycle.js:214:16)
9 verbose stack     at emitTwo (events.js:87:13)
9 verbose stack     at EventEmitter.emit (events.js:172:7)
9 verbose stack     at ChildProcess.<anonymous> (/usr/local/lib/node_modules/npm/lib/utils/spawn.js:24:14)
9 verbose stack     at emitTwo (events.js:87:13)
9 verbose stack     at ChildProcess.emit (events.js:172:7)
9 verbose stack     at maybeClose (internal/child_process.js:818:16)
9 verbose stack     at Process.ChildProcess._handle.onexit (internal/child_process.js:211:5)
10 verbose pkgid [email protected]
11 verbose cwd /Users/chiehlun/Project/react/react-tabs
12 error Darwin 15.3.0
13 error argv "/usr/local/bin/node" "/usr/local/bin/npm" "run" "test"
14 error node v4.2.2
15 error npm  v2.14.7
16 error code ELIFECYCLE
17 error [email protected] test: `rackt test --single-run --browsers Firefox`
17 error Exit status 1
18 error Failed at the [email protected] test script 'rackt test --single-run --browsers Firefox'.
18 error This is most likely a problem with the react-tabs package,
18 error not with npm itself.
18 error Tell the author that this fails on your system:
18 error     rackt test --single-run --browsers Firefox
18 error You can get their info via:
18 error     npm owner ls react-tabs
18 error There is likely additional logging output above.
19 verbose exit [ 1, true ]

Two copies of React are loaded due to peerDependencies

As react-tabs has react listed as peerDependencies, npm will install another copy of React that is compatible with the listed version.

If the application requires another incompatible version, it will cause two copies of React to be loaded. As React does not support loading multiple versions on the same page, the application will break.

I propose that the peerDependencies in package.json should be moved to devDependencies.

tab resets to first tab onclick event

Hi. I have an onclick event fire from one of my tabs, but on fire, it somehow reset the tab index to go back to the first tab. Say i have 2 tabs, and i'm on the second page of the tab 2, which has Griddle table, when i click on something in one of the griddle's table column ( i have an onclick on an item there ) it triggers the react tab to go back to the first tab vs staying put. I need it to stay put on tab 2 vs somehow route back to tab 1. Any ideas?

const LinkComponent = ({ data, rowData }) => {
  let result = <span></span>;
  if (data) {
    result = (
      <div>
        <span>{rowData.user}</span>&nbsp;
        <span onClick={this.props.onClickUserDetails.bind(this, rowData.user)}>
          <i className='fa fa-info-circle fa-lg'></i>
        </span>
      </div>
    );
  }
  return result;
};
const columnMeta = [
  {
    columnName: 'user',
    order: 1,
    locked: false,
    visible: true,
    customComponent: LinkComponent,
    displayName: 'User ID',
  },

Update version and push to npm.

There is no react dependency in package.json in the version that's pushed to npm.
This is apparently fixed in master so please push to npm.

Issue when paired w/ Turbolinks

Not necessarily react-tabs's fault, but here's a scenario I encountered:

  1. Page loads and my Tabs component renders. Works fine.
  2. I click a link on one of my panels.
  3. Turbolinks intercepts the click, caches the current page DOM and loads the new content.
  4. I hit the back button. Turbolinks restored my cached page.
  5. Tabs are in the exact state I left them in (yay!), but I can't tab to new panels. Eventually react throws an error.

I got around this by listening to Turbolink's page:change event and emptying out the component's container DIV every time, which means you lose state when you travel back to my first page, but at least it works.

I debugged it a bit and found that handleClick was firing, as was setSelected. State was getting updated but the component wasn't re-rendering as expected.

If you have any insight at all as to what might be going on here, that'd be awesome. But feel free to close this regardless :).

Error with `TestUtils.renderIntoDocument`

I think this happens because you are cloning elements outside of render?

Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs.
This usually means that you're trying to add a ref to a component that doesn't have an
owner (that is, was not created inside of another component's `render` method). Try 
rendering this component inside of a new top-level component which will hold the ref.

Using [email protected] and [email protected].

Warning with React 0.14.0

Warning: cloneWithProps(...) is deprecated. Please use React.cloneElement instead.
Warning: Tab.getDOMNode(...) is deprecated. Please use ReactDOM.findDOMNode(instance) instead.

ReferenceError: document is not defined when using on server

Hello! Thank you for good tabs :-)

I faced with problem when use component on server-side:

import React from 'react';
import ReactTabs from 'react-tabs';

const Tabs = ReactTabs.Tabs,
    TabList = ReactTabs.TabList,
    Tab = ReactTabs.Tab,
    TabPanel = ReactTabs.TabPanel;

export default React.createClass({
    render: function() {
        return (
            <Tabs>
                <TabList>
                    <Tab>One</Tab>
                    <Tab>Two</Tab>
                    <Tab>Three</Tab>
                </TabList>
                <TabPanel>
                    <h2>Hello from One</h2>
                </TabPanel>
                <TabPanel>
                    <h2>Hello from Two</h2>
                </TabPanel>
                <TabPanel>
                    <h2>Hello from Three</h2>
                </TabPanel>
            </Tabs>
        );
    }
});
ReferenceError: document is not defined
    at injectCSS (/Users/tenorok/projects/multf/node_modules/react-tabs/node_modules/js-stylesheet/jss.js:21:17)
    at jss (/Users/tenorok/projects/multf/node_modules/react-tabs/node_modules/js-stylesheet/jss.js:6:5)
    at componentWillMount (/Users/tenorok/projects/multf/node_modules/react-tabs/lib/components/Tabs.js:66:35)
    at ReactCompositeComponentMixin.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactCompositeComponent.js:228:14)
    at wrapper [as mountComponent] (/Users/tenorok/projects/multf/node_modules/react/lib/ReactPerf.js:70:21)
    at Object.ReactReconciler.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactReconciler.js:38:35)
    at ReactDOMComponent.ReactMultiChild.Mixin.mountChildren (/Users/tenorok/projects/multf/node_modules/react/lib/ReactMultiChild.js:192:44)
    at ReactDOMComponent.Mixin._createContentMarkup (/Users/tenorok/projects/multf/node_modules/react/lib/ReactDOMComponent.js:289:32)
    at ReactDOMComponent.Mixin.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactDOMComponent.js:199:12)
    at Object.ReactReconciler.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactReconciler.js:38:35)
    at ReactCompositeComponentMixin.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactCompositeComponent.js:247:34)
    at wrapper [as mountComponent] (/Users/tenorok/projects/multf/node_modules/react/lib/ReactPerf.js:70:21)
    at Object.ReactReconciler.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactReconciler.js:38:35)
    at ReactCompositeComponentMixin.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactCompositeComponent.js:247:34)
    at wrapper [as mountComponent] (/Users/tenorok/projects/multf/node_modules/react/lib/ReactPerf.js:70:21)
    at Object.ReactReconciler.mountComponent (/Users/tenorok/projects/multf/node_modules/react/lib/ReactReconciler.js:38:35) [ReferenceError: document is not defined]

I can't understand how fix this, can you help me please?

style tag support?

I'm using inline styles for my app. it'd be nice if I could continue to just add style attributes to style the Tabs, etc. I tried doing this but doesn't seem they're allowed.

Can't suppress click events when clicking on tabs.

The tabs I'm using are in a div which has an onClick event, which triggers whenever I click on a tab (since it's in the div). I want to suppress this, and have been using the code onClick={(evt) => this.suppressClick(evt)} to accomplish this elsewhere. However, it doesn't work (as in, it won't enter the suppressClick function at all) in the tab code, no matter where I put it; I've tried to put it as a property in the <TabList> and <Tab> tags to no avail. I know it works in <div>s so I put one around the <tab> tags but that disabled clicking on the tabs entirely. What's the recommended method to disable click event propagation for these tabs?

Server Side Rendering won't work with default styles

Server side rendering won't work. I get the same error as described in /issues/39.

Tabs.js:81 [object Object].componentWillMount
[app]/[react-tabs]/lib/components/Tabs.js:81:37

Are react-tabs supposed to work on the server side? If not, any plans on supporting them?

React 0.13 support?

Hey @mzabriskie,

Would you accept a PR that updated this to work with React 0.13? I see there are a few open PRs and don’t want to put in the effort if it will be left neglected. What are your requirements and constraints to accept 0.13 support?

Errors when testing with Jest

When testing a react-tabs component either with TestUtils.renderIntoDocument or TestUtils.createRenderer the component prints the warning:

Warning: Failed propType: There should be an equal number of `Tabs` and `TabPanels`. Received 3 `Tabs` and 0 `TabPanels`.

When running exactly the same code in the browser there is no error.

I'm using react-tabs 0.4.1 and react 0.13.3.

Tabs below content

I want to display the tab content above the tabs, eg:

      <Tabs>
        <TabPanel>
          This is content for tab 1
        </TabPanel>
        <TabPanel>
          This is content for tab 2
        </TabPanel>
        <TabPanel>
          This is content for tab 3
        </TabPanel>
        <TabList>
          <Tab>Tab 1</Tab>
          <Tab>Tab 2</Tab>
          <Tab>Tab 3</Tab>
        </TabList>
      </Tabs>

Unfortunately, this does not work. Clicking the tabs doesn't do anything.
Is this possible with react-tabs? If yes, how?

can't be used in webpack build environment

we would love to use this in our project. but we use webpack for our build, bundling process. As the component files are saved ending .js there is a configuration overhead (webback transforms just jsx files).

as we got multiple projects having to put special configurations to every project - so right now simplest solution would be to create a fork (renaming the files to abc.jsx or serve already transformed files in that fork.)

JedWatson/react-select#40 is an interesting discussion about the same topic.

do you consider to optimize this for webpack usage?!?

Custom tab panel ids

Hello. Can I assign my custom id to panel?
I need to have been panel ids: ['actions', 'news', 'something'].
Can I do this?

Bundling of React in /dist files

So I believe this is related to #23 and #15.

I can't figure out why all of React is bundled inside of dist/react-tabs.js and dist/react-tabs.min.js. As far as I can tell this makes it impossible to include react-tabs on a project that already has React as a dependency. Ideally we wouldn't be dependent on a single plugin to provide the version of React that everything in a project would use. This seems to be a particular problem when using bower. As far as this warning:

Uncaught Error: Invariant Violation: addComponentAsRefTo(...): Only a ReactOwner can have refs. This usually means that you're trying to add a ref to a component that doesn't have an owner (that is, was not created inside of another component's render method). Try rendering this component inside of a new top-level component which will hold the ref.

Am I missing something? Or would it be possible to include a /dist version of react-tabs that doesn't include React itself?

focus is lost when using react-tabs as a controlled component

i tried using react-tabs as a "controlled component", a la https://facebook.github.io/react/docs/forms.html#controlled-components

for react-tabs to behave as a proper controlled component, the behavior i would expect is as such:

if you pass <Tabs> a selectedIndex property, then it will ALWAYS be respected. i.e., the prop is not used merely to determine which tab to render initially, it's used to determine which tab to render all the time. so even if a user clicks a tab, that tab won't be selected unless the parent component reacts to the click by changing the selectedIndex. therefore, onSelect gets invoked when a Tab is clicked or keyboard-navigated to, which allows the developer to update selectedIndex appropriately.

a minimal example is as follows:

var MyComponent = React.createComponent({
  getInitialState () {
    return { currentTab: 0 };
  },
  handleTabSelect (index) {
    this.setState({ currentTab: index });
  },
  render () {
    return (
      <Tabs
        selectedIndex={ this.state.currentTab },
        onSelect={ this.handleTabSelect }
      >
        <TabList><Tab>One</Tab><Tab>Two</Tab></TabList>
        <TabPanel><p>Content of first tab</p></TabPanel>
        <TabPanel><p>Content of second tab</p></TabPanel>
      </Tabs>
    );
  }
});

If you try it, this minimal example actually mostly behaves as expected, but the problem I discovered is if you focus one of the tabs and then use the arrow key to navigate to the other, the other tab gets selected but your focus is immediately lost. If you remove both of those props from <Tabs>, then this issue goes away, but now MyComponent isn't keeping track of the selected tab in its state. (In our particular case, we want MyComponent to keep track of that index because we sometimes programmatically select a different tab based on other things going on in the component.)

Also, if you change the example such that handleTabSelect doesn't update this.state.currentTab, then react-tabs still changes its selected tab anyway -- i.e. it ignores its selectedIndex prop.

So, what do you think? Does controlled component behavior make sense for react-tabs? Is it perhaps something that's already on the roadmap?

Server side rendering checksum error

Hi there is a checksum error when using serverside rendering..
(client) tab" id="react-tabs-0" aria-selected="tr
(server) tab" id="react-tabs-4" aria-selected="tr

Any ideas what it could be?

bower support

is it possible to support bower and npm as package managers and not only npm??

Add tab dinamicaly

Hello! Thank you for the library! I have a question about dynamic addition of tabs. In pseudo code it's looks like this:

handleAddProfileClick() {
    this.refs.tabs.add(
     <UserProfileTab userId="123" />
    );
},
handleAddSettingsClick() {
    this.refs.tabs.add(
     <Settings  />
    );
}

It is also important that other tabs are not redrawn (kept its state).
How about tab closing?
Thanks a lot!

Why select first tab by default?

I mean, if the passed model has not an active tab, why should we open one by default?
Doesn't it leads to inconsistence with the data model and the view?

Thanks.

React v15

Any plans for react 15 support? I tried forking and getting started to upgrade but npm start has some other errors..

when set state on selected, tabs dont change

So, when i try to so this.setState({}) on select, the code in handleSelected will be executed but the tabs will stop changing.

  handleSelected(index, last) {
    console.log('Selected tab: ' + index + ', Last tab: ' + last);
    if (index == 1) {

      console.log(index);
      this.setState({paymentType: 'paypal'})
    }
    else {

      this.setState({paymentType: 'creditcard'})
    }
  }

how to add a class of the selected tab ?

I do it as this, but the first tab seems not clickable.

getInitialState() {
return {
      selectedIndex: 0
    };
},
handleSelect(index, last) {
    this.setState({
       selectedIndex: index
    });
}

tabs:

<Tabs
onSelect={this.handleSelect}
selectedIndex={0}
 >
  <TabList>
     <Tab>
      <div className={
cx({"bg-color-w": (this.state.selectedIndex == 0?true:false)
                            })}>涨幅榜
</div>
...

please give me a hint~~thanks very much. 😃

Can't use Tabs in another Tabs

<Tabs selectedIndex={1}>
              <TabList>
                <Tab>Disclosure Req.</Tab>
                <Tab>Page Instructions</Tab>
              </TabList>
              <TabPanel>
                <Instructions sectionName="DisclosuresRequirements" source="disclosures/instruction" />
              </TabPanel>
              <TabPanel>
                <Tabs selectedIndex={1}>
                  <TabList>
                    <Tab>Disclosure Req.</Tab>
                    <Tab>Page Instructions</Tab>
                 </TabList>
                  <TabPanel>
                    <Instructions sectionName="DisclosuresRequirements" source="disclosures/instruction" />
                  </TabPanel>
                  <TabPanel>
                    <Instructions sectionName="EffortSummary" source="effort/instruction" />
                  </TabPanel>
                </Tabs>
              </TabPanel>
            </Tabs>

When I click on inner second Tab it change parent second tab.
Who can help me with this problem?

Small issue: no children --> exception

Hi,
Very small issue here: when there are (presumably temporarily) no child elements for the tabs elements, then the page doesn't load due to the following code:

                // Setup tab/panel ids
        React.Children.forEach(this.props.children[0].props.children, function () {
            tabIds.push(uuid());
            panelIds.push(uuid());
        });
Uncaught TypeError: Cannot read property 'children' of undefined 

Migrate to rackt eslint config

https://github.com/rackt/eslint-config-rackt contains a starting point that all org repos can build off of. This can be introduced by first using the config and overriding any rules that the repo doesn't comply with, without having to change any of the source. Then for non-controversial rules, PRs can be made to update the source to comply.

Here's the initial PR: #47

React 15.x support release on npm

We're having some difficulty upgrading React in our application because the latest version of react-tabs limits us to 0.14.x

I can see a commit in master on package.json which bumps support - time for a new tagged release?

Cheers 😄

Error when conditionally generating Tabs and TabPanels

If you use a ternary condition to return a null instead of a Tab react-tabs you get a "Uncaught TypeError: Cannot read property 'ref' of null".

Example

<div>
  <Tabs>
    { shouldShowTabA ? <Tab>Tab A</Tab> : null }
    { shouldShowTabB ? <Tab>Tab B</Tab> : null }
  </Tabs>
  { shouldShowTabA ? <TabPanel>{contentForA}</TabPanel> : null }
  { shouldShowTabB ? <TabPanel>{contentForB}</TabPanel> : null }
</div>

The assumption here is of course that at least one of the tabs will be displayed. I am not sure what will happen if you don't define any Tab elements.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.