gtcesar/filament-expandable-table

Expandable master-detail rows with nested Filament tables

Maintainers

Package info

github.com/gtcesar/filament-expandable-table

pkg:composer/gtcesar/filament-expandable-table

Statistics

Installs: 1

Dependents: 0

Suggesters: 0

Stars: 4

Open Issues: 0

v1.0.0 2026-05-09 13:19 UTC

This package is auto-updated.

Last update: 2026-05-09 19:55:01 UTC


README

filament-expandable-table

Expandable master-detail rows with nested Filament tables

Packagist License PHP Filament

πŸ‡ΊπŸ‡Έ English Β |Β  πŸ‡§πŸ‡· PortuguΓͺs

πŸ‡ΊπŸ‡Έ English

What does this plugin do?

It adds expandable rows to Filament 5 tables. When the user clicks the expand button on a row, a full Filament table appears directly below it β€” no modal, no page redirect.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  # β”‚ Customer       β”‚ Total    β”‚ Status   β”‚      [+]    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1 β”‚ John Smith     β”‚ $120.00  β”‚ Paid     β”‚      [+]    β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚    ↳ Items for Order #1                                  β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β” β”‚
β”‚    β”‚ Product          β”‚ Qty  β”‚ Unit Price             β”‚ β”‚
β”‚    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€ β”‚
β”‚    β”‚ Blue T-Shirt (M) β”‚  2   β”‚ $ 30.00                β”‚ β”‚
β”‚    β”‚ Slim Jeans       β”‚  1   β”‚ $ 60.00                β”‚ β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜ β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  2 β”‚ Mary Johnson    β”‚ $200.00  β”‚ Pending  β”‚      [+]    β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

The expand/collapse toggle is instant (no server round-trip). Sub-table data is loaded on demand by Livewire.

The sub-table is a full Filament table: columns, filters, actions, bulk actions, sorting, search, and pagination all work out of the box.

Requirements

You need a Laravel project with Filament 5 already installed and working.

Dependency Min version
PHP 8.3+
Laravel 11 or 12
Filament 5.x
Livewire 4.x (bundled with Filament 5)

Installation

Run these two commands from your project root:

composer require gtcesar/filament-expandable-table
php artisan filament:assets

The first installs the package. The second publishes the CSS and JS assets the plugin needs for styling and animations.

No extra configuration needed. Laravel auto-discovers the service provider. You do not need to touch AppServiceProvider, PanelProvider, or any config file.

Step-by-step setup

We'll build an Orders table where each row expands to show its Order Items.

Step 1 β€” Create the sub-table class

Create a PHP file anywhere in your project (we suggest app/Filament/Tables/). This class describes the sub-table: which columns to show, which filters to apply, and how to fetch the related records.

<?php

// app/Filament/Tables/OrderItemsTable.php

namespace App\Filament\Tables;

use App\Models\OrderItem;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Tibras\ExpandableTable\Contracts\HasExpandedTable;

class OrderItemsTable implements HasExpandedTable
{
    public function table(Table $table, Model $record): Table
    {
        // $record is the parent row (the Order).
        // Use $record->id to fetch only the items belonging to that order.
        return $table
            ->query(
                OrderItem::query()->where('order_id', $record->id)
            )
            ->columns([
                TextColumn::make('product_name')
                    ->label('Product')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('quantity')
                    ->label('Qty')
                    ->sortable(),
                TextColumn::make('unit_price')
                    ->label('Unit Price')
                    ->money('USD')
                    ->sortable(),
                TextColumn::make('status')
                    ->label('Status')
                    ->badge(),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->label('Status')
                    ->options([
                        'pending'   => 'Pending',
                        'shipped'   => 'Shipped',
                        'delivered' => 'Delivered',
                    ]),
            ])
            ->actions([
                EditAction::make(),
                DeleteAction::make(),
            ])
            ->paginated([5, 10, 25])
            ->defaultSort('product_name');
    }
}

