Row Links
Introduction
Row Links and actions can be used to provide additional functionality to the rows in a table. They can be used to navigate to a different page or perform an action. Before defining Row Links and actions, it is necessary to include the ActionColumn
in the Table's column array. The ActionColumn
is a special column that is used to define Row Links and actions. Without the ActionColumn
, Row Links and actions will not be displayed.
use InertiaUI\Table\Columns;
class Users extends Table
{
public function columns(): array
{
return [
Columns\TextColumn::make('email'),
Columns\ActionColumn::new(),
];
}
}
Using Row Links
Row Links are used to navigate to a different page when. To define a row link, pass the label as the first argument and a callback as the second argument. The callback should return the URL to navigate to when the row link is clicked.
use App\Models\User;
use InertiaUI\Table\Action;
class Users extends Table
{
public function actions(): array
{
return [
Action::make('Edit', fn (User $user) => '/users/'.$user->id.'/edit'),
];
}
}
The callback accepts a second argument, which is a Url
object. Instead of returning a string URL, you can use the Url
object to generate URLs and tweak behavior.
use InertiaUI\Table\Url;
Action::make('Edit', fn (User $user, Url $url) => $url->route('users.edit', $user));
The Url
object has the following methods:
Action::make('Edit', fn (User $user, Url $url) => $url
->to('/users/'.$user->id.'/edit')
->route('users.edit', $user) // Same as URL::route()
->signedRoute('users.edit', $user) // Same as URL::signedRoute()
->temporarySignedRoute('users.edit', now()->addMinutes(30), $user) // Same as URL::temporarySignedRoute()
->preserveScroll()
->preserveState()
->openInNewTab()
->asDownload()
->disabled()
->hidden()
);
The preserveScroll()
, preserveState()
, openInNewTab()
, asDownload()
, disabled()
, and hidden()
methods accept a boolean argument that can be used to enable or disable the behavior:
Action::make('Edit', fn (User $user, Url $url) => $url
->route('users.edit', $user)
->disabled(!auth()->user()->is_admin)
);
The Url
class uses Laravel's Conditionable
trait, which can help prevent repeating the condition:
Action::make('Edit', fn (User $user, Url $url) => $url
->route('users.edit', $user)
->when(
auth()->user()->is_admin,
fn (Url $url) => $url->openInNewTab(),
fn (Url $url) => $url->disabled()
)
);
Downloading Files
Row Links usually navigate with the Inertia Router, which expects a JSON response and doesn't support file downloads. To download a file when a Row Link is clicked, you can use the asDownload()
method on the Action
or Url
object, or use the downloadUrl
argument in the make()
method.
// Call 'asDownload()' on the Action object
Action::make('Invoice', fn (Order $order) => $order->invoice_url)->asDownload();
// Call 'asDownload()' on the Url object
Action::make('Invoice', fn (Order $order, Url $url) => $url->to($order->invoice_url)->asDownload());
// Use the 'downloadUrl' argument in the 'make()' method
Action::make('Invoice', downloadUrl: fn (Order $order) => $order->invoice_url);
Display links as buttons
By default, Row Links are displayed as text links. To display Row Links as buttons, you can use the asButton()
method.
Action::make('Edit', fn (User $user) => route('users.edit', $user))->asButton();
To display a row link as a primary or danger button, you can use the asPrimaryButton()
or asDangerButton()
method.
Action::make('Edit', fn (User $user) => route('users.edit', $user))->asPrimaryButton();
Action::make('Suspend', fn (User $user) => route('users.suspend', $user))->asDangerButton();
Alternatively, you can use the style
argument to specify the button style with the ActionStyle enum.
use InertiaUI\Table\ActionStyle;
Action::make(
label: 'Edit',
url: fn (User $user) => route('users.edit', $user),
style: ActionStyle::PrimaryButton
);
Custom Icons
You can add an icon to the Row Link by using the icon()
method, or by using the icon
argument in the make()
method. In your Page component, you must define how the icon should be resolved. You can also configure this globally in your app.js
so that you don't have to define it for each Page.
Action::make(
label: 'Edit',
url: fn (User $user) => route('users.edit', $user),
icon: 'PencilIcon'
);
Let's take the Heroicons set as an example. On your Page, you can import the icon set and define a resolver method that will be used to resolve the icon name to the actual icon component. This method should be passed to the Table
component:
<script setup>
import { Table } from 'inertiaui/table'
import * as Icons from '@heroicons/vue/24/outline'
defineProps({
users: Object,
});
function resolveIcon(icon) {
return Icons[icon]
}
</script>
<template>
<Table :resource="users" :icon-resolver="resolveIcon" />
</template>
import { Table } from 'inertiaui/table'
import * as Icons from '@heroicons/react/24/outline'
export default function Users({ users }) {
function resolveIcon(icon) {
return Icons[icon]
}
return (
<Table resource={users} iconResolver={resolveIcon} />
);
}
Alternatively, you can do it inline without defining a separate method:
<template>
<Table :resource="users" :icon-resolver="(icon) => Icons[icon]" />
</template>
export default function Users({ users }) {
return (
<Table resource={users} iconResolver={(icon) => Icons[icon]} />
);
}
Resolve icons globally
If you want to resolve icons globally, you can do so in your app.js
file by importing the setIconResolver
function and passing the resolver method.
import { setIconResolver } from 'inertiaui/table'
import * as Icons from '@heroicons/vue/24/outline'
setIconResolver((icon, context) => Icons[icon])
Note that the resolver method receives a second argument, context
, which is an object containing the properties of the Action. This can be useful if you want to resolve the icon based on the label or other properties. Check out the Custom Table documentation for more information about the properties.
Use multiple icon sets
If you want to use multiple icon sets, you can define a resolver method that will resolve the icon based on the icon set. Here's an example using the Heroicons and Bootstrap Icons set:
import * as BootstrapIcons from "bootstrap-icons-vue";
import * as Heroicons from '@heroicons/vue/24/outline'
setIconResolver(icon => icon.startsWith('BIcon') ? BootstrapIcons[icon] : Heroicons[icon])
Of course, there are many other ways to resolve icons. If you use a limited set of icons, you can define a mapping object that maps the icon names to the actual components.
import { BIconTrashFill } from 'bootstrap-icons-vue';
import { PencilIcon } from '@heroicons/vue/24/outline';
setIconResolver(icon => ({
Pencil: PencilIcon,
Trash: BIconTrashFill
}[icon]))
Icon-only
You can display only the icon without the label by using the hideLabel()
method.
Action::make('Edit', fn (User $user) => route('users.edit', $user))
->icon('PencilIcon')
->hideLabel();
Data Attributes
You can add Data Attributes to the Row Links by using the dataAttributes
argument in the make()
method or by using the dataAttributes
method. You don't have to prefix the keys with data-
.
Action::make('Edit', fn (User $user) => route('users.edit', $user))
->dataAttributes(['action' => 'edit-user']);
Targetting Row Links with CSS
You can target the Row Link with specific data attributes using CSS. For example, to style the Row Link with the data-action="edit-user"
attribute, you can use the following CSS:
button[data-action="edit-user"] {
/* ... */
}
Metadata
You can add metadata to Actions by using the meta
argument in the make()
method or by using the meta()
method.
Action::make(
label: 'Edit',
url: fn (User $user) => route('users.edit', $user),
meta: ['key' => 'value'],
);
In the default Table component, this metadata is unused and not passed to any DOM element. However, this feature can be useful when extending the Table component using slots, or when you build a custom Table component.