Skip to content
Zonvoir Table LogoZonvoir Table
Zonvoir TableMenu
Laravel + Inertia.js + Tailwind

Tables that
speak Laravel.

Define tables with expressive PHP classes and render them with our first-party Vue and Inertia adapters.

Zonvoir Table dashboard preview showing searchable columns, status badges, and action buttons in Inertia Vue
Table Classes
Typed Columns
Searching
Sorting
Pagination
Column Visibility
Sticky Columns
Row Actions
Bulk Actions
Exports
TypeScript

The capability ledger

Every row, accounted for.

Zonvoir Table's own feature set, kept in the same format your users will see it in.

No.CapabilityLayerStatus
01Table DefinitionPHPCore
02Typed ColumnsPHPCore
03Search & SortQueryLive
04PaginationQueryStandard / Cursor
05Row & Bulk ActionsVueInteractive
06Column Visibility & StickyVueInteractive
07Excel ExportsServerFiltered / Selected
08TypeScript TypesFrontendGenerated

One class, one source of truth

The query, columns and payload - defined once.

A table class drives the Eloquent query, the columns, URL state, row actions, and exports. The Vue adapter just renders what it's given.

UsersTable.php
1  use App\Models\User;
2  use Zonvoir\ZonvoirTable\Columns\BadgeColumn;
3  use Zonvoir\ZonvoirTable\Columns\TextColumn;
4  use Zonvoir\ZonvoirTable\Export;
5  use Zonvoir\ZonvoirTable\Table;
6
7  final class UsersTable extends Table
8  {
9     protected ?string $resource = User::class;
10     protected array|string|null $search = ['name', 'email'];
11     protected ?string $defaultSort = 'name';
12
13     public function columns(): array
14     {
15         return [
16             TextColumn::make('name', 'Full Name')->searchable(),
17             TextColumn::make('email')->searchable(),
18         ];
19     }
20  }
Query
Columns
URL State
Export

Features

Built for every row. Ready for every workflow.

features / table-definition.php

# Built-in Table Definition

One PHP class drives the query, columns, URL state, row actions, exports, and frontend metadata.

  • Resolve an Eloquent model class or query builder.
  • Return typed column, action, and export definitions.
  • Serialize a stable payload for Inertia.
UsersTable::make();

Read the Table Generation Guide →

features / sorting.php

# Sorting

Sortable columns expose direction-aware query state while the backend stays in charge of the query.

  • Enable sorting per column.
  • Use `-column` for descending defaults.
  • Override sorting with `sortUsing()` when needed.
protected ?string $defaultSort = '-created_at';

TextColumn::make(‘name’)->sortable();

Read the Sorting Guide →

features / pagination.php

# Pagination

Pagination configuration lives with the table, including allowed page sizes and pagination strategy.

  • Standard, simple, and cursor modes.
  • Configurable per-page options.
  • Normalized page, cursor, and per-page input.
protected ?int $defaultPerPage = 30;
protected ?array $perPageOptions = [15, 30, 50];

Read the Pagination Guide →

features / row-actions.php

# Row Actions & Links

Actions and row URLs are serialized as metadata so Vue can render the right controls.

  • Return actions from `actions()`.
  • Use `Url` for route and Inertia metadata.
  • Support authorization, disabled, hidden, and confirm states.
Action::make('Edit')
    ->url(fn ($user, $url) => $url->route('users.edit', $user));

Read the Row Actions Guide →

features / bulk-actions.php

# Bulk Actions

Bulk actions reuse the action API and execute against selected row keys.

  • Enable bulk mode with `asBulkAction()`.
  • Use `onlyAsBulkAction()` for bulk-only flows.
  • Control chunk size and strategy.
Action::make('Archive')
    ->asBulkAction(chunkSize: 100)
    ->confirm('Archive users?');

Read the Bulk Actions Guide →

features / columns.php

# Columns

One Columns guide covers common options plus text, numeric, boolean, badge, image, date, date-time, and action columns.

  • Shared visibility, sizing, sticky, search, and sort metadata.
  • Column-specific display settings.
  • Export labels, values, formats, and styles.
BadgeColumn::make('status')
    ->colors(['active' => 'success'])
    ->solid();

Read the Typed Columns Guide →

features / sticky-columns.php

# Sticky Columns

Sticky columns keep high-value identifiers visible while users scan wide data sets.

  • Enable sticky behavior per column.
  • Pair with width metadata for predictable layout.
  • Allow sticky overrides through table state.
TextColumn::make('name')
    ->sticky()
    ->width('16rem');

Read the Sticky Columns Guide →

features / exports.php

# Excel Exports

Return export definitions from the table and choose filtered or selected-row export scope.

  • Expose export controls in table metadata.
  • Limit to filtered or selected rows.
  • Queue large exports when needed.
Export::make('Users', 'users.xlsx')
    ->limitToFilteredRows();

Read the Exports Guide →

features / url-state.php

# URL State

Table state is represented in query string keys for page, per-page, cursor, search, sort, direction, columns, and sticky overrides.

  • Name tables to namespace query state.
  • Generate navigation URLs from the current state.
  • Keep reloads and browser history predictable.
$table->navigation()->search('olivia');
$table->navigation()->sort('name');

Read the Table State & URL API →

features / multiple-tables.php

# Multiple Tables

Name each table to avoid query string collisions when a page renders more than one table.

  • Use `named()` or `as()`.
  • Separate page, search, sort, columns, and sticky state.
  • Render multiple independent table payloads.
UsersTable::make()->named('users')->results();
OrdersTable::make()->named('orders')->results();

Read the Multiple Tables Guide →

GUIDES

Start with a real table

Create a table, render it, then add behavior feature by feature.

CONCEPTS

Understand the moving parts

Columns, state, row links, selection, pagination, and payload shape.

API REFERENCE

Check exact signatures

Classes, methods, enum cases, callback signatures, and Vue exports.