{"id":15520694,"url":"https://github.com/turbolent/collection-view","last_synced_at":"2026-03-04T08:01:15.847Z","repository":{"id":3162840,"uuid":"48607667","full_name":"turbolent/collection-view","owner":"turbolent","description":"UICollectionView for the web","archived":false,"fork":false,"pushed_at":"2023-01-14T00:59:29.000Z","size":5786,"stargazers_count":67,"open_issues_count":31,"forks_count":7,"subscribers_count":4,"default_branch":"master","last_synced_at":"2025-10-03T04:34:19.338Z","etag":null,"topics":["collectionview","grid","grid-layout","javascript","list","performance","react","recylerview","scroll","scrolling","typescript","uicollectionview","virtualization","virtualized","windowing"],"latest_commit_sha":null,"homepage":"","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/turbolent.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2015-12-26T10:51:42.000Z","updated_at":"2025-09-09T18:52:39.000Z","dependencies_parsed_at":"2023-01-16T20:45:35.105Z","dependency_job_id":null,"html_url":"https://github.com/turbolent/collection-view","commit_stats":null,"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/turbolent/collection-view","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbolent%2Fcollection-view","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbolent%2Fcollection-view/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbolent%2Fcollection-view/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbolent%2Fcollection-view/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/turbolent","download_url":"https://codeload.github.com/turbolent/collection-view/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/turbolent%2Fcollection-view/sbom","scorecard":{"id":902572,"data":{"date":"2025-08-11","repo":{"name":"github.com/turbolent/collection-view","commit":"32f9159227eee890e7af5c0a1f80ac750b8365be"},"scorecard":{"version":"v5.2.1-40-gf6ed084d","commit":"f6ed084d17c9236477efd66e5b258b9d4cc7b389"},"score":1.7,"checks":[{"name":"Dangerous-Workflow","score":-1,"reason":"no workflows found","details":null,"documentation":{"short":"Determines if the project's GitHub Action workflows avoid dangerous patterns.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#dangerous-workflow"}},{"name":"Code-Review","score":0,"reason":"Found 0/2 approved changesets -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project requires human code review before pull requests (aka merge requests) are merged.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#code-review"}},{"name":"Packaging","score":-1,"reason":"packaging workflow not detected","details":["Warn: no GitHub/GitLab publishing workflow detected."],"documentation":{"short":"Determines if the project is published as a package that others can easily download, install, easily update, and uninstall.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#packaging"}},{"name":"Token-Permissions","score":-1,"reason":"No tokens found","details":null,"documentation":{"short":"Determines if the project's workflows follow the principle of least privilege.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#token-permissions"}},{"name":"Maintained","score":0,"reason":"0 commit(s) and 0 issue activity found in the last 90 days -- score normalized to 0","details":null,"documentation":{"short":"Determines if the project is \"actively maintained\".","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#maintained"}},{"name":"Binary-Artifacts","score":10,"reason":"no binaries found in the repo","details":null,"documentation":{"short":"Determines if the project has generated executable (binary) artifacts in the source repository.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#binary-artifacts"}},{"name":"Pinned-Dependencies","score":-1,"reason":"no dependencies found","details":null,"documentation":{"short":"Determines if the project has declared and pinned the dependencies of its build process.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#pinned-dependencies"}},{"name":"CII-Best-Practices","score":0,"reason":"no effort to earn an OpenSSF best practices badge detected","details":null,"documentation":{"short":"Determines if the project has an OpenSSF (formerly CII) Best Practices Badge.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#cii-best-practices"}},{"name":"Security-Policy","score":0,"reason":"security policy file not detected","details":["Warn: no security policy file detected","Warn: no security file to analyze","Warn: no security file to analyze","Warn: no security file to analyze"],"documentation":{"short":"Determines if the project has published a security policy.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#security-policy"}},{"name":"Fuzzing","score":0,"reason":"project is not fuzzed","details":["Warn: no fuzzer integrations found"],"documentation":{"short":"Determines if the project uses fuzzing.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#fuzzing"}},{"name":"License","score":10,"reason":"license file detected","details":["Info: project has a license file: LICENSE:0","Info: FSF or OSI recognized license: MIT License: LICENSE:0"],"documentation":{"short":"Determines if the project has defined a license.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#license"}},{"name":"Signed-Releases","score":-1,"reason":"no releases found","details":null,"documentation":{"short":"Determines if the project cryptographically signs release artifacts.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#signed-releases"}},{"name":"Branch-Protection","score":0,"reason":"branch protection not enabled on development/release branches","details":["Warn: branch protection not enabled for branch 'master'"],"documentation":{"short":"Determines if the default and release branches are protected with GitHub's branch protection settings.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#branch-protection"}},{"name":"SAST","score":0,"reason":"SAST tool is not run on all commits -- score normalized to 0","details":["Warn: 0 commits out of 28 are checked with a SAST tool"],"documentation":{"short":"Determines if the project uses static code analysis.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#sast"}},{"name":"Vulnerabilities","score":0,"reason":"64 existing vulnerabilities detected","details":["Warn: Project is vulnerable to: GHSA-968p-4wvh-cqc8","Warn: Project is vulnerable to: GHSA-67hx-6x53-jw92","Warn: Project is vulnerable to: GHSA-v88g-cgmw-v5xw","Warn: Project is vulnerable to: GHSA-93q8-gq69-wqmw","Warn: Project is vulnerable to: GHSA-v6h2-p8h4-qcjw","Warn: Project is vulnerable to: GHSA-grv7-fg5c-xmjg","Warn: Project is vulnerable to: GHSA-x9w5-v3q2-3rhw","Warn: Project is vulnerable to: GHSA-w8qv-6jwh-64r5","Warn: Project is vulnerable to: GHSA-gxpj-cx7g-858c","Warn: Project is vulnerable to: GHSA-w573-4hg7-7wgq","Warn: Project is vulnerable to: GHSA-r9p9-mrjm-926w","Warn: Project is vulnerable to: GHSA-434g-2637-qmqr","Warn: Project is vulnerable to: GHSA-49q7-c7j4-3p7m","Warn: Project is vulnerable to: GHSA-977x-g7h5-7qgw","Warn: Project is vulnerable to: GHSA-f7q4-pwc6-w24p","Warn: Project is vulnerable to: GHSA-fc9h-whq2-v747","Warn: Project is vulnerable to: GHSA-vjh7-7g9h-fjfh","Warn: Project is vulnerable to: GHSA-8r6j-v8pm-fqw3","Warn: Project is vulnerable to: MAL-2023-462","Warn: Project is vulnerable to: GHSA-qqgx-2p2h-9c37","Warn: Project is vulnerable to: GHSA-9c47-m6qq-7p4h","Warn: Project is vulnerable to: GHSA-6c8f-qphg-qjgp","Warn: Project is vulnerable to: GHSA-76p3-8jx3-jpfq","Warn: Project is vulnerable to: GHSA-3rfm-jhwj-7488","Warn: Project is vulnerable to: GHSA-hhq3-ff78-jv3g","Warn: Project is vulnerable to: GHSA-29mw-wpgm-hmr9","Warn: Project is vulnerable to: GHSA-35jh-r3h4-6jhm","Warn: Project is vulnerable to: GHSA-952p-6rrq-rcjv","Warn: Project is vulnerable to: GHSA-f8q6-p94x-37v3","Warn: Project is vulnerable to: GHSA-vh95-rmgr-6w4m","Warn: Project is vulnerable to: GHSA-xvch-5gv4-984h","Warn: Project is vulnerable to: GHSA-hj48-42vr-x3v9","Warn: Project is vulnerable to: GHSA-h7cp-r72f-jxh6","Warn: Project is vulnerable to: GHSA-v62p-rq8g-8h59","Warn: Project is vulnerable to: GHSA-c2qf-rxjj-qqgw","Warn: Project is vulnerable to: GHSA-h9rv-jmmf-4pgx","Warn: Project is vulnerable to: GHSA-hxcc-f52p-wc94","Warn: Project is vulnerable to: GHSA-4g88-fppr-53pp","Warn: Project is vulnerable to: GHSA-4jqc-8m5r-9rpr","Warn: Project is vulnerable to: GHSA-vx3p-948g-6vhq","Warn: Project is vulnerable to: GHSA-3jfq-g458-7qm9","Warn: Project is vulnerable to: GHSA-r628-mhmh-qjhw","Warn: Project is vulnerable to: GHSA-9r2w-394v-53qc","Warn: Project is vulnerable to: GHSA-5955-9wpr-37jh","Warn: Project is vulnerable to: GHSA-qq89-hq3f-393p","Warn: Project is vulnerable to: GHSA-f5x3-32g6-xq36","Warn: Project is vulnerable to: GHSA-4wf5-vphf-c2xc","Warn: Project is vulnerable to: GHSA-c4w7-xm78-47vh","Warn: Project is vulnerable to: GHSA-3xgq-45jj-v275","Warn: Project is vulnerable to: GHSA-fjxv-7rqg-78g4","Warn: Project is vulnerable to: GHSA-vvj3-85vf-fgmw","Warn: Project is vulnerable to: GHSA-896r-f27r-55mw","Warn: Project is vulnerable to: GHSA-p6mc-m468-83gw","Warn: Project is vulnerable to: GHSA-5fw9-fq32-wv5p","Warn: Project is vulnerable to: GHSA-566m-qj78-rww5","Warn: Project is vulnerable to: GHSA-7fh5-64p2-3v2j","Warn: Project is vulnerable to: GHSA-hrpp-h998-j3pp","Warn: Project is vulnerable to: GHSA-p8p7-x288-28g6","Warn: Project is vulnerable to: GHSA-jgrx-mgxx-jf9v","Warn: Project is vulnerable to: GHSA-72xf-g2v4-qvf3","Warn: Project is vulnerable to: GHSA-j8xg-fqg3-53r7","Warn: Project is vulnerable to: GHSA-6fc8-4gx4-v693","Warn: Project is vulnerable to: GHSA-3h5v-q93c-6h6q","Warn: Project is vulnerable to: GHSA-p9pc-299p-vxgp"],"documentation":{"short":"Determines if the project has open, known unfixed vulnerabilities.","url":"https://github.com/ossf/scorecard/blob/f6ed084d17c9236477efd66e5b258b9d4cc7b389/docs/checks.md#vulnerabilities"}}]},"last_synced_at":"2025-08-24T16:09:45.659Z","repository_id":3162840,"created_at":"2025-08-24T16:09:45.659Z","updated_at":"2025-08-24T16:09:45.659Z"},"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":30075906,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-03-04T05:31:57.858Z","status":"ssl_error","status_checked_at":"2026-03-04T05:31:38.462Z","response_time":59,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["collectionview","grid","grid-layout","javascript","list","performance","react","recylerview","scroll","scrolling","typescript","uicollectionview","virtualization","virtualized","windowing"],"created_at":"2024-10-02T10:28:48.443Z","updated_at":"2026-03-04T08:01:15.827Z","avatar_url":"https://github.com/turbolent.png","language":"TypeScript","readme":"# collection-view\n\n[![Build Status](https://travis-ci.org/turbolent/collection-view.svg?branch=master)](https://travis-ci.org/turbolent/collection-view)\n\nA 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](#changing-the-data) (remove, add, move) and [changes to the layout](#changing-the-layout) are properly animated by the collection view. The library is inspired by [iOS' UICollectionView](https://developer.apple.com/documentation/uikit/uicollectionview) and [Android's RecyclerView](https://developer.android.com/guide/topics/ui/layout/recyclerview.html).\n\nThe collection view gets its data from a [delegate](#delegate) and gets its visual information from a layout. Currently there is a [grid layout](#grid-layout), which presents the collection in rows and columns, and a simple [list layout](#list-layout), which presents the collection in rows. [Custom layouts](#custom-layout) can be implemented easily. Contributions are welcome!\n\n![Scrolling](demo/scroll.gif)\n\nThe collection view also handles resizing of the container properly, maintaining the current position in the collection:\n\n![Resizing](demo/resize.gif)\n\nElements can be individually animated:\n\n![Staggering](demo/staggered.gif)\n\n![Pivot](demo/pivot.gif)\n\n\n## Usage\n\n```js\nimport { CollectionView, GridLayout } from 'collection-view'\n\nclass Delegate {\n  constructor(items) {\n    this.items = items\n  }\n\n  getCount() {\n    return this.items.length\n  }\n\n  configureElement(element, index) {\n    element.textContent = this.items[index]\n  }\n}\n\nlet items = [\"Item 1\", \"Item 2\", \"Item 3\", \"Item 4\", \"Item 5\", \"Item 6\", \"Item 7\", \"Item 8\", \"Item 9\", \"Item 10\"]\nlet delegate = new Delegate(items)\nlet layout = new GridLayout()\nlet contentElement = document.getElementById('content')\nlet view = new CollectionView(contentElement, layout, delegate)\n```\n\nImplement a [delegate](#delegate) for your collection. Instantiate a layout, like a [grid](#grid-layout) or [list](#list-layout), 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.\n\nIf the grid or list layouts do not fit your needs you can also [implement a custom layout](#custom-layout).\n\n\n## Delegate\n\nThe delegate object is responsible for defining how many items the collection view should display and configuring the elements  corresponding to the items.\n\n- **getCount(): _number_** (required)\n\n  Return the number of items in the collection.\n\n  Similar to [`UICollectionViewDataSource.collectionView(_:numberOfItemsInSection:)`](https://developer.apple.com/documentation/uikit/uicollectionviewdatasource/1618058-collectionview)\n\n- **configureElement(element: _HTMLElement_, index: _number_)** (required)\n\n  Configure the DOM element that corresponds to the item in the collection at the given index. The element might have previously been used to represent another item in the collection, so ensure to properly restore it to its initial state. If this method registers events, implement `invalidateElement` (see below) and make sure to unregister them there.\n\n  Similar to [`UICollectionViewDataSource.collectionView(_:cellForItemAtIndexPath:)`](https://developer.apple.com/documentation/uikit/uicollectionviewdatasource/1618029-collectionview)\n\n- **invalidateElement(element: _HTMLElement_, index: _number_)** (optional)\n\n  Called when an element no longer displays the item at the given index. Implement this method to e.g. unregister events.\n\n- **onScroll(view: _CollectionView_)** (optional)\n\n  Called when the collection view is scrolled.\n\n  Similar to [`UIScrollViewDelegate.scrollViewDidScroll(_:)`](https://developer.apple.com/documentation/uikit/uiscrollviewdelegate/1619392-scrollviewdidscroll)\n\n- **getStyle(index: _number_, phase: _CollectionViewAnimationPhase_, info, position: _Position_): _Style_** (optional)\n\n  Called to determine the style of the element at the given index for the given animation phase and position.\n  The returned style is an object with hyphen-style CSS properties and string values, e.g. `{\"background-color\": \"red\"}`.\n\n  See below for the `info` parameter.\n\n  - **phase: _CollectionViewAnimationPhase_**\n\n    - `ELEMENT_APPEARING`: The element is about to appear (\"is entering\")\n    - `ELEMENT_APPEARED`: The element has appeared\n    - `ELEMENT_DISAPPEARED`: The element has disappeared (\"has left\")\n\n- **getAnimation(index: _number_, info, property: _string_, reason: _CollectionViewAnimationReason_): _Animation_** (optional)\n\n  Return the animation for the given property of the element at the given index.\n\n  - **_Animation_**\n\n    - **duration: _number_** (optional): The duration of the CSS transition\n    - **delay: _number_** (optional): The delay of the CSS transition\n    - **timingFunction: _string_** (optional): The timing function of the CSS transition\n\n  See below for the `info` parameter.\n\n  - **reason: _CollectionViewAnimationReason_**\n\n    Indicates why the element is animated.\n\n    - `ELEMENT_ADDITION`: The element is being added\n    - `ELEMENT_REMOVAL`: The element is being removed\n    - `ELEMENT_MOVE`: The element is being repositioned\n    - `LAYOUT_UPDATE`: The layout is updated. This is also the case when the collection view is being resized.\n\nThe `getStyle` and `getAnimation` delegate methods are also passed an `info` parameter, which is layout information for the element, provided by the current layout.\nWhen 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.\n\n\n## Changing the data\n\nThe 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:\n\n**changeIndices(removed: _number[]_, added: _number[]_, moved: _Map.\u003cnumber, number\u003e_): Promise**\n\n* **removed: _number[]_**\n\n  Indices which were removed, referring to the collection before the changes\n\n* **added: _number[]_**\n\n  Indices which were added, referring to the collection after the changes\n\n* **moved: _Map.\u003cnumber, number\u003e_**\n\n  Indices which were moved. The keys are indices referring to the collection before the changes, and the values are indices referring to the collection after the changes.\n\n  May also be passed as an _Object.\u003cstring, number\u003e_\n\n![](demo/change-data.gif)\n\nFor 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]:\n\n* The items at indices [1, 4, 6, 8] in the original collection are not in the target collection anymore (**removed**):\n\n  [1, **2**, 3, 4, **5**, 6, **7**, 8, **9**, 10, 11]\n\n* The items at indices [1, 2] in the target collection are new in the target collection (**added**):\n\n  [1, **15**, **16**, 3, 6, 8, 4, 10, 11]\n\n* The item at index 3 in the original collection is now at index 6 in the target collection (**moved**):\n\n  [1, 2, 3, **4**, 5, 6, 7, 8, 9, 10, 11]\n\n  [1, 15, 16, 3, 6, 8, **4**, 10, 11]\n\nTherefore, 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).\n\nSimilar to calling [`UICollectionView.deleteItems(at:)`](https://developer.apple.com/documentation/uikit/uicollectionview/1618060-deleteitems), [`UICollectionView.insertItems(at:)`](https://developer.apple.com/documentation/uikit/uicollectionview/1618097-insertitems), and multiple [`UICollectionView.moveItem(at:to:)`](https://developer.apple.com/documentation/uikit/uicollectionview/1618059-moveitem) as part of a call to [`performBatchUpdates(_:completion:)`](https://developer.apple.com/documentation/uikit/uicollectionview/1618045-performbatchupdates)\n\n\n## Grid layout\n\nThe `GridLayout` displays collection items in a grid. All items are the same size and flow from\none row or column (depending on the direction) to the next.\n\nIt is similar to [`UICollectionViewFlowLayout`](https://developer.apple.com/library/ios/documentation/UIKit/Reference/UICollectionViewFlowLayout_class/).\n\n\n* **direction: _Direction_**\n\n  The direction in which the collection view scrolls.\n\n  If `Direction.VERTICAL`, the collection view scrolls vertically and items flow in rows from left to right.\n\n  If `Direction.HORIZONTAL`, the collection view scrolls horizontally and items flow in columns from top to bottom.\n\n  Default: `Direction.VERTICAL`\n\n  Similar to [`UICollectionViewFlowLayout.scrollDirection`](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/1617720-scrolldirection)\n\n\n* **itemSize: _Size_**\n\n  The size (width and height) of each item.\n\n  Default: `new Size(200, 200)`\n\n  Similar to [`UICollectionViewFlowLayout.itemSize`](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/1617711-itemsize)\n\n\n* **spacing: _Spacing_**\n\n  The spacing (horizontal and vertical) between the items.\n\n  Default: `new Spacing(20, 20)`\n\n  Similar to [`UICollectionViewFlowLayout.minimumInteritemSpacing`](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/1617706-minimuminteritemspacing) and [`UICollectionViewFlowLayout.minimumLineSpacing`](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/1617717-minimumlinespacing)\n\n\n* **insets: _Insets_**\n\n  The insets (padding) of the whole content: top, bottom, left, right.\n\n  Default: `new Insets(10, 10, 10, 10)`\n\n  Similar to [`UICollectionViewFlowLayout.sectionInset`](https://developer.apple.com/documentation/uikit/uicollectionviewflowlayout/1617714-sectioninset)\n\n\n## List layout\n\nThe `ListLayout` displays collection items in a list. All items have the same height.\n\n* **rowHeight: _number_**\n\n  The height of each row.\n\n  Default: `200`\n\n\n## Changing the layout\n\nThe collection view supports transitions between different layouts. Simply instantiate a new layout, configure it, and call:\n\n**updateLayout(newLayout: _CollectionViewLayout_): Promise**\n\nFor example, this allows changing the item size or direction of a [grid layout](#grid-layout). The collection view properly maintains the position in the collection.\n\n![](demo/change-size.gif)\n\n![](demo/change-direction.gif)\n\n\n## Custom layout\n\nThe 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](#grid-layout) and [list layout](#list-layout) should be sufficient in most use-cases. Still, if another layout is desired, the following methods need to be implemented:\n\n- **getContentSize(count: _number_, containerSize: _Size_): _Size_** (required)\n\n  Return the width and height of the whole content, i.e. the space that all elements occupy, not just the content that is currently visible.\n\n  Similar to [`UICollectionViewLayout.collectionViewContentSize`](https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617796-collectionviewcontentsize)\n\n- **updateContainerSize(containerSize: _Size_)** (optional)\n\n  Informs the layout about the new size of the container. Might be used to recalculate positioning information.\n\n- **getIndices(ranges: _Ranges_, count: _number_, containerSize: _Size_): _number[]_** (required)\n\n  Return an array of the visible indices in the region (given by ranges). The given container size might be different from the container size provided to `updateContainerSize` if the collection view is updated to another layout.\n\n  Similar to [`UICollectionViewLayout.layoutAttributesForElements(in:)`](https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617769-layoutattributesforelements)\n\n- **getElementPosition(index: _number_): _Position_** (required)\n\n  Return the top-left position of the element representing the item at the specified index in the collection.\n\n  Similar to [`UICollectionViewLayout.layoutAttributesForItem(at:)`](https://developer.apple.com/documentation/uikit/uicollectionviewlayout/1617797-layoutattributesforitem)\n\n- **configureElement(element: _HTMLElement_, index: _number_)** (required)\n\n  Apply visual details to the element, e.g. set the size.\n\n- **convertPositionInSize(position: _Position_, newContainerSize: _Size_, oldLayout: _CollectionViewLayout_): _Position_** (required)\n\n  Calculate the new scroll position for the given current scroll position in the given layout. The old layout may be of another type. Used to maintain the current scroll position in the collection view when it is transitioning to another layout and when the collection view is resizing.\n\n\n## Collection view\n\n* **contentSize: _Size_**\n\n  The size of the scrolled content. Computed by the layout based on the data returned from the delegate.\n\n  Similar to [`UIScrollView.contentSize`](https://developer.apple.com/documentation/uikit/uiscrollview/1619399-contentsize)\n\n* **containerSize: _Size_**\n\n  The size of the container wrapping the scrolled content, i.e. the size of the content that is actually displayed, a region of `contentSize`.\n\n* **scrollPosition: _Position_**\n\n  The point at which the origin of the content is offset from the origin of the collection view.\n\n  Similar to [`UIScrollView.contentOffset`](https://developer.apple.com/documentation/uikit/uiscrollview/1619404-contentoffset)\n\n* **thresholds: _object_**\n\n  Specifies the additional values by which the region is extended that is used to determine the visible elements. Increasing the values leads to more elements staying attached to the scroll element. This improves appearance, as elements are already properly positioned and configured when they are becoming visible to the user. However, it is also likely to reduce scroll performance, as more elements need to be rendered by the browser.\n\n  Keys: `left`, `top`, `right`, and `bottom`.\n\n  Default: all values are `CollectionView.DEFAULT_THRESHOLD` = `3000`\n\n* **animationDuration: _number_**\n\n  Specifies how long animations take by default. Animations durations for each element can also be provided through the delegate method `getAnimation`.\n\n  Default: `CollectionView.DEFAULT_ANIMATION_DURATION` = `400`\n\n\n## Examples\n\nThe `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`.\n\n## React\n\nFor usage with React, see `examples/react`.\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturbolent%2Fcollection-view","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fturbolent%2Fcollection-view","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fturbolent%2Fcollection-view/lists"}