Polaris-react: Tabs Documentation

Created on 24 May 2017  路  9Comments  路  Source: Shopify/polaris-react

Can you please extend Tabs documentation? It's really confusing how it works and the example doesn't really help. Do Tabs run their own state or I have to implement it for the selected tab. How are children managed, how do I set the content for a tab? What do the properties of tabs mean? I understand Title but id and panelID?
Thanks

Most helpful comment

Hi @AdityaAnand1. Like @lemonmade said above, this isn't automatic, and the state needs to be managed from within your app. This is an example of a simple component that manages state for a set of tabs.

import React, { Component } from 'react';

import {Tabs} from '@shopify/polaris';

import '@shopify/polaris/styles.css';

class App extends Component {
  constructor(props) {
    super(props);

    this.handleTabChange = this.handleTabChange.bind(this);

    this.state = {
      selectedTab: 0,
    };
  }

  handleTabChange(selectedTab) {
    this.setState({selectedTab});
  }

  render() {
    const {selectedTab} = this.state;

    const tabs = [
      {
        id: 'tab1',
        title: 'something1',
        panelID: 'panel2',
      },
      {
        id: 'tab2',
        title: 'something2',
        panelID: 'panel2',
      },
    ];

    const tabPanels = [
      (
        <Tabs.Panel id="panel1">
          something
        </Tabs.Panel>
      ),
      (
        <Tabs.Panel id="panel2">
          something else
        </Tabs.Panel>
      ),
    ];

    return (
      <div>
        <Tabs
          selected={selectedTab}
          tabs={tabs}
          onSelect={this.handleTabChange}
        />
        {tabPanels[selectedTab]}
      </div>
    );
  }
}

export default App;

Hopefully this helps clarify how these can be used.

All 9 comments

Hi @nishikawa7863, I've added an issue to our internal tracker for improving the documentation here. Definitely agree that we have not documented this component particularly well. Here's some brief answers to your questions, though:

  1. Tabs do not manage their own state. You must provide the index of the selected tab as the selected prop, and we will tell you when the selected tab changes by giving you the new selected index as the only argument to the onSelect callback.

  2. You have two choices for children. The simpler way is to provide them as children of the Tabs component. If you go this way, you will need to decide what children to actually put in based on the selected tab (this is a little awkward but ends up being good for performance because you do not render a bunch of content for hidden tabs unnecessarily). The second way is to just use the selected tab state that you passed to tabs/ updated in onSelect, and then render something, somewhere on the page based on the selected tab. We often have to do this in cases where the tabs themselves are visually disconnected from the content then control.

  3. panelID is intended to connect a tab to a "panel" (container around the content that tab controls). This is useful for accessibility purposes as screen readers will associate the panel to the content. Essentially, you provide a panelID for the tab, and if you render the contents of that tab elsewhere on the page (that is, not as children of Tabs), you would wrap them in a Tabs.Panel component with an id that matches the panelID (though I just noted, we actually expose the panel as Tabs.panel 鈥斅爓ill add an issue to address this ASAP as well). This whole process happens automatically when you pass in the tab's contents as children of Tabs

I will update this issue when we ship fixes for these issues.

Any progress on this by any chance? I'm trying to implement the simpler option from your #2 but struggling a bit. Any chance you can provide an example of that?

Thanks for the clarification, @lemonmade. I feel like I have to struggle with every new component I try to add for 15 minutes because there's literally no examples of Polaris usage anywhere so I have to dig through the source code and hope I bump into a random blog or SO question or a github issue like this made by a confused person like me.

I, and I imagine other developers, would much rather prefer that the official documentation was more extensive, code-wise. To me, when I'm trying to create a UI, I don't care so much about the rationale or design principles which is what is included in the documentation, when I can't even figure out how to use the components yet :/

Right now I'm trying to figure out why the following doesn't seem to be working.

<Tabs
          selected={0}
          tabs={[
            {
              id: 'id1',
              title: 'something1',
              panelID: 'id1',
            },
            {
              id: 'id2',
              title: 'something2',
              panelID: 'id2',
            },
          ]}
        />
        <Tabs.Panel
        id: {"id1"}>
          something
        </Tabs.Panel> 
        <Tabs.Panel
        id: {"id2"}>
          something else
        </Tabs.Panel> 

Hi @AdityaAnand1. Like @lemonmade said above, this isn't automatic, and the state needs to be managed from within your app. This is an example of a simple component that manages state for a set of tabs.

import React, { Component } from 'react';

import {Tabs} from '@shopify/polaris';

import '@shopify/polaris/styles.css';

class App extends Component {
  constructor(props) {
    super(props);

    this.handleTabChange = this.handleTabChange.bind(this);

    this.state = {
      selectedTab: 0,
    };
  }

  handleTabChange(selectedTab) {
    this.setState({selectedTab});
  }

  render() {
    const {selectedTab} = this.state;

    const tabs = [
      {
        id: 'tab1',
        title: 'something1',
        panelID: 'panel2',
      },
      {
        id: 'tab2',
        title: 'something2',
        panelID: 'panel2',
      },
    ];

    const tabPanels = [
      (
        <Tabs.Panel id="panel1">
          something
        </Tabs.Panel>
      ),
      (
        <Tabs.Panel id="panel2">
          something else
        </Tabs.Panel>
      ),
    ];

    return (
      <div>
        <Tabs
          selected={selectedTab}
          tabs={tabs}
          onSelect={this.handleTabChange}
        />
        {tabPanels[selectedTab]}
      </div>
    );
  }
}

export default App;

Hopefully this helps clarify how these can be used.

Hi @dfmcphee ,

I have noticed a warning on my console saying: _The title property on Tabs has been deprecated. Use content instead._

But in the examples in this page every tab has an id, title and panelID. Can you please update the examples?

Thanks a lot.

Thanks for catching that @NickDevG. I will make sure that gets fixed in the next release.

Thanks again, @NickDevG - the typo was fixed a few weeks ago.

Great news guys, thank you for your work

I'm going to close this now as our new Tabs documentation should resolve the confusion mentioned here: https://polaris.shopify.com/components/navigation/tabs

Was this page helpful?
0 / 5 - 0 ratings