PHPackages                             secretninjas/filament-masonry - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [Utility &amp; Helpers](/categories/utility)
4. /
5. secretninjas/filament-masonry

ActiveLibrary[Utility &amp; Helpers](/categories/utility)

secretninjas/filament-masonry
=============================

Masonry CSS Grid layout for Filament v5 dashboards

v1.0.1(2mo ago)029↓21.4%MITPHPPHP ^8.3

Since Jun 18Pushed 2mo agoCompare

[ Source](https://github.com/secretninjas/filament-masonry)[ Packagist](https://packagist.org/packages/secretninjas/filament-masonry)[ RSS](/packages/secretninjas-filament-masonry/feed)WikiDiscussions main Synced 1w ago

READMEChangelogDependencies (1)Versions (3)Used By (0)

secretninjas/filament-masonry
=============================

[](#secretninjasfilament-masonry)

A Filament v5 plugin that replaces the default dashboard widget grid with a **CSS Grid dense-packed masonry layout** — no DOM height measurements, no JavaScript layout engine, no gaps.

Requirements
------------

[](#requirements)

- PHP 8.3+
- Laravel 12+
- Filament 5.x

Installation
------------

[](#installation)

```
composer require secretninjas/filament-masonry
```

Setup
-----

[](#setup)

### 1. Register the plugin

[](#1-register-the-plugin)

Add `MasonryPlugin` to every panel that should use masonry dashboards:

```
use SecretNinjas\FilamentMasonry\MasonryPlugin;

->plugins([
    MasonryPlugin::make(),
])
```

The defaults are `['default' => 1, 'sm' => 2, 'xl' => 4]`. Override with `->columns([...])` if you need different breakpoints:

```
MasonryPlugin::make()
    ->columns(['default' => 1, 'lg' => 3, '2xl' => 6])
```

### 2. Enable masonry on your Dashboard page

[](#2-enable-masonry-on-your-dashboard-page)

Add `HasMasonryDashboard` to any `Dashboard` page class:

```
use SecretNinjas\FilamentMasonry\Concerns\HasMasonryDashboard;

class Dashboard extends BaseDashboard
{
    use HasMasonryDashboard;

    // ... existing getWidgets(), getColumns(), etc.
}
```

That's it. No other Dashboard changes required.

### 3. Size your widgets (optional but recommended)

[](#3-size-your-widgets-optional-but-recommended)

Add `HasMasonryLayout` to each widget to control how many grid columns and rows it occupies:

```
use SecretNinjas\FilamentMasonry\Concerns\HasMasonryLayout;
use SecretNinjas\FilamentMasonry\Enums\WidgetSize;

class RevenueWidget extends Widget
{
    use HasMasonryLayout;

    protected static WidgetSize $size = WidgetSize::Large;
    protected static int $order = 10;
}
```

Widgets **without** the trait continue to work — they fall back to their existing `$columnSpan` value, treated as 1 row.

Widget sizes
------------

[](#widget-sizes)

SizeColumnsRowsUse for`Small`11KPI card, compact list`Medium`21Standard table, chart`Large`32Tall table, multi-row chart`FullWidth`41Stats bar, wide summary tableWidget ordering
---------------

[](#widget-ordering)

`$order` replaces Filament's `$sort` when the trait is present. Lower = rendered first. The trait overrides `getSort()` so Filament's own widget-sort mechanism stays in sync.

How it works
------------

[](#how-it-works)

The layout uses pure CSS:

```
display: grid;
grid-auto-flow: dense;
grid-template-columns: repeat(4, minmax(0, 1fr));
align-items: stretch;
```

Each widget wrapper receives inline `grid-column: span X / span X; grid-row: span Y / span Y;`. The `dense` packing algorithm fills gaps automatically without any JavaScript.

Responsive breakpoints are emitted as a scoped `` block driven by the plugin's `->columns([...])` config.

Plugin configuration
--------------------

[](#plugin-configuration)

All options are fluent and chainable on `MasonryPlugin::make()`:

```
MasonryPlugin::make()
    ->columns(['default' => 1, 'sm' => 2, 'xl' => 4])
    ->stretchWidgets()       // default: true  — see below
    ->useCssMasonry(false)   // default: false — see below
```

### `->stretchWidgets(bool $stretch = true)`

[](#-stretchwidgetsbool-stretch--true)

Controls whether widgets fill the **full height of their grid cell**.

- `true` (default) — `align-items: stretch` on the grid. Widgets and their inner sections stretch to match the tallest widget in a row. Great for dashboards where visual alignment matters.
- `false` — `align-items: start` on the grid. Each widget takes its natural content height. Row height is still set by the tallest widget, but shorter widgets won't stretch to match.

```
MasonryPlugin::make()
    ->stretchWidgets(false)  // cards take natural height
```

### `->useCssMasonry(bool $enabled = true)`

[](#-usecssmasonrybool-enabled--true)

Switches from the CSS Grid dense algorithm to the **native CSS Masonry spec** (`grid-template-rows: masonry`).

> **Experimental** — as of 2026, supported only behind feature flags in Chrome and Firefox. Not in Safari stable. Do not use in production.

When enabled, row spans (`grid-row: span X`) are omitted from widget wrappers — the browser handles vertical placement automatically based on actual content height. Column spans still apply.

The rule is emitted inside `@supports (grid-template-rows: masonry) { ... }`, so the standard dense grid is used as a fallback on unsupported browsers:

```
/* Browsers that support native masonry */
@supports (grid-template-rows: masonry) {
    .fi-masonry-grid { grid-template-rows: masonry; }
}
```

To test in Chrome: enable `chrome://flags/#enable-experimental-web-platform-features`. To test in Firefox: set `layout.css.grid-template-masonry-value.enabled = true` in `about:config`.

```
MasonryPlugin::make()
    ->useCssMasonry()   // enable for experimentation
```

### Architecture for future features

[](#architecture-for-future-features)

The package is designed to support these features in future versions without breaking changes:

- **Drag &amp; drop** — swap widget `$order` values and persist per user
- **User-specific layouts** — store `(user_id, widget_class, cols, rows, order)` in a `masonry_layouts` table
- **Collapsible widgets** — toggle `rows` between 0 and the default via Alpine
- **Dashboard templates** — named presets of `[widget => size]` maps
- **Tenant-specific dashboards** — scope the layout table by `tenant_id`
- **Widget groups** — render a `MasonrySection` that spans multiple cells

Testing
-------

[](#testing)

Tests live in the consuming application. After installing the package, add tests that cover:

- Your widget classes using `HasMasonryLayout` — verify `getMasonryColumns()`, `getMasonryRows()`, `getMasonryOrder()`
- Your Dashboard page using `HasMasonryDashboard` — verify `getWidgetsContentComponent()` returns a `MasonryGrid`
- The `MasonryGrid` component — verify `getBaseGridStyle()` and `getResponsiveStyles()` output

```
php artisan test --filter=Masonry
```

###  Health Score

41

—

FairBetter than 87% of packages

Maintenance87

Actively maintained with recent releases

Popularity10

Limited adoption so far

Community6

Small or concentrated contributor base

Maturity50

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 100% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~0 days

Total

2

Last Release

64d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/23424932?v=4)[Mohamed Said](/maintainers/EG-Mohamed)[@EG-Mohamed](https://github.com/EG-Mohamed)

---

Top Contributors

[![wouterdijkstra81](https://avatars.githubusercontent.com/u/194213754?v=4)](https://github.com/wouterdijkstra81 "wouterdijkstra81 (2 commits)")

### Embed Badge

![Health badge](/badges/secretninjas-filament-masonry/health.svg)

```
[![Health](https://phpackages.com/badges/secretninjas-filament-masonry/health.svg)](https://phpackages.com/packages/secretninjas-filament-masonry)
```

###  Alternatives

[stephenjude/filament-feature-flags

Filament implementation of feature flags and segmentation with Laravel Pennant.

123204.9k1](/packages/stephenjude-filament-feature-flags)[marcelweidum/filament-expiration-notice

Customize the livewire expiration notice

94160.6k6](/packages/marcelweidum-filament-expiration-notice)[backstage/mails

View logged mails and events in a beautiful Filament UI.

16429.7k](/packages/backstage-mails)[crumbls/layup

A visual page builder plugin for Filament 5 — Divi-style grid layouts with extensible widgets.

604.0k2](/packages/crumbls-layup)[eduardoribeirodev/filament-leaflet

Um widget de mapa para FilamentPHP.

2226.5k](/packages/eduardoribeirodev-filament-leaflet)[rawilk/profile-filament-plugin

Profile &amp; MFA starter kit for filament.

3915.5k](/packages/rawilk-profile-filament-plugin)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
