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

Table

Mẫu chuẩn

Dữ liệu đọc theo cả hai chiều — hàng và cột cùng mang nghĩa. Tailwind thuần trên <table> HTML thật, không runtime mới.

Native tableKhông variantChiều cao hàng theo densityLight & dark

Playground

Đổi brand, theme và dữ liệu để xem cùng một Table thích ứng với nhận diện và ngữ cảnh.

LIVE PREVIEW
Giao dịch gần đây
Mã giao dịchKhách hàngTrạng tháiSố tiềnNgày tạo
GD-4821Nguyễn Thị LanHoàn tất1.250.000₫12/09/2026
GD-4820Trần Văn MinhĐang xử lý480.000₫12/09/2026
GD-4819Lê Hoàng PhúcThất bại2.100.000₫11/09/2026
GD-4818Phạm Thu HàHoàn tất915.000₫11/09/2026

Mật độ trang hiện tại: Rộng (48px/hàng).

import { Table, TableBody, TableCaption, TableCell, TableHead, TableHeader, TableRow } from "@nexobox/ui";

<Table>
  <TableCaption>Giao dịch gần đây</TableCaption>
  <TableHeader>
    <TableRow>
      <TableHead>Khách hàng</TableHead>
      <TableHead>Trạng thái</TableHead>
    </TableRow>
  </TableHeader>
  <TableBody>
    <TableRow>
      <TableCell>Nguyễn Thị Lan</TableCell>
      <TableCell>Hoàn tất</TableCell>
    </TableRow>
  </TableBody>
</Table>

Khi nào sử dụng

Dữ liệu đọc theo cả hai chiều — hàng và cột cùng mang nghĩa, và người dùng so sánh giữa các hàng. Danh sách giao dịch, người dùng, đơn hàng với nhiều thuộc tính cùng cấp.

Khi nào không dùng

Danh sách thẻ không có quan hệ cột — dùng Card lặp lại. Bố cục thuần layout không mang dữ liệu bảng — dùng CSS grid của trang. Bảng cần sắp xếp, chọn hàng, hoặc phân trang — dùng DataTable. Bậc Table không có cả ba, xem mục Variants.

Anatomy

Giao dịch gần đây
Mã giao dịchKhách hàngTrạng thái
GD-4821Nguyễn Thị LanHoàn tất
GD-4820Trần Văn MinhĐang xử lý
1 Table — viền border-subtle, bo card 12, cuộn ngang khi tràn2 TableCaption — mô tả bảng, đứng trên header3 TableHeader — nền header-background4 TableHead — cột tiêu đề, scope="col"5 TableRow — chiều cao đổi theo density6 TableCell — ô dữ liệu, bo none, đệm ngang --nf-component-table-cell-padding-inline

Variants

Không có. Table không nhận prop biến thể — một cách trình bày duy nhất cho mọi ngữ cảnh. Ba khả năng sau không có ở bậc này: sắp xếp cột (cần trạng thái hướng sort chưa đặc tả), chọn hàng (cần checkbox cột đầu và hành vi bàn phím chưa quyết), phân trang (component riêng — Pagination — không import vào đây, chỉ đi kèm trên cùng một trang danh sách).

Header dính — không có. Bật đúng cách cần theo dõi vị trí cuộn để chỉ hiện --nf-foundation-shadow-raised khi có nội dung cuộn bên dưới; không component nào khác trong gói này theo dõi cuộn bằng JS, và một sticky tĩnh cộng shadow luôn bật sẽ vi phạm điều kiện đó.

Hàng nhấn được — không có. Không hàng nào nhận press-scale hay outline tiêu điểm; hover chỉ đổi nền để dễ dò dòng, không đổi con trỏ.

States

Khách hàngTrạng thái
Nguyễn Thị LanHoàn tất
Trần Văn MinhĐang xử lý

Hàng thứ hai mô phỏng nền hover — không cần rê chuột thật để xem.

Giao dịch gần đây
Mã giao dịchKhách hàngTrạng tháiSố tiềnNgày tạo
Không có giao dịch trong khoảng thời gian đã chọn.

Rỗng — một hàng, một ô colSpan bằng số cột. Không ẩn tbody.

Không có loading hay error ở bậc primitive: đó là trạng thái của vùng gọi Table, không phải của chính <table>.

Khách hàngTrạng thái
Nguyễn Thị LanHoàn tất
Trần Văn MinhĐang xử lý

Rộng (comfortable) · --nf-component-table-row-height đo được: …

Khách hàngTrạng thái
Nguyễn Thị LanHoàn tất
Trần Văn MinhĐang xử lý

Gọn (compact) · --nf-component-table-row-height đo được: …

Keyboard & accessibility

Không hàng nào tự nhận tiêu điểm; <table> không tham gia thứ tự Tab mặc định.
TableHead luôn mang scope, mặc định col, để trình đọc màn hình đọc tên cột đi kèm mỗi ô.
Một điều khiển đặt trong TableCell giữ nguyên hợp đồng bàn phím của chính nó.
Trình đọc màn hình điều hướng bảng bằng phím của chính AT đó — hành vi gốc của <table>.

Design tokens

Giá trị theo NexoCRM / light đang chọn trong playground. Bề mặt đọc --nf-component-table-header-background, -row-background, -row-hover. Chiều cao hàng đọc --nf-component-table-row-height. Đệm ô đọc --nf-component-table-cell-padding-inline, caption đọc thêm -cell-padding-block. Khung đọc --nf-component-card-radius và --nf-semantic-border-subtle.

Kiểu chữ: --nf-foundation-typography-ui-* cho tiêu đề cột (0.875rem, weight 500). Ô dữ liệu cùng cỡ, weight 400. Số trong ô bind thêm vai data (tabular-nums). --nf-foundation-typography-caption-* cho caption.

API & triển khai

PropMặc địnhQuy ước
Table.children—TableCaption, TableHeader, TableBody
Table.containerProps—Props của div cuộn bọc ngoài: ref, className, max-height, onScroll và nhãn vùng
*.className—Nối vào phần tử tương ứng, không thay thế
TableHead.scopecolcol | row | colgroup | rowgroup
TableCell.colSpan—Thuộc tính <td> gốc — dùng cho hàng rỗng

Do / Don't

Nên dùng

  • TableHead cho mọi ô tiêu đề cột
  • Để chiều cao hàng theo density của vùng
  • Render hàng rỗng thật khi không có dữ liệu
  • Đặt Pagination cạnh Table như hai component độc lập
  • Đặt nút/checkbox trong TableCell khi một ô thật sự cần bấm được

Tránh dùng

  • TableCell trong thead — mất scope, AT không đọc được tên cột
  • Đặt h-[...] cứng trên TableRow để ép một cỡ khác
  • Ẩn tbody hoàn toàn khi rỗng
  • Import Pagination bên trong table.tsx
  • Gắn onClick lên TableRow để giả một hàng bấm được