Skip to content

mikechabot/react-tabify

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Build Status Dependency Status devDependencies Status

NPM

GitHub stars GitHub forks

react-tabify

A dead simple tab component for ReactJS.

Yarn or npm:

  • $ yarn add react-tabify
  • $ npm install --save react-tabify

import { Tab, Tabs } from 'react-tabify';

export default () => (
  <Tabs>
    <Tab label="Tab 1">First Content</Tab>
    <Tab label="Tab 2">Second Content</Tab>
    <Tab label="Tab 3">Third Content</Tab>
  </Tabs>
);

Edit 23x92qvy9n


react-tabify consists of two (2) components which need to be used together.

<Tabs />

Name Type Default Description
id string __tabify__ Id of the <Tabs /> component
defaultActiveKey string / number 0                 eventKey of the initial <Tab /> to render
activeKey string / number eventKey of the current <Tab />
theme object Optional color theme
stacked bool false Whether to display <Tabs /> vertically
sticky bool false Enable sticky tabs
onSelect func Callback fired when a <Tab /> is selected
style object style forwarded to the <Tab /> containing <div />
children node <Tab /> components

<Tab />

Name Type Default Description
eventKey string / number index Unique key of the <Tab />
label string / node Label of the <Tab/>
hide bool false Whether to hide the <Tab/>
style object style forwarded to the <Tab /> containing <div />
children node Any abritary React node

Uncontrolled Mode

By default, <Tabs /> are uncontrolled, and will display the first <Tab /> child during initial render. Use defaultActiveKey to default to another <Tab /> instead.

If <Tab /> components are not passed an eventKey, they will default to their order index. In the example below, we're defaulting <Tabs /> to display "Tab 3" since it sits at the second index (defaultActiveKey={2}).

export default () => (
  <Tabs defaultActiveKey={2}>
    <Tab label="Tab 1">First Content</Tab>
    <Tab label="Tab 2">Second Content</Tab>
    <Tab label="Tab 3">Third Content</Tab>
  </Tabs>
);

Edit k9zlwno4zv


Controlled Mode

Alternatively, to control the component, pass an activeKey, however you must pass an onSelect callback to handle the event. onSelect passes the eventKey of the selected <Tab />.

Again, if your <Tab /> components are not passed an eventKey, they will default to their order index.

import { Tab, Tabs } from 'react-tabify';

class App extends React.Component {
  constructor(props) {
    super(props);
    this.state = {
      activeKey: 0
    };
  }

  handleTabSelect = activeKey => {
    this.setState({ activeKey });
  };

  render() {
    return (
      <Tabs activeKey={this.state.activeKey} onSelect={this.handleTabSelect}>
        <Tab label="Tab 1">First Content</Tab>
        <Tab label="Tab 2">Second Content</Tab>
        <Tab label="Tab 3">Third Content</Tab>
      </Tabs>
    );
  }
}

Edit 30zw8qz25p


Add the stacked prop to render the tabs vertically.

export default () => (
  <Tabs stacked>
    <Tab label="Tab 1">First Content</Tab>
    <Tab label="Tab 2">Second Content</Tab>
    <Tab label="Tab 3">Third Content</Tab>
  </Tabs>
);

Edit p5y4mpxowq


If <Tabs /> is uncontrolled, pass sticky to "remember" the last active <Tab /> between page refreshes. When sticky is enabled, you must pass you own id to <Tabs />. This will be used within LocalStorage to distinguish between multiple <Tabs /> instances.

LocalStorage must be enabled in the browser.

export default () => (
  <Tabs sticky>
    <Tab label="Tab 1">First Content</Tab>
    <Tab label="Tab 2">Second Content</Tab>
    <Tab label="Tab 3">Third Content</Tab>
  </Tabs>
);

Edit ovqynq18k9


Easily nest tabs to create a section/subsection layout.

export default () => (
  <Tabs stacked>
    <Tab label="Tab 1">
      <Tabs>
        <Tab label="Subtab 1.1">Tab 1 Content 1</Tab>
        <Tab label="Subtab 1.2">Tab 1 Content 2</Tab>
        <Tab label="Subtab 1.3">Tab 1 Content 3</Tab>
      </Tabs>
    </Tab>
    <Tab label="Tab 2">
      <Tabs>
        <Tab label="Subtab 2.1">Tab 2 Content 1</Tab>
        <Tab label="Subtab 2.2">Tab 2 Content 2</Tab>
        <Tab label="Subtab 2.3">Tab 2 Content 3</Tab>
      </Tabs>
      </Tab>
    <Tab label="Tab 3">
      <Tabs>
        <Tab label="Subtab 3.1">Tab 3 Content 1</Tab>
        <Tab label="Subtab 3.2">Tab 3 Content 2</Tab>
        <Tab label="Subtab 3.3">Tab 3 Content 3</Tab>
      </Tabs>
    </Tab>
  </Tabs>
);

