mirror of
https://github.com/bitwarden/browser
synced 2025-12-15 15:53:27 +00:00
[SM-74] TableDataSource for sorting (#4079)
* Initial draft of a table data source * Improve table data source * Migrate projects table for demo * Update existing tables * Fix access selector * remove sortDirection from custom fn * a11y improvements * update icons; make button full width * update storybook docs * apply code review changes * fix: add table body to projects list * Fix error on create secret. Fix project list setting projects on getter. Copy table data on set. Fix documentation * Change signature to protected, rename method to not start with underscore * add hover and focus effects Co-authored-by: William Martin <contact@willmartian.com>
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
import { Meta, Story, Source } from "@storybook/addon-docs";
|
||||
import { Meta, Story } from "@storybook/addon-docs";
|
||||
|
||||
<Meta title="Documentation/Button" />
|
||||
|
||||
|
||||
104
libs/components/src/stories/table-docs.stories.mdx
Normal file
104
libs/components/src/stories/table-docs.stories.mdx
Normal file
@@ -0,0 +1,104 @@
|
||||
import { Meta, Story, Source } from "@storybook/addon-docs";
|
||||
|
||||
<Meta title="Documentation/Table" />
|
||||
|
||||
# Table
|
||||
|
||||
## Overview
|
||||
|
||||
All tables should have a visible horizontal header and label for each column.
|
||||
|
||||
<Story id="component-library-table--default" />
|
||||
|
||||
The below code is the absolute minimum required to create a table. However we stronly advice you to
|
||||
use the `dataSource` input to provide a data source for your table. This allows you to easily sort
|
||||
data.
|
||||
|
||||
```html
|
||||
<bit-table>
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell>Header 1</th>
|
||||
<th bitCell>Header 2</th>
|
||||
<th bitCell>Header 3</th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template body>
|
||||
<tr bitRow>
|
||||
<td bitCell>Cell 1</td>
|
||||
<td bitCell>Cell 2</td>
|
||||
<td bitCell>Cell 3</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
```
|
||||
|
||||
## Data Source
|
||||
|
||||
Bitwarden provides a data source for tables that can be used in place of a traditional data array.
|
||||
The `TableDataSource` implements sorting and will in the future also support filtering. This allows
|
||||
the `bitTable` component to focus on rendering while offloading the data management to the data
|
||||
source.
|
||||
|
||||
```ts
|
||||
// External data source
|
||||
const data: T[];
|
||||
|
||||
const dataSource = new TableDataSource<T>();
|
||||
dataSource.data = data;
|
||||
```
|
||||
|
||||
We use the `dataSource` as an input to the `bit-table` component, and access the rows to render
|
||||
within the `ng-template`which provides access to the rows using `let-rows$`.
|
||||
|
||||
<Source id="component-library-table--data-source" />
|
||||
|
||||
### Sortable
|
||||
|
||||
We provide a simple component for displaying sortable column headers. The `bitSortable` component
|
||||
wires up to the `TableDataSource` and will automatically sort the data when clicked and display
|
||||
an indicator for which column is currently sorted. The dafault sorting can be specified by setting
|
||||
the `default`.
|
||||
|
||||
```html
|
||||
<th bitCell bitSortable="id" default>Id</th>
|
||||
<th bitCell bitSortable="name" default>Name</th>
|
||||
```
|
||||
|
||||
It's also possible to define a custom sorting function by setting the `fn` input.
|
||||
|
||||
```ts
|
||||
const sortFn = (a: T, b: T) => (a.id > b.id ? 1 : -1);
|
||||
```
|
||||
|
||||
### Virtual Scrolling
|
||||
|
||||
It's heavily adviced to use virtual scrolling if you expect the table to have any significant amount
|
||||
of data. This is easily done by wrapping the table in the `cdk-virtual-scroll-viewport` component,
|
||||
specify a `itemSize`, set `scrollWindow` to `true` and replace `*ngFor` with `*cdkVirtualFor`.
|
||||
|
||||
```html
|
||||
<cdk-virtual-scroll-viewport scrollWindow itemSize="47">
|
||||
<bit-table [dataSource]="dataSource">
|
||||
<ng-container header>
|
||||
<tr>
|
||||
<th bitCell bitSortable="id" default>Id</th>
|
||||
<th bitCell bitSortable="name">Name</th>
|
||||
<th bitCell bitSortable="other" [fn]="sortFn">Other</th>
|
||||
</tr>
|
||||
</ng-container>
|
||||
<ng-template let-rows$>
|
||||
<tr bitRow *cdkVirtualFor="let r of rows$">
|
||||
<td bitCell>{{ r.id }}</td>
|
||||
<td bitCell>{{ r.name }}</td>
|
||||
<td bitCell>{{ r.other }}</td>
|
||||
</tr>
|
||||
</ng-template>
|
||||
</bit-table>
|
||||
</cdk-virtual-scroll-viewport>
|
||||
```
|
||||
|
||||
## Accessibility
|
||||
|
||||
- Always incude a row or column header with your table; this allows screen readers to better contextualize the data
|
||||
- Avoid spanning data across cells
|
||||
Reference in New Issue
Block a user