What does implements HasExpandedTable mean? It's a PHP contract that guarantees your class has the table() method the plugin needs to call. Think of it as a promise: the plugin knows it can ask any class that implements HasExpandedTable to build a table.

Step 2 β€” Add the expand button to the parent table

In your ListRecords page, add ExpandAction to the table actions array:

<?php

// app/Filament/Resources/OrderResource/Pages/ListOrders.php

namespace App\Filament\Resources\OrderResource\Pages;

use App\Filament\Resources\OrderResource;
use App\Filament\Tables\OrderItemsTable;
use Filament\Resources\Pages\ListRecords;
use Tibras\ExpandableTable\Actions\ExpandAction;

class ListOrders extends ListRecords
{
    protected static string $resource = OrderResource::class;

    protected function getTableActions(): array
    {
        return [
            ExpandAction::make()
                ->detailComponent(OrderItemsTable::class),
            // Other actions (EditAction, DeleteAction, etc.) can go here too.
        ];
    }
}

This adds a [+] button to each row. Clicking it instantly toggles the row open or closed via Alpine.js β€” no server call needed.

Step 3 β€” Render the sub-table in the view

This step "closes the loop": you tell Filament where to render the sub-table when a row is expanded.

Finding the right view file:

Publish Filament's views if you haven't already:

php artisan filament:publish --views

The file to edit is:

resources/views/vendor/filament-tables/index.blade.php

Inside that file, find the <tr> that renders each data row (look for a @foreach over the records). Add the following block right after that <tr>:

{{-- Expansion row β€” hidden until the [+] button is clicked --}}
<tr x-show="$store.expandableTable.isExpanded('{{ $this->getId() }}.{{ $record->getKey() }}')">
    <td colspan="99" class="p-0">
        @livewire(
            'expandable-table::expanded-table-detail',
            [
                'recordClass'     => get_class($record),
                'recordKey'       => $record->getKey(),
                'detailComponent' => \App\Filament\Tables\OrderItemsTable::class,
            ],
            key('expand-' . $record->getKey())
        )
    </td>
</tr>

Why colspan="99"? So the sub-table cell spans the full width of the parent table, regardless of how many columns it has.

Why key('expand-' . $record->getKey())? Livewire uses this key to keep each row's sub-table state isolated. Without it, sub-tables from different rows interfere with each other.

Optional: start a row expanded

To have certain rows open by default when the page loads (e.g., the most recent order), use ->startExpanded():

ExpandAction::make()
    ->detailComponent(OrderItemsTable::class)
    ->startExpanded(fn (Order $record): bool => $record->is_latest),

Or pass true to expand all rows by default:

->startExpanded()  // equivalent to ->startExpanded(true)

API reference

ExpandAction

Method Description
->detailComponent(string|Closure) The fully-qualified class name of the class implementing HasExpandedTable. Required.
->startExpanded(bool|Closure) If true (or if the Closure returns true), the row starts expanded. Default: false.

HasExpandedTable (interface)

interface HasExpandedTable
{
    public function table(Table $table, Model $record): Table;
}
Parameter Description
$table The Filament Table instance β€” use all the standard fluent methods: ->query(), ->columns(), ->filters(), ->actions(), ->bulkActions(), ->defaultSort(), etc.
$record The parent row's Eloquent model (e.g., the Order). Use it to scope the sub-table query.

How it works

User clicks [+]
      β”‚
      β–Ό
Alpine.js toggles store (no server round-trip)
      β”‚
      β–Ό
<tr x-show="isExpanded(...)"> becomes visible via CSS
      β”‚
      β–Ό
Livewire mounts ExpandedTableDetail component
      β”‚
      β–Ό
ExpandedTableDetail calls OrderItemsTable::table()
      β”‚
      β–Ό
Full Filament table rendered inside the row

Troubleshooting

Sub-table doesn't appear after clicking the button

