Tabs
Mẫu chuẩnMột bề mặt, nhiều khung nhìn ngang hàng. Chuyển khung nhìn không đổi URL, không mất ngữ cảnh.
Playground
Đổi brand, theme và trạng thái. Không có prop size, không có prop variant.
Dùng mũi tên Trái/Phải để chuyển tab, Home/End về đầu/cuối. Mặc định activationMode là automatic.
import { Tabs, TabsContent, TabsList, TabsTrigger } from "@nexobox/ui";
<Tabs defaultValue="overview">
<TabsList>
<TabsTrigger value="overview">Tổng quan</TabsTrigger>
<TabsTrigger value="activity">Hoạt động</TabsTrigger>
<TabsTrigger value="settings">Cấu hình</TabsTrigger>
</TabsList>
<TabsContent value="overview">Khung nhìn tổng quan.</TabsContent>
<TabsContent value="activity">Khung nhìn hoạt động.</TabsContent>
<TabsContent value="settings">Khung nhìn cấu hình.</TabsContent>
</Tabs>Khi nào sử dụng
Nên dùng
Một bề mặt duy nhất chia thành nhiều khung nhìn ngang hàng, nơi người dùng chỉ xem một khung mỗi lúc và cần chuyển qua lại nhanh mà không mất ngữ cảnh — ví dụ các nhóm cấu hình cùng một đối tượng, hoặc các lát dữ liệu cùng cấp của một hồ sơ.
Tránh dùng
Các bước tuần tự có thứ tự bắt buộc — đó là một wizard. Điều hướng giữa các trang khác nhau, nơi URL phải đổi — dùng link thật. Ẩn nội dung dài để trang trông ngắn — đó là Accordion.
Anatomy
| # | Phần | Ghi chú |
|---|---|---|
| 1 | Root | Tabs. Không render DOM riêng ngoài container, giữ value hiện hành. |
| 2 | List | div[role=tablist]. Viền dưới --nf-semantic-border-subtle, không nền pill, không viền bao. |
| 3 | Trigger | button[role=tab] cho mỗi khung nhìn. Viền dưới 2 px đổi màu khi active. Cao 40 px ở comfortable, 36 px ở compact — bind --nf-component-tabs-trigger-height riêng của Tabs, không còn bậc nền tảng. |
| 4 | Content | div[role=tabpanel]. Chỉ khung đang active tương tác được; khung khác hidden. |
Không có nội dung nào portal ra ngoài. TabsContent nằm nguyên tại chỗ trong cây DOM.
Variants & states
Không có variant, không có size. Loading, error, empty: không có — Tabs không bất đồng bộ.
Nền trong suốt, chữ text-secondary, viền dưới trong suốt.
Chữ text-primary, viền dưới action-primary-background.
Di chuột vào tab. Nền đọc --nf-component-tabs-trigger-hover.
Giữ chuột xuống. Nền đọc --nf-component-tabs-trigger-pressed. Không co scale — DS-018 rút press-scale khỏi mọi primitive.
Outline theo --nf-component-focus-*. Ảnh mô phỏng bằng class xem trước, không phải Tab thật.
Con trỏ not-allowed, chữ màu disabled. Bị bỏ qua bởi roving tabindex.
Loading, error, empty: không có, Tabs không bất đồng bộ.
Design tokens
Giá trị theo NexoCrew / light đang chọn trong playground. List đọc --nf-semantic-border-subtle, --nf-component-tabs-list-gap. Trigger đọc --nf-component-tabs-trigger-height — alias riêng của Tabs, không còn bind thẳng --nf-foundation-size-* — cộng --nf-component-tabs-trigger-padding-inline, --nf-semantic-text-secondary, --nf-semantic-text-primary, --nf-semantic-action-primary-background, --nf-component-tabs-trigger-hover, --nf-component-tabs-trigger-pressed, --nf-component-button-disabled-foreground. Content đọc --nf-component-tabs-content-padding-block-start. Cả hai dùng --nf-component-focus-width, --nf-component-focus-color, --nf-component-focus-offset, --nf-component-transition-duration, --nf-component-transition-easing.
API & triển khai
| Prop | Mặc định | Quy ước |
|---|---|---|
| value (Root) | — | Chế độ controlled, khung nhìn đang active. |
| defaultValue (Root) | — | Chế độ uncontrolled. |
| onValueChange (Root) | — | Phát khi tab active đổi. |
| orientation (Root) | "horizontal" | Đổi trục điều hướng bằng phím mũi tên. |
| dir (Root) | — | Hướng đọc, ảnh hưởng chiều mũi tên. |
| activationMode (Root) | "automatic" | "manual" cần Enter/Space để kích hoạt. |
| value (Trigger) | — | Khoá liên kết trigger với content cùng value. |
| disabled (Trigger) | false | Bỏ qua tương tác và roving tabindex. |
| value (Content) | — | Khoá liên kết content với trigger cùng value. |
| forceMount (Content) | false | Ép render dù đang không active, dùng cho animation ngoài. |
Các type TabsListProps, TabsTriggerProps, TabsContentProps là ComponentPropsWithoutRef của Radix nên asChild, id, className, style truyền thẳng.