Skip to content

Wrapper for Material UI Tabs to integrate them with React Router

License

Notifications You must be signed in to change notification settings

allpro/react-nav-tabs

Repository files navigation

React NavTabs

npm package gzip-size install-size build coverage license donate

React NavTabs is a helper that integrates Material UI Tabs with React Router 4/5. The tabs then function as navigation and sync with the URL. Hyperlinks, Back/Forward buttons, and other navigation work as expected.

Motivation

I usually want each 'tab' in a set of tabs to have a unique URL. This makes Back/Forward function as users expect, and makes it possible to 'link' directly to any specific tabs.

Integrating Tabs with React Router requires making each 'tab' a <Link> component, with a corresponding <Route> component for each tab. This requires a lot of boilerplate and is error-prone. NavTabs makes it fast & easy to create navigation-tabs.

Live Example

Try the demos at: https://allpro.github.io/react-nav-tabs

Play with the demo code at: https://codesandbox.io/s/github/allpro/react-nav-tabs/tree/master/example

If you pull or fork the repo, you can run the demos like this:

  • In the root folder, run npm start
  • In a second terminal, in the /example folder, run npm start
  • The demo will start at http://localhost:3000
  • Changes to the component or the demo will auto-update the browser

Installation

  • NPM: npm install @allpro/react-nav-tabs
  • Yarn: yarn add @allpro/react-nav-tabs
  • CDN: Exposed global is ReactNavTabs
    • Unpkg: <script src="https://unpkg.com/@allpro/react-nav-tabs/umd/react-nav-tabs.min.js"></script>
    • JSDelivr: <script src="https://cdn.jsdelivr.net/npm/@allpro/react-nav-tabs/umd/react-nav-tabs.min.js"></script>

Compatibility

NavTabs uses the new React Context API, so requires React 16.3. It uses the withRouter() HOC provided by React-Router 4+.

Peer-Dependencies

NavTabs will work in any project meeting these dependencies.

"peerDependencies": {
    "prop-types": ">=15",
    "react": ">=16.3",
    "react-dom": ">=16.3",
    "react-router-dom": ">=4"
}

Usage

NavTabs wraps Material UI <Tabs> and <Tab> components, plus React Router <Route> components. It generates all these components for you. If you already use Material UI Tabs in your app, it's very easy to convert them to NavTabs, with no change to their appearance.

NavTabs consists of 3 separate components:

  • <NavTabs> Wrapper   (default export)
    Tab configuration is set on this component. It does not output any mark-up.
    See NavTabs Component Props

  • <Tabs> Subcomponent   (named export)
    Outputs the Material UI <Tabs> component.
    See Tabs Subomponent Props

  • <Content> Subcomponent   (named export)
    Outputs the React Router <Route> components (one per tab).
    See Content Subomponent Props

The <Tabs> and <Content> are separate subcomponents so they can fit inside any layout you need. NavTabs can also be nested (tabs within tabs).

Exposed Helpers

Two internal helper component are also exported in case they are useful to devs:

  • <Placeholder> Component   (named export)
    A simple placeholder component used when no component is specified.
    Accepts a text prop to customize the placeholder text.
    Also accepts a code prop, which is used by some NavTabs demos.

  • <PropsRoute> Component   (named export)
    A wrapper around the React Router <Route> component. This allows props to be passed-through to the component specified for a route.
    Use this in place of <Route> if you want to pass-through props.
    Any prop not applicable to a <Route> is considered a component prop.

NavTabs Component Props

Usually you only need the tabs prop. The other props listed here are needed only for special cases.

  • tabs   {array} [null]   required
    This is the configuration for all the tabs.
    (If tabs is not set, a sample set of tabs will be displayed.)
    See tabs Configuration below.

  • defaultTab   {integer|false} [0]   optional
    Specify which tab should display by default. (0 = first tab; 1 = second, etc.)
    Set to false to have no tab selected by default.
    NavTabs will redirect to the path set for the default tab if URL does not already include a valid tab-path.

  • depth   {integer} [null]   optional
    When NavTabs are nested, it cannot automatically determine which part of the URL is for the tabs. This can be handled by specifying which segment of the URL the tabs occupy. Set to 0 for the root of the URL, 1 for the second segment, and so on.

  • parentPath   {string} [""]   optional
    This also addresses the issue of confusing URLs that cannot be automatically parsed. In most cases, using depth is easier.

  • rootPath   {string} [""]   optional
    Handles scenarios where one tab is the 'root' ("/") of the website.
    In most cases this can be handled by just leaving the tab path blank.

