import { LiveAnnouncer } from '@angular/cdk/a11y'; import { Component, inject } from '@angular/core'; import { AccessibilityModule, AccordionModule, CheckboxModule, TabsetModule, VirtualScrollModule, } from '@ux-aspects/ux-aspects'; import 'chance'; import { Subject } from 'rxjs'; import { ApiPropertiesComponent } from '../../../../../components/api-properties/api-properties.component'; import { ApiPropertyComponent } from '../../../../../components/api-property/api-property.component'; import { BaseDocumentationSection } from '../../../../../components/base-documentation-section/base-documentation-section'; import { SnippetComponent } from '../../../../../components/snippet/snippet.component'; import { DocumentationSectionComponent } from '../../../../../decorators/documentation-section-component'; import { IPlayground } from '../../../../../interfaces/IPlayground'; import { IPlaygroundProvider } from '../../../../../interfaces/IPlaygroundProvider'; const DEPARTMENTS = [ 'Finance', 'Operations', 'Investor Relations', 'Technical', 'Auditing', 'Labs', ]; @Component({ selector: 'uxd-components-virtual-scroll', templateUrl: './virtual-scroll.component.html', styleUrls: ['./virtual-scroll.component.less'], imports: [ VirtualScrollModule, AccessibilityModule, AccordionModule, CheckboxModule, ApiPropertiesComponent, ApiPropertyComponent, TabsetModule, SnippetComponent, ], }) @DocumentationSectionComponent('ComponentsVirtualScrollComponent') export class ComponentsVirtualScrollComponent extends BaseDocumentationSection implements IPlaygroundProvider { private readonly _liveAnnouncer = inject(LiveAnnouncer); loadOnScroll: boolean = true; employees: Subject = new Subject(); loading = false; pageSize = 2000; totalPages = 10; totalItems: number; playground: IPlayground = { files: { 'app.component.html': this.snippets.raw.appHtml, 'app.component.ts': this.snippets.raw.appTs, 'app.component.css': this.snippets.raw.appCss, }, modules: [ { imports: ['VirtualScrollModule', 'CheckboxModule', 'AccordionModule'], library: '@ux-aspects/ux-aspects', }, { imports: ['A11yModule'], library: '@angular/cdk/a11y', }, ], }; constructor() { super( import.meta.webpackContext('./snippets/', { recursive: false, regExp: /\.(html|css|js|ts)$/, }) ); this.totalItems = this.pageSize * this.totalPages; } loadPage(pageNumber: number): void { const startIdx = pageNumber * this.pageSize; const endIdx = startIdx + this.pageSize; const employees: Employee[] = []; this.loading = true; this._liveAnnouncer.announce('Loading more items, please wait.'); // generate sample employee data for (let idx = startIdx; idx < endIdx; idx++) { const name = chance.name(); employees.push({ id: idx, name: name, email: name.toLowerCase().replace(' ', '.') + '@business.com', department: chance.pickone(DEPARTMENTS), }); } // push the next batch of employees to the subject - (delay to simulate server time) setTimeout(() => { this.employees.next(employees); this.loading = false; this._liveAnnouncer.announce(`${employees.length} items loaded.`); // impose a limit of 10 pages if (pageNumber === 10) { this.employees.complete(); } }, 1000); } } interface Employee { id: number; name: string; email: string; department: string; }