Skip to content
Zonvoir Table LogoZonvoir Table

Table Columns & Formatting

Columns define how values from your records are displayed, formatted, and serialized by Zonvoir Table.

They control properties such as labels, formatting, sorting, searching, visibility, sizing, sticky behavior, row links, images, exports, and frontend metadata.

Return your columns from the columns() method of your table class.

use Zonvoir\ZonvoirTable\Columns\BadgeColumn;
use Zonvoir\ZonvoirTable\Columns\TextColumn;
public function columns(): array
{
return [
TextColumn::make('name')
->label('Name')
->sortable()
->searchable()
->sticky(),
TextColumn::make('email')
->searchable(),
BadgeColumn::make('status')
->colors([
'active' => 'success',
'pending' => 'warning',
]),
];
}

Zonvoir Table includes several column types for common data patterns.


Most columns extend the base Column class and share a common set of configuration methods.

Method Description
label() Set the column heading.
key() Override the serialized key.
visible() Control whether the column is visible initially.
sortable() Allow the column to be sorted.
searchable() Include the column in table search.
toggleable() Allow users to show or hide the column.
sticky() Keep the column fixed while horizontally scrolling.
alignment() Control cell alignment.
width() Set the preferred width.
minWidth() Set the minimum width.
maxWidth() Set the maximum width.
labelClass() Add classes to the column heading.
cellClass() Add classes to table cells.
tooltip() Add additional information to the heading.
defaultValue() Provide a fallback when no value exists.
mapAs() Transform the value before serialization.
url() Make the cell resolve to a URL.
image() Attach image metadata to the column.
exportAs() Change how the value is exported.
dontExport() Exclude the column from exports.
meta() Attach custom frontend metadata.

Not every method is relevant to every column type.

Specialized columns may provide additional methods specific to their value type.


By default, the column name determines which value is read from the model.

TextColumn::make('email');

For a User model, this resolves:

$user->email;

Nested values can also be represented when supported by your table configuration.

TextColumn::make('profile.phone')
->label('Phone');

Use mapAs() when you need to transform a value before it is sent to the frontend.

The callback receives the resolved value and the current record.

TextColumn::make('name')
->mapAs(
fn ($value, User $user) => strtoupper($user->name)
);

You can also ignore the original value entirely:

TextColumn::make('user')
->label('User')
->mapAs(
fn ($value, User $user) => $user->first_name.' '.$user->last_name
);

mapAs() changes the serialized display value.

If the underlying database column is sortable or searchable, those operations still work against the configured backend field rather than the mapped display value.


TextColumn is the general-purpose column and is suitable for most string-like values.

use Zonvoir\ZonvoirTable\Columns\TextColumn;
TextColumn::make('name')
->label('Full Name')
->sortable()
->searchable();

Typical uses include:

  • Names
  • Emails
  • Identifiers
  • Addresses
  • Descriptions
  • General text values
TextColumn::make('email')
->label('Email address')
->searchable()
->toggleable();

NumericColumn provides formatting metadata for numeric values.

use Zonvoir\ZonvoirTable\Columns\NumericColumn;
NumericColumn::make('revenue')
->precision(2)
->thousandsSeparator(',')
->decimalSeparator('.')
->prefix('$');

It is useful for values such as:

  • Currency
  • Totals
  • Quantities
  • Percentages
  • Measurements
NumericColumn::make('price')
->precision(2)
->prefix('$');
NumericColumn::make('progress')
->precision(0)
->suffix('%');

BooleanColumn is designed for boolean and nullable boolean values.

use Zonvoir\ZonvoirTable\Columns\BooleanColumn;
BooleanColumn::make('active')
->trueLabel('Active')
->falseLabel('Inactive')
->nullLabel('Unknown');

This lets the frontend display meaningful labels instead of raw true, false, or null values.


BadgeColumn is ideal for statuses, states, categories, and other compact values.

use Zonvoir\ZonvoirTable\Columns\BadgeColumn;
BadgeColumn::make('status')
->colors([
'active' => 'success',
'pending' => 'warning',
'disabled' => 'muted',
])
->solid();
BadgeColumn::make('status')
->colors([
'draft' => 'neutral',
'active' => 'success',
'pending' => 'warning',
'failed' => 'danger',
]);

You can use badge variants to match the visual hierarchy of your application.


ImageColumn provides metadata for displaying images such as avatars and thumbnails.

use Zonvoir\ZonvoirTable\Columns\ImageColumn;
use Zonvoir\ZonvoirTable\Image;
ImageColumn::make('avatar')
->image(
fn (User $user, Image $image) => $image
->url($user->avatar_url)
->rounded()
->small()
->alt($user->name)
);

Typical uses include:

  • User avatars
  • Product thumbnails
  • Logos
  • File previews

For image sizing options, rounded avatars, and alternative text callbacks, see the full Images guide.


DateColumn is intended for date-only values.

use Zonvoir\ZonvoirTable\Columns\DateColumn;
DateColumn::make('joined_at')
->format('M j, Y')
->placeholder('Not set');

Example output:

Aug 27, 2026

Use DateTimeColumn instead when the time portion is important.


DateTimeColumn handles date and time values and supports timezone metadata.

use Zonvoir\ZonvoirTable\Columns\DateTimeColumn;
DateTimeColumn::make('created_at')
->format('M j, Y g:i A')
->timezone('UTC');

Example output:

Aug 27, 2026 2:30 PM

SerialNumberColumn renders the current row number without needing a value on the model. Its default key is _serial_number, its label is S.no, and it is centered and non-toggleable by default.

use Zonvoir\ZonvoirTable\Columns\SerialNumberColumn;
public function columns(): array
{
return [
SerialNumberColumn::make(),
TextColumn::make('name'),
];
}

The Vue adapter calculates the number from the row position and the paginator offset, so a paginated table continues its numbering on subsequent pages.


ActionColumn controls where row actions are rendered inside the table.

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

For example, a row may expose actions such as:

View
Edit
Delete

The actual actions are defined by your table’s action configuration, while ActionColumn controls their placement inside the row.


A typical table will use several column types together.

public function columns(): array
{
return [
ImageColumn::make('avatar'),
TextColumn::make('name')
->sortable()
->searchable(),
TextColumn::make('email')
->searchable(),
BadgeColumn::make('status')
->colors([
'active' => 'success',
'pending' => 'warning',
]),
DateTimeColumn::make('created_at')
->label('Created')
->sortable(),
ActionColumn::make()
->asDropdown(),
];
}