tabs Configuration

The tabs prop accepts an array of tab-configurations. Each tab configuration accepts these props:

  • label   {string} [""]   required
    The text to display on the tab - identical to the Material UI Tab label prop.

  • path   {string} [""]   required
    Set a path the same as if adding a sub-route to React Router.
    The path is treated as relative to the parent path unless path starts with a slash, like: "/absolute/path".

  • exact   {boolean} [null]   optional
    This is the React Router 'exact' prop. In most cases NavTabs will correctly set this automatically.

  • component   {component} [null]   required
    The component to display when this tab is selected.
    If no component is set, a <Placeholder> component will display.

  • props   {object} [null]   optional
    Props that you want passed to the component specified.

See the Configuration Example below.

Any other props will be passed-through to the Material UI Tab component. For example, set disabled: true to disable a tab.

<Tabs> Subcomponent Props

NavTabs exports a named <Tabs> component that outputs the Material UI Tabs markup. This is separate so the tabs can be rendered inside a special layout or wrapper.

This component does not require any props, but you can set any prop applicable to the Material UI Tabs component. For example:

<Tabs 
    textColor="primary" 
    indicatorColor="primary" 
/>

This component also accepts one special prop: TabProps. This lets you pass props to each of the autogenerated Material UI Tab subcomponents. For example:

const tabProps = { 
    disableRipple: true, 
    classes: classes.tab 
}

<Tabs TabProps={tabProps} />

Note: To set different props for each <Tab>, add these in the tabs config. For example, to disable one specific tab:

const tabs = [
    {
        label: 'Contact Us',
        path:  'contacts',
        disabled: true, // Extra prop is passed-through to MUI 'Tab' component
        component: ContactInfo
    },
    { ... }
]

<Content> Subcomponent Props

NavTabs exports a named <Content> component that outputs all the <Route> components; one for each tab. This is separate so the tab-content can be rendered separate from the tabs.
This component does not accept any props.

Examples

Structure Example

If NavTabs is implemented without any configuration, sample tabs data is used to create a quick 3-tab prototype. Cosmetic tab props can still be applied.

import NavTabs, { Tabs, Content } from '@allpro/react-nav-tabs'

function Test() {
    return (
        <NavTabs>
            <CustomHeader>
                <Tabs 
                    textColor="primary" 
                    indicatorColor="primary"
                    TabProps={{ classes: classes.tab }}
                />
            </CustomHeader>

            <ContentWrapper>
                <Content />
            </ContentWrapper>
        </NavTabs>
    );
}

Configuration Example

The configure for each tab requires a label, path and component. However a blank path is valid; meaning it will display by default.

If a props key is specified, these are passed to the component.

Any unexpected props are passed-through to the <Tab> component, like the disabled prop shown below.

const tabs = [
    {
        label: 'Company',
        path:  'company',
        component: CompanyDescription
    },
    {
        label: 'Contact Us',
        path:  'contacts',
        disabled: true, // Extra prop is passed-through to MUI 'Tab' component
        component: ContactInfo
    },
    {
        label: 'Careers',
        path:  'careers',
        component: JobPostings,
        props: { filter: 'current' } // Props passed to JobPostings component
    }
];

function Test() {
    return (
        <NavTabs tabs={tabs}>
            <Tabs indicatorColor="primary" />
            <Content />
        </NavTabs>
    );
}

See more examples in the Live Demos

Built With

Contributing

Please read CONTRIBUTING.md for details on our code of conduct, and the process for submitting pull requests to us.

Versioning

We use SemVer for versioning. For the versions available, see the tags on this repository.

License

MIT © allpro
See LICENSE file for details

About

Wrapper for Material UI Tabs to integrate them with React Router

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published