Check that:

  1. key('expand-' . $record->getKey()) is present in the @livewire call.
  2. x-show is on the <tr> element itself, not on a wrapper inside it.

Sub-table has no styling (CSS missing)

Run php artisan filament:assets and verify expandable-table.css was published to public/vendor/filament/.

Button exists but doesn't react to clicks

The plugin's JavaScript may not be loaded. Run php artisan filament:assets again and hard-refresh your browser (Ctrl+Shift+R).

Page is slow with many rows

Livewire mounts one component per open row. Keep the parent table paginated to 25 records or fewer.

Can I use different sub-tables depending on the record?

Yes. Use a Closure in ->detailComponent():

ExpandAction::make()
    ->detailComponent(fn (Order $record): string => match ($record->type) {
        'wholesale' => WholesaleItemsTable::class,
        default     => OrderItemsTable::class,
    }),

License

MIT β€” Augusto CΓ©sar (gtcesar)

πŸ‡§πŸ‡· PortuguΓͺs

O que esse plugin faz?

Adiciona linhas expansΓ­veis Γ s tabelas do Filament 5. Ao clicar no botΓ£o de expansΓ£o, a linha abre uma tabela Filament completa diretamente abaixo dela β€” sem modal e sem recarregar a pΓ‘gina.

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚  # β”‚ Cliente         β”‚ Total    β”‚ Status    β”‚      [+]   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  1 β”‚ JoΓ£o Silva      β”‚ R$120,00 β”‚ Pago      β”‚      [+]   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚    ↳ Itens do Pedido #1                                  β”‚
β”‚    β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”   β”‚
β”‚    β”‚ Produto          β”‚ Qtd  β”‚ PreΓ§o Un.            β”‚   β”‚
β”‚    β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”Όβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€   β”‚
β”‚    β”‚ Camiseta Azul M  β”‚  2   β”‚ R$ 30,00             β”‚   β”‚
β”‚    β”‚ CalΓ§a Slim       β”‚  1   β”‚ R$ 60,00             β”‚   β”‚
β”‚    β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”΄β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜   β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚  2 β”‚ Maria Souza     β”‚ R$200,00 β”‚ Pendente  β”‚      [+]   β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

A expansΓ£o Γ© instantΓ’nea (sem chamada ao servidor para abrir/fechar). Os dados da sub-tabela sΓ£o carregados sob demanda pelo Livewire.

A sub-tabela Γ© uma tabela Filament completa: colunas, filtros, aΓ§Γ΅es, bulk actions, ordenaΓ§Γ£o, busca e paginaΓ§Γ£o funcionam normalmente.

Requisitos

VocΓͺ precisa ter um projeto Laravel com o Filament 5 jΓ‘ instalado e funcionando.

DependΓͺncia VersΓ£o mΓ­nima
PHP 8.3+
Laravel 11 ou 12
Filament 5.x
Livewire 4.x (vem com o Filament 5)

InstalaΓ§Γ£o

Execute os dois comandos abaixo no terminal, dentro da pasta do seu projeto:

composer require gtcesar/filament-expandable-table
php artisan filament:assets

O primeiro instala o pacote. O segundo publica os arquivos de CSS e JS que o plugin usa para a animaΓ§Γ£o e o estilo das linhas expansΓ­veis.

Nenhuma configuraΓ§Γ£o adicional. O Laravel registra o plugin automaticamente. NΓ£o Γ© preciso editar AppServiceProvider, PanelProvider nem nenhum outro arquivo de configuraΓ§Γ£o.

ConfiguraΓ§Γ£o passo a passo

Vamos usar o exemplo de uma tabela de Pedidos onde cada linha expande para mostrar seus Itens.

Passo 1 β€” Criar a classe que define a sub-tabela

Crie um arquivo PHP em qualquer lugar do seu projeto (sugerimos app/Filament/Tables/). Esse arquivo descreve a sub-tabela: quais colunas mostrar, quais filtros aplicar e como buscar os registros relacionados.

<?php

