Summary
Press-and-hold confirmation for high-risk Filament actions (delete account, purge data, irreversible settings). The user must keep the button pressed until a fill animation completes — a single click does nothing. Accidental taps are blocked; intentional actions feel deliberate.| Class | Bjanczak\FilamentFlexFields\Filament\Actions\Action |
| Extends | Filament\Actions\Action |
| Trait | CanRequireHoldConfirm |
| Enabler | ->holdConfirm() on the package Action class |
| Assets | Lazy hold-confirm-action.js + hold-confirm-action.css per rendered action |
Important: Import the package action class, not Filament’s base class:
use Bjanczak\FilamentFlexFields\Filament\Actions\Action;
When to use it
| Pattern | Good for |
|---|---|
->holdConfirm() | Destructive or irreversible actions where a normal click is too easy to trigger by mistake |
->requiresConfirmation() | Actions that need an explicit modal “Are you sure?” step |
| Both together | Rare — pick one UX pattern per action |
action() callbacks and url() navigation.
Quick start
color('danger').
How it works
- PHP renders the normal Filament button, then wraps label/icon in base and overlay layers (
renderHoldConfirmTriggerHtml()). - The action view swaps to
filament-flex-fields::actions.hold-confirmand disables the default Livewire click handler. - Alpine
holdConfirmActionFormComponentlistens for pointer down on the left mouse button / touch. - Progress fills over
durationms using a directional clip-path (sweep). - Releasing early reverses progress over
releaseDurationms. - At 100%, Alpine dispatches
fff-hold-complete→$wire.mountAction('…')or navigates tourl().
click events are suppressed so the action cannot fire without completing the hold.
Configuration catalog
| Method | Type / values | Default | Section |
|---|---|---|---|
holdConfirm() | int ms, string sweep | 2000, 'right' | Duration |
holdConfirmSweep() | right, left, up, down | right | Sweep direction |
holdConfirmReleaseDuration() | int ms | 200 | Release animation |
holdConfirmThemed() | bool | true | Theming |
rounded() | none, sm, md, lg, xl, full | auto full for danger | Rounded corners |
itemCard() | bool | false | Item card styling |
label(), icon(), color(), size(), disabled(), url(), action(), requiresConfirmation(), etc.) work as usual.
Basic usage
Default hold (2 seconds)
Custom duration
Fast confirmation (800 ms)
Useful for lower-risk actions that still benefit from intentional input:Sweep direction
The fill animation direction. Second argument toholdConfirm() or via holdConfirmSweep().
right (default)
left
up
down
Change sweep after holdConfirm()
'diagonal') throw InvalidArgumentException.
Release animation
When the user releases before completion, progress animates back to zero.Theming
WhenholdConfirmThemed() is enabled (default), color('danger') applies the package danger track/fill palette (fff-hold-confirm-action--palette-danger) and defaults to fully rounded corners.
Danger palette (default for destructive actions)
Keep Filament’s native button colors
Primary / success / warning
Themed palette applies only todanger today. Other colors use Filament styling with the hold overlay on top:
Rounded corners
Use the packagerounded() helper (CanRoundAction):
none, sm, md, lg, xl, full.
Item card integration
Common pattern: destructive control in an ItemCard trailing slot.itemCard() + holdConfirm() for settings-style rows. See the playground Item card group section for live demos (default, fast 800 ms, slow 4 s left sweep).
Table actions
Action instances. Always use the package Action class.
Resource page actions
URL actions
Hold confirm can navigate instead of calling Livewire:Disabled state
When the action is disabled, Alpine receivesdisabled: true and ignores pointer down:
Comparison with modal confirmation
requiresConfirmation() when you need to show extra context, a checkbox, or typed confirmation in a modal.
Assets & performance
| Asset | Loading |
|---|---|
hold-confirm-action.js | Per-action @push modulepreload + Alpine x-load when action renders |
hold-confirm-action.css | Lazy via load-stylesheet partial when action renders |
core.css bundle — only actions that call holdConfirm() pull the stylesheet. After upgrading the package, run:
Accessibility & mobile
- Only primary button (
event.button === 0) starts a hold; right-click is ignored. - Progress is visual; pair with a clear
label()(e.g. “Hold to Delete”). - On supported devices, a short vibration fires when the hold completes.
wire:loadingindicators are preserved outside the duplicated label layers.
Playground
Enable the Flex Fields playground and open Item card group:| Card | Duration | Sweep | Color |
|---|---|---|---|
| Hold confirm | 2000 ms | right | primary |
| Hold confirm (fast) | 800 ms | right | danger |
| Hold confirm (slow) | 4000 ms | left | danger |
API reference
holdConfirm(int|Closure $duration = 2000, string|Closure $sweep = 'right'): static
Enables hold-to-confirm, sets duration and sweep, disables Livewire click handler, switches view to hold-confirm. Auto-applies rounded('full') for danger actions when no explicit rounded() was set.
holdConfirmSweep(string|Closure $sweep): static
Updates sweep direction: right, left, up, down.
holdConfirmReleaseDuration(int|Closure $duration): static
Milliseconds to animate progress back to zero when the user releases early. Default: 200.
holdConfirmThemed(bool|Closure $themed = true): static
When true, applies package danger palette for color('danger'). When false, keeps Filament’s default button styling.
Introspection (advanced)
| Method | Returns |
|---|---|
hasHoldConfirm() | Whether hold confirm is active |
getHoldConfirmDuration() | Hold duration in ms, or null |
getHoldConfirmSweep() | Sweep direction string |
getHoldConfirmReleaseDuration() | Release duration in ms |
isHoldConfirmThemed() | Whether themed palette is enabled |
getHoldConfirmPalette() | 'danger' or null |
getHoldConfirmCompleteExpression() | JS expression run on complete (testing / debugging) |
Related
- ItemCard — trailing
Actionslots anditemCard()styling - ItemCardGroup — grouped settings rows with hold confirm demos
- Shared concepts — lazy assets and design tokens