Bỏ qua tới nội dung
Component / 047 / NEXOFRAME

FilterTabs

Mẫu chuẩn

Một hàng tab dùng để lọc một danh sách, không phải để đổi vùng nội dung. Mỗi tab có thể kèm một số đếm. Composite báo một giá trị, là khoá của bộ lọc đang chọn, qua một callback.

Composite tầng 2Dựng từ Tabs + Badge2 đến 5 bộ lọcKhông render TabsContent

Playground

Đổi brand và theme rồi chuyển bộ lọc để xem tên trợ năng ghép số đếm đúng cách.

LIVE PREVIEW

Đang chọn "Tất cả". Composite không render danh sách đã lọc — host tự render bên dưới.

import { FilterTabs } from "@nexobox/ui";

const [value, setValue] = useState("all");

<FilterTabs
  aria-label="Lọc đề xuất"
  value={value}
  onValueChange={setValue}
  options={[
    { value: "all", label: "Tất cả", count: 12 },
    { value: "pending", label: "Đang chờ", count: 3 },
    { value: "rejected", label: "Đã từ chối" },
  ]}
/>

Bài toán

Một danh sách đề xuất hay hoạt động cần lọc theo trạng thái. Người dùng cần thấy mỗi bộ lọc có bao nhiêu mục trước khi chọn. Tabs giải được việc chọn, nhưng không có chỗ đặt số đếm, và trình đọc màn hình sẽ đọc "Đang chờ3" nếu ghép chữ tay. Composite gắn số đếm vào tab theo một cách, kèm tên trợ năng đúng.

Khi nào sử dụng

Nên dùng

Hai đến năm bộ lọc loại trừ nhau trên cùng một danh sách. Khi số đếm của từng bộ lọc giúp người dùng quyết định chọn tab nào.

Khi nào không dùng

Tránh dùng

Không dùng choDùng thay
Đổi giữa các vùng nội dung khác nhau (Tổng quan / Cài đặt)Tabs
Nhiều bộ lọc chọn cùng lúcCheckboxCardGroup hoặc một menu lọc
Trên năm lựa chọnSelect

Dựng từ

Primitive tầng 1Vai trong composite
Tabs, TabsList, TabsTriggerHàng tab, chọn một, điều hướng bằng mũi tên (Radix Tabs).
BadgeSố đếm, variant="quiet". Nền mute, không viền. Không dùng variant trạng thái cho số.
FilterTabs thêm gì
Số đếm trong tab, kèm tên trợ năng "Đang chờ, 3 mục" thay vì đọc liền chữ
Không render TabsContent: danh sách đã lọc do host render bên dưới

Anatomy

Tab được chọn hiển thị theo TabsTrigger, composite không vẽ lại. Số đếm nằm sau nhãn, cách space-2.

States

Trạng tháiBiểu hiện
Chọn / không chọndata-state="active" của Radix
Hover, focusTừ TabsTrigger
Số đếm bằng 0Vẫn hiện "0". Composite không tự ẩn tab
Không có số đếmTab không kèm Badge

Bàn phím & trợ năng

Tab vào hàng tab, dừng ở tab đang chọn -- Radix Tabs.
← / →, Home / End -- Radix Tabs.
Kích hoạt tự động khi di chuyển -- Radix Tabs, activationMode="automatic".
Composite không thêm phím nào.

Seam — host sở hữu gì

Composite không lọc dữ liệu, không đếm, không đồng bộ với URL. Không fetch, không router, không next.

Host sở hữuCấp qua
Danh sách bộ lọcoptions
Số đếm (tính từ dữ liệu)options[].count
Giá trị đang chọnvalue / onValueChange
Render danh sách đã lọcHost, bên dưới FilterTabs

API & triển khai

PropMặc địnhQuy ước
options—Bắt buộc. ReadonlyArray<{ value: string; label: string; count?: number }>. Từ 2 đến 5 mục.
value—Bắt buộc.
onValueChange—Bắt buộc. (value: string) => void.
aria-label—Bắt buộc. Ví dụ "Lọc đề xuất".

Design tokens

Hàng tab đọc --nf-component-tabs-list-gap và --nf-component-tabs-trigger-padding-inline. Số đếm là Badge quiet: --nf-semantic-surface-subtle, --nf-semantic-text-muted, không viền. Khoảng nhãn–số là --nf-foundation-space-2 trên trigger. Chiều cao là chiều cao của TabsTrigger; composite không ghi đè.

Do / Don't

Nên dùng

Nhãn là trạng thái: "Đang chờ". Hiện "0" khi bộ lọc trống. Dùng cho một danh sách.

Tránh dùng

Nhãn chứa số: "Đang chờ (3)" — số đếm là prop count. Ẩn tab khi trống — người dùng mất dấu bộ lọc. Dùng thay Tabs để đổi trang con.