nettantra/filament-slider-input-field
Add an interactive range slider to Filament forms with this Laravel package. Configure min, max, step, and labels to give users smooth numeric input for resource forms, settings pages, and admin panels.
Install and register
composer require nettantra/filament-slider-input-field
Pin at least ^0.0.6. That release exists specifically to declare Filament v3 compatibility, which implies earlier 0.0.x versions were not reliably v3-ready — if you are on a fresh install, start here; if you are upgrading, treat it as a real version bump and re-test the form (see Gotchas).
Then check the package's service provider / README for asset registration. Two things to verify on install, because they are the usual cause of a "dead" slider:
PanelProvider:
->plugins([
\Nettantra\FilamentSliderInputField\FilamentSliderInputFieldPlugin::make(),
])
If it instead registers assets directly in boot() via FilamentAsset::register(), no panel change is needed — but you should run php artisan filament:assets (or optimize:clear) so the noUiSlider JS/CSS lands in public/.composer.json constraint only to make sure the resolved version is >=0.0.6, and assume no v4 support until tested.Where to look first
src/Forms/Components/*.php — the field class. This is your API surface; every slider option is a fluent setter here. Read it before the README, since docs for small packages drift.resources/views/*.blade.php — the markup and where wire:model binding happens. This tells you whether state is entangled two-way or only pushed on change.resources/js/* — the noUiSlider.create() call, the options object it builds, and any Alpine/event wiring. This is where you go when a value stops syncing.composer.json + the 0.0.5...0.0.6 diff — the release note says "compatibility", which for a package this size is often a one-line constraint change against filament/filament or livewire/livewire. Reading it tells you whether anything behavioural actually moved.dist/ or public/ — the compiled asset; if it's stale, rebuild or publish.First use case
A single-handle 0–100 "priority" or "discount %" field in a resource form:
use Nettantra\FilamentSliderInputField\Forms\Components\Slider;
Slider::make('priority')
->label('Priority')
->minValue(0)
->maxValue(100)
->step(5)
->default(50)
->required(),
Method names (minValue / maxValue / step / tooltips / behaviour) mirror noUiSlider's range/step/tooltips options; confirm the exact spellings in the field class, as small packages often use abbreviated setters.
Dehydrate to the type your column expects. Sliders naturally produce strings or floats. Normalize on the way out so you never debug a "50" vs 50 mismatch in a where() clause:
Slider::make('discount')
->minValue(0)->maxValue(100)->step(1)
->formatStateUsing(fn ($state) => (int) $state)
->dehydrateStateUsing(fn ($state) => (int) $state),
Pair this with a model cast ('discount' => 'integer') and a matching migration column type. Doing both is cheaper than chasing the mismatch later.
Live previews with live() + debounce. The slider's whole value proposition is immediacy; use it for the readout, not for expensive queries:
Slider::make('budget')
->minValue(0)->maxValue(10000)->step(100)
->live(debounce: 500)
->afterStateUpdated(fn ($state, Set $set) => $set('budget_label', '€ ' . number_format((float) $state))),
Placeholder::make('budget_label')->content(fn (Get $get) => $get('budget_label')),
Keep debounce non-zero. noUiSlider fires continuously during drag, and each tick is a Livewire round trip.
Two-handle ranges (if supported). If the field exposes a range/dual-handle mode, state arrives as an array — store it in a JSON column and cast to array, and validate with ->rule('array') plus per-index rules rather than a single numeric.
Repeaters and table action modals. The field works inside a Repeater, but each instance needs a DOM-unique element id; if the package hardcodes the id in its Blade view, wrap the field's container with a keyed section or override the view. Inside a table action modal it is generally fine, since the form is mounted fresh per modal open.
Consistent formatting across a form. If you use several sliders, define a small factory or a Macroable helper so step, tooltips, and dehydrateStateUsing stay in sync — it is easy to end up with one slider emitting float and another int.
Integration with the rest of the panel. The slider is a Field, so it composes with everything else: ->helperText(), ->hint(), ->hidden(), ->disabled(), section/grid columns (->columnSpan(2)), and ->visible(fn (Get $get) => ...). Reach for those before writing custom JS.
noUiSlider.create() call. For Filament v4, assume it won't work until you test it.php artisan filament:assets (the compiled dist may have changed), clear the view cache, and re-check the slider in a Repeater and in a table action modal, not just a plain resource form.^0.0.5, composer update nettantra/filament-slider-input-field alone may not move you. Check composer show nettantra/filament-slider-input-field and the actual vendor composer.json requirement on filament/filament before concluding the upgrade "didn't help".slide/change or only on change. If it's change-only, a form submitted mid-drag can persist a stale value — acceptable for most UX, but surprising in tests and in action modals.wire:ignore in the Blade view, or re-init on livewire:navigated / morph.updated. This bites hardest in Repeaters when items are added or reordered.noUiSlider script gives you a plain <div> with no error in the console if the init code guards on typeof noUiSlider !== 'undefined'. Check the network tab for the asset first, then the init guard. This is the single most common post-upgrade symptom.step must divide the range evenly. minValue(0)->maxValue(1)->step(0.1) produces floating-point artifacts like 0.30000000000000004. Use integer ranges and scale on read, or round in dehydrateStateUsing.->viteTheme()), particularly for handle and connect colors. If the package injects its CSS globally, scope your overrides rather than editing vendor files.->minValue()/->maxValue() constrain the widget, not the request. Add ->rules(['numeric', 'min:0', 'max:100']) for anything security-relevant, since a crafted Livewire payload can post any value.Livewire::test(...)->fillForm(['priority' => 40])->call('save') sets the state directly and never touches noUiSlider — so unit tests pass even if the front end is broken. Do one Dusk/browser assertion on the slider itself if the feature matters.->label() and ->helperText() so the value is announced meaningfully.->view('vendor/...') override → publishing the package views → a custom Alpine component wrapping noUiSlider yourself. If you find yourself at step four, a 30-line TextInput + Alpine x-data slider is a reasonable escape hatch that removes the dependency entirely.How can I help you explore Laravel packages today?