@atom-learning/components 2.5.1 → 2.6.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +25 -2
- package/dist/components/data-table/DataTable.d.ts +71 -0
- package/dist/components/data-table/DataTable.js +1 -0
- package/dist/components/data-table/DataTableBody.d.ts +5 -0
- package/dist/components/data-table/DataTableBody.js +1 -0
- package/dist/components/data-table/DataTableContext.d.ts +20 -0
- package/dist/components/data-table/DataTableContext.js +1 -0
- package/dist/components/data-table/DataTableDataCell.d.ts +7 -0
- package/dist/components/data-table/DataTableDataCell.js +1 -0
- package/dist/components/data-table/DataTableGlobalFilter.d.ts +8 -0
- package/dist/components/data-table/DataTableGlobalFilter.js +1 -0
- package/dist/components/data-table/DataTableHead.d.ts +7 -0
- package/dist/components/data-table/DataTableHead.js +1 -0
- package/dist/components/data-table/DataTableHeaderCell.d.ts +8 -0
- package/dist/components/data-table/DataTableHeaderCell.js +1 -0
- package/dist/components/data-table/DataTableRow.d.ts +8 -0
- package/dist/components/data-table/DataTableRow.js +1 -0
- package/dist/components/data-table/DataTableTable.d.ts +6 -0
- package/dist/components/data-table/DataTableTable.js +1 -0
- package/dist/components/data-table/index.d.ts +2 -0
- package/dist/components/data-table/pagination/Pagination.d.ts +273 -0
- package/dist/components/data-table/pagination/Pagination.js +1 -0
- package/dist/components/data-table/pagination/PaginationButtons.d.ts +21 -0
- package/dist/components/data-table/pagination/PaginationButtons.js +1 -0
- package/dist/components/data-table/pagination/index.d.ts +1 -0
- package/dist/components/index.d.ts +1 -0
- package/dist/components/select/Select.js +1 -1
- package/dist/components/table/TableHeader.d.ts +6 -1
- package/dist/components/table/TableHeader.js +1 -1
- package/dist/docgen.json +1 -1
- package/dist/docs/DataTable.mdx +160 -0
- package/dist/index.cjs.js +1 -1
- package/dist/index.js +1 -1
- package/dist/utilities/optionally-visually-hidden-container/OptionallyVisuallyHiddenContainer.d.ts +4 -0
- package/dist/utilities/optionally-visually-hidden-container/OptionallyVisuallyHiddenContainer.js +1 -0
- package/dist/utilities/optionally-visually-hidden-container/index.d.ts +1 -0
- package/package.json +2 -1
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { DataTableExample } from './DataTableExample'
|
|
2
|
+
|
|
3
|
+
---
|
|
4
|
+
|
|
5
|
+
title: DataTable
|
|
6
|
+
component: DataTable, DataTable.Table, DataTable.Head, DataTable.Header, DataTable.Body, DataTable.Row, DataTable.DataCell
|
|
7
|
+
description: Displays tabular data with features such as sorting and pagination
|
|
8
|
+
category: Content
|
|
9
|
+
|
|
10
|
+
---
|
|
11
|
+
|
|
12
|
+
`DataTable` provides complex features for tables, like sorting and pagination. It's built around the `@tanstack/react-table` library and exposes the `table` state from that library directly. All util functions from the library are also compatible with `DataTable`. It's worth a good read of [`@tanstack/react-table`'s documentation](https://tanstack.com/table/v8/docs/guide/introduction) too, since we won't be repeating much of it here.
|
|
13
|
+
|
|
14
|
+
`DataTable` and its subcomponents are designed to be very simple to use. This is achieved by abstracting complex and/or boilerplate logic away from the consumer. For example, `DataTable.Pagination` can be dropped inside a `DataTable` to paginate the table's data without the need to add any configuration on `DataTable` itself. This is achieved by having `DataTable.Pagination` itself use the `applyPagination` and `setPageSize` methods exposed by `useDataTable` on its first render. This pattern should be replicated wherever practical to maintain the best developer experience possible.
|
|
15
|
+
|
|
16
|
+
## Anatomy
|
|
17
|
+
|
|
18
|
+
The root `DataTable` component manages the table's state and exposes it via the React Context API. This state can be accessed by any child components by calling `useDataTable`.
|
|
19
|
+
|
|
20
|
+
Other `DataTable` components call `useDataTable` and provide useful default implementations for common patterns. For example, `DataTable.Head` will render a header for every column defined in the parent `DataTable`. `DataTable.Body` will render a row for every data item. `DataTable.Table` combines both `DataTable.Head` and `DataTable.Body`.
|
|
21
|
+
|
|
22
|
+
### Using defaults vs using rolling your own
|
|
23
|
+
|
|
24
|
+
Here's a simple config for some table data and columns.
|
|
25
|
+
|
|
26
|
+
```tsx
|
|
27
|
+
import { createColumnHelper } from '@tanstack/react-table'
|
|
28
|
+
|
|
29
|
+
const columnHelper = createColumnHelper<{
|
|
30
|
+
name: string
|
|
31
|
+
hobby: string
|
|
32
|
+
}>()
|
|
33
|
+
|
|
34
|
+
const columns = [
|
|
35
|
+
columnHelper.accessor('name', {
|
|
36
|
+
cell: (info) => info.getValue()
|
|
37
|
+
}),
|
|
38
|
+
columnHelper.accessor('hobby', {
|
|
39
|
+
cell: (info) => info.getValue()
|
|
40
|
+
}),
|
|
41
|
+
// Columns created with columnHelper.display won't be sortable.
|
|
42
|
+
// They need a header to be set manually since they're not just reading
|
|
43
|
+
// a property from the row.
|
|
44
|
+
columnHelper.display({
|
|
45
|
+
cell: (info) => <button>do something</button>,
|
|
46
|
+
header: 'Actions'
|
|
47
|
+
})
|
|
48
|
+
]
|
|
49
|
+
|
|
50
|
+
const data = [
|
|
51
|
+
{ name: 'chrissy', hobby: 'bare-knuckle boxing' },
|
|
52
|
+
{ name: 'agatha', hobby: 'crossfit' },
|
|
53
|
+
{ name: 'betty', hobby: 'acting' }
|
|
54
|
+
]
|
|
55
|
+
```
|
|
56
|
+
|
|
57
|
+
There are basically two ways to use `DataTable` to build a table from this config. The first uses the highest-level components that are bundled into `DataTable` to provide useful default behaviours with minimal code. The second directly accesses the state from `DataTable` and combines it with the `Table` UI components to achieve the same thing. This demonstrates how you could create more custom table UIs without the need to extend the high-level components.
|
|
58
|
+
|
|
59
|
+
#### With Defaults
|
|
60
|
+
|
|
61
|
+
The following two examples are exactly equivalent in their output. The second example is included to demonstrate what `DataTable`'s subcomponents do: they bundle up UI components and logic to provide useful defaults. They exist at various levels of abstraction, e.g. `DataTable.Table` renders `DataTable.Body`, which renders `DataTable.Row`. This means that you can use whichever component provides useful functionality for your use case while still being low-level enough to let you combine it with your own custom logic.
|
|
62
|
+
|
|
63
|
+
```tsx
|
|
64
|
+
<DataTable columns={columns} data={data}>
|
|
65
|
+
<DataTable.Table sortable css={{mb: '$4'}}/>
|
|
66
|
+
<DataTable.Pagination pageSize={5} />
|
|
67
|
+
</DataTable>
|
|
68
|
+
|
|
69
|
+
<DataTable columns={columns} data={data}>
|
|
70
|
+
<Table>
|
|
71
|
+
<DataTable.Head sortable />
|
|
72
|
+
<DataTable.Body />
|
|
73
|
+
</Table>
|
|
74
|
+
<DataTable.Pagination pageSize={5} />
|
|
75
|
+
</DataTable>
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
### Rolling your own
|
|
79
|
+
|
|
80
|
+
If you need more flexibility than the default implementations provide, you can roll your own. Note that you can mix and match default implementations with your own. For example you could write your own table head implementation but use `DataTable.Body` for the body.
|
|
81
|
+
|
|
82
|
+
Note also that `useDataTable` can only be called by a child component of `DataTable`. In a real example, you'll probably have a separate named component which makes the `useDataTable` call, because if you're not using the defaults as above then you probably have some complex logic involved. In this example we've got an inline child component for simplicity.
|
|
83
|
+
|
|
84
|
+
```tsx
|
|
85
|
+
<DataTable columns={columns} data={data}>
|
|
86
|
+
{() => {
|
|
87
|
+
const { getHeaderGroups, getRowModel, setGlobalFilter, getState } =
|
|
88
|
+
useDataTable()
|
|
89
|
+
const { globalFilter } = getState()
|
|
90
|
+
|
|
91
|
+
return (
|
|
92
|
+
<>
|
|
93
|
+
<Label htmlFor="search">User search</Label>
|
|
94
|
+
<SearchInput
|
|
95
|
+
name="search"
|
|
96
|
+
value={globalFilter}
|
|
97
|
+
onChange={setGlobalFilter}
|
|
98
|
+
/>
|
|
99
|
+
<Table>
|
|
100
|
+
<Table.Header>
|
|
101
|
+
{getHeaderGroups().map((headerGroup) => (
|
|
102
|
+
<Table.Row key={headerGroup.id}>
|
|
103
|
+
{headerGroup.headers.map((header) => {
|
|
104
|
+
const sort = header.column.getIsSorted()
|
|
105
|
+
return (
|
|
106
|
+
<Table.HeaderCell
|
|
107
|
+
onClick={header.column.getToggleSortingHandler()}
|
|
108
|
+
{...props}
|
|
109
|
+
>
|
|
110
|
+
{flexRender(
|
|
111
|
+
header.column.columnDef.header,
|
|
112
|
+
header.getContext()
|
|
113
|
+
)}
|
|
114
|
+
{sort && { asc: '^', desc: 'v' }[sort as string]}
|
|
115
|
+
</Table.HeaderCell>
|
|
116
|
+
)
|
|
117
|
+
})}
|
|
118
|
+
</Table.Row>
|
|
119
|
+
))}
|
|
120
|
+
</Table.Header>
|
|
121
|
+
<Table.Body>
|
|
122
|
+
{getRowModel().rows.map((row) => (
|
|
123
|
+
<Table.Row>
|
|
124
|
+
{row.getVisibleCells().map((cell) => (
|
|
125
|
+
<Table.Cell key={cell.id}>
|
|
126
|
+
{flexRender(cell.column.columnDef.cell, cell.getContext())}
|
|
127
|
+
</Table.Cell>
|
|
128
|
+
))}
|
|
129
|
+
</Table.Row>
|
|
130
|
+
))}
|
|
131
|
+
</Table.Body>
|
|
132
|
+
</Table>
|
|
133
|
+
</>
|
|
134
|
+
// Then you could build your own pagination here too I guess? If you really wanted to?
|
|
135
|
+
)
|
|
136
|
+
}}
|
|
137
|
+
</DataTable>
|
|
138
|
+
```
|
|
139
|
+
|
|
140
|
+
## Features
|
|
141
|
+
|
|
142
|
+
### Search
|
|
143
|
+
|
|
144
|
+
`DataTable.Search` renders a search input that filters the whole table by matching the input against values from any table column.
|
|
145
|
+
|
|
146
|
+
### Sorting
|
|
147
|
+
|
|
148
|
+
A `DataTable`'s data can be sorted by default and can also be sortable by the user. These two options are independent of each other.
|
|
149
|
+
|
|
150
|
+
#### Default sorting
|
|
151
|
+
|
|
152
|
+
`DataTable` takes an optional `defaultSort` prop to configure the column and direction for the table's default sorting, e.g. `{column: 'name', direction: 'asc'}`
|
|
153
|
+
|
|
154
|
+
#### User sorting
|
|
155
|
+
|
|
156
|
+
If `DataTable`'s `isSortable` state is `true`, then `DataTable.Header` will be clickable to toggle between ascending, descending and no sorting in any sortable columns. `DataTable.Head` and `DataTable.Table` take an optional boolean `sortable` prop to configure this option.
|
|
157
|
+
|
|
158
|
+
### Pagination
|
|
159
|
+
|
|
160
|
+
`DataTable.Pagination` can be passed as a child to `DataTable` to render the pagination UI and configure the parent `DataTable` to paginate its data.
|