// app/Filament/Tables/OrderItemsTable.php

namespace App\Filament\Tables;

use App\Models\OrderItem;
use Filament\Tables\Actions\DeleteAction;
use Filament\Tables\Actions\EditAction;
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Filters\SelectFilter;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Tibras\ExpandableTable\Contracts\HasExpandedTable;

class OrderItemsTable implements HasExpandedTable
{
    public function table(Table $table, Model $record): Table
    {
        // $record Γ© a linha da tabela PAI (o Pedido).
        // Use $record->id para buscar apenas os itens daquele pedido.
        return $table
            ->query(
                OrderItem::query()->where('order_id', $record->id)
            )
            ->columns([
                TextColumn::make('product_name')
                    ->label('Produto')
                    ->searchable()
                    ->sortable(),
                TextColumn::make('quantity')
                    ->label('Qtd')
                    ->sortable(),
                TextColumn::make('unit_price')
                    ->label('PreΓ§o Un.')
                    ->money('BRL')
                    ->sortable(),
                TextColumn::make('status')
                    ->label('Status')
                    ->badge(),
            ])
            ->filters([
                SelectFilter::make('status')
                    ->label('Status')
                    ->options([
                        'pending'   => 'Pendente',
                        'shipped'   => 'Enviado',
                        'delivered' => 'Entregue',
                    ]),
            ])
            ->actions([
                EditAction::make(),
                DeleteAction::make(),
            ])
            ->paginated([5, 10, 25])
            ->defaultSort('product_name');
    }
}

O que Γ© implements HasExpandedTable? Γ‰ uma forma do PHP garantir que a sua classe tem o mΓ©todo table() que o plugin precisa chamar. Pense como um contrato: o plugin sabe que pode pedir a qualquer classe que implemente HasExpandedTable para montar uma tabela.

Passo 2 β€” Adicionar o botΓ£o de expansΓ£o na tabela pai

No seu ListRecords (o arquivo da pΓ‘gina de listagem do recurso), adicione o ExpandAction ao array de aΓ§Γ΅es da tabela:

<?php

// app/Filament/Resources/OrderResource/Pages/ListOrders.php

namespace App\Filament\Resources\OrderResource\Pages;

use App\Filament\Resources\OrderResource;
use App\Filament\Tables\OrderItemsTable;
use Filament\Resources\Pages\ListRecords;
use Tibras\ExpandableTable\Actions\ExpandAction;

class ListOrders extends ListRecords
{
    protected static string $resource = OrderResource::class;

    protected function getTableActions(): array
    {
        return [
            ExpandAction::make()
                ->detailComponent(OrderItemsTable::class),
            // Outras aΓ§Γ΅es (EditAction, DeleteAction, etc.) podem ficar aqui tambΓ©m.
        ];
    }
}

Isso adiciona um botΓ£o [+] em cada linha da tabela de pedidos. Ao clicar, ele abre ou fecha a linha instantaneamente via Alpine.js β€” sem chamada ao servidor.

Passo 3 β€” Exibir a sub-tabela na view

Este Γ© o passo que "fecha o circuito": vocΓͺ diz ao Filament onde renderizar a sub-tabela quando uma linha for expandida.

Como encontrar o arquivo de view correto:

Publique as views do Filament (se ainda nΓ£o fez isso):

php artisan filament:publish --views

O arquivo a editar estΓ‘ em:

resources/views/vendor/filament-tables/index.blade.php

Dentro desse arquivo, localize o <tr> que renderiza cada linha de dado (geralmente hΓ‘ um @foreach sobre os registros). Logo apΓ³s esse <tr>, adicione o bloco abaixo:

