NovaField Indicator v2.0.1
NovaField Indicator

Laravel Nova 5 · field

Status you can read at a glance.

A colour-coded indicator field for Laravel Nova. It takes the enum your application already has and renders a dot, ring, square or pill that says what the value means — in light mode, in dark mode, and to a screen reader.

1.07 kBJS, gzipped
186tests
0runtime deps
Users
Shape
Size

The whole thing

One enum in, a status column out.

If the attribute is cast to a backed enum and that enum describes itself, this is the entire configuration.

app/Nova/User.php
use Gabrielesbaiz\NovaFieldIndicator\NovaFieldIndicator;

NovaFieldIndicator::make('Status')
    ->enum(Status::class)
    ->withIcons()
    ->filterable(),

Rendered on the index

Users
NameStatus
Ada Lovelace Active
Grace Hopper Invited
Alan Turing Banned

Labels, colours and icons all come from the enum. Nothing is repeated in the resource.

01  Not just four colours

The whole palette, and your own.

Colours resolve to Nova’s own --colors-* variables, so any Tailwind family and shade works — and re-theming Nova re-themes every indicator. Literal CSS colours and explicit light/dark pairs are first-class too.

Four ways to name a colour
NovaFieldIndicator::make('Status')->colors([
    'active'   => 'success',        // a semantic token
    'archived' => 'emerald-600',    // any family and shade
    'brand'    => '#7c3aed',        // a literal
    'custom'   => ['light' => 'violet-600', 'dark' => 'violet-400'],
]),

Rendered

active archived brand custom

Switch the theme in the masthead — the first, second and fourth shift shade; the literal deliberately does not.

02  Four shapes, three sizes

A shape can carry meaning too.

Colour alone fails about one man in twelve, and fails everyone in a greyscale print. A distinct shape per state is one of the three ways this package lets you avoid relying on it.

Shapes
NovaFieldIndicator::make('Status')->dot(),
NovaFieldIndicator::make('Status')->ring(),
NovaFieldIndicator::make('Status')->square(),
NovaFieldIndicator::make('Status')->pill(),

// and a state that is still happening
NovaFieldIndicator::make('Status')->states([
    'syncing' => ['label' => 'Syncing', 'color' => 'sky-400', 'pulse' => true],
]),

Rendered

Dot — the default Ring — pending Square — queued Pill — failed Syncing — pulsing

The pulse is wrapped in prefers-reduced-motion, so it never overrides a stated preference.

03  Resolved on the server

An index row carries a result, not a rulebook.

Version 2 pushed the whole label and colour configuration into every row of an index and looked it up again in the browser. A six-state field on fifty rows shipped its maps fifty times. Resolution now happens once per value, in PHP.

1.x — per row
// repeated on all 50 rows
{
  "labels": { "active": "Active", "banned": "Banned", /* … */ },
  "colors": { "active": "success", "banned": "danger", /* … */ },
  "unknownLabel": "Unknown",
  "withoutLabels": false
}
2.0 — per row
{
  "indicators": [{
    "value": "active",
    "label": "Active",
    "ariaLabel": "Active",
    "color": { "light": "rgba(var(--colors-green-500))", /* … */ },
    "icon": null, "pulse": false
  }],
  "shape": "dot", "size": "md"
}
A side effect worth naming. Because the browser no longer inspects a colour string, colour literals are validated once, server-side, against an anchored allow-list. The 1.x client-side regex was unanchored and would have accepted #fff; background-image:url(…).

Honest comparison

When not to reach for this.

Nova already ships Badge, and for four hard-coded states it is the right answer — it is built in, it needs no dependency, and ->map() covers a surprising amount. If success, info, danger and warning are all you need, use it and stop reading.

Use Badge

Four states, default styling, no colour of your own, and no need for a filter or an icon. Fewer moving parts wins.

Use this package

States come from an enum, you want a specific shade, you need dark mode to be right, or colour must not be the only channel.

Use neither

If the value is editable, it is a Select. This field is Unfillable by contract and never writes.

Support this package

Free forever. Not free to maintain.

The work you never see is the work that keeps a status column boring. Nova moved its colours from var(--success) to a palette of CSS variables between majors, and four of this field’s documented colours quietly stopped rendering — no error, no warning, just an empty cell. Finding that, and the is_callable() branch that was invoking a value as a callback, took far longer than writing either fix. It stays MIT either way.

Sponsorship buys the time to keep doing that: tracking Nova and Laravel releases before your upgrade does, keeping 186 tests honest, and answering issues from people who are not paying anything. It stays MIT either way.

Free

Star the repo

It is how other Nova developers find the package at all.

Free

Open a good issue

A Nova version, a field definition and what you expected. That is a gift.

Sponsor from $5

Roughly one coffee a month, against every future Nova release.

Company tier

If this runs in your admin panel at work, your employer can help.

Why ask at all? This package is MIT and always will be. Nothing is paywalled, nothing phones home, and no feature is held back for sponsors. Sponsorship buys maintenance time, not features — and if you cannot sponsor, the star and the bug report genuinely help.