<SortedTableInHtmlTable />
In this demo, we showcase the SortedTableInHtmlTable
component, a more complex and interactive way to render a TinyBase Table
.
Rather than building the whole demo and boilerplate from scratch, we're making changes to the <TableInHtmlTable /> demo to support this new component.
Set Up
We switch out the TableInHtmlTable
component and import the SortedTableInHtmlTable
component instead.
-const {TableInHtmlTable} = TinyBaseUiReactDom;
+const {SortedTableInHtmlTable} = TinyBaseUiReactDom;
This component is best showcased with a larger data set, so we load up movies instead of genres:
useMemo(async () => {
- await loadTable(store, 'genres');
+ await loadTable(store, 'movies');
setIsLoading(false);
}, []);
Using the SortedTableInHtmlTable
Component
The SortedTableInHtmlTable
component is similar to the TableInHtmlTable
component, requiring at least the Table
Id
:
const Body = () => {
return (
<>- <TableInHtmlTable tableId='genres' />
- <TableInHtmlTable tableId='genres' headerRow={false} idColumn={false} />
- <TableInHtmlTable tableId='genres' customCells={customCells} />
+ <SortedTableInHtmlTable
+ tableId='movies'
+ />
</>
);
};
Take a look at the SortedTableInHtmlTableProps
type and HtmlTableProps
type to see all the ways in which you can configure this component. We're going to use a few here.
Firstly, since the Table
is very wide (and contains a lengthy description), we will first explicitly set the Cell
Ids
we want to display:
-const customCells = {name: {label: 'Name', component: DictionaryCell}};
+const customCells = {name: 'Name', year: 'Year', rating: 'Rating'};
(This configuration can simply be an array of the Cell
Ids
, an object with Cell
Id
as key and label as value (like this), or an object made up of CustomCell
objects. See the HtmlTableProps
type for more details.)
<SortedTableInHtmlTable
tableId='movies'
+ customCells={customCells}
/>
The SortedTableInHtmlTableProps
component, much like the getSortedRowIds
method, can take props to indicate how the sorting should work. cellId
indicates which Cell
to use to sort on, and descending
indicates the direction. We can sort the movies by rating accordingly:
<SortedTableInHtmlTable
tableId='movies'
customCells={customCells}
+ cellId='rating'
+ descending={true}
+ limit={7}
/>
Note that we can also use the limit
prop to paginate the data.
The component automatically adds two classes to the heading of the column that is being used for the sorting. We can add styling to show which column it is, and a small arrow to indicate the direction:
th.sorted {
background: #ddd;
}
Interactivity
The SortedTableInHtmlTable
component can be made to be interactive. By adding the sortOnClick flag prop, you can make it such that users can click on the column headings to change the sorting:
<SortedTableInHtmlTable
tableId='movies'
customCells={customCells}
cellId='rating'
descending={true}
limit={7}
+ sortOnClick={true}
/>
As this means the table's content can change, the columns might adjust their widths and the table jumps around. We can quickly fix this by hinting about the widths of the header row so that the layout is stable:
thead th {
width: 5rem;
&:nth-of-type(2) {
width: 28rem;
}
}
Nice! It's still a simple table, but we have some useful interactivity out of the box.
We can also add pagination controls, by adding the paginator
prop. This either takes true
to enable the default SortedTablePaginator
component, or a paginator component of your own design that accepts SortedTablePaginatorProps
.
<SortedTableInHtmlTable
tableId='movies'
customCells={customCells}
cellId='rating'
descending={true}
limit={7}
sortOnClick={true}
+ paginator={true}
/>
This places the pagination controls in the <caption>
element of the <table>
, and you can use CSS to position and style it. We are removing the default text from
table caption {
caption-side: top;
text-align: left;
margin-bottom: 1rem;
button {
margin-right: 0.5rem;
}
}
As well as rendering raw Tables
from a Store
, we can do the same for each Slice
of an Indexes
object - as you'll see in the next <SliceInHtmlTable /> demo.