Skip to content
/ table Public

πŸ€– Headless UI for building powerful tables & datagrids for TS/JS - React-Table, Vue-Table, Solid-Table, Svelte-Table

License

Notifications You must be signed in to change notification settings

TanStack/table

This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Repository files navigation

react-table

react-table

A fast, lightweight, opinionated table and datagrid built on React

Build Status react-table on Slack

Features

  • Lightweight at 3kb (and just 2kb more for styles)
  • Fully customizable JSX and callbacks for everything
  • Supports both Client-side & Server-side pagination and sorting
  • Minimal design & easily themeable

Table of Contents

Installation

$ npm install react-table

Example

import ReactTable from 'react-table'

const data = [{
  name: 'Tanner Linsley',
  age: 26,
  friend: {
    name: 'Jason Maurer',
    age: 23,
  }
},{
  ...
}]

const columns = [{
  header: 'Name',
  accessor: 'name',
}, {
  header: 'Age',
  accessor: 'age'
}, {
  header: 'Friend Name',
  accessor: d => d.friend.name
}, {
  header: 'Friend Age',
  accessor: 'friend.age'
}]

<ReactTable
  data=[data]
  columns={columns}
/>

Data

Every React-Table instance requires you to set the data prop. To use client-side data, simply pass the data prop anything that resembles an array or object. Client-side filtering and pagination is built in, and your table will update gracefully if you change any props. Server-side data is also supported.

Default Props

These are the default props for the main react component <ReactTable />

{
  // General
  pageSize: 20,
  minRows: 0, // Ensure this many rows are always rendered, regardless of rows on page

  // Text
  previousText: 'Previous',
  nextText: 'Next'

  // Classes
  className: '-striped -highlight', // The most top level className for the component
  tableClassName: '', // ClassName for the `table` element
  theadClassName: '', // ClassName for the `thead` element
  tbodyClassName: '', // ClassName for the `tbody` element
  trClassName: '', // ClassName for all `tr` elements
  trClassCallback: row => null, // A call back to dynamically add classes (via the classnames module) to a row element
  paginationClassName: '' // ClassName for `pagination` element
  // Styles
  style: {}, // Main style object for the component
  tableStyle: {}, // style object for the `table` component
  theadStyle: {}, // style object for the `thead` component
  tbodyStyle: {}, // style object for the `tbody` component
  trStyle: {}, // style object for the `tr` component
  trStyleCallback: row => {}, // A call back to dynamically add styles to a row element
  thStyle: {}, // style object for the `th` component
  tdStyle: {}, // style object for the `td` component
  paginationStyle: {}, // style object for the `paginination` component
}

You can easily override the core defaults like so:

import { ReactTableDefaults } from 'react-table'

Object.assign(ReactTableDefaults, {
  pageSize: 10,
  minRows: 3,
  // etc...
})

Or just define them on the component per-instance

<ReactTable
  pageSize={10}
  minRows={3}
  // etc...
  />

Columns

Every React-Table instance requires a columns prop, which is an array of objects containing the following properties

[{
  // General
  accessor: 'propertyName' or Accessor eg. (row) => row.propertyName,
  id: 'myProperty', // Conditional - A unique ID is required if the accessor is not a string or if you would like to override the column name used in server-side calls
  sortable: true,
  sort: 'asc' or 'desc',
  show: true,
  minWidth: Number // Allows the column to flex above this minimum amount

  // Cell Options
  className: '', // Set the classname of the `td` element of the column
  style: {}, // Set the style of the `td` element of the column
  innerClassName: '', // Set the classname of the `.-td-inner` element of the column
  innerStyle: {}, // Set the style of the `.-td-inner` element of the column
  render: JSX eg. ({value, rowValues, row, index, viewIndex}) => <span>{value}</span>, // Provide a JSX element or stateless function to render whatever you want as the column's cell with access to the entire row
    // value == the accessed value of the column
    // rowValues == an object of all of the accessed values for the row
    // row == the original row of data supplied to the table
    // index == the original index of the data supplied to the table
    // viewIndex == the index of the row in the current page

  // Header & HeaderGroup Options
  header: 'Header Name' or JSX eg. ({data, column}) => <div>Header Name</div>,
  headerClassName: '', // Set the classname of the `th` element of the column
  headerStyle: {}, // Set the style of the `th` element of the column
  headerInnerClassName: '', // Set the classname of the `.-th-inner` element of the column
  headerInnerStyle: {}, // Set the style of the `.th-inner` element of the column

  // Header Groups only
  columns: [...] // See Header Groups section below

}]

