nori-ui

Table

Compound table primitive. Semantic <table> on web for full a11y; View flex-grid on native.

2.4 kBgzipped

At a glance

  • Compound primitive: Table, .Header, .Body, .Footer, .Row, .HeaderCell, .Cell, .Caption.
  • Web uses semantic <table> / <thead> / <tbody> / <tfoot> / <tr> / <th> / <td> / <caption> for full screen-reader support.
  • Native renders a ScrollView + View flex-grid (all columns equal-width in v1; variable widths are a v2 improvement).
  • Optional cosmetic flags: striped, compact, bordered.
  • Interactive rows via onPress on Table.Row.
  • For automatic column/data rendering with sort + pagination, see DataTable.

Basic usage

Direction:
Locale:
import { Table } from '@nori-ui/core';
 
const invoices = [
    { id: 'INV-001', status: 'Paid', amount: '$250.00' },
    { id: 'INV-002', status: 'Pending', amount: '$150.00' },
    { id: 'INV-003', status: 'Overdue', amount: '$350.00' },
];
 
export function InvoiceTable() {
    return (
        <Table>
            <Table.Caption>Recent invoices</Table.Caption>
            <Table.Header>
                <Table.Row>
                    <Table.HeaderCell>Invoice</Table.HeaderCell>
                    <Table.HeaderCell>Status</Table.HeaderCell>
                    <Table.HeaderCell align="right">Amount</Table.HeaderCell>
                </Table.Row>
            </Table.Header>
            <Table.Body>
                {invoices.map((inv) => (
                    <Table.Row key={inv.id}>
                        <Table.Cell>{inv.id}</Table.Cell>
                        <Table.Cell>{inv.status}</Table.Cell>
                        <Table.Cell align="right">{inv.amount}</Table.Cell>
                    </Table.Row>
                ))}
            </Table.Body>
            <Table.Footer>
                <Table.Row>
                    <Table.Cell colSpan={2}>Total</Table.Cell>
                    <Table.Cell align="right">$750.00</Table.Cell>
                </Table.Row>
            </Table.Footer>
        </Table>
    );
}

Striped rows

Pass striped to alternate row backgrounds:

<Table striped>
    {/* ... */}
</Table>

Compact

Tighter cell padding for dense layouts:

<Table compact>
    {/* ... */}
</Table>

Bordered

Draw a border around all cells:

<Table bordered>
    {/* ... */}
</Table>

Aligned columns

align works on both Table.Cell and Table.HeaderCell:

<Table.HeaderCell align="right">Amount</Table.HeaderCell>
<Table.Cell align="center">Status</Table.Cell>

Accepted values: 'left' (default) | 'center' | 'right'.

Column span

Pass colSpan to merge cells:

<Table.Cell colSpan={2}>Merged cell</Table.Cell>

On web this maps to the HTML colspan attribute. On native it is a visual hint only (the cell still occupies its flex slot).

Clickable rows

Pass onPress to Table.Row to make a row interactive:

<Table.Row onPress={() => router.push(`/invoices/${inv.id}`)}>
    {/* ... */}
</Table.Row>

On web the row gets a pointer cursor and a hover background. On native it wraps in a Pressable with an opacity feedback.

Native notes

  • The root element is a ScrollView with horizontal enabled so wide tables can scroll on narrow screens.
  • All columns share equal flex: 1 in v1. Custom column widths are deferred to v2.
  • striped is not yet applied on native (rows have no index-aware background without a parent counter context); use a plain list with custom backgroundColor on alternating rows as a workaround.
  • compact reduces paddingVertical on all rows.
  • bordered adds a borderWidth: 1 around the outer container.

Accessibility

  • Web: uses semantic table elements. Screen readers announce column headers via <th> and can navigate by row/column.
  • Native: no explicit accessibilityRole is set on the grid container; individual cells are plain Views. For data-heavy native UIs where VoiceOver/TalkBack navigation matters, consider labelling cells manually via accessibilityLabel.

API

Table

PropTypeDefaultDescription
stripedbooleanfalseAlternate row background tinting.
compactbooleanfalseReduce cell padding.
borderedbooleanfalseDraw borders around cells.
classNamestringWeb: extra CSS classes on the <table>.
testIDstringTest identifier.

Table.Row

PropTypeDefaultDescription
selectedbooleanfalseHighlight row as selected.
onPress() => voidMakes the row pressable.
classNamestringWeb only.
testIDstringTest identifier.

Table.Cell / Table.HeaderCell

PropTypeDefaultDescription
align'left' | 'center' | 'right''left'Horizontal alignment.
colSpannumberColumn span (HTML on web; visual on native).
classNamestringWeb only.
testIDstringTest identifier.

Table.Header / Table.Body / Table.Footer / Table.Caption

Structural wrappers. Accept children, className (web), and testID.

On this page

Preview theme