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 Color Field Laravel Package

juniora/nova-color-field

View on GitHub
Deep Wiki
Context7

Getting Started

This is a single-purpose Nova field package: it ships one field class plus a compiled Vue component. Treat it as a snippet library rather than infrastructure — the whole package is probably ~5 files, so read it before you rely on it.

Install and verify compatibility first.

composer require juniora/nova-color-field

Before writing any code, open vendor/juniora/nova-color-field/composer.json and check the laravel/nova constraint. The last release is 2024-12-21, which predates Nova 5. If you're on Nova 5, expect to fork or patch the constraint — the field API is stable enough that this usually works, but the Vue component's imports (laravel-nova, laravel-mix vs Vite) are the part that breaks.

Check that dist/ is committed. Nova resolves a field's frontend from the field.js path declared in the field class. If the repo omits the compiled bundle, you get a silently blank/missing component and must build it yourself:

cd vendor/juniora/nova-color-field
npm install && npm run prod   # or dev

That path is gitignored inside vendor/, so it disappears on every composer install — a hard blocker for CI. In that case copy the field into your app with php artisan nova:field acme color and port the Vue component.

First use case — a brand/accent color on a settings resource:

use Juniora\NovaColorField\ColorField; // confirm the exact namespace in src/

ColorField::make('Brand Color', 'brand_color')
    ->rules('required', 'regex:/^#([A-Fa-f0-9]{3}|[A-Fa-f0-9]{6})$/')
    ->help('Hex value, e.g. #4F46E5'),

with a matching column:

$table->string('brand_color', 7)->nullable();

Where to look first, in order: src/*.php (the field class — this tells you what withMeta keys the component actually reads), resources/js/components/Field.vue (what props/options exist), dist/js/field.js (does it exist), and composer.json.

Implementation Patterns

Normalize on the way in and out. Pickers are inconsistent about what they emit — #fff vs #ffffff, with or without the hash, sometimes '' for cleared. Pin it down at the field level so the rest of your app can assume one format:

ColorField::make('Brand Color')
    ->resolveUsing(fn ($value) => $value ? strtolower($value) : null)
    ->fillUsing(function ($request, $model, $attribute) {
        $value = $request->input($attribute);
        $model->{$attribute} = $value ? strtolower(trim($value)) : null;
    })
    ->nullable(),

Do not store the color as-is and normalize at render time; you'll end up with three formats in the column within a month.

Index views need a swatch, not a hex string. Most color fields render as plain text on the index, which is useless at a glance. Options, roughly in order of effort:

  • ->hideFromIndex() if the color is a detail-page concern only.
  • Add a sibling computed field for the list: Text::make('Color', fn () => $this->brand_color)->asHtml() with an inline <span style="..."> — sanitize if the value is user-writable.
  • Override the field's index component via ->withMeta() if the package supports a swatch mode (check the Vue file).

Palettes enforce brand consistency. If the component accepts preset swatches (usually a withMeta(['palette' => [...]]) or a dedicated method), use it. Free-form color input on a marketing site produces #FF0000 and #f00 and red and everyone hates it six months later.

Pair it with a semantic field, don't replace one. A color column is a presentation detail. If the color means something — status, priority, category — store an enum/status string and map to colors in the Nova layer or a config file:

Badge::make('Status')->map([
    'active'   => 'green',
    'archived' => 'gray',
])

Storing raw hex for semantic state means a redesign becomes a data migration. Reserve ColorField for genuinely presentational choices: brand accents, chart series colors, label backgrounds on a per-record basis.

JSON columns for multi-color sets. If you need two or three coordinated colors (background + foreground + accent), store a JSON object and validate keys individually with ->rules(['array', 'accent.regex:...']). Don't invent column-per-color schemas.

Multi-tenant / settings resources are the sweet spot: a singleton Setting model or a BrandTheme resource where an admin picks colors, and the frontend reads them via a cached config. Wrap reads in Cache::remember and bust on saved.

Testing. Nova's own Nova::assertField / field assertion helpers cover existence and metadata but not interaction. For anything beyond presence, use Laravel Dusk against a real Nova page, or skip the component entirely in tests and assert the normalized value written by fillUsing — that's the part that actually breaks.

Gotchas and Tips

  • Bus factor is the real risk here. Zero stars, zero dependents, one release. This is a 100-line package maintained by nobody. It's MIT, so vendor the field into app/Nova/Fields/ via php artisan nova:field and own it. That's an hour of work and removes the package from your composer.json risk surface entirely.
  • Nova major-version drift. Nova 4 → 5 changed frontend tooling (Mix → Vite in the Nova toolchain, laravel-nova import paths). A package last released in Dec 2024 is a coin flip on Nova 5. Pin to a working Nova minor or fork; don't discover this in a production deploy.
  • Column width. varchar(7) holds #ffffff. It does not hold 8-digit hex with alpha (#ffffffcc), rgb(...), or hsl(...). If the component supports an alpha slider or format switch, use varchar(9) or varchar(32) from day one — widening a column later is easy, but the dirty data written in the meantime is not.
  • Empty string is not null. Pickers commonly submit '' when cleared. Without a fillUsing/mutator, you get '' in a nullable column and whereNull('brand_color') starts lying to you. Normalize '' → null explicitly.
  • Dark mode contrast. A very dark or very light swatch disappears against Nova's dark theme. Whatever swatch rendering you build, give it a 1px neutral border; it's the difference between "the field works" and "the field looks broken."
  • CSS injection surface. If admins can write a color and you interpolate it into a style attribute on the public site, validate against a strict hex regex server-side on write — never trust the picker's output. A value like red;background:url(...) is not a color.
  • Debugging a blank field component. Confirm the class's $component property matches the registered Vue component name, confirm dist/js/field.js is present and readable by the web server (ls -l, check permissions after composer install as a different user), then hard-refresh — Nova's field assets are cached aggressively by the browser.
  • Extension points are the whole value. Even if the UI is minimal, ->withMeta([...]), ->resolveUsing(), ->fillUsing(), ->displayUsing(), and ->component('your-own') let you reskin it against your own Vue component while keeping the PHP-side ergonomics. If the bundled component disappoints, keep the field class and swap the component rather than abandoning the package.
  • Search and sort. Nova's searchable columns use WHERE col LIKE ?, which is meaningless for colors; adding a color column to $search is noise. Sortable color columns are equally pointless — resist.
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.
coleus/frame
thtg88/journalism
filagora/filagora-ai-forums
rlacerda83/query-parser
socialdept/atp-orm
cboxdk/laravel-assistant-client
socialdept/atp-resolver
socialdept/tenant-domains
tautvydasr/blade-class-names
socialdept/color-scales
maherelgamil/controller
coleus/widgets
coleus/table
coleus/users
coleus/music
coleus/health
coleus/calendar
coleus/notes
coleus/support
coleus/settings