Edit 2pvlwjzp60


To ensure that scrolling (i.e. overflow) is only visible within the <Tab /> component, we'll want to wrap <Tabs /> with a Flexbox whose height is set to 100%. Otherwise, if our <Tab /> had enough content to induce a scrollbar, our entire <Tabs /> component would be subject to scrolling, which means the clickable tab links (horizontal and stacked) could scroll out of view.

const tabsContainer = {
  display: "flex",
  height: "100%"
};

const App = () => (
  <div style={tabsContainer}>
    <Tabs stacked>
      <Tab label="Tab 1" style={tabStyle}>
       {__getLorumIpsum()}
      </Tab>
      <Tab label="Tab 2" style={tabStyle}>
       {__getLorumIpsum()}
      </Tab>
      <Tab label="Tab 3" style={tabStyle}>
        {__getLorumIpsum()}
      </Tab>
    </Tabs>
  </div>
);

Edit w2wzlnqyw


Use the hide prop to dynmically hide/show <Tab /> components. Pass a bool, or evaluate a function that returns a bool.

// Dummy rejection
const __hasAccess = user => false;

const App = ({ user }) => (
  <div style={styles}>
    <Tabs>
      <Tab label="Super Admin Tab" hide>
        Super Admin Content
      </Tab>
      <Tab label="Admin Tab" hide={() => !__hasAccess(user)}>
        Admin Content
      </Tab>
      <Tab label="User Tab">User Content</Tab>
    </Tabs>
  </div>
);

Edit 1y19m2q7mj


react-tabify leverages <ThemeManager /> from glamorous to expose an optional theme object. The tabs property of the theme controls the horizontal styling, while menu controls the stacked view.

Accepts any valid color (e.g. "red", "#FF0000", "hsl(0, 100%, 50%)", "rgb(255, 0, 0)", etc).

Theme object
const theme = {
  tabs: {
    color: <color>,
    borderBottomColor: <color>,
    active: {
      borderBottomColor: <color>,
      color: <color>
    },
    hover: {
      borderBottomColor: <color>,
      color: <color>
    }
  },
  menu: {
    color: <color>,
    borderRight: <color>,
    active: {
        backgroundColor: <color>,
        color: <color>
    },
    hover: {
        color: <color>,
        backgroundColor: <color>
    }
  }
};

Override any of the properties above. Here's a simple example:

const theme = {
  tabs: {
    color: "red",
    active: {
      color: "green"
    }
  }
}

const App = () => (
  <Tabs theme={theme}>
    <Tab label="Tab 1">First Content</Tab>
    <Tab label="Tab 2">Second Content</Tab>
    <Tab label="Tab 3">Third Content</Tab>
  </Tabs>
);

Edit jjw53xqn69


A more complex, yet very ugly example theme:

const theme = {
  tabs: {
    color: "#FF000",
    active: {
      color: "green"
    }
  },
  menu: {
    color: "hsl(248, 39%, 39%)",
    borderRight: "darkmagenta",
    active: {
      backgroundColor: "rgb(165,42,42)"
    },
    hover: {
      color: "hsl(240, 100%, 50%)"
    }
  }
};

const App = () => (
  <Tabs stacked theme={theme}>
    <Tab label="Tab 1">
      <Tabs theme={theme}>
        <Tab label="Subtab 1.1">Tab 1 Content 1</Tab>
        <Tab label="Subtab 1.2">Tab 1 Content 2</Tab>
        <Tab label="Subtab 1.3">Tab 1 Content 3</Tab>
      </Tabs>
    </Tab>
    <Tab label="Tab 2">
      <Tabs theme={theme}>
        <Tab label="Subtab 2.1">Tab 2 Content 1</Tab>
        <Tab label="Subtab 2.2">Tab 2 Content 2</Tab>
        <Tab label="Subtab 2.3">Tab 2 Content 3</Tab>
      </Tabs>
    </Tab>
    <Tab label="Tab 3">
      <Tabs theme={theme}>
        <Tab label="Subtab 3.1">Tab 3 Content 1</Tab>
        <Tab label="Subtab 3.2">Tab 3 Content 2</Tab>
        <Tab label="Subtab 3.3">Tab 3 Content 3</Tab>
      </Tabs>
    </Tab>
  </Tabs>
);

Edit nkk5550ox4

Releases

No releases published

Packages

No packages published