Skip to main content

Overview

The TextColumn displays text-based data from your database. It’s the most common column type and includes support for sorting, searching, and custom formatting.

Creating a Text Column

Basic Usage

use Livewire\Tables\Columns\TextColumn;

TextColumn::make('name')

Factory Method

You can also create text columns using the base Column class:
use Livewire\Tables\Columns\Column;

Column::text('name')

Without Field Binding

Create computed columns that don’t map to a database field:
TextColumn::make()
    ->label('Full Name')
    ->render(fn($row) => $row->first_name . ' ' . $row->last_name)

Common Methods

All methods return the column instance for fluent chaining.
label
string
Set a custom label for the column header. If not specified, the label is automatically generated from the field name.
TextColumn::make('email_address')->label('Email')
sortable
void
Enable sorting on this column.
TextColumn::make('name')->sortable()
searchable
string|Closure|null
Enable searching on this column. Accepts an optional field name for join columns or a custom closure for advanced search logic.
// Basic searchable
TextColumn::make('name')->searchable()

// Search on a joined table field
TextColumn::make('brand_name')->searchable('brands.name')

// Custom search logic
TextColumn::make('name')->searchable(
    fn($query, $search) => $query->orWhere('name', 'LIKE', "%{$search}%")
)
format
string|Closure
Format the cell value. Accepts a sprintf-style format string or a closure.
// Using sprintf format
TextColumn::make('price')->format('$%.2f')

// Using a closure
TextColumn::make('price')->format(fn($value, $row) => '$' . number_format($value, 2))
render
Closure
Completely customize the cell content. This takes precedence over format(). The closure receives the model instance and optionally the table component.
TextColumn::make()->render(function($row) {
    return "{$row->first_name} {$row->last_name}";
})
width
string
Set the column width using any CSS width value.
TextColumn::make('email')->width('300px')
TextColumn::make('name')->width('25%')
hidden
void
Hide the column from display.
TextColumn::make('internal_id')->hidden()
hideIf
bool
Conditionally hide the column based on a boolean condition.
TextColumn::make('admin_notes')->hideIf(!auth()->user()->isAdmin())
columnClass
string
Apply CSS classes to both the header and cell for this column.
TextColumn::make('price')->columnClass('text-right font-mono')
headerClass
string
Apply CSS classes only to the column header.
TextColumn::make('price')->headerClass('text-right')
cellClass
string
Apply CSS classes only to the column cells.
TextColumn::make('status')->cellClass('font-semibold')
key
string
Set a unique key for the column. Useful when using multiple columns with the same field.
TextColumn::make('created_at')->key('created')->label('Created')
TextColumn::make('created_at')->key('created_formatted')->label('Date')->format('M d, Y')
selectAs
string
Specify a SQL alias for the select statement. Useful for computed columns or aggregates.
TextColumn::make('total_orders')->selectAs('order_count')
view
string
Use a custom Blade view to render the cell.
TextColumn::make('status')->view('components.status-badge')

Examples

Basic Text Column

public function columns(): array
{
    return [
        TextColumn::make('name')
            ->sortable()
            ->searchable(),
            
        TextColumn::make('email')
            ->sortable()
            ->searchable(),
    ];
}

Formatted Price Column

TextColumn::make('price')
    ->label('Price')
    ->sortable()
    ->format(fn($value) => '$' . number_format($value, 2))
    ->columnClass('text-right font-mono')

Computed Full Name Column

TextColumn::make()
    ->label('Full Name')
    ->render(fn($row) => "{$row->first_name} {$row->last_name}")
    ->searchable(fn($query, $search) => 
        $query->where('first_name', 'LIKE', "%{$search}%")
              ->orWhere('last_name', 'LIKE', "%{$search}%")
    )
TextColumn::make('brand.name')
    ->label('Brand')
    ->sortable()
    ->searchable('brands.name')

Status Badge with Styling

TextColumn::make('status')
    ->sortable()
    ->render(function($row) {
        $colors = [
            'active' => 'bg-green-100 text-green-800',
            'pending' => 'bg-yellow-100 text-yellow-800',
            'inactive' => 'bg-gray-100 text-gray-800',
        ];
        
        $class = $colors[$row->status] ?? 'bg-gray-100 text-gray-800';
        
        return "<span class='px-2 py-1 rounded-full text-xs {$class}'>" . 
               ucfirst($row->status) . 
               "</span>";
    })

Conditional Formatting

TextColumn::make('balance')
    ->label('Balance')
    ->sortable()
    ->format(function($value, $row) {
        $formatted = '$' . number_format($value, 2);
        
        if ($value < 0) {
            return "<span class='text-red-600'>{$formatted}</span>";
        }
        
        return $formatted;
    })

Truncated Text with Tooltip

TextColumn::make('description')
    ->render(function($row) {
        $text = $row->description;
        $truncated = strlen($text) > 50 ? substr($text, 0, 50) . '...' : $text;
        
        return "<span title='{$text}'>{$truncated}</span>";
    })

Field Name Resolution

When using dotted field names (for relationships), the label is automatically derived from the last segment:
// Field: 'brands.name' → Label: 'Name'
TextColumn::make('brands.name')

// Field: 'orders.unit_price' → Label: 'Unit price'
TextColumn::make('orders.unit_price')
The internal resolution key automatically converts dots to underscores for attribute access:
  • brands.namebrands_name
  • orders.unit_priceorders_unit_price
See the Joins documentation for more information on working with related tables.

Build docs developers (and LLMs) love