1
0
mirror of https://github.com/bitwarden/browser synced 2025-12-16 08:13:42 +00:00

[CL-696] un-revert "various drawer improvements" + bug fix (#14887)

* Revert "Revert "[CL-622][CL-562][CL-621][CL-632] various drawer improvements …"

This reverts commit 4b32d1f9dd.

* fix virtual scroll: add .cdk-virtual-scrollable to scroll viewport target

* remove references to main el

* use directives instead of querySelector (#14950)

* remove references to main el

* wip

* banish querySelector to the shadow realm

* revert apps/ files

* Add virtual scrolling docs

Co-authored-by: Vicki League <vleague@bitwarden.com>

* add jsdoc

* run eslint

* fix skip links bug

* Update libs/components/src/layout/layout.component.ts

Co-authored-by: Vicki League <vleague@bitwarden.com>

* update tab handler

* only run on tab

* fix lint

* fix virtual scroll issue due to Angular 19 upgrade (#15193)

thanks Vicki

---------

Co-authored-by: Vicki League <vleague@bitwarden.com>
This commit is contained in:
Will Martin
2025-06-17 11:05:14 -04:00
committed by GitHub
parent 674886a28b
commit b8a1856fc6
37 changed files with 807 additions and 286 deletions

View File

@@ -1,5 +1,5 @@
<cdk-virtual-scroll-viewport
scrollWindow
bitScrollLayout
[itemSize]="rowSize"
[ngStyle]="{ paddingBottom: headerHeight + 'px' }"
>

View File

@@ -4,7 +4,6 @@ import {
CdkVirtualScrollViewport,
CdkFixedSizeVirtualScroll,
CdkVirtualForOf,
CdkVirtualScrollableWindow,
} from "@angular/cdk/scrolling";
import { CommonModule } from "@angular/common";
import {
@@ -21,6 +20,8 @@ import {
TrackByFunction,
} from "@angular/core";
import { ScrollLayoutDirective } from "../layout";
import { RowDirective } from "./row.directive";
import { TableComponent } from "./table.component";
@@ -52,10 +53,10 @@ export class BitRowDef {
imports: [
CommonModule,
CdkVirtualScrollViewport,
CdkVirtualScrollableWindow,
CdkFixedSizeVirtualScroll,
CdkVirtualForOf,
RowDirective,
ScrollLayoutDirective,
],
})
export class TableScrollComponent

View File

@@ -142,7 +142,7 @@ dataSource.filter = (data) => data.orgType === "family";
Rudimentary string filtering is supported out of the box with `TableDataSource.simpleStringFilter`.
It works by converting each entry into a string of it's properties. The provided string is then
compared against the filter value using a simple `indexOf` check. For convienence, you can also just
compared against the filter value using a simple `indexOf` check. For convenience, you can also just
pass a string directly.
```ts
@@ -153,7 +153,7 @@ dataSource.filter = "search value";
### Virtual Scrolling
It's heavily adviced to use virtual scrolling if you expect the table to have any significant amount
It's heavily advised to use virtual scrolling if you expect the table to have any significant amount
of data. This is done by using the `bit-table-scroll` component instead of the `bit-table`
component. This component behaves slightly different from the `bit-table` component. Instead of
using the `*ngFor` directive to render the rows, you provide a `bitRowDef` template that will be
@@ -178,6 +178,14 @@ height and align vertically.
</bit-table-scroll>
```
#### Deprecated approach
Before `bit-table-scroll` was introduced, virtual scroll in tables was implemented manually via
constructs from Angular CDK. This included wrapping the table with a `cdk-virtual-scroll-viewport`
and targeting with `bit-layout`'s scroll container with the `bitScrollLayout` directive.
This pattern is deprecated in favor of `bit-table-scroll`.
## Accessibility
- Always include a row or column header with your table; this allows assistive technology to better

View File

@@ -1,6 +1,13 @@
import { RouterTestingModule } from "@angular/router/testing";
import { Meta, moduleMetadata, StoryObj } from "@storybook/angular";
import { I18nService } from "@bitwarden/common/platform/abstractions/i18n.service";
import { countries } from "../form/countries";
import { LayoutComponent } from "../layout";
import { mockLayoutI18n } from "../layout/mocks";
import { positionFixedWrapperDecorator } from "../stories/storybook-decorators";
import { I18nMockService } from "../utils";
import { TableDataSource } from "./table-data-source";
import { TableModule } from "./table.module";
@@ -8,8 +15,17 @@ import { TableModule } from "./table.module";
export default {
title: "Component Library/Table",
decorators: [
positionFixedWrapperDecorator(),
moduleMetadata({
imports: [TableModule],
imports: [TableModule, LayoutComponent, RouterTestingModule],
providers: [
{
provide: I18nService,
useFactory: () => {
return new I18nMockService(mockLayoutI18n);
},
},
],
}),
],
argTypes: {
@@ -116,18 +132,20 @@ export const Scrollable: Story = {
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>
<bit-layout>
<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>
</bit-layout>
`,
}),
};
@@ -144,17 +162,19 @@ export const Filterable: Story = {
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>
<bit-layout>
<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>
</bit-layout>
`,
}),
};