React UI
Edit page
Home
Getting Started
Customize
Foundation
Components: UI
Alert Badge Button ButtonGroup Card CheckboxField Modal Radio ScrollView SelectField Table
Basic Usage General Guidelines Responsive Tables Sortable Columns API TextArea TextField Toggle
Components: Layouts
CSS Helpers
Readme

# Table

Table presents complex tabular data in an easy-to-scan way.

##
Basic Usage

To implement the Table component, you need to import it first:

    import { Table } from '@react-ui-org/react-ui';

And use it:

ID | Name | Date of birth
--- | --- | ---
1 | John Lennon | 09/11/1940
2 | Paul McCartney | 18/07/1942
3 | George Harrison | 25/03/1943
4 | Richard Starkey (Ringo Starr) | 07/08/1940

<Table columns={[ { label: 'ID', name: 'id', }, { label: 'Name', name: 'name', }, { format: row => row.dateOfBirth.toLocaleDateString('en-GB'), label: 'Date of birth', name: 'dateOfBirth', }, ]} rows={[ { dateOfBirth: new Date(1940, 10, 9), id: 1, name: 'John Lennon', }, { dateOfBirth: new Date(1942, 6, 18), id: 2, name: 'Paul McCartney', }, { dateOfBirth: new Date(1943, 2, 25), id: 3, name: 'George Harrison', }, { dateOfBirth: new Date(1940, 7, 7), id: 4, name: 'Richard Starkey (Ringo Starr)', }, ]} />

    <Table  columns={[    {      label: 'ID',      name: 'id',    },    {      label: 'Name',      name: 'name',    },    {      format: row => row.dateOfBirth.toLocaleDateString('en-GB'),      label: 'Date of birth',      name: 'dateOfBirth',    },  ]}  rows={[    {      dateOfBirth: new Date(1940, 10, 9),      id: 1,      name: 'John Lennon',    },    {      dateOfBirth: new Date(1942, 6, 18),      id: 2,      name: 'Paul McCartney',    },    {      dateOfBirth: new Date(1943, 2, 25),      id: 3,      name: 'George Harrison',    },    {      dateOfBirth: new Date(1940, 7, 7),      id: 4,      name: 'Richard Starkey (Ringo Starr)',    },  ]}/>

See
API for all available options.

## General Guidelines

- Keep headers short so users can quickly scan the content of the table. Just one or two words should be enough.

- Tables are good for displaying complex tabular data. For simpler data sets or even plain key-value pairs, consider using the List component.

- Tables make lots of information easier to scan and compare. If you have fewer sections and want to emphasize each group more, consider using Cards.

## Responsive Tables

The easiest way to make tables responsive is to wrap them with the ScrollView component in the horizontal mode.

ID | Name | Note | Date of birth
--- | --- | --- | ---
1 | John Lennon | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. | 09/11/1940
2 | Paul McCartney | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. | 18/07/1942
3 | George Harrison | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. | 25/03/1943
4 | Richard Starkey (Ringo Starr) | Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Aenean commodo ligula eget dolor. Aenean massa. Cum sociis natoque penatibus et magnis dis parturient montes, nascetur ridiculus mus. Donec quam felis, ultricies nec, pellentesque eu, pretium quis, sem. | 07/08/1940

