akunbeben/inline-confirm
A lightweight Laravel package that replaces browser confirm dialogs with inline confirmation prompts for destructive actions. Add simple Blade integration, customize labels and styling, and keep users in context without modal windows. Ideal for delete buttons and other risky links.
akunbeben/fluid-actions is the renamed successor to akunbeben/inline-confirm. It provides Filament action UI variants — inline confirmation and hold-to-confirm — that let you avoid a modal for lightweight destructive or irreversible actions.
Install
composer require akunbeben/fluid-actions
If you previously had akunbeben/inline-confirm, remove it first (composer remove akunbeben/inline-confirm) so you don't end up with two service providers registering two view namespaces and two asset tags.
Register the plugin in your panel provider:
use Akunbeben\FluidActions\FluidActionsPlugin;
public function panel(Panel $panel): Panel
{
return $panel
// ...
->plugin(FluidActionsPlugin::make());
}
The service provider is Akunbeben\FluidActions\FluidActionsServiceprovider/FluidActionsServiceProvider — it is auto-discovered, so you should not need to add it to bootstrap/providers.php.
Publish assets (the plugin ships fluid-actions.css and fluid-actions.js):
php artisan vendor:publish --tag=fluid-actions-assets
php artisan filament:assets
There are typically separate fluid-actions-css / fluid-actions-js tags if you only need one. Note the tag names changed with the rename — an old --tag=inline-confirm-assets will silently publish nothing (or error) and leave you with unstyled buttons.
First use case — a table row delete that doesn't deserve a modal:
Tables\Actions\DeleteAction::make()
->inlineConfirm(),
That is the fastest path to validating the install: if the button renders and the confirm state toggles without a JS console error, your assets and view namespace are wired correctly.
Where to look first: the published fluid-actions.{css,js} in public/ (confirms the asset pipeline), then the package's resources/views to see the action view names — that's where the real behaviour lives and where you'll be extending.
Two flavours, one mental model. Both features are action-decorators: they swap the action's view and attach Alpine state, so they compose with Filament's existing action API rather than replacing it.
// Inline confirm: first click arms, second click fires
Tables\Actions\DeleteAction::make()->inlineConfirm(),
// Hold to confirm: press-and-hold for irreversible operations
Tables\Actions\Action::make('purgeCache')
->requiresConfirmation(false)
->holdToConfirm(),
Pick the right one per risk level. Inline confirm suits reversible-ish, low-blast-radius actions (delete a row, revoke a token). Hold-to-confirm suits bulk or irreversible operations (purge all cache, force-deploy) where a mis-click is expensive and the extra friction is the point.
Custom action views now compose correctly (v1.0.0 fix). Prior to this release, calling ->inlineConfirm() after defining your own ->view(...) could clobber it. As of 1.0.0 the original explicit action view is preserved. Pattern:
Action::make('refund')
->view('filament.actions.refund-custom')
->inlineConfirm(),
You can now add confirmation semantics to a bespoke action view without having to re-implement the confirmation UI yourself. This is the headline behavioural change in the release and is worth re-testing any action where you previously worked around it with a wrapper view.
Dropdowns. closeDropdown is stored per-action and controls whether the dropdown closes when the confirmation state is entered. For actions inside a ->dropdown() / grouped action menu, decide deliberately: keeping the dropdown open lets the user see the two-step state change; closing it means the confirmation UI must be visible elsewhere. Because the config is now correctly stored (v1.0.0 fix), any dropdown action that previously appeared to ignore your closeDropdown setting will start honouring it — expect a visible behavioural shift even without code changes.
Bulk and header actions. The same decorators apply to BulkAction and header actions; the constraint is layout, not API. Hold-to-confirm in a bulk toolbar is the highest-value placement, since bulk selections are where accidental destruction is most likely.
Escaping the modal. Do not stack these on top of ->requiresConfirmation(). Choose one confirmation mechanism per action — modal, inline, or hold — otherwise the user confirms twice and the second gate looks like a bug.
This is a hard rename, not an alias. Every string changed: package name, namespace (Akunbeben\InlineConfirm → Akunbeben\FluidActions), plugin class, service provider class, view namespace (inline-confirm → fluid-actions), and both published assets. There is no shim package mentioned in the notes, so a composer update will fatal on missing classes until you fix imports. Audit at minimum:
use statements in panel providers, resources, and custom actions->plugin(InlineConfirmPlugin::make())view('inline-confirm::...') calls or published view overrides in resources/views/vendor/inline-confirm@vite/@assets references or CSS imports pointing at inline-confirm.cssRe-publish views, don't just re-publish assets. The view namespace changed, so previously published overrides under resources/views/vendor/inline-confirm/ are now dead weight — Laravel resolves the new fluid-actions namespace and will silently fall back to the package defaults. Move the directory (or re-publish with the new tag) if you had customised markup.
Stale assets are the number-one "it's broken" symptom. After the rename you can end up with inline-confirm.css still in public/ while the view now requests fluid-actions.css. The result is an unstyled but functional button, which reads as a broken install. Run php artisan filament:assets (and your build step) after upgrading, and confirm the new filenames exist.
Cache clearing is not optional. With the namespace, provider, and view namespace all changing, run php artisan optimize:clear before debugging anything. A cached compiled view or config will produce errors that reference classes you have already removed.
Debug the confirmation state in the browser, not the PHP. These are Alpine-driven; a failing click almost always means the JS asset didn't load or an older inline-confirm.js is still registered. Check the network tab for fluid-actions.js before you go reading Filament internals.
Verify the exact fluent method names against the source for v1.0.0. The release notes document renames and the two config fixes, not the full public API surface. Before mass-editing call sites, grep the plugin's classes for the method names you intend to use — the rename touched identifiers broadly enough that muscle memory from the pre-1.0 package is not a reliable guide.
Extension points. The published views are the intended customisation seam: override the fluid-actions namespace views rather than subclassing the plugin. For behavioural tweaks (hold duration, confirm labels), prefer the action's own configuration over patching the JS, since the JS bundle is published as-is and will be overwritten on the next vendor:publish.
Semver signal. A 1.0.0 that consists almost entirely of renames plus two composition fixes says the API has stabilised but that the maintainer is willing to do a clean-break rename. Pin to ^1.0 and read release notes on minor bumps rather than assuming drop-in upgrades.
How can I help you explore Laravel packages today?