@allpro/react-nav-tabs
v0.9.6
Published
Wrapper for Material UI Tabs to integrate them with React Router
Downloads
81
Readme
React NavTabs
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, runnpm 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>
- Unpkg:
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 nocomponent
is specified. Accepts atext
prop to customize the placeholder text. Also accepts acode
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. (Iftabs
is not set, a sample set of tabs will be displayed.) Seetabs
Configuration below.defaultTab
{integer|false}[0]
optional Specify which tab should display by default. (0 = first tab; 1 = second, etc.) Set tofalse
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 to0
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, usingdepth
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 tabpath
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. Thepath
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 thecomponent
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
- create-react-library - A React component framework based on create-react-app
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.