Skip to Content
🎉 Coral x Panda has been released 🎉 Read the Migration Guide

useTable

This hook provides functionality to filter, sort, paginate and select rows of data for a Table component. This hook takes over the state management of the Table data and returns us a handful of variables to use.

Basic Usage

import { useTable } from '@krakentech/coral'; const { data } = useTable({ data: initialData }); <Table data={data} columns={columns} />
NameAgeAddressEmail address
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com
Name 3423 Street Road, Town, City, Postcodename3.152@myemail.org
Name 4424 Street Road, Town, City, Postcodename4.834@webmail.net
Name 5425 Street Road, Town, City, Postcodename5.611@example.com
Name 6426 Street Road, Town, City, Postcodename6.299@testmail.com

Now that we’ve provided the Table component with the data given back to us from the hook, it’ll give us back a handful of helpful variables to play with.

Filtering

It’s possible to use a Coral TextField component to filter the results of a Table.

const initialData: TableColumnData[] = [ { key: '1', name: 'Name 1', address: '1 Street Road, Town, City, Postcode', age: 65, }, ... ]; const columns: TableColumn[] = [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age', align: 'center', }, { title: 'Address', key: 'address', align: 'right' }, ]; const { data, filterValue, handleFilterChange } = useTable({ data: initialData, }); <Stack flexDirection="column" gap="lg"> <TextField label="Filter table" startIcon={<IconSearch size={16} />} value={filterValue} onChange={handleFilterChange} /> <Table data={data} columns={columns} /> </Stack>
NameAgeAddressEmail address
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com
Name 3423 Street Road, Town, City, Postcodename3.152@myemail.org
Name 4424 Street Road, Town, City, Postcodename4.834@webmail.net
Name 5425 Street Road, Town, City, Postcodename5.611@example.com
Name 6426 Street Road, Town, City, Postcodename6.299@testmail.com

Sort

It’s possible to sort each column in a Table, alphabetically ascending / descending, by clicking on the column header. Passing sortable: true to the column configuration will enable this feature.

const initialData: TableColumnData[] = [ { key: '1', name: 'Name 1', address: '1 Street Road, Town, City, Postcode', age: 65, }, ... ]; const columns: TableColumn[] = [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age', sortable: true }, { title: 'Address', key: 'address' }, ]; const { data, sortValue, handleSortChange } = useTable({ data: initialData, }); <Table data={data} columns={columns} sortValue={sortValue} handleSortChange={handleSortChange} />
NameAddressEmail address
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com
Name 3423 Street Road, Town, City, Postcodename3.152@myemail.org
Name 4424 Street Road, Town, City, Postcodename4.834@webmail.net
Name 5425 Street Road, Town, City, Postcodename5.611@example.com
Name 6426 Street Road, Town, City, Postcodename6.299@testmail.com

Custom Sort

You can provide a custom sorting function using the compareFn parameter. This allows you to define your own sorting logic.

For example, you could sort by numbers within a string as shown with the address column below.

const initialData: TableColumnData[] = [ { key: '1', name: 'Name 1', address: '1 Street Road, Town, City, Postcode', age: 65, }, ... ]; const columns: TableColumn[] = [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age', sortable: true }, { title: 'Address', key: 'address', sortable: true }, ]; const customCompareFn = ( valueA: any, valueB: any, sortOrder: 'asc' | 'desc' | 'none' = 'none' ) => { if (valueA == null || valueB == null) { return valueA == null ? (valueB == null ? 0 : 1) : -1; } const extractLeadingNumber = (str: string) => Number(str.match(/^(-?\d+)/)?.[0] ?? NaN); const [strA, strB] = [String(valueA).trim(), String(valueB).trim()]; const [numA, numB] = [extractLeadingNumber(strA), extractLeadingNumber(strB)]; if (isNaN(numA) && isNaN(numB)) { return sortOrder === 'asc' ? strA.localeCompare(strB) : strB.localeCompare(strA); } if (isNaN(numA)) {return sortOrder === 'asc' ? 1 : -1} if (isNaN(numB)) {return sortOrder === 'asc' ? -1 : 1} return sortOrder === 'asc' ? numA - numB : numB - numA; }; const { data, sortValue, handleSortChange } = useTable({ data: initialData, compareFn: customCompareFn, }); <Table data={data} columns={columns} sortValue={sortValue} handleSortChange={handleSortChange} />
Name
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com
Name 3423 Street Road, Town, City, Postcodename3.152@myemail.org
Name 4424 Street Road, Town, City, Postcodename4.834@webmail.net
Name 5425 Street Road, Town, City, Postcodename5.611@example.com
Name 6426 Street Road, Town, City, Postcodename6.299@testmail.com

Paginate

It’s possible to create pagination for a Table using a combination of useTable, plus other Coral components like Stack, Select, Button and Typography.

const initialData: TableColumnData[] = [ { key: '1', name: 'Name 1', address: '1 Street Road, Town, City, Postcode', age: 65, }, ... ]; const columns: TableColumn[] = [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age' }, { title: 'Address', key: 'address' }, ]; const { data, currentPage, setNextPage, setPreviousPage, prevPageDisabled, nextPageDisabled, pageSelectValues, handleSelectChange, totalPages, } = useTable({ data: initialData, perPage: 2, }); <Stack direction="vertical" gap="lg"> <Table data={data} columns={columns} /> <Stack gap="lg" alignItems="center"> <Button onClick={() => setPreviousPage()} size="small" color="secondary" disabled={prevPageDisabled} > <IconChevronLeft /> </Button> <Typography>Page</Typography> <Select label="Page" values={pageSelectValues} value={{ label: currentPage.toString(), value: currentPage, }} onChange={handleSelectChange} /> <Typography>of {totalPages}</Typography> <Button onClick={() => setNextPage()} size="small" color="secondary" disabled={nextPageDisabled} > <IconChevronRight /> </Button> </Stack> </Stack>
NameAgeAddressEmail address
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com

Page

of 1

Selectable rows

It’s possible to select all rows in the Table, or select individual rows.

const initialData: TableColumnData[] = [ { key: '1', name: 'Name 1', address: '1 Street Road, Town, City, Postcode', age: 65, }, ... ]; const columns: TableColumn[] = [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age' }, { title: 'Address', key: 'address' }, ]; const { data, rowsSelected, allRowsSelected, handleRowSelected, handleAllRowsSelected, } = useTable({ data: initialData, }); <Table data={data} columns={columns} rowsSelectable rowsSelected={rowsSelected} allRowsSelected={allRowsSelected} handleRowSelected={handleRowSelected} handleAllRowsSelected={handleAllRowsSelected} />
NameAgeAddressEmail address
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com
Name 3423 Street Road, Town, City, Postcodename3.152@myemail.org
Name 4424 Street Road, Town, City, Postcodename4.834@webmail.net
Name 5425 Street Road, Town, City, Postcodename5.611@example.com
Name 6426 Street Road, Town, City, Postcodename6.299@testmail.com

Full Example

It’s possible to combine all of these features together to give the user as much flexibility as possible with the Table component.

const initialData: TableColumnData[] = [ { key: '1', name: 'Name 1', address: '1 Street Road, Town, City, Postcode', age: 65, }, ... ]; const columns: TableColumn[] = [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age', sortable: true }, { title: 'Address', key: 'address' }, ]; const { data, currentPage, setNextPage, totalPages, setPreviousPage, pageSelectValues, handleSelectChange, filterValue, handleFilterChange, prevPageDisabled, nextPageDisabled, handleSortChange, sortValue, handleRowSelected, handleAllRowsSelected, allRowsSelected, rowsSelected, } = useTable({ data: initialData, perPage: 4, }); <Stack direction="vertical" gap="lg"> <TextField label="Filter table" startIcon={<IconSearch size={16} />} value={filterValue} onChange={handleFilterChange} /> <Table data={data} columns={columns} handleSortChange={handleSortChange} sortValue={sortValue} rowsSelectable handleAllRowsSelected={handleAllRowsSelected} handleRowSelected={handleRowSelected} rowsSelected={rowsSelected} allRowsSelected={allRowsSelected} /> <Stack gap="lg" alignItems="center"> <Button onClick={() => setPreviousPage()} size="small" color="secondary" disabled={prevPageDisabled} > <IconChevronLeft /> </Button> <Typography>Page</Typography> <Select label="Page" values={pageSelectValues} value={{ label: currentPage.toString(), value: currentPage, }} onChange={handleSelectChange} /> <Typography>of {totalPages}</Typography> <Button onClick={() => setNextPage()} size="small" color="secondary" disabled={nextPageDisabled} > <IconChevronRight /> </Button> </Stack> </Stack>
NameAddressEmail address
Name 1321 Street Road, Town, City, Postcodename1.483@testmail.com
Name 2422 Street Road, Town, City, Postcodename2.927@example.com
Name 3423 Street Road, Town, City, Postcodename3.152@myemail.org
Name 4424 Street Road, Town, City, Postcodename4.834@webmail.net

Page

of 1

Full API

Arguments

NameDescriptiontypeDefault valueRequired
dataThe initial data given by the consumerTableColumnData[]undefinedtrue
columnsThe initial column data given by the consumerTableColumn[]undefinedfalse
columnVisibilityAn object listing whether columns should be visible or notRecord<string, boolean>{}false
perPageHow many results to show per paginated pagenumber100false
compareFnA custom compare function for sorting(a: any, b: any, sortOrder?: 'asc' , 'desc' , 'none') => numberundefinedfalse

Return

NameDescriptiontype
dataThe data to use with the Table data propTableColumnData[]
columnsThe column data to use with the Table columns propTableColumn[]
currentPageThe current page of paginated data being displayednumber
setCurrentPageA callback function that sets the current page when paginated(page: number) => void
setNextPageA callback function that sets pagination to the next page if there is one() => void
setPreviousPageA callback function that sets pagination to the previous page if there is one() => void
nextPageDisabledA boolean to tell if there is a next page available or notboolean
prevPageDisabledA boolean to tell if there is a previous page available or notboolean
totalPagesThe total number of pages of datanumber
pageSelectValuesA helper variable to be used directly with the <Select values={}> propSelectOption[]
handleSelectChangeA helper variable to be used directly with the <Select onChange={}> propSelectProps['onChange']
filterValueA helper variable to be used directly with the TextField value={} propstring
handleFilterChangeA helper variable to be used directly with the TextField onChange={} prop(e: React.ChangeEvent<HTMLInputElement>) => void
handleSortChangeA callback function to handle sorting(columnKey: any) => void
sortValueThe current sort valueSortValueStateType
handleRowSelectedA callback function to handle selecting a single row(rowIndex: number / string, isChecked: boolean) => void
handleAllRowsSelectedA callback function to handle selecting all rowsCheckboxProps['onChange']
allRowsSelectedAre all rows selected or notboolean
rowsSelectedAn array of all the currently selected rowsTableColumnData[]
Last updated on