{"id":14970974,"url":"https://github.com/micha-lmxt/svelte-window","last_synced_at":"2025-10-26T14:30:51.587Z","repository":{"id":52197017,"uuid":"342306875","full_name":"micha-lmxt/svelte-window","owner":"micha-lmxt","description":"Svelte components for efficiently rendering large, scrollable lists and tabular data. Port of react-window to Svelte.","archived":false,"fork":false,"pushed_at":"2022-10-13T22:47:58.000Z","size":100,"stargazers_count":57,"open_issues_count":3,"forks_count":4,"subscribers_count":2,"default_branch":"master","last_synced_at":"2024-09-28T13:42:43.182Z","etag":null,"topics":["grid","react","react-virtualized","react-window","svelte","tables","virtualization"],"latest_commit_sha":null,"homepage":"https://gradientdescent.de/porting-react-window/","language":"Svelte","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/micha-lmxt.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2021-02-25T16:26:52.000Z","updated_at":"2024-09-27T18:23:23.000Z","dependencies_parsed_at":"2022-09-05T07:10:51.790Z","dependency_job_id":null,"html_url":"https://github.com/micha-lmxt/svelte-window","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micha-lmxt%2Fsvelte-window","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micha-lmxt%2Fsvelte-window/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micha-lmxt%2Fsvelte-window/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/micha-lmxt%2Fsvelte-window/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/micha-lmxt","download_url":"https://codeload.github.com/micha-lmxt/svelte-window/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":219862755,"owners_count":16555951,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["grid","react","react-virtualized","react-window","svelte","tables","virtualization"],"created_at":"2024-09-24T13:44:26.739Z","updated_at":"2025-10-26T14:30:51.276Z","avatar_url":"https://github.com/micha-lmxt.png","language":"Svelte","funding_links":[],"categories":[],"sub_categories":[],"readme":"# svelte-window\n\n\u003e Svelte components for efficiently rendering large, scrollable lists and tabular data. Port of react-window to Svelte.\n\nSvelte window works by only rendering *part* of a large data set (just enough to fill the viewport). This helps address some common performance bottlenecks:\n1. It reduces the amount of work (and time) required to render the initial view and to process updates.\n2. It reduces the memory footprint by avoiding over-allocation of DOM nodes.\n\n[![NPM license](https://img.shields.io/badge/license-mit-red.svg?style=for-the-badge)](LICENSE.md)\n\n## Install\n\n```bash\nnpm install --save-dev svelte-window\n```\n\n## Usage\n\nThis library is a port of react-window, here are some examples: [react-window.now.sh](https://react-window.now.sh/).\n\nThis is how to render a basic list:\n\n\n```svelte\n\u003cscript\u003e\n    import { FixedSizeList as List, styleString as sty } from 'svelte-window';\n\u003c/script\u003e\n\u003cList\nheight={150}\nitemCount={1000}\nitemSize={35}\nwidth={300}\nlet:items\u003e\n    {#each items as it (it.key)}\n        \u003cdiv style={sty(it.style)}\u003eRow {it.index}\u003c/div\u003e        \n    {/each}\n\u003c/List\u003e\n```\n\nHere is another example with a fixed size grid with a scroll-to button, scrolling indicators:\n\n```svelte\n\u003cscript\u003e\n  import { FixedSizeGrid as Grid, styleString as sty } from 'svelte-window'\n\n  let grid\n\n  const click = () =\u003e {\n    if (grid) {\n      grid.scrollToItem({\n        align: 'start',\n        columnIndex: 150,\n        rowIndex: 300,\n      })\n    }\n  }\n\u003c/script\u003e\n\n\u003cGrid\n  bind:this={grid}\n  columnCount={1000}\n  columnWidth={100}\n  height={150}\n  rowCount={1000}\n  rowHeight={35}\n  width={300}\n  useIsScrolling\n  let:items\u003e\n  {#each items as it (it.key)}\n    \u003cdiv style={sty(it.style)}\u003e\n      {it.isScrolling ? 'Scrolling' : `Row ${it.rowIndex} - Col ${it.columnIndex}`}\n    \u003c/div\u003e\n  {/each}\n\u003c/Grid\u003e\n\n\u003cbutton on:click={click}\u003e To row 300, column 150 \u003c/button\u003e\n```\n\n#### Calendar example with VariableSizeGrid\n\nHere is a more complex example. Each column represents a date, workday coluns are wider than weekend columns. A sparse dataset is called.\n\n```svelte\n\u003cscript lang=\"ts\"\u003e\n  import { VariableSizeGrid as Grid, styleString as sty } from 'svelte-window';\n  const startDate = new Date(\"1/1/2022\");\n  const dateCell = (rowIndex:number,columnIndex:number)=\u003e{\n    return new Date(startDate.getTime() + \n      1000 * 60 * 60 * 8  + // start at 8 o'clock\n      1000 * 60 * 60 * rowIndex + // each row adds an hour\n      1000 * 60 * 60 * 24 * columnIndex // each column adds a day\n    )\n  }\n \n  const isWorkday = (index)=\u003e{\n    const offset = startDate.getDay();\n    const d = (index + offset) % 7;\n    //return true on monday to friday\n    return d!==0 \u0026\u0026 d !== 6; \n  }\n\n  const columnWidth = (index)=\u003eisWorkday(index) ? 200 : 100\n\n  //round date to full hours\n  const formatDate = (date:Date)=\u003eMath.round(date.getTime() / (1000 * 60 * 60 )) \n\n  //sparse event data\n  const rawEvents = [\n    {date:new Date(\"1/4/2022 10:00\"), event:\"Pilates\"},\n    {date:new Date(\"1/11/2022 11:00\"), event:\"Zumba\"},\n    {date:new Date(\"1/18/2022 11:00\"), event:\"Pilates\"},\n    {date:new Date(\"1/25/2022 10:00\"), event:\"Zumba\"},\n    //etc.\n  ]\n  \n  //format for quick access\n  const events = rawEvents.reduce(\n    (p,v)=\u003e{\n      p[formatDate(v.date)] = v\n      return p\n    },{}\n  )\n  \n\u003c/script\u003e\n\n\u003cGrid\n  columnCount={1000}\n  {columnWidth}\n  height={150}\n  rowCount={12}\n  rowHeight={()=\u003e95}\n  width={300}\n  let:items\u003e\n  {#each items as it (it.key)}\n    \u003cdiv style={sty(it.style)}\u003e\n      {dateCell(it.rowIndex, it.columnIndex)}\n      {#if events[formatDate(dateCell(it.rowIndex,it.columnIndex))]}\n        {events[formatDate(dateCell(it.rowIndex,it.columnIndex))].event}\n      {/if}\n    \u003c/div\u003e\n  {/each}\n\u003c/Grid\u003e\n```\n\n\n### SvelteKit\n\nThis section is probably obsolete. SvelteKit is pretty stable today, so no problems should occur. \n----\nSvelteKit is in public beta, so a 100% compatibility cannot be guaranteed. Since version 1.2.0 `svelte-window` should work with SvelteKit when imported as a devDependency (`npm i --save-dev svelte-window`). By design, `svelte-window` is a client side library. Normal components like `FixedSizeList` need to be guarded from server-side-rendering (eg. with a `{#if mounted}...` clause). For convenience, there are SSR counterparts to all four components, which handle guarding within the library: `FixedSizeListSSR`, `FixedSizeGridSSR`, `VariableSizeListSSR`, `VariableSizeGridSSR`. In the examples above, just change eg.:\n\n```javascript\n\u003cscript\u003e\n    import { FixedSizeList as List, styleString as sty } from 'svelte-window';\n\u003c/script\u003e\n...\n```\n\nto \n\n```javascript\n\u003cscript\u003e\n    import { FixedSizeListSSR as List, styleString as sty } from 'svelte-window';\n\u003c/script\u003e\n...\n```\n---\n\n## Bundle Size\n\nIf you don't use all of `svelte-window`s components on a page, you can minimize the bundle size by using direct imports from the `lib` folder. Eg. you can change imports like this\n\n```javascript\nimport { FixedSizeListSSR as List, styleString as sty } from 'svelte-window';\n```\n\nto\n\n```javascript\nimport List from 'svelte-window/lib/FixedSizeListSSR.svelte';\nimport {styleString as sty} from 'svelte-window/src/styleString';\n```\n\n## Differences to the React library\n\n1. Grids and lists don't actively render the children. Instead, an array of item information is passed down via item props. You can use the [let:item](https://svelte.dev/tutorial/slot-props) to access it and render with the [each block](https://svelte.dev/tutorial/each-blocks).\n2. Styles are passed down as objects, like in the React library, but Svelte only accepts strings for style. A helper function `styleString` is exported from `svelte-window`, to convert the style object to string\n3. Variable sized variants have utilities to reset the cache, when row/cell sizes change. These are not directly added to the class, but to a member called `instance`. Eg. instead of\n\n```javascript\nlist.resetAfterIndex(...)\n```\n\nuse \n\n```javascript\nlist.instance.resetAfterIndex(...)\n```\n\nAffected functions:\n\nVariableSizeList:\n\n- resetAfterIndex\n\nVariableSizeGrid:\n\n- resetAfterIndices\n- resetAfterColumnIndex\n- resetAfterRowIndex\n\n## Related libraries\n\n* [`svelte-virtualized-auto-sizer`](https://npmjs.com/package/svelte-virtualized-auto-sizer): HOC that grows to fit all of the available space and passes the width and height values to its child.\n\n## More information\n\n[Here is a blog post](https://gradientdescent.de/porting-react-window) about how the library was ported from React to Svelte.\n\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicha-lmxt%2Fsvelte-window","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmicha-lmxt%2Fsvelte-window","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmicha-lmxt%2Fsvelte-window/lists"}