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

datomatic/nova-enum-field

A Laravel Nova field for working with PHP enums—display them as badges or labels, edit via select inputs, and filter Nova resources by enum values. Supports backed and pure enums, nullable values, and customizable colors for clean, type-safe admin panels.

View on GitHub
Deep Wiki
Context7

Technical Evaluation

Architecture fit. datomatic/nova-enum-field is a thin, Nova-native extension: a field class (Fields/Enum.php) that renders PHP 8.1 backed-enum cases into a select and persists the backing value, plus two filter classes (EnumFilter, EnumBooleanFilter) that translate enum cases into whereIn constraints. It adds no service provider surface, no persistence layer, no migrations — it decorates Nova's existing field/filter contract. Architecturally this is a presentation adapter over a domain type, which is the right shape: the enum on the model cast remains the source of truth, and the package only maps cases → labels → query constraints. Fit is contingent on two facts, not opinions: (1) we are on Laravel Nova (v4/v5), and (2) our state columns are backed enums cast on the model. If either is false, the package is inert.

Integration feasibility. Low effort, high determinism. Install is a single composer require; wiring is three lines per resource (field + rule + filter registration). Because the surface is a few hundred lines and readable in minutes, we can verify behavior by reading src/ and tests/ rather than trusting docs — a meaningful de-risker for a low-signal package. The one non-obvious integration constraint is that filters must be returned from Resource::filters() and the resource must be reachable via availableFilters(); a missed second step yields a silently absent filter, not an error. Second constraint: do not mix ->options() with ->enum() — enum() populates options internally and a later options() call overwrites them, producing a phantom mapping bug that costs more debugging time than the package saves.

