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

fastlist

v1.0.4

Published

## Installation

Downloads

6

Readme

Fast List

Installation

npm install fastlist

The FastList is a virtual-list implementation based on the DomScheduler. See <fxos-fastlist> for the simpler, more opinionated web-component.

The content of the list comes from a DataSource that needs to implement the API described below. When the content is edited from the list "Edit mode", the list will trigger calls to the source itself.

But there's no observation going on, so if the content changes for other reasons the list needs to be made aware of that.

var myList = new FastList({

  /**
   * The element your list sits inside.
   * NOTE: Must be `position: relative|absolute`
   * @type {HTMLElement}
   */
  container: document.querySelector('.my-container'),

  /**
   * Should return a unique element to
   * be used as a list item.
   * @return {HTMLElement}
   */
  createItem: function() {},

  /**
   * Should return a unique element to
   * be used as a section.
   * @return {HTMLElement}
   */
  createSection: function() {},

  /**
   * Called each time a list item needs rendering.
   * @param  {HTMLElement} el Your listTemplate
   * @param  {Number} index
   */
  populateItem: function(el, index) { ... },

  /**
   * Called when the ressources allows it to do more expensive rendering
   * (ie. images)
   * This method isn't mandatory.
   * @param  {HTMLElement} el Your listTemplate
   * @param  {Number} index
   */
  populateItemDetail: function(el, index) { ... },

  /**
   * Called when an item is recycled to undo/cleanup the detail
   * rendering
   * This method isn't mandatory.
   * @param  {HTMLElement} el Your listTemplate
   */
  unpopulateItemDetail: function(el) { ... },

  /**
   * Called each time a section needs rendering.
   * @param  {HTMLElement} el Your sectionTemplate
   * @param  {Section} section
   * @param  {Number} index
   */
  populateSection: function(el, section, index) { ... }

  /**
   * Should return a list of sections.
   * Return empty array if not using sections.
   * @return {Array}
   */
  getSections() { ... },

  /**
   * Should return the height of the section header.
   * Can return 0 is not using sections.
   * @return {Number}
   */
  getSectionHeaderHeight() { ... },

  /**
   * Should return the height of all
   * the items in a section.
   * @return {Number}
   */
  getFullSectionHeight() { ... },

  /**
   * Should return the total number of sections.
   * @return {Number}
   */
  getFullSectionLength() { ... },

  /**
   * Should return the section data for the item.
   * @return {*}
   */
  getSectionFor(index) { ... },

  /**
   * Should return the item at index.
   * @param  {Number} index
   * @return {Object}
   */
  getRecordAt: function(index) { ... },

  /**
   * Should return the item index at
   * the given y-offset position.

   * @param  {Number} pos
   * @return {Index}
   */
  getIndexAtPosition: function(pos) { ... },

  /**
   * Should return the y-offset of
   * the given item index.
   * @param  {Number} index
   * @return {Number}
   */
  getPositionForIndex: function(index) { ... },

  /**
   * Should return the full list length.
   * @return {Number}
   */
  getFullLength: function() { ... },

  /**
   * Should return the item px height.
   * @return {Number}
   */
  getItemHeight: function() { ... },

  /**
   * Should return the full height of the list
   * including all items and section headers.
   * @return {Number}
   */
  getFullHeight: function() { ... },

  /**
   * An optional parameter to allow you to
   * provide the list viewport height in
   * a more efficient way than .offsetHeight.
   * @return {Number}
   */
  getViewportHeight: function() {},

  /**
   * SHould insert the given record into the your
   * source data list at the given index.
   * @param  {Number} index
   * @param  {Object} record
   * @param  {*} toSection
   */
  insertAtIndex: function(index, record, toSection) { ... },

  /**
   * Should replace a record in the source data
   * list at the given index.
   * @param  {Number} index
   * @param  {Object} record
   */
  replaceAtIndex: function(index, record) { ... }
});

If the content is not ready by the time it needs to be rendered

When the source is not ready to populate an item, maybe because the IndexedDB cursor hasn't caught up with scrolling yet it should do the following.

  • return a Promise from populateItem, resolving once the content is ready
  • return false if it implements the populateItemDetail method

Once the promise resolves, the list will try again to call populateItem / populateItemDetail.

API

Notifying of new content insertion

list.insertedAtIndex(0);

To insert with a nice transition.

list.reloadData()

For bigger, instantaneous changes.

Scrolling

list.scrollTop

Will give you the cached scroll top position (not causing a reflow).

list.scrollInstantly(by)

Will do as it says.

list.updateListHeight()

Can be called if the number of items in the list has changed, it'll return a scheduler promise fulfilled after the mutation is executed. This will also cause the scrollbar to flash.

Edit mode

The edit mode support leaves in a plugin, to enable in you need to load plugins/edit.js and initialize the FastList as follow.

var list = new FastList(config).plugin(fastListEdit);
/**
 * Toggles the edit mode on and off
 *
 * Returns the DomScheduler promise of the edit mode transition
 *
 * @return {Promise}
 */
list.toggleEditMode()

This method returns a promise, fulfilled once the transition is done.