Core
Actions
The Actions module provides row, bulk, and header actions for tables and related UI flows.
The Actions module provides row, bulk, and header actions for tables and related UI flows.
Action Types
| Class | Use Case | Callback Receives |
|---|---|---|
Action |
Row action — single record | fn (Model $record, array $data) |
BulkAction |
Selected records | fn (Collection $records, array $data) |
HeaderAction |
Table header — no record context | fn (array $data) |
ActionGroup |
Groups actions into a dropdown | — |
All extend BaseAction and share the same fluent API for label, icon, color, size, modal, lifecycle.
Pre-built Actions
| Class | Description |
|---|---|
DeleteAction |
Single record delete with confirmation |
DeleteBulkAction |
Bulk delete with confirmation |
EditAction |
Opens edit modal/form |
ViewAction |
Opens view modal |
use NyonCode\WireCore\Actions\DeleteAction;use NyonCode\WireCore\Actions\DeleteBulkAction; $table->actions([DeleteAction::make()]) ->bulkActions([DeleteBulkAction::make()]);
Basic Usage
use NyonCode\WireCore\Actions\Action;use NyonCode\WireCore\Actions\BulkAction;use NyonCode\WireCore\Actions\HeaderAction; // Row actionAction::make('edit') ->label('Edit') ->icon('pencil') ->color('primary') ->url(fn (User $record) => route('users.edit', $record)) // Row action with callbackAction::make('archive') ->label('Archive') ->icon('archive') ->action(fn (User $record) => $record->update(['archived' => true])) ->successNotification('Archived!') // Bulk actionBulkAction::make('export') ->label('Export Selected') ->icon('download') ->action(fn (Collection $records) => Excel::download($records)) ->deselectRecordsAfterCompletion() // Header actionHeaderAction::make('create') ->label('New User') ->icon('plus') ->url(route('users.create')) ->badge(fn () => User::whereNull('verified_at')->count()) ->badgeColor('danger')
Action Groups
use NyonCode\WireCore\Actions\ActionGroup; $table->actions([ Action::make('edit')->icon('pencil'), ActionGroup::make('more', [ Action::make('duplicate') ->icon('copy') ->action(fn ($record) => $record->replicate()->save()), Action::make('archive') ->icon('archive') ->action(fn ($record) => $record->archive()), Action::divider(), // visual separator Action::make('delete') ->icon('trash') ->color('danger') ->requiresConfirmation() ->action(fn ($record) => $record->delete()), ])->divided(), // auto-insert dividers between items]);
Groups support badge() and badgeColor() just like HeaderAction.
Dynamic Properties
All properties support Closures — evaluated per-record at render time:
Action::make('toggle') ->label(fn (User $record) => $record->is_active ? 'Deactivate' : 'Activate') ->color(fn (User $record) => $record->is_active ? 'danger' : 'success') ->icon(fn (User $record) => $record->is_active ? 'x' : 'check') ->hidden(fn (User $record) => $record->trashed())
Confirmation Modal
Action::make('delete') ->requiresConfirmation() ->modalHeading('Delete this record?') ->modalDescription('This action cannot be undone.') ->modalIcon('trash', 'danger') ->modalSubmitActionLabel('Yes, delete') ->modalCancelActionLabel('Cancel') ->action(fn ($record) => $record->delete());
Slide-Over
Action::make('details') ->slideOver() ->stickyHeader() ->stickyFooter() ->modalMaxHeight('60vh');
Modal Appearance
Action::make('edit') ->modalWidth('2xl') // sm, md, lg, xl, 2xl, 3xl, 4xl, 5xl ->modalAlignment('center') // center, start ->closeModalOnClickAway() ->closeModalOnEscape() ->slideOverOnMobile() // slide-over on mobile, modal on desktop ->fullScreenOnMobile(); // full screen on mobile
Form Modal
When wire-forms is installed, actions can display form modals:
use NyonCode\WireForms\Components\TextInput;use NyonCode\WireForms\Components\Select; Action::make('edit') ->form([ TextInput::make('name')->required(), Select::make('role')->options([ 'admin' => 'Admin', 'editor' => 'Editor', ]), ]) ->fillFormUsing(fn ($record) => $record->only(['name', 'role'])) ->action(fn ($record, array $data) => $record->update($data));
Multi-Step Wizard
use NyonCode\WireCore\Actions\ModalStep; Action::make('create') ->steps([ ModalStep::make('basics') ->label('Basic Info') ->description('Enter user details') ->icon('user') ->fields([ TextInput::make('name')->required(), TextInput::make('email')->email()->required(), ]), ModalStep::make('settings') ->label('Settings') ->fields([ Select::make('role')->options([...]), Toggle::make('active'), ]), ModalStep::make('review') ->label('Review') ->fields([ Placeholder::make('summary'), ]), ]) ->action(fn ($record, $data) => $record->update($data));
Footer Actions
use NyonCode\WireCore\Actions\ModalFooterAction; Action::make('edit') ->form([...]) ->modalFooterActions([ ModalFooterAction::make('save') ->label('Save') ->color('primary') ->submit(), ModalFooterAction::make('save-and-close') ->label('Save & Close') ->action(fn () => $this->saveAndClose()), ]);
Lifecycle Hooks
Action::make('publish') ->before(fn ($record) => $record->validate()) ->action(fn ($record) => $record->update(['status' => 'published'])) ->after(fn ($record) => event(new Published($record))) ->successNotification('Published!') ->failureNotification('Publish failed.');
Halt Execution
Halt pauses execution and shows a secondary modal for user confirmation:
Action::make('process') ->before(function ($record, Action $action) { if ($record->has_warnings) { $action->halt() ->modalHeading('Warnings Detected') ->modalDescription('There are unresolved warnings. Continue anyway?'); } }) ->action(fn ($record) => $record->process());
Icon Button
Action::make('edit') ->icon('pencil') ->iconButton() // renders as icon-only button ->tooltip('Edit record'); // Or hide just the labelAction::make('edit') ->icon('pencil') ->hideLabel();
URL Actions
Action::make('view') ->url(fn ($record) => route('users.show', $record)) ->openUrlInNewTab(); // String URLAction::make('docs') ->url('/docs') ->openUrlInNewTab();
Keyboard Shortcuts
Action::make('save')->keyboardShortcut('mod+s');Action::make('delete')->keyboardShortcut('Delete');
Uses Alpine.js @keydown under the hood.
Outlined & Sizing
Action::make('cancel') ->outlined() // outline variant instead of solid ->color('gray') ->size('sm'); // xs, sm, md, lg
Extra Attributes
Action::make('custom') ->extraAttributes([ 'data-testid' => 'custom-action', 'x-on:click' => 'console.log("clicked")', ]);
BaseAction API Reference
Shared across Action, BulkAction, HeaderAction:
->label(string|Closure $label)->icon(string|Closure $icon)->iconPosition('before'|'after')->color(string|Closure $color) // primary, danger, success, warning, info, gray->size(string $size) // xs, sm, md, lg->outlined(bool $outlined = true)->tooltip(string|Closure $tooltip)->action(Closure $callback)->hidden(bool|Closure $hidden = true)->visible(bool|Closure $visible = true)->disabled(bool|Closure $disabled = true)->requiresConfirmation()->modalHeading(string $heading)->modalDescription(string $description)->modalIcon(string $icon, ?string $color)->modalWidth(string $width)->modalSubmitActionLabel(string $label)->modalCancelActionLabel(string $label)->slideOver()->form(array $components)->fillFormUsing(Closure $fn)->steps(array $steps)->before(Closure $fn)->after(Closure $fn)->successNotification(string $message)->failureNotification(string $message)->keyboardShortcut(string $keys)->extraAttributes(array $attrs)
Blade Components
<x-wire-actions::button :action="$action" /><x-wire-actions::group :group="$group" />