Navigation
Tabs
Switches between related panels while keeping the surrounding layout stable.Overview content
import { Tabs } from "@hyzrui/core";
export function Example() {
return <Tabs items={[{ label: "Overview", value: "overview", content: "Overview content" }, { label: "Usage", value: "usage", content: "Usage content" }]} />;
}Installation
Install the primitive source, then keep editing it inside your app. The command names the component file you want copied.
pnpm dlx hyzrui add tabsUsage
Import the component from the generated source folder and compose it with normal React props.
import { Tabs } from "@hyzrui/core";<Tabs className="my-tabs" />Customization
Every primitive accepts local props and class names, then inherits design tokens from HyzrThemeProvider . Copy the file, keep the markup, and tune the CSS until it matches your product.
Overview content
--hui-radiusControls the default corner system for buttons, inputs, cards, overlays, and nested surfaces.--hui-foregroundControls the page and component text colors. Dark mode uses the same component source with different tokens.--hui-surfaceControls card, dialog, popover, and input surfaces.--hui-borderControls separators, input strokes, card outlines, and menu edges.--hui-primaryControls the main action color and the matching foreground color for solid controls.--hui-font-familyControls the font stack used by every primitive inside the provider.--hui-control-font-sizeControls the default font size for buttons, inputs, selects, tabs, command rows, and menu triggers.--hui-font-weight-controlControls the default weight of buttons, tabs, menus, badges, and compact actions.--hui-control-heightControls the default field and trigger height across forms and navigation.--hui-button-heightControls button height independently from form fields.--hui-button-paddingControls horizontal button spacing without changing the text size.--hui-card-paddingControls card, dialog, sheet, drawer, and panel interior spacing.--hui-border-widthControls default edge width for controls, cards, tables, and floating panels.--hui-focus-widthControls keyboard focus outline thickness.--hui-transition-durationControls shared hover timing for controls and surfaces.--hui-hover-liftControls subtle hover lift for raised styles.--hui-overlayControls dialog, sheet, drawer, and command overlay strength.--hui-floating-offsetControls menu, command, popover, and hover-card distance from the trigger.import { defineHyzrTheme } from "@hyzrui/core";
export const theme = defineHyzrTheme({
id: "product",
density: "comfortable",
radius: 10,
shadow: 0.08,
colors: {
background: "#fbfbfc",
foreground: "#09090b",
surface: "#ffffff",
border: "#e4e4e7",
primary: "#18181b",
primaryForeground: "#ffffff",
},
typography: {
controlSize: 14,
controlWeight: 500,
headingWeight: 680,
},
sizing: {
controlHeight: 38,
buttonHeight: 34,
buttonPadding: 14,
cardPadding: 18,
},
borders: {
radius: 10,
radiusSm: 7,
radiusLg: 16,
width: 1,
focusWidth: 2,
},
motion: {
duration: 150,
hoverLift: 0,
hoverMix: 5,
},
});See the customization guide for the full theme shape, style presets, scoped CSS overrides, and source-edit workflow.
Examples
These examples show the same primitive in realistic combinations and states.
Page sections
Tabs work well for top-level page sections where switching does not require a navigation event.
import { Badge, Tabs } from "@hyzrui/core";
export function TabsNavigation() {
return (
<Tabs
items={[
{
label: "Overview",
value: "overview",
content: (
<div style={{ padding: "16px 0", fontSize: "0.875rem", color: "var(--hui-muted)" }}>
Project summary, recent activity, and team members.
</div>
),
},
{
label: "Deployments",
value: "deployments",
content: (
<div style={{ padding: "16px 0", fontSize: "0.875rem", color: "var(--hui-muted)" }}>
All deployment runs, rollback controls, and environment status.
</div>
),
},
{
label: "Settings",
value: "settings",
content: (
<div style={{ padding: "16px 0", fontSize: "0.875rem", color: "var(--hui-muted)" }}>
Project configuration, secrets, and team access.
</div>
),
},
]}
/>
);
}Filtered list
Append counts to tab labels so users can prioritize before clicking through.
- Login timeout on mobile
- Webhook retry failed
- Invoice email missing
import { Tabs } from "@hyzrui/core";
export function TabsFilter() {
const tickets = {
open: ["Login timeout on mobile", "Webhook retry failed", "Invoice email missing"],
closed: ["CSV export malformed", "2FA bypass bug"],
snoozed: ["Rate limit documentation"],
};
return (
<Tabs
items={[
{
label: `Open (${tickets.open.length})`,
value: "open",
content: (
<ul style={{ padding: 0, margin: "12px 0 0", listStyle: "none", display: "grid", gap: 8 }}>
{tickets.open.map((t) => <li key={t} style={{ fontSize: "0.875rem", padding: "8px 0", borderBottom: "1px solid var(--hui-border)" }}>{t}</li>)}
</ul>
),
},
{
label: `Closed (${tickets.closed.length})`,
value: "closed",
content: (
<ul style={{ padding: 0, margin: "12px 0 0", listStyle: "none", display: "grid", gap: 8 }}>
{tickets.closed.map((t) => <li key={t} style={{ fontSize: "0.875rem", padding: "8px 0", borderBottom: "1px solid var(--hui-border)", color: "var(--hui-muted)" }}>{t}</li>)}
</ul>
),
},
{
label: "Snoozed",
value: "snoozed",
content: (
<ul style={{ padding: 0, margin: "12px 0 0", listStyle: "none", display: "grid", gap: 8 }}>
{tickets.snoozed.map((t) => <li key={t} style={{ fontSize: "0.875rem", padding: "8px 0", color: "var(--hui-muted)" }}>{t}</li>)}
</ul>
),
},
]}
/>
);
}API Reference
Props are intentionally small. For deeper changes, edit the component source file directly.
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Adds classes to the copied component without replacing the default structure. |
children | React.ReactNode | - | The rendered content for compound or wrapper components. |
...props | HTMLAttributes | - | Forwards native element props such as id, aria attributes, and event handlers. |
items | TabItem[] | - | Tab items with value, label, and content. |
value | string | - | Controlled active tab. |
onValueChange | (value: string) => void | - | Called when the active tab changes. |