Styles

React-table is built to be dropped into existing applications or styled from the ground up, but if you'd like a decent starting point, you can optionally include our default theme react-table.css. We think it looks great, honestly :)

Header Groups

To group columns with another header column, just nest your columns in a header column like so:

const columns = [{
  header: 'Favorites',
  columns: [{
    header: 'Color',
    accessor: 'favorites.color'
  }, {
    header: 'Food',
    accessor: 'favorites.food'
  } {
    header: 'Actor',
    accessor: 'favorites.actor'
  }]
}]

Server-side Data

If you want to handle pagination, and sorting on the server, react-table makes it easy on you.

  1. Feed React Table data from somewhere dynamic. eg. state, a redux store, etc...
  2. Add manual as a prop. This informs React Table that you'll be handling sorting and pagination server-side
  3. Subscribe to the onChange prop. This function is called any time sorting or pagination is changed by the user
  4. In the onChange callback, request your data using the provided information in the params of the function (state and instance)
  5. Update your data with the rows to be displayed
  6. Optionally set how many pages there are total
<ReactTable
  ...
  data={this.state.data} // should default to []
  pages={this.state.pages} // should default to -1 (which means we don't know how many pages we have)
  manual // informs React Table that you'll be handling sorting and pagination server-side
  onChange={(state, instance) => {
    Axios.post('mysite.com/data', {
      page: state.page,
      pageSize: state.pageSize,
      sorting: state.sorting
    })
      .then((res) => {
        this.setState({
          data: res.data.rows,
          pages: res.data.pages
        })
      })
  }}
/>

For a detailed example, take a peek at our async table mockup

Multi-Sort

When clicking on a column header, hold shift to multi-sort! You can toggle ascending descending and none for multi-sort columns. Clicking on a header without holding shift will clear the multi-sort and replace it with the single sort of that column. It's quite handy!

Component Overrides

Though we wouldn't suggest it, react-table has the ability to change the core componentry it used to render it's table. You can do so by assigning a react component to it's corresponding global prop, or on a one-off basis like so:

// Change the global default
import { ReactTableDefaults } from 'react-table'
Object.assign(ReactTableDefaults, {
  tableComponent: Component,
  theadComponent: Component,
  tbodyComponent: Component,
  trComponent: Component,
  thComponent: Component,
  tdComponent: Component,
  paginationComponent: Component,
  previousComponent: Component,
  nextComponent: Component,
  loadingComponent: Component
})

// Or change per instance
<ReactTable
  tableComponent={Component},
  theadComponent={Component},
  // etc...
  />

If you choose to change the core components React-Table uses to render, you must make sure your components support and utilized all of the neeeded features for that component to work properly. For a broad reference on how to do this, investigate the source for the component you wish to replace.

Contributing

To suggest a feature, create an issue if it does not already exist. If you would like to help develop a suggested feature follow these steps:

  • Fork this repo
  • npm install
  • npm watch
  • Implement your changes to files in the src/ directory
  • Submit PR for review

If you would like to preview your changes, you can link and utilize the example like so:

  • npm link
  • cd example
  • npm install
  • npm link react-table
  • npm watch
  • Make changes to the example in src/screens/index.js if needed
  • View changes at localhost:8000