diff --git a/packages/tables/docs/05-actions.md b/packages/tables/docs/05-actions.md index 9d1c9d06590..6664ef280c7 100644 --- a/packages/tables/docs/05-actions.md +++ b/packages/tables/docs/05-actions.md @@ -250,6 +250,27 @@ public function table(Table $table): Table } ``` +### Displaying bulk actions below the table + +By default, the bulk actions are rendered above the table. Alternatively, you can move them below the table: + +```php +use Filament\Tables\Table; +use Filament\Tables\Enums\BulkActionsPosition; + +public function table(Table $table): Table +{ + return $table + ->bulkActions([ + // ... + ]) + ->bulkActionsPosition(BulkActionsPosition::BelowTable); +} +``` + +Or display bulk actions both above and below the table, with the `BulkActionsPosition::AboveAndBelowTable` +position option. + ## Header actions Both [row actions](#row-actions) and [bulk actions](#bulk-actions) can be rendered in the header of the table. You can put them in the `$table->headerActions()` method: diff --git a/packages/tables/resources/views/index.blade.php b/packages/tables/resources/views/index.blade.php index 70f0b5cc72d..78bec7083a4 100644 --- a/packages/tables/resources/views/index.blade.php +++ b/packages/tables/resources/views/index.blade.php @@ -5,6 +5,7 @@ use Filament\Tables\Columns\Column; use Filament\Tables\Columns\ColumnGroup; use Filament\Tables\Enums\ActionsPosition; + use Filament\Tables\Enums\BulkActionsPosition; use Filament\Tables\Enums\FiltersLayout; use Filament\Tables\Enums\RecordCheckboxPosition; use Illuminate\Support\Str; @@ -36,6 +37,9 @@ $getBulkActions(), fn (\Filament\Tables\Actions\BulkAction | \Filament\Tables\Actions\ActionGroup $action): bool => $action->isVisible(), ); + $bulkActionsPosition = $getBulkActionsPosition(); + $hasBulkActionsAboveTable = $bulkActionsPosition->isAboveTable(); + $hasBulkActionsBelowTable = $bulkActionsPosition->isBelowTable(); $groups = $getGroups(); $description = $getDescription(); $isGroupsOnly = $isGroupsOnly() && $group; @@ -193,7 +197,7 @@ class="fi-ta-header-toolbar flex items-center justify-between gap-x-4 px-4 py-3 {{ \Filament\Support\Facades\FilamentView::renderHook(\Filament\Tables\View\TablesRenderHook::TOOLBAR_REORDER_TRIGGER_AFTER, scopes: static::class) }} - @if ((! $isReordering) && count($bulkActions)) + @if ($hasBulkActionsAboveTable && (! $isReordering) && count($bulkActions)) + @if ($hasBulkActionsBelowTable && (! $isReordering) && count($bulkActions)) + + @endif + @if ((($records instanceof \Illuminate\Contracts\Pagination\Paginator) || ($records instanceof \Illuminate\Contracts\Pagination\CursorPaginator)) && ((! ($records instanceof \Illuminate\Contracts\Pagination\LengthAwarePaginator)) || $records->total())) true, + self::BelowTable => false, + }; + } + + public function isBelowTable(): bool + { + return match ($this) { + self::BelowTable, self::AboveAndBelowTable => true, + self::AboveTable => false, + }; + } +} diff --git a/packages/tables/src/Table/Concerns/HasBulkActions.php b/packages/tables/src/Table/Concerns/HasBulkActions.php index 84d8cf3eec8..e32cca39d83 100644 --- a/packages/tables/src/Table/Concerns/HasBulkActions.php +++ b/packages/tables/src/Table/Concerns/HasBulkActions.php @@ -6,6 +6,7 @@ use Filament\Tables\Actions\ActionGroup; use Filament\Tables\Actions\BulkAction; use Filament\Tables\Actions\BulkActionGroup; +use Filament\Tables\Enums\BulkActionsPosition; use Filament\Tables\Enums\RecordCheckboxPosition; use Illuminate\Database\Eloquent\Collection as EloquentCollection; use Illuminate\Database\Eloquent\Model; @@ -29,6 +30,8 @@ trait HasBulkActions protected bool | Closure | null $selectsCurrentPageOnly = false; + protected BulkActionsPosition | Closure | null $bulkActionsPosition = null; + protected RecordCheckboxPosition | Closure | null $recordCheckboxPosition = null; protected bool | Closure | null $isSelectable = null; @@ -184,6 +187,18 @@ public function checksIfRecordIsSelectable(): bool return $this->checkIfRecordIsSelectableUsing !== null; } + public function bulkActionsPosition(BulkActionsPosition | Closure | null $position = null): static + { + $this->bulkActionsPosition = $position; + + return $this; + } + + public function getBulkActionsPosition(): BulkActionsPosition + { + return $this->evaluate($this->bulkActionsPosition) ?? BulkActionsPosition::AboveTable; + } + public function recordCheckboxPosition(RecordCheckboxPosition | Closure | null $position = null): static { $this->recordCheckboxPosition = $position;