Basic proof of concept for cdk-virtual-scroll

This commit is contained in:
Thomas Rittson 2021-05-20 12:35:23 +10:00
parent b827614563
commit 9e5869773d
5 changed files with 84 additions and 29 deletions

View File

@ -1,4 +1,5 @@
import { DragDropModule } from '@angular/cdk/drag-drop'; import { DragDropModule } from '@angular/cdk/drag-drop';
import { ScrollingModule } from '@angular/cdk/scrolling';
import { ToasterModule } from 'angular2-toaster'; import { ToasterModule } from 'angular2-toaster';
import { InfiniteScrollModule } from 'ngx-infinite-scroll'; import { InfiniteScrollModule } from 'ngx-infinite-scroll';
@ -172,6 +173,7 @@ registerLocaleData(localeZhTw, 'zh-TW');
ToasterModule.forRoot(), ToasterModule.forRoot(),
InfiniteScrollModule, InfiniteScrollModule,
DragDropModule, DragDropModule,
ScrollingModule,
], ],
declarations: [ declarations: [
A11yTitleDirective, A11yTitleDirective,

View File

@ -1,4 +1,5 @@
<a *ngFor="let c of ciphers" (click)="selectCipher(c)" (dblclick)="launchCipher(c)" href="#" appStopClick <cdk-virtual-scroll-viewport itemSize="46">
<a *cdkVirtualFor="let c of ciphers" (click)="selectCipher(c)" (dblclick)="launchCipher(c)" href="#" appStopClick
title="{{title}} - {{c.name}}" class="box-content-row box-content-row-flex"> title="{{title}} - {{c.name}}" class="box-content-row box-content-row-flex">
<div class="row-main"> <div class="row-main">
<app-vault-icon [cipher]="c"></app-vault-icon> <app-vault-icon [cipher]="c"></app-vault-icon>
@ -21,3 +22,4 @@
class="action-buttons"> class="action-buttons">
</app-action-buttons> </app-action-buttons>
</a> </a>
</cdk-virtual-scroll-viewport>

View File

@ -34,4 +34,6 @@ export class CiphersListComponent {
viewCipher(c: CipherView) { viewCipher(c: CipherView) {
this.onView.emit(c); this.onView.emit(c);
} }
async resetPaging() { }
} }

View File

@ -356,3 +356,54 @@ select option {
background-color: darken(themed('inputBackgroundColor'), +1); background-color: darken(themed('inputBackgroundColor'), +1);
} }
} }
// TODO: this but better
cdk-virtual-scroll-viewport {
height: 500px;
width: 375px;
position: absolute;
top: 0;
bottom: 0;
left: 0;
right: 0;
overflow-y: auto !important;
overflow-x: hidden !important;
&.flex {
display: flex;
flex-flow: column;
&.tab-page {
height: calc(100% - 99px);
}
}
}
// cribbed directly from base.scss
cdk-virtual-scroll-viewport::-webkit-scrollbar, cdk-virtual-scroll-viewport::-webkit-scrollbar {
width: 10px;
height: 10px;
}
cdk-virtual-scroll-viewport::-webkit-scrollbar-track, cdk-virtual-scroll-viewport::-webkit-scrollbar {
background-color: transparent;
}
cdk-virtual-scroll-viewport::-webkit-scrollbar-thumb, cdk-virtual-scroll-viewport::-webkit-scrollbar {
border-radius: 10px;
margin-right: 1px;
@include themify($themes) {
background-color: themed('scrollbarColor');
}
&:hover {
@include themify($themes) {
background-color: themed('scrollbarHoverColor');
}
}
}
.cdk-virtual-scroll-content-wrapper {
width: 100%;
}

View File

@ -53,8 +53,8 @@
</div> </div>
</div> </div>
</ng-container> </ng-container>
<ng-container *ngIf="(isPaging() ? pagedCiphers : ciphers) as filteredCiphers"> <ng-container *ngIf="ciphers">
<div class="no-items" *ngIf="!filteredCiphers.length"> <div class="no-items" *ngIf="!ciphers.length">
<i class="fa fa-spinner fa-spin fa-3x" *ngIf="!loaded" aria-hidden="true"></i> <i class="fa fa-spinner fa-spin fa-3x" *ngIf="!loaded" aria-hidden="true"></i>
<ng-container *ngIf="loaded"> <ng-container *ngIf="loaded">
<p>{{'noItemsInList' | i18n}}</p> <p>{{'noItemsInList' | i18n}}</p>
@ -63,15 +63,13 @@
</button> </button>
</ng-container> </ng-container>
</div> </div>
<div class="box list only-list" *ngIf="filteredCiphers.length" infiniteScroll [infiniteScrollDistance]="1" <div class="box list only-list" *ngIf="ciphers.length">
[infiniteScrollContainer]="'content'" [fromRoot]="true" [infiniteScrollDisabled]="!isPaging()"
(scrolled)="loadMore()">
<div class="box-header"> <div class="box-header">
{{groupingTitle}} {{groupingTitle}}
<span class="flex-right">{{isSearching() ? filteredCiphers.length : ciphers.length}}</span> <span class="flex-right">{{isSearching() ? ciphers.length : ciphers.length}}</span>
</div> </div>
<div class="box-content"> <div class="box-content">
<app-ciphers-list [ciphers]="filteredCiphers" title="{{'viewItem' | i18n}}" <app-ciphers-list [ciphers]="ciphers" title="{{'viewItem' | i18n}}"
(onSelected)="selectCipher($event)" (launchEvent)="launchCipher($event)"></app-ciphers-list> (onSelected)="selectCipher($event)" (launchEvent)="launchCipher($event)"></app-ciphers-list>
</div> </div>
</div> </div>