@atom-learning/components 2.5.1 → 2.6.1

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.
Files changed (38) hide show
  1. package/CHANGELOG.md +8 -2
  2. package/dist/components/data-table/DataTable.d.ts +71 -0
  3. package/dist/components/data-table/DataTable.js +1 -0
  4. package/dist/components/data-table/DataTableBody.d.ts +5 -0
  5. package/dist/components/data-table/DataTableBody.js +1 -0
  6. package/dist/components/data-table/DataTableContext.d.ts +20 -0
  7. package/dist/components/data-table/DataTableContext.js +1 -0
  8. package/dist/components/data-table/DataTableDataCell.d.ts +7 -0
  9. package/dist/components/data-table/DataTableDataCell.js +1 -0
  10. package/dist/components/data-table/DataTableGlobalFilter.d.ts +8 -0
  11. package/dist/components/data-table/DataTableGlobalFilter.js +1 -0
  12. package/dist/components/data-table/DataTableHead.d.ts +7 -0
  13. package/dist/components/data-table/DataTableHead.js +1 -0
  14. package/dist/components/data-table/DataTableHeaderCell.d.ts +8 -0
  15. package/dist/components/data-table/DataTableHeaderCell.js +1 -0
  16. package/dist/components/data-table/DataTableRow.d.ts +8 -0
  17. package/dist/components/data-table/DataTableRow.js +1 -0
  18. package/dist/components/data-table/DataTableTable.d.ts +6 -0
  19. package/dist/components/data-table/DataTableTable.js +1 -0
  20. package/dist/components/data-table/index.d.ts +2 -0
  21. package/dist/components/data-table/pagination/Pagination.d.ts +273 -0
  22. package/dist/components/data-table/pagination/Pagination.js +1 -0
  23. package/dist/components/data-table/pagination/PaginationButtons.d.ts +21 -0
  24. package/dist/components/data-table/pagination/PaginationButtons.js +1 -0
  25. package/dist/components/data-table/pagination/index.d.ts +1 -0
  26. package/dist/components/index.d.ts +1 -0
  27. package/dist/components/select/Select.js +1 -1
  28. package/dist/components/table/TableHeader.d.ts +6 -1
  29. package/dist/components/table/TableHeader.js +1 -1
  30. package/dist/docgen.json +1 -1
  31. package/dist/docs/DataTable.mdx +156 -0
  32. package/dist/docs/TopBar.mdx +18 -4
  33. package/dist/index.cjs.js +1 -1
  34. package/dist/index.js +1 -1
  35. package/dist/utilities/optionally-visually-hidden-container/OptionallyVisuallyHiddenContainer.d.ts +4 -0
  36. package/dist/utilities/optionally-visually-hidden-container/OptionallyVisuallyHiddenContainer.js +1 -0
  37. package/dist/utilities/optionally-visually-hidden-container/index.d.ts +1 -0
  38. package/package.json +2 -1