Technical risk. Classify as a vendored utility, not a strategic dependency. Evidence: 19 stars, zero dependents, single maintainer, MIT. That is a bus-factor of one and no downstream validation signal. Offsetting evidence: v1.11.1 is a named-contributor fix to a real production crash (exception #8 when EnumFilter/EnumBooleanFilter is applied to an index rendered through a relation), which demonstrates active triage and, importantly, that someone is running this against nested Nova indexes. A patch release does not upgrade the risk class — it upgrades our confidence in the fork-and-own plan, which is cheap here because the code is small. The dominant residual risk is Nova major-version skew: the package must track Nova's internal field/meta contract, and Nova majors are where that contract moves. Treat every Nova upgrade as a breaking-change event for this package.

Key questions.

  1. Which Nova major are we on, and does the package composer.json constraint actually admit it? Verify against the repo, not the README.
  2. How many enum-backed columns do we have today, and how many are planned? Below three, a stock Select with an options array is ~20 lines and this dependency is not justified.
  3. Are all target enums backed (string/int) and cast on the model? Pure enums render but filters silently fail to narrow; int-backed enums on VARCHAR columns pass validation but produce filters that never match.
  4. Do our support workflows depend on filtering index views rendered through a relation (e.g. the Orders panel on a customer detail page)? If yes, the 1.11.1 fix is the reason to care at all, and pinning ^1.11.1 is mandatory.
  5. Does our dependency policy permit single-maintainer packages, or does it require a vendor/SLA arrangement we would have to satisfy by forking in-repo?
  6. Is a Nova migration on the 12-month roadmap? If so, this package's value is bounded by that horizon.

Integration Approach

Stack fit. Requires PHP 8.1+ (native enums) and Laravel Nova 4/5. Both are gating, not aspirational. The package assumes Laravel's Rule::enum validation exists alongside it — it does not replace validation, so the resource rules stay ours. It composes with stock Nova field modifiers (hideWhenCreating, hideFromIndex, nullable, help) rather than introducing package-specific flags, which keeps resources readable and portable. It also emits backing values from filters, so the same EnumFilter instance works in resource filters and in metric/card queries with no translation layer — a small but real reduction in duplicated query logic across dashboards.

Migration path. Strangler, per column, low blast radius:

  1. Confirm Nova major compatibility and pin ^1.11.1 in a branch.
  2. Land the enum on the domain side first (backed enum + HasLabel + model cast), leaving the existing Select in place. The cast is the source of truth; the field follows it.
  3. Swap Select::make(...)->options([...]) for Enum::make(...)->enum(...) on one resource. Add 'required'/'nullable' plus Rule::enum.
  4. Add the matching filter (EnumFilter for multi-case, EnumBooleanFilter for binary), register it in filters() and availableFilters().
  5. Repeat per column only after the first is green.

Order matters: enum + cast before field, field before filter. Reversing it produces filter comparisons against raw strings and looks like a package defect.

Compatibility. The hard boundary is the Nova major. Within a major, the package is stable because it touches a narrow contract. The known incompatibility classes are all data-shape issues rather than version issues: pure (non-backed) enums, int backing on string columns, nullable columns where only the field is nullable, and wrong filter class selection (EnumBooleanFilter vs EnumFilter — both render fine, one never narrows). Blank field/no styles is an asset-publish symptom, not a compatibility failure: compiled assets ship in dist/, but php artisan nova:publish plus a Nova cache clear is the first move before filing a bug.

Sequencing.

  • Phase 0 (0.5 day): compatibility gate — Nova major vs. composer.json, read src/ and tests/, run a throwaway field against one enum in a dev environment.
  • Phase 1 (1–2 days): vendor/fork in-repo, pin, adopt on one high-traffic enum column with a filter.
  • Phase 2: roll out to remaining enum columns; add the relation-index regression smoke test.
  • Phase 3 (ongoing): re-run the smoke test on every Nova and PHP upgrade.

Explicit non-goal. This does nothing for customer-facing UX and does not justify Nova spend. Scope it as internal-tooling spend only.

Operational Impact

Maintenance. We own it. Single maintainer, zero dependents, MIT — the correct posture is to vendor or fork the code in-repo, pin the version, and treat upstream as a convenience rather than a lifeline. The economics favor this: the surface is a few hundred lines, so forking is a realistic, low-drama plan rather than an emergency contingency. Budget roughly half a day per quarter for upgrade verification and near-zero for feature work, since there is no feature pressure — the package does one thing.

Support. The win here is operational self-service. Filterable enum columns let support and ops slice queues by state (order status, subscription lifecycle, ticket priority, KYC state) without filing engineering tickets, and since 1.11.1 that extends to relation-scoped views — the nested panels where support actually spends its day. This is the primary business justification: it converts recurring "can you pull a list of X in state Y" requests into self-service clicks. Secondary support benefit: replacing hand-maintained options arrays with enum-derived labels eliminates a class of drift bug where the select options and the database values disagree.

Scaling. Query behavior is standard whereIn on indexed, low-cardinality columns — the shape databases handle best. No N+1 concerns beyond what Nova index rendering already implies, and label resolution happens in PHP from an in-memory enum, so there is no per-row query cost. The scaling risk is not throughput, it is breadth: the more resources that depend on the package, the wider the blast radius of a Nova upgrade. Mitigate by keeping the dependency behind a small number of field/filter usages and by centralizing enum definitions so label changes are single-point.

Failure modes.

  • 500 on relation-rendered index filters — exception #8, fixed in 1.11.1. Pinning an older tag or forking without the fix reintroduces it, and it only manifests on nested indexes, so it will pass top-level QA.
  • Silent filter no-op — wrong filter class, pure (non-backed) enum, or int-backing on a VARCHAR column. Renders correctly, never narrows. Highest-cost failure mode because it looks like a data problem.
  • Option drift — ->options() called after ->enum() silently overwrites the generated options.
  • Invisible filter — missing from availableFilters(); no error, just an absent UI control.
  • Blank field — asset/cache issue; nova:publish and cache clear, not a package bug.
  • Nova upgrade breakage — the structural risk; the field/filter contract moves and the package lags. Detect via the smoke test, remediate by patching our fork.

Ramp-up. Very low. One engineer can be productive in an afternoon: install, read src/ (the package is effectively self-documenting), model the enum with HasLabel, wire field + filter, verify via the field's meta JSON in Nova's debug output rather than reading the Vue component. Debugging guidance worth codifying for the team: (1) inspect meta first to confirm options/labels map correctly; (2) confirm HasLabel is implemented on the enum before suspecting the field, since Nova falls back to case names; (3) check the migration's column type before blaming the filter; (4) verify the filter appears in both registration points. Add exactly one regression test — an enum filter on a relation-mounted resource — as the standing guard for the failure class this package has already exhibited once.

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.
diephp/sequences
users-au/socialite-provider
twidpay/twid-logger
mrnewport/laravel-plaid
mrnewport/laravel-repo
mrnewport/laravel-docsign
mrnewport/laravel-stow
mrnewport/laravel-flow
mrnewport/laravel-priceable
mrnewport/laravel-nestedterms
fredmeng/laravel-apidoc-generator
itstructure/laravel-multilingual-tools
pdustdar/elasticsearch
markupai/php-sdk
rlacerda83/lumem-microservice-shipment
uni-method/symfony-lib
tacticmedia/scim-server-bundle
neika-ai/symfony-bundle
mattleads/agent-publishing-bundle
glavweb/framework-bundle