Skip to content
Zonvoir Table LogoZonvoir Table

Row Actions & Interactive Menus

Row actions let users perform operations on a specific record directly from the table.

Define row actions by returning Action objects from your table’s actions() method.

use Zonvoir\ZonvoirTable\Action;
use Zonvoir\ZonvoirTable\Url;
public function actions(): array
{
return [
Action::make('Edit')
->icon('mdi:pencil')
->url(
fn (User $user, Url $url) =>
$url->route('users.edit', $user)
),
];
}

Each action is resolved for the current row and passed to the frontend adapter.

An action with URL metadata behaves as a link.

Action::make('View')
->icon('heroicons:eye')
->url(
fn (User $user, Url $url) =>
$url->route('users.show', $user)
);

Link actions are useful for navigation such as:

  • View
  • Edit
  • Open details
  • Navigate to related resources

You can use the normal Url options when configuring navigation:

Action::make('Edit')
->url(
fn (User $user, Url $url) => $url
->route('users.edit', $user)
->preserveScroll()
);

When an action has a backend handler instead of URL metadata, Zonvoir Table treats it as an executable action.

For example:

Action::make('Archive')
->icon('mdi:archive')
->confirm(
'Archive user?',
'This action can be reversed later.'
)
->handle(function (User $user) {
$user->update([
'archived_at' => now(),
]);
});

Use backend actions for operations that modify or process the current record.

The exact handler method may depend on your current Action API. Use the handler method exposed by your package and keep the row record type-hinted where possible.

An action without URL metadata or a backend handler is serialized as a custom action.

Action::make('Preview')
->icon('heroicons:eye');

Custom actions can be handled by the frontend when you need application-specific behavior that does not map directly to navigation or a backend operation.

Zonvoir Table determines the action type from its configuration.

Configuration Type
Has URL metadata link
Has a backend handler action
Has neither custom

You normally do not need to set the action type manually.

Add an icon using a string-based icon identifier.

Action::make('Edit')
->icon('mdi:pencil');

You can use any icon collection supported by your frontend adapter:

->icon('heroicons:pencil')
->icon('lucide:pencil')
->icon('mdi:pencil')

See the Icons guide for more information.

Use tooltip() to provide additional context.

Action::make('Archive')
->icon('mdi:archive')
->tooltip('Archive user');

Tooltips are especially useful when the action label is hidden.

Use hideLabel() to render an icon-only action.

Action::make('Edit')
->icon('mdi:pencil')
->tooltip('Edit user')
->hideLabel();

When hiding labels, adding a tooltip is recommended so the action remains understandable.

Use variant() to control the visual style of the action.

Action::make('Edit')
->variant('ghost');

You can also configure the variant color:

Action::make('Delete')
->variant('ghost')
->variantColor('red');

This is useful for visually distinguishing destructive or secondary actions.

Use confirm() when an action should require confirmation before it runs.

Action::make('Archive')
->icon('mdi:archive')
->confirm(
'Archive user?',
'This action can be reversed later.'
);

The first argument is the confirmation title and the second provides additional context.

Confirmation is useful for operations such as:

  • Delete
  • Archive
  • Disable
  • Remove access
  • Other potentially destructive changes
public function actions(): array
{
return [
Action::make('View')
->icon('heroicons:eye')
->url(
fn (User $user, Url $url) =>
$url->route('users.show', $user)
),
Action::make('Edit')
->icon('mdi:pencil')
->tooltip('Edit user')
->hideLabel()
->variant('ghost')
->url(
fn (User $user, Url $url) =>
$url->route('users.edit', $user)
),
Action::make('Archive')
->icon('mdi:archive')
->tooltip('Archive user')
->hideLabel()
->variant('ghost')
->variantColor('red')
->confirm(
'Archive user?',
'This action can be reversed later.'
),
];
}

Row actions are defined through actions().

Use ActionColumn when you want to control where those actions appear in the table.

use Zonvoir\ZonvoirTable\Columns\ActionColumn;
ActionColumn::make()
->asDropdown();

This lets you keep the action definitions separate from their table presentation.