Weave Code
Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Nova Grid Laravel Package

nibri10/nova-grid

Laravel Nova package that adds a configurable grid layout field for arranging resource form fields into responsive columns. It helps build cleaner, more compact admin forms and keeps complex Nova resources easier to scan without custom CSS or manual markup.

View on GitHub
Deep Wiki
Context7

Getting Started

nibri10/nova-grid does one thing: it lets you wrap a group of Nova fields so create and update screens render them side by side in a CSS grid instead of Nova's default single column. That's it. If you're planning to lean on it heavily, read the rest of this section first — the package has one maintainer, 23 stars, zero dependents, and no release since 2021-07-15, which means you are the QA team.

Before you write a single Grid::make(), spend ten minutes confirming the facts the README won't tell you:

composer require nibri10/nova-grid
cat vendor/nibri10/nova-grid/composer.json          # what laravel/nova constraint?
grep -rn "class \|function " vendor/nibri10/nova-grid/src
ls vendor/nibri10/nova-grid/resources 2>/dev/null   # views? js? css?

You're checking three things:

  1. The real class name and namespace. Package names lie about internals constantly — the wrapper might be Nibri10\NovaGrid\Grid, Nibri10\NovaGrid\Fields\Grid, or something else entirely. Never copy a namespace from a blog post; copy it from src/.
  2. Whether it publishes assets. If there's a boot() with publishes(), run php artisan vendor:publish --tag=<tag>. Missing frontend assets is the #1 reason people install this and see a vertical stack with extra whitespace.
  3. How it integrates with Nova. If it's a Field subclass that swaps a Vue component, your rules(), authorize(), dependsOn(), and fill() calls all still run through Nova's normal path. If it's a view override, all bets are off and you should stop.

Your first use case: pick one resource with a mix of short fields (name, email, phone, status) and wide ones (markdown notes, file uploads, relationships). Wrap only the short ones.

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),

        // short, tabular fields — safe to grid
        Grid::make([                                    // verify this class in src/
            Text::make('First name', 'first_name')->rules('required'),
            Text::make('Last name', 'last_name')->rules('required'),
            Text::make('Email')->rules('required', 'email'),
            Text::make('Phone'),
        ])->columns(2),

        // wide fields stay flat — NOT inside the grid
        Markdown::make('Notes'),
        File::make('Attachment'),
        BelongsTo::make('Company', 'company', Company::class),
    ];
}

Create a record, edit it, submit it with an intentionally invalid email. If the field errors anchor to the right input and the layout holds, you're in business.


Implementation Patterns

Wrap contiguous blocks, never the whole resource. Nova renders whatever you return in array order — the grid is a container, not a reflow engine. Keep one grid per logical group (identity, contact, billing) and leave full-width widgets outside. The classic mistake is dropping a File field into a two-column grid; you get a truncated dropzone and an unusable form.

Isolate the dependency at one call site. You will fork this, remove it, or replace it with Nova 4's native ->halfWidth(). Make that a one-file change:

trait GridsFields
{
    protected function grid(array $fields, int $cols = 2)
    {
        if (! config('nova.grids.enabled')) {
            return $fields; // flatten — Nova handles the array fine
        }

        return \Nibri10\NovaGrid\Grid::make($fields)->columns($cols);
    }
}

Then in resources:

public function fields(Request $request)
{
    return [
        ID::make()->sortable(),
        $this->grid([
            Text::make('First name', 'first_name'),
            Text::make('Last name', 'last_name'),
            Text::make('Email'),
            Text::make('Phone'),
        ]),
        Markdown::make('Notes'),
    ];
}

The config flag isn't paranoia — it's the fallback for the day a Nova patch breaks rendering and you need to ship a hotfix in five minutes without touching twenty resources.

Branch create vs. update inside fields(). Both screens call the same method. If you want wider density on update (existing data, more whitespace) versus compact on create, branch on the request, don't duplicate the array:

$cols = $request->isMethod('post') ? 3 : 2;

