1
0
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:
Oscar Hinton
2023-01-12 23:06:58 +01:00
committed by GitHub
parent 23897ae5fb
commit 344a054ba2
19 changed files with 557 additions and 33 deletions

View File

@@ -1,4 +1,4 @@
import { Meta, Story, Source } from "@storybook/addon-docs";
import { Meta, Story } from "@storybook/addon-docs";
<Meta title="Documentation/Button" />

View 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