akunbeben/fluid-actions
Fluid Actions is a UX toolkit for Filament Actions, offering inline confirmation, hold-to-confirm gestures, and ActionGroup support with per-action timeouts and smart fallbacks to Filament's default behavior.
Install the package and register the plugin in your target panel:
composer require akunbeben/fluid-actions
use Akunbeben\FluidActions\FluidActionsPlugin;
$panel->plugin(FluidActionsPlugin::make());
Before using it day-to-day, confirm three things:
composer.json constraints and the changelog before adopting it across an admin panel.Action::make('deactivate') followed by a fluid interaction — but confirm the exact method names in vendor/akunbeben/fluid-actions/src or the full README. Likely candidates include inline confirmation, hold-to-confirm, hold duration, and confirmation timeout methods.First example pattern, assuming the package exposes an inline confirmation method:
use Filament\Actions\Action;
Action::make('deactivate')
->inlineConfirmation()
->action(fn ($record) => $record->update(['active' => false]));
If that renders and behaves correctly inside your table or page header, you have verified installation, plugin registration, asset loading, and action rendering in one pass.
Use inline confirmation for close-to-the-action decisions. This works best where the user is already focused on a row or resource and a full modal would feel heavy. Keep inline-confirmed actions short, reversible, and easy to understand.
Reserve hold-to-confirm for genuinely costly actions. Deleting a record, revoking credentials, or triggering an irreversible job are candidates. Do not use hold-to-confirm for routine actions; it slows down normal workflows. Configure the hold duration per action rather than globally where possible.
Let smart fallback handle complex flows. If an action already needs a form, a large confirmation modal, or multi-step input, rely on Filament’s default behavior or the package’s fallback path. Forcing a fluid interaction onto a complex action usually produces an inconsistent UX.
Centralize action configuration. In a real panel you will repeat these actions across resources. Create small helper methods or action factory classes so timeout and hold-duration values stay consistent:
final class FluidAction
{
public static function destructive(string $name): Action
{
return Action::make($name)
->holdToConfirm()
->holdDuration(1500);
}
}
Account for ActionGroup and dropdown contexts. If actions appear in table row dropdowns, page headers, or grouped action menus, test each location. The package advertises ActionGroup support, but dropdown rendering is where UX and JavaScript behavior are most likely to differ from the default action rendering.
Integrate at the table and page-header level first. Typical integration points are Resource tables, ListRecords page header actions, and ViewRecord/EditRecord header actions. Bulk actions are less obvious: verify whether the package supports them before replacing default bulk confirmation behavior.
Add a browser-level smoke test. This package is interaction-heavy, so Livewire component tests alone will not prove it works. Add at least one browser test or a manual QA checklist covering pointer hold, mobile touch, keyboard activation, and dropdown placement.
Do not assume API stability. The package is young and has no dependents. Pin the version in composer.json, read the changelog on upgrades, and avoid spreading fluid interaction methods across every action until you have verified the API on a branch.
Hold-to-confirm has accessibility implications. Press-and-hold interactions can exclude keyboard users and users with motor impairments. Provide a fallback path, retain standard confirmation where required, and test keyboard interaction explicitly. Do not make hold-to-confirm the only way to complete a critical action.
Inline confirmation inside dropdowns needs deliberate testing. Dropdown and ActionGroup rendering can behave differently from inline table actions. Check z-index, click-outside behavior, and whether the confirmation state survives Livewire re-renders.
Watch for Livewire rerender surprises. Filament actions are Livewire-driven. If an inline confirmation state resets after a table refresh, search, or filter change, that is a Livewire state issue rather than a CSS problem. Debug by inspecting the component payload and checking the package source for how it stores confirmation state.
Clear caches when assets behave oddly. After installing or upgrading, run:
php artisan filament:assets
php artisan view:clear
php artisan optimize:clear
Also check that the plugin is registered in the correct panel when using multiple panels or tenant panels.
Verify the “smart fallback” before relying on it. If the package falls back to Filament’s default behavior for complex actions, confirm what “complex” means in practice. Test actions with forms, requiresConfirmation(), and custom modal content. A silent fallback can be fine, but you need to know when it happens.
Prefer per-action configuration over global changes. The README claims per-action timeout, hold duration, and dropdown behavior. Use that to avoid one aggressive hold duration affecting every destructive action in the panel. If global configuration exists, treat it as a default and override at the action level.
Keep debugging close to the rendered action. When something does not work, isolate it in a minimal Filament page with one action before investigating the resource table. Check the browser console for JavaScript errors, inspect whether assets are loaded from the plugin, and compare the rendered markup against a default Filament action.
Extension points are likely thin. With a small package, expect to work within the exposed action methods rather than subclassing internals. If you need behavior the package does not expose, implement your own action class or keep the default Filament confirmation rather than patching vendor code.
How can I help you explore Laravel packages today?