[增添]添加了datasource的setting数据库以及默认值
This commit is contained in:
176
vendor/filament/tables/docs/01-installation.md
vendored
Normal file
176
vendor/filament/tables/docs/01-installation.md
vendored
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: Installation
|
||||
---
|
||||
|
||||
**The Table Builder package is pre-installed with the [Panel Builder](/docs/panels).** This guide is for using the Table Builder in a custom TALL Stack application (Tailwind, Alpine, Livewire, Laravel).
|
||||
|
||||
## Requirements
|
||||
|
||||
Filament requires the following to run:
|
||||
|
||||
- PHP 8.1+
|
||||
- Laravel v10.0+
|
||||
- Livewire v3.0+
|
||||
|
||||
## Installation
|
||||
|
||||
Require the Table Builder package using Composer:
|
||||
|
||||
```bash
|
||||
composer require filament/tables:"^3.2" -W
|
||||
```
|
||||
|
||||
## New Laravel projects
|
||||
|
||||
To quickly get started with Filament in a new Laravel project, run the following commands to install [Livewire](https://livewire.laravel.com), [Alpine.js](https://alpinejs.dev), and [Tailwind CSS](https://tailwindcss.com):
|
||||
|
||||
> Since these commands will overwrite existing files in your application, only run this in a new Laravel project!
|
||||
|
||||
```bash
|
||||
php artisan filament:install --scaffold --tables
|
||||
|
||||
npm install
|
||||
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Existing Laravel projects
|
||||
|
||||
Run the following command to install the Table Builder assets:
|
||||
|
||||
```bash
|
||||
php artisan filament:install --tables
|
||||
```
|
||||
|
||||
### Installing Tailwind CSS
|
||||
|
||||
Run the following command to install Tailwind CSS with the Tailwind Forms and Typography plugins:
|
||||
|
||||
```bash
|
||||
npm install tailwindcss @tailwindcss/forms @tailwindcss/typography postcss postcss-nesting autoprefixer --save-dev
|
||||
```
|
||||
|
||||
Create a new `tailwind.config.js` file and add the Filament `preset` *(includes the Filament color scheme and the required Tailwind plugins)*:
|
||||
|
||||
```js
|
||||
import preset from './vendor/filament/support/tailwind.config.preset'
|
||||
|
||||
export default {
|
||||
presets: [preset],
|
||||
content: [
|
||||
'./app/Filament/**/*.php',
|
||||
'./resources/views/filament/**/*.blade.php',
|
||||
'./vendor/filament/**/*.blade.php',
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Configuring styles
|
||||
|
||||
Add Tailwind's CSS layers to your `resources/css/app.css`:
|
||||
|
||||
```css
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
```
|
||||
|
||||
Create a `postcss.config.js` file in the root of your project and register Tailwind CSS, PostCSS Nesting and Autoprefixer as plugins:
|
||||
|
||||
```js
|
||||
export default {
|
||||
plugins: {
|
||||
'tailwindcss/nesting': 'postcss-nesting',
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Automatically refreshing the browser
|
||||
You may also want to update your `vite.config.js` file to refresh the page automatically when Livewire components are updated:
|
||||
|
||||
```js
|
||||
import { defineConfig } from 'vite'
|
||||
import laravel, { refreshPaths } from 'laravel-vite-plugin'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
laravel({
|
||||
input: ['resources/css/app.css', 'resources/js/app.js'],
|
||||
refresh: [
|
||||
...refreshPaths,
|
||||
'app/Livewire/**',
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### Compiling assets
|
||||
|
||||
Compile your new CSS and Javascript assets using `npm run dev`.
|
||||
|
||||
### Configuring your layout
|
||||
|
||||
Create a new `resources/views/components/layouts/app.blade.php` layout file for Livewire components:
|
||||
|
||||
```blade
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="application-name" content="{{ config('app.name') }}">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{{ config('app.name') }}</title>
|
||||
|
||||
<style>
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@filamentStyles
|
||||
@vite('resources/css/app.css')
|
||||
</head>
|
||||
|
||||
<body class="antialiased">
|
||||
{{ $slot }}
|
||||
|
||||
@filamentScripts
|
||||
@vite('resources/js/app.js')
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Publishing configuration
|
||||
|
||||
You can publish the package configuration using the following command (optional):
|
||||
|
||||
```bash
|
||||
php artisan vendor:publish --tag=filament-config
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
> Upgrading from Filament v2? Please review the [upgrade guide](upgrade-guide).
|
||||
|
||||
Filament automatically upgrades to the latest non-breaking version when you run `composer update`. After any updates, all Laravel caches need to be cleared, and frontend assets need to be republished. You can do this all at once using the `filament:upgrade` command, which should have been added to your `composer.json` file when you ran `filament:install` the first time:
|
||||
|
||||
```json
|
||||
"post-autoload-dump": [
|
||||
// ...
|
||||
"@php artisan filament:upgrade"
|
||||
],
|
||||
```
|
||||
|
||||
Please note that `filament:upgrade` does not actually handle the update process, as Composer does that already. If you're upgrading manually without a `post-autoload-dump` hook, you can run the command yourself:
|
||||
|
||||
```bash
|
||||
composer update
|
||||
|
||||
php artisan filament:upgrade
|
||||
```
|
||||
177
vendor/filament/tables/docs/02-getting-started.md
vendored
Normal file
177
vendor/filament/tables/docs/02-getting-started.md
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
---
|
||||
title: Getting started
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Filament's Table Builder package allows you to [add an interactive datatable to any Livewire component](adding-a-table-to-a-livewire-component). It's also used within other Filament packages, such as the [Panel Builder](../panels) for displaying [resources](../panels/resources/getting-started) and [relation managers](../panels/resources/relation-managers), as well as for the [table widget](../panels/dashboard#table-widgets). Learning the features of the Table Builder will be incredibly time-saving when both building your own custom Livewire tables and using Filament's other packages.
|
||||
|
||||
This guide will walk you through the basics of building tables with Filament's table package. If you're planning to add a new table to your own Livewire component, you should [do that first](adding-a-table-to-a-livewire-component) and then come back. If you're adding a table to an [app resource](../panels/resources/getting-started), or another Filament package, you're ready to go!
|
||||
|
||||
## Defining table columns
|
||||
|
||||
The basis of any table is rows and columns. Filament uses Eloquent to get the data for rows in the table, and you are responsible for defining the columns that are used in that row.
|
||||
|
||||
Filament includes many column types prebuilt for you, and you can [view a full list here](columns/getting-started#available-columns). You can even [create your own custom column types](columns/custom) to display data in whatever way you need.
|
||||
|
||||
Columns are stored in an array, as objects within the `$table->columns()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('title'),
|
||||
TextColumn::make('slug'),
|
||||
IconColumn::make('is_featured')
|
||||
->boolean(),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/columns" alt="Table with columns" version="3.x" />
|
||||
|
||||
In this example, there are 3 columns in the table. The first two display [text](columns/text) - the title and slug of each row in the table. The third column displays an [icon](columns/icon), either a green check or a red cross depending on if the row is featured or not.
|
||||
|
||||
### Making columns sortable and searchable
|
||||
|
||||
You can easily modify columns by chaining methods onto them. For example, you can make a column [searchable](columns/getting-started#searching) using the `searchable()` method. Now, there will be a search field in the table, and you will be able to filter rows by the value of that column:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->searchable()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/searchable-columns" alt="Table with searchable column" version="3.x" />
|
||||
|
||||
You can make multiple columns searchable, and Filament will be able to search for matches within any of them, all at once.
|
||||
|
||||
You can also make a column [sortable](columns/getting-started#sorting) using the `sortable()` method. This will add a sort button to the column header, and clicking it will sort the table by that column:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->sortable()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/sortable-columns" alt="Table with sortable column" version="3.x" />
|
||||
|
||||
### Accessing related data from columns
|
||||
|
||||
You can also display data in a column that belongs to a relationship. For example, if you have a `Post` model that belongs to a `User` model (the author of the post), you can display the user's name in the table:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('author.name')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/relationship-columns" alt="Table with relationship column" version="3.x" />
|
||||
|
||||
In this case, Filament will search for an `author` relationship on the `Post` model, and then display the `name` attribute of that relationship. We call this "dot notation" - you can use it to display any attribute of any relationship, even nested distant relationships. Filament uses this dot notation to eager-load the results of that relationship for you.
|
||||
|
||||
## Defining table filters
|
||||
|
||||
As well as making columns `searchable()`, you can allow the users to filter rows in the table in other ways. We call these components "filters", and they are defined in the `$table->filters()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->filters([
|
||||
Filter::make('is_featured')
|
||||
->query(fn (Builder $query) => $query->where('is_featured', true)),
|
||||
SelectFilter::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
]),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/filters" alt="Table with filters" version="3.x" />
|
||||
|
||||
In this example, we have defined 2 table filters. On the table, there is now a "filter" icon button in the top corner. Clicking it will open a dropdown with the 2 filters we have defined.
|
||||
|
||||
The first filter is rendered as a checkbox. When it's checked, only featured rows in the table will be displayed. When it's unchecked, all rows will be displayed.
|
||||
|
||||
The second filter is rendered as a select dropdown. When a user selects an option, only rows with that status will be displayed. When no option is selected, all rows will be displayed.
|
||||
|
||||
It's possible to define as many filters as you need, and use any component from the [Form Builder package](../forms) to create a UI. For example, you could create [a custom date range filter](../filters/custom).
|
||||
|
||||
## Defining table actions
|
||||
|
||||
Filament's tables can use [Actions](../actions/overview). They are buttons that can be added to the [end of any table row](actions#row-actions), or even in the [header](actions#header-actions) of a table. For instance, you may want an action to "create" a new record in the header, and then "edit" and "delete" actions on each row. [Bulk actions](actions#bulk-actions) can be used to execute code when records in the table are selected.
|
||||
|
||||
```php
|
||||
use App\Models\Post;
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Actions\BulkActionGroup;
|
||||
use Filament\Tables\Actions\DeleteBulkAction;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->actions([
|
||||
Action::make('feature')
|
||||
->action(function (Post $record) {
|
||||
$record->is_featured = true;
|
||||
$record->save();
|
||||
})
|
||||
->hidden(fn (Post $record): bool => $record->is_featured),
|
||||
Action::make('unfeature')
|
||||
->action(function (Post $record) {
|
||||
$record->is_featured = false;
|
||||
$record->save();
|
||||
})
|
||||
->visible(fn (Post $record): bool => $record->is_featured),
|
||||
])
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
DeleteBulkAction::make(),
|
||||
]),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/actions" alt="Table with actions" version="3.x" />
|
||||
|
||||
In this example, we define 2 actions for table rows. The first action is a "feature" action. When clicked, it will set the `is_featured` attribute on the record to `true` - which is written within the `action()` method. Using the `hidden()` method, the action will be hidden if the record is already featured. The second action is an "unfeature" action. When clicked, it will set the `is_featured` attribute on the record to `false`. Using the `visible()` method, the action will be hidden if the record is not featured.
|
||||
|
||||
We also define a bulk action. When bulk actions are defined, each row in the table will have a checkbox. This bulk action is [built-in to Filament](../actions/prebuilt-actions/delete#bulk-delete), and it will delete all selected records. However, you can [write your own custom bulk actions](actions#bulk-actions) easily too.
|
||||
|
||||
<AutoScreenshot name="tables/getting-started/actions-modal" alt="Table with action modal open" version="3.x" />
|
||||
|
||||
Actions can also open modals to request confirmation from the user, as well as render forms inside to collect extra data. It's a good idea to read the [Actions documentation](../actions/overview) to learn more about their extensive capabilities throughout Filament.
|
||||
|
||||
## Next steps with the Table Builder package
|
||||
|
||||
Now you've finished reading this guide, where to next? Here are some suggestions:
|
||||
|
||||
- [Explore the available columns to display data in your table.](columns/getting-started#available-columns)
|
||||
- [Deep dive into table actions and start using modals.](actions)
|
||||
- [Discover how to build complex, responsive table layouts without touching CSS.](layout)
|
||||
- [Add summaries to your tables, which give an overview of the data inside them.](summaries)
|
||||
- [Find out about all advanced techniques that you can customize tables to your needs.](advanced)
|
||||
- [Write automated tests for your tables using our suite of helper methods.](testing)
|
||||
641
vendor/filament/tables/docs/03-columns/01-getting-started.md
vendored
Normal file
641
vendor/filament/tables/docs/03-columns/01-getting-started.md
vendored
Normal file
@@ -0,0 +1,641 @@
|
||||
---
|
||||
title: Getting started
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
<LaracastsBanner
|
||||
title="Table Columns"
|
||||
description="Watch the Rapid Laravel Development with Filament series on Laracasts - it will teach you the basics of adding columns to Filament resource tables."
|
||||
url="https://laracasts.com/series/rapid-laravel-development-with-filament/episodes/9"
|
||||
series="rapid-laravel-development"
|
||||
/>
|
||||
|
||||
Column classes can be found in the `Filament\Tables\Columns` namespace. You can put them inside the `$table->columns()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Columns may be created using the static `make()` method, passing its unique name. The name of the column should correspond to a column or accessor on your model. You may use "dot notation" to access columns within relationships.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
|
||||
TextColumn::make('author.name')
|
||||
```
|
||||
|
||||
## Available columns
|
||||
|
||||
Filament ships with two main types of columns - static and editable.
|
||||
|
||||
Static columns display data to the user:
|
||||
|
||||
- [Text column](text)
|
||||
- [Icon column](icon)
|
||||
- [Image column](image)
|
||||
- [Color column](color)
|
||||
|
||||
Editable columns allow the user to update data in the database without leaving the table:
|
||||
|
||||
- [Select column](select)
|
||||
- [Toggle column](toggle)
|
||||
- [Text input column](text-input)
|
||||
- [Checkbox column](checkbox)
|
||||
|
||||
You may also [create your own custom columns](custom) to display data however you wish.
|
||||
|
||||
## Setting a label
|
||||
|
||||
By default, the label of the column, which is displayed in the header of the table, is generated from the name of the column. You may customize this using the `label()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->label('Post title')
|
||||
```
|
||||
|
||||
Optionally, you can have the label automatically translated [using Laravel's localization features](https://laravel.com/docs/localization) with the `translateLabel()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->translateLabel() // Equivalent to `label(__('Title'))`
|
||||
```
|
||||
|
||||
## Sorting
|
||||
|
||||
Columns may be sortable, by clicking on the column label. To make a column sortable, you must use the `sortable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->sortable()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/sortable" alt="Table with sortable column" version="3.x" />
|
||||
|
||||
If you're using an accessor column, you may pass `sortable()` an array of database columns to sort by:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('full_name')
|
||||
->sortable(['first_name', 'last_name'])
|
||||
```
|
||||
|
||||
You may customize how the sorting is applied to the Eloquent query using a callback:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
TextColumn::make('full_name')
|
||||
->sortable(query: function (Builder $query, string $direction): Builder {
|
||||
return $query
|
||||
->orderBy('last_name', $direction)
|
||||
->orderBy('first_name', $direction);
|
||||
})
|
||||
```
|
||||
|
||||
## Sorting by default
|
||||
|
||||
You may choose to sort a table by default if no other sort is applied. You can use the `defaultSort()` method for this:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->defaultSort('stock', 'desc');
|
||||
}
|
||||
```
|
||||
|
||||
### Persist sort in session
|
||||
|
||||
To persist the sorting in the user's session, use the `persistSortInSession()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->persistSortInSession();
|
||||
}
|
||||
```
|
||||
|
||||
## Searching
|
||||
|
||||
Columns may be searchable by using the text input field in the top right of the table. To make a column searchable, you must use the `searchable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->searchable()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/searchable" alt="Table with searchable column" version="3.x" />
|
||||
|
||||
If you're using an accessor column, you may pass `searchable()` an array of database columns to search within:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('full_name')
|
||||
->searchable(['first_name', 'last_name'])
|
||||
```
|
||||
|
||||
You may customize how the search is applied to the Eloquent query using a callback:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
TextColumn::make('full_name')
|
||||
->searchable(query: function (Builder $query, string $search): Builder {
|
||||
return $query
|
||||
->where('first_name', 'like', "%{$search}%")
|
||||
->orWhere('last_name', 'like', "%{$search}%");
|
||||
})
|
||||
```
|
||||
|
||||
#### Customizing the table search field placeholder
|
||||
|
||||
You may customize the placeholder in the search field using the `searchPlaceholder()` method on the `$table`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->searchPlaceholder('Search (ID, Name)');
|
||||
}
|
||||
```
|
||||
|
||||
### Searching individually
|
||||
|
||||
You can choose to enable a per-column search input field using the `isIndividual` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->searchable(isIndividual: true)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/individually-searchable" alt="Table with individually searchable column" version="3.x" />
|
||||
|
||||
If you use the `isIndividual` parameter, you may still search that column using the main "global" search input field for the entire table.
|
||||
|
||||
To disable that functionality while still preserving the individual search functionality, you need the `isGlobal` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->searchable(isIndividual: true, isGlobal: false)
|
||||
```
|
||||
|
||||
You may optionally persist the searches in the query string:
|
||||
|
||||
```php
|
||||
use Livewire\Attributes\Url;
|
||||
|
||||
/**
|
||||
* @var array<string, string | array<string, string | null> | null>
|
||||
*/
|
||||
#[Url]
|
||||
public array $tableColumnSearches = [];
|
||||
```
|
||||
|
||||
### Customizing the table search debounce
|
||||
|
||||
You may customize the debounce time in all table search fields using the `searchDebounce()` method on the `$table`. By default it is set to `500ms`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->searchDebounce('750ms');
|
||||
}
|
||||
```
|
||||
|
||||
### Searching when the input is blurred
|
||||
|
||||
Instead of automatically reloading the table contents while the user is typing their search, which is affected by the [debounce](#customizing-the-table-search-debounce) of the search field, you may change the behavior so that the table is only searched when the user blurs the input (tabs or clicks out of it), using the `searchOnBlur()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public static function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->searchOnBlur();
|
||||
}
|
||||
```
|
||||
|
||||
### Persist search in session
|
||||
|
||||
To persist the table or individual column search in the user's session, use the `persistSearchInSession()` or `persistColumnSearchInSession()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->persistSearchInSession()
|
||||
->persistColumnSearchesInSession();
|
||||
}
|
||||
```
|
||||
|
||||
## Column actions and URLs
|
||||
|
||||
When a cell is clicked, you may run an "action", or open a URL.
|
||||
|
||||
### Running actions
|
||||
|
||||
To run an action, you may use the `action()` method, passing a callback or the name of a Livewire method to run. Each method accepts a `$record` parameter which you may use to customize the behavior of the action:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->action(function (Post $record): void {
|
||||
$this->dispatch('open-post-edit-modal', post: $record->getKey());
|
||||
})
|
||||
```
|
||||
|
||||
#### Action modals
|
||||
|
||||
You may open [action modals](../actions#modals) by passing in an `Action` object to the `action()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->action(
|
||||
Action::make('select')
|
||||
->requiresConfirmation()
|
||||
->action(function (Post $record): void {
|
||||
$this->dispatch('select-post', post: $record->getKey());
|
||||
}),
|
||||
)
|
||||
```
|
||||
|
||||
Action objects passed into the `action()` method must have a unique name to distinguish it from other actions within the table.
|
||||
|
||||
### Opening URLs
|
||||
|
||||
To open a URL, you may use the `url()` method, passing a callback or static URL to open. Callbacks accept a `$record` parameter which you may use to customize the URL:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))
|
||||
```
|
||||
|
||||
You may also choose to open the URL in a new tab:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))
|
||||
->openUrlInNewTab()
|
||||
```
|
||||
|
||||
## Setting a default value
|
||||
|
||||
To set a default value for columns with an empty state, you may use the `default()` method. This method will treat the default state as if it were real, so columns like [image](image) or [color](color) will display the default image or color.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->default('No description.')
|
||||
```
|
||||
|
||||
## Adding placeholder text if a column is empty
|
||||
|
||||
Sometimes you may want to display placeholder text for columns with an empty state, which is styled as a lighter gray text. This differs from the [default value](#setting-a-default-value), as the placeholder is always text and not treated as if it were real state.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->placeholder('No description.')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/placeholder" alt="Column with a placeholder for empty state" version="3.x" />
|
||||
|
||||
## Hiding columns
|
||||
|
||||
To hide a column conditionally, you may use the `hidden()` and `visible()` methods, whichever you prefer:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('role')
|
||||
->hidden(! auth()->user()->isAdmin())
|
||||
// or
|
||||
TextColumn::make('role')
|
||||
->visible(auth()->user()->isAdmin())
|
||||
```
|
||||
|
||||
### Toggling column visibility
|
||||
|
||||
Users may hide or show columns themselves in the table. To make a column toggleable, use the `toggleable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->toggleable()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/toggleable" alt="Table with toggleable column" version="3.x" />
|
||||
|
||||
#### Making toggleable columns hidden by default
|
||||
|
||||
By default, toggleable columns are visible. To make them hidden instead:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('id')
|
||||
->toggleable(isToggledHiddenByDefault: true)
|
||||
```
|
||||
|
||||
#### Customizing the toggle columns dropdown trigger action
|
||||
|
||||
To customize the toggle dropdown trigger button, you may use the `toggleColumnsTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](../actions/trigger-button) can be used:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->toggleColumnsTriggerAction(
|
||||
fn (Action $action) => $action
|
||||
->button()
|
||||
->label('Toggle columns'),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Calculated state
|
||||
|
||||
Sometimes you need to calculate the state of a column, instead of directly reading it from a database column.
|
||||
|
||||
By passing a callback function to the `state()` method, you can customize the returned state for that column based on the `$record`:
|
||||
|
||||
```php
|
||||
use App\Models\Order;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('amount_including_vat')
|
||||
->state(function (Order $record): float {
|
||||
return $record->amount * (1 + $record->vat_rate);
|
||||
})
|
||||
```
|
||||
|
||||
## Tooltips
|
||||
|
||||
You may specify a tooltip to display when you hover over a cell:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->tooltip('Title')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/tooltips" alt="Table with column triggering a tooltip" version="3.x" />
|
||||
|
||||
This method also accepts a closure that can access the current table record:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
TextColumn::make('title')
|
||||
->tooltip(fn (Model $record): string => "By {$record->author->name}")
|
||||
```
|
||||
|
||||
## Horizontally aligning column content
|
||||
|
||||
Table columns are aligned to the start (left in LTR interfaces or right in RTL interfaces) by default. You may change the alignment using the `alignment()` method, and passing it `Alignment::Start`, `Alignment::Center`, `Alignment::End` or `Alignment::Justify` options:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->alignment(Alignment::End)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/alignment" alt="Table with column aligned to the end" version="3.x" />
|
||||
|
||||
Alternatively, you may use shorthand methods like `alignEnd()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->alignEnd()
|
||||
```
|
||||
|
||||
## Vertically aligning column content
|
||||
|
||||
Table column content is vertically centered by default. You may change the vertical alignment using the `verticalAlignment()` method, and passing it `VerticalAlignment::Start`, `VerticalAlignment::Center` or `VerticalAlignment::End` options:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->verticalAlignment(VerticalAlignment::Start)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/vertical-alignment" alt="Table with column vertically aligned to the start" version="3.x" />
|
||||
|
||||
Alternatively, you may use shorthand methods like `verticallyAlignStart()`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->verticallyAlignStart()
|
||||
```
|
||||
|
||||
## Allowing column headers to wrap
|
||||
|
||||
By default, column headers will not wrap onto multiple lines, if they need more space. You may allow them to wrap using the `wrapHeader()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->wrapHeader()
|
||||
```
|
||||
|
||||
## Controlling the width of columns
|
||||
|
||||
By default, columns will take up as much space as they need. You may allow some columns to consume more space than others by using the `grow()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->grow()
|
||||
```
|
||||
|
||||
Alternatively, you can define a width for the column, which is passed to the header cell using the `style` attribute, so you can use any valid CSS value:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('is_paid')
|
||||
->label('Paid')
|
||||
->boolean()
|
||||
->width('1%')
|
||||
```
|
||||
|
||||
## Grouping columns
|
||||
|
||||
You group multiple columns together underneath a single heading using a `ColumnGroup` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ColumnGroup;
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('title'),
|
||||
TextColumn::make('slug'),
|
||||
ColumnGroup::make('Visibility', [
|
||||
TextColumn::make('status'),
|
||||
IconColumn::make('is_featured'),
|
||||
]),
|
||||
TextColumn::make('author.name'),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
The first argument is the label of the group, and the second is an array of column objects that belong to that group.
|
||||
|
||||
<AutoScreenshot name="tables/columns/grouping" alt="Table with grouped columns" version="3.x" />
|
||||
|
||||
You can also control the group header [alignment](#horizontally-aligning-column-content) and [wrapping](#allowing-column-headers-to-wrap) on the `ColumnGroup` object. To improve the multi-line fluency of the API, you can chain the `columns()` onto the object instead of passing it as the second argument:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Tables\Columns\ColumnGroup;
|
||||
|
||||
ColumnGroup::make('Website visibility')
|
||||
->columns([
|
||||
// ...
|
||||
])
|
||||
->alignment(Alignment::Center)
|
||||
->wrapHeader()
|
||||
```
|
||||
|
||||
## Custom attributes
|
||||
|
||||
The HTML of columns can be customized, by passing an array of `extraAttributes()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('slug')
|
||||
->extraAttributes(['class' => 'bg-gray-200'])
|
||||
```
|
||||
|
||||
These get merged onto the outer `<div>` element of each cell in that column.
|
||||
|
||||
## Global settings
|
||||
|
||||
If you wish to change the default behavior of all columns globally, then you can call the static `configureUsing()` method inside a service provider's `boot()` method, to which you pass a Closure to modify the columns using. For example, if you wish to make all columns [`searchable()`](#searching) and [`toggleable()`](#toggling-column-visibility), you can do it like so:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Column;
|
||||
|
||||
Column::configureUsing(function (Column $column): void {
|
||||
$column
|
||||
->toggleable()
|
||||
->searchable();
|
||||
});
|
||||
```
|
||||
|
||||
Additionally, you can call this code on specific column types as well:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::configureUsing(function (TextColumn $column): void {
|
||||
$column
|
||||
->toggleable()
|
||||
->searchable();
|
||||
});
|
||||
```
|
||||
|
||||
Of course, you are still able to overwrite this on each column individually:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('name')
|
||||
->toggleable(false)
|
||||
```
|
||||
526
vendor/filament/tables/docs/03-columns/02-text.md
vendored
Normal file
526
vendor/filament/tables/docs/03-columns/02-text.md
vendored
Normal file
@@ -0,0 +1,526 @@
|
||||
---
|
||||
title: Text column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Text columns display simple text from your database:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/simple" alt="Text column" version="3.x" />
|
||||
|
||||
## Displaying as a "badge"
|
||||
|
||||
By default, the text is quite plain and has no background color. You can make it appear as a "badge" instead using the `badge()` method. A great use case for this is with statuses, where may want to display a badge with a [color](#customizing-the-color) that matches the status:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('status')
|
||||
->badge()
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'draft' => 'gray',
|
||||
'reviewing' => 'warning',
|
||||
'published' => 'success',
|
||||
'rejected' => 'danger',
|
||||
})
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/badge" alt="Text column as badge" version="3.x" />
|
||||
|
||||
You may add other things to the badge, like an [icon](#adding-an-icon).
|
||||
|
||||
## Displaying a description
|
||||
|
||||
Descriptions may be used to easily render additional text above or below the column contents.
|
||||
|
||||
You can display a description below the contents of a text column using the `description()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->description(fn (Post $record): string => $record->description)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/description" alt="Text column with description" version="3.x" />
|
||||
|
||||
By default, the description is displayed below the main text, but you can move it above using the second parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->description(fn (Post $record): string => $record->description, position: 'above')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/description-above" alt="Text column with description above the content" version="3.x" />
|
||||
|
||||
## Date formatting
|
||||
|
||||
You may use the `date()` and `dateTime()` methods to format the column's state using [PHP date formatting tokens](https://www.php.net/manual/en/datetime.format.php):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
```
|
||||
|
||||
You may use the `since()` method to format the column's state using [Carbon's `diffForHumans()`](https://carbon.nesbot.com/docs/#api-humandiff):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('created_at')
|
||||
->since()
|
||||
```
|
||||
|
||||
## Number formatting
|
||||
|
||||
The `numeric()` method allows you to format an entry as a number:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('stock')
|
||||
->numeric()
|
||||
```
|
||||
|
||||
If you would like to customize the number of decimal places used to format the number with, you can use the `decimalPlaces` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('stock')
|
||||
->numeric(decimalPlaces: 0)
|
||||
```
|
||||
|
||||
By default, your app's locale will be used to format the number suitably. If you would like to customize the locale used, you can pass it to the `locale` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('stock')
|
||||
->numeric(locale: 'nl')
|
||||
```
|
||||
|
||||
Alternatively, you can set the default locale used across your app using the `Number::useLocale()` method in the `boot()` method of a service provider:
|
||||
|
||||
```php
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
Number::useLocale('nl');
|
||||
```
|
||||
|
||||
## Currency formatting
|
||||
|
||||
The `money()` method allows you to easily format monetary values, in any currency:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->money('EUR')
|
||||
```
|
||||
|
||||
There is also a `divideBy` argument for `money()` that allows you to divide the original value by a number before formatting it. This could be useful if your database stores the price in cents, for example:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->money('EUR', divideBy: 100)
|
||||
```
|
||||
|
||||
By default, your app's locale will be used to format the money suitably. If you would like to customize the locale used, you can pass it to the `locale` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->money('EUR', locale: 'nl')
|
||||
```
|
||||
|
||||
Alternatively, you can set the default locale used across your app using the `Number::useLocale()` method in the `boot()` method of a service provider:
|
||||
|
||||
```php
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
Number::useLocale('nl');
|
||||
```
|
||||
|
||||
## Limiting text length
|
||||
|
||||
You may `limit()` the length of the cell's value:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->limit(50)
|
||||
```
|
||||
|
||||
You may also reuse the value that is being passed to `limit()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->limit(50)
|
||||
->tooltip(function (TextColumn $column): ?string {
|
||||
$state = $column->getState();
|
||||
|
||||
if (strlen($state) <= $column->getCharacterLimit()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only render the tooltip if the column content exceeds the length limit.
|
||||
return $state;
|
||||
})
|
||||
```
|
||||
|
||||
## Limiting word count
|
||||
|
||||
You may limit the number of `words()` displayed in the cell:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->words(10)
|
||||
```
|
||||
|
||||
## Limiting text to a specific number of lines
|
||||
|
||||
You may want to limit text to a specific number of lines instead of limiting it to a fixed length. Clamping text to a number of lines is useful in responsive interfaces where you want to ensure a consistent experience across all screen sizes. This can be achieved using the `lineClamp()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->lineClamp(2)
|
||||
```
|
||||
|
||||
## Adding a prefix or suffix
|
||||
|
||||
You may add a prefix or suffix to the cell's value:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('domain')
|
||||
->prefix('https://')
|
||||
->suffix('.com')
|
||||
```
|
||||
|
||||
## Wrapping content
|
||||
|
||||
If you'd like your column's content to wrap if it's too long, you may use the `wrap()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->wrap()
|
||||
```
|
||||
|
||||
## Listing multiple values
|
||||
|
||||
By default, if there are multiple values inside your text column, they will be comma-separated. You may use the `listWithLineBreaks()` method to display them on new lines instead:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
```
|
||||
|
||||
### Adding bullet points to the list
|
||||
|
||||
You may add a bullet point to each list item using the `bulleted()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
->bulleted()
|
||||
```
|
||||
|
||||
### Limiting the number of values in the list
|
||||
|
||||
You can limit the number of values in the list using the `limitList()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
->limitList(3)
|
||||
```
|
||||
|
||||
#### Expanding the limited list
|
||||
|
||||
You can allow the limited items to be expanded and collapsed, using the `expandableLimitedList()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
->limitList(3)
|
||||
->expandableLimitedList()
|
||||
```
|
||||
|
||||
Please note that this is only a feature for `listWithLineBreaks()` or `bulleted()`, where each item is on its own line.
|
||||
|
||||
### Using a list separator
|
||||
|
||||
If you want to "explode" a text string from your model into multiple list items, you can do so with the `separator()` method. This is useful for displaying comma-separated tags [as badges](#displaying-as-a-badge), for example:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('tags')
|
||||
->badge()
|
||||
->separator(',')
|
||||
```
|
||||
|
||||
## Rendering HTML
|
||||
|
||||
If your column value is HTML, you may render it using `html()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->html()
|
||||
```
|
||||
|
||||
If you use this method, then the HTML will be sanitized to remove any potentially unsafe content before it is rendered. If you'd like to opt out of this behavior, you can wrap the HTML in an `HtmlString` object by formatting it:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
TextColumn::make('description')
|
||||
->formatStateUsing(fn (string $state): HtmlString => new HtmlString($state))
|
||||
```
|
||||
|
||||
Or, you can return a `view()` object from the `formatStateUsing()` method, which will also not be sanitized:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
TextColumn::make('description')
|
||||
->formatStateUsing(fn (string $state): View => view(
|
||||
'filament.tables.columns.description-entry-content',
|
||||
['state' => $state],
|
||||
))
|
||||
```
|
||||
|
||||
### Rendering Markdown as HTML
|
||||
|
||||
If your column contains Markdown, you may render it using `markdown()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('description')
|
||||
->markdown()
|
||||
```
|
||||
|
||||
## Custom formatting
|
||||
|
||||
You may instead pass a custom formatting callback to `formatStateUsing()`, which accepts the `$state` of the cell, and optionally its `$record`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('status')
|
||||
->formatStateUsing(fn (string $state): string => __("statuses.{$state}"))
|
||||
```
|
||||
|
||||
## Customizing the color
|
||||
|
||||
You may set a color for the text, either `danger`, `gray`, `info`, `primary`, `success` or `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('status')
|
||||
->color('primary')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/color" alt="Text column in the primary color" version="3.x" />
|
||||
|
||||
## Adding an icon
|
||||
|
||||
Text columns may also have an icon:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/icon" alt="Text column with icon" version="3.x" />
|
||||
|
||||
You may set the position of an icon using `iconPosition()`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
->iconPosition(IconPosition::After) // `IconPosition::Before` or `IconPosition::After`
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/icon-after" alt="Text column with icon after" version="3.x" />
|
||||
|
||||
The icon color defaults to the text color, but you may customize the icon color separately using `iconColor()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
->iconColor('primary')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/icon-color" alt="Text column with icon in the primary color" version="3.x" />
|
||||
|
||||
## Customizing the text size
|
||||
|
||||
Text columns have small font size by default, but you may change this to `TextColumnSize::ExtraSmall`, `TextColumnSize::Medium`, or `TextColumnSize::Large`.
|
||||
|
||||
For instance, you may make the text larger using `size(TextColumnSize::Large)`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->size(TextColumn\TextColumnSize::Large)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/large" alt="Text column in a large font size" version="3.x" />
|
||||
|
||||
## Customizing the font weight
|
||||
|
||||
Text columns have regular font weight by default, but you may change this to any of the following options: `FontWeight::Thin`, `FontWeight::ExtraLight`, `FontWeight::Light`, `FontWeight::Medium`, `FontWeight::SemiBold`, `FontWeight::Bold`, `FontWeight::ExtraBold` or `FontWeight::Black`.
|
||||
|
||||
For instance, you may make the font bold using `weight(FontWeight::Bold)`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('title')
|
||||
->weight(FontWeight::Bold)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/bold" alt="Text column in a bold font" version="3.x" />
|
||||
|
||||
## Customizing the font family
|
||||
|
||||
You can change the text font family to any of the following options: `FontFamily::Sans`, `FontFamily::Serif` or `FontFamily::Mono`.
|
||||
|
||||
For instance, you may make the font mono using `fontFamily(FontFamily::Mono)`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontFamily;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->fontFamily(FontFamily::Mono)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/mono" alt="Text column in a monospaced font" version="3.x" />
|
||||
|
||||
## Allowing the text to be copied to the clipboard
|
||||
|
||||
You may make the text copyable, such that clicking on the cell copies the text to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('email')
|
||||
->copyable()
|
||||
->copyMessage('Email address copied')
|
||||
->copyMessageDuration(1500)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text/copyable" alt="Text column with a button to copy it" version="3.x" />
|
||||
|
||||
### Customizing the text that is copied to the clipboard
|
||||
|
||||
You can customize the text that gets copied to the clipboard using the `copyableState()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('url')
|
||||
->copyable()
|
||||
->copyableState(fn (string $state): string => "URL: {$state}")
|
||||
```
|
||||
|
||||
In this function, you can access the whole table row with `$record`:
|
||||
|
||||
```php
|
||||
use App\Models\Post;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('url')
|
||||
->copyable()
|
||||
->copyableState(fn (Post $record): string => "URL: {$record->url}")
|
||||
```
|
||||
|
||||
## Displaying the row index
|
||||
|
||||
You may want a column to contain the number of the current row in the table:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Contracts\HasTable;
|
||||
|
||||
TextColumn::make('index')->state(
|
||||
static function (HasTable $livewire, stdClass $rowLoop): string {
|
||||
return (string) (
|
||||
$rowLoop->iteration +
|
||||
($livewire->getTableRecordsPerPage() * (
|
||||
$livewire->getTablePage() - 1
|
||||
))
|
||||
);
|
||||
}
|
||||
),
|
||||
```
|
||||
|
||||
As `$rowLoop` is [Laravel Blade's `$loop` object](https://laravel.com/docs/blade#the-loop-variable), you can reference all other `$loop` properties.
|
||||
|
||||
As a shortcut, you may use the `rowIndex()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('index')
|
||||
->rowIndex()
|
||||
```
|
||||
|
||||
To start counting from 0 instead of 1, use `isFromZero: true`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('index')
|
||||
->rowIndex(isFromZero: true)
|
||||
```
|
||||
115
vendor/filament/tables/docs/03-columns/03-icon.md
vendored
Normal file
115
vendor/filament/tables/docs/03-columns/03-icon.md
vendored
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
title: Icon column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Icon columns render an [icon](https://blade-ui-kit.com/blade-icons?set=1#search) representing their contents:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('status')
|
||||
->icon(fn (string $state): string => match ($state) {
|
||||
'draft' => 'heroicon-o-pencil',
|
||||
'reviewing' => 'heroicon-o-clock',
|
||||
'published' => 'heroicon-o-check-circle',
|
||||
})
|
||||
```
|
||||
|
||||
In the function, `$state` is the value of the column, and `$record` can be used to access the underlying Eloquent record.
|
||||
|
||||
<AutoScreenshot name="tables/columns/icon/simple" alt="Icon column" version="3.x" />
|
||||
|
||||
## Customizing the color
|
||||
|
||||
Icon columns may also have a set of icon colors, using the same syntax. They may be either `danger`, `gray`, `info`, `primary`, `success` or `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('status')
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'draft' => 'info',
|
||||
'reviewing' => 'warning',
|
||||
'published' => 'success',
|
||||
default => 'gray',
|
||||
})
|
||||
```
|
||||
|
||||
In the function, `$state` is the value of the column, and `$record` can be used to access the underlying Eloquent record.
|
||||
|
||||
<AutoScreenshot name="tables/columns/icon/color" alt="Icon column with color" version="3.x" />
|
||||
|
||||
## Customizing the size
|
||||
|
||||
The default icon size is `IconColumnSize::Large`, but you may customize the size to be either `IconColumnSize::ExtraSmall`, `IconColumnSize::Small`, `IconColumnSize::Medium`, `IconColumnSize::ExtraLarge` or `IconColumnSize::TwoExtraLarge`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('status')
|
||||
->size(IconColumn\IconColumnSize::Medium)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/icon/medium" alt="Medium-sized icon column" version="3.x" />
|
||||
|
||||
## Handling booleans
|
||||
|
||||
Icon columns can display a check or cross icon based on the contents of the database column, either true or false, using the `boolean()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('is_featured')
|
||||
->boolean()
|
||||
```
|
||||
|
||||
> If this column in the model class is already cast as a `bool` or `boolean`, Filament is able to detect this, and you do not need to use `boolean()` manually.
|
||||
|
||||
<AutoScreenshot name="tables/columns/icon/boolean" alt="Icon column to display a boolean" version="3.x" />
|
||||
|
||||
### Customizing the boolean icons
|
||||
|
||||
You may customize the icon representing each state. Icons are the name of a Blade component present. By default, [Heroicons](https://heroicons.com) are installed:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('is_featured')
|
||||
->boolean()
|
||||
->trueIcon('heroicon-o-check-badge')
|
||||
->falseIcon('heroicon-o-x-mark')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/icon/boolean-icon" alt="Icon column to display a boolean with custom icons" version="3.x" />
|
||||
|
||||
### Customizing the boolean colors
|
||||
|
||||
You may customize the icon color representing each state. These may be either `danger`, `gray`, `info`, `primary`, `success` or `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('is_featured')
|
||||
->boolean()
|
||||
->trueColor('info')
|
||||
->falseColor('warning')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/icon/boolean-color" alt="Icon column to display a boolean with custom colors" version="3.x" />
|
||||
|
||||
## Wrapping multiple icons
|
||||
|
||||
When displaying multiple icons, they can be set to wrap if they can't fit on one line, using `wrap()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
|
||||
IconColumn::make('icon')
|
||||
->wrap()
|
||||
```
|
||||
|
||||
Note: the "width" for wrapping is affected by the column label, so you may need to use a shorter or hidden label to wrap more tightly.
|
||||
|
||||
239
vendor/filament/tables/docs/03-columns/04-image.md
vendored
Normal file
239
vendor/filament/tables/docs/03-columns/04-image.md
vendored
Normal file
@@ -0,0 +1,239 @@
|
||||
---
|
||||
title: Image column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Images can be easily displayed within your table:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('avatar')
|
||||
```
|
||||
|
||||
The column in the database must contain the path to the image, relative to the root directory of its storage disk.
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/simple" alt="Image column" version="3.x" />
|
||||
|
||||
## Managing the image disk
|
||||
|
||||
By default, the `public` disk will be used to retrieve images. You may pass a custom disk name to the `disk()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('header_image')
|
||||
->disk('s3')
|
||||
```
|
||||
|
||||
## Private images
|
||||
|
||||
Filament can generate temporary URLs to render private images, you may set the `visibility()` to `private`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('header_image')
|
||||
->visibility('private')
|
||||
```
|
||||
|
||||
## Customizing the size
|
||||
|
||||
You may customize the image size by passing a `width()` and `height()`, or both with `size()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('header_image')
|
||||
->width(200)
|
||||
|
||||
ImageColumn::make('header_image')
|
||||
->height(50)
|
||||
|
||||
ImageColumn::make('author.avatar')
|
||||
->size(40)
|
||||
```
|
||||
|
||||
## Square image
|
||||
|
||||
You may display the image using a 1:1 aspect ratio:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('avatar')
|
||||
->square()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/square" alt="Square image column" version="3.x" />
|
||||
|
||||
## Circular image
|
||||
|
||||
You may make the image fully rounded, which is useful for rendering avatars:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('avatar')
|
||||
->circular()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/circular" alt="Circular image column" version="3.x" />
|
||||
|
||||
## Adding a default image URL
|
||||
|
||||
You can display a placeholder image if one doesn't exist yet, by passing a URL to the `defaultImageUrl()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('avatar')
|
||||
->defaultImageUrl(url('/images/placeholder.png'))
|
||||
```
|
||||
|
||||
## Stacking images
|
||||
|
||||
You may display multiple images as a stack of overlapping images by using `stacked()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/stacked" alt="Stacked image column" version="3.x" />
|
||||
|
||||
### Customizing the stacked ring width
|
||||
|
||||
The default ring width is `3`, but you may customize it to be from `0` to `8`:
|
||||
|
||||
```php
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->ring(5)
|
||||
```
|
||||
|
||||
### Customizing the stacked overlap
|
||||
|
||||
The default overlap is `4`, but you may customize it to be from `0` to `8`:
|
||||
|
||||
```php
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->overlap(2)
|
||||
```
|
||||
|
||||
## Wrapping multiple images
|
||||
|
||||
Images can be set to wrap if they can't fit on one line, by setting `wrap()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->wrap()
|
||||
```
|
||||
|
||||
Note: the "width" for wrapping is affected by the column label, so you may need to use a shorter or hidden label to wrap more tightly.
|
||||
|
||||
## Setting a limit
|
||||
|
||||
You may limit the maximum number of images you want to display by passing `limit()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/limited" alt="Limited image column" version="3.x" />
|
||||
|
||||
### Showing the remaining images count
|
||||
|
||||
When you set a limit you may also display the count of remaining images by passing `limitedRemainingText()`.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
->limitedRemainingText()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/limited-remaining-text" alt="Limited image column with remaining text" version="3.x" />
|
||||
|
||||
#### Showing the limited remaining text separately
|
||||
|
||||
By default, `limitedRemainingText()` will display the count of remaining images as a number stacked on the other images. If you prefer to show the count as a number after the images, you may use the `isSeparate: true` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
->limitedRemainingText(isSeparate: true)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/image/limited-remaining-text-separately" alt="Limited image column with remaining text separately" version="3.x" />
|
||||
|
||||
#### Customizing the limited remaining text size
|
||||
|
||||
By default, the size of the remaining text is `sm`. You can customize this to be `xs`, `md` or `lg` using the `size` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('colleagues.avatar')
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
->limitedRemainingText(size: 'lg')
|
||||
```
|
||||
|
||||
## Custom attributes
|
||||
|
||||
You may customize the extra HTML attributes of the image using `extraImgAttributes()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('logo')
|
||||
->extraImgAttributes(['loading' => 'lazy']),
|
||||
```
|
||||
|
||||
You can access the current record using a `$record` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('logo')
|
||||
->extraImgAttributes(fn (Company $record): array => [
|
||||
'alt' => "{$record->name} logo",
|
||||
]),
|
||||
```
|
||||
|
||||
## Prevent file existence checks
|
||||
|
||||
When the table is loaded, it will automatically detect whether the images exist. This is all done on the backend. When using remote storage with many images, this can be time-consuming. You can use the `checkFileExistence(false)` method to disable this feature:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
|
||||
ImageColumn::make('attachment')
|
||||
->checkFileExistence(false)
|
||||
```
|
||||
68
vendor/filament/tables/docs/03-columns/05-color.md
vendored
Normal file
68
vendor/filament/tables/docs/03-columns/05-color.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Color column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The color column allows you to show the color preview from a CSS color definition, typically entered using the color picker field, in one of the supported formats (HEX, HSL, RGB, RGBA).
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ColorColumn;
|
||||
|
||||
ColorColumn::make('color')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/color/simple" alt="Color column" version="3.x" />
|
||||
|
||||
## Allowing the color to be copied to the clipboard
|
||||
|
||||
You may make the color copyable, such that clicking on the preview copies the CSS value to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ColorColumn;
|
||||
|
||||
ColorColumn::make('color')
|
||||
->copyable()
|
||||
->copyMessage('Color code copied')
|
||||
->copyMessageDuration(1500)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/color/copyable" alt="Color column with a button to copy it" version="3.x" />
|
||||
|
||||
### Customizing the text that is copied to the clipboard
|
||||
|
||||
You can customize the text that gets copied to the clipboard using the `copyableState()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ColorColumn;
|
||||
|
||||
ColorColumn::make('color')
|
||||
->copyable()
|
||||
->copyableState(fn (string $state): string => "Color: {$state}")
|
||||
```
|
||||
|
||||
In this function, you can access the whole table row with `$record`:
|
||||
|
||||
```php
|
||||
use App\Models\Post;
|
||||
use Filament\Tables\Columns\ColorColumn;
|
||||
|
||||
ColorColumn::make('color')
|
||||
->copyable()
|
||||
->copyableState(fn (Post $record): string => "Color: {$record->color}")
|
||||
```
|
||||
|
||||
## Wrapping multiple color blocks
|
||||
|
||||
Color blocks can be set to wrap if they can't fit on one line, by setting `wrap()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ColorColumn;
|
||||
|
||||
ColorColumn::make('color')
|
||||
->wrap()
|
||||
```
|
||||
|
||||
Note: the "width" for wrapping is affected by the column label, so you may need to use a shorter or hidden label to wrap more tightly.
|
||||
|
||||
69
vendor/filament/tables/docs/03-columns/06-select.md
vendored
Normal file
69
vendor/filament/tables/docs/03-columns/06-select.md
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
title: Select column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The select column allows you to render a select field inside the table, which can be used to update that database record without needing to open a new page or a modal.
|
||||
|
||||
You must pass options to the column:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\SelectColumn;
|
||||
|
||||
SelectColumn::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/select/simple" alt="Select column" version="3.x" />
|
||||
|
||||
## Validation
|
||||
|
||||
You can validate the input by passing any [Laravel validation rules](https://laravel.com/docs/validation#available-validation-rules) in an array:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\SelectColumn;
|
||||
|
||||
SelectColumn::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
->rules(['required'])
|
||||
```
|
||||
|
||||
## Disabling placeholder selection
|
||||
|
||||
You can prevent the placeholder from being selected using the `selectablePlaceholder()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\SelectColumn;
|
||||
|
||||
SelectColumn::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
->selectablePlaceholder(false)
|
||||
```
|
||||
|
||||
## Lifecycle hooks
|
||||
|
||||
Hooks may be used to execute code at various points within the select's lifecycle:
|
||||
|
||||
```php
|
||||
SelectColumn::make()
|
||||
->beforeStateUpdated(function ($record, $state) {
|
||||
// Runs before the state is saved to the database.
|
||||
})
|
||||
->afterStateUpdated(function ($record, $state) {
|
||||
// Runs after the state is saved to the database.
|
||||
})
|
||||
```
|
||||
30
vendor/filament/tables/docs/03-columns/07-toggle.md
vendored
Normal file
30
vendor/filament/tables/docs/03-columns/07-toggle.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Toggle column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The toggle column allows you to render a toggle button inside the table, which can be used to update that database record without needing to open a new page or a modal:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ToggleColumn;
|
||||
|
||||
ToggleColumn::make('is_admin')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/toggle/simple" alt="Toggle column" version="3.x" />
|
||||
|
||||
## Lifecycle hooks
|
||||
|
||||
Hooks may be used to execute code at various points within the toggle's lifecycle:
|
||||
|
||||
```php
|
||||
ToggleColumn::make()
|
||||
->beforeStateUpdated(function ($record, $state) {
|
||||
// Runs before the state is saved to the database.
|
||||
})
|
||||
->afterStateUpdated(function ($record, $state) {
|
||||
// Runs after the state is saved to the database.
|
||||
})
|
||||
```
|
||||
51
vendor/filament/tables/docs/03-columns/08-text-input.md
vendored
Normal file
51
vendor/filament/tables/docs/03-columns/08-text-input.md
vendored
Normal file
@@ -0,0 +1,51 @@
|
||||
---
|
||||
title: Text input column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The text input column allows you to render a text input inside the table, which can be used to update that database record without needing to open a new page or a modal:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextInputColumn;
|
||||
|
||||
TextInputColumn::make('email')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/text-input/simple" alt="Text input column" version="3.x" />
|
||||
|
||||
## Validation
|
||||
|
||||
You can validate the input by passing any [Laravel validation rules](https://laravel.com/docs/validation#available-validation-rules) in an array:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextInputColumn;
|
||||
|
||||
TextInputColumn::make('name')
|
||||
->rules(['required', 'max:255'])
|
||||
```
|
||||
|
||||
## Customizing the HTML input type
|
||||
|
||||
You may use the `type()` method to pass a custom [HTML input type](https://developer.mozilla.org/en-US/docs/Web/HTML/Element/input#input_types):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextInputColumn;
|
||||
|
||||
TextInputColumn::make('background_color')->type('color')
|
||||
```
|
||||
|
||||
## Lifecycle hooks
|
||||
|
||||
Hooks may be used to execute code at various points within the input's lifecycle:
|
||||
|
||||
```php
|
||||
TextInputColumn::make()
|
||||
->beforeStateUpdated(function ($record, $state) {
|
||||
// Runs before the state is saved to the database.
|
||||
})
|
||||
->afterStateUpdated(function ($record, $state) {
|
||||
// Runs after the state is saved to the database.
|
||||
})
|
||||
```
|
||||
30
vendor/filament/tables/docs/03-columns/09-checkbox.md
vendored
Normal file
30
vendor/filament/tables/docs/03-columns/09-checkbox.md
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
---
|
||||
title: Checkbox column
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The checkbox column allows you to render a checkbox inside the table, which can be used to update that database record without needing to open a new page or a modal:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\CheckboxColumn;
|
||||
|
||||
CheckboxColumn::make('is_admin')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/columns/checkbox/simple" alt="Checkbox column" version="3.x" />
|
||||
|
||||
## Lifecycle hooks
|
||||
|
||||
Hooks may be used to execute code at various points within the checkbox's lifecycle:
|
||||
|
||||
```php
|
||||
CheckboxColumn::make()
|
||||
->beforeStateUpdated(function ($record, $state) {
|
||||
// Runs before the state is saved to the database.
|
||||
})
|
||||
->afterStateUpdated(function ($record, $state) {
|
||||
// Runs after the state is saved to the database.
|
||||
})
|
||||
```
|
||||
68
vendor/filament/tables/docs/03-columns/10-custom.md
vendored
Normal file
68
vendor/filament/tables/docs/03-columns/10-custom.md
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
---
|
||||
title: Custom columns
|
||||
---
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
<LaracastsBanner
|
||||
title="Build a Custom Table Column"
|
||||
description="Watch the Build Advanced Components for Filament series on Laracasts - it will teach you how to build components, and you'll get to know all the internal tools to help you."
|
||||
url="https://laracasts.com/series/build-advanced-components-for-filament/episodes/10"
|
||||
series="building-advanced-components"
|
||||
/>
|
||||
|
||||
## View columns
|
||||
|
||||
You may render a custom view for a cell using the `view()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\ViewColumn;
|
||||
|
||||
ViewColumn::make('status')->view('filament.tables.columns.status-switcher')
|
||||
```
|
||||
|
||||
This assumes that you have a `resources/views/filament/tables/columns/status-switcher.blade.php` file.
|
||||
|
||||
## Custom classes
|
||||
|
||||
You may create your own custom column classes and cell views, which you can reuse across your project, and even release as a plugin to the community.
|
||||
|
||||
> If you're just creating a simple custom column to use once, you could instead use a [view column](#view-columns) to render any custom Blade file.
|
||||
|
||||
To create a custom column class and view, you may use the following command:
|
||||
|
||||
```bash
|
||||
php artisan make:table-column StatusSwitcher
|
||||
```
|
||||
|
||||
This will create the following column class:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Column;
|
||||
|
||||
class StatusSwitcher extends Column
|
||||
{
|
||||
protected string $view = 'filament.tables.columns.status-switcher';
|
||||
}
|
||||
```
|
||||
|
||||
It will also create a view file at `resources/views/filament/tables/columns/status-switcher.blade.php`.
|
||||
|
||||
## Accessing the state
|
||||
|
||||
Inside your view, you may retrieve the state of the cell using the `$getState()` function:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $getState() }}
|
||||
</div>
|
||||
```
|
||||
|
||||
## Accessing the Eloquent record
|
||||
|
||||
Inside your view, you may access the Eloquent record using the `$getRecord()` function:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $getRecord()->name }}
|
||||
</div>
|
||||
```
|
||||
82
vendor/filament/tables/docs/03-columns/11-relationships.md
vendored
Normal file
82
vendor/filament/tables/docs/03-columns/11-relationships.md
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Column relationships
|
||||
---
|
||||
|
||||
## Displaying data from relationships
|
||||
|
||||
You may use "dot notation" to access columns within relationships. The name of the relationship comes first, followed by a period, followed by the name of the column to display:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('author.name')
|
||||
```
|
||||
|
||||
## Counting relationships
|
||||
|
||||
If you wish to count the number of related records in a column, you may use the `counts()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('users_count')->counts('users')
|
||||
```
|
||||
|
||||
In this example, `users` is the name of the relationship to count from. The name of the column must be `users_count`, as this is the convention that [Laravel uses](https://laravel.com/docs/eloquent-relationships#counting-related-models) for storing the result.
|
||||
|
||||
If you'd like to scope the relationship before calculating, you can pass an array to the method, where the key is the relationship name and the value is the function to scope the Eloquent query with:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
TextColumn::make('users_count')->counts([
|
||||
'users' => fn (Builder $query) => $query->where('is_active', true),
|
||||
])
|
||||
```
|
||||
|
||||
## Determining relationship existence
|
||||
|
||||
If you simply wish to indicate whether related records exist in a column, you may use the `exists()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('users_exists')->exists('users')
|
||||
```
|
||||
|
||||
In this example, `users` is the name of the relationship to check for existence. The name of the column must be `users_exists`, as this is the convention that [Laravel uses](https://laravel.com/docs/eloquent-relationships#other-aggregate-functions) for storing the result.
|
||||
|
||||
If you'd like to scope the relationship before calculating, you can pass an array to the method, where the key is the relationship name and the value is the function to scope the Eloquent query with:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
TextColumn::make('users_exists')->exists([
|
||||
'users' => fn (Builder $query) => $query->where('is_active', true),
|
||||
])
|
||||
```
|
||||
|
||||
## Aggregating relationships
|
||||
|
||||
Filament provides several methods for aggregating a relationship field, including `avg()`, `max()`, `min()` and `sum()`. For instance, if you wish to show the average of a field on all related records in a column, you may use the `avg()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('users_avg_age')->avg('users', 'age')
|
||||
```
|
||||
|
||||
In this example, `users` is the name of the relationship, while `age` is the field that is being averaged. The name of the column must be `users_avg_age`, as this is the convention that [Laravel uses](https://laravel.com/docs/eloquent-relationships#other-aggregate-functions) for storing the result.
|
||||
|
||||
If you'd like to scope the relationship before calculating, you can pass an array to the method, where the key is the relationship name and the value is the function to scope the Eloquent query with:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
TextColumn::make('users_avg_age')->avg([
|
||||
'users' => fn (Builder $query) => $query->where('is_active', true),
|
||||
], 'age')
|
||||
```
|
||||
123
vendor/filament/tables/docs/03-columns/12-advanced.md
vendored
Normal file
123
vendor/filament/tables/docs/03-columns/12-advanced.md
vendored
Normal file
@@ -0,0 +1,123 @@
|
||||
---
|
||||
title: Advanced columns
|
||||
---
|
||||
|
||||
## Table column utility injection
|
||||
|
||||
The vast majority of methods used to configure columns accept functions as parameters instead of hardcoded values:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('status')
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'draft' => 'gray',
|
||||
'reviewing' => 'warning',
|
||||
'published' => 'success',
|
||||
'rejected' => 'danger',
|
||||
})
|
||||
```
|
||||
|
||||
This alone unlocks many customization possibilities.
|
||||
|
||||
The package is also able to inject many utilities to use inside these functions, as parameters. All customization methods that accept functions as arguments can inject utilities.
|
||||
|
||||
These injected utilities require specific parameter names to be used. Otherwise, Filament doesn't know what to inject.
|
||||
|
||||
### Injecting the current state of a column
|
||||
|
||||
If you wish to access the current state (value) of the column, define a `$state` parameter:
|
||||
|
||||
```php
|
||||
function ($state) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current Eloquent record
|
||||
|
||||
If you wish to access the current Eloquent record of the column, define a `$record` parameter:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
function (Model $record) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Be aware that this parameter will be `null` if the column is not bound to an Eloquent record. For instance, the `label()` method of a column will not have access to the record, as the label is not related to any table row.
|
||||
|
||||
### Injecting the current column instance
|
||||
|
||||
If you wish to access the current column instance, define a `$column` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Column;
|
||||
|
||||
function (Column $column) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current Livewire component instance
|
||||
|
||||
If you wish to access the current Livewire component instance that the table belongs to, define a `$livewire` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Contracts\HasTable;
|
||||
|
||||
function (HasTable $livewire) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current table instance
|
||||
|
||||
If you wish to access the current table configuration instance that the column belongs to, define a `$table` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
function (Table $table) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current table row loop
|
||||
|
||||
If you wish to access the current [Laravel Blade loop object](https://laravel.com/docs/blade#the-loop-variable) that the column is rendered part of, define a `$rowLoop` parameter:
|
||||
|
||||
```php
|
||||
function (stdClass $rowLoop) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
As `$rowLoop` is [Laravel Blade's `$loop` object](https://laravel.com/docs/blade#the-loop-variable), you can access the current row index using `$rowLoop->index`. Similar to `$record`, this parameter will be `null` if the column is currently being rendered outside a table row.
|
||||
|
||||
### Injecting multiple utilities
|
||||
|
||||
The parameters are injected dynamically using reflection, so you are able to combine multiple parameters in any order:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Contracts\HasTable;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
function (HasTable $livewire, Model $record) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting dependencies from Laravel's container
|
||||
|
||||
You may inject anything from Laravel's container like normal, alongside utilities:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
function (Request $request, Model $record) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
310
vendor/filament/tables/docs/04-filters/01-getting-started.md
vendored
Normal file
310
vendor/filament/tables/docs/04-filters/01-getting-started.md
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
---
|
||||
title: Getting started
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
<LaracastsBanner
|
||||
title="Table Filters"
|
||||
description="Watch the Rapid Laravel Development with Filament series on Laracasts - it will teach you the basics of adding filters to Filament resource tables."
|
||||
url="https://laracasts.com/series/rapid-laravel-development-with-filament/episodes/10"
|
||||
series="rapid-laravel-development"
|
||||
/>
|
||||
|
||||
Filters allow you to define certain constraints on your data, and allow users to scope it to find the information they need. You put them in the `$table->filters()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/filters/simple" alt="Table with filter" version="3.x" />
|
||||
|
||||
Filters may be created using the static `make()` method, passing its unique name. You should then pass a callback to `query()` which applies your filter's scope:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
Filter::make('is_featured')
|
||||
->query(fn (Builder $query): Builder => $query->where('is_featured', true))
|
||||
```
|
||||
|
||||
## Available filters
|
||||
|
||||
By default, using the `Filter::make()` method will render a checkbox form component. When the checkbox is on, the `query()` will be activated.
|
||||
|
||||
- You can also [replace the checkbox with a toggle](#using-a-toggle-button-instead-of-a-checkbox).
|
||||
- You can use a [ternary filter](ternary) to replace the checkbox with a select field to allow users to pick between 3 states - usually "true", "false" and "blank". This is useful for filtering boolean columns that are nullable.
|
||||
- The [trashed filter](ternary#filtering-soft-deletable-records) is a pre-built ternary filter that allows you to filter soft-deletable records.
|
||||
- You may use a [select filter](select) to allow users to select from a list of options, and filter using the selection.
|
||||
- You may use a [query builder](query-builder) to allow users to create complex sets of filters, with an advanced user interface for combining constraints.
|
||||
- You may build [custom filters](custom) with other form fields, to do whatever you want.
|
||||
|
||||
## Setting a label
|
||||
|
||||
By default, the label of the filter, which is displayed in the filter form, is generated from the name of the filter. You may customize this using the `label()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('is_featured')
|
||||
->label('Featured')
|
||||
```
|
||||
|
||||
Optionally, you can have the label automatically translated [using Laravel's localization features](https://laravel.com/docs/localization) with the `translateLabel()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('is_featured')
|
||||
->translateLabel() // Equivalent to `label(__('Is featured'))`
|
||||
```
|
||||
|
||||
## Customizing the filter form
|
||||
|
||||
By default, creating a filter with the `Filter` class will render a [checkbox form component](../../forms/fields/checkbox). When the checkbox is checked, the `query()` function will be applied to the table's query, scoping the records in the table. When the checkbox is unchecked, the `query()` function will be removed from the table's query.
|
||||
|
||||
Filters are built entirely on Filament's form fields. They can render any combination of form fields, which users can then interact with to filter the table.
|
||||
|
||||
### Using a toggle button instead of a checkbox
|
||||
|
||||
The simplest example of managing the form field that is used for a filter is to replace the [checkbox](../../forms/fields/checkbox) with a [toggle button](../../forms/fields/toggle), using the `toggle()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('is_featured')
|
||||
->toggle()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/filters/toggle" alt="Table with toggle filter" version="3.x" />
|
||||
|
||||
### Applying the filter by default
|
||||
|
||||
You may set a filter to be enabled by default, using the `default()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('is_featured')
|
||||
->default()
|
||||
```
|
||||
|
||||
### Customizing the built-in filter form field
|
||||
|
||||
Whether you are using a checkbox, a [toggle](#using-a-toggle-button-instead-of-a-checkbox) or a [select](select), you can customize the built-in form field used for the filter, using the `modifyFormFieldUsing()` method. The method accepts a function with a `$field` parameter that gives you access to the form field object to customize:
|
||||
|
||||
```php
|
||||
use Filament\Forms\Components\Checkbox;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('is_featured')
|
||||
->modifyFormFieldUsing(fn (Checkbox $field) => $field->inline(false))
|
||||
```
|
||||
|
||||
## Persist filters in session
|
||||
|
||||
To persist the table filters in the user's session, use the `persistFiltersInSession()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->persistFiltersInSession();
|
||||
}
|
||||
```
|
||||
|
||||
## Deferring filters
|
||||
|
||||
You can defer filter changes from affecting the table, until the user clicks an "Apply" button. To do this, use the `deferFilters()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->deferFilters();
|
||||
}
|
||||
```
|
||||
|
||||
### Customizing the apply filters action
|
||||
|
||||
When deferring filters, you can customize the "Apply" button, using the `filtersApplyAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](../../actions/trigger-button) can be used:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->filtersApplyAction(
|
||||
fn (Action $action) => $action
|
||||
->link()
|
||||
->label('Save filters to table'),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Deselecting records when filters change
|
||||
|
||||
By default, all records will be deselected when the filters change. Using the `deselectAllRecordsWhenFiltered(false)` method, you can disable this behavior:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->deselectAllRecordsWhenFiltered(false);
|
||||
}
|
||||
```
|
||||
|
||||
## Modifying the base query
|
||||
|
||||
By default, modifications to the Eloquent query performed in the `query()` method will be applied inside a scoped `where()` clause. This is to ensure that the query does not clash with any other filters that may be applied, especially those that use `orWhere()`.
|
||||
|
||||
However, the downside of this is that the `query()` method cannot be used to modify the query in other ways, such as removing global scopes, since the base query needs to be modified directly, not the scoped query.
|
||||
|
||||
To modify the base query directly, you may use the `baseQuery()` method, passing a closure that receives the base query:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\SoftDeletingScope;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
|
||||
TernaryFilter::make('trashed')
|
||||
// ...
|
||||
->baseQuery(fn (Builder $query) => $query->withoutGlobalScopes([
|
||||
SoftDeletingScope::class,
|
||||
]))
|
||||
```
|
||||
|
||||
## Customizing the filters trigger action
|
||||
|
||||
To customize the filters trigger buttons, you may use the `filtersTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](../../actions/trigger-button) can be used:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->filtersTriggerAction(
|
||||
fn (Action $action) => $action
|
||||
->button()
|
||||
->label('Filter'),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/filters/custom-trigger-action" alt="Table with custom filters trigger action" version="3.x" />
|
||||
|
||||
## Table filter utility injection
|
||||
|
||||
The vast majority of methods used to configure filters accept functions as parameters instead of hardcoded values:
|
||||
|
||||
```php
|
||||
use App\Models\Author;
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('author')
|
||||
->options(fn (): array => Author::query()->pluck('name', 'id')->all())
|
||||
```
|
||||
|
||||
This alone unlocks many customization possibilities.
|
||||
|
||||
The package is also able to inject many utilities to use inside these functions, as parameters. All customization methods that accept functions as arguments can inject utilities.
|
||||
|
||||
These injected utilities require specific parameter names to be used. Otherwise, Filament doesn't know what to inject.
|
||||
|
||||
### Injecting the current filter instance
|
||||
|
||||
If you wish to access the current filter instance, define a `$filter` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\BaseFilter;
|
||||
|
||||
function (BaseFilter $filter) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current Livewire component instance
|
||||
|
||||
If you wish to access the current Livewire component instance that the table belongs to, define a `$livewire` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Contracts\HasTable;
|
||||
|
||||
function (HasTable $livewire) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current table instance
|
||||
|
||||
If you wish to access the current table configuration instance that the filter belongs to, define a `$table` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
function (Table $table) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting multiple utilities
|
||||
|
||||
The parameters are injected dynamically using reflection, so you are able to combine multiple parameters in any order:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Contracts\HasTable;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
function (HasTable $livewire, Table $table) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting dependencies from Laravel's container
|
||||
|
||||
You may inject anything from Laravel's container like normal, alongside utilities:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
function (Request $request, Table $table) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
119
vendor/filament/tables/docs/04-filters/02-select.md
vendored
Normal file
119
vendor/filament/tables/docs/04-filters/02-select.md
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Select filters
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Often, you will want to use a [select field](../../forms/fields/select) instead of a checkbox. This is especially true when you want to filter a column based on a set of pre-defined options that the user can choose from. To do this, you can create a filter using the `SelectFilter` class:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
```
|
||||
|
||||
The `options()` that are passed to the filter are the same as those that are passed to the [select field](../../forms/fields/select).
|
||||
|
||||
## Customizing the column used by a select filter
|
||||
|
||||
Select filters do not require a custom `query()` method. The column name used to scope the query is the name of the filter. To customize this, you may use the `attribute()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
->attribute('status_id')
|
||||
```
|
||||
|
||||
## Multi-select filters
|
||||
|
||||
These allow the user to select multiple options to apply the filter to their table. For example, a status filter may present the user with a few status options to pick from and filter the table using. When the user selects multiple options, the table will be filtered to show records that match any of the selected options. You can enable this behavior using the `multiple()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('status')
|
||||
->multiple()
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
```
|
||||
|
||||
## Relationship select filters
|
||||
|
||||
Select filters are also able to automatically populate themselves based on a relationship. For example, if your table has a `author` relationship with a `name` column, you may use `relationship()` to filter the records belonging to an author:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('author')
|
||||
->relationship('author', 'name')
|
||||
```
|
||||
|
||||
### Preloading the select filter relationship options
|
||||
|
||||
If you'd like to populate the searchable options from the database when the page is loaded, instead of when the user searches, you can use the `preload()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('author')
|
||||
->relationship('author', 'name')
|
||||
->searchable()
|
||||
->preload()
|
||||
```
|
||||
|
||||
### Customizing the select filter relationship query
|
||||
|
||||
You may customize the database query that retrieves options using the third parameter of the `relationship()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
SelectFilter::make('author')
|
||||
->relationship('author', 'name', fn (Builder $query) => $query->withTrashed())
|
||||
```
|
||||
|
||||
### Searching select filter options
|
||||
|
||||
You may enable a search input to allow easier access to many options, using the `searchable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('author')
|
||||
->relationship('author', 'name')
|
||||
->searchable()
|
||||
```
|
||||
|
||||
## Disable placeholder selection
|
||||
|
||||
You can remove the placeholder (null option), which disables the filter so all options are applied, using the `selectablePlaceholder()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\SelectFilter;
|
||||
|
||||
SelectFilter::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
->default('draft')
|
||||
->selectablePlaceholder(false)
|
||||
```
|
||||
82
vendor/filament/tables/docs/04-filters/03-ternary.md
vendored
Normal file
82
vendor/filament/tables/docs/04-filters/03-ternary.md
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Ternary filters
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Ternary filters allow you to easily create a select filter which has three states - usually true, false and blank. To filter a column named `is_admin` to be `true` or `false`, you may use the ternary filter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
|
||||
TernaryFilter::make('is_admin')
|
||||
```
|
||||
|
||||
## Using a ternary filter with a nullable column
|
||||
|
||||
Another common pattern is to use a nullable column. For example, when filtering verified and unverified users using the `email_verified_at` column, unverified users have a null timestamp in this column. To apply that logic, you may use the `nullable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
|
||||
TernaryFilter::make('email_verified_at')
|
||||
->nullable()
|
||||
```
|
||||
|
||||
## Customizing the column used by a ternary filter
|
||||
|
||||
The column name used to scope the query is the name of the filter. To customize this, you may use the `attribute()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
|
||||
TernaryFilter::make('verified')
|
||||
->nullable()
|
||||
->attribute('status_id')
|
||||
```
|
||||
|
||||
## Customizing the ternary filter option labels
|
||||
|
||||
You may customize the labels used for each state of the ternary filter. The true option label can be customized using the `trueLabel()` method. The false option label can be customized using the `falseLabel()` method. The blank (default) option label can be customized using the `placeholder()` method:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
|
||||
TernaryFilter::make('email_verified_at')
|
||||
->label('Email verification')
|
||||
->nullable()
|
||||
->placeholder('All users')
|
||||
->trueLabel('Verified users')
|
||||
->falseLabel('Not verified users')
|
||||
```
|
||||
|
||||
## Customizing how a ternary filter modifies the query
|
||||
|
||||
You may customize how the query changes for each state of the ternary filter, use the `queries()` method:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Filament\Tables\Filters\TernaryFilter;
|
||||
|
||||
TernaryFilter::make('email_verified_at')
|
||||
->label('Email verification')
|
||||
->placeholder('All users')
|
||||
->trueLabel('Verified users')
|
||||
->falseLabel('Not verified users')
|
||||
->queries(
|
||||
true: fn (Builder $query) => $query->whereNotNull('email_verified_at'),
|
||||
false: fn (Builder $query) => $query->whereNull('email_verified_at'),
|
||||
blank: fn (Builder $query) => $query, // In this example, we do not want to filter the query when it is blank.
|
||||
)
|
||||
```
|
||||
|
||||
## Filtering soft deletable records
|
||||
|
||||
The `TrashedFilter` can be used to filter soft deleted records. It is a type of ternary filter that is built-in to Filament. You can use it like so:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\TrashedFilter;
|
||||
|
||||
TrashedFilter::make()
|
||||
```
|
||||
495
vendor/filament/tables/docs/04-filters/04-query-builder.md
vendored
Normal file
495
vendor/filament/tables/docs/04-filters/04-query-builder.md
vendored
Normal file
@@ -0,0 +1,495 @@
|
||||
---
|
||||
title: Query builder
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
The query builder allows you to define a complex set of conditions to filter the data in your table. It is able to handle unlimited nesting of conditions, which you can group together with "and" and "or" operations.
|
||||
|
||||
To use it, you need to define a set of "constraints" that will be used to filter the data. Filament includes some built-in constraints, that follow common data types, but you can also define your own custom constraints.
|
||||
|
||||
You can add a query builder to any table using the `QueryBuilder` filter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\BooleanConstraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\DateConstraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\NumberConstraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint\Operators\IsRelatedToOperator;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\SelectConstraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
QueryBuilder::make()
|
||||
->constraints([
|
||||
TextConstraint::make('name'),
|
||||
BooleanConstraint::make('is_visible'),
|
||||
NumberConstraint::make('stock'),
|
||||
SelectConstraint::make('status')
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
->multiple(),
|
||||
DateConstraint::make('created_at'),
|
||||
RelationshipConstraint::make('categories')
|
||||
->multiple()
|
||||
->selectable(
|
||||
IsRelatedToOperator::make()
|
||||
->titleAttribute('name')
|
||||
->searchable()
|
||||
->multiple(),
|
||||
),
|
||||
NumberConstraint::make('reviewsRating')
|
||||
->relationship('reviews', 'rating')
|
||||
->integer(),
|
||||
])
|
||||
```
|
||||
|
||||
When deeply nesting the query builder, you might need to increase the amount of space that the filters can consume. One way of doing this is to [position the filters above the table content](layout#displaying-filters-above-the-table-content):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\FiltersLayout;
|
||||
use Filament\Tables\Filters\QueryBuilder;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
QueryBuilder::make()
|
||||
->constraints([
|
||||
// ...
|
||||
]),
|
||||
], layout: FiltersLayout::AboveContent);
|
||||
}
|
||||
```
|
||||
|
||||
## Available constraints
|
||||
|
||||
Filament ships with many different constraints that you can use out of the box. You can also [create your own custom constraints](#creating-custom-constraints):
|
||||
|
||||
- [Text constraint](#text-constraints)
|
||||
- [Boolean constraint](#boolean-constraints)
|
||||
- [Number constraint](#number-constraints)
|
||||
- [Date constraint](#date-constraints)
|
||||
- [Select constraint](#select-constraints)
|
||||
- [Relationship constraint](#relationship-constraints)
|
||||
|
||||
### Text constraints
|
||||
|
||||
Text constraints allow you to filter text fields. They can be used to filter any text field, including via relationships.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
TextConstraint::make('name') // Filter the `name` column
|
||||
|
||||
TextConstraint::make('creatorName')
|
||||
->relationship(name: 'creator', titleAttribute: 'name') // Filter the `name` column on the `creator` relationship
|
||||
```
|
||||
|
||||
By default, the following operators are available:
|
||||
|
||||
- Contains - filters a column to contain the search term
|
||||
- Does not contain - filters a column to not contain the search term
|
||||
- Starts with - filters a column to start with the search term
|
||||
- Does not start with - filters a column to not start with the search term
|
||||
- Ends with - filters a column to end with the search term
|
||||
- Does not end with - filters a column to not end with the search term
|
||||
- Equals - filters a column to equal the search term
|
||||
- Does not equal - filters a column to not equal the search term
|
||||
- Is filled - filters a column to not be empty
|
||||
- Is blank - filters a column to be empty
|
||||
|
||||
### Boolean constraints
|
||||
|
||||
Boolean constraints allow you to filter boolean fields. They can be used to filter any boolean field, including via relationships.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\BooleanConstraint;
|
||||
|
||||
BooleanConstraint::make('is_visible') // Filter the `is_visible` column
|
||||
|
||||
BooleanConstraint::make('creatorIsAdmin')
|
||||
->relationship(name: 'creator', titleAttribute: 'is_admin') // Filter the `is_admin` column on the `creator` relationship
|
||||
```
|
||||
|
||||
By default, the following operators are available:
|
||||
|
||||
- Is true - filters a column to be `true`
|
||||
- Is false - filters a column to be `false`
|
||||
|
||||
### Number constraints
|
||||
|
||||
Number constraints allow you to filter numeric fields. They can be used to filter any numeric field, including via relationships.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\NumberConstraint;
|
||||
|
||||
NumberConstraint::make('stock') // Filter the `stock` column
|
||||
|
||||
NumberConstraint::make('ordersItemCount')
|
||||
->relationship(name: 'orders', titleAttribute: 'item_count') // Filter the `item_count` column on the `orders` relationship
|
||||
```
|
||||
|
||||
By default, the following operators are available:
|
||||
|
||||
- Is minimum - filters a column to be greater than or equal to the search number
|
||||
- Is less than - filters a column to be less than the search number
|
||||
- Is maximum - filters a column to be less than or equal to the search number
|
||||
- Is greater than - filters a column to be greater than the search number
|
||||
- Equals - filters a column to equal the search number
|
||||
- Does not equal - filters a column to not equal the search number
|
||||
- Is filled - filters a column to not be empty
|
||||
- Is blank - filters a column to be empty
|
||||
|
||||
When using `relationship()` with a number constraint, users also have the ability to "aggregate" related records. This means that they can filter the column to be the sum, average, minimum or maximum of all the related records at once.
|
||||
|
||||
#### Integer constraints
|
||||
|
||||
By default, number constraints will allow decimal values. If you'd like to only allow integer values, you can use the `integer()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\NumberConstraint;
|
||||
|
||||
NumberConstraint::make('stock')
|
||||
->integer()
|
||||
```
|
||||
|
||||
### Date constraints
|
||||
|
||||
Date constraints allow you to filter date fields. They can be used to filter any date field, including via relationships.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\DateConstraint;
|
||||
|
||||
DateConstraint::make('created_at') // Filter the `created_at` column
|
||||
|
||||
DateConstraint::make('creatorCreatedAt')
|
||||
->relationship(name: 'creator', titleAttribute: 'created_at') // Filter the `created_at` column on the `creator` relationship
|
||||
```
|
||||
|
||||
By default, the following operators are available:
|
||||
|
||||
- Is after - filters a column to be after the search date
|
||||
- Is not after - filters a column to not be after the search date, or to be the same date
|
||||
- Is before - filters a column to be before the search date
|
||||
- Is not before - filters a column to not be before the search date, or to be the same date
|
||||
- Is date - filters a column to be the same date as the search date
|
||||
- Is not date - filters a column to not be the same date as the search date
|
||||
- Is month - filters a column to be in the same month as the selected month
|
||||
- Is not month - filters a column to not be in the same month as the selected month
|
||||
- Is year - filters a column to be in the same year as the searched year
|
||||
- Is not year - filters a column to not be in the same year as the searched year
|
||||
|
||||
### Select constraints
|
||||
|
||||
Select constraints allow you to filter fields using a select field. They can be used to filter any field, including via relationships.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\SelectConstraint;
|
||||
|
||||
SelectConstraint::make('status') // Filter the `status` column
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
|
||||
SelectConstraint::make('creatorStatus')
|
||||
->relationship(name: 'creator', titleAttribute: 'department') // Filter the `department` column on the `creator` relationship
|
||||
->options([
|
||||
'sales' => 'Sales',
|
||||
'marketing' => 'Marketing',
|
||||
'engineering' => 'Engineering',
|
||||
'purchasing' => 'Purchasing',
|
||||
])
|
||||
```
|
||||
|
||||
#### Searchable select constraints
|
||||
|
||||
By default, select constraints will not allow the user to search the options. If you'd like to allow the user to search the options, you can use the `searchable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\SelectConstraint;
|
||||
|
||||
SelectConstraint::make('status')
|
||||
->searchable()
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
```
|
||||
|
||||
#### Multi-select constraints
|
||||
|
||||
By default, select constraints will only allow the user to select a single option. If you'd like to allow the user to select multiple options, you can use the `multiple()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\SelectConstraint;
|
||||
|
||||
SelectConstraint::make('status')
|
||||
->multiple()
|
||||
->options([
|
||||
'draft' => 'Draft',
|
||||
'reviewing' => 'Reviewing',
|
||||
'published' => 'Published',
|
||||
])
|
||||
```
|
||||
|
||||
When the user selects multiple options, the table will be filtered to show records that match any of the selected options.
|
||||
|
||||
### Relationship constraints
|
||||
|
||||
Relationship constraints allow you to filter fields using data about a relationship:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint\Operators\IsRelatedToOperator;
|
||||
|
||||
RelationshipConstraint::make('creator') // Filter the `creator` relationship
|
||||
->selectable(
|
||||
IsRelatedToOperator::make()
|
||||
->titleAttribute('name')
|
||||
->searchable()
|
||||
->multiple(),
|
||||
)
|
||||
```
|
||||
|
||||
The `IsRelatedToOperator` is used to configure the "Is / Contains" and "Is not / Does not contain" operators. It provides a select field which allows the user to filter the relationship by which records are attached to it. The `titleAttribute()` method is used to specify which attribute should be used to identify each related record in the list. The `searchable()` method makes the list searchable. The `multiple()` method allows the user to select multiple related records, and if they do, the table will be filtered to show records that match any of the selected related records.
|
||||
|
||||
#### Multiple relationships
|
||||
|
||||
By default, relationship constraints only include operators that are appropriate for filtering a singular relationship, like a `BelongsTo`. If you have a relationship such as a `HasMany` or `BelongsToMany`, you may wish to mark the constraint as `multiple()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint;
|
||||
|
||||
RelationshipConstraint::make('categories')
|
||||
->multiple()
|
||||
```
|
||||
|
||||
This will add the following operators to the constraint:
|
||||
|
||||
- Has minimum - filters a column to have at least the specified number of related records
|
||||
- Has less than - filters a column to have less than the specified number of related records
|
||||
- Has maximum - filters a column to have at most the specified number of related records
|
||||
- Has more than - filters a column to have more than the specified number of related records
|
||||
- Has - filters a column to have the specified number of related records
|
||||
- Does not have - filters a column to not have the specified number of related records
|
||||
|
||||
#### Empty relationship constraints
|
||||
|
||||
The `RelationshipConstraint` does not support [`nullable()`](#nullable-constraints) in the same way as other constraints.
|
||||
|
||||
If the relationship is `multiple()`, then the constraint will show an option to filter out "empty" relationships. This means that the relationship has no related records. If your relationship is singular, then you can use the `emptyable()` method to show an option to filter out "empty" relationships:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint;
|
||||
|
||||
RelationshipConstraint::make('creator')
|
||||
->emptyable()
|
||||
```
|
||||
|
||||
If you have a `multiple()` relationship that must always have at least 1 related record, then you can use the `emptyable(false)` method to hide the option to filter out "empty" relationships:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\RelationshipConstraint;
|
||||
|
||||
RelationshipConstraint::make('categories')
|
||||
->emptyable(false)
|
||||
```
|
||||
|
||||
#### Nullable constraints
|
||||
|
||||
By default, constraints will not show an option to filter `null` values. If you'd like to show an option to filter `null` values, you can use the `nullable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
TextConstraint::make('name')
|
||||
->nullable()
|
||||
```
|
||||
|
||||
Now, the following operators are also available:
|
||||
|
||||
- Is filled - filters a column to not be empty
|
||||
- Is blank - filters a column to be empty
|
||||
|
||||
## Scoping relationships
|
||||
|
||||
When you use the `relationship()` method on a constraint, you can scope the relationship to filter the related records using the `modifyQueryUsing` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
TextConstraint::make('adminCreatorName')
|
||||
->relationship(
|
||||
name: 'creator',
|
||||
titleAttribute: 'name',
|
||||
modifyQueryUsing: fn (Builder $query) => $query->where('is_admin', true),
|
||||
)
|
||||
```
|
||||
|
||||
## Customizing the constraint icon
|
||||
|
||||
Each constraint type has a default [icon](https://blade-ui-kit.com/blade-icons?set=1#search), which is displayed next to the label in the picker. You can customize the icon for a constraint by passing its name to the `icon()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
TextConstraint::make('author')
|
||||
->relationship(name: 'author', titleAttribute: 'name')
|
||||
->icon('heroicon-m-user')
|
||||
```
|
||||
|
||||
## Overriding the default operators
|
||||
|
||||
Each constraint type has a set of default operators, which you can customize by using the `operators()`method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Operators\IsFilledOperator;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
TextConstraint::make('author')
|
||||
->relationship(name: 'author', titleAttribute: 'name')
|
||||
->operators([
|
||||
IsFilledOperator::make(),
|
||||
])
|
||||
```
|
||||
|
||||
This will remove all operators, and register the `EqualsOperator`.
|
||||
|
||||
If you'd like to add an operator to the end of the list, use `pushOperators()` instead:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Operators\IsFilledOperator;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
TextConstraint::make('author')
|
||||
->relationship(name: 'author', titleAttribute: 'name')
|
||||
->pushOperators([
|
||||
IsFilledOperator::class,
|
||||
])
|
||||
```
|
||||
|
||||
If you'd like to add an operator to the start of the list, use `unshiftOperators()` instead:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Operators\IsFilledOperator;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\TextConstraint;
|
||||
|
||||
TextConstraint::make('author')
|
||||
->relationship(name: 'author', titleAttribute: 'name')
|
||||
->unshiftOperators([
|
||||
IsFilledOperator::class,
|
||||
])
|
||||
```
|
||||
|
||||
## Creating custom constraints
|
||||
|
||||
Custom constraints can be created "inline" with other constraints using the `Constraint::make()` method. You should also pass an [icon](#customizing-the-constraint-icon) to the `icon()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Constraint;
|
||||
|
||||
Constraint::make('subscribed')
|
||||
->icon('heroicon-m-bell')
|
||||
->operators([
|
||||
// ...
|
||||
]),
|
||||
```
|
||||
|
||||
If you want to customize the label of the constraint, you can use the `label()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Constraint;
|
||||
|
||||
Constraint::make('subscribed')
|
||||
->label('Subscribed to updates')
|
||||
->icon('heroicon-m-bell')
|
||||
->operators([
|
||||
// ...
|
||||
]),
|
||||
```
|
||||
|
||||
Now, you must [define operators](#creating-custom-operators) for the constraint. These are options that you can pick from to filter the column. If the column is [nullable](#nullable-constraints), you can also register that built-in operator for your custom constraint:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Constraint;
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Operators\IsFilledOperator;
|
||||
|
||||
Constraint::make('subscribed')
|
||||
->label('Subscribed to updates')
|
||||
->icon('heroicon-m-bell')
|
||||
->operators([
|
||||
// ...
|
||||
IsFilledOperator::class,
|
||||
]),
|
||||
```
|
||||
|
||||
### Creating custom operators
|
||||
|
||||
Custom operators can be created using the `Operator::make()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder\Constraints\Operators\Operator;
|
||||
|
||||
Operator::make('subscribed')
|
||||
->label(fn (bool $isInverse): string => $isInverse ? 'Not subscribed' : 'Subscribed')
|
||||
->summary(fn (bool $isInverse): string => $isInverse ? 'You are not subscribed' : 'You are subscribed')
|
||||
->baseQuery(fn (Builder $query, bool $isInverse) => $query->{$isInverse ? 'whereDoesntHave' : 'whereHas'}(
|
||||
'subscriptions.user',
|
||||
fn (Builder $query) => $query->whereKey(auth()->user()),
|
||||
)),
|
||||
```
|
||||
|
||||
In this example, the operator is able to filter records based on whether or not the authenticated user is subscribed to the record. A subscription is recorded in the `subscriptions` relationship of the table.
|
||||
|
||||
The `baseQuery()` method is used to define the query that will be used to filter the records. The `$isInverse` argument is `false` when the "Subscribed" option is selected, and `true` when the "Not subscribed" option is selected. The function is applied to the base query of the table, where `whereHas()` can be used. If your function does not need to be applied to the base query of the table, like when you are using a simple `where()` or `whereIn()`, you can use the `query()` method instead, which has the bonus of being able to be used inside nested "OR" groups.
|
||||
|
||||
The `label()` method is used to render the options in the operator select. Two options are registered for each operator, one for when the operator is not inverted, and one for when it is inverted.
|
||||
|
||||
The `summary()` method is used in the header of the constraint when it is applied to the query, to provide an overview of the active constraint.
|
||||
|
||||
## Customizing the constraint picker
|
||||
|
||||
### Changing the number of columns in the constraint picker
|
||||
|
||||
The constraint picker has only 1 column. You may customize it by passing a number of columns to `constraintPickerColumns()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder;
|
||||
|
||||
QueryBuilder::make()
|
||||
->constraintPickerColumns(2)
|
||||
->constraints([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
This method can be used in a couple of different ways:
|
||||
|
||||
- You can pass an integer like `constraintPickerColumns(2)`. This integer is the number of columns used on the `lg` breakpoint and higher. All smaller devices will have just 1 column.
|
||||
- You can pass an array, where the key is the breakpoint and the value is the number of columns. For example, `constraintPickerColumns(['md' => 2, 'xl' => 4])` will create a 2 column layout on medium devices, and a 4 column layout on extra large devices. The default breakpoint for smaller devices uses 1 column, unless you use a `default` array key.
|
||||
|
||||
Breakpoints (`sm`, `md`, `lg`, `xl`, `2xl`) are defined by Tailwind, and can be found in the [Tailwind documentation](https://tailwindcss.com/docs/responsive-design#overview).
|
||||
|
||||
### Increasing the width of the constraint picker
|
||||
|
||||
When you [increase the number of columns](#changing-the-number-of-columns-in-the-constraint-picker), the width of the dropdown should increase incrementally to handle the additional columns. If you'd like more control, you can manually set a maximum width for the dropdown using the `constraintPickerWidth()` method. Options correspond to [Tailwind's max-width scale](https://tailwindcss.com/docs/max-width). The options are `xs`, `sm`, `md`, `lg`, `xl`, `2xl`, `3xl`, `4xl`, `5xl`, `6xl`, `7xl`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\QueryBuilder;
|
||||
|
||||
QueryBuilder::make()
|
||||
->constraintPickerColumns(3)
|
||||
->constraintPickerWidth('2xl')
|
||||
->constraints([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
145
vendor/filament/tables/docs/04-filters/05-custom.md
vendored
Normal file
145
vendor/filament/tables/docs/04-filters/05-custom.md
vendored
Normal file
@@ -0,0 +1,145 @@
|
||||
---
|
||||
title: Custom filters
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
## Custom filter forms
|
||||
|
||||
<LaracastsBanner
|
||||
title="Build a Custom Table Filter"
|
||||
description="Watch the Build Advanced Components for Filament series on Laracasts - it will teach you how to build components, and you'll get to know all the internal tools to help you."
|
||||
url="https://laracasts.com/series/build-advanced-components-for-filament/episodes/11"
|
||||
series="building-advanced-components"
|
||||
/>
|
||||
|
||||
You may use components from the [Form Builder](../../forms/fields/getting-started) to create custom filter forms. The data from the custom filter form is available in the `$data` array of the `query()` callback:
|
||||
|
||||
```php
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
Filter::make('created_at')
|
||||
->form([
|
||||
DatePicker::make('created_from'),
|
||||
DatePicker::make('created_until'),
|
||||
])
|
||||
->query(function (Builder $query, array $data): Builder {
|
||||
return $query
|
||||
->when(
|
||||
$data['created_from'],
|
||||
fn (Builder $query, $date): Builder => $query->whereDate('created_at', '>=', $date),
|
||||
)
|
||||
->when(
|
||||
$data['created_until'],
|
||||
fn (Builder $query, $date): Builder => $query->whereDate('created_at', '<=', $date),
|
||||
);
|
||||
})
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/filters/custom-form" alt="Table with custom filter form" version="3.x" />
|
||||
|
||||
### Setting default values for custom filter fields
|
||||
|
||||
To customize the default value of a field in a custom filter form, you may use the `default()` method:
|
||||
|
||||
```php
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('created_at')
|
||||
->form([
|
||||
DatePicker::make('created_from'),
|
||||
DatePicker::make('created_until')
|
||||
->default(now()),
|
||||
])
|
||||
```
|
||||
|
||||
## Active indicators
|
||||
|
||||
When a filter is active, an indicator is displayed above the table content to signal that the table query has been scoped.
|
||||
|
||||
<AutoScreenshot name="tables/filters/indicators" alt="Table with filter indicators" version="3.x" />
|
||||
|
||||
By default, the label of the filter is used as the indicator. You can override this using the `indicator()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('is_admin')
|
||||
->label('Administrators only?')
|
||||
->indicator('Administrators')
|
||||
```
|
||||
|
||||
If you are using a [custom filter form](#custom-filter-forms), you should use [`indicateUsing()`](#custom-active-indicators) to display an active indicator.
|
||||
|
||||
Please note: if you do not have an indicator for your filter, then the badge-count of how many filters are active in the table will not include that filter.
|
||||
|
||||
### Custom active indicators
|
||||
|
||||
Not all indicators are simple, so you may need to use `indicateUsing()` to customize which indicators should be shown at any time.
|
||||
|
||||
For example, if you have a custom date filter, you may create a custom indicator that formats the selected date:
|
||||
|
||||
```php
|
||||
use Carbon\Carbon;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
|
||||
Filter::make('created_at')
|
||||
->form([DatePicker::make('date')])
|
||||
// ...
|
||||
->indicateUsing(function (array $data): ?string {
|
||||
if (! $data['date']) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return 'Created at ' . Carbon::parse($data['date'])->toFormattedDateString();
|
||||
})
|
||||
```
|
||||
|
||||
### Multiple active indicators
|
||||
|
||||
You may even render multiple indicators at once, by returning an array of `Indicator` objects. If you have different fields associated with different indicators, you should set the field using the `removeField()` method on the `Indicator` object to ensure that the correct field is reset when the filter is removed:
|
||||
|
||||
```php
|
||||
use Carbon\Carbon;
|
||||
use Filament\Forms\Components\DatePicker;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Filament\Tables\Filters\Indicator;
|
||||
|
||||
Filter::make('created_at')
|
||||
->form([
|
||||
DatePicker::make('from'),
|
||||
DatePicker::make('until'),
|
||||
])
|
||||
// ...
|
||||
->indicateUsing(function (array $data): array {
|
||||
$indicators = [];
|
||||
|
||||
if ($data['from'] ?? null) {
|
||||
$indicators[] = Indicator::make('Created from ' . Carbon::parse($data['from'])->toFormattedDateString())
|
||||
->removeField('from');
|
||||
}
|
||||
|
||||
if ($data['until'] ?? null) {
|
||||
$indicators[] = Indicator::make('Created until ' . Carbon::parse($data['until'])->toFormattedDateString())
|
||||
->removeField('until');
|
||||
}
|
||||
|
||||
return $indicators;
|
||||
})
|
||||
```
|
||||
|
||||
### Preventing indicators from being removed
|
||||
|
||||
You can prevent users from removing an indicator using `removable(false)` on an `Indicator` object:
|
||||
|
||||
```php
|
||||
use Carbon\Carbon;
|
||||
use Filament\Tables\Filters\Indicator;
|
||||
|
||||
Indicator::make('Created from ' . Carbon::parse($data['from'])->toFormattedDateString())
|
||||
->removable(false)
|
||||
```
|
||||
180
vendor/filament/tables/docs/04-filters/06-layout.md
vendored
Normal file
180
vendor/filament/tables/docs/04-filters/06-layout.md
vendored
Normal file
@@ -0,0 +1,180 @@
|
||||
---
|
||||
title: Filter layout
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Positioning filters into grid columns
|
||||
|
||||
To change the number of columns that filters may occupy, you may use the `filtersFormColumns()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->filtersFormColumns(3);
|
||||
}
|
||||
```
|
||||
|
||||
## Controlling the width of the filters dropdown
|
||||
|
||||
To customize the dropdown width, you may use the `filtersFormWidth()` method, and specify a width - `ExtraSmall`, `Small`, `Medium`, `Large`, `ExtraLarge`, `TwoExtraLarge`, `ThreeExtraLarge`, `FourExtraLarge`, `FiveExtraLarge`, `SixExtraLarge` or `SevenExtraLarge`. By default, the width is `ExtraSmall`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->filtersFormWidth(MaxWidth::FourExtraLarge);
|
||||
}
|
||||
```
|
||||
|
||||
## Controlling the maximum height of the filters dropdown
|
||||
|
||||
To add a maximum height to the filters' dropdown content, so that they scroll, you may use the `filtersFormMaxHeight()` method, passing a [CSS length](https://developer.mozilla.org/en-US/docs/Web/CSS/length):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->filtersFormMaxHeight('400px');
|
||||
}
|
||||
```
|
||||
|
||||
## Displaying filters in a modal
|
||||
|
||||
To render the filters in a modal instead of in a dropdown, you may use:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\FiltersLayout;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
], layout: FiltersLayout::Modal);
|
||||
}
|
||||
```
|
||||
|
||||
You may use the [trigger action API](getting-started#customizing-the-filters-trigger-action) to [customize the modal](../actions/modals), including [using a `slideOver()`](../actions/modals#using-a-slide-over-instead-of-a-modal).
|
||||
|
||||
## Displaying filters above the table content
|
||||
|
||||
To render the filters above the table content instead of in a dropdown, you may use:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\FiltersLayout;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
], layout: FiltersLayout::AboveContent);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/filters/above-content" alt="Table with filters above content" version="3.x" />
|
||||
|
||||
### Allowing filters above the table content to be collapsed
|
||||
|
||||
To allow the filters above the table content to be collapsed, you may use:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\FiltersLayout;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
], layout: FiltersLayout::AboveContentCollapsible);
|
||||
}
|
||||
```
|
||||
|
||||
## Displaying filters below the table content
|
||||
|
||||
To render the filters below the table content instead of in a dropdown, you may use:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\FiltersLayout;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
], layout: FiltersLayout::BelowContent);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/filters/below-content" alt="Table with filters below content" version="3.x" />
|
||||
|
||||
## Hiding the filter indicators
|
||||
|
||||
To hide the active filters indicators above the table, you may use `hiddenFilterIndicators()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->hiddenFilterIndicators();
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the filter form schema
|
||||
|
||||
You may customize the [form schema](../../forms/layout) of the entire filter form at once, in order to rearrange filters into your desired layout, and use any of the [layout components](../../forms/layout) available to forms. To do this, use the `filterFormSchema()` method, passing a closure function that receives the array of defined `$filters` that you can insert:
|
||||
|
||||
```php
|
||||
use Filament\Forms\Components\Section;
|
||||
use Filament\Tables\Filters\Filter;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->filters([
|
||||
Filter::make('is_featured'),
|
||||
Filter::make('published_at'),
|
||||
Filter::make('author'),
|
||||
])
|
||||
->filtersFormColumns(2)
|
||||
->filtersFormSchema(fn (array $filters): array => [
|
||||
Section::make('Visibility')
|
||||
->description('These filters affect the visibility of the records in the table.')
|
||||
->schema([
|
||||
$filters['is_featured'],
|
||||
$filters['published_at'],
|
||||
])
|
||||
->columns(2)
|
||||
->columnSpanFull(),
|
||||
$filters['author'],
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
In this example, we have put two of the filters inside a [section](../../forms/layout/section) component, and used the `columns()` method to specify that the section should have two columns. We have also used the `columnSpanFull()` method to specify that the section should span the full width of the filter form, which is also 2 columns wide. We have inserted each filter into the form schema by using the filter's name as the key in the `$filters` array.
|
||||
457
vendor/filament/tables/docs/05-actions.md
vendored
Normal file
457
vendor/filament/tables/docs/05-actions.md
vendored
Normal file
@@ -0,0 +1,457 @@
|
||||
---
|
||||
title: Actions
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
<LaracastsBanner
|
||||
title="Table Actions"
|
||||
description="Watch the Rapid Laravel Development with Filament series on Laracasts - it will teach you the basics of adding actions to Filament resource tables."
|
||||
url="https://laracasts.com/series/rapid-laravel-development-with-filament/episodes/11"
|
||||
series="rapid-laravel-development"
|
||||
/>
|
||||
|
||||
Filament's tables can use [Actions](../actions). They are buttons that can be added to the [end of any table row](#row-actions), or even in the [header](#header-actions) of a table. For instance, you may want an action to "create" a new record in the header, and then "edit" and "delete" actions on each row. [Bulk actions](#bulk-actions) can be used to execute code when records in the table are selected. Additionally, actions can be added to any [table column](#column-actions), such that each cell in that column is a trigger for your action.
|
||||
|
||||
It's highly advised that you read the documentation about [customizing action trigger buttons](../actions/trigger-button) and [action modals](../actions/modals) to that you are aware of the full capabilities of actions.
|
||||
|
||||
## Row actions
|
||||
|
||||
Action buttons can be rendered at the end of each table row. You can put them in the `$table->actions()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->actions([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Actions may be created using the static `make()` method, passing its unique name.
|
||||
|
||||
You can then pass a function to `action()` which executes the task, or a function to `url()` which creates a link:
|
||||
|
||||
```php
|
||||
use App\Models\Post;
|
||||
use Filament\Tables\Actions\Action;
|
||||
|
||||
Action::make('edit')
|
||||
->url(fn (Post $record): string => route('posts.edit', $record))
|
||||
->openUrlInNewTab()
|
||||
|
||||
Action::make('delete')
|
||||
->requiresConfirmation()
|
||||
->action(fn (Post $record) => $record->delete())
|
||||
```
|
||||
|
||||
All methods on the action accept callback functions, where you can access the current table `$record` that was clicked.
|
||||
|
||||
<AutoScreenshot name="tables/actions/simple" alt="Table with actions" version="3.x" />
|
||||
|
||||
### Positioning row actions before columns
|
||||
|
||||
By default, the row actions in your table are rendered in the final cell of each row. You may move them before the columns by using the `position` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\ActionsPosition;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->actions([
|
||||
// ...
|
||||
], position: ActionsPosition::BeforeColumns);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/before-columns" alt="Table with actions before columns" version="3.x" />
|
||||
|
||||
### Positioning row actions before the checkbox column
|
||||
|
||||
By default, the row actions in your table are rendered in the final cell of each row. You may move them before the checkbox column by using the `position` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\ActionsPosition;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->actions([
|
||||
// ...
|
||||
], position: ActionsPosition::BeforeCells);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/before-cells" alt="Table with actions before cells" version="3.x" />
|
||||
|
||||
### Accessing the selected table rows
|
||||
|
||||
You may want an action to be able to access all the selected rows in the table. Usually, this is done with a [bulk action](#bulk-actions) in the header of the table. However, you may want to do this with a row action, where the selected rows provide context for the action.
|
||||
|
||||
For example, you may want to have a row action that copies the row data to all the selected records. To force the table to be selectable, even if there aren't bulk actions defined, you need to use the `selectable()` method. To allow the action to access the selected records, you need to use the `accessSelectedRecords()` method. Then, you can use the `$selectedRecords` parameter in your action to access the selected records:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->selectable()
|
||||
->actions([
|
||||
Action::make('copyToSelected')
|
||||
->accessSelectedRecords()
|
||||
->action(function (Model $record, Collection $selectedRecords) {
|
||||
$selectedRecords->each(
|
||||
fn (Model $selectedRecord) => $selectedRecord->update([
|
||||
'is_active' => $record->is_active,
|
||||
]),
|
||||
);
|
||||
}),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Bulk actions
|
||||
|
||||
Tables also support "bulk actions". These can be used when the user selects rows in the table. Traditionally, when rows are selected, a "bulk actions" button appears in the top left corner of the table. When the user clicks this button, they are presented with a dropdown menu of actions to choose from. You can put them in the `$table->bulkActions()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->bulkActions([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Bulk actions may be created using the static `make()` method, passing its unique name. You should then pass a callback to `action()` which executes the task:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\BulkAction;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
BulkAction::make('delete')
|
||||
->requiresConfirmation()
|
||||
->action(fn (Collection $records) => $records->each->delete())
|
||||
```
|
||||
|
||||
The function allows you to access the current table `$records` that are selected. It is an Eloquent collection of models.
|
||||
|
||||
<AutoScreenshot name="tables/actions/bulk" alt="Table with bulk action" version="3.x" />
|
||||
|
||||
### Grouping bulk actions
|
||||
|
||||
You may use a `BulkActionGroup` object to [group multiple bulk actions together](../actions/grouping-actions) in a dropdown. Any bulk actions that remain outside the `BulkActionGroup` will be rendered next to the dropdown's trigger button:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\BulkAction;
|
||||
use Filament\Tables\Actions\BulkActionGroup;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->bulkActions([
|
||||
BulkActionGroup::make([
|
||||
BulkAction::make('delete')
|
||||
->requiresConfirmation()
|
||||
->action(fn (Collection $records) => $records->each->delete()),
|
||||
BulkAction::make('forceDelete')
|
||||
->requiresConfirmation()
|
||||
->action(fn (Collection $records) => $records->each->forceDelete()),
|
||||
]),
|
||||
BulkAction::make('export')->button()->action(fn (Collection $records) => ...),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, if all of your bulk actions are grouped, you can use the shorthand `groupedBulkActions()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\BulkAction;
|
||||
use Filament\Tables\Actions\BulkActionGroup;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groupedBulkActions([
|
||||
BulkAction::make('delete')
|
||||
->requiresConfirmation()
|
||||
->action(fn (Collection $records) => $records->each->delete()),
|
||||
BulkAction::make('forceDelete')
|
||||
->requiresConfirmation()
|
||||
->action(fn (Collection $records) => $records->each->forceDelete()),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### Deselecting records once a bulk action has finished
|
||||
|
||||
You may deselect the records after a bulk action has been executed using the `deselectRecordsAfterCompletion()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\BulkAction;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
|
||||
BulkAction::make('delete')
|
||||
->action(fn (Collection $records) => $records->each->delete())
|
||||
->deselectRecordsAfterCompletion()
|
||||
```
|
||||
|
||||
### Disabling bulk actions for some rows
|
||||
|
||||
You may conditionally disable bulk actions for a specific record:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->bulkActions([
|
||||
// ...
|
||||
])
|
||||
->checkIfRecordIsSelectableUsing(
|
||||
fn (Model $record): bool => $record->status === Status::Enabled,
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
### Preventing bulk-selection of all pages
|
||||
|
||||
The `selectCurrentPageOnly()` method can be used to prevent the user from easily bulk-selecting all records in the table at once, and instead only allows them to select one page at a time:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->bulkActions([
|
||||
// ...
|
||||
])
|
||||
->selectCurrentPageOnly();
|
||||
}
|
||||
```
|
||||
|
||||
## 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:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->headerActions([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
This is useful for things like "create" actions, which are not related to any specific table row, or bulk actions that need to be more visible.
|
||||
|
||||
<AutoScreenshot name="tables/actions/header" alt="Table with header actions" version="3.x" />
|
||||
|
||||
## Column actions
|
||||
|
||||
Actions can be added to columns, such that when a cell in that column is clicked, it acts as the trigger for an action. You can learn more about [column actions](columns/getting-started#running-actions) in the documentation.
|
||||
|
||||
## Prebuilt table actions
|
||||
|
||||
Filament includes several prebuilt actions and bulk actions that you can add to a table. Their aim is to simplify the most common Eloquent-related actions:
|
||||
|
||||
- [Create](../actions/prebuilt-actions/create)
|
||||
- [Edit](../actions/prebuilt-actions/edit)
|
||||
- [View](../actions/prebuilt-actions/view)
|
||||
- [Delete](../actions/prebuilt-actions/delete)
|
||||
- [Replicate](../actions/prebuilt-actions/replicate)
|
||||
- [Force-delete](../actions/prebuilt-actions/force-delete)
|
||||
- [Restore](../actions/prebuilt-actions/restore)
|
||||
- [Import](../actions/prebuilt-actions/import)
|
||||
- [Export](../actions/prebuilt-actions/export)
|
||||
|
||||
## Grouping actions
|
||||
|
||||
You may use an `ActionGroup` object to group multiple table actions together in a dropdown:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
use Filament\Tables\Actions\DeleteAction;
|
||||
use Filament\Tables\Actions\EditAction;
|
||||
use Filament\Tables\Actions\ViewAction;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->actions([
|
||||
ActionGroup::make([
|
||||
ViewAction::make(),
|
||||
EditAction::make(),
|
||||
DeleteAction::make(),
|
||||
]),
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group" alt="Table with action group" version="3.x" />
|
||||
|
||||
### Choosing an action group button style
|
||||
|
||||
Out of the box, action group triggers have 3 styles - "button", "link", and "icon button".
|
||||
|
||||
"Icon button" triggers are circular buttons with an [icon](#setting-the-action-group-button-icon) and no label. Usually, this is the default button style, but you can use it manually with the `iconButton()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])->iconButton()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-icon-button" alt="Table with icon button action group" version="3.x" />
|
||||
|
||||
"Button" triggers have a background color, label, and optionally an [icon](#setting-the-action-group-button-icon). You can switch to that style with the `button()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])
|
||||
->button()
|
||||
->label('Actions')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-button" alt="Table with button action group" version="3.x" />
|
||||
|
||||
"Link" triggers have no background color. They must have a label and optionally an [icon](#setting-the-action-group-button-icon). They look like a link that you might find embedded within text. You can switch to that style with the `link()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])
|
||||
->link()
|
||||
->label('Actions')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-link" alt="Table with link action group" version="3.x" />
|
||||
|
||||
### Setting the action group button icon
|
||||
|
||||
You may set the [icon](https://blade-ui-kit.com/blade-icons?set=1#search) of the action group button using the `icon()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])->icon('heroicon-m-ellipsis-horizontal');
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-icon" alt="Table with customized action group icon" version="3.x" />
|
||||
|
||||
### Setting the action group button color
|
||||
|
||||
You may set the color of the action group button using the `color()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])->color('info');
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-color" alt="Table with customized action group color" version="3.x" />
|
||||
|
||||
### Setting the action group button size
|
||||
|
||||
Buttons come in 3 sizes - `sm`, `md` or `lg`. You may set the size of the action group button using the `size()` method:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\ActionSize;
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])->size(ActionSize::Small);
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-small" alt="Table with small action group" version="3.x" />
|
||||
|
||||
### Setting the action group tooltip
|
||||
|
||||
You may set the tooltip of the action group using the `tooltip()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\ActionGroup;
|
||||
|
||||
ActionGroup::make([
|
||||
// ...
|
||||
])->tooltip('Actions');
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/actions/group-tooltip" alt="Table with action group tooltip" version="3.x" />
|
||||
|
||||
## Table action utility injection
|
||||
|
||||
All actions, not just table actions, have access to [many utilities](../actions/advanced#action-utility-injection) within the vast majority of configuration methods. However, in addition to those, table actions have access to a few more:
|
||||
|
||||
### Injecting the current Eloquent record
|
||||
|
||||
If you wish to access the current Eloquent record of the action, define a `$record` parameter:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
function (Model $record) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
Be aware that bulk actions, header actions, and empty state actions do not have access to the `$record`, as they are not related to any table row.
|
||||
|
||||
### Injecting the current Eloquent model class
|
||||
|
||||
If you wish to access the current Eloquent model class of the table, define a `$model` parameter:
|
||||
|
||||
```php
|
||||
function (string $model) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
### Injecting the current table instance
|
||||
|
||||
If you wish to access the current table configuration instance that the action belongs to, define a `$table` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
function (Table $table) {
|
||||
// ...
|
||||
}
|
||||
```
|
||||
468
vendor/filament/tables/docs/06-layout.md
vendored
Normal file
468
vendor/filament/tables/docs/06-layout.md
vendored
Normal file
@@ -0,0 +1,468 @@
|
||||
---
|
||||
title: Layout
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## The problem with traditional table layouts
|
||||
|
||||
Traditional tables are notorious for having bad responsiveness. On mobile, there is only so much flexibility you have when rendering content that is horizontally long:
|
||||
|
||||
- Allow the user to scroll horizontally to see more table content
|
||||
- Hide non-important columns on smaller devices
|
||||
|
||||
Both of these are possible with Filament. Tables automatically scroll horizontally when they overflow anyway, and you may choose to show and hide columns based on the responsive [breakpoint](https://tailwindcss.com/docs/responsive-design#overview) of the browser. To do this, you may use a `visibleFrom()` or `hiddenFrom()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('slug')
|
||||
->visibleFrom('md')
|
||||
```
|
||||
|
||||
This is fine, but there is still a glaring issue - **on mobile, the user is unable to see much information in a table row at once without scrolling**.
|
||||
|
||||
Thankfully, Filament lets you build responsive table-like interfaces, without touching HTML or CSS. These layouts let you define exactly where content appears in a table row, at each responsive breakpoint.
|
||||
|
||||
<AutoScreenshot name="tables/layout/demo" alt="Table with responsive layout" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/demo/mobile" alt="Table with responsive layout on mobile" version="3.x" />
|
||||
|
||||
## Allowing columns to stack on mobile
|
||||
|
||||
Let's introduce a component - `Split`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('email'),
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/layout/split" alt="Table with a split layout" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/split/mobile" alt="Table with a split layout on mobile" version="3.x" />
|
||||
|
||||
A `Split` component is used to wrap around columns, and allow them to stack on mobile.
|
||||
|
||||
By default, columns within a split will appear aside each other all the time. However, you may choose a responsive [breakpoint](https://tailwindcss.com/docs/responsive-design#overview) where this behavior starts `from()`. Before this point, the columns will stack on top of each other:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('email'),
|
||||
])->from('md')
|
||||
```
|
||||
|
||||
In this example, the columns will only appear horizontally aside each other from `md` [breakpoint](https://tailwindcss.com/docs/responsive-design#overview) devices onwards:
|
||||
|
||||
<AutoScreenshot name="tables/layout/split-desktop" alt="Table with a split layout on desktop" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/split-desktop/mobile" alt="Table with a stacked layout on mobile" version="3.x" />
|
||||
|
||||
### Preventing a column from creating whitespace
|
||||
|
||||
Splits, like table columns, will automatically adjust their whitespace to ensure that each column has proportionate separation. You can prevent this from happening, using `grow(false)`. In this example, we will make sure that the avatar image will sit tightly against the name column:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular()
|
||||
->grow(false),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
TextColumn::make('email'),
|
||||
])
|
||||
```
|
||||
|
||||
The other columns which are allowed to `grow()` will adjust to consume the newly-freed space:
|
||||
|
||||
<AutoScreenshot name="tables/layout/grow-disabled" alt="Table with a column that doesn't grow" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/grow-disabled/mobile" alt="Table with a column that doesn't grow on mobile" version="3.x" />
|
||||
|
||||
### Stacking within a split
|
||||
|
||||
Inside a split, you may stack multiple columns on top of each other vertically. This allows you to display more data inside fewer columns on desktop:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Stack::make([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
]),
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/layout/stack" alt="Table with a stack" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/stack/mobile" alt="Table with a stack on mobile" version="3.x" />
|
||||
|
||||
#### Hiding a stack on mobile
|
||||
|
||||
Similar to individual columns, you may choose to hide a stack based on the responsive [breakpoint](https://tailwindcss.com/docs/responsive-design#overview) of the browser. To do this, you may use a `visibleFrom()` method:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Stack::make([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])->visibleFrom('md'),
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/layout/stack-hidden-on-mobile" alt="Table with a stack" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/stack-hidden-on-mobile/mobile" alt="Table with no stack on mobile" version="3.x" />
|
||||
|
||||
#### Aligning stacked content
|
||||
|
||||
By default, columns within a stack are aligned to the start. You may choose to align columns within a stack to the `Alignment::Center` or `Alignment::End`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
Stack::make([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone')
|
||||
->grow(false),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
->grow(false),
|
||||
])
|
||||
->alignment(Alignment::End)
|
||||
->visibleFrom('md'),
|
||||
])
|
||||
```
|
||||
|
||||
Ensure that the columns within the stack have `grow(false)` set, otherwise they will stretch to fill the entire width of the stack and follow their own alignment configuration instead of the stack's.
|
||||
|
||||
<AutoScreenshot name="tables/layout/stack-aligned-right" alt="Table with a stack aligned right" version="3.x" />
|
||||
|
||||
#### Spacing stacked content
|
||||
|
||||
By default, stacked content has no vertical padding between columns. To add some, you may use the `space()` method, which accepts either `1`, `2`, or `3`, corresponding to [Tailwind's spacing scale](https://tailwindcss.com/docs/space):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Stack::make([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])->space(1)
|
||||
```
|
||||
|
||||
## Controlling column width using a grid
|
||||
|
||||
Sometimes, using a `Split` creates inconsistent widths when columns contain lots of content. This is because it's powered by Flexbox internally and each row individually controls how much space is allocated to content.
|
||||
|
||||
Instead, you may use a `Grid` layout, which uses CSS Grid Layout to allow you to control column widths:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Layout\Grid;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Grid::make([
|
||||
'lg' => 2,
|
||||
])
|
||||
->schema([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])
|
||||
```
|
||||
|
||||
These columns will always consume equal width within the grid, from the `lg` [breakpoint](https://tailwindcss.com/docs/responsive-design#overview).
|
||||
|
||||
You may choose to customize the number of columns within the grid at other breakpoints:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Layout\Grid;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Grid::make([
|
||||
'lg' => 2,
|
||||
'2xl' => 4,
|
||||
])
|
||||
->schema([
|
||||
Stack::make([
|
||||
TextColumn::make('name'),
|
||||
TextColumn::make('job'),
|
||||
]),
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])
|
||||
```
|
||||
|
||||
And you can even control how many grid columns will be consumed by each component at each [breakpoint](https://tailwindcss.com/docs/responsive-design#overview):
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Layout\Grid;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Grid::make([
|
||||
'lg' => 2,
|
||||
'2xl' => 5,
|
||||
])
|
||||
->schema([
|
||||
Stack::make([
|
||||
TextColumn::make('name'),
|
||||
TextColumn::make('job'),
|
||||
])->columnSpan([
|
||||
'lg' => 'full',
|
||||
'2xl' => 2,
|
||||
]),
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone')
|
||||
->columnSpan([
|
||||
'2xl' => 2,
|
||||
]),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])
|
||||
```
|
||||
|
||||
## Collapsible content
|
||||
|
||||
When you're using a column layout like split or stack, then you can also add collapsible content. This is very useful for when you don't want to display all data in the table at once, but still want it to be accessible to the user if they need to access it, without navigating away.
|
||||
|
||||
Split and stack components can be made `collapsible()`, but there is also a dedicated `Panel` component that provides a pre-styled background color and border radius, to separate the collapsible content from the rest:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Panel;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
[
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
]),
|
||||
Panel::make([
|
||||
Stack::make([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
]),
|
||||
])->collapsible(),
|
||||
]
|
||||
```
|
||||
|
||||
You can expand a panel by default using the `collapsed(false)` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Layout\Panel;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
Panel::make([
|
||||
Split::make([
|
||||
TextColumn::make('phone')
|
||||
->icon('heroicon-m-phone'),
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])->from('md'),
|
||||
])->collapsed(false)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/layout/collapsible" alt="Table with collapsible content" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/collapsible/mobile" alt="Table with collapsible content on mobile" version="3.x" />
|
||||
|
||||
## Arranging records into a grid
|
||||
|
||||
Sometimes, you may find that your data fits into a grid format better than a list. Filament can handle that too!
|
||||
|
||||
Simply use the `$table->contentGrid()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Layout\Stack;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
Stack::make([
|
||||
// Columns
|
||||
]),
|
||||
])
|
||||
->contentGrid([
|
||||
'md' => 2,
|
||||
'xl' => 3,
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
In this example, the rows will be displayed in a grid:
|
||||
|
||||
- On mobile, they will be displayed in 1 column only.
|
||||
- From the `md` [breakpoint](https://tailwindcss.com/docs/responsive-design#overview), they will be displayed in 2 columns.
|
||||
- From the `xl` [breakpoint](https://tailwindcss.com/docs/responsive-design#overview) onwards, they will be displayed in 3 columns.
|
||||
|
||||
These settings are fully customizable, any [breakpoint](https://tailwindcss.com/docs/responsive-design#overview) from `sm` to `2xl` can contain `1` to `12` columns.
|
||||
|
||||
<AutoScreenshot name="tables/layout/grid" alt="Table with grid layout" version="3.x" />
|
||||
|
||||
<AutoScreenshot name="tables/layout/grid/mobile" alt="Table with grid layout on mobile" version="3.x" />
|
||||
|
||||
## Custom HTML
|
||||
|
||||
You may add custom HTML to your table using a `View` component. It can even be `collapsible()`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\Layout\View;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
[
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
]),
|
||||
View::make('users.table.collapsible-row-content')
|
||||
->collapsible(),
|
||||
]
|
||||
```
|
||||
|
||||
Now, create a `/resources/views/users/table/collapsible-row-content.blade.php` file, and add in your HTML. You can access the table record using `$getRecord()`:
|
||||
|
||||
```blade
|
||||
<p class="px-4 py-3 bg-gray-100 rounded-lg">
|
||||
<span class="font-medium">
|
||||
Email address:
|
||||
</span>
|
||||
|
||||
<span>
|
||||
{{ $getRecord()->email }}
|
||||
</span>
|
||||
</p>
|
||||
```
|
||||
|
||||
### Embedding other components
|
||||
|
||||
You could even pass in columns or other layout components to the `components()` method:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Tables\Columns\Layout\Split;
|
||||
use Filament\Tables\Columns\Layout\View;
|
||||
use Filament\Tables\Columns\ImageColumn;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
[
|
||||
Split::make([
|
||||
ImageColumn::make('avatar')
|
||||
->circular(),
|
||||
TextColumn::make('name')
|
||||
->weight(FontWeight::Bold)
|
||||
->searchable()
|
||||
->sortable(),
|
||||
]),
|
||||
View::make('users.table.collapsible-row-content')
|
||||
->components([
|
||||
TextColumn::make('email')
|
||||
->icon('heroicon-m-envelope'),
|
||||
])
|
||||
->collapsible(),
|
||||
]
|
||||
```
|
||||
|
||||
Now, render the components in the Blade file:
|
||||
|
||||
```blade
|
||||
<div class="px-4 py-3 bg-gray-100 rounded-lg">
|
||||
<x-filament-tables::columns.layout
|
||||
:components="$getComponents()"
|
||||
:record="$getRecord()"
|
||||
:record-key="$recordKey"
|
||||
/>
|
||||
</div>
|
||||
```
|
||||
360
vendor/filament/tables/docs/07-summaries.md
vendored
Normal file
360
vendor/filament/tables/docs/07-summaries.md
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
---
|
||||
title: Summaries
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
You may render a "summary" section below your table content. This is great for displaying the results of calculations such as averages, sums, counts, and ranges of the data in your table.
|
||||
|
||||
By default, there will be a single summary line for the current page of data, and an additional summary line for the totals for all data if multiple pages are available. You may also add summaries for [groups](grouping) of records, see ["Summarising groups of rows"](#summarising-groups-of-rows).
|
||||
|
||||
"Summarizer" objects can be added to any [table column](columns) using the `summarize()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(Average::make())
|
||||
```
|
||||
|
||||
Multiple "summarizers" may be added to the same column:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\Summarizers\Range;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->numeric()
|
||||
->summarize([
|
||||
Average::make(),
|
||||
Range::make(),
|
||||
])
|
||||
```
|
||||
|
||||
> The first column in a table may not use summarizers. That column is used to render the heading and subheading/s of the summary section.
|
||||
|
||||
<AutoScreenshot name="tables/summaries" alt="Table with summaries" version="3.x" />
|
||||
|
||||
## Available summarizers
|
||||
|
||||
Filament ships with four types of summarizer:
|
||||
|
||||
- [Average](#average)
|
||||
- [Count](#count)
|
||||
- [Range](#range)
|
||||
- [Sum](#sum)
|
||||
|
||||
You may also [create your own custom summarizers](#custom-summaries) to display data in whatever way you wish.
|
||||
|
||||
## Average
|
||||
|
||||
Average can be used to calculate the average of all values in the dataset:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(Average::make())
|
||||
```
|
||||
|
||||
In this example, all ratings in the table will be added together and divided by the number of ratings.
|
||||
|
||||
## Count
|
||||
|
||||
Count can be used to find the total number of values in the dataset. Unless you just want to calculate the number of rows, you will probably want to [scope the dataset](#scoping-the-dataset) as well:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\Summarizers\Count;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
IconColumn::make('is_published')
|
||||
->boolean()
|
||||
->summarize(
|
||||
Count::make()->query(fn (Builder $query) => $query->where('is_published', true)),
|
||||
),
|
||||
```
|
||||
|
||||
In this example, the table will calculate how many posts are published.
|
||||
|
||||
### Counting the occurrence of icons
|
||||
|
||||
Using a count on an [icon column](columns/icon) allows you to use the `icons()` method, which gives the user a visual representation of how many of each icon are in the table:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\Summarizers\Count;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
IconColumn::make('is_published')
|
||||
->boolean()
|
||||
->summarize(Count::make()->icons()),
|
||||
```
|
||||
|
||||
## Range
|
||||
|
||||
Range can be used to calculate the minimum and maximum value in the dataset:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Range;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->summarize(Range::make())
|
||||
```
|
||||
|
||||
In this example, the minimum and maximum price in the table will be found.
|
||||
|
||||
### Date range
|
||||
|
||||
You may format the range as dates using the `minimalDateTimeDifference()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Range;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('created_at')
|
||||
->dateTime()
|
||||
->summarize(Range::make()->minimalDateTimeDifference())
|
||||
```
|
||||
|
||||
This method will present the minimal difference between the minimum and maximum date. For example:
|
||||
|
||||
- If the minimum and maximum dates are different days, only the dates will be displayed.
|
||||
- If the minimum and maximum dates are on the same day at different times, both the date and time will be displayed.
|
||||
- If the minimum and maximum dates and times are identical, they will only appear once.
|
||||
|
||||
### Text range
|
||||
|
||||
You may format the range as text using the `minimalTextualDifference()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Range;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('sku')
|
||||
->summarize(Range::make()->minimalTextualDifference())
|
||||
```
|
||||
|
||||
This method will present the minimal difference between the minimum and maximum. For example:
|
||||
|
||||
- If the minimum and maximum start with different letters, only the first letters will be displayed.
|
||||
- If the minimum and maximum start with the same letter, more of the text will be rendered until a difference is found.
|
||||
- If the minimum and maximum are identical, they will only appear once.
|
||||
|
||||
### Including null values in the range
|
||||
|
||||
By default, we will exclude null values from the range. If you would like to include them, you may use the `excludeNull(false)` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Range;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('sku')
|
||||
->summarize(Range::make()->excludeNull(false))
|
||||
```
|
||||
|
||||
## Sum
|
||||
|
||||
Sum can be used to calculate the total of all values in the dataset:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Sum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->summarize(Sum::make())
|
||||
```
|
||||
|
||||
In this example, all prices in the table will be added together.
|
||||
|
||||
## Setting a label
|
||||
|
||||
You may set a summarizer's label using the `label()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Sum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->summarize(Sum::make()->label('Total'))
|
||||
```
|
||||
|
||||
## Scoping the dataset
|
||||
|
||||
You may apply a database query scope to a summarizer's dataset using the `query()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(
|
||||
Average::make()->query(fn (Builder $query) => $query->where('is_published', true)),
|
||||
),
|
||||
```
|
||||
|
||||
In this example, now only rows where `is_published` is set to `true` will be used to calculate the average.
|
||||
|
||||
This feature is especially useful with the [count](#count) summarizer, as it can count how many records in the dataset pass a test:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\IconColumn;
|
||||
use Filament\Tables\Columns\Summarizers\Count;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
IconColumn::make('is_published')
|
||||
->boolean()
|
||||
->summarize(
|
||||
Count::make()->query(fn (Builder $query) => $query->where('is_published', true)),
|
||||
),
|
||||
```
|
||||
|
||||
In this example, the table will calculate how many posts are published.
|
||||
|
||||
## Formatting
|
||||
|
||||
### Number formatting
|
||||
|
||||
The `numeric()` method allows you to format an entry as a number:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(Average::make()->numeric())
|
||||
```
|
||||
|
||||
If you would like to customize the number of decimal places used to format the number with, you can use the `decimalPlaces` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(Average::make()->numeric(
|
||||
decimalPlaces: 0,
|
||||
))
|
||||
```
|
||||
|
||||
By default, your app's locale will be used to format the number suitably. If you would like to customize the locale used, you can pass it to the `locale` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(Average::make()->numeric(
|
||||
locale: 'nl',
|
||||
))
|
||||
```
|
||||
|
||||
Alternatively, you can set the default locale used across your app using the `Number::useLocale()` method in the `boot()` method of a service provider:
|
||||
|
||||
```php
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
Number::useLocale('nl');
|
||||
```
|
||||
|
||||
### Currency formatting
|
||||
|
||||
The `money()` method allows you to easily format monetary values, in any currency:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Sum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->summarize(Sum::make()->money('EUR'))
|
||||
```
|
||||
|
||||
There is also a `divideBy` argument for `money()` that allows you to divide the original value by a number before formatting it. This could be useful if your database stores the price in cents, for example:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Sum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->summarize(Sum::make()->money('EUR', divideBy: 100))
|
||||
```
|
||||
|
||||
By default, your app's locale will be used to format the money suitably. If you would like to customize the locale used, you can pass it to the `locale` argument:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('price')
|
||||
->summarize(Sum::make()->money('EUR', locale: 'nl'))
|
||||
```
|
||||
|
||||
Alternatively, you can set the default locale used across your app using the `Number::useLocale()` method in the `boot()` method of a service provider:
|
||||
|
||||
```php
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
Number::useLocale('nl');
|
||||
```
|
||||
|
||||
### Limiting text length
|
||||
|
||||
You may `limit()` the length of the summary's value:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Range;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('sku')
|
||||
->summarize(Range::make()->limit(5))
|
||||
```
|
||||
|
||||
## Custom summaries
|
||||
|
||||
You may create a custom summary by returning the value from the `using()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Summarizer;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Illuminate\Database\Query\Builder;
|
||||
|
||||
TextColumn::make('name')
|
||||
->summarize(Summarizer::make()
|
||||
->label('First last name')
|
||||
->using(fn (Builder $query): string => $query->min('last_name')))
|
||||
```
|
||||
|
||||
The callback has access to the database `$query` builder instance to perform calculations with. It should return the value to display in the table.
|
||||
|
||||
## Summarising groups of rows
|
||||
|
||||
You can use summaries with [groups](grouping) to display a summary of the records inside a group. This works automatically if you choose to add a summariser to a column in a grouped table.
|
||||
|
||||
### Hiding the grouped rows and showing the summary only
|
||||
|
||||
You may hide the rows inside groups and just show the summary of each group using the `groupsOnly()` method. This is very useful in many reporting scenarios.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Sum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('views_count')
|
||||
->summarize(Sum::make()),
|
||||
TextColumn::make('likes_count')
|
||||
->summarize(Sum::make()),
|
||||
])
|
||||
->defaultGroup('category')
|
||||
->groupsOnly();
|
||||
}
|
||||
```
|
||||
354
vendor/filament/tables/docs/08-grouping.md
vendored
Normal file
354
vendor/filament/tables/docs/08-grouping.md
vendored
Normal file
@@ -0,0 +1,354 @@
|
||||
---
|
||||
title: Grouping rows
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
You may allow users to group table rows together using a common attribute. This is useful for displaying lots of data in a more organized way.
|
||||
|
||||
Groups can be set up using the name of the attribute to group by (e.g. `'status'`), or a `Group` object which allows you to customize the behavior of that grouping (e.g. `Group::make('status')->collapsible()`).
|
||||
|
||||
## Grouping rows by default
|
||||
|
||||
You may want to always group posts by a specific attribute. To do this, pass the group to the `defaultGroup()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->defaultGroup('status');
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/grouping" alt="Table with grouping" version="3.x" />
|
||||
|
||||
## Allowing users to choose between groupings
|
||||
|
||||
You may also allow users to pick between different groupings, by passing them in an array to the `groups()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
'status',
|
||||
'category',
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
You can use both `groups()` and `defaultGroup()` together to allow users to choose between different groupings, but have a default grouping set:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
'status',
|
||||
'category',
|
||||
])
|
||||
->defaultGroup('status');
|
||||
}
|
||||
```
|
||||
|
||||
## Grouping by a relationship attribute
|
||||
|
||||
You can also group by a relationship attribute using dot-syntax. For example, if you have an `author` relationship which has a `name` attribute, you can use `author.name` as the name of the attribute:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
'author.name',
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Setting a grouping label
|
||||
|
||||
By default, the label of the grouping will be generated based on the attribute. You may customize it with a `Group` object, using the `label()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('author.name')
|
||||
->label('Author name'),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Setting a group title
|
||||
|
||||
By default, the title of a group will be the value of the attribute. You may customize it by returning a new title from the `getTitleFromRecordUsing()` method of a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->getTitleFromRecordUsing(fn (Post $record): string => ucfirst($record->status->getLabel())),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
### Disabling the title label prefix
|
||||
|
||||
By default, the title is prefixed with the label of the group. To disable this prefix, utilize the `titlePrefixedWithLabel(false)` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->titlePrefixedWithLabel(false),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Setting a group description
|
||||
|
||||
You may also set a description for a group, which will be displayed underneath the group title. To do this, use the `getDescriptionFromRecordUsing()` method on a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->getDescriptionFromRecordUsing(fn (Post $record): string => $record->status->getDescription()),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/grouping-descriptions" alt="Table with group descriptions" version="3.x" />
|
||||
|
||||
## Setting a group key
|
||||
|
||||
By default, the key of a group will be the value of the attribute. It is used internally as a raw identifier of that group, instead of the [title](#setting-a-group-title). You may customize it by returning a new key from the `getKeyFromRecordUsing()` method of a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->getKeyFromRecordUsing(fn (Post $record): string => $record->status->value),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Date groups
|
||||
|
||||
When using a date-time column as a group, you may want to group by the date only, and ignore the time. To do this, use the `date()` method on a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('created_at')
|
||||
->date(),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Collapsible groups
|
||||
|
||||
You can allow rows inside a group to be collapsed underneath their group title. To enable this, use a `Group` object with the `collapsible()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('author.name')
|
||||
->collapsible(),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Summarising groups
|
||||
|
||||
You can use [summaries](summaries) with groups to display a summary of the records inside a group. This works automatically if you choose to add a summariser to a column in a grouped table.
|
||||
|
||||
### Hiding the grouped rows and showing the summary only
|
||||
|
||||
You may hide the rows inside groups and just show the summary of each group using the `groupsOnly()` method. This is very useful in many reporting scenarios.
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Sum;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->columns([
|
||||
TextColumn::make('views_count')
|
||||
->summarize(Sum::make()),
|
||||
TextColumn::make('likes_count')
|
||||
->summarize(Sum::make()),
|
||||
])
|
||||
->defaultGroup('category')
|
||||
->groupsOnly();
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the Eloquent query ordering behavior
|
||||
|
||||
Some features require the table to be able to order an Eloquent query according to a group. You can customize how we do this using the `orderQueryUsing()` method on a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->orderQueryUsing(fn (Builder $query, string $direction) => $query->orderBy('status', $direction)),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the Eloquent query scoping behavior
|
||||
|
||||
Some features require the table to be able to scope an Eloquent query according to a group. You can customize how we do this using the `scopeQueryByKeyUsing()` method on a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->scopeQueryByKeyUsing(fn (Builder $query, string $key) => $query->where('status', $key)),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the Eloquent query grouping behavior
|
||||
|
||||
Some features require the table to be able to group an Eloquent query according to a group. You can customize how we do this using the `groupQueryUsing()` method on a `Group` object:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Grouping\Group;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
Group::make('status')
|
||||
->groupQueryUsing(fn (Builder $query) => $query->groupBy('status')),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the groups dropdown trigger action
|
||||
|
||||
To customize the groups dropdown trigger button, you may use the `groupRecordsTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](../actions/trigger-button) can be used:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
// ...
|
||||
])
|
||||
->groupRecordsTriggerAction(
|
||||
fn (Action $action) => $action
|
||||
->button()
|
||||
->label('Group records'),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
## Using the grouping settings dropdown on desktop
|
||||
|
||||
By default, the grouping settings dropdown will only be shown on mobile devices. On desktop devices, the grouping settings are in the header of the table. You can enable the dropdown on desktop devices too by using the `groupingSettingsInDropdownOnDesktop()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->groups([
|
||||
// ...
|
||||
])
|
||||
->groupingSettingsInDropdownOnDesktop();
|
||||
}
|
||||
```
|
||||
|
||||
## Hiding the grouping settings
|
||||
|
||||
You can hide the grouping settings interface using the `groupingSettingsHidden()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->defaultGroup('status')
|
||||
->groupingSettingsHidden();
|
||||
}
|
||||
```
|
||||
|
||||
### Hiding the grouping direction setting only
|
||||
|
||||
You can hide the grouping direction select interface using the `groupingDirectionSettingHidden()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->defaultGroup('status')
|
||||
->groupingDirectionSettingHidden();
|
||||
}
|
||||
```
|
||||
96
vendor/filament/tables/docs/09-empty-state.md
vendored
Normal file
96
vendor/filament/tables/docs/09-empty-state.md
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
---
|
||||
title: Empty state
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The table's "empty state" is rendered when there are no rows in the table.
|
||||
|
||||
<AutoScreenshot name="tables/empty-state" alt="Table with empty state" version="3.x" />
|
||||
|
||||
## Setting the empty state heading
|
||||
|
||||
To customize the heading of the empty state, use the `emptyStateHeading()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->emptyStateHeading('No posts yet');
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/empty-state-heading" alt="Table with customized empty state heading" version="3.x" />
|
||||
|
||||
## Setting the empty state description
|
||||
|
||||
To customize the description of the empty state, use the `emptyStateDescription()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->emptyStateDescription('Once you write your first post, it will appear here.');
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/empty-state-description" alt="Table with empty state description" version="3.x" />
|
||||
|
||||
## Setting the empty state icon
|
||||
|
||||
To customize the [icon](https://blade-ui-kit.com/blade-icons?set=1#search) of the empty state, use the `emptyStateIcon()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->emptyStateIcon('heroicon-o-bookmark');
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/empty-state-icon" alt="Table with customized empty state icon" version="3.x" />
|
||||
|
||||
## Adding empty state actions
|
||||
|
||||
You can add [Actions](actions) to the empty state to prompt users to take action. Pass these to the `emptyStateActions()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->emptyStateActions([
|
||||
Action::make('create')
|
||||
->label('Create post')
|
||||
->url(route('posts.create'))
|
||||
->icon('heroicon-m-plus')
|
||||
->button(),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/empty-state-actions" alt="Table with empty state actions" version="3.x" />
|
||||
|
||||
## Using a custom empty state view
|
||||
|
||||
You may use a completely custom empty state view by passing it to the `emptyState()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->emptyState(view('tables.posts.empty-state'));
|
||||
}
|
||||
```
|
||||
438
vendor/filament/tables/docs/10-advanced.md
vendored
Normal file
438
vendor/filament/tables/docs/10-advanced.md
vendored
Normal file
@@ -0,0 +1,438 @@
|
||||
---
|
||||
title: Advanced
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Pagination
|
||||
|
||||
### Disabling pagination
|
||||
|
||||
By default, tables will be paginated. To disable this, you should use the `$table->paginated(false)` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->paginated(false);
|
||||
}
|
||||
```
|
||||
|
||||
### Customizing the pagination options
|
||||
|
||||
You may customize the options for the paginated records per page select by passing them to the `paginated()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->paginated([10, 25, 50, 100, 'all']);
|
||||
}
|
||||
```
|
||||
|
||||
### Customizing the default pagination page option
|
||||
|
||||
To customize the default number of records shown use the `defaultPaginationPageOption()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->defaultPaginationPageOption(25);
|
||||
}
|
||||
```
|
||||
|
||||
### Preventing query string conflicts with the pagination page
|
||||
|
||||
By default, Livewire stores the pagination state in a `page` parameter of the URL query string. If you have multiple tables on the same page, this will mean that the pagination state of one table may be overwritten by the state of another table.
|
||||
|
||||
To fix this, you may define a `$table->queryStringIdentifier()`, to return a unique query string identifier for that table:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->queryStringIdentifier('users');
|
||||
}
|
||||
```
|
||||
|
||||
### Displaying links to the first and the last pagination page
|
||||
|
||||
To add "extreme" links to the first and the last page using the `extremePaginationLinks()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->extremePaginationLinks();
|
||||
}
|
||||
```
|
||||
|
||||
### Using simple pagination
|
||||
|
||||
You may use simple pagination by overriding `paginateTableQuery()` method.
|
||||
|
||||
First, locate your Livewire component. If you're using a resource from the Panel Builder and you want to add simple pagination to the List page, you'll want to open the `Pages/List.php` file in the resource, not the resource class itself.
|
||||
|
||||
```php
|
||||
use Illuminate\Contracts\Pagination\Paginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
protected function paginateTableQuery(Builder $query): Paginator
|
||||
{
|
||||
return $query->simplePaginate(($this->getTableRecordsPerPage() === 'all') ? $query->count() : $this->getTableRecordsPerPage());
|
||||
}
|
||||
```
|
||||
|
||||
### Using cursor pagination
|
||||
|
||||
You may use cursor pagination by overriding `paginateTableQuery()` method.
|
||||
|
||||
First, locate your Livewire component. If you're using a resource from the Panel Builder and you want to add simple pagination to the List page, you'll want to open the `Pages/List.php` file in the resource, not the resource class itself.
|
||||
|
||||
```php
|
||||
use Illuminate\Contracts\Pagination\CursorPaginator;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
protected function paginateTableQuery(Builder $query): CursorPaginator
|
||||
{
|
||||
return $query->cursorPaginate(($this->getTableRecordsPerPage() === 'all') ? $query->count() : $this->getTableRecordsPerPage());
|
||||
}
|
||||
```
|
||||
|
||||
## Record URLs (clickable rows)
|
||||
|
||||
You may allow table rows to be completely clickable by using the `$table->recordUrl()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordUrl(
|
||||
fn (Model $record): string => route('posts.edit', ['record' => $record]),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
In this example, clicking on each post will take you to the `posts.edit` route.
|
||||
|
||||
You may also open the URL in a new tab:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->openRecordUrlInNewTab();
|
||||
}
|
||||
```
|
||||
|
||||
If you'd like to [override the URL](columns/getting-started#opening-urls) for a specific column, or instead [run an action](columns/getting-started#running-actions) when a column is clicked, see the [columns documentation](columns/getting-started#opening-urls).
|
||||
|
||||
## Reordering records
|
||||
|
||||
To allow the user to reorder records using drag and drop in your table, you can use the `$table->reorderable()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->reorderable('sort');
|
||||
}
|
||||
```
|
||||
|
||||
If you're using mass assignment protection on your model, you will also need to add the `sort` attribute to the `$fillable` array there.
|
||||
|
||||
When making the table reorderable, a new button will be available on the table to toggle reordering.
|
||||
|
||||
<AutoScreenshot name="tables/reordering" alt="Table with reorderable rows" version="3.x" />
|
||||
|
||||
The `reorderable()` method accepts the name of a column to store the record order in. If you use something like [`spatie/eloquent-sortable`](https://github.com/spatie/eloquent-sortable) with an order column such as `order_column`, you may use this instead:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->reorderable('order_column');
|
||||
}
|
||||
```
|
||||
|
||||
The `reorderable()` method also accepts a boolean condition as its second parameter, allowing you to conditionally enable reordering:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->reorderable('sort', auth()->user()->isAdmin());
|
||||
}
|
||||
```
|
||||
|
||||
### Enabling pagination while reordering
|
||||
|
||||
Pagination will be disabled in reorder mode to allow you to move records between pages. It is generally bad UX to re-enable pagination while reordering, but if you are sure then you can use `$table->paginatedWhileReordering()`:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->paginatedWhileReordering();
|
||||
}
|
||||
```
|
||||
|
||||
### Customizing the reordering trigger action
|
||||
|
||||
To customize the reordering trigger button, you may use the `reorderRecordsTriggerAction()` method, passing a closure that returns an action. All methods that are available to [customize action trigger buttons](../actions/trigger-button) can be used:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Actions\Action;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->reorderRecordsTriggerAction(
|
||||
fn (Action $action, bool $isReordering) => $action
|
||||
->button()
|
||||
->label($isReordering ? 'Disable reordering' : 'Enable reordering'),
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/reordering/custom-trigger-action" alt="Table with reorderable rows and a custom trigger action" version="3.x" />
|
||||
|
||||
## Customizing the table header
|
||||
|
||||
You can add a heading to a table using the `$table->heading()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->heading('Clients')
|
||||
->columns([
|
||||
// ...
|
||||
]);
|
||||
```
|
||||
|
||||
You can also add a description below the heading using the `$table->description()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->heading('Clients')
|
||||
->description('Manage your clients here.')
|
||||
->columns([
|
||||
// ...
|
||||
]);
|
||||
```
|
||||
|
||||
You can pass a view to the `$table->header()` method to customize the entire header:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->header(view('tables.header', [
|
||||
'heading' => 'Clients',
|
||||
]))
|
||||
->columns([
|
||||
// ...
|
||||
]);
|
||||
```
|
||||
|
||||
## Polling table content
|
||||
|
||||
You may poll table content so that it refreshes at a set interval, using the `$table->poll()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->poll('10s');
|
||||
}
|
||||
```
|
||||
|
||||
## Deferring loading
|
||||
|
||||
Tables with lots of data might take a while to load, in which case you can load the table data asynchronously using the `deferLoading()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->deferLoading();
|
||||
}
|
||||
```
|
||||
|
||||
## Searching records with Laravel Scout
|
||||
|
||||
While Filament doesn't provide a direct integration with [Laravel Scout](https://laravel.com/docs/scout), you may override methods to integrate it.
|
||||
|
||||
Use a `whereIn()` clause to filter the query for Scout results:
|
||||
|
||||
```php
|
||||
use App\Models\Post;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
|
||||
protected function applySearchToTableQuery(Builder $query): Builder
|
||||
{
|
||||
$this->applyColumnSearchesToTableQuery($query);
|
||||
|
||||
if (filled($search = $this->getTableSearch())) {
|
||||
$query->whereIn('id', Post::search($search)->keys());
|
||||
}
|
||||
|
||||
return $query;
|
||||
}
|
||||
```
|
||||
|
||||
Scout uses this `whereIn()` method to retrieve results internally, so there is no performance penalty for using it.
|
||||
|
||||
The `applyColumnSearchesToTableQuery()` method ensures that searching individual columns will still work. You can replace that method with your own implementation if you want to use Scout for those search inputs as well.
|
||||
|
||||
For the global search input to show, at least one column in the table needs to be `searchable()`. Alternatively, if you are using Scout to control which columns are searchable already, you can simply pass `searchable()` to the entire table instead:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->searchable();
|
||||
}
|
||||
```
|
||||
|
||||
## Query string
|
||||
|
||||
Livewire ships with a feature to store data in the URL's query string, to access across requests.
|
||||
|
||||
With Filament, this allows you to store your table's filters, sort, search and pagination state in the URL.
|
||||
|
||||
To store the filters, sorting, and search state of your table in the query string:
|
||||
|
||||
```php
|
||||
use Livewire\Attributes\Url;
|
||||
|
||||
#[Url]
|
||||
public bool $isTableReordering = false;
|
||||
|
||||
/**
|
||||
* @var array<string, mixed> | null
|
||||
*/
|
||||
#[Url]
|
||||
public ?array $tableFilters = null;
|
||||
|
||||
#[Url]
|
||||
public ?string $tableGrouping = null;
|
||||
|
||||
#[Url]
|
||||
public ?string $tableGroupingDirection = null;
|
||||
|
||||
/**
|
||||
* @var ?string
|
||||
*/
|
||||
#[Url]
|
||||
public $tableSearch = '';
|
||||
|
||||
#[Url]
|
||||
public ?string $tableSortColumn = null;
|
||||
|
||||
#[Url]
|
||||
public ?string $tableSortDirection = null;
|
||||
```
|
||||
|
||||
## Styling table rows
|
||||
|
||||
### Striped table rows
|
||||
|
||||
To enable striped table rows, you can use the `striped()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Table;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->striped();
|
||||
}
|
||||
```
|
||||
|
||||
<AutoScreenshot name="tables/striped" alt="Table with striped rows" version="3.x" />
|
||||
|
||||
### Custom row classes
|
||||
|
||||
You may want to conditionally style rows based on the record data. This can be achieved by specifying a string or array of CSS classes to be applied to the row using the `$table->recordClasses()` method:
|
||||
|
||||
```php
|
||||
use Closure;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->recordClasses(fn (Model $record) => match ($record->status) {
|
||||
'draft' => 'opacity-30',
|
||||
'reviewing' => 'border-s-2 border-orange-600 dark:border-orange-300',
|
||||
'published' => 'border-s-2 border-green-600 dark:border-green-300',
|
||||
default => null,
|
||||
});
|
||||
}
|
||||
```
|
||||
|
||||
These classes are not automatically compiled by Tailwind CSS. If you want to apply Tailwind CSS classes that are not already used in Blade files, you should update your `content` configuration in `tailwind.config.js` to also scan for classes inside your directory: `'./app/Filament/**/*.php'`
|
||||
|
||||
## Resetting the table
|
||||
|
||||
If you make changes to the table definition during a Livewire request, for example, when consuming a public property in the `table()` method, you may need to reset the table to ensure that the changes are applied. To do this, you can call the `resetTable()` method on the Livewire component:
|
||||
|
||||
```php
|
||||
$this->resetTable();
|
||||
```
|
||||
|
||||
## Global settings
|
||||
|
||||
To customize the default configuration that is used for all tables, you can call the static `configureUsing()` method from the `boot()` method of a service provider. The function will be run for each table that gets created:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Enums\FiltersLayout;
|
||||
use Filament\Tables\Table;
|
||||
|
||||
Table::configureUsing(function (Table $table): void {
|
||||
$table
|
||||
->filtersLayout(FiltersLayout::AboveContentCollapsible)
|
||||
->paginationPageOptions([10, 25, 50]);
|
||||
});
|
||||
```
|
||||
137
vendor/filament/tables/docs/11-adding-a-table-to-a-livewire-component.md
vendored
Normal file
137
vendor/filament/tables/docs/11-adding-a-table-to-a-livewire-component.md
vendored
Normal file
@@ -0,0 +1,137 @@
|
||||
---
|
||||
title: Adding a table to a Livewire component
|
||||
---
|
||||
|
||||
## Setting up the Livewire component
|
||||
|
||||
First, generate a new Livewire component:
|
||||
|
||||
```bash
|
||||
php artisan make:livewire ListProducts
|
||||
```
|
||||
|
||||
Then, render your Livewire component on the page:
|
||||
|
||||
```blade
|
||||
@livewire('list-products')
|
||||
```
|
||||
|
||||
Alternatively, you can use a full-page Livewire component:
|
||||
|
||||
```php
|
||||
use App\Livewire\ListProducts;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('products', ListProducts::class);
|
||||
```
|
||||
|
||||
## Adding the table
|
||||
|
||||
There are 3 tasks when adding a table to a Livewire component class:
|
||||
|
||||
1) Implement the `HasTable` and `HasForms` interfaces, and use the `InteractsWithTable` and `InteractsWithForms` traits.
|
||||
2) Add a `table()` method, which is where you configure the table. [Add the table's columns, filters, and actions](getting-started#columns).
|
||||
3) Make sure to define the base query that will be used to fetch rows in the table. For example, if you're listing products from your `Product` model, you will want to return `Product::query()`.
|
||||
|
||||
```php
|
||||
<?php
|
||||
|
||||
namespace App\Livewire;
|
||||
|
||||
use App\Models\Shop\Product;
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
use Filament\Tables\Concerns\InteractsWithTable;
|
||||
use Filament\Tables\Contracts\HasTable;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Contracts\View\View;
|
||||
use Livewire\Component;
|
||||
|
||||
class ListProducts extends Component implements HasForms, HasTable
|
||||
{
|
||||
use InteractsWithTable;
|
||||
use InteractsWithForms;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->query(Product::query())
|
||||
->columns([
|
||||
TextColumn::make('name'),
|
||||
])
|
||||
->filters([
|
||||
// ...
|
||||
])
|
||||
->actions([
|
||||
// ...
|
||||
])
|
||||
->bulkActions([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
|
||||
public function render(): View
|
||||
{
|
||||
return view('livewire.list-products');
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Finally, in your Livewire component's view, render the table:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $this->table }}
|
||||
</div>
|
||||
```
|
||||
|
||||
Visit your Livewire component in the browser, and you should see the table.
|
||||
|
||||
## Building a table for an Eloquent relationship
|
||||
|
||||
If you want to build a table for an Eloquent relationship, you can use the `relationship()` and `inverseRelationship()` methods on the `$table` instead of passing a `query()`. `HasMany`, `HasManyThrough`, `BelongsToMany`, `MorphMany` and `MorphToMany` relationships are compatible:
|
||||
|
||||
```php
|
||||
use App\Models\Category;
|
||||
use Filament\Tables\Table;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
public Category $category;
|
||||
|
||||
public function table(Table $table): Table
|
||||
{
|
||||
return $table
|
||||
->relationship(fn (): BelongsToMany => $this->category->products())
|
||||
->inverseRelationship('categories')
|
||||
->columns([
|
||||
TextColumn::make('name'),
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
In this example, we have a `$category` property which holds a `Category` model instance. The category has a relationship named `products`. We use a function to return the relationship instance. This is a many-to-many relationship, so the inverse relationship is called `categories`, and is defined on the `Product` model. We just need to pass the name of this relationship to the `inverseRelationship()` method, not the whole instance.
|
||||
|
||||
Now that the table is using a relationship instead of a plain Eloquent query, all actions will be performed on the relationship instead of the query. For example, if you use a [`CreateAction`](../actions/prebuilt-actions/create), the new product will be automatically attached to the category.
|
||||
|
||||
If your relationship uses a pivot table, you can use all pivot columns as if they were normal columns on your table, as long as they are listed in the `withPivot()` method of the relationship *and* inverse relationship definition.
|
||||
|
||||
Relationship tables are used in the Panel Builder as ["relation managers"](../panels/resources/relation-managers#creating-a-relation-manager). Most of the documented features for relation managers are also available for relationship tables. For instance, [attaching and detaching](../panels/resources/relation-managers#attaching-and-detaching-records) and [associating and dissociating](../panels/resources/relation-managers#associating-and-dissociating-records) actions.
|
||||
|
||||
## Generating table Livewire components with the CLI
|
||||
|
||||
It's advised that you learn how to set up a Livewire component with the Table Builder manually, but once you are confident, you can use the CLI to generate a table for you.
|
||||
|
||||
```bash
|
||||
php artisan make:livewire-table Products/ListProducts
|
||||
```
|
||||
|
||||
This will ask you for the name of a prebuilt model, for example `Product`. Finally, it will generate a new `app/Livewire/Products/ListProducts.php` component, which you can customize.
|
||||
|
||||
### Automatically generating table columns
|
||||
|
||||
Filament is also able to guess which table columns you want in the table, based on the model's database columns. You can use the `--generate` flag when generating your table:
|
||||
|
||||
```bash
|
||||
php artisan make:livewire-table Products/ListProducts --generate
|
||||
```
|
||||
683
vendor/filament/tables/docs/12-testing.md
vendored
Normal file
683
vendor/filament/tables/docs/12-testing.md
vendored
Normal file
@@ -0,0 +1,683 @@
|
||||
---
|
||||
title: Testing
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
|
||||
|
||||
Since the Table Builder works on Livewire components, you can use the [Livewire testing helpers](https://livewire.laravel.com/docs/testing). However, we have many custom testing helpers that you can use for tables:
|
||||
|
||||
## Render
|
||||
|
||||
To ensure a table component renders, use the `assertSuccessful()` Livewire helper:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can render page', function () {
|
||||
livewire(ListPosts::class)->assertSuccessful();
|
||||
});
|
||||
```
|
||||
|
||||
To test which records are shown, you can use `assertCanSeeTableRecords()`, `assertCanNotSeeTableRecords()` and `assertCountTableRecords()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('cannot display trashed posts by default', function () {
|
||||
$posts = Post::factory()->count(4)->create();
|
||||
$trashedPosts = Post::factory()->trashed()->count(6)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanSeeTableRecords($posts)
|
||||
->assertCanNotSeeTableRecords($trashedPosts)
|
||||
->assertCountTableRecords(4);
|
||||
});
|
||||
```
|
||||
|
||||
> If your table uses pagination, `assertCanSeeTableRecords()` will only check for records on the first page. To switch page, call `call('gotoPage', 2)`.
|
||||
|
||||
> If your table uses `deferLoading()`, you should call `loadTable()` before `assertCanSeeTableRecords()`.
|
||||
|
||||
## Columns
|
||||
|
||||
To ensure that a certain column is rendered, pass the column name to `assertCanRenderTableColumn()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can render post titles', function () {
|
||||
Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanRenderTableColumn('title');
|
||||
});
|
||||
```
|
||||
|
||||
This helper will get the HTML for this column, and check that it is present in the table.
|
||||
|
||||
For testing that a column is not rendered, you can use `assertCanNotRenderTableColumn()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can not render post comments', function () {
|
||||
Post::factory()->count(10)->create()
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanNotRenderTableColumn('comments');
|
||||
});
|
||||
```
|
||||
|
||||
This helper will assert that the HTML for this column is not shown by default in the present table.
|
||||
|
||||
### Sorting
|
||||
|
||||
To sort table records, you can call `sortTable()`, passing the name of the column to sort by. You can use `'desc'` in the second parameter of `sortTable()` to reverse the sorting direction.
|
||||
|
||||
Once the table is sorted, you can ensure that the table records are rendered in order using `assertCanSeeTableRecords()` with the `inOrder` parameter:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can sort posts by title', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->sortTable('title')
|
||||
->assertCanSeeTableRecords($posts->sortBy('title'), inOrder: true)
|
||||
->sortTable('title', 'desc')
|
||||
->assertCanSeeTableRecords($posts->sortByDesc('title'), inOrder: true);
|
||||
});
|
||||
```
|
||||
|
||||
### Searching
|
||||
|
||||
To search the table, call the `searchTable()` method with your search query.
|
||||
|
||||
You can then use `assertCanSeeTableRecords()` to check your filtered table records, and use `assertCanNotSeeTableRecords()` to assert that some records are no longer in the table:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can search posts by title', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
$title = $posts->first()->title;
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->searchTable($title)
|
||||
->assertCanSeeTableRecords($posts->where('title', $title))
|
||||
->assertCanNotSeeTableRecords($posts->where('title', '!=', $title));
|
||||
});
|
||||
```
|
||||
|
||||
To search individual columns, you can pass an array of searches to `searchTableColumns()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can search posts by title column', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
$title = $posts->first()->title;
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->searchTableColumns(['title' => $title])
|
||||
->assertCanSeeTableRecords($posts->where('title', $title))
|
||||
->assertCanNotSeeTableRecords($posts->where('title', '!=', $title));
|
||||
});
|
||||
```
|
||||
|
||||
### State
|
||||
|
||||
To assert that a certain column has a state or does not have a state for a record you can use `assertTableColumnStateSet()` and `assertTableColumnStateNotSet()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can get post author names', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
$post = $posts->first();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableColumnStateSet('author.name', $post->author->name, record: $post)
|
||||
->assertTableColumnStateNotSet('author.name', 'Anonymous', record: $post);
|
||||
});
|
||||
```
|
||||
|
||||
To assert that a certain column has a formatted state or does not have a formatted state for a record you can use `assertTableColumnFormattedStateSet()` and `assertTableColumnFormattedStateNotSet()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can get post author names', function () {
|
||||
$post = Post::factory(['name' => 'John Smith'])->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableColumnFormattedStateSet('author.name', 'Smith, John', record: $post)
|
||||
->assertTableColumnFormattedStateNotSet('author.name', $post->author->name, record: $post);
|
||||
});
|
||||
```
|
||||
|
||||
### Existence
|
||||
|
||||
To ensure that a column exists, you can use the `assertTableColumnExists()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('has an author column', function () {
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableColumnExists('author');
|
||||
});
|
||||
```
|
||||
|
||||
You may pass a function as an additional argument in order to assert that a column passes a given "truth test". This is useful for asserting that a column has a specific configuration. You can also pass in a record as the third parameter, which is useful if your check is dependant on which table row is being rendered:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
it('has an author column', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableColumnExists('author', function (TextColumn $column): bool {
|
||||
return $column->getDescriptionBelow() === $post->subtitle;
|
||||
}, $post);
|
||||
});
|
||||
```
|
||||
|
||||
### Authorization
|
||||
|
||||
To ensure that a particular user cannot see a column, you can use the `assertTableColumnVisible()` and `assertTableColumnHidden()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('shows the correct columns', function () {
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableColumnVisible('created_at')
|
||||
->assertTableColumnHidden('author');
|
||||
});
|
||||
```
|
||||
|
||||
### Descriptions
|
||||
|
||||
To ensure a column has the correct description above or below you can use the `assertTableColumnHasDescription()` and `assertTableColumnDoesNotHaveDescription()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('has the correct descriptions above and below author', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->assertTableColumnHasDescription('author', 'Author! ↓↓↓', $post, 'above')
|
||||
->assertTableColumnHasDescription('author', 'Author! ↑↑↑', $post)
|
||||
->assertTableColumnDoesNotHaveDescription('author', 'Author! ↑↑↑', $post, 'above')
|
||||
->assertTableColumnDoesNotHaveDescription('author', 'Author! ↓↓↓', $post);
|
||||
});
|
||||
```
|
||||
|
||||
### Extra Attributes
|
||||
|
||||
To ensure that a column has the correct extra attributes, you can use the `assertTableColumnHasExtraAttributes()` and `assertTableColumnDoesNotHaveExtraAttributes()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('displays author in red', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->assertTableColumnHasExtraAttributes('author', ['class' => 'text-danger-500'], $post)
|
||||
->assertTableColumnDoesNotHaveExtraAttributes('author', ['class' => 'text-primary-500'], $post);
|
||||
});
|
||||
```
|
||||
|
||||
### Select Columns
|
||||
|
||||
If you have a select column, you can ensure it has the correct options with `assertTableSelectColumnHasOptions()` and `assertTableSelectColumnDoesNotHaveOptions()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('has the correct statuses', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->assertTableSelectColumnHasOptions('status', ['unpublished' => 'Unpublished', 'published' => 'Published'], $post)
|
||||
->assertTableSelectColumnDoesNotHaveOptions('status', ['archived' => 'Archived'], $post);
|
||||
});
|
||||
```
|
||||
|
||||
## Filters
|
||||
|
||||
To filter the table records, you can use the `filterTable()` method, along with `assertCanSeeTableRecords()` and `assertCanNotSeeTableRecords()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can filter posts by `is_published`', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanSeeTableRecords($posts)
|
||||
->filterTable('is_published')
|
||||
->assertCanSeeTableRecords($posts->where('is_published', true))
|
||||
->assertCanNotSeeTableRecords($posts->where('is_published', false));
|
||||
});
|
||||
```
|
||||
|
||||
For a simple filter, this will just enable the filter.
|
||||
|
||||
If you'd like to set the value of a `SelectFilter` or `TernaryFilter`, pass the value as a second argument:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can filter posts by `author_id`', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
$authorId = $posts->first()->author_id;
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanSeeTableRecords($posts)
|
||||
->filterTable('author_id', $authorId)
|
||||
->assertCanSeeTableRecords($posts->where('author_id', $authorId))
|
||||
->assertCanNotSeeTableRecords($posts->where('author_id', '!=', $authorId));
|
||||
});
|
||||
```
|
||||
|
||||
### Resetting filters
|
||||
|
||||
To reset all filters to their original state, call `resetTableFilters()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can reset table filters', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->resetTableFilters();
|
||||
});
|
||||
```
|
||||
|
||||
### Removing Filters
|
||||
|
||||
To remove a single filter you can use `removeTableFilter()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('filters list by published', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
$unpublishedPosts = $posts->where('is_published', false)->get();
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->filterTable('is_published')
|
||||
->assertCanNotSeeTableRecords($unpublishedPosts)
|
||||
->removeTableFilter('is_published')
|
||||
->assertCanSeeTableRecords($posts);
|
||||
});
|
||||
```
|
||||
|
||||
To remove all filters you can use `removeTableFilters()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can remove all table filters', function () {
|
||||
$posts = Post::factory()->count(10)->forAuthor()->create();
|
||||
|
||||
$unpublishedPosts = $posts
|
||||
->where('is_published', false)
|
||||
->where('author_id', $posts->first()->author->getKey());
|
||||
|
||||
livewire(PostsTable::class)
|
||||
->filterTable('is_published')
|
||||
->filterTable('author', $author)
|
||||
->assertCanNotSeeTableRecords($unpublishedPosts)
|
||||
->removeTableFilters()
|
||||
->assertCanSeeTableRecords($posts);
|
||||
});
|
||||
```
|
||||
|
||||
## Actions
|
||||
|
||||
### Calling actions
|
||||
|
||||
You can call an action by passing its name or class to `callTableAction()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can delete posts', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->callTableAction(DeleteAction::class, $post);
|
||||
|
||||
$this->assertModelMissing($post);
|
||||
});
|
||||
```
|
||||
|
||||
This example assumes that you have a `DeleteAction` on your table. If you have a custom `Action::make('reorder')`, you may use `callTableAction('reorder')`.
|
||||
|
||||
For column actions, you may do the same, using `callTableColumnAction()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can copy posts', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->callTableColumnAction('copy', $post);
|
||||
|
||||
$this->assertDatabaseCount((new Post)->getTable(), 2);
|
||||
});
|
||||
```
|
||||
|
||||
For bulk actions, you may do the same, passing in multiple records to execute the bulk action against with `callTableBulkAction()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can bulk delete posts', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->callTableBulkAction(DeleteBulkAction::class, $posts);
|
||||
|
||||
foreach ($posts as $post) {
|
||||
$this->assertModelMissing($post);
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
To pass an array of data into an action, use the `data` parameter:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can edit posts', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->callTableAction(EditAction::class, $post, data: [
|
||||
'title' => $title = fake()->words(asText: true),
|
||||
])
|
||||
->assertHasNoTableActionErrors();
|
||||
|
||||
expect($post->refresh())
|
||||
->title->toBe($title);
|
||||
});
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
To check if an action or bulk action has been halted, you can use `assertTableActionHalted()` / `assertTableBulkActionHalted()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('will halt delete if post is flagged', function () {
|
||||
$posts= Post::factory()->count(2)->flagged()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->callTableAction('delete', $posts->first())
|
||||
->callTableBulkAction('delete', $posts)
|
||||
->assertTableActionHalted('delete')
|
||||
->assertTableBulkActionHalted('delete');
|
||||
|
||||
$this->assertModelExists($post);
|
||||
});
|
||||
```
|
||||
|
||||
### Errors
|
||||
|
||||
`assertHasNoTableActionErrors()` is used to assert that no validation errors occurred when submitting the action form.
|
||||
|
||||
To check if a validation error has occurred with the data, use `assertHasTableActionErrors()`, similar to `assertHasErrors()` in Livewire:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can validate edited post data', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->callTableAction(EditAction::class, $post, data: [
|
||||
'title' => null,
|
||||
])
|
||||
->assertHasTableActionErrors(['title' => ['required']]);
|
||||
});
|
||||
```
|
||||
|
||||
For bulk actions these methods are called `assertHasTableBulkActionErrors()` and `assertHasNoTableBulkActionErrors()`.
|
||||
|
||||
### Pre-filled data
|
||||
|
||||
To check if an action or bulk action is pre-filled with data, you can use the `assertTableActionDataSet()` or `assertTableBulkActionDataSet()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can load existing post data for editing', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->mountTableAction(EditAction::class, $post)
|
||||
->assertTableActionDataSet([
|
||||
'title' => $post->title,
|
||||
])
|
||||
->setTableActionData([
|
||||
'title' => $title = fake()->words(asText: true),
|
||||
])
|
||||
->callMountedTableAction()
|
||||
->assertHasNoTableActionErrors();
|
||||
|
||||
expect($post->refresh())
|
||||
->title->toBe($title);
|
||||
});
|
||||
```
|
||||
|
||||
### Action state
|
||||
|
||||
To ensure that an action or bulk action exists or doesn't in a table, you can use the `assertTableActionExists()` / `assertTableActionDoesNotExist()` or `assertTableBulkActionExists()` / `assertTableBulkActionDoesNotExist()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can publish but not unpublish posts', function () {
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionExists('publish')
|
||||
->assertTableActionDoesNotExist('unpublish')
|
||||
->assertTableBulkActionExists('publish')
|
||||
->assertTableBulkActionDoesNotExist('unpublish');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure different sets of actions exist in the correct order, you can use the various "InOrder" assertions
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('has all actions in expected order', function () {
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionsExistInOrder(['edit', 'delete'])
|
||||
->assertTableBulkActionsExistInOrder(['restore', 'forceDelete'])
|
||||
->assertTableHeaderActionsExistInOrder(['create', 'attach'])
|
||||
->assertTableEmptyStateActionsExistInOrder(['create', 'toggle-trashed-filter'])
|
||||
});
|
||||
```
|
||||
|
||||
To ensure that an action or bulk action is enabled or disabled for a user, you can use the `assertTableActionEnabled()` / `assertTableActionDisabled()` or `assertTableBulkActionEnabled()` / `assertTableBulkActionDisabled()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can not publish, but can delete posts', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionDisabled('publish', $post)
|
||||
->assertTableActionEnabled('delete', $post)
|
||||
->assertTableBulkActionDisabled('publish')
|
||||
->assertTableBulkActionEnabled('delete');
|
||||
});
|
||||
```
|
||||
|
||||
|
||||
To ensure that an action or bulk action is visible or hidden for a user, you can use the `assertTableActionVisible()` / `assertTableActionHidden()` or `assertTableBulkActionVisible()` / `assertTableBulkActionHidden()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can not publish, but can delete posts', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionHidden('publish', $post)
|
||||
->assertTableActionVisible('delete', $post)
|
||||
->assertTableBulkActionHidden('publish')
|
||||
->assertTableBulkActionVisible('delete');
|
||||
});
|
||||
```
|
||||
|
||||
### Button Style
|
||||
|
||||
To ensure an action or bulk action has the correct label, you can use `assertTableActionHasLabel()` / `assertTableBulkActionHasLabel()` and `assertTableActionDoesNotHaveLabel()` / `assertTableBulkActionDoesNotHaveLabel()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('delete actions have correct labels', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionHasLabel('delete', 'Archive Post')
|
||||
->assertTableActionDoesNotHaveLabel('delete', 'Delete');
|
||||
->assertTableBulkActionHasLabel('delete', 'Archive Post')
|
||||
->assertTableBulkActionDoesNotHaveLabel('delete', 'Delete');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure an action or bulk action's button is showing the correct icon, you can use `assertTableActionHasIcon()` / `assertTableBulkActionHasIcon()` or `assertTableActionDoesNotHaveIcon()` / `assertTableBulkActionDoesNotHaveIcon()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('delete actions have correct icons', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionHasIcon('delete', 'heroicon-m-archive-box')
|
||||
->assertTableActionDoesNotHaveIcon('delete', 'heroicon-m-trash');
|
||||
->assertTableBulkActionHasIcon('delete', 'heroicon-m-archive-box')
|
||||
->assertTableBulkActionDoesNotHaveIcon('delete', 'heroicon-m-trash');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure that an action or bulk action's button is displaying the right color, you can use `assertTableActionHasColor()` / `assertTableBulkActionHasColor()` or `assertTableActionDoesNotHaveColor()` / `assertTableBulkActionDoesNotHaveColor()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('delete actions have correct colors', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionHasColor('delete', 'warning')
|
||||
->assertTableActionDoesNotHaveColor('delete', 'danger');
|
||||
->assertTableBulkActionHasColor('delete', 'warning')
|
||||
->assertTableBulkActionDoesNotHaveColor('delete', 'danger');
|
||||
});
|
||||
```
|
||||
|
||||
### URL
|
||||
|
||||
To ensure an action or bulk action has the correct URL traits, you can use `assertTableActionHasUrl()`, `assertTableActionDoesNotHaveUrl()`, `assertTableActionShouldOpenUrlInNewTab()`, and `assertTableActionShouldNotOpenUrlInNewTab()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('links to the correct Filament sites', function () {
|
||||
$post = Post::factory()->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertTableActionHasUrl('filament', 'https://filamentphp.com/')
|
||||
->assertTableActionDoesNotHaveUrl('filament', 'https://github.com/filamentphp/filament')
|
||||
->assertTableActionShouldOpenUrlInNewTab('filament')
|
||||
->assertTableActionShouldNotOpenUrlInNewTab('github');
|
||||
});
|
||||
```
|
||||
|
||||
## Summaries
|
||||
|
||||
To test that a summary calculation is working, you may use the `assertTableColumnSummarySet()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can average values in a column', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanSeeTableRecords($posts)
|
||||
->assertTableColumnSummarySet('rating', 'average', $posts->avg('rating'));
|
||||
});
|
||||
```
|
||||
|
||||
The first argument is the column name, the second is the summarizer ID, and the third is the expected value.
|
||||
|
||||
You may set a summarizer ID by passing it to the `make()` method:
|
||||
|
||||
```php
|
||||
use Filament\Tables\Columns\Summarizers\Average;
|
||||
use Filament\Tables\Columns\TextColumn;
|
||||
|
||||
TextColumn::make('rating')
|
||||
->summarize(Average::make('average'))
|
||||
```
|
||||
|
||||
The ID should be unique between summarizers in that column.
|
||||
|
||||
### Summarizing only one pagination page
|
||||
|
||||
To calculate the average for only one pagination page, use the `isCurrentPaginationPageOnly` argument:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can average values in a column', function () {
|
||||
$posts = Post::factory()->count(20)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanSeeTableRecords($posts->take(10))
|
||||
->assertTableColumnSummarySet('rating', 'average', $posts->take(10)->avg('rating'), isCurrentPaginationPageOnly: true);
|
||||
});
|
||||
```
|
||||
|
||||
### Testing a range summarizer
|
||||
|
||||
To test a range, pass the minimum and maximum value into a tuple-style `[$minimum, $maximum]` array:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can average values in a column', function () {
|
||||
$posts = Post::factory()->count(10)->create();
|
||||
|
||||
livewire(PostResource\Pages\ListPosts::class)
|
||||
->assertCanSeeTableRecords($posts)
|
||||
->assertTableColumnSummarySet('rating', 'range', [$posts->min('rating'), $posts->max('rating')]);
|
||||
});
|
||||
```
|
||||
82
vendor/filament/tables/docs/13-upgrade-guide.md
vendored
Normal file
82
vendor/filament/tables/docs/13-upgrade-guide.md
vendored
Normal file
@@ -0,0 +1,82 @@
|
||||
---
|
||||
title: Upgrading from v2.x
|
||||
---
|
||||
|
||||
> If you see anything missing from this guide, please do not hesitate to [make a pull request](https://github.com/filamentphp/filament/edit/3.x/packages/tables/docs/13-upgrade-guide.md) to our repository! Any help is appreciated!
|
||||
|
||||
## New requirements
|
||||
|
||||
- Laravel v10.0+
|
||||
- Livewire v3.0+
|
||||
|
||||
Please upgrade Filament before upgrading to Livewire v3. Instructions on how to upgrade Livewire can be found [here](https://livewire.laravel.com/docs/upgrading).
|
||||
|
||||
## Upgrading automatically
|
||||
|
||||
The easiest way to upgrade your app is to run the automated upgrade script. This script will automatically upgrade your application to the latest version of Filament, and make changes to your code which handle most breaking changes.
|
||||
|
||||
```bash
|
||||
composer require filament/upgrade:"^3.2" -W --dev
|
||||
vendor/bin/filament-v3
|
||||
```
|
||||
|
||||
Make sure to carefully follow the instructions, and review the changes made by the script. You may need to make some manual changes to your code afterwards, but the script should handle most of the repetitive work for you.
|
||||
|
||||
Finally, you must run `php artisan filament:install` to finalize the Filament v3 installation. This command must be run for all new Filament projects.
|
||||
|
||||
You can now `composer remove filament/upgrade` as you don't need it anymore.
|
||||
|
||||
> Some plugins you're using may not be available in v3 just yet. You could temporarily remove them from your `composer.json` file until they've been upgraded, replace them with a similar plugins that are v3-compatible, wait for the plugins to be upgraded before upgrading your app, or even write PRs to help the authors upgrade them.
|
||||
|
||||
## Upgrading manually
|
||||
|
||||
After upgrading the dependency via Composer, you should execute `php artisan filament:upgrade` in order to clear any Laravel caches and publish the new frontend assets.
|
||||
|
||||
### High-impact changes
|
||||
|
||||
#### Config file renamed and combined with other Filament packages
|
||||
|
||||
Only one config file is now used for all Filament packages. Most configuration has been moved into other parts of the codebase, and little remains. You should use the v3 documentation as a reference when replace the configuration options you did modify. To publish the new configuration file and remove the old one, run:
|
||||
|
||||
```bash
|
||||
php artisan vendor:publish --tag=filament-config --force
|
||||
rm config/tables.php
|
||||
```
|
||||
|
||||
#### `TABLES_FILESYSTEM_DRIVER` .env variable
|
||||
|
||||
The `TABLES_FILESYSTEM_DRIVER` .env variable has been renamed to `FILAMENT_FILESYSTEM_DISK`. This is to make it more consistent with Laravel, as Laravel v9 introduced this change as well. Please ensure that you update your .env files accordingly, and don't forget production!
|
||||
|
||||
#### New `@filamentScripts` and `@filamentStyles` Blade directives
|
||||
|
||||
The `@filamentScripts` and `@filamentStyles` Blade directives must be added to your Blade layout file/s. Since Livewire v3 no longer uses similar directives, you can replace `@livewireScripts` with `@filamentScripts` and `@livewireStyles` with `@filamentStyles`.
|
||||
|
||||
#### CSS file removed
|
||||
|
||||
The CSS file for form components, `module.esm.css`, has been removed. Check `resources/css/app.css`. That CSS is now automatically loaded by `@filamentStyles`.
|
||||
|
||||
#### JavaScript files removed
|
||||
|
||||
You no longer need to import the `FormsAlpinePlugin` in your JavaScript files. Alpine plugins are now automatically loaded by `@filamentScripts`.
|
||||
|
||||
#### Heroicons have been updated to v2
|
||||
|
||||
The Heroicons library has been updated to v2. This means that any icons you use in your app may have changed names. You can find a list of changes [here](https://github.com/tailwindlabs/heroicons/releases/tag/v2.0.0).
|
||||
|
||||
### Medium-impact changes
|
||||
|
||||
#### Secondary color
|
||||
|
||||
Filament v2 had a `secondary` color for many components which was gray. All references to `secondary` should be replaced with `gray` to preserve the same appearance. This frees `secondary` to be registered to a new custom color of your choice.
|
||||
|
||||
#### `BadgeColumn::enum()` removed
|
||||
|
||||
You can use a `formatStateUsing()` function to transform text.
|
||||
|
||||
#### Enum classes moved
|
||||
|
||||
The following enum classes have moved:
|
||||
|
||||
- `Filament\Tables\Actions\Position` has moved to `Filament\Tables\Enums\ActionsPosition`.
|
||||
- `Filament\Tables\Actions\RecordCheckboxPosition` has moved to `Filament\Tables\Enums\RecordCheckboxPosition`.
|
||||
- `Filament\Tables\Filters\Layout` has moved to `Filament\Tables\Enums\FiltersLayout`.
|
||||
Reference in New Issue
Block a user