{{-- Linha de expansΓ£o β€” invisΓ­vel atΓ© o botΓ£o [+] ser clicado --}}
<tr x-show="$store.expandableTable.isExpanded('{{ $this->getId() }}.{{ $record->getKey() }}')">
    <td colspan="99" class="p-0">
        @livewire(
            'expandable-table::expanded-table-detail',
            [
                'recordClass'     => get_class($record),
                'recordKey'       => $record->getKey(),
                'detailComponent' => \App\Filament\Tables\OrderItemsTable::class,
            ],
            key('expand-' . $record->getKey())
        )
    </td>
</tr>

Por que colspan="99"? Para a cΓ©lula da sub-tabela ocupar toda a largura da tabela, independente de quantas colunas a tabela pai tiver.

Por que key('expand-' . $record->getKey())? O Livewire usa essa chave para manter o estado de cada sub-tabela isolado. Sem ela, as sub-tabelas de linhas diferentes interferem entre si.

OpΓ§Γ£o: expandir uma linha automaticamente

Para que certas linhas jΓ‘ abram expandidas quando a pΓ‘gina carrega (por exemplo, o pedido mais recente), use ->startExpanded():

ExpandAction::make()
    ->detailComponent(OrderItemsTable::class)
    ->startExpanded(fn (Order $record): bool => $record->is_latest),

Ou passe true para expandir todas as linhas por padrΓ£o:

->startExpanded()  // equivalente a ->startExpanded(true)

ReferΓͺncia da API

ExpandAction

MΓ©todo O que faz
->detailComponent(string|Closure) Informa qual classe PHP monta a sub-tabela. ObrigatΓ³rio.
->startExpanded(bool|Closure) Se true (ou se a Closure retornar true), a linha comeΓ§a expandida. PadrΓ£o: false.

HasExpandedTable (interface)

interface HasExpandedTable
{
    public function table(Table $table, Model $record): Table;
}
ParΓ’metro DescriΓ§Γ£o
$table InstΓ’ncia da tabela Filament β€” use os mΓ©todos fluentes normais: ->query(), ->columns(), ->filters(), ->actions(), ->bulkActions(), ->defaultSort(), etc.
$record O model da linha pai (ex.: o Pedido). Use para filtrar os registros da sub-tabela.

Como funciona por baixo dos panos

UsuΓ‘rio clica no botΓ£o [+]
        β”‚
        β–Ό
Alpine.js atualiza o store local (sem chamada ao servidor)
        β”‚
        β–Ό
<tr x-show="isExpanded(...)"> torna-se visΓ­vel via CSS
        β”‚
        β–Ό
Livewire monta o componente ExpandedTableDetail
        β”‚
        β–Ό
ExpandedTableDetail chama OrderItemsTable::table()
        β”‚
        β–Ό
Tabela Filament completa renderizada dentro da linha

Perguntas frequentes e problemas comuns

A sub-tabela nΓ£o aparece quando clico no botΓ£o

Verifique duas coisas:

  1. O key('expand-' . $record->getKey()) estΓ‘ presente na diretiva @livewire.
  2. O x-show estΓ‘ exatamente no elemento <tr> (nΓ£o dentro de outro elemento).

O visual da sub-tabela estΓ‘ sem estilo (sem CSS)

Execute php artisan filament:assets e verifique que o arquivo expandable-table.css foi publicado em public/vendor/filament/.

O botΓ£o existe mas nΓ£o reage ao clique

O JavaScript do plugin pode nΓ£o estar carregado. Execute php artisan filament:assets novamente e limpe o cache do navegador (Ctrl+Shift+R).

A pΓ‘gina fica lenta com muitas linhas

O Livewire instancia um componente para cada linha aberta. Mantenha a paginaΓ§Γ£o da tabela pai em 25 registros ou menos para evitar sobrecarga.

Posso usar sub-tabelas diferentes dependendo do registro?

Sim. Use uma Closure em ->detailComponent():

ExpandAction::make()
    ->detailComponent(fn (Order $record): string => match ($record->type) {
        'wholesale' => WholesaleItemsTable::class,
        default     => OrderItemsTable::class,
    }),

LicenΓ§a

MIT β€” Augusto CΓ©sar (gtcesar)