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

Filament Input Select Affix Laravel Package

marvinosswald/filament-input-select-affix

A Filament form component that combines a select dropdown with an input affix, letting users pick a prefix or suffix (like currency, unit, or domain) alongside a text field. Simple to install and configure for Laravel Filament forms.

View on GitHub
Deep Wiki
Context7

Getting Started

This package adds a Filament form component that pairs a value input with a selectable affix (prefix/suffix), so a single field can capture something like 250 + kg or $ + 19.99 without you hand-rolling a Grid of two fields every time.

1. Install (pin to the 0.3 line):

composer require marvinosswald/filament-input-select-affix:^0.3

Pre-1.0 caret ranges only allow patch drift (^0.3 = >=0.3.0 <0.4.0), which is what you want here — a 0.4.0 may contain breaking changes. If you're coming from 0.2.0, this is a drop-in upgrade: 0.3.0 is constraint widening for Laravel 12 plus CI/dependency housekeeping, no API changes.

2. Requirements to check before upgrading in anger: PHP 8.2+, Laravel 10/11/12, Filament v3, Livewire 3. If you're on Filament v4, confirm the filament/filament constraint in the package's composer.json before assuming support — "Laravel 12 compatibility" is not the same claim as "Filament 4 compatibility".

3. Where to look first:

  • The README usage block — the component is a single class you reference directly in a form schema, so there's no service provider to register or config to publish.
  • src/ for the component class and its fluent setters (options(), affix position, etc.).
  • resources/views/ if you need to restyle; the component renders a Blade view you can override.

4. First use case: a ProductResource form where quantity needs a unit. Drop the component in place of a bare TextInput, pass your unit list as options, and you've got a validated number plus a constrained unit without a second field eating half the grid column.

Implementation Patterns

Basic field in a resource form

use Marvinosswald\FilamentInputSelectAffix\Components\InputSelectAffix; // confirm FQCN against README

InputSelectAffix::make('quantity')
    ->label('Quantity')
    ->numeric()
    ->options([
        'kg' => 'Kilograms',
        'g'  => 'Grams',
        'lb' => 'Pounds',
    ])
    ->required();

Persisting both halves. The select is a real piece of state, not decoration — plan your schema for two columns (quantity + quantity_unit) rather than trying to squeeze both into one string. If you must store one column, do the concatenation in mutateFormDataBeforeSave() on the page and the split in mutateFormDataBeforeFill(), keeping the component's state non-dehydrated. Don't rely on string parsing of a free-text input for this.

Reactive behaviour. Because the affix is a select, it's the natural driver for the rest of the form:

InputSelectAffix::make('measurement')
    ->live()
    ->afterStateUpdated(fn ($state, Set $set) => $set('unit_hint', $state['unit'] ?? null))

Use ->live(onBlur: true) (or debounce) on the numeric half so you're not firing a Livewire round trip per keystroke.

Validation split. Rules attach to the value half; the select is already constrained by options(). For cross-field rules, read the affix via $get() in a closure rule — e.g. reject negative values only when the unit is a weight.

Display in tables and infolists. The package gives you an input, not a column. Pair a TextColumn with the stored unit:

TextColumn::make('quantity')
    ->suffix(fn ($record) => ' ' . $record->quantity_unit)

Nested schemas. Inside a Repeater or Builder, state paths are suffixed — closures reading sibling state need $get('../../unit'), not $get('unit'). Test this explicitly; it's the most common silent breakage.

Testing. Standard Filament form testing works — livewire(CreateProduct::class)->fillForm(['quantity' => 250, 'quantity_unit' => 'kg'])->call('create') — but assert on the dehydrated payload, since the affix may or may not dehydrate under the same key depending on how you configured the component.

Gotchas and Tips

Pre-1.0 means minor versions are breaking. 0.2 → 0.3 happens to be additive, but 0.4 need not be. Read the changelog on every bump for this package; it's small enough that the changelog is short. Also note 0.3.0's diff is dominated by Dependabot PRs bumping GitHub Actions (fetch-metadata, laravel-pint-action) — those are CI-only and irrelevant at runtime. The one substantive change is #19, which widens the illuminate/* constraints.

Laravel 12 doesn't mean Filament 4. Verify the Filament constraint yourself. Filament v3.3 supports Laravel 12, so this release is almost certainly just the Laravel widening — but the package's composer.json is the source of truth, and a v4 migration will be a separate (and probably longer-awaited) release.

Tailwind purging with a custom theme. If you use a custom Filament theme, the package's view classes may not be in your tailwind.config.js content array — you'll get an unstyled affix in production builds only. Add the package's resources/views/**/*.blade.php to content and rebuild.

Published views go stale. If you published the package views to override styling, a composer update won't update them, and you'll silently stay on the old markup. Either don't publish, or diff after each upgrade. php artisan view:clear && php artisan filament:assets after upgrading fixes most "nothing changed" confusion.

State debugging. When the affix value isn't landing where you expect, drop ->afterStateUpdated(fn ($state, $set, $get) => logger()->debug('affix', ['state' => $state, 'get' => $get('quantity_unit')])) on both halves and check storage/logs/laravel.log during a Livewire request. Faster than guessing at dehydration behaviour.

Numeric input friction. Combining ->numeric() with locale-formatted input (comma decimal separators, thousand separators) will produce validation failures that look like bugs in the package. Disable masking on this field or normalise in dehydrateStateUsing().

Don't build a currency field on this alone. For money you want integer minor units and a brick/money-style value object; letting the affix select drive a float column is a decision you'll regret at the first rounding report. This component is best for genuinely unit-qualified quantities, percentages, and simple prefixes.

Extension point: subclass the component and override getView() (or call ->view() fluently) rather than editing vendor files — this is a thin wrapper over Filament's own input primitives, so most customisation is better done on the inner components than by forking.

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