← Vois design previews
Components · Job 18 · Display data

Table vs DataTable

A plain Table implies the point is comparison across a handful of comparable attributes — under ~100 rows. Reaching for full DataTable infrastructure (sort, bulk actions, pagination) for 20 rows is overkill; reach for it once row count and interaction needs actually justify it.

Table · <100 rows, simple compare

PlanPriceSeats
Starter$12/mo3
Team$29/mo10
EnterpriseCustomUnlimited

DataTable · 100+ rows, sortable, bulk actions

0 selected
Acme Corp2024-01-04$2,400
Globex2023-11-19$980
Initech2024-03-02$5,120
Umbrella2023-08-27$1,760

Sortable columns, row selection, bulk action — the infrastructure a <100-row Table skips.

States · render, don't redecide (JOB-LOADING-STATE, JOB-EMPTY-CONTENT)

Loading
CustomerSigned upMRR

Skeleton rows match the table's real shape — column widths don't jump when data lands.

Error · failed to load

Couldn't load customers

Check your connection and try again.

Empty · true zero state, can create here

No customers yet

Add your first customer to start tracking revenue.

User has never created anything here and can create from this screen → EmptyState with a primary CTA.

Empty · filters removed all results

No customers match "acme, status: churned".

Filtered-empty, not true zero — a lightweight inline message, not a full EmptyState (too heavy for "zero results this search").