PHPackages                             awcodes/mason - 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. awcodes/mason

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

awcodes/mason
=============

A simple block based drag and drop page / document builder field for Filament.

v3.0.4(3mo ago)2279.6k↓11.6%19[1 PRs](https://github.com/awcodes/mason/pulls)3MITPHPPHP ^8.2CI passing

Since Mar 4Pushed 1mo ago3 watchersCompare

[ Source](https://github.com/awcodes/mason)[ Packagist](https://packagist.org/packages/awcodes/mason)[ Docs](https://github.com/awcodes/mason)[ GitHub Sponsors](https://github.com/awcodes)[ RSS](/packages/awcodes-mason/feed)WikiDiscussions 3.x Synced 1mo ago

READMEChangelog (10)Dependencies (14)Versions (22)Used By (3)

Mason
=====

[](#mason)

A simple block-based drag and drop page / document builder field for Filament.

[![Latest Version](https://camo.githubusercontent.com/b5f13ef9cde180f362356dd3f23746a9d8542fac0d9655df4f744161d432ade9/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f72656c656173652f6177636f6465732f6d61736f6e2e7376673f7374796c653d666c61742d73717561726526636f6c6f723d626c7565266c6162656c3d52656c65617365)](https://github.com/awcodes/mason/releases)[![MIT Licensed](https://camo.githubusercontent.com/a7e65aee57b11d28e4caff8b945729a66be0bb663f7f93bd24c5aa65699f148e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f4c6963656e73652d4d49542d626c75652e7376673f7374796c653d666c61742d737175617265)](LICENSE.md)[![Total Downloads](https://camo.githubusercontent.com/85137142844ae28448126ce83f80db995e8534e85def65acf9b946e429e25704/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6177636f6465732f6d61736f6e2e7376673f7374796c653d666c61742d73717561726526636f6c6f723d626c7565266c6162656c3d446f776e6c6f616473)](https://packagist.org/packages/awcodes/mason)[![GitHub Repo stars](https://camo.githubusercontent.com/ee58c910fc92cb7b4ac52ce2500a1d93759ab0910e75d0844ecf170fcfdcec70/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f73746172732f6177636f6465732f6d61736f6e3f7374796c653d666c61742d73717561726526636f6c6f723d626c7565266c6162656c3d5374617273)](https://github.com/awcodes/mason/stargazers)

Compatibility
-------------

[](#compatibility)

Package VersionFilament Version0.x3.x1.x4.x2.x5.x3.x4.x, 5.xInstallation
------------

[](#installation)

You can install the package via composer:

```
composer require awcodes/mason
```

In an effort to align with Filament's theming methodology, you will need to use a custom theme to use this plugin.

Important

If you have not set up a custom theme and are using Filament Panels, follow the instructions in the [Filament Docs](https://filamentphp.com/docs/5.x/styling/overview#creating-a-custom-theme) first. The following applies to both the Panels Package and the standalone Forms package.

After setting up a custom theme, add the plugin's CSS to your theme CSS file or your app's CSS file if using the standalone forms package.

```
@import '../../../../vendor/awcodes/mason/resources/css/plugin.css';

@source '../../../../vendor/awcodes/mason/resources/**/*.blade.php';
```

Configuration
-------------

[](#configuration)

You can publish the config file with:

```
php artisan vendor:publish --tag="mason-config"
```

These are the contents of the published config file:

```
return [
    'generator' => [
        'namespace' => 'App\\Mason',
        'views_path' => 'mason',
    ],
    'preview' => [
        'layout' => 'mason::iframe-preview',
    ],
    'entry' => [
        'layout' => 'mason::iframe-entry',
    ],
    'routes' => [
        'middleware' => ['web', 'auth'],
    ],
];
```

### Auth Guards

[](#auth-guards)

By default, Mason uses the `web` and `auth` middleware for its routes internally. If you are using a different guard or have multiple guards, you can customize the middleware used by updating the `routes.middleware` configuration option in the published config file.

```
'routes' => [
    'middleware' => ['web', 'auth:admin'],
],
```

Usage
-----

[](#usage)

Important

Mason uses JSON to store its data in the database, so it is important that you cast the field to either 'array' or 'json' on your model, and it's recommended to store the content as a `longText` column in the database.

### Form Field

[](#form-field)

In your Filament forms you should use the `Mason` component. The `Mason` component accepts a `name` prop which should be the name of the field in your model, and requires an array 'bricks' available to the editor.

```
use Awcodes\Mason\Mason;
use Awcodes\Mason\Bricks\Section;

->schema([
    Mason::make('content')
        ->bricks([
            Section::class,
        ]),
])
```

#### Field Preview Layout

[](#field-preview-layout)

Since Mason uses an iframe to render in the editor, you should set the preview layout for the field to a view in your application that includes your app's styles. This will ensure that the content in the editor looks similar to how it will look on the front end of your site. If all Mason fields in your forms use the same layout, you can set a default in the config file. Otherwise, you can set it per field like so:

```
Mason::make('content')
    ->previewLayout('layouts.mason-preview') // your app's layout
    ->bricks([...])
```

Then in your layout file you can include the necessary styles and includes to render the content correctly.

```
// resources/views/layouts/mason-preview.blade.php

        {{ config('app.name') }}

        @vite(['resources/css/app.css', 'resources/js/app.js'])

        @masonStyles

            @include('mason::iframe-preview-content', ['blocks' => $blocks])

```

If the blue color used in the editor doesn't work with your design, you can customize it with CSS in your app's CSS file.

```
#mason-preview-container {
    --mason-border-color: rgb(236, 72, 153);
    --mason-controls-background: rgba(0, 0, 0, 0.8);
    --mason-button-hover-background: rgba(255, 255, 255, 0.2);
    --mason-drop-zone-background: rgba(236, 72, 153, 0.5);
}
```

#### Double-Clicking Bricks to Edit

[](#double-clicking-bricks-to-edit)

By default, Mason requires you to click the edit button on each brick to edit its content. If you would like to enable double-clicking on bricks to open the edit modal, you can chain the `doubleClickToEdit` method on the field.

```
Mason::make('content')
    ->doubleClickToEdit()
    ->bricks([...])
```

### Infolist Entry

[](#infolist-entry)

In your Filament infolists you should use the `MasonEntry` component. The `MasonEntry` component accepts a `name` prop which should be the name of the field in your model, and requires an array of 'bricks' available to the entry.

```
use Awcodes\Mason\MasonEntry;
use Awcodes\Mason\Bricks\Section;

->schema([
    MasonEntry::make('content')
        ->bricks([
            Section::class,
        ]),
])
```

#### Entry Preview Layout

[](#entry-preview-layout)

Since Mason uses an iframe to render in the infolist, you should set the preview layout for the field to a view in your application that includes your app's styles. This will ensure that the content in the editor looks similar to how it will look on the front end of your site. If all Mason fields in your forms use the same layout, you can set a default in the config file. Otherwise, you can set it per field like so:

```
MasonEntry::make('content')
    ->previewLayout('layouts.mason-entry')
    ->bricks([...])
```

Then in your layout file you can include the necessary styles and includes to render the content correctly.

```
// resources/views/layouts/mason-entry.blade.php

        {{ config('app.name') }}

        @vite(['resources/css/app.css', 'resources/js/app.js'])

        @masonEntryStyles

            @include('mason::iframe-entry-content', ['blocks' => $blocks])

```

Tips &amp; Tricks
-----------------

[](#tips--tricks)

### Custom Height

[](#custom-height)

If you find that the default height of the Mason editor or entry is not enough for your use case, you can customize using Filament's default `->extraInputAttrbutes()` method on both the `Mason` field and the `MasonEntry` component.

```
Mason::make('content')
    ->extraInputAttributes(['style' => 'min-height: 30rem;'])
    ->bricks([...])

MasonEntry::make('content')
    ->extraInputAttributes(['style' => 'min-height: 40rem;'])
    ->bricks([...])
```

### Brick Collections

[](#brick-collections)

To keep from having to repeat yourself when assigning bricks to the editor and the entry, it would help to create sets of bricks that make sense for their use case. Then you can use that in the `bricks` method.

```
class BrickCollection
{
    public static function make(): array
    {
        return [
            NewsletterSignup::class,
            Section::class,
            Cards::class,
            SupportCenter::class,
        ];
    }
}

Mason::make('content')
    ->bricks(BrickCollection::make())

MasonEntry::make('content')
    ->bricks(BrickCollection::make())
```

### Sidebar Position

[](#sidebar-position)

By default, the Mason editor sidebar is positioned on the right side of the editor. If you would like to position it on the left side, you can chain the `sidebarPosition` method on the field and assign it the new position.

```
use Awcodes\Mason\Enums\SidebarPosition;

Mason::make('content')
    ->sidebarPosition(SidebarPosition::Start)
    ->bricks([...])
```

### Displaying Brick Actions as a Grid

[](#displaying-brick-actions-as-a-grid)

By default, the Mason editor displays the brick actions in a list. If you would like to display them in a grid format, you can chain the `displayActionsAsGrid` method on the field.

```
Mason::make('content')
    ->displayActionsAsGrid()
    ->bricks([...])
```

### Sorting Bricks

[](#sorting-bricks)

By default, bricks are sorted in the order they are defined in the `bricks` array. If you would like to allow users to sort the bricks in the editor, you can chain the `sortBricks` method on the field.

```
// Sort ascending (A-Z) by label
Mason::make('content')
    ->sortBricks('asc')
    ->bricks([...])

// Or simply (defaults to 'asc')
Mason::make('content')
    ->sortBricks()
    ->bricks([...])

// Sort descending (Z-A) by label
Mason::make('content')
    ->sortBricks('desc')
    ->bricks([...])
```

### Static Bricks without data or forms

[](#static-bricks-without-data-or-forms)

If you would like to create a brick that does not require any data or forms, you can return the view in the `toHtml` method and set the action to have a hidden modal in the `configureBrickAction` method in your brick class. Now, when inserting the brick, it will simply add the brick without any configuration.

```
public static function toHtml(array $config, ?array $data = null): ?string
{
    return view('mason.static-brick');
}

public static function configureBrickAction(Action $action): Action
{
    return $action->modalHidden();
}
```

### Light / Dark Mode

[](#light--dark-mode)

If your application supports light and dark mode, you can optionally add support for it in the Mason editor by using the `colorModeToggle` method on the field. This will add a toggle button to the editor sidebar that allows users to switch between light and dark mode. You can also use the `defaultColorMode` method to set the default color mode for the editor. One thing to note is that `defaultColorMode` only sets the initial mode when the editor is loaded. If the user switches modes, their preference will be saved in local storage for future visits.

In order for this to work properly, you will need to ensure that your application's CSS supports manually setting light and dark mode according to the Tailwind CSS documentation on [manually controlling color mode](https://tailwindcss.com/docs/dark-mode#toggling-dark-mode-manually).

```
@custom-variant dark (&:where(.dark, .dark *));
```

```
Mason::make('content')
    ->colorModeToggle()
    ->defaultColorMode('dark')
    ->bricks([...])
```

Creating Bricks
---------------

[](#creating-bricks)

Bricks are nothing more than classes that have an associated view that is rendered in the editor with its data.

To help you get started, there is a `make:mason-brick` command that will create a new brick for you with the necessary class and blade template in the paths specified in the config file.

```
php artisan make:mason-brick Section
```

This will create a new brick in the `App\Mason` namespace with the class `Section` and a preview and index blade template in the `resources/views/mason` directory. Bricks follow the same conventions as Filament RichEditor custom blocks.

```
use Awcodes\Mason\Brick;
use Filament\Actions\Action;
use Filament\Forms\Components\FileUpload;
use Filament\Forms\Components\Radio;
use Filament\Forms\Components\RichEditor;
use Filament\Forms\Components\ToggleButtons;
use Filament\Schemas\Components\Grid;
use Filament\Schemas\Components\Section as FilamentSection;
use Filament\Support\Icons\Heroicon;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\HtmlString;
use Throwable;

class Section extends Brick
{
    public static function getId(): string
    {
        return 'section';
    }

    public static function getLabel(): string
    {
        return parent::getLabel();
    }

    public static function getIcon(): string | Heroicon | Htmlable | null
    {
        return new HtmlString('');
    }

    /**
     * @throws Throwable
     */
    public static function toHtml(array $config, ?array $data = null): ?string
    {
        return view('mason::bricks.section.index', [
            'background_color' => $config['background_color'] ?? 'white',
            'image' => $config['image'] ?? null,
            'text' => $config['text'] ?? null,
        ])->render();
    }

    public static function configureBrickAction(Action $action): Action
    {
        return $action
            ->slideOver()
            ->schema([
                Radio::make('background_color'),
                FileUpload::make('image'),
                RichEditor::make('text'),
            ]);
    }
}
```

Rendering Content
-----------------

[](#rendering-content)

You are free to render the content however you see fit. The data is stored in the database as JSON, so you can use the data however you see fit. But the plugin offers a helper method for converting the data to HTML should you choose to use it.

Similar to the form field and entry components, the helper needs to know what bricks are available. You can pass the bricks to the helper as the second argument. See, above about creating a collection of bricks. This will help keep your code DRY.

```
{!! mason(content: $post->content, bricks: \App\Mason\BrickCollection::make())->toHtml() !!}
```

There is also a dedicated Render that can be used if you need more control over the rendering process.

```
use Awcodes\Mason\Support\MasonRenderer;

$renderer = MasonRenderer::make($content)->bricks(\App\Mason\BrickCollection::make());

$renderer->toHtml()
$renderer->toUnsafeHtml();
$renderer->toArray();
$renderer->toText();
```

Faking Content
--------------

[](#faking-content)

When testing, you may want to fake some Mason content. There is a helper method for that as well.

```
use Awcodes\Mason\Support\Faker;

Faker::make()
    ->brick(
        id: 'section',
        config: [
            'background_color' => 'white',
            'text' => 'This is a headingJust some random text for a paragraph',
            'image' => null,
        ]
    )
    ->brick(
        id: 'section',
        config: [
            'background_color' => 'primary',
            'text' => 'This is a headingJust some random text for a paragraph',
            'image' => null,
        ]
    )
    ->asJson(),
```

Testing
-------

[](#testing)

```
composer test
```

Contributing
------------

[](#contributing)

Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Security Vulnerabilities
------------------------

[](#security-vulnerabilities)

Please review [our security policy](../../security/policy) on how to report security vulnerabilities.

Credits
-------

[](#credits)

- [Adam Weston](https://github.com/awcodes)
- [All Contributors](../../contributors)

License
-------

[](#license)

The MIT License (MIT). Please see [License File](LICENSE.md) for more information.

###  Health Score

56

—

FairBetter than 98% of packages

Maintenance86

Actively maintained with recent releases

Popularity45

Moderate usage in the ecosystem

Community25

Small or concentrated contributor base

Maturity59

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 79.8% 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 ~24 days

Recently: every ~7 days

Total

16

Last Release

77d ago

Major Versions

v0.1.4 → v1.0.02025-12-22

v1.0.1 → 2.x-dev2026-01-19

v2.0.0 → v3.0.02026-01-31

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/3596800?v=4)[Adam Weston](/maintainers/awcodes)[@awcodes](https://github.com/awcodes)

---

Top Contributors

[![awcodes](https://avatars.githubusercontent.com/u/3596800?v=4)](https://github.com/awcodes "awcodes (91 commits)")[![dependabot[bot]](https://avatars.githubusercontent.com/in/29110?v=4)](https://github.com/dependabot[bot] "dependabot[bot] (12 commits)")[![github-actions[bot]](https://avatars.githubusercontent.com/in/15368?v=4)](https://github.com/github-actions[bot] "github-actions[bot] (6 commits)")[![martin-ro](https://avatars.githubusercontent.com/u/10107779?v=4)](https://github.com/martin-ro "martin-ro (3 commits)")[![Jubeki](https://avatars.githubusercontent.com/u/15707543?v=4)](https://github.com/Jubeki "Jubeki (1 commits)")[![mohamedsabil83](https://avatars.githubusercontent.com/u/10126040?v=4)](https://github.com/mohamedsabil83 "mohamedsabil83 (1 commits)")

---

Tags

filamentfilament-pluginlaravelfilamentphpawcodesmason

###  Code Quality

TestsPest

Static AnalysisPHPStan, Rector

Code StyleLaravel Pint

### Embed Badge

![Health badge](/badges/awcodes-mason/health.svg)

```
[![Health](https://phpackages.com/badges/awcodes-mason/health.svg)](https://phpackages.com/packages/awcodes-mason)
```

###  Alternatives

[dotswan/filament-map-picker

Easily pick and retrieve geo-coordinates using a map-based interface in your Filament applications.

124139.3k2](/packages/dotswan-filament-map-picker)[jibaymcs/filament-tour

Bring the power of DriverJs to your Filament panels and start a tour !

12247.8k](/packages/jibaymcs-filament-tour)[codewithdennis/filament-lucide-icons

A Filament plugin that integrates Lucide icons, allowing you to use them seamlessly across Filament forms, tables, actions, and more.

4529.4k2](/packages/codewithdennis-filament-lucide-icons)[lara-zeus/popover

Zeus Popover is filamentphp component to show a Popover with custom content in tables and infolist

2968.2k3](/packages/lara-zeus-popover)[lara-zeus/inline-chart

Zeus Inline Chart easily add a chart in filamentPHP table column

2139.9k](/packages/lara-zeus-inline-chart)[defstudio/filament-searchable-input

A searchable autocomplete input for Filament forms

3212.4k](/packages/defstudio-filament-searchable-input)

PHPackages © 2026

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