Nest inside Nova panels. A Panel + grid gives you a labelled, collapsible section with columns — it reads far better than a bare grid floating among unwrapped fields. It's also a clean upgrade path: when you move to Nova 4, the panel survives and you just swap the grid wrapper.

Match column count to label reality. Two columns is right almost always. Three-plus looks great in a screenshot and breaks the first time someone adds a ->help() string, a translated label, or a long validation error. If you find yourself wanting three columns, that's usually a signal to split into two panels instead.

Treat index/detail as a separate concern. These wrappers are form-layout only. Don't assume onlyOnIndex() fields behave inside a grid, and don't try to use this to densify indexQuery tables — that's a different mechanism entirely.


Gotchas and Tips

Assets not published → silent no-op. If everything stacks vertically, check vendor:publish output and confirm the component key the wrapper references actually exists in public/ or nova-components/. A no-op install looks identical to "the package is broken."

Nova 4/5 is not supported. The last release predates Nova 4 entirely. Gate on the major version before adopting:

if (version_compare(\Laravel\Nova\Nova::version(), '4.0.0', '<')) { ... }

Nova 4/5 ships ->halfWidth() / ->fullWidth() and proper field panels — the honest migration path is to unwrap every grid and replace it with those. Plan that before you write the first Grid::make(), not after the upgrade is scheduled.

The debugging heuristic that saves hours: when a field vanishes or a row looks wrong, unwrap the grid and return the fields flat. Field reappears → the wrapper is the cause. Field still missing → it's a Nova visibility/authorization/dependsOn() issue and the grid has nothing to do with it. Do this before anything else.

onlyOn* and conditional fields leave empty cells. hideFromIndex, onlyOnDetail, dependsOn, and canSee() all filter fields after the grid is constructed, and the grid doesn't reflow. You get holes. Keep conditional fields flat and out of grid blocks.

Verify validation and authorization actually pass through. The wrapper is presentation-layer, so server-side rules() and policies should be untouched — but "should" is doing a lot of work for a 2021 package with no test suite. Do this once per wrapped resource: submit an invalid form and confirm errors anchor correctly; then log in as a user whose policy denies update and confirm the 403 lands. Check dependsOn() behavior too if you use it.

Wide field types fight grids. File, Markdown/Trix, KeyValue, BelongsTo search-selects, and MorphTo all need horizontal room. Squeezing any of them into a column produces truncated editors and dropdowns that can't be used. Full width, outside the grid, always.

Test at 375px and with a screen reader. Multi-column forms degrade on mobile and disrupt screen-reader flow, and this package ships no accessibility story. For an internal ops tool that's a judgment call; for anything customer-adjacent it's a blocker.

Pin the version and own the fork. If you keep the dependency, pin the exact version, vendor it under an internal namespace (Apache-2.0 permits it), and name an owner. There's no CI and no test suite, so your own upgrade checklist is the only early warning system. Run it on every Nova bump: create + update + validation errors + policy denial on every wrapped resource.

Scope adoption narrowly. Cap it at a handful of resources with real edit-throughput pain — ops staff editing 20+ field records repeatedly. The layout benefit is flat as adoption grows; the fork-maintenance cost isn't. It's admin polish, not house style, and it should never be a prerequisite for a feature branch landing.

Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
jinas/dhivatar
store-doc/laravel-storage-driver
plus-it/laravel-translation-manager
diephp/perhaps
diephp/telegraph
osmaviation/spreadsheet
microsoft/fluentui-system-icons
mmccook/php-json-canonicalization-scheme
middlewares/firewall
qubiqx/montapacking
nyoncode/laravel-package-console
pnscripts/filament-broadquill-lite
pnscripts/laravel-sentfold-lite
vleap/mx-sdk-laravel-internal
twidpay/utils
htetmyathlaing/scout-elasticsearch-driver
artisan-toolbox/front-awesome
ls/client-assistant
users-au/laravel-client
cgv/localized-resource