{"id":24271707,"url":"https://github.com/soenneker/soenneker.blazor.masonry","last_synced_at":"2026-06-09T07:01:28.359Z","repository":{"id":65673569,"uuid":"597071685","full_name":"soenneker/soenneker.blazor.masonry","owner":"soenneker","description":"A Blazor interop library that integrates Masonry, the cascading grid layout library","archived":false,"fork":false,"pushed_at":"2026-06-05T20:43:38.000Z","size":2661,"stargazers_count":15,"open_issues_count":4,"forks_count":5,"subscribers_count":1,"default_branch":"main","last_synced_at":"2026-06-05T21:11:10.598Z","etag":null,"topics":["blazor","csharp","css","dotnet","grid-layout","interop","masonry"],"latest_commit_sha":null,"homepage":"https://soenneker.com","language":"CSS","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/soenneker.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":".github/CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":".github/CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":".github/SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"github":"soenneker","thanks_dev":"soenneker"}},"created_at":"2023-02-03T15:09:40.000Z","updated_at":"2026-06-05T19:19:49.000Z","dependencies_parsed_at":"2023-11-23T02:36:35.218Z","dependency_job_id":"78e395a0-66c7-4d03-b22d-fbb4633aae01","html_url":"https://github.com/soenneker/soenneker.blazor.masonry","commit_stats":{"total_commits":6,"total_committers":1,"mean_commits":6.0,"dds":0.0,"last_synced_commit":"fe4b3689c36bd02095e30c8dad9100694e95500f"},"previous_names":[],"tags_count":374,"template":false,"template_full_name":null,"purl":"pkg:github/soenneker/soenneker.blazor.masonry","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.blazor.masonry","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.blazor.masonry/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.blazor.masonry/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.blazor.masonry/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/soenneker","download_url":"https://codeload.github.com/soenneker/soenneker.blazor.masonry/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/soenneker%2Fsoenneker.blazor.masonry/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33961252,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-05T02:00:06.157Z","response_time":120,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"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":["blazor","csharp","css","dotnet","grid-layout","interop","masonry"],"created_at":"2025-01-15T17:59:20.613Z","updated_at":"2026-06-05T22:01:03.872Z","avatar_url":"https://github.com/soenneker.png","language":"CSS","funding_links":["https://github.com/sponsors/soenneker","https://thanks.dev/soenneker"],"categories":[],"sub_categories":[],"readme":"[![](https://img.shields.io/nuget/v/Soenneker.Blazor.Masonry.svg?style=for-the-badge)](https://www.nuget.org/packages/Soenneker.Blazor.Masonry/)\n[![](https://img.shields.io/github/actions/workflow/status/soenneker/soenneker.blazor.masonry/publish-package.yml?style=for-the-badge)](https://github.com/soenneker/soenneker.blazor.masonry/actions/workflows/publish-package.yml)\n[![](https://img.shields.io/nuget/dt/Soenneker.Blazor.Masonry.svg?style=for-the-badge)](https://www.nuget.org/packages/Soenneker.Blazor.Masonry/)\n[![](https://img.shields.io/github/actions/workflow/status/soenneker/soenneker.blazor.masonry/codeql.yml?label=CodeQL\u0026style=for-the-badge)](https://github.com/soenneker/soenneker.blazor.masonry/actions/workflows/codeql.yml)\n\n# ![](https://user-images.githubusercontent.com/4441470/224455560-91ed3ee7-f510-4041-a8d2-3fc093025112.png) Soenneker.Blazor.Masonry ??\n### A lightweight, responsive **Blazor** component for Masonry (the cascading grid layout library) � perfect for image grids, cards, and dynamic content.\n\n## ? Features\n\n- Fully compatible with Bootstrap grid classes\n- Script auto-loading (CDN or embedded)\n- No manual cleanup required\n\n## Installation\n\n```\ndotnet add package Soenneker.Blazor.Masonry\n```\n\n## Usage\n\n1. Register the interop within DI (`Program.cs`)\n\n```csharp\npublic static async Task Main(string[] args)\n{\n    ...\n    builder.Services.AddMasonryInteropAsScoped();\n}\n```\n\n## ?? Components\n\n### `Masonry`\n\nWraps a group of items in a Masonry layout.\n\n```razor\n\u003cMasonry AutoRender=\"true\" class=\"row\"\u003e // or if not Bootstrap, a different class\n    ...\n\u003c/Masonry\u003e\n```\n\n**Parameters:**\n\n- `AutoRender` � Automatically initializes layout after render\n- `SizerClass` � Automatically adds a sizer with the given class(es). Used by Masonry to determine width of a single column.\n\n### `MasonryItem`\n\nWraps a single item in the layout and adds the required class.\n\n```razor\n\u003cMasonryItem class=\"col-md-6\"\u003e\n    \u003cdiv class=\"card\"\u003e...\u003c/div\u003e\n\u003c/MasonryItem\u003e\n```\n\nAutomatically appends `masonry-item` to the `class` attribute.\n\n---\n\n## ?? Example\n\n```razor\n\u003cMasonry AutoRender=\"false\" SizerClass=\"col-sm-1\" @ref=\"_masonry\" class=\"row\"\u003e\n    @foreach (var card in _cards)\n    {\n        \u003cMasonryItem class=\"col-lg-4 col-md-6 mb-4\"\u003e\n            \u003cdiv class=\"card\"\u003e\n                \u003cimg src=\"@card.ImageUrl\" class=\"card-img-top\" /\u003e\n                \u003cdiv class=\"card-body\"\u003e\n                    \u003ch5\u003e@card.Title\u003c/h5\u003e\n                    \u003cp\u003e@card.Text\u003c/p\u003e\n                \u003c/div\u003e\n            \u003c/div\u003e\n        \u003c/MasonryItem\u003e\n    }\n\u003c/Masonry\u003e\n\n@code {\n    private Masonry _masonry = null!;\n\n    protected override async Task OnAfterRenderAsync(bool firstRender)\n    {\n        if (firstRender)\n        {\n            // Example delay for images to load\n            await Task.Delay(3000); \n            await _masonry.Init();\n        }\n    }\n}\n```\n\n---\n\n## ?? Initialization\n\n- If `AutoRender` is `true`, Masonry initializes on first render.\n- If `false`, call `Init()` manually when ready (e.g., after images load).\n- **No disposal needed** � cleanup is handled automatically when navigating away.\n\n## ?? Manual Interop Usage\n\nIf you want full control without using the `Masonry` component, you can use the provided `IMasonryInterop` service directly.\n\n```csharp\n@inject IMasonryInterop MasonryInterop\n```\n\n### Warmup (Script Load)\n\n```csharp\nawait MasonryInterop.Warmup(); // Loads Masonry script from CDN\n```\n\nOr use the embedded version:\n\n```csharp\nawait MasonryInterop.Warmup(useCdn: false);\n```\n\n### Initialize Layout\n\n```csharp\nawait MasonryInterop.Init(\"myElementId\");\n```\n\nAdvanced options:\n\n```csharp\nawait MasonryInterop.Init(\n    elementId: \"gallery\",\n    containerSelector: \"#gallery\",\n    itemSelector: \".masonry-item\",\n    columnWidthSelector: \".masonry-sizer\",\n    percentPosition: true,\n    transitionDurationSecs: 0.25f,\n    useCdn: true\n);\n```\n\n### Force Layout Recalculation\n\n```csharp\nawait MasonryInterop.Layout(\"gallery\");\n```\n\n### Set Up Mutation Observer\n\n```csharp\nawait MasonryInterop.CreateObserver(\"gallery\");\n```\n\n### Destroy Instance\n\n```csharp\nawait MasonryInterop.Destroy(\"gallery\");\n```\n\n\u003e ?? **Note:** The `Masonry` component handles these automatically. Use manual interop when building custom wrappers or integrations.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoenneker%2Fsoenneker.blazor.masonry","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fsoenneker%2Fsoenneker.blazor.masonry","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fsoenneker%2Fsoenneker.blazor.masonry/lists"}