Table
نمای کلیimport { SortDirection, Table, TableAlign, TableBody, TableCell, TableFooter } from '@nili/ui';این همان صفحهی نمای کلیِ خود کتابخانه است که زنده رندر میشود. زبان یا تم را از هدر عوض کنید، همراهش میآید.
پایه
یک المان table واقعی، نه div با نقش ردیف. صفحهخوانها به جدول واقعی حالت ناوبری میدهند — حرکت سلولبهسلول، شنیدن سرستون در هر پرش — و هیچکدام از اینها در بازنویسی با div باقی نمیماند. label نامش میدهد؛ جدول بینام فقط بهصورت «جدول» اعلام میشود و بس.
| مشتری | مبلغ | وضعیت |
|---|---|---|
| Acme Co. | 1,200 | پرداختشده |
| Globex | 480 | در انتظار |
| Initech | 3,150 | معوق |
| Umbrella | 90 | پرداختشده |
import {
Table, TableHeader, TableBody, TableRow, TableHead, TableCell, Badge,
} from "@nili/ui"
export function Example() {
return (
<Table label="Invoices">
<TableHeader>
<TableRow>
<TableHead>Customer</TableHead>
<TableHead align="end">Amount</TableHead>
<TableHead>Status</TableHead>
</TableRow>
</TableHeader>
<TableBody>
{rows.map((row) => (
<TableRow key={row.id}>
<TableCell header>{row.customer}</TableCell>
<TableCell align="end" numeric>{row.amount}</TableCell>
<TableCell>
<Badge appearance="light" color="green" dot>Paid</Badge>
</TableCell>
</TableRow>
))}
</TableBody>
</Table>
)
}ارتفاع ردیف و عنوان جدول
دو ارتفاع ردیف — X-Large (۶۴) و Large (۴۸). یک caption دیدهشدنی جدول را نامگذاری میکند، پس دیگر به label هم نیاز نیست.
| مشتری | مبلغ |
|---|---|
| Acme Co. | 1,200 |
| Globex | 480 |
| Initech | 3,150 |
import { Table } from "@nili/ui"
export function Example() {
return (
<>
<Table size="xl" label="Invoices">…</Table>
<Table size="lg" caption={t('sizes.caption')}>…</Table>
</>
)
}اولویت سلول
اینکه یک ستون چقدر بلند خوانده شود. leading هویت ردیف است، passive فرادادهای است که چشم باید از رویش رد شود، و none استایل تایپوگرافی را کاملاً برمیدارد تا سلول بتواند یک کنترل را در خود جا دهد.
| مشتری | ایمیل | بهروزرسانی | کنشها |
|---|---|---|---|
A | billing@acme.com | ۲ روز پیش | |
G | ap@globex.io | ۲ روز پیش | |
I | finance@initech.dev | ۲ روز پیش |
import { Table, TableCell } from "@nili/ui"
export function Example() {
return (
<TableRow>
<TableCell priority="leading" header>Acme Co.</TableCell>
<TableCell priority="regular">billing@acme.com</TableCell>
<TableCell priority="passive">Updated 2 days ago</TableCell>
<TableCell priority="none">
<CompactButton aria-label="More"><Icon icon={RiMore2Fill} /></CompactButton>
</TableCell>
</TableRow>
)
}مرتبسازی
sortable دکمهٔ مرتبسازی را میسازد و aria-sort را روی سلول مدیریت میکند. فقط روی ستون مرتبشده مینشیند — «none» روی بقیهٔ ستونها نویزی است که صفحهخوان بلند میخواند.
| Initech | 3,150 |
|---|---|
| Acme Co. | 1,200 |
| Globex | 480 |
| Umbrella | 90 |
import { TableHead } from "@nili/ui"
export function Example() {
const [sort, setSort] = useState({ key: "amount", direction: "desc" })
return (
<TableHead
align="end"
sortable
sortDirection={sort.key === "amount" ? sort.direction : null}
sortLabel={t('sorting.byAmount')}
onSort={(direction) => setSort({ key: "amount", direction })}
>
Amount
</TableHead>
)
}انتخاب، سربرگ چسبان و پابرگ
selected یک ردیف را برجسته میکند و aria-selected میافزاید. interactive فقط نشانهٔ هاور است — ردیفی که با onClick یک رکورد را باز کند برای صفحهخوان نامرئی است، پس یک لینک یا دکمهٔ واقعی در سلول بگذارید و بگذارید برجستگی ردیف دنبالش بیاید.
| مشتری | مبلغ | |
|---|---|---|
| Acme Co. | 1,200 | |
| Globex | 480 | |
| Initech | 3,150 | |
| Umbrella | 90 | |
| 1 از 4 انتخاب شده | 4,920 | |
import { Table, TableRow, TableHead, TableCell, Checkbox } from "@nili/ui"
export function Example() {
return (
<Table label="Invoices" stickyHeader>
<TableHeader sticky>
<TableRow>
<TableHead state="empty"><Checkbox aria-label="Select all" /></TableHead>
<TableHead>Customer</TableHead>
</TableRow>
</TableHeader>
<TableBody>
<TableRow selected interactive>
<TableCell priority="none"><Checkbox aria-label="Select row" checked /></TableCell>
<TableCell header>Globex</TableCell>
</TableRow>
</TableBody>
<TableFooter>
<TableRow>
<TableCell colSpan={2}>4 invoices</TableCell>
</TableRow>
</TableFooter>
</Table>
)
}Table
extends ComponentPropsWithoutRef<'table'>
بقیهی پراپها
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| size | xl | lg | xl | |
| label | string | — | Accessible name. A table with no name is announced as "table" and nothing else, which is useless on a page with three of them. |
| caption | ReactNode | — | Visible caption, rendered above the table. Also names it. |
| stickyHeader | boolean | false | Keeps the header visible while the body scrolls. |
| scrollable | boolean | true | Wrap in a scrollable, keyboard-focusable region. On by default: a table that overflows horizontally is unreachable by keyboard otherwise. |
| scrollClassName | string | — | Class for the scroll wrapper. Use `className` for the `<table>`. |
TableCaption
داخلیTableCell
extends Omit< ComponentPropsWithoutRef<'td'>, 'align' >
محورهای واریانت — از تعریف cva کامپوننت
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| align | start | center | end | start | |
| priority | leading | regular | passive | none | regular | Figma's `Priority` — how loudly the column reads. `leading` is the row's identity, `passive` is metadata the eye should skip, `none` drops the type styling so the cell can host a control. |
| numeric | boolean | false | Tabular figures, so a column of numbers lines up. |
| size | xl | lg | xl |
بقیهی پراپها
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| header | boolean | false | Makes the cell a row header (`<th scope="row">`). The first column of a data table usually is one, and marking it lets a screen reader say which row it is reading. |
TableHead
extends Omit< ComponentPropsWithoutRef<'th'>, 'align' >
محورهای واریانت — از تعریف cva کامپوننت
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| align | start | center | end | start | |
| state | default | disabled | empty | default | Figma's header `State`. `empty` marks a header with no label — the checkbox column — so it is not announced as naming its column. |
| size | xl | lg | xl |
بقیهی پراپها
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — | |
| sortable | boolean | false | Renders a sort button and manages `aria-sort` on the cell. |
| sortDirection | desc | asc | — | Current direction, or `null` when this column is not the sort key. |
| onSort | (direction: SortDirection) => void | — | |
| sortLabel | string | — | Accessible name for the sort button, e.g. `` (c) => `Sort by ${c}` ``. |
TableHeader
محورهای واریانت — از تعریف cva کامپوننت
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| sticky | 'true' | 'false' | false |
TableRow
extends ComponentPropsWithoutRef<'tr'>
محورهای واریانت — از تعریف cva کامپوننت
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| selected | boolean | false | Highlights the row and adds `aria-selected`. |
| interactive | boolean | false | Hover affordance for a row that navigates. The click target must still be a real control *inside* the row — see the note in the component. |
بقیهی پراپها
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| children | ReactNode | — | |
| aria-label | string | — |
TableScroll
داخلیTableSortButton
داخلیمحورهای واریانت — از تعریف cva کامپوننت
| پراپ | نوع | پیشفرض | توضیح |
|---|---|---|---|
| align | start | center | end | start | |
| sorted | 'true' | 'false' | false |