{"id":13810446,"url":"https://github.com/janosh/svelte-bricks","last_synced_at":"2026-01-17T16:29:15.187Z","repository":{"id":40399572,"uuid":"305065373","full_name":"janosh/svelte-bricks","owner":"janosh","description":"Naive Svelte Masonry component without column balancing (ragged columns at the bottom)","archived":false,"fork":false,"pushed_at":"2024-10-07T16:34:20.000Z","size":300,"stargazers_count":105,"open_issues_count":4,"forks_count":4,"subscribers_count":3,"default_branch":"main","last_synced_at":"2024-10-12T15:56:52.907Z","etag":null,"topics":["layout","masonry","pinterest-layout","svelte","svelte-kit","typescript"],"latest_commit_sha":null,"homepage":"https://janosh.github.io/svelte-bricks","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/janosh.png","metadata":{"files":{"readme":"readme.md","changelog":"changelog.md","contributing":null,"funding":null,"license":"license","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2020-10-18T09:24:41.000Z","updated_at":"2024-10-07T18:08:14.000Z","dependencies_parsed_at":"2023-02-13T14:01:10.338Z","dependency_job_id":"57e86844-ae43-4c02-9356-4b6053567bc6","html_url":"https://github.com/janosh/svelte-bricks","commit_stats":{"total_commits":49,"total_committers":2,"mean_commits":24.5,"dds":"0.10204081632653061","last_synced_commit":"6b7085029c5f6b5a0671a833da97fa8ac283ed15"},"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janosh%2Fsvelte-bricks","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janosh%2Fsvelte-bricks/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janosh%2Fsvelte-bricks/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/janosh%2Fsvelte-bricks/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/janosh","download_url":"https://codeload.github.com/janosh/svelte-bricks/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248647258,"owners_count":21139081,"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":["layout","masonry","pinterest-layout","svelte","svelte-kit","typescript"],"created_at":"2024-08-04T02:00:53.945Z","updated_at":"2026-01-17T16:29:15.171Z","avatar_url":"https://github.com/janosh.png","language":"Svelte","funding_links":[],"categories":["Svelte"],"sub_categories":[],"readme":"\u003cdiv class=\"hide-in-docs\"\u003e\n\n\u003ch1 align=\"center\"\u003e\n  \u003cimg src=\"https://raw.githubusercontent.com/janosh/svelte-bricks/main/static/favicon.svg\" alt=\"Logo\" height=60\u003e\n  \u003cbr\u003e\u0026ensp;Svelte Bricks\n\u003c/h1\u003e\n\n\u003ch4 align=\"center\"\u003e\n\n[![Tests](https://github.com/janosh/svelte-bricks/actions/workflows/test.yml/badge.svg)](https://github.com/janosh/svelte-bricks/actions/workflows/test.yml)\n[![NPM version](https://img.shields.io/npm/v/svelte-bricks?color=blue\u0026logo=NPM)](https://npmjs.com/package/svelte-bricks)\n[![GitHub Pages](https://github.com/janosh/svelte-bricks/actions/workflows/gh-pages.yml/badge.svg)](https://github.com/janosh/svelte-bricks/actions/workflows/gh-pages.yml)\n[![Open in StackBlitz](https://img.shields.io/badge/Open%20in-StackBlitz-darkblue?logo=stackblitz)](https://stackblitz.com/github/janosh/svelte-bricks)\n\n\u003c/h4\u003e\n\nSvelte masonry component with SSR support (via CSS container queries) and automatic column balancing. **[Live demo](https://janosh.github.io/svelte-bricks)**\n\n\u003c/div\u003e\n\n## Installation\n\n```sh\npnpm add -D svelte-bricks\n```\n\n## Usage\n\nThe kitchen sink for this component looks something like this:\n\n```svelte\n\u003cscript\u003e\n  import Masonry from 'svelte-bricks'\n\n  let nItems = $state(30);\n  let items = $derived([...Array(nItems).keys()])\n\n  let [minColWidth, maxColWidth, gap] = [200, 800, 20]\n  let width = $state(0), height = $state(0)\n\u003c/script\u003e\n\nMasonry size: \u003cspan\u003e{width}px\u003c/span\u003e \u0026times; \u003cspan\u003e{height}px\u003c/span\u003e (w \u0026times; h)\n\n\u003cMasonry\n  {items}\n  {minColWidth}\n  {maxColWidth}\n  {gap}\n  style=\"padding: 20px;\"\n  columnStyle=\"background-color: rgba(0, 0, 0, 0.1);\"\n  bind:masonryWidth={width}\n  bind:masonryHeight={height}\n\u003e\n  {#snippet children({ item })}\n    \u003cSome {item} /\u003e\n  {/snippet}\n\u003c/Masonry\u003e\n```\n\n**Note**: If `items` is an array of objects, this component tries to access an `id` property on each item. This value is used to tell items apart in the keyed `{#each}` block that creates the masonry layout. Without it, Svelte could not avoid duplicates when new items are added or existing ones rearranged. Read the [Svelte docs](https://svelte.dev/docs/svelte/each#Keyed-each-blocks) for details. To change the name of the identifier key, pass `idKey=\"some-uniq-key`. Or pass a function `getId = (item: Item) =\u003e string | number` that maps items to unique IDs.\n\n## Props\n\n`Masonry.svelte` expects an array of `items` as well as a `\u003cslot /\u003e` component used to render each of the `items`. The array can contain whatever data (objects, strings, numbers) as long as the slot component knows how to handle it.\n\nAdditional optional props are:\n\n1. ```ts\n   animate: boolean = true\n   ```\n\n   Whether to [FLIP-animate](https://svelte.dev/docs/svelte/svelte-animate) masonry items when viewport resizing or other events cause `items` to rearrange.\n\n1. ```ts\n   balance: boolean = true\n   ```\n\n   Enable height-based column balancing. Items are distributed to the shortest column for a more even layout. Set to `false` for simple round-robin distribution.\n\n1. ```ts\n   calcCols = (\n     masonryWidth: number,\n     minColWidth: number,\n     gap: number,\n   ): number =\u003e {\n     return Math.min(\n       items.length,\n       Math.floor((masonryWidth + gap) / (minColWidth + gap)) || 1,\n     )\n   }\n   ```\n\n   Function used to compute the number of columns based on the masonry width, minimum column width and gap.\n\n1. ```ts\n   class: string = ``\n   ```\n\n   Applies to the outer `div` wrapping all masonry columns. For use with CSS frameworks like Tailwind.\n\n1. ```ts\n   columnClass: string = ``\n   ```\n\n   Applies to each column `div`.\n\n1. ```ts\n   duration: number = 200\n   ```\n\n   Transition duration in milli seconds when masonry items are rearranged or added/removed. Set to 0 to disable transitions.\n\n1. ```ts\n   gap: number = 20\n   ```\n\n   Gap between columns and items within each column in `px`.\n\n1. ```ts\n   getId = (item: Item): string | number =\u003e {\n     if (typeof item === `number`) return item\n     if (typeof item === `string`) return item\n     return item[idKey]\n   }\n   ```\n\n   Custom function that maps masonry items to unique IDs of type `string` or `number`.\n\n1. ```ts\n   idKey: string = `id`\n   ```\n\n   Name of the attribute to use as identifier if items are objects.\n\n1. ```ts\n   items: Item[]\n   ```\n\n   The only required prop is the list of items to render where `Item` is a generic type (via `generics=\"Item\"`) which usually will be `object` but can also be simple types `string` or `number`.\n\n1. ```ts\n   masonryHeight: number = 0\n   ```\n\n   The masonry `div`s height in `px`.\n\n1. ```ts\n   masonryWidth: number = 0\n   ```\n\n   The masonry `div`s width in `px`.\n\n1. ```ts\n   maxColWidth: number = 500\n   ```\n\n   Maximum column width in `px`.\n\n1. ```ts\n   minColWidth: number = 330\n   ```\n\n   Minimum column width in `px`.\n\n1. ```ts\n   style: string = ``\n   ```\n\n   Inline styles that will be applied to the top-level `div.masonry`.\n\n## Virtual Scrolling\n\nFor large lists (1000+ items), enable virtual scrolling to render only visible items:\n\n```svelte\n\u003cMasonry\n  {items}\n  virtualize={true}\n  height={600}\n  getEstimatedHeight={(item) =\u003e item.height ?? 150}\n  overscan={5}\n\u003e\n  {#snippet children({ item })}\n    \u003cCard {item} /\u003e\n  {/snippet}\n\u003c/Masonry\u003e\n```\n\n### Virtualization Props\n\n1. ```ts\n   virtualize: boolean = false\n   ```\n\n   Enable virtual scrolling. When `true`, only visible items are rendered. Requires the `height` prop.\n\n1. ```ts\n   height: number | string\n   ```\n\n   Required when `virtualize=true`. Sets the scroll container height (e.g., `500` for pixels or `\"80vh\"`).\n\n1. ```ts\n   getEstimatedHeight?: (item: Item) =\u003e number\n   ```\n\n   Optional function that returns an estimated height for items before they're measured. Defaults to 150px if not provided. Better estimates = less layout shift.\n\n1. ```ts\n   overscan: number = 5\n   ```\n\n   Number of items to render above and below the visible area. Higher values reduce flicker during fast scrolling but render more items.\n\n**Notes:**\n\n- FLIP animations are automatically disabled when virtualizing\n- Balance mode works with estimated heights until items are measured\n- The masonry div becomes a scroll container (`overflow-y: auto`)\n\n## Styling\n\nBesides inline CSS which you can apply through the `style` prop, the following `:global()` CSS selectors can be used for fine-grained control of wrapper and column styles:\n\n```css\n:global(div.masonry) {\n  /* top-level wrapper div */\n}\n:global(div.masonry div.col) {\n  /* each column in the masonry layout */\n}\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanosh%2Fsvelte-bricks","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fjanosh%2Fsvelte-bricks","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fjanosh%2Fsvelte-bricks/lists"}