turbolent / collection-view

UICollectionView for the web
MIT License
67 stars 7 forks source link
collectionview grid grid-layout javascript list performance react recylerview scroll scrolling typescript uicollectionview virtualization virtualized windowing

collection-view

Build Status

A container for displaying large ordered collections of data items and presenting them using arbitrary layouts (e.g. lists, grids). Large collections can be scrolled smoothly by displaying only a limited number of elements. This is also known as "windowing" or "virtualization". Changes to the data (remove, add, move) and changes to the layout are properly animated by the collection view. The library is inspired by iOS' UICollectionView and Android's RecyclerView.

The collection view gets its data from a delegate and gets its visual information from a layout. Currently there is a grid layout, which presents the collection in rows and columns, and a simple list layout, which presents the collection in rows. Custom layouts can be implemented easily. Contributions are welcome!

Scrolling

The collection view also handles resizing of the container properly, maintaining the current position in the collection:

Resizing

Elements can be individually animated:

Staggering

Pivot

Usage

import { CollectionView, GridLayout } from 'collection-view'

class Delegate {
  constructor(items) {
    this.items = items
  }

  getCount() {
    return this.items.length
  }

  configureElement(element, index) {
    element.textContent = this.items[index]
  }
}

let items = ["Item 1", "Item 2", "Item 3", "Item 4", "Item 5", "Item 6", "Item 7", "Item 8", "Item 9", "Item 10"]
let delegate = new Delegate(items)
let layout = new GridLayout()
let contentElement = document.getElementById('content')
let view = new CollectionView(contentElement, layout, delegate)

Implement a delegate for your collection. Instantiate a layout, like a grid or list, and configure it. Finally, instantiate a collection view, providing the DOM element which should contain the elements representing the items in the collection, the layout, and the delegate.

If the grid or list layouts do not fit your needs you can also implement a custom layout.

Delegate

The delegate object is responsible for defining how many items the collection view should display and configuring the elements corresponding to the items.

The getStyle and getAnimation delegate methods are also passed an info parameter, which is layout information for the element, provided by the current layout. When a list layout is used, it is an object with a row property, and when a grid layout layout is used, it is an object containing row and column properties.

Changing the data

The collection view supports transitions between different collections. As it is not aware of the underlying data itself, the changes have to be provided to the collection view explicitly, in the form of the indices of the items which were removed, added, and moved, passed to the method:

changeIndices(removed: number[], added: number[], moved: Map.<number, number>): Promise

For example, when transitioning from the original collection [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11] to the target collection [1, 15, 16, 3, 6, 8, 4, 10, 11]:

Therefore, the method call would be changeIndices([1, 4, 6, 8], [1, 2], new Map([[3, 6]])) (or alternatively changeIndices([1, 4, 6, 8], [1, 2], new Map([3, 6])) for older environments).

Similar to calling UICollectionView.deleteItems(at:), UICollectionView.insertItems(at:), and multiple UICollectionView.moveItem(at:to:) as part of a call to performBatchUpdates(_:completion:)

Grid layout

The GridLayout displays collection items in a grid. All items are the same size and flow from one row or column (depending on the direction) to the next.

It is similar to UICollectionViewFlowLayout.

List layout

The ListLayout displays collection items in a list. All items have the same height.

Changing the layout

The collection view supports transitions between different layouts. Simply instantiate a new layout, configure it, and call:

updateLayout(newLayout: CollectionViewLayout): Promise

For example, this allows changing the item size or direction of a grid layout. The collection view properly maintains the position in the collection.

Custom layout

The layout object is responsible for defining the size of the collection view content element and positions of the elements representing the items of the collection. Normally it is not necessary to implement a custom layout, as the grid and list layout should be sufficient in most use-cases. Still, if another layout is desired, the following methods need to be implemented:

Collection view

Examples

The examples directory contains several examples demonstrating the features of the collection view. To try them out, go to each subdirectory, run webpack and open the index.html.

React

For usage with React, see examples/react.