Tabs
Tabs is a neobrutalist React component from Cruise UI. Three styles: Underline for page sections, Boxed for settings, Pill for filters. Install it with npx shadcn@latest add @cruiseui/tabs.
Install
Terminal
npx shadcn@latest add @cruiseui/tabsFirst time? Installation shows the one-off components.json setup (the @cruiseui registry) and how to turn the theme on.
Example
Corners
Three layers of vanilla sponge. Serves 12.
Your name, photo and phone number.
Showing all 48 products.
import { CruiseTabs } from "@/components/cruise/tabs";
export default function TabsExample() {
return (
<div className="flex flex-col gap-10">
<CruiseTabs
label="Product details"
items={[
{ value: "details", label: "Details", content: <p>Three layers of vanilla sponge. Serves 12.</p> },
{ value: "reviews", label: "Reviews", content: <p>4.8 out of 5 from 126 reviews.</p> },
{ value: "delivery", label: "Delivery", content: <p>Same-day delivery in Lagos.</p> },
]}
/>
<CruiseTabs
variant="boxed"
label="Settings"
items={[
{ value: "profile", label: "Profile", content: <p>Your name, photo and phone number.</p> },
{ value: "security", label: "Security", content: <p>Password and two-step sign-in.</p> },
]}
/>
<CruiseTabs
variant="pill"
label="Filter products"
items={[
{ value: "all", label: "All", content: <p>Showing all 48 products.</p> },
{ value: "cakes", label: "Cakes", content: <p>Showing 18 cakes.</p> },
{ value: "drinks", label: "Drinks", content: <p>Showing 8 drinks.</p> },
]}
/>
</div>
);
}
<div class="tabs-underline"> <!-- or tabs-boxed / tabs-pill -->
<div class="tab-list" role="tablist" aria-label="Product details">
<button type="button" class="tab" role="tab" id="tab-details" aria-selected="true" aria-controls="panel-details">Details</button>
<button type="button" class="tab" role="tab" id="tab-reviews" aria-selected="false" aria-controls="panel-reviews" tabindex="-1">Reviews</button>
<button type="button" class="tab" role="tab" id="tab-delivery" aria-selected="false" aria-controls="panel-delivery" tabindex="-1">Delivery</button>
</div>
<div class="tab-panel" role="tabpanel" id="panel-details" aria-labelledby="tab-details" tabindex="0">…</div>
<div class="tab-panel" role="tabpanel" id="panel-reviews" aria-labelledby="tab-reviews" tabindex="0" hidden>…</div>
<div class="tab-panel" role="tabpanel" id="panel-delivery" aria-labelledby="tab-delivery" tabindex="0" hidden>…</div>
</div>Needs theme.css. Interactive parts (menus, tabs, drawers) also need the script in the spec for that component.
When to use it
When to use
Switching between views of the same thing without leaving the page.
When not to
Tabs that are really pages (use links). More than ~6 tabs.
Props
CruiseTabs
| Prop | Type | Default | Description |
|---|---|---|---|
label | string | — | Accessible name for the tab row, e.g. "Order details". |
items | CruiseTabItem<V>[] | — | — |
variant? | CruiseTabsVariant | "underline" | — |
value? | V | — | — |
defaultValue? | V | items[0]?.value | — |
onValueChange? | ((value: V) => void) | — | — |
keepMounted? | boolean | false | Render every panel's content in the HTML (hidden until chosen), so it can be found without JavaScript and by search engines. |
className? | string | — | — |
Accessibility
- tablist / tab / tabpanel roles with aria-selected and aria-controls.
- Left / Right, Home / End move between tabs; the row scrolls sideways on phones.