@@ -0,0 +1,156 @@
1
+ ---
2
+ title: DataTable
3
+ component: DataTable, DataTable.Table, DataTable.Head, DataTable.HeaderCell, DataTable.Body, DataTable.Row, DataTable.DataCell, DataTable.GlobalFilter
4
+ description: Displays tabular data with features such as sorting and pagination
5
+ category: Content
6
+ ---
7
+
8
+ `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.
9
+
10
+ `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.
11
+
12
+ ## Anatomy
13
+
14
+ 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`.
15
+
16
+ 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`.
17
+
18
+ ### Using defaults vs using rolling your own
19
+
20
+ Here's a simple config for some table data and columns.
21
+
22
+ ```tsx
23
+ // import { createColumnHelper } from '@tanstack/react-table'
24
+
25
+ const columnHelper = createColumnHelper<{
26
+ name: string
27
+ hobby: string
28
+ }>()
29
+
30
+ const columns = [
31
+ columnHelper.accessor('name', {
32
+ cell: (info) => info.getValue()
33
+ }),
34
+ columnHelper.accessor('hobby', {
35
+ cell: (info) => info.getValue()
36
+ }),
37
+ // Columns created with columnHelper.display won't be sortable.
38
+ // They need a header to be set manually since they're not just reading
39
+ // a property from the row.
40
+ columnHelper.display({
41
+ cell: (info) => <button>do something</button>,
42
+ header: 'Actions'
43
+ })
44
+ ]
45
+
46
+ const data = [
47
+ { name: 'chrissy', hobby: 'bare-knuckle boxing' },
48
+ { name: 'agatha', hobby: 'crossfit' },
49
+ { name: 'betty', hobby: 'acting' }
50
+ ]
51
+ ```
52
+
53
+ 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.
54
+
55
+ #### With Defaults
56
+
57
+ 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.
58
+
59
+ ```tsx
60
+ <DataTable columns={columns} data={data}>
61
+ <DataTable.Table sortable css={{mb: '$4'}}/>
62
+ <DataTable.Pagination pageSize={5} />
63
+ </DataTable>
64
+
65
+ <DataTable columns={columns} data={data}>
66
+ <Table>
67
+ <DataTable.Head sortable />
68
+ <DataTable.Body />
69
+ </Table>
70
+ <DataTable.Pagination pageSize={5} />
71
+ </DataTable>
72
+ ```
73
+
74
+ ### Rolling your own
75
+
76
+ 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.
77
+
78
+ 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.
79
+
80
+ ```tsx
81
+ <DataTable columns={columns} data={data}>
82
+ {() => {
83
+ const { getHeaderGroups, getRowModel, setGlobalFilter, getState } =
84
+ useDataTable()
85
+ const { globalFilter } = getState()
86
+
87
+ return (
88
+ <>
89
+ <Label htmlFor="search">User search</Label>
90
+ <SearchInput
91
+ name="search"
92
+ value={globalFilter}
93
+ onChange={setGlobalFilter}
94
+ />
95
+ <Table>
96
+ <Table.Header>
97
+ {getHeaderGroups().map((headerGroup) => (
98
+ <Table.Row key={headerGroup.id}>
99
+ {headerGroup.headers.map((header) => {
100
+ const sort = header.column.getIsSorted()
101
+ return (
102
+ <Table.HeaderCell
103
+ onClick={header.column.getToggleSortingHandler()}
104
+ {...props}
105
+ >
106
+ {flexRender(
107
+ header.column.columnDef.header,
108
+ header.getContext()
109
+ )}
110
+ {sort && { asc: '^', desc: 'v' }[sort as string]}
111
+ </Table.HeaderCell>
112
+ )
113
+ })}
114
+ </Table.Row>
115
+ ))}
116
+ </Table.Header>
117
+ <Table.Body>
118
+ {getRowModel().rows.map((row) => (
119
+ <Table.Row>
120
+ {row.getVisibleCells().map((cell) => (
121
+ <Table.Cell key={cell.id}>
122
+ {flexRender(cell.column.columnDef.cell, cell.getContext())}
123
+ </Table.Cell>
124
+ ))}
125
+ </Table.Row>
126
+ ))}
127
+ </Table.Body>
128
+ </Table>
129
+ </>
130
+ // Then you could build your own pagination here too I guess? If you really wanted to?
131
+ )
132
+ }}
133
+ </DataTable>
134
+ ```
135
+
136
+ ## Features
137
+
138
+ ### Search
139
+
140
+ `DataTable.Search` renders a search input that filters the whole table by matching the input against values from any table column.
141
+
142
+ ### Sorting
143
+
144
+ 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.
145
+
146
+ #### Default sorting
147
+
148
+ `DataTable` takes an optional `defaultSort` prop to configure the column and direction for the table's default sorting, e.g. `{column: 'name', direction: 'asc'}`
149
+
150
+ #### User sorting
151
+
152
+ 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.
153
+
154
+ ### Pagination
155
+
156
+ `DataTable.Pagination` can be passed as a child to `DataTable` to render the pagination UI and configure the parent `DataTable` to paginate its data.
@@ -32,7 +32,11 @@ TopBar has a default size of `md` which means that the default height of the com
32
32
  ```tsx preview
33
33
  <TopBar>
34
34
  <TopBar.Brand href="atomlearning.co.uk">
35
- <TopBar.BrandLogo src={logo} />
35
+ <TopBar.BrandLogo
36
+ src={
37
+ 'https://space-1.atomlearning.com/static/f61e49cfb245016e612a34818e27dcfb.svg'
38
+ }
39
+ />
36
40
  </TopBar.Brand>
37
41
  </TopBar>
38
42
  ```
@@ -42,7 +46,11 @@ If size `lg` is passed to the `TopBar` it will be 96px in height and the `TopBar
42
46
  ```tsx preview
43
47
  <TopBar size="lg">
44
48
  <TopBar.Brand href="atomlearning.co.uk">
45
- <TopBar.BrandLogo src={logo} />
49
+ <TopBar.BrandLogo
50
+ src={
51
+ 'https://space-1.atomlearning.com/static/f61e49cfb245016e612a34818e27dcfb.svg'
52
+ }
53
+ />
46
54
  </TopBar.Brand>
47
55
  </TopBar>
48
56
  ```
@@ -52,13 +60,19 @@ If size `lg` is passed to the `TopBar` it will be 96px in height and the `TopBar
52
60
  `TopBar.Brand` renders a styled link.
53
61
 
54
62
  ```tsx
55
- import logo from '@atom-learning/theme/lib/assets/logo.svg'
63
+ // You'll import the logo like this in practice, but it doesn't work
64
+ // in these previews
65
+ // import logo from '@atom-learning/theme/lib/assets/logo.svg'
56
66
 
57
67
  const App = () => {
58
68
  return (
59
69
  <TopBar>
60
70
  <TopBar.Brand href="atomlearning.co.uk">
61
- <TopBar.BrandLogo src={logo} />
71
+ <TopBar.BrandLogo
72
+ src={
73
+ 'https://space-1.atomlearning.com/static/f61e49cfb245016e612a34818e27dcfb.svg'
74
+ }
75
+ />
62
76
  <TopBar.BrandName>Admin Panel</TopBar.BrandName>
63
77
  </TopBar.Brand>
64
78
  </TopBar>