React Table UI
Out-of-the-box React component build around headless React-Table library.
GitHub | NPM | Documentation | Demo
I have extensively used React-Table at work and was amazed by the sheer amount of options provided by the library to build a functional table/grid in React applications. With introduction of Hooks in React, the library moved to a headless approach where the logic was provided via hooks and plugins, allowing consumers/users could build their own UI around it.
The headless approach with plugins is great for experienced developers and companies with ample resources to figure out what exactly they need and how everything fits into the puzzle. This approach, though, gets problematic for novice users or developers with limited resources. The learning-curve could be high as integrating all plugins and features in an accessible and usable interface is a big challenge. Furthermore, it doesn’t help that the library does not provide type-declarations and community driven types needs careful composition.
So, I took it as a challenge to make a helper library for those developers who want to utilise the power of React-Table without putting in the work needed to get the first functional render.
The project is dedicated to the awesome work done at React-Table by Tanner Linsley as it wouldn’t have been possible without his great library. I have personally use the library and wanted to contribute back to it somehow.
Overview
React-Table-UI is a library that provides a pre-developed UI that is integrated with (almost) all the plugins of provided by React-Table and adopts some sensible defaults for most use-cases. The React component is
- Features — The table natively supports following features which can be disabled if needed — sorting, column-filtering, global-search, sub-rows, sub-components, table & row actions, sticky headers and columns, pagination (client-side & server-side), multi-row select, column-resize, etc.
- Customisable — Everything in the Table can be customised like style & theme, actions, enabling/disabling features, locale & translations, custom components and behaviours.
- Sensible defaults — It is good to have customisations but it is great to have useful and sensible defaults. The library works out-of-the-box with just a dataset by leveraging the default settings.
- Extensible — The UI should support all plugins and extensions supported by parent library. (WIP)
- Type-safe — The library is built with TypeScript and provides a nice and safe developer experience with in-line documentation for all options. The API documentation is also available online for an overview.
- Accessible — The table component rendered tries to be follow accessibility guidelines for web and provide option for keyboard-navigation (WIP).
- Responsive — The component resizes and rearranges itself when used in Mobile or Desktop setting.
- Beautiful — Beauty is subjective, but I hope the base table provided is soothing to eyes and usable without any customisations. Though it can be completely changed with style/theme options provided or overriding CSS.
Custom components can be provided to override default components like InputField, Button, Checkbox and more if you are already have some existing components that are used in your application (WIP). - Localised — Numbers and dates can be localised by just provided the locale option, though browser locale acts as the default. The default English-text can be easily translated to your choosing by providing translated values for specific word-keys.
- Transparent — The library makes it easier to access the inner-workings and state changes with simple callbacks or refs, so every thing is transparent and can be connected to outside triggers and actions.
Many things are still “work-in-progress” as more and more developers join-in and convey what kind of customisation (and defaults) should be exposed for better development-experience.
Get started
The package size for production usage (with styles and without types) is ~36 KB (unzipped). The ~200 KB size of the complete package contains helpful TypeScript typings that makes using React-Table-UI a bliss.
Install package
First, the package/library must be installed locally as dependency. It will install a copy of react-table
, @types/react-table
, and react-table-sticky
as dependencies. It requires react@16.8 || react@17
or above for Hooks support.
# NPM
npm install react-table-ui# Yarn
yarn add react-table-ui
Other optional package like @reach/menu-button
can be installed to use dropdown menus for actions if you don’t have your own implementation.
Setup types
This step is for TypeScript users only. Since React-Table depends on community driven types, it is important to configure and compose types correctly for the features being used in the table. React-Table-UI provides a precomposed type-declaration which needs to copied to your source (`src`) directory.
If the installation goes well, there must be a react-table-config.d.ts
file in your source (src
) directory, but if it isn’t, do one of the following to get it:
- [Preferred] Copy the file from your project’s node_modules (./node_modules/react-table-ui/dist/react-table-config.d.ts) to your source folder.
- [Fallback] Get the file from GitHub. It may not match the exact version of library that you are using. So you may have to look to correct version git-tag before copying the file.
The whole appeal of React-Table-UI is enriched with its TypeScript core. So all tutorials and examples will use TypeScript, but converting them to JavaScript shouldn’t be too much trouble.
Import the package
Package exports single component as default which can be imported by any name. You can use ReactTableUI
, Table
, or any name that suits you.
import ReactTableUI from 'react-table-ui';
All other exports of the package are TypeScript types which will be useful in various scenarios. Import them separately as per requirement from primary component import is recommended.
import type { DataType, TableInstance, ... } from 'react-table-ui';
A list of exported types is available on API documentation.
DataType setup
Since we are dealing with TypeScript and types, it is important for the Table to know what type of data will be processed and displayed. The library provides a base-type called DataType
which can be extended to create the your own Data Type which represents the dataset provided to the table.
For example: Creating a table of users will require a dataset of users, where each user (or row) can be represented by User
type/interface.
import type { DataType } from 'react-table-ui';interface User extends DataType {
name: string;
age: number;
}
The newly created User
interface must be used whenever Table expects a type-parameter. This will allow library to provide better tooling and error-handling when composing actions and behaviours.
Procuring dataset
A dataset is only required piece of information required for React-Table-UI to work. Depending on use case, the dataset could be static or dynamic. Though, 99% of the time, it will be dynamic data fetched from an API or read from a file/database.
- Example for static data (It can be defined in global or local scope)
const data: User[] = [
{ name: 'Abc Xyx', age: 20 },
{ name: 'Def Uvw', age: 25 },
{ name: 'Ghi Rst', age: 23 },
{ name: 'Jklm Nopq', age: 30 },
];
- Example for dynamic data (needs to be in local scope as it needs to be memo-ised by React). The data fetched by using hooks provided from “react-query”, “apollo-react” or other libraries provide memo-ised data, but they still might need manipulation to fit the defined type-interface.
Furthermore, the dynamic data can be server-side paginated (will be discussed later).
import type { FC } from 'react';
import useFetchData from '...'const App: FC = () => {
...
const data: User[] = useFetchData<User>()
...}export default App
Compose — Basic/Static example
To begin with, compose a very basic table with minimum input and customisations. The table will create column headers from data keys.
import ReactTableUI from 'react-table-ui';
import { useMemo } from 'react';
import { render } from 'react-dom';
import type { FC } from 'react';
import type { DataType } from 'react-table-ui';interface User extends DataType {
name: string;
age: number;
}const App: FC = () => {
const data: User[] = useMemo(() => [
{ name: 'Abc Xyx', age: 20 },
{ name: 'Def Uvw', age: 25 },
{ name: 'Ghi Rst', age: 23 },
{ name: 'Jklm Nopq', age: 30 },
], []);
return <ReactTableUI data={data} title="Users" />;
}render(<App />, document.body);
Examples
- Server pagination — https://codesandbox.io/s/react-table-ui-basic-8ukxd
- More coming soon…
React Table UI is a library under development. Please use and test it.
Raise some issues, recommend some ideas and contribute if possible.
Looking forward to your input.