npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2024 – Pkg Stats / Ryan Hefner

ngx-with-virtual-scroll

v1.0.3

Published

[<img src="https://badgen.net/npm/v/ngx-with-virtual-scroll?cache=43200">](https://www.npmjs.com/package/ngx-with-virtual-scroll) [<img src="https://img.shields.io/badge/minzipped-2.6kb-informational">](https://bundlephobia.com/result?p=ngx-with-virtual-s

Downloads

21

Readme

ngx-with-virtual-scroll

The kit to create virtual scrolling lists, tables, grids etc. Zero styling, non-component. It allows you to render huge amount of items with high performance by rendering only items within viewport. Other items will be rendered dynamicly during the scroll.

Heavily inspired by react-virtual

Features

  • It doesn't provide any component to wrap your lists, so you can create your own markup and styling
  • You can pass any scroll element to be scrolled, even if it's not ancestor of your container (see examples)
  • It can render both static, dynamic and different size elements
  • It provides scrollTo and scrollToIndex functions
  • You can override scrolling function with your own (see examples)
  • It allows you to override scrolling function that is using in previous pt.
  • It allows you to render one list to several containers (see examples)
  • It can be both horizontal and vertical
  • Scrolling can be throttled and/or debounced

Examples

  • The most minimal use case Source | Live
  • measure-size-for usage. Contains the most recommended way to use this package Source | Live
  • Pre and post blocks with any nested level. This example introduces containerRef input that must be set if viewport element contains something else except container. It can be helpful if your viewport and container are not in direct inheritance Source | Live
  • Using one viewport to render several independent virtual scrolls. It can be very useful if you have kinda a list of sections with items inside, but you need to use shared scroll viewport Source | Live
  • Using one viewport to render multiple columns with the same list. It can be very useful if you are building a table with two columns where first is a main column and second is table columns Source | Live
  • Scrolling, custom scrolling, smooth scrolling Source | Live

Installation

npm install ngx-with-virtual-scroll@latest -S

How to use

The package provides two Angular's directives: with-virtual-scroll and measure-size-for. You need to use either first or both depends on your case (see examples). First one with-virtual-scroll is the main directive. It accepts count and viewportRef in order to calculate virtualItems you gonna to use in your component. Second. measure-size-for is using when you don't want to declare estimateSize input, or your items have different or even dynamic sizes.

To start using you need to:

  1. Import NgxWithVirtualScrollModule to your module

  2. In your component's html (it is recommended to create your list component that will wrap and hide virtual scrolling applying) use with-virtual-scroll directive (it is recommended to use it on ng-container):

    <ng-container with-virtual-scroll
                  [items]="rows"
                  [estimateSize]="estimateSizeFn"
                  [viewportRef]="verticalViewportRef"
                  #verticalScroll="with-virtual-scroll">
        <div class="viewport" #verticalViewportRef>
            <div [style.height.px]="verticalScroll.totalSize" class="container">
                <div *ngFor="let item of verticalScroll.virtualItems; trackBy: trackByRows()"
                     [style.transform]="'translateY(' + item.start + 'px)'"
                     class="item">
                    {{rows[item.index].name}}
                </div>
            </div>
        </div>
    </ng-container>
  3. In your component's style:

    .viewport {
        overflow: auto;
        height: 600px;
    }
       
    .container {
        height: 100%;
        position: relative;
    }
       
    .item {
        position: absolute;
        top: 0;
        left: 0;
        width: 100%;
    }
  4. In your component's ts:

    import { VirtualItem } from 'ngx-with-virtual-scroll';
       
    export class ListComponent {
        rows = [...Array(100000)].map((i, index) => ({
            id: index,
            name: `row ${index}`,
            size: 50,
        }));
       
        estimateSizeFn = () => 50;
       
        trackByRows() {
            return (index: number, item: VirtualItem) => this.rows[item.index].id;
        }
    }
  5. That is it. It is up to you to create your own logic of markup and styling. This is just one recommended way to do it. For more cases see examples.

API

with-virtual-scroll

export declare class WithVirtualScrollDirective {
    /**
     * @Input() items ref
     */
    items?: unknown[];
    /**
     * @Input() the reference to viewport element ref. Its height / width will be used as items limiter
     */
    viewportRef?: HTMLElement;
    /**
     * @Input() whether horizontal or vertical scrolling is set
     * default: false
     */
    horizontal: boolean;
    /**
     * @Input() count of additional items before and after virtualItems.
     * It is recommended to add at least one bufferLength item, so focus will work
     * default: 0
     */
    bufferLength: number;
    /**
     * @Input() the reference to container element ref. This container should contain visible items,
     * but its height / width must be set using totalSize property.
     * This input is optional if viewportRef contains only containerRef, otherwise it must be set.
     */
    containerRef?: HTMLElement;
    /**
     * @Input() this fn is used for calculating size of item during initial measuring.
     * The value it returns will be overridden by [measure-size-for] directive if it is set
     * default () => 50
     */
    estimateSize?: VirtualEstimateSizeFn;
    /**
     * @Input() whether to use first measured size by [measure-size-for] directive as a size for all items.
     * It is useful when all of your items have the same size but you don't want to set it using estimateSize input.
     * default: true
     */
    useFirstMeasuredSize: boolean;
    /**
     * @Input() passing this function allows you to override default scrolling behavior.
     * Default scrolling behavior: setting scrollTop / scrollLeft
     */
    scrollToFn?: VirtualCustomScrollToFn;
    /**
     * this property must be used as height / width setter for containerRef
     */
    totalSize: number;
    /**
     * this property will contain virtual items to render
     */
    virtualItems: VirtualItem[];
    /**
     * current scroll offset
     */
    scrollOffset: number;
    /**
     * current measurements
     */
    measurements: VirtualMeasurement[];
    /**
     * current range in indexes
     */
    range: VirtualBoundaries;

    /**
     * this allows you to scroll to offset.
     * @param [offset] to scroll
     * @param [align]:
     *  start - offset will be at start of visible viewport area
     *  end - offset will be at end of visible viewport area
     *  center - offset will be at center of visible viewport area
     *  auto - it will try to find closer align for offset.
     *  It will be end if current scroll position is more then offset + viewport size,
     *  otherwise it will be start
     *
     */
    scrollToOffset(offset: number, align?: VirtualScrollToAlign): void;

    /**
     * this allows you to scroll to specified index.
     * @param [index] to scroll
     * @param [align]:
     *  start - top of the item will be at the top of visible viewport area
     *  end - bottom of the item will be at the top of visible viewport area
     *  center - center of the item will be at the top of visible viewport area
     *  auto - it will try to find closer align for item.
     *  It will be end if item's end at index position is more then offset + viewport size,
     *  otherwise it will be start
     */
    scrollToIndex(index: number, align?: VirtualScrollToAlign): void;
}

measure-size-for

export declare class MeasureSizeForDirective {
    /**
     * virtual item connect to
     */
    item?: VirtualItem;
}