<ScrollView direction="horizontal" shadowSize="100px"> <Table columns={[ { label: 'ID', name: 'id', }, { format: row => ( <span style={{ whiteSpace: 'nowrap' }}>{row.name}</span> ), label: 'Name', name: 'name', }, { format: row => ( <span style={{ whiteSpace: 'nowrap' }}>{row.note}</span> ), label: 'Note', name: 'note', }, { format: row => row.dateOfBirth.toLocaleDateString('en-GB'), label: 'Date of birth', name: 'dateOfBirth', }, ]} rows={[ { dateOfBirth: new Date(1940, 10, 9), id: 1, name: 'John Lennon', note: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' + 'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' + 'natoque penatibus et magnis dis parturient montes, nascetur ' + 'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' + 'eu, pretium quis, sem.', }, { dateOfBirth: new Date(1942, 6, 18), id: 2, name: 'Paul McCartney', note: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' + 'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' + 'natoque penatibus et magnis dis parturient montes, nascetur ' + 'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' + 'eu, pretium quis, sem.', }, { dateOfBirth: new Date(1943, 2, 25), id: 3, name: 'George Harrison', note: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' + 'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' + 'natoque penatibus et magnis dis parturient montes, nascetur ' + 'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' + 'eu, pretium quis, sem.', }, { dateOfBirth: new Date(1940, 7, 7), id: 4, name: 'Richard Starkey (Ringo Starr)', note: 'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' + 'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' + 'natoque penatibus et magnis dis parturient montes, nascetur ' + 'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' + 'eu, pretium quis, sem.', }, ]} /> </ScrollView>

    <ScrollView direction="horizontal" shadowSize="100px">  <Table    columns={[      {        label: 'ID',        name: 'id',      },      {        format: row => (          <span style={{ whiteSpace: 'nowrap' }}>{row.name}</span>        ),        label: 'Name',        name: 'name',      },      {        format: row => (          <span style={{ whiteSpace: 'nowrap' }}>{row.note}</span>        ),        label: 'Note',        name: 'note',      },      {        format: row => row.dateOfBirth.toLocaleDateString('en-GB'),        label: 'Date of birth',        name: 'dateOfBirth',      },    ]}    rows={[      {        dateOfBirth: new Date(1940, 10, 9),        id: 1,        name: 'John Lennon',        note:          'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' +          'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' +          'natoque penatibus et magnis dis parturient montes, nascetur ' +          'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' +          'eu, pretium quis, sem.',      },      {        dateOfBirth: new Date(1942, 6, 18),        id: 2,        name: 'Paul McCartney',        note:          'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' +          'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' +          'natoque penatibus et magnis dis parturient montes, nascetur ' +          'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' +          'eu, pretium quis, sem.',      },      {        dateOfBirth: new Date(1943, 2, 25),        id: 3,        name: 'George Harrison',        note:          'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' +          'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' +          'natoque penatibus et magnis dis parturient montes, nascetur ' +          'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' +          'eu, pretium quis, sem.',      },      {        dateOfBirth: new Date(1940, 7, 7),        id: 4,        name: 'Richard Starkey (Ringo Starr)',        note:          'Lorem ipsum dolor sit amet, consectetuer adipiscing elit. ' +          'Aenean commodo ligula eget dolor. Aenean massa. Cum sociis ' +          'natoque penatibus et magnis dis parturient montes, nascetur ' +          'ridiculus mus. Donec quam felis, ultricies nec, pellentesque ' +          'eu, pretium quis, sem.',      },    ]}  /></ScrollView>

## Sortable Columns

The Table supports sorting indicators by adding a simple configuration.

⚠️ The Table component only provides necessary visual support for sorting. Aside from icons, you must provide the comparing functionality yourself if you aren't rendering already sorted data. The reason for this decision is that client often does not have access to the full dataset.

The following is an example of custom sorting function executed on the client.

ID | Name | Date of birth
--- | --- | ---
1 | John Lennon | 1940-11-08T22:00:00.000Z
2 | Paul McCartney | 1942-07-17T22:00:00.000Z
3 | George Harrison | 1943-03-24T23:00:00.000Z
4 | Richard Starkey (Ringo Starr) | 1940-08-06T22:00:00.000Z

() => { const [tableSortColumn, setTableSortColumn] = React.useState('id') const [tableSortDirection, setTableSortDirection] = React.useState('asc') const [rows, setRows] = React.useState([ { dateOfBirth: new Date(1940, 10, 9), id: 1, name: 'John Lennon', }, { dateOfBirth: new Date(1942, 6, 18), id: 2, name: 'Paul McCartney', }, { dateOfBirth: new Date(1943, 2, 25), id: 3, name: 'George Harrison', }, { dateOfBirth: new Date(1940, 7, 7), id: 4, name: 'Richard Starkey (Ringo Starr)', }, ]) const compare = (items, key, direction) => { const sortedItems = [...items] if (key === 'id' || key === 'dateOfBirth') { sortedItems.sort((a, b) => b[key] - a[key]) } else if (key === 'name') { sortedItems.sort((a, b) => { if (a.name < b.name) { return -1 } if (a.name > b.name) { return 1 } return 0 }) } return direction === 'desc' ? sortedItems.reverse() : sortedItems } const columns = [ { isSortable: true, label: 'ID', name: 'id', }, { isSortable: true, label: 'Name', name: 'name', }, { format: row => row.dateOfBirth.toISOString(), isSortable: true, label: 'Date of birth', name: 'dateOfBirth', }, ] return ( <Table columns={columns} rows={rows} sort={{ ascendingIcon: <Icon icon="up" />, changeHandler: (column, direction) => { setTableSortColumn(column) setTableSortDirection(direction === 'asc' ? 'desc' : 'asc') setRows(compare(rows, column, direction)) }, column: tableSortColumn, descendingIcon: <Icon icon="down" />, direction: tableSortDirection, }} /> ) }

    () => {  const [tableSortColumn, setTableSortColumn] = React.useState('id')  const [tableSortDirection, setTableSortDirection] = React.useState('asc')  const [rows, setRows] = React.useState([    {      dateOfBirth: new Date(1940, 10, 9),      id: 1,      name: 'John Lennon',    },    {      dateOfBirth: new Date(1942, 6, 18),      id: 2,      name: 'Paul McCartney',    },    {      dateOfBirth: new Date(1943, 2, 25),      id: 3,      name: 'George Harrison',    },    {      dateOfBirth: new Date(1940, 7, 7),      id: 4,      name: 'Richard Starkey (Ringo Starr)',    },  ])  const compare = (items, key, direction) => {    const sortedItems = [...items]    if (key === 'id' || key === 'dateOfBirth') {      sortedItems.sort((a, b) => b[key] - a[key])    } else if (key === 'name') {      sortedItems.sort((a, b) => {        if (a.name < b.name) {          return -1        }        if (a.name > b.name) {          return 1        }        return 0      })    }    return direction === 'desc' ? sortedItems.reverse() : sortedItems  }  const columns = [    {      isSortable: true,      label: 'ID',      name: 'id',    },    {      isSortable: true,      label: 'Name',      name: 'name',    },    {      format: row => row.dateOfBirth.toISOString(),      isSortable: true,      label: 'Date of birth',      name: 'dateOfBirth',    },  ]  return (    <Table      columns={columns}      rows={rows}      sort={{        ascendingIcon: <Icon icon="up" />,        changeHandler: (column, direction) => {          setTableSortColumn(column)          setTableSortDirection(direction === 'asc' ? 'desc' : 'asc')          setRows(compare(rows, column, direction))        },        column: tableSortColumn,        descendingIcon: <Icon icon="down" />,        direction: tableSortDirection,      }}    />  )}

## API

columns
Array<{ "format": "Function", "isSortable": "Boolean", "label": "string", "name": "string" }>
required
id
string
undefined
rows
Array<{ "id": "number │ string" }>
required
sort
{ "ascendingIcon": "node", "changeHandler": "Function", "column": "string", "descendingIcon": "node", "direction": "'asc' │ 'desc'" }
null

Next: TextArea →