React Bootstrap Tabs
React Bootstrap tabs without Bootstrap's JavaScript: TabContainer, TabLink and TabPane switch panes from state, with arrow keys and colored or vertical styles.
This component is only available in AdminKit PRO. Learn more.
Tabs split related content into panes and show one pane at a time, so a settings page or a project view does not turn into one long scroll. The user clicks a tab, or moves to it with the arrow keys, and its pane appears.
Three React components do the work: TabContainer, TabLink and TabPane. They keep the active tab in React state, so you need neither Bootstrap's JavaScript nor react-bootstrap. They are part of the PRO version of AdminKit for React.
You still write the nav and the panes with Bootstrap's markup. A TabLink and a TabPane with the same eventKey belong together. TabContainer holds the active key. It renders no element of its own, so it does not change your markup. The components are in src/components/bootstrap/tabs.tsx.
Example
import { TabContainer, TabLink, TabPane } from "@/components/bootstrap/tabs";
export function AccountTabs() {
return (
<div className="tab">
<TabContainer defaultActiveKey="profile">
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item" role="presentation">
<TabLink eventKey="profile" className="nav-link">Profile</TabLink>
</li>
<li className="nav-item" role="presentation">
<TabLink eventKey="security" className="nav-link">Security</TabLink>
</li>
<li className="nav-item" role="presentation">
<TabLink eventKey="billing" className="nav-link">Billing</TabLink>
</li>
</ul>
<div className="tab-content">
<TabPane eventKey="profile">
<p>Your name, photo and contact details.</p>
</TabPane>
<TabPane eventKey="security">
<p>Your password and two-factor authentication.</p>
</TabPane>
<TabPane eventKey="billing">
<p>Your plan, invoices and payment method.</p>
</TabPane>
</div>
</TabContainer>
</div>
);
}The .tab wrapper gives you AdminKit's tab style: borderless tabs on top of a card-like .tab-content. Leave it out to get Bootstrap's plain .nav-tabs. For pills, use nav nav-pills on the list.
Props
TabContainer:
| Prop | Type | Default | Description |
|---|---|---|---|
defaultActiveKey | string | The tab that is active first | |
activeKey | string | Controlled: the active tab; use it with onSelect | |
onSelect | (key: string) => void | Called with the eventKey of the tab that was selected |
TabLink:
| Prop | Type | Default | Description |
|---|---|---|---|
eventKey | string | The key of the pane it shows | |
as | ElementType | "a" | The element: an a with href="#", or "button" (gets type="button") |
disabled | boolean | Adds .disabled; a click does nothing and the arrow keys skip it |
TabPane:
| Prop | Type | Default | Description |
|---|---|---|---|
eventKey | string | The key of its tab | |
fade | boolean | true | Fades the pane in (.fade); false switches at once |
Other props, such as className and onClick, go to the TabLink and TabPane elements. You do not write the id, aria-controls and aria-labelledby attributes that connect a tab and its pane: they are generated with useId.
Controlled tabs
Sometimes the active tab has to change from outside the nav: a button elsewhere on the page opens a tab, or the URL keeps track of it. Pass activeKey and onSelect, and the parent component owns the active tab:
import { useSearchParams } from "react-router";
export function SettingsTabs() {
const [params, setParams] = useSearchParams();
const tab = params.get("tab") ?? "profile";
return (
<TabContainer activeKey={tab} onSelect={(key) => setParams({ tab: key })}>
{/* the nav and the panes */}
</TabContainer>
);
}Colored and vertical tabs
When the tabs should stand out, give them a color. Add a theme color to the wrapper (tab-primary, tab-success, tab-danger, ...) to color the active tab and the content. Add tab-vertical to put the tabs on the left. The demo panes use .tab-title for their headings.
<div className="tab tab-vertical tab-primary">
<TabContainer defaultActiveKey="general">
<ul className="nav nav-tabs" role="tablist">
<li className="nav-item" role="presentation">
<TabLink eventKey="general" className="nav-link">General</TabLink>
</li>
<li className="nav-item" role="presentation">
<TabLink eventKey="team" className="nav-link">Team</TabLink>
</li>
</ul>
<div className="tab-content">
<TabPane eventKey="general" fade={false}>
<h2 className="h4 tab-title">General</h2>
<p>The name and the time zone of the workspace.</p>
</TabPane>
<TabPane eventKey="team" fade={false}>
<h2 className="h4 tab-title">Team</h2>
<p>The members of the workspace and their roles.</p>
</TabPane>
</div>
</TabContainer>
</div>Tabs can also show an icon instead of a label. Put the icon in the TabLink and give the link an aria-label, as the demo does: <TabLink eventKey="settings" className="nav-link" aria-label="Settings"><Settings className="align-middle" /></TabLink>. The .tab style sizes the icon to 20px.
Accessibility
TabLinkhasrole="tab",aria-selectedandaria-controls.TabPanehasrole="tabpanel",aria-labelledbyandtabIndex={0}. Addrole="tablist"to the list androle="presentation"to its items yourself, as in the example.- Only the active tab is in the Tab order. Arrow keys, Home and End move to another tab of the same
role="tablist"and show its pane, as in Bootstrap 5.3. Withoutrole="tablist"on the list, the arrow keys do nothing. - Icon-only tabs need an
aria-label. disabledonly adds the.disabledclass. Addaria-disabled="true"for screen readers.
Related
- Next.js Bootstrap tabs: the same component in AdminKit for Next.js
- Bootstrap 5 navs and tabs: the nav and tab classes of the HTML version
- Accordion: another way to show one section at a time
- Tabs demo
Last updated on
TooltipsPro
A React Bootstrap tooltip that wraps any element: shown on hover and focus, placed by Floating UI on the top, bottom, left or right, styled by Bootstrap's CSS.
Navbar
Change the React Bootstrap navbar of AdminKit: the top bar with notifications, messages, color mode and user menus, each a small component you can edit.