mirror of
https://github.com/bitwarden/browser
synced 2026-02-12 14:34:02 +00:00
This creates a new component called bit-table-scroll as it's a breaking change in how tables works. We could probably conditionally support both behaviors in the existing table component if we desire. Rather than iterating the rows in the consuming component, we now need to define a row definition, bitRowDef which provides access to the rows data through angular let- syntax. This allows the table component to own the behaviour which is needed in order to use the cdkVirtualFor directive which must be inside the cdk-virtual-scroll-viewport component.
189 lines
5.1 KiB
TypeScript
189 lines
5.1 KiB
TypeScript
import { Meta, moduleMetadata, StoryObj } from "@storybook/angular";
|
|
|
|
import { countries } from "../form/countries";
|
|
|
|
import { TableDataSource } from "./table-data-source";
|
|
import { TableModule } from "./table.module";
|
|
|
|
export default {
|
|
title: "Component Library/Table",
|
|
decorators: [
|
|
moduleMetadata({
|
|
imports: [TableModule],
|
|
}),
|
|
],
|
|
argTypes: {
|
|
alignRowContent: {
|
|
options: ["top", "middle", "bottom", "baseline"],
|
|
control: { type: "select" },
|
|
},
|
|
},
|
|
parameters: {
|
|
design: {
|
|
type: "figma",
|
|
url: "https://www.figma.com/file/Zt3YSeb6E6lebAffrNLa0h/Tailwind-Component-Library?node-id=1881%3A18371",
|
|
},
|
|
},
|
|
} as Meta;
|
|
|
|
type Story = StoryObj;
|
|
|
|
export const Default: Story = {
|
|
render: (args) => ({
|
|
props: args,
|
|
template: `
|
|
<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 [alignContent]="alignRowContent">
|
|
<td bitCell>Cell 1</td>
|
|
<td bitCell>Cell 2 <br /> Multiline Cell</td>
|
|
<td bitCell>Cell 3</td>
|
|
</tr>
|
|
<tr bitRow [alignContent]="alignRowContent">
|
|
<td bitCell>Cell 4</td>
|
|
<td bitCell>Cell 5</td>
|
|
<td bitCell>Cell 6</td>
|
|
</tr>
|
|
<tr bitRow [alignContent]="alignRowContent">
|
|
<td bitCell>Cell 7 <br /> Multiline Cell</td>
|
|
<td bitCell>Cell 8</td>
|
|
<td bitCell>Cell 9</td>
|
|
</tr>
|
|
</ng-template>
|
|
</bit-table>
|
|
`,
|
|
}),
|
|
args: {
|
|
alignRowContent: "middle",
|
|
},
|
|
};
|
|
|
|
const data = new TableDataSource<{ id: number; name: string; other: string }>();
|
|
|
|
data.data = [...Array(5).keys()].map((i) => ({
|
|
id: i,
|
|
name: `name-${i}`,
|
|
other: `other-${i}`,
|
|
}));
|
|
|
|
export const DataSource: Story = {
|
|
render: (args) => ({
|
|
props: {
|
|
dataSource: data,
|
|
sortFn: (a: any, b: any) => a.id - b.id,
|
|
},
|
|
template: `
|
|
<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 body let-rows$>
|
|
<tr bitRow *ngFor="let r of rows$ | async">
|
|
<td bitCell>{{ r.id }}</td>
|
|
<td bitCell>{{ r.name }}</td>
|
|
<td bitCell>{{ r.other }}</td>
|
|
</tr>
|
|
</ng-template>
|
|
</bit-table>
|
|
`,
|
|
}),
|
|
};
|
|
|
|
const data2 = new TableDataSource<{ id: number; name: string; other: string }>();
|
|
|
|
data2.data = [...Array(100).keys()].map((i) => ({
|
|
id: i,
|
|
name: `name-${i}`,
|
|
other: `other-${i}`,
|
|
}));
|
|
|
|
export const Scrollable: Story = {
|
|
render: (args) => ({
|
|
props: {
|
|
dataSource: data2,
|
|
sortFn: (a: any, b: any) => a.id - b.id,
|
|
trackBy: (index: number, item: any) => item.id,
|
|
},
|
|
template: `
|
|
<bit-table-scroll [dataSource]="dataSource" [rowSize]="43">
|
|
<ng-container header>
|
|
<th bitCell bitSortable="id" default>Id</th>
|
|
<th bitCell bitSortable="name">Name</th>
|
|
<th bitCell bitSortable="other" [fn]="sortFn">Other</th>
|
|
</ng-container>
|
|
<ng-template bitRowDef let-row>
|
|
<td bitCell>{{ row.id }}</td>
|
|
<td bitCell>{{ row.name }}</td>
|
|
<td bitCell>{{ row.other }}</td>
|
|
</ng-template>
|
|
</bit-table-scroll>
|
|
`,
|
|
}),
|
|
};
|
|
|
|
const data3 = new TableDataSource<{ value: string; name: string }>();
|
|
|
|
// Chromatic has a max page size, lowering the number of entries to ensure we don't hit it
|
|
data3.data = countries.slice(0, 100);
|
|
|
|
export const Filterable: Story = {
|
|
render: (args) => ({
|
|
props: {
|
|
dataSource: data3,
|
|
sortFn: (a: any, b: any) => a.id - b.id,
|
|
},
|
|
template: `
|
|
<input type="search" placeholder="Search" (input)="dataSource.filter = $event.target.value" />
|
|
<bit-table-scroll [dataSource]="dataSource" [rowSize]="43">
|
|
<ng-container header>
|
|
<th bitCell bitSortable="name" default>Name</th>
|
|
<th bitCell bitSortable="value" width="120px">Value</th>
|
|
</ng-container>
|
|
<ng-template bitRowDef let-row>
|
|
<td bitCell>{{ row.name }}</td>
|
|
<td bitCell>{{ row.value }}</td>
|
|
</ng-template>
|
|
</bit-table-scroll>
|
|
`,
|
|
}),
|
|
};
|
|
|
|
const data4 = new TableDataSource<{ name: string }>();
|
|
|
|
data4.data = [...Array(5).keys()].map((i) => ({
|
|
name: i % 2 == 0 ? `name-${i}`.toUpperCase() : `name-${i}`.toLowerCase(),
|
|
}));
|
|
|
|
export const VariableCase: Story = {
|
|
render: (args) => ({
|
|
props: {
|
|
dataSource: data4,
|
|
},
|
|
template: `
|
|
<bit-table [dataSource]="dataSource">
|
|
<ng-container header>
|
|
<tr>
|
|
<th bitCell bitSortable="name" default>Name</th>
|
|
</tr>
|
|
</ng-container>
|
|
<ng-template body let-rows$>
|
|
<tr bitRow *ngFor="let r of rows$ | async">
|
|
<td bitCell>{{ r.name }}</td>
|
|
</tr>
|
|
</ng-template>
|
|
</bit-table>
|
|
`,
|
|
}),
|
|
};
|