🆙 Add cms i using 🆙

This commit is contained in:
Remco
2025-11-25 22:42:56 +01:00
parent 94704e0925
commit d44196149e
35591 changed files with 3601123 additions and 0 deletions
@@ -0,0 +1,339 @@
<?php
namespace Livewire\Features\SupportTesting {
use Closure;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
class Testable {
public function selectTableRecords(array | Collection $records): static {}
public function assertCanRenderTableColumn(string $name): static {}
public function assertCanNotRenderTableColumn(string $name): static {}
public function assertTableColumnExists(string $name, ?Closure $checkColumnUsing = null, $record = null): static {}
public function assertTableColumnDoesNotExist(string $name, ?Closure $checkColumnUsing = null, $record = null): static {}
public function assertTableColumnVisible(string $name): static {}
public function assertTableColumnHidden(string $name): static {}
public function assertTableColumnStateSet(string $name, $state, $record): static {}
public function assertTableColumnStateNotSet(string $name, $state, $record): static {}
public function assertTableColumnSummarizerExists(string $columnName, string $summarizerId): static {}
public function assertTableColumnSummarySet(string $columnName, string $summarizerId, $state, bool $isCurrentPaginationPageOnly = false): static {}
public function assertTableColumnSummaryNotSet(string $columnName, string $summarizerId, $state, bool $isCurrentPaginationPageOnly = false): static {}
public function assertTableColumnFormattedStateSet(string $name, $state, $record): static {}
public function assertTableColumnFormattedStateNotSet(string $name, $state, $record): static {}
public function assertTableColumnHasExtraAttributes(string $name, array $attributes, $record): static {}
public function assertTableColumnDoesNotHaveExtraAttributes(string $name, array $attributes, $record): static {}
public function assertTableColumnHasDescription(string $name, $description, $record, $position = 'below'): static {}
public function assertTableColumnDoesNotHaveDescription(string $name, $description, $record, $position = 'below'): static {}
public function assertTableSelectColumnHasOptions(string $name, array $options, $record): static {}
public function assertTableSelectColumnDoesNotHaveOptions(string $name, array $options, $record): static {}
public function sortTable(?string $name = null, ?string $direction = null): static {}
public function searchTable(?string $search = null): static {}
public function searchTableColumns(array $searches): static {}
public function filterTable(string $name, $data = null): static {}
public function resetTableFilters(): static {}
public function removeTableFilter(string $filter, ?string $field = null): static {}
public function removeTableFilters(): static {}
public function assertTableFilterVisible(string $name): static {}
public function assertTableFilterHidden(string $name): static {}
public function assertTableFilterExists(string $name, ?Closure $checkFilterUsing = null): static {}
public function assertCanSeeTableRecords(array | Collection $records, bool $inOrder = false): static {}
public function assertCanNotSeeTableRecords(array | Collection $records): static {}
public function assertCountTableRecords(int $count): static {}
public function toggleAllTableColumns(bool $condition = true): static {}
public function loadTable(): static {}
/**
* @deprecated Use `mountAction()` instead.
*/
public function mountTableAction(string | array $name, $record = null): static {}
/**
* @deprecated Use `unmountAction()` instead.
*/
public function unmountTableAction(): static {}
/**
* @deprecated Use `fillForm()` instead.
*/
public function setTableActionData(array $data): static {}
/**
* @deprecated Use `assertSchemaStateSet()` instead.
*/
public function assertTableActionDataSet(array | Closure $state): static {}
/**
* @deprecated Use `callAction()` instead.
*/
public function callTableAction(string | array $name, $record = null, array $data = [], array $arguments = []): static {}
public function callTableColumnAction(string $name, $record = null): static {}
/**
* @deprecated Use `callMountedAction()` instead.
*/
public function callMountedTableAction(array $arguments = []): static {}
/**
* @deprecated Use `assertActionExists()` instead.
*/
public function assertTableActionExists(string | array $name, ?Closure $checkActionUsing = null, $record = null): static {}
/**
* @deprecated Use `assertActionDoesNotExist()` instead.
*/
public function assertTableActionDoesNotExist(string | array $name, ?Closure $checkActionUsing = null, $record = null): static {}
public function assertTableActionsExistInOrder(array $names): static {}
public function assertTableHeaderActionsExistInOrder(array $names): static {}
public function assertTableEmptyStateActionsExistInOrder(array $names): static {}
/**
* @deprecated Use `assertActionVisible()` instead.
*/
public function assertTableActionVisible(string | array $name, $record = null): static {}
/**
* @deprecated Use `assertActionHidden()` instead.
*/
public function assertTableActionHidden(string | array $name, $record = null): static {}
/**
* @deprecated Use `assertActionEnabled()` instead.
*/
public function assertTableActionEnabled(string | array $name, $record = null): static {}
/**
* @deprecated Use `assertActionDisabled()` instead.
*/
public function assertTableActionDisabled(string | array $name, $record = null): static {}
/**
* @deprecated Use `assertActionMounted()` instead.
*/
public function assertTableActionMounted(string | array $name): static {}
/**
* @deprecated Use `assertActionNotMounted()` instead.
*/
public function assertTableActionNotMounted(string | array $name): static {}
/**
* @deprecated Use `assertActionHalted()` instead.
*/
public function assertTableActionHalted(string | array $name): static {}
/**
* @deprecated Use `assertHasTableActionErrors()` instead.
*/
public function assertHasTableActionErrors(array $keys = []): static {}
/**
* @deprecated Use `assertHasNoFormErrors()` instead.
*/
public function assertHasNoTableActionErrors(array $keys = []): static {}
/**
* @deprecated Use `mountBulkAction()` instead.
*/
public function mountTableBulkAction(string $name, array | Collection $records): static {}
/**
* @deprecated Use `fillForm()` instead.
*/
public function setTableBulkActionData(array $data): static {}
/**
* @deprecated Use `assertSchemaStateSet()` instead.
*/
public function assertTableBulkActionDataSet(array | Closure $state): static {}
/**
* @deprecated Use `callAction()` instead.
*/
public function callTableBulkAction(string $name, array | Collection $records, array $data = [], array $arguments = []): static {}
/**
* @deprecated Use `callMountedAction()` instead.
*/
public function callMountedTableBulkAction(array $arguments = []): static {}
/**
* @deprecated Use `assertActionExists()` instead.
*/
public function assertTableBulkActionExists(string $name): static {}
/**
* @deprecated Use `assertActionDoesNotExist()` instead.
*/
public function assertTableBulkActionDoesNotExist(string $name): static {}
/**
* @deprecated Use `assertActionsExistInOrder()` instead.
*/
public function assertTableBulkActionsExistInOrder(array $names): static {}
/**
* @deprecated Use `assertActionVisible()` instead.
*/
public function assertTableBulkActionVisible(string $name): static {}
/**
* @deprecated Use `assertActionHidden()` instead.
*/
public function assertTableBulkActionHidden(string $name): static {}
/**
* @deprecated Use `assertActionEnabled()` instead.
*/
public function assertTableBulkActionEnabled(string $name): static {}
/**
* @deprecated Use `assertActionDisabled()` instead.
*/
public function assertTableBulkActionDisabled(string $name): static {}
/**
* @deprecated Use `assertActionHasIcon()` instead.
*/
public function assertTableActionHasIcon(string | array $name, string $icon, $record = null): static {}
/**
* @deprecated Use `assertActionDoesNotHaveIcon()` instead.
*/
public function assertTableActionDoesNotHaveIcon(string | array $name, string $icon, $record = null): static {}
/**
* @deprecated Use `assertActionHasLabel()` instead.
*/
public function assertTableActionHasLabel(string | array $name, string $label, $record = null): static {}
/**
* @deprecated Use `assertActionDoesNotHaveLabel()` instead.
*/
public function assertTableActionDoesNotHaveLabel(string | array $name, string $label, $record = null): static {}
/**
* @deprecated Use `assertActionHasColor()` instead.
*/
public function assertTableActionHasColor(string | array $name, string | array $color, $record = null): static {}
/**
* @deprecated Use `assertActionDoesNotHaveColor()` instead.
*/
public function assertTableActionDoesNotHaveColor(string | array $name, string | array $color, $record = null): static {}
/**
* @deprecated Use `assertActionHasIcon()` instead.
*/
public function assertTableBulkActionHasIcon(string $name, string $icon): static {}
/**
* @deprecated Use `assertActionDoesNotHaveIcon()` instead.
*/
public function assertTableBulkActionDoesNotHaveIcon(string $name, string $icon): static {}
/**
* @deprecated Use `assertActionHasLabel()` instead.
*/
public function assertTableBulkActionHasLabel(string $name, string $label): static {}
/**
* @deprecated Use `assertActionDoesNotHaveLabel()` instead.
*/
public function assertTableBulkActionDoesNotHaveLabel(string $name, string $label): static {}
/**
* @deprecated Use `assertActionHasColor()` instead.
*/
public function assertTableBulkActionHasColor(string $name, string | array $color): static {}
/**
* @deprecated Use `assertActionDoesNotHaveColor()` instead.
*/
public function assertTableBulkActionDoesNotHaveColor(string $name, string | array $color): static {}
/**
* @deprecated Use `assertActionHasUrl()` instead.
*/
public function assertTableActionHasUrl(string | array $name, string $url, $record = null): static {}
/**
* @deprecated Use `assertActionDoesNotHaveUrl()` instead.
*/
public function assertTableActionDoesNotHaveUrl(string | array $name, string $url, $record = null): static {}
/**
* @deprecated Use `assertActionShouldOpenUrlInNewTab()` instead.
*/
public function assertTableActionShouldOpenUrlInNewTab(string | array $name, $record = null): static {}
/**
* @deprecated Use `assertActionShouldNotOpenUrlInNewTab()` instead.
*/
public function assertTableActionShouldNotOpenUrlInNewTab(string | array $name, $record = null): static {}
/**
* @deprecated Use `assertActionMounted()` instead.
*/
public function assertTableBulkActionMounted(string $name): static {}
/**
* @deprecated Use `assertActionNotMounted()` instead.
*/
public function assertTableBulkActionNotMounted(string $name): static {}
/**
* @deprecated Use `assertActionHalted()` instead.
*/
public function assertTableBulkActionHalted(string $name): static {}
/**
* @deprecated Use `assertHasFormErrors()` instead.
*/
public function assertHasTableBulkActionErrors(array $keys = []): static {}
/**
* @deprecated Use `assertHasNoFormErrors()` instead.
*/
public function assertHasNoTableBulkActionErrors(array $keys = []): static {}
}
}
@@ -0,0 +1,34 @@
{
"name": "filament/tables",
"description": "Easily add beautiful tables to any Livewire component.",
"license": "MIT",
"homepage": "https://github.com/filamentphp/filament",
"support": {
"issues": "https://github.com/filamentphp/filament/issues",
"source": "https://github.com/filamentphp/filament"
},
"require": {
"php": "^8.2",
"filament/actions": "self.version",
"filament/forms": "self.version",
"filament/query-builder": "self.version",
"filament/support": "self.version"
},
"autoload": {
"psr-4": {
"Filament\\Tables\\": "src"
}
},
"extra": {
"laravel": {
"providers": [
"Filament\\Tables\\TablesServiceProvider"
]
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev",
"prefer-stable": true
}
@@ -0,0 +1 @@
function o({name:i,recordKey:s,state:a}){return{error:void 0,isLoading:!1,state:a,init(){Livewire.hook("commit",({component:e,commit:r,succeed:n,fail:h,respond:u})=>{n(({snapshot:f,effect:d})=>{this.$nextTick(()=>{if(this.isLoading||e.id!==this.$root.closest("[wire\\:id]")?.attributes["wire:id"].value)return;let t=this.getServerState();t===void 0||Alpine.raw(this.state)===t||(this.state=t)})})}),this.$watch("state",async()=>{let e=this.getServerState();if(e===void 0||Alpine.raw(this.state)===e)return;this.isLoading=!0;let r=await this.$wire.updateTableColumnState(i,s,this.state);this.error=r?.error??void 0,!this.error&&this.$refs.serverState&&(this.$refs.serverState.value=this.state?"1":"0"),this.isLoading=!1})},getServerState(){if(this.$refs.serverState)return[1,"1"].includes(this.$refs.serverState.value)}}}export{o as default};
File diff suppressed because one or more lines are too long
@@ -0,0 +1 @@
function o({name:i,recordKey:s,state:a}){return{error:void 0,isLoading:!1,state:a,init(){Livewire.hook("commit",({component:e,commit:r,succeed:n,fail:d,respond:u})=>{n(({snapshot:f,effect:h})=>{this.$nextTick(()=>{if(this.isLoading||e.id!==this.$root.closest("[wire\\:id]")?.attributes["wire:id"].value)return;let t=this.getServerState();t===void 0||this.getNormalizedState()===t||(this.state=t)})})}),this.$watch("state",async()=>{let e=this.getServerState();if(e===void 0||this.getNormalizedState()===e)return;this.isLoading=!0;let r=await this.$wire.updateTableColumnState(i,s,this.state);this.error=r?.error??void 0,!this.error&&this.$refs.serverState&&(this.$refs.serverState.value=this.getNormalizedState()),this.isLoading=!1})},getServerState(){if(this.$refs.serverState)return[null,void 0].includes(this.$refs.serverState.value)?"":this.$refs.serverState.value.replaceAll('\\"','"')},getNormalizedState(){let e=Alpine.raw(this.state);return[null,void 0].includes(e)?"":e}}}export{o as default};
@@ -0,0 +1 @@
function o({name:i,recordKey:s,state:a}){return{error:void 0,isLoading:!1,state:a,init(){Livewire.hook("commit",({component:e,commit:r,succeed:n,fail:h,respond:u})=>{n(({snapshot:f,effect:d})=>{this.$nextTick(()=>{if(this.isLoading||e.id!==this.$root.closest("[wire\\:id]")?.attributes["wire:id"].value)return;let t=this.getServerState();t===void 0||Alpine.raw(this.state)===t||(this.state=t)})})}),this.$watch("state",async()=>{let e=this.getServerState();if(e===void 0||Alpine.raw(this.state)===e)return;this.isLoading=!0;let r=await this.$wire.updateTableColumnState(i,s,this.state);this.error=r?.error??void 0,!this.error&&this.$refs.serverState&&(this.$refs.serverState.value=this.state?"1":"0"),this.isLoading=!1})},getServerState(){if(this.$refs.serverState)return[1,"1"].includes(this.$refs.serverState.value)}}}export{o as default};
File diff suppressed because one or more lines are too long
@@ -0,0 +1,595 @@
---
title: Overview
---
import Aside from "@components/Aside.astro"
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
Tables are a common UI pattern for displaying lists of records in web applications. Filament provides a PHP-based API for defining tables with many features, while also being incredibly customizable.
### 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/overview). You can even [create your own custom column types](columns/custom-columns) 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/overview/columns" alt="Table with columns" version="4.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/overview#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/overview/searchable-columns" alt="Table with searchable column" version="4.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/overview#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/overview/sortable-columns" alt="Table with sortable column" version="4.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/overview/relationship-columns" alt="Table with relationship column" version="4.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", and you can use it to display any attribute of any relationship, even nested relationships. Filament uses this dot notation to eager-load the results of that relationship for you.
For more information about column relationships, visit the [Relationships section](columns/overview#displaying-data-from-relationships).
#### Adding new columns alongside existing columns
While the `columns()` method redefines all columns for a table, you may sometimes want to add columns to an existing configuration without overriding it completely. This is particularly useful when you have global column configurations that should appear across multiple tables.
Filament provides the `pushColumns()` method for this purpose. Unlike `columns()`, which replaces the entire column configuration, `pushColumns()` appends new columns to any existing ones.
This is especially powerful when combined with [global table settings](#global-settings) in the `boot()` method of a service provider, such as `AppServiceProvider`:
```php
use Filament\Tables\Columns\TextColumn;
use Filament\Tables\Table;
Table::configureUsing(function (Table $table) {
$table
->pushColumns([
TextColumn::make('created_at')
->label('Created')
->sortable()
->toggleable(isToggledHiddenByDefault: true),
TextColumn::make('updated_at')
->label('Updated')
->sortable()
->toggleable(isToggledHiddenByDefault: true),
]);
});
```
### Defining table filters
As well as making columns `searchable()`, which allows the user to filter the table by searching the content of columns, you can also allow the users to filter rows in the table in other ways. [Filters](filters) can be 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/overview/filters" alt="Table with filters" version="4.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.
You can use any [schema component](../schemas) to build the UI for a filter. 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#record-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\Actions\Action;
use Filament\Actions\BulkActionGroup;
use Filament\Actions\DeleteBulkAction;
public function table(Table $table): Table
{
return $table
->columns([
// ...
])
->recordActions([
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),
])
->toolbarActions([
BulkActionGroup::make([
DeleteBulkAction::make(),
]),
]);
}
```
<AutoScreenshot name="tables/overview/actions" alt="Table with actions" version="4.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/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/overview/actions-modal" alt="Table with action modal open" version="4.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) to learn more about their extensive capabilities throughout Filament.
## Pagination
By default, Filament tables will be paginated. The user can choose between 5, 10, 25, and 50 records per page. If there are more records than the selected number, the user can navigate between pages using the pagination buttons.
### 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']);
}
```
<Aside variant="warning">
Be aware when using very high numbers and `all` as large number of records can cause performance issues.
</Aside>
### 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);
}
```
<Aside variant="info">
Make sure that the default pagination page option is included in the [pagination options](#customizing-the-pagination-options).
</Aside>
### 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 using the `paginationMode(PaginationMode::Simple)` method:
```php
use Filament\Tables\Enums\PaginationMode;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->paginationMode(PaginationMode::Simple);
}
```
### Using cursor pagination
You may use cursor pagination by using the `paginationMode(PaginationMode::Cursor)` method:
```php
use Filament\Tables\Enums\PaginationMode;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->paginationMode(PaginationMode::Cursor);
}
```
### 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');
}
```
### 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);
}
```
## 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]),
);
}
```
When using a [resource](../resources) table, the URL for each row is usually already set up for you, but this method can be called to override the default URL for each row.
<Aside variant="tip">
You can also [override the URL](columns/overview#opening-urls) for a specific column, or [trigger an action](columns/overview#triggering-actions) when a column is clicked.
</Aside>
You may also open the URL in a new tab:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->openRecordUrlInNewTab();
}
```
## 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');
}
```
The `sort` database column in this example will be used to store the order of records in the table. Whenever you order a database query using that column, they will be returned in the defined order. 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="4.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());
}
```
You can pass a `direction` parameter as `desc` to reorder the records in descending order instead of ascending:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->reorderable('sort', direction: 'desc');
}
```
### Enabling pagination while reordering
Pagination will be disabled in reorder mode to allow you to move records between pages. It is generally a bad experience to have pagination while reordering, but if would like to override this 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/overview) can be used:
```php
use Filament\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="4.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 HTML:
```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 use the `searchUsing()` method with a `whereKey()` clause to filter the query for Scout results:
```php
use App\Models\Post;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
public function table(Table $table): Table
{
return $table
->searchUsing(fn (Builder $query, string $search) => $query->whereKey(Post::search($search)->keys()));
```
Under normal circumstances Scout uses the `whereKey()` (`whereIn()`) method to retrieve results internally, so there is no performance penalty for using it.
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();
}
```
## 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="4.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 App\Models\Post;
use Closure;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
public function table(Table $table): Table
{
return $table
->recordClasses(fn (Post $record) => match ($record->status) {
'draft' => 'draft-post-table-row',
'reviewing' => 'reviewing-post-table-row',
'published' => 'published-post-table-row',
default => null,
});
}
```
## Global settings
To customize the default configuration 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
->reorderableColumns()
->filtersLayout(FiltersLayout::AboveContentCollapsible)
->paginationPageOptions([10, 25, 50]);
});
```
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,753 @@
---
title: Text column
---
import Aside from "@components/Aside.astro"
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
Text columns display simple text:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('title')
```
<AutoScreenshot name="tables/columns/text/simple" alt="Text column" version="4.x" />
## Customizing the color
You may set a [color](../../styling/colors) for the text:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('status')
->color('primary')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `color()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/color" alt="Text column in the primary color" version="4.x" />
## Adding an icon
Text columns may also have an [icon](../../styling/icons):
```php
use Filament\Tables\Columns\TextColumn;
use Filament\Support\Icons\Heroicon;
TextColumn::make('email')
->icon(Heroicon::Envelope)
```
<UtilityInjection set="tableColumns" version="4.x">The `icon()` method also accepts a function to dynamically calculate the icon. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/icon" alt="Text column with icon" version="4.x" />
You may set the position of an icon using `iconPosition()`:
```php
use Filament\Tables\Columns\TextColumn;
use Filament\Support\Enums\IconPosition;
use Filament\Support\Icons\Heroicon;
TextColumn::make('email')
->icon(Heroicon::Envelope)
->iconPosition(IconPosition::After) // `IconPosition::Before` or `IconPosition::After`
```
<UtilityInjection set="tableColumns" version="4.x">The `iconPosition()` method also accepts a function to dynamically calculate the icon position. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/icon-after" alt="Text column with icon after" version="4.x" />
The icon color defaults to the text color, but you may customize the icon [color](../../styling/colors) separately using `iconColor()`:
```php
use Filament\Tables\Columns\TextColumn;
use Filament\Support\Icons\Heroicon;
TextColumn::make('email')
->icon(Heroicon::Envelope)
->iconColor('primary')
```
<UtilityInjection set="tableColumns" version="4.x">The `iconColor()` method also accepts a function to dynamically calculate the icon color. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/icon-color" alt="Text column with icon in the primary color" version="4.x" />
## Displaying as a "badge"
By default, 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="4.x" />
You may add other things to the badge, like an [icon](#adding-an-icon).
Optionally, you may pass a boolean value to control if the text should be in a badge or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('status')
->badge(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `badge()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Formatting
When using a text column, you may want the actual outputted text in the UI to differ from the raw [state](overview#column-content-state) of the column, which is often automatically retrieved from an Eloquent model. Formatting the state allows you to preserve the integrity of the raw data while also allowing it to be presented in a more user-friendly way.
To format the state of a text column without changing the state itself, you can use the `formatStateUsing()` method. This method accepts a function that takes the state as an argument and returns the formatted state:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('status')
->formatStateUsing(fn (string $state): string => __("statuses.{$state}"))
```
In this case, the `status` column in the database might contain values like `draft`, `reviewing`, `published`, or `rejected`, but the formatted state will be the translated version of these values.
<UtilityInjection set="tableColumns" version="4.x">The function passed to `formatStateUsing()` can inject various utilities as parameters.</UtilityInjection>
### Date formatting
Instead of passing a function to `formatStateUsing()`, you may use the `date()`, `dateTime()`, and `time()` 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')
->date()
TextColumn::make('created_at')
->dateTime()
TextColumn::make('created_at')
->time()
```
You may customize the date format by passing a custom format string to the `date()`, `dateTime()`, or `time()` method. You may use any [PHP date formatting tokens](https://www.php.net/manual/en/datetime.format.php):
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('created_at')
->date('M j, Y')
TextColumn::make('created_at')
->dateTime('M j, Y H:i:s')
TextColumn::make('created_at')
->time('H:i:s')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `date()`, `dateTime()`, and `time()` methods also accept a function to dynamically calculate the format. You can inject various utilities into the function as parameters.</UtilityInjection>
#### Date formatting using Carbon macro formats
You may use also the `isoDate()`, `isoDateTime()`, and `isoTime()` methods to format the column's state using [Carbon's macro-formats](https://carbon.nesbot.com/docs/#available-macro-formats):
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('created_at')
->isoDate()
TextColumn::make('created_at')
->isoDateTime()
TextColumn::make('created_at')
->isoTime()
```
You may customize the date format by passing a custom macro format string to the `isoDate()`, `isoDateTime()`, or `isoTime()` method. You may use any [Carbon's macro-formats](https://carbon.nesbot.com/docs/#available-macro-formats):
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('created_at')
->isoDate('L')
TextColumn::make('created_at')
->isoDateTime('LLL')
TextColumn::make('created_at')
->isoTime('LT')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `isoDate()`, `isoDateTime()`, and `isoTime()` methods also accept a function to dynamically calculate the format. You can inject various utilities into the function as parameters.</UtilityInjection>
#### Relative date formatting
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()
```
#### Displaying a formatting date in a tooltip
Additionally, you can use the `dateTooltip()`, `dateTimeTooltip()`, `timeTooltip()`, `isoDateTooltip()`, `isoDateTimeTooltip()`, `isoTime()`, `isoTimeTooltip()`, or `sinceTooltip()` method to display a formatted date in a [tooltip](overview#adding-a-tooltip-to-an-column), often to provide extra information:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('created_at')
->since()
->dateTooltip() // Accepts a custom PHP date formatting string
TextColumn::make('created_at')
->since()
->dateTimeTooltip() // Accepts a custom PHP date formatting string
TextColumn::make('created_at')
->since()
->timeTooltip() // Accepts a custom PHP date formatting string
TextColumn::make('created_at')
->since()
->isoDateTooltip() // Accepts a custom Carbon macro format string
TextColumn::make('created_at')
->since()
->isoDateTimeTooltip() // Accepts a custom Carbon macro format string
TextColumn::make('created_at')
->since()
->isoTimeTooltip() // Accepts a custom Carbon macro format string
TextColumn::make('created_at')
->dateTime()
->sinceTooltip()
```
#### Setting the timezone for date formatting
Each of the date formatting methods listed above also accepts a `timezone` argument, which allows you to convert the time set in the state to a different timezone:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('created_at')
->dateTime(timezone: 'America/New_York')
```
You can also pass a timezone to the `timezone()` method of the column to apply a timezone to all date-time formatting methods at once:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('created_at')
->timezone('America/New_York')
->dateTime()
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `timezone()` method also accepts a function to dynamically calculate the timezone. You can inject various utilities into the function as parameters.</UtilityInjection>
If you do not pass a `timezone()` to the column, it will use Filament's default timezone. You can set Filament's default timezone using the `FilamentTimezone::set()` method in the `boot()` method of a service provider such as `AppServiceProvider`:
```php
use Filament\Support\Facades\FilamentTimezone;
public function boot(): void
{
FilamentTimezone::set('America/New_York');
}
```
This is useful if you want to set a default timezone for all text columns in your application. It is also used in other places where timezones are used in Filament.
<Aside variant="warning">
Filament's default timezone will only apply when the column stores a time. If the column stores a date only (`date()` instead of `dateTime()`), the timezone will not be applied. This is to prevent timezone shifts when storing dates without times.
</Aside>
### Number formatting
Instead of passing a function to `formatStateUsing()`, you can use the `numeric()` method to format a column 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)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `decimalPlaces` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
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')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `locale` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Money formatting
Instead of passing a function to `formatStateUsing()`, you can use the `money()` method to easily format amounts of money, in any currency:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('price')
->money('EUR')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `money()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
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)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `divideBy` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
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')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `locale` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
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('price')
->money('EUR', decimalPlaces: 3)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `decimalPlaces` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Rendering Markdown
If your column value is Markdown, you may render it using `markdown()`:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->markdown()
```
Optionally, you may pass a boolean value to control if the text should be rendered as Markdown or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->markdown(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `markdown()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Rendering HTML
If your column value is HTML, you may render it using `html()`:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->html()
```
Optionally, you may pass a boolean value to control if the text should be rendered as HTML or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->html(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `html()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
#### Rendering raw HTML without sanitization
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))
```
<Aside variant="danger">
Be cautious when rendering raw HTML, as it may contain malicious content, which can lead to security vulnerabilities in your app such as cross-site scripting (XSS) attacks. Always ensure that the HTML you are rendering is safe before using this method.
</Aside>
Alternatively, 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-column-content',
['state' => $state],
))
```
## 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)
```
<UtilityInjection set="tableColumns" version="4.x">The function passed to `description()` can inject various utilities as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/description" alt="Text column with description" version="4.x" />
By default, the description is displayed below the main text, but you can move it using `'above'` as 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="4.x" />
## Listing multiple values
Multiple values can be rendered in a text column if its [state](overview#column-content-state) is an array. This can happen if you are using an `array` cast on an Eloquent attribute, an Eloquent relationship with multiple results, or if you have passed an array to the [`state()` method](overview#setting-the-state-of-an-column). 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()
```
Optionally, you may pass a boolean value to control if the text should have line breaks between each item or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('authors.name')
->listWithLineBreaks(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `listWithLineBreaks()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### 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')
->bulleted()
```
Optionally, you may pass a boolean value to control if the text should have bullet points or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('authors.name')
->bulleted(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `bulleted()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### 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)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `limitList()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
#### 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()
```
<Aside variant="info">
This is only a feature for `listWithLineBreaks()` or `bulleted()`, where each item is on its own line.
</Aside>
Optionally, you may pass a boolean value to control if the text should be expandable or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('authors.name')
->listWithLineBreaks()
->limitList(3)
->expandableLimitedList(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `expandableLimitedList()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Splitting a single value into multiple list items
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(',')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `separator()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Customizing the text size
Text columns have small font size by default, but you may change this to `TextSize::ExtraSmall`, `TextSize::Medium`, or `TextSize::Large`.
For instance, you may make the text larger using `size(TextSize::Large)`:
```php
use Filament\Tables\Columns\TextColumn;
use Filament\Support\Enums\TextSize;
TextColumn::make('title')
->size(TextSize::Large)
```
<AutoScreenshot name="tables/columns/text/large" alt="Text column in a large font size" version="4.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\Tables\Columns\TextColumn;
use Filament\Support\Enums\FontWeight;
TextColumn::make('title')
->weight(FontWeight::Bold)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `weight()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/bold" alt="Text column in a bold font" version="4.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 monospaced using `fontFamily(FontFamily::Mono)`:
```php
use Filament\Support\Enums\FontFamily;
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->fontFamily(FontFamily::Mono)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `fontFamily()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/text/mono" alt="Text column in a monospaced font" version="4.x" />
## Handling long text
### Limiting text length
You may `limit()` the length of the column's value:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->limit(50)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `limit()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
By default, when text is truncated, an ellipsis (`...`) is appended to the end of the text. You may customize this by passing a custom string to the `end` argument:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->limit(50, end: ' (more)')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `end` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
You may also reuse the value that is being passed to `limit()` in a function, by getting it using the `getCharacterLimit()` method:
```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 contents exceeds the length limit.
return $state;
})
```
### Limiting word count
You may limit the number of `words()` displayed in the column:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->words(10)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `words()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
By default, when text is truncated, an ellipsis (`...`) is appended to the end of the text. You may customize this by passing a custom string to the `end` argument:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->words(10, end: ' (more)')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `end` argument also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Allowing text wrapping
By default, text will not wrap to the next line if it exceeds the width of the container. You can enable this behavior using the `wrap()` method:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->wrap()
```
Optionally, you may pass a boolean value to control if the text should wrap or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('description')
->wrap(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `wrap()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
#### 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')
->wrap()
->lineClamp(2)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `lineClamp()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Allowing the text to be copied to the clipboard
You may make the text copyable, such that clicking on the column copies the text to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds:
```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="4.x" />
Optionally, you may pass a boolean value to control if the text should be copyable or not:
```php
use Filament\Tables\Columns\TextColumn;
TextColumn::make('email')
->copyable(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `copyable()`, `copyMessage()`, and `copyMessageDuration()` methods also accept functions to dynamically calculate them. You can inject various utilities into the function as parameters.</UtilityInjection>
<Aside variant="warning">
This feature only works when SSL is enabled for the app.
</Aside>
@@ -0,0 +1,147 @@
---
title: Icon column
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
import Aside from "@components/Aside.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
Icon columns render an [icon](../../styling/icons) representing the state of the column:
```php
use Filament\Tables\Columns\IconColumn;
use Filament\Support\Icons\Heroicon;
IconColumn::make('status')
->icon(fn (string $state): Heroicon => match ($state) {
'draft' => Heroicon::OutlinedPencil,
'reviewing' => Heroicon::OutlinedClock,
'published' => Heroicon::OutlinedCheckCircle,
})
```
<UtilityInjection set="tableColumns" version="4.x">The `icon()` method can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/icon/simple" alt="Icon column" version="4.x" />
## Customizing the color
You may change the [color](../../styling/colors) of the icon, using the `color()` method:
```php
use Filament\Tables\Columns\IconColumn;
IconColumn::make('status')
->color('success')
```
By passing a function to `color()`, you can customize the color based on the state of the column:
```php
use Filament\Tables\Columns\IconColumn;
IconColumn::make('status')
->color(fn (string $state): string => match ($state) {
'draft' => 'info',
'reviewing' => 'warning',
'published' => 'success',
default => 'gray',
})
```
<UtilityInjection set="tableColumns" version="4.x">The `color()` method can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/icon/color" alt="Icon column with color" version="4.x" />
## Customizing the size
The default icon size is `IconSize::Large`, but you may customize the size to be either `IconSize::ExtraSmall`, `IconSize::Small`, `IconSize::Medium`, `IconSize::ExtraLarge` or `IconSize::TwoExtraLarge`:
```php
use Filament\Tables\Columns\IconColumn;
use Filament\Support\Enums\IconSize;
IconColumn::make('status')
->size(IconSize::Medium)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `size()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/icon/medium" alt="Medium-sized icon column" version="4.x" />
## Handling booleans
Icon columns can display a check or "X" icon based on the state of the column, either true or false, using the `boolean()` method:
```php
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->boolean()
```
> If this attribute 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="4.x" />
Optionally, you may pass a boolean value to control if the icon should be boolean or not:
```php
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->boolean(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `boolean()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Customizing the boolean icons
You may customize the [icon](../../styling/icons) representing each state:
```php
use Filament\Tables\Columns\IconColumn;
use Filament\Support\Icons\Heroicon;
IconColumn::make('is_featured')
->boolean()
->trueIcon(Heroicon::OutlinedCheckBadge)
->falseIcon(Heroicon::OutlinedXMark)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `trueIcon()` and `falseIcon()` methods also accept functions to dynamically calculate them. You can inject various utilities into the functions as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/icon/boolean-icon" alt="Icon column to display a boolean with custom icons" version="4.x" />
### Customizing the boolean colors
You may customize the icon [color](../../styling/colors) representing each state:
```php
use Filament\Tables\Columns\IconColumn;
IconColumn::make('is_featured')
->boolean()
->trueColor('info')
->falseColor('warning')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `trueColor()` and `falseColor()` methods also accept functions to dynamically calculate them. You can inject various utilities into the functions as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/icon/boolean-color" alt="Icon column to display a boolean with custom colors" version="4.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()
```
<Aside variant="tip">
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.
</Aside>
@@ -0,0 +1,308 @@
---
title: Image column
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
import Aside from "@components/Aside.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
Tables can render images, based on the path in the state of the column:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('avatar')
```
In this case, the `header_image` state could contain `posts/header-images/4281246003439.jpg`, which is relative to the root directory of the storage disk. The storage disk is defined in the [configuration file](../../introduction/installation#publishing-configuration), `local` by default. You can also set the `FILESYSTEM_DISK` environment variable to change this.
Alternatively, the state could contain an absolute URL to an image, such as `https://example.com/images/header.jpg`.
<AutoScreenshot name="tables/columns/image/simple" alt="Image column" version="4.x" />
## Managing the image disk
The default storage disk is defined in the [configuration file](../../introduction/installation#publishing-configuration), `local` by default. You can also set the `FILESYSTEM_DISK` environment variable to change this. If you want to deviate from the default disk, you may pass a custom disk name to the `disk()` method:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('header_image')
->disk('s3')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `disk()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Public images
By default, Filament will generate temporary URLs to images in the filesystem, unless the [disk](#managing-the-image-disk) is set to `public`. If your images are stored in a public disk, you can set the `visibility()` to `public`:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('header_image')
->visibility('public')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `visibility()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Customizing the size
You may customize the image size by passing a `imageWidth()` and `imageHeight()`, or both with `imageSize()`:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('header_image')
->imageWidth(200)
ImageColumn::make('header_image')
->imageHeight(50)
ImageColumn::make('avatar')
->imageSize(40)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static values, the `imageWidth()`, `imageHeight()` and `imageSize()` methods also accept functions to dynamically calculate them. You can inject various utilities into the function as parameters.</UtilityInjection>
### Square images
You may display the image using a 1:1 aspect ratio:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('avatar')
->imageHeight(40)
->square()
```
<AutoScreenshot name="tables/columns/image/square" alt="Square image column" version="4.x" />
Optionally, you may pass a boolean value to control if the image should be square or not:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('avatar')
->imageHeight(40)
->square(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `square()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Circular images
You may make the image fully rounded, which is useful for rendering avatars:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('avatar')
->imageHeight(40)
->circular()
```
<AutoScreenshot name="tables/columns/image/circular" alt="Circular image column" version="4.x" />
Optionally, you may pass a boolean value to control if the image should be circular or not:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('avatar')
->imageHeight(40)
->circular(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `circular()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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('header_image')
->defaultImageUrl(url('storage/posts/header-images/default.jpg'))
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `defaultImageUrl()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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')
->imageHeight(40)
->circular()
->stacked()
```
<AutoScreenshot name="tables/columns/image/stacked" alt="Stacked image column" version="4.x" />
Optionally, you may pass a boolean value to control if the images should be stacked or not:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('colleagues.avatar')
->imageHeight(40)
->circular()
->stacked(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `stacked()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Customizing the stacked ring width
The default ring width is `3`, but you may customize it to be from `0` to `8`:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('colleagues.avatar')
->imageHeight(40)
->circular()
->stacked()
->ring(5)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `ring()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Customizing the stacked overlap
The default overlap is `4`, but you may customize it to be from `0` to `8`:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('colleagues.avatar')
->imageHeight(40)
->circular()
->stacked()
->overlap(2)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `overlap()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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')
->imageHeight(40)
->circular()
->stacked()
->limit(3)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `limit()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/columns/image/limited" alt="Limited image column" version="4.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')
->imageHeight(40)
->circular()
->stacked()
->limit(3)
->limitedRemainingText()
```
<AutoScreenshot name="tables/columns/image/limited-remaining-text" alt="Limited image column with remaining text" version="4.x" />
Optionally, you may pass a boolean value to control if the remaining text should be displayed or not:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('colleagues.avatar')
->imageHeight(40)
->circular()
->stacked()
->limit(3)
->limitedRemainingText(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `limitedRemainingText()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
#### Customizing the limited remaining text size
By default, the size of the remaining text is `TextSize::Small`. You can customize this to be `TextSize::ExtraSmall`, `TextSize::Medium` or `TextSize::Large` using the `size` parameter:
```php
use Filament\Tables\Columns\ImageColumn;
use Filament\Support\Enums\TextSize;
ImageColumn::make('colleagues.avatar')
->imageHeight(40)
->circular()
->stacked()
->limit(3)
->limitedRemainingText(size: TextSize::Large)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `limitedRemainingText()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Prevent file existence checks
When the schema is loaded, it will automatically detect whether the images exist to prevent errors for missing files. 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)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `checkFileExistence()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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()
```
<Aside variant="tip">
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.
</Aside>
## Adding extra HTML attributes to the image
You can pass extra HTML attributes to the `<img>` element via the `extraImgAttributes()` method. The attributes should be represented by an array, where the key is the attribute name and the value is the attribute value:
```php
use Filament\Tables\Columns\ImageColumn;
ImageColumn::make('logo')
->extraImgAttributes([
'alt' => 'Logo',
'loading' => 'lazy',
])
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `extraImgAttributes()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
By default, calling `extraImgAttributes()` multiple times will overwrite the previous attributes. If you wish to merge the attributes instead, you can pass `merge: true` to the method.
@@ -0,0 +1,59 @@
---
title: Color column
---
import Aside from "@components/Aside.astro"
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
The color column allows you to show the color preview from a CSS color definition, typically entered using the [color picker field](../../forms/color-picker), 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="4.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('Copied!')
->copyMessageDuration(1500)
```
<AutoScreenshot name="tables/columns/color/copyable" alt="Color column with a button to copy it" version="4.x" />
Optionally, you may pass a boolean value to control if the text should be copyable or not:
```php
use Filament\Tables\Columns\ColorColumn;
ColorColumn::make('color')
->copyable(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `copyable()`, `copyMessage()`, and `copyMessageDuration()` methods also accept functions to dynamically calculate them. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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()
```
<Aside variant="tip">
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.
</Aside>
@@ -0,0 +1,466 @@
---
title: Select column
---
import Aside from "@components/Aside.astro"
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
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="4.x" />
## Enabling the JavaScript select
By default, Filament uses the native HTML5 select. You may enable a more customizable JavaScript select using the `native(false)` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->native(false)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `native()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Searching options
You may enable a search input to allow easier access to many options, using the `searchableOptions()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->label('Author')
->options(User::query()->pluck('name', 'id'))
->searchableOptions()
```
Optionally, you may pass a boolean value to control if the input should be searchable or not:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->label('Author')
->options(User::query()->pluck('name', 'id'))
->searchableOptions(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `searchableOptions()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Returning custom search results
If you have lots of options and want to populate them based on a database search or other external data source, you can use the `getOptionsSearchResultsUsing()` and `getOptionLabelUsing()` methods instead of `options()`.
The `getOptionsSearchResultsUsing()` method accepts a callback that returns search results in `$key => $value` format. The current user's search is available as `$search`, and you should use that to filter your results.
The `getOptionLabelUsing()` method accepts a callback that transforms the selected option `$value` into a label. This is used when the form is first loaded when the user has not made a search yet. Otherwise, the label used to display the currently selected option would not be available.
Both `getOptionsSearchResultsUsing()` and `getOptionLabelUsing()` must be used on the select if you want to provide custom search results:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->searchableOptions()
->getOptionsSearchResultsUsing(fn (string $search): array => User::query()
->where('name', 'like', "%{$search}%")
->limit(50)
->pluck('name', 'id')
->all())
->getOptionLabelUsing(fn ($value): ?string => User::find($value)?->name),
```
`getOptionLabelUsing()` is crucial, since it provides Filament with the label of the selected option, so it doesn't need to execute a full search to find it. If an option is not valid, it should return `null`.
<UtilityInjection set="tableColumns" version="4.x" extras="Option value;;mixed;;$value;;The option value to retrieve the label for.||Search;;?string;;$search;;[<code>getOptionsSearchResultsUsing()</code> only] The current search input value, if the field is searchable.">You can inject various utilities into these functions as parameters.</UtilityInjection>
### Setting a custom loading message
When you're using a searchable select or multi-select, you may want to display a custom message while the options are loading. You can do this using the `optionsLoadingMessage()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->optionsLoadingMessage('Loading authors...')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `optionsLoadingMessage()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Setting a custom no search results message
When you're using a searchable select or multi-select, you may want to display a custom message when no search results are found. You can do this using the `noOptionsSearchResultsMessage()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->noOptionsSearchResultsMessage('No authors found.')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `noOptionsSearchResultsMessage()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Setting a custom search prompt
When you're using a searchable select or multi-select, you may want to display a custom message when the user has not yet entered a search term. You can do this using the `optionsSearchPrompt()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions(['name', 'email'])
->optionsSearchPrompt('Search authors by their name or email address')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `optionsSearchPrompt()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Setting a custom searching message
When you're using a searchable select or multi-select, you may want to display a custom message while the search results are being loaded. You can do this using the `optionsSearchingMessage()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->optionsSearchingMessage('Searching authors...')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `optionsSearchingMessage()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Tweaking the search debounce
By default, Filament will wait 1000 milliseconds (1 second) before searching for options when the user types in a searchable select or multi-select. It will also wait 1000 milliseconds between searches, if the user is continuously typing into the search input. You can change this using the `optionsSearchDebounce()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->optionsSearchDebounce(500)
```
Ensure that you are not lowering the debounce too much, as this may cause the select to become slow and unresponsive due to a high number of network requests to retrieve options from server.
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `optionsSearchDebounce()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Integrating with an Eloquent relationship
You may employ the `optionsRelationship()` method of the `SelectColumn` to configure a `BelongsTo` relationship to automatically retrieve options from. The `titleAttribute` is the name of a column that will be used to generate a label for each option:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
```
### Searching relationship options across multiple columns
By default, if the select is also searchable, Filament will return search results for the relationship based on the title column of the relationship. If you'd like to search across multiple columns, you can pass an array of columns to the `searchableOptions()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions(['name', 'email'])
```
### Preloading 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 `preloadOptions()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->preloadOptions()
```
Optionally, you may pass a boolean value to control if the input should be preloaded or not:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->preload(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `preload()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
### Excluding the current record
When working with recursive relationships, you will likely want to remove the current record from the set of results.
This can be easily be done using the `ignoreRecord` argument:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('parent_id')
->optionsRelationship(name: 'parent', titleAttribute: 'name', ignoreRecord: true)
```
### Customizing the relationship query
You may customize the database query that retrieves options using the third parameter of the `optionsRelationship()` method:
```php
use Filament\Tables\Columns\SelectColumn;
use Illuminate\Database\Eloquent\Builder;
SelectColumn::make('author_id')
->optionsRelationship(
name: 'author',
titleAttribute: 'name',
modifyQueryUsing: fn (Builder $query) => $query->withTrashed(),
)
```
<UtilityInjection set="tableColumns" version="4.x" extras="Query;;Illuminate\Database\Eloquent\Builder;;$query;;The Eloquent query builder to modify.||Search;;?string;;$search;;The current search input value, if the field is searchable.">The `modifyQueryUsing` argument can inject various utilities into the function as parameters.</UtilityInjection>
### Customizing the relationship option labels
If you'd like to customize the label of each option, maybe to be more descriptive, or to concatenate a first and last name, you could use a virtual column in your database migration:
```php
$table->string('full_name')->virtualAs('concat(first_name, \' \', last_name)');
```
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'full_name')
```
Alternatively, you can use the `getOptionLabelFromRecordUsing()` method to transform an option's Eloquent model into a label:
```php
use Filament\Tables\Columns\SelectColumn;
use Illuminate\Database\Eloquent\Builder;
use Illuminate\Database\Eloquent\Model;
SelectColumn::make('author_id')
->optionsRelationship(
name: 'author',
modifyQueryUsing: fn (Builder $query) => $query->orderBy('first_name')->orderBy('last_name'),
)
->getOptionLabelFromRecordUsing(fn (Model $record) => "{$record->first_name} {$record->last_name}")
->searchableOptions(['first_name', 'last_name'])
```
<UtilityInjection set="tableColumns" version="4.x" extras="Eloquent record;;Illuminate\Database\Eloquent\Model;;$record;;The Eloquent record to get the option label for.">The `getOptionLabelFromRecordUsing()` method can inject various utilities into the function as parameters.</UtilityInjection>
### Remembering options
By default, when using `optionsRelationship()`, Filament will remember the options for the duration of the table page to improve performance. This means that the options function will only run once per table page instead of once per cell. You can disable this behavior using the `rememberOptions(false)` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->rememberOptions(false)
```
<Aside variant="warning">
When options are remembered, any record-specific options or disabled options will not work correctly, as the same options will be used for all records in the table. If you need record-specific options or disabled options, you should disable option remembering.
</Aside>
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `rememberOptions()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Allowing HTML in the option labels
By default, Filament will escape any HTML in the option labels. If you'd like to allow HTML, you can use the `allowOptionsHtml()` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('technology')
->options([
'tailwind' => '<span class="text-blue-500">Tailwind</span>',
'alpine' => '<span class="text-green-500">Alpine</span>',
'laravel' => '<span class="text-red-500">Laravel</span>',
'livewire' => '<span class="text-pink-500">Livewire</span>',
])
->searchableOptions()
->allowOptionsHtml()
```
<Aside variant="danger">
Be aware that you will need to ensure that the HTML is safe to render, otherwise your application will be vulnerable to XSS attacks.
</Aside>
Optionally, you may pass a boolean value to control if the input should allow HTML or not:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('technology')
->options([
'tailwind' => '<span class="text-blue-500">Tailwind</span>',
'alpine' => '<span class="text-green-500">Alpine</span>',
'laravel' => '<span class="text-red-500">Laravel</span>',
'livewire' => '<span class="text-pink-500">Livewire</span>',
])
->searchableOptions()
->allowOptionsHtml(FeatureFlag::active())
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `allowOptionsHtml()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Wrap or truncate option labels
When using the JavaScript select, labels that exceed the width of the select element will wrap onto multiple lines by default. Alternatively, you may choose to truncate overflowing labels.
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('truncate')
->wrapOptionLabels(false)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `wrapOptionLabels()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Disable placeholder selection
You can prevent the placeholder (null option) from being selected using the `selectablePlaceholder(false)` method:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->selectablePlaceholder(false)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `selectablePlaceholder()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Disabling specific options
You can disable specific options using the `disableOptionWhen()` method. It accepts a closure, in which you can check if the option with a specific `$value` should be disabled:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->default('draft')
->disableOptionWhen(fn (string $value): bool => $value === 'published')
```
<UtilityInjection set="tableColumns" version="4.x" extras="Option value;;mixed;;$value;;The value of the option to disable.||Option label;;string | Illuminate\Contracts\Support\Htmlable;;$label;;The label of the option to disable.">You can inject various utilities into the function as parameters.</UtilityInjection>
## Limiting the number of options
You can limit the number of options that are displayed in a searchable select or multi-select using the `optionsLimit()` method. The default is 50:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->optionsRelationship(name: 'author', titleAttribute: 'name')
->searchableOptions()
->optionsLimit(20)
```
Ensure that you are not raising the limit too high, as this may cause the select to become slow and unresponsive due to high in-browser memory usage.
<UtilityInjection set="tableColumns" version="4.x">As well as allowing a static value, the `optionsLimit()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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'])
```
### Valid options validation (`in` rule)
The `in` rule ensures that users cannot select an option that is not in the list of options. This is an important rule for data integrity purposes, so Filament applies it by default to all select fields.
Since there are many ways for a select field to populate its options, and in many cases the options are not all loaded into the select by default and require searching to retrieve them, Filament uses the presence of a valid "option label" to determine whether the selected value exists. It also checks if that option is [disabled](#disabling-specific-options) or not.
If you are using a custom search query to retrieve options, you should ensure that the `getOptionLabelUsing()` method is defined, so that Filament can validate the selected value against the available options:
```php
use Filament\Tables\Columns\SelectColumn;
SelectColumn::make('author_id')
->searchableOptions()
->getOptionsSearchResultsUsing(fn (string $search): array => Author::query()
->where('name', 'like', "%{$search}%")
->limit(50)
->pluck('name', 'id')
->all())
->getOptionLabelUsing(fn (string $value): ?string => Author::find($value)?->name),
```
The `getOptionLabelUsing()` method should return `null` if the option is not valid, to allow Filament to determine that the selected value is not in the list of options. If the option is valid, it should return the label of the option.
If you are using the `optionsRelationship()` method, the `getOptionLabelUsing()` method will be automatically defined for you, so you don't need to worry about it.
## 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.
})
```
@@ -0,0 +1,30 @@
---
title: Toggle column
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
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="4.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.
})
```
@@ -0,0 +1,96 @@
---
title: Text input column
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
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="4.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.
})
```
## Adding affix text aside the field
You may place text before and after the input using the `prefix()` and `suffix()` methods:
```php
use Filament\Tables\Columns\TextInputColumn;
TextInputColumn::make('domain')
->prefix('https://')
->suffix('.com')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `prefix()` and `suffix()` methods also accept a function to dynamically calculate them. You can inject various utilities into the function as parameters.</UtilityInjection>
### Using icons as affixes
You may place an [icon](../../../../docs/08-styling/04-icons) before and after the input using the `prefixIcon()` and `suffixIcon()` methods:
```php
use Filament\Tables\Columns\TextInputColumn;
use Filament\Support\Icons\Heroicon;
TextInputColumn::make('domain')
->prefixIcon(Heroicon::GlobeAlt)
->suffixIcon(Heroicon::CheckCircle)
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `prefixIcon()` and `suffixIcon()` methods also accept a function to dynamically calculate them. You can inject various utilities into the function as parameters.</UtilityInjection>
#### Setting the affix icon's color
Affix icons are gray by default, but you may set a different color using the `prefixIconColor()` and `suffixIconColor()` methods:
```php
use Filament\Tables\Columns\TextInputColumn;
use Filament\Support\Icons\Heroicon;
TextInputColumn::make('status')
->suffixIcon(Heroicon::CheckCircle)
->suffixIconColor('success')
```
<UtilityInjection set="tableColumns" version="4.x">As well as allowing static values, the `prefixIconColor()` and `suffixIconColor()` methods also accept a function to dynamically calculate them. You can inject various utilities into the function as parameters.</UtilityInjection>
@@ -0,0 +1,30 @@
---
title: Checkbox column
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
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="4.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.
})
```
@@ -0,0 +1,162 @@
---
title: Custom columns
---
import Aside from "@components/Aside.astro"
## Introduction
You may create your own custom column classes and views, which you can reuse across your project, and even release as a plugin to the community.
To create a custom column class and view, you may use the following command:
```bash
php artisan make:filament-table-column AudioPlayerColumn
```
This will create the following component class:
```php
use Filament\Tables\Columns\Column;
class AudioPlayerColumn extends Column
{
protected string $view = 'filament.tables.columns.audio-player-column';
}
```
It will also create a view file at `resources/views/filament/tables/columns/audio-player-column.blade.php`.
<Aside variant="info">
Filament table columns are **not** Livewire components. Defining public properties and methods on a table column class will not make them accessible in the Blade view.
</Aside>
## Accessing the state of the column in the Blade view
Inside the Blade view, you may access the [state](overview#column-content-state) of the column using the `$getState()` function:
```blade
<div>
{{ $getState() }}
</div>
```
## Accessing the Eloquent record in the Blade view
Inside the Blade view, you may access the current table row's Eloquent record using the `$record` variable:
```blade
<div>
{{ $record->name }}
</div>
```
## Accessing the current Livewire component instance in the Blade view
Inside the Blade view, you may access the current Livewire component instance using `$this`:
```blade
@php
use Filament\Resources\Users\RelationManagers\ConferencesRelationManager;
@endphp
<div>
@if ($this instanceof ConferencesRelationManager)
You are editing the conferences of a user.
@endif
</div>
```
## Accessing the current column instance in the Blade view
Inside the Blade view, you may access the current column instance using `$column`. You can call public methods on this object to access other information that may not be available in variables:
```blade
<div>
@if ($column->isLabelHidden())
This is a new conference.
@endif
</div>
```
## Adding a configuration method to a custom column class
You may add a public method to the custom column class that accepts a configuration value, stores it in a protected property, and returns it again from another public method:
```php
use Filament\Tables\Columns\Column;
class AudioPlayerColumn extends Column
{
protected string $view = 'filament.tables.columns.audio-player-column';
protected ?float $speed = null;
public function speed(?float $speed): static
{
$this->speed = $speed;
return $this;
}
public function getSpeed(): ?float
{
return $this->speed;
}
}
```
Now, in the Blade view for the custom column, you may access the speed using the `$getSpeed()` function:
```blade
<div>
{{ $getSpeed() }}
</div>
```
Any public method that you define on the custom column class can be accessed in the Blade view as a variable function in this way.
To pass the configuration value to the custom column class, you may use the public method:
```php
use App\Filament\Tables\Columns\AudioPlayerColumn;
AudioPlayerColumn::make('recording')
->speed(0.5)
```
## Allowing utility injection in a custom column configuration method
[Utility injection](overview#column-utility-injection) is a powerful feature of Filament that allows users to configure a component using functions that can access various utilities. You can allow utility injection by ensuring that the parameter type and property type of the configuration allows the user to pass a `Closure`. In the getter method, you should pass the configuration value to the `$this->evaluate()` method, which will inject utilities into the user's function if they pass one, or return the value if it is static:
```php
use Closure;
use Filament\Tables\Columns\Column;
class AudioPlayerColumn extends Column
{
protected string $view = 'filament.tables.columns.audio-player-column';
protected float | Closure | null $speed = null;
public function speed(float | Closure | null $speed): static
{
$this->speed = $speed;
return $this;
}
public function getSpeed(): ?float
{
return $this->evaluate($this->speed);
}
}
```
Now, you can pass a static value or a function to the `speed()` method, and [inject any utility](overview#component-utility-injection) as a parameter:
```php
use App\Filament\Tables\Columns\AudioPlayerColumn;
AudioPlayerColumn::make('recording')
->speed(fn (Conference $record): float => $record->isGlobal() ? 1 : 0.5)
```
@@ -0,0 +1,305 @@
---
title: Overview
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
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.
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 Filament\Tables\Table;
use Illuminate\Database\Eloquent\Builder;
public function table(Table $table): Table
{
return $table
->filters([
Filter::make('is_featured')
->query(fn (Builder $query): Builder => $query->where('is_featured', true))
// ...
]);
}
```
<AutoScreenshot name="tables/filters/simple" alt="Table with filter" version="4.x" />
## 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 may use a [select filter](select) to allow users to select from a list of options, and filter using the selection.
- 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.
- The [trashed filter](ternary#filtering-soft-deletable-records) is a pre-built ternary filter that allows you to filter soft-deletable records.
- Using a [query builder](query-builder), users can 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 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')
```
<UtilityInjection set="tableFilters" version="4.x">As well as allowing a static value, the `label()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
Customizing the label in this way is useful if you wish to use a [translation string for localization](https://laravel.com/docs/localization#retrieving-translation-strings):
```php
use Filament\Tables\Filters\Filter;
Filter::make('is_featured')
->label(__('filters.is_featured'))
```
## Customizing the filter schema
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="4.x" />
### 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))
```
<UtilityInjection set="tableFilters" version="4.x" extras="Field;;Filament\Forms\Components\Field;;$field;;The field object to modify.">The function passed to `modifyFormFieldUsing()` can inject various utilities as parameters.</UtilityInjection>
## 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()
```
If you're using a [select filter](select), [visit the "applying select filters by default" section](select#applying-select-filters-by-default).
## Persisting filters in the user's 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();
}
```
## Live filters
By default, filter changes are deferred and do not affect the table, until the user clicks an "Apply" button. To disable this and make the filters "live" instead, use the `deferFilters(false)` method:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->filters([
// ...
])
->deferFilters(false);
}
```
### 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/overview) can be used:
```php
use Filament\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/overview) can be used:
```php
use Filament\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="4.x" />
## 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) {
// ...
}
```
@@ -0,0 +1,172 @@
---
title: Select filters
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Introduction
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).
<UtilityInjection set="tableFilters" version="4.x">As well as allowing a static value, the `options()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## 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')
```
<UtilityInjection set="tableFilters" version="4.x">As well as allowing a static value, the `attribute()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
## Multi-select filters
These allow the user to [select multiple options](../../forms/select#multi-select) 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()
```
### Filtering empty relationships
By default, upon selecting an option, all records that have an empty relationship will be excluded from the results. If you want to introduce an additional "None" option for the user to select, which will include all records that do not have a relationship, you can use the `hasEmptyOption()` argument of the `relationship()` method:
```php
use Filament\Tables\Filters\SelectFilter;
SelectFilter::make('author')
->relationship('author', 'name', hasEmptyOption: true)
```
You can rename the "None" option using the `emptyRelationshipOptionLabel()` method:
```php
use Filament\Tables\Filters\SelectFilter;
SelectFilter::make('author')
->relationship('author', 'name', hasEmptyOption: true)
->emptyRelationshipOptionLabel('No author')
```
### 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)
```
## Applying select filters by default
You may set a select filter to be enabled by default, using the `default()` method. If using a single select filter, the `default()` method accepts a single option value. If using a `multiple()` select filter, the `default()` method accepts an array of option values:
```php
use Filament\Tables\Filters\SelectFilter;
SelectFilter::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->default('draft')
SelectFilter::make('status')
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
->multiple()
->default(['draft', 'reviewing'])
```
<UtilityInjection set="tableFilters" version="4.x">As well as allowing a static value, the `default()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
@@ -0,0 +1,82 @@
---
title: Ternary filters
---
## Introduction
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()
```
@@ -0,0 +1,482 @@
---
title: Query builder
---
## Introduction
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\QueryBuilder\Constraints\BooleanConstraint;
use Filament\QueryBuilder\Constraints\DateConstraint;
use Filament\QueryBuilder\Constraints\NumberConstraint;
use Filament\QueryBuilder\Constraints\RelationshipConstraint;
use Filament\QueryBuilder\Constraints\RelationshipConstraint\Operators\IsRelatedToOperator;
use Filament\QueryBuilder\Constraints\SelectConstraint;
use Filament\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('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\QueryBuilder\Constraints\TextConstraint;
TextConstraint::make('name') // Filter the `name` column
TextConstraint::make('creator.name') // Filter the `name` column on the `creator` relationship using dot syntax
```
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\QueryBuilder\Constraints\BooleanConstraint;
BooleanConstraint::make('is_visible') // Filter the `is_visible` column
BooleanConstraint::make('creator.is_admin') // Filter the `is_admin` column on the `creator` relationship using dot syntax
```
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\QueryBuilder\Constraints\NumberConstraint;
NumberConstraint::make('stock') // Filter the `stock` column
NumberConstraint::make('orders.item_count') // Filter the `item_count` column on the `orders` relationship using dot syntax
```
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 column 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\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\QueryBuilder\Constraints\DateConstraint;
DateConstraint::make('created_at') // Filter the `created_at` column
DateConstraint::make('creator.created_at') // Filter the `created_at` column on the `creator` relationship using dot syntax
```
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\QueryBuilder\Constraints\SelectConstraint;
SelectConstraint::make('status') // Filter the `status` column
->options([
'draft' => 'Draft',
'reviewing' => 'Reviewing',
'published' => 'Published',
])
SelectConstraint::make('creator.department') // Filter the `department` column on the `creator` relationship using dot syntax
->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\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\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\QueryBuilder\Constraints\RelationshipConstraint;
use Filament\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\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\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\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\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 a relationship constraint, you can scope the relationship to filter the related records using the `modifyRelationshipQueryUsing()` method:
```php
use Filament\QueryBuilder\Constraints\TextConstraint;
use Illuminate\Database\Eloquent\Builder;
TextConstraint::make('creator.name')
->label('Admin creator name')
->modifyRelationshipQueryUsing(fn (Builder $query) => $query->where('is_admin', true))
```
## Customizing the constraint icon
Each constraint type has a default [icon](../../styling/icons), 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\QueryBuilder\Constraints\TextConstraint;
TextConstraint::make('author.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\QueryBuilder\Constraints\Operators\IsFilledOperator;
use Filament\QueryBuilder\Constraints\TextConstraint;
TextConstraint::make('author.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\QueryBuilder\Constraints\Operators\IsFilledOperator;
use Filament\QueryBuilder\Constraints\TextConstraint;
TextConstraint::make('author.name')
->pushOperators([
IsFilledOperator::class,
])
```
If you'd like to add an operator to the start of the list, use `unshiftOperators()` instead:
```php
use Filament\QueryBuilder\Constraints\Operators\IsFilledOperator;
use Filament\QueryBuilder\Constraints\TextConstraint;
TextConstraint::make('author.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\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\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\QueryBuilder\Constraints\Constraint;
use Filament\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\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([
// ...
])
```
@@ -0,0 +1,140 @@
---
title: Custom filters
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
import UtilityInjection from "@components/UtilityInjection.astro"
## Custom filter schemas
You may use [schema components](../../schemas) to create custom filters. The data from the custom filter schema 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')
->schema([
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),
);
})
```
<UtilityInjection set="formFields" version="4.x" extras="Query;;Illuminate\Database\Eloquent\Builder;;$query;;The Eloquent query builder to modify.||Data;;array<string, mixed>;;$data;;The data from the filter's form fields.">The `query()` function can inject various utilities into the function as parameters.</UtilityInjection>
<AutoScreenshot name="tables/filters/custom-form" alt="Table with custom filter schema" version="4.x" />
### Setting default values for custom filter fields
To customize the default value of a field in a custom filter schema, you may use the `default()` method:
```php
use Filament\Forms\Components\DatePicker;
use Filament\Tables\Filters\Filter;
Filter::make('created_at')
->schema([
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="4.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 schema](#custom-filter-schemas), 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')
->schema([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')
->schema([
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)
```
@@ -0,0 +1,214 @@
---
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\Width;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->filters([
// ...
])
->filtersFormWidth(Width::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](overview#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="4.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="4.x" />
## Displaying filters to the left or right of the table content
To render the filters to the left (before) or right (after) of 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::BeforeContent); // or `FiltersLayout::AfterContent`
}
```
### Allowing filters to be collapsible when displayed to the left or right of the table content
To allow the filters to be collapsible when displayed to the left or right of the table content, you may use:
```php
use Filament\Tables\Enums\FiltersLayout;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->filters([
// ...
], layout: FiltersLayout::BeforeContentCollapsible); // or `FiltersLayout::AfterContentCollapsible`
}
```
## 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](../../schemas/layouts) of the entire filter form at once, in order to rearrange filters into your desired layout, and use any of the [layout components](../../schemas/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\Schemas\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](../../schemas/sections) 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.
@@ -0,0 +1,522 @@
---
title: Actions
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
Filament's tables can use [Actions](../actions). They are buttons that can be added to the [end of any table row](#record-actions), or even in the [header](#header-actions) or [toolbar](#toolbar-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/overview) and [action modals](../actions/modals) to that you are aware of the full capabilities of actions.
## Record actions
Action buttons can be rendered at the end of each table row. You can put them in the `$table->recordActions()` method:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->recordActions([
// ...
]);
}
```
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\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="4.x" />
### Positioning record actions before columns
By default, the record 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\RecordActionsPosition;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->recordActions([
// ...
], position: RecordActionsPosition::BeforeColumns);
}
```
<AutoScreenshot name="tables/actions/before-columns" alt="Table with actions before columns" version="4.x" />
### Positioning record actions before the checkbox column
By default, the record 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\RecordActionsPosition;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->recordActions([
// ...
], position: RecordActionsPosition::BeforeCells);
}
```
### Global record action settings
To customize the default configuration used for ungrouped record actions, you can use `modifyUngroupedRecordActionsUsing()` from a [`Table::configureUsing()` function](overview#global-settings) in the `boot()` method of a service provider:
```php
use Filament\Actions\Action;
use Filament\Tables\Table;
Table::configureUsing(function (Table $table): void {
$table
->modifyUngroupedRecordActionsUsing(fn (Action $action) => $action->iconButton());
});
```
<AutoScreenshot name="tables/actions/before-cells" alt="Table with actions before cells" version="4.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\Actions\Action;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;
public function table(Table $table): Table
{
return $table
->selectable()
->recordActions([
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. 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->toolbarActions()` or `$table->headerActions()` methods:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->toolbarActions([
// ...
]);
}
```
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\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="4.x" />
### Authorizing bulk actions
When using a bulk action, you may check a policy method for each record that is selected. This is useful for checking if the user has permission to perform the action on each record. You can use the `authorizeIndividualRecords()` method, passing the name of a policy method, which will be called for each record. If the policy denies authorization, the record will not be present in the bulk action's `$records` parameter:
```php
use Filament\Actions\BulkAction;
use Illuminate\Database\Eloquent\Collection;
BulkAction::make('delete')
->requiresConfirmation()
->authorizeIndividualRecords('delete')
->action(fn (Collection $records) => $records->each->delete())
```
### Bulk action notifications
After a bulk action is completed, you may want to send a notification to the user with a summary of the action's success. This is especially useful if you're using [authorization](#authorizing-bulk-actions) for individual records, as the user may not know how many records were actually affected.
To send a notification after the bulk action is completed, you should set the `successNotificationTitle()` and `failureNotificationTitle()`:
- The `successNotificationTitle()` is used as the title of the notification when all records have been successfully processed.
- The `failureNotificationTitle()` is used as the title of the notification when some or all of the records failed to be processed. By passing a function to this methods, you can inject the `$successCount` and `$failureCount` parameters, to provide this information to the user.
For example:
```php
use Filament\Actions\BulkAction;
use Illuminate\Database\Eloquent\Collection;
BulkAction::make('delete')
->requiresConfirmation()
->authorizeIndividualRecords('delete')
->action(fn (Collection $records) => $records->each->delete())
->successNotificationTitle('Deleted users')
->failureNotificationTitle(function (int $successCount, int $totalCount): string {
if ($successCount) {
return "{$successCount} of {$totalCount} users deleted";
}
return 'Failed to delete any users';
})
```
You can also use a special [authorization response object](https://laravel.com/docs/authorization#policy-responses) in a policy method to provide a custom message about why the authorization failed. The special object is called `DenyResponse` and replaces `Response::deny()`, allowing the developer to pass a function as the message which can receive information about how many records were denied by that authorization check:
```php
use App\Models\User;
use Filament\Support\Authorization\DenyResponse;
use Illuminate\Auth\Access\Response;
class UserPolicy
{
public function delete(User $user, User $model): bool | Response
{
if (! $model->is_admin) {
return true;
}
return DenyResponse::make('cannot_delete_admin', message: function (int $failureCount, int $totalCount): string {
if (($failureCount === 1) && ($totalCount === 1)) {
return 'You cannot delete an admin user.';
}
if ($failureCount === $totalCount) {
return 'All users selected were admin users.';
}
if ($failureCount === 1) {
return 'One of the selected users was an admin user.';
}
return "{$failureCount} of the selected users were admin users.";
});
}
}
```
The first argument to the `make()` method is a unique key to identify that failure type. If multiple failures of that key are detected, they are grouped together and only one message is generated. If there are multiple points of failure in the policy method, each response object can have its own key, and the messages will be concatenated together in the notification.
#### Reporting failures in bulk action processing
Alongside [individual record authorization](#authorizing-bulk-actions) messages, you can also report failures in the bulk action processing itself. This is useful if you want to provide a message for each record that failed to be processed for a particular reason, even after authorization passes. This is done by injecting the `Action` instance into the `action()` function, and calling the `reportBulkProcessingFailure()` method on it, passing a key and message function similar to `DenyResponse`:
```php
use Filament\Actions\BulkAction;
use Illuminate\Database\Eloquent\Collection;
BulkAction::make('delete')
->requiresConfirmation()
->authorizeIndividualRecords('delete')
->action(function (BulkAction $action, Collection $records) {
$records->each(function (Model $record) use ($action) {
$record->delete() || $action->reportBulkProcessingFailure(
'deletion_failed',
message: function (int $failureCount, int $totalCount): string {
if (($failureCount === 1) && ($totalCount === 1)) {
return 'One user failed to delete.';
}
if ($failureCount === $totalCount) {
return 'All users failed to delete.';
}
if ($failureCount === 1) {
return 'One of the selected users failed to delete.';
}
return "{$failureCount} of the selected users failed to delete.";
},
);
});
})
->successNotificationTitle('Deleted users')
->failureNotificationTitle(function (int $successCount, int $totalCount): string {
if ($successCount) {
return "{$successCount} of {$totalCount} users deleted";
}
return 'Failed to delete any users';
})
```
The `delete()` method on an Eloquent model returns `false` if the deletion fails, so you can use that to determine if the record was deleted successfully. The `reportBulkProcessingFailure()` method will then add a failure message to the notification, which will be displayed when the action is completed.
The `reportBulkProcessingFailure()` method can be called at multiple points during the action execution for different reasons, but you should only call it once per record. You should not proceed with the action for that particular record once you have called the method for it.
### 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\Actions\BulkAction;
use Filament\Actions\BulkActionGroup;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->toolbarActions([
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\Actions\BulkAction;
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\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
->toolbarActions([
// ...
])
->checkIfRecordIsSelectableUsing(
fn (Model $record): bool => $record->status === Status::Enabled,
);
}
```
### Limiting the number of selectable records
You may restrict how many records the user can select in total:
```php
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
public function table(Table $table): Table
{
return $table
->toolbarActions([
// ...
])
->maxSelectableRecords(4);
}
```
### 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
->toolbarActions([
// ...
])
->selectCurrentPageOnly();
}
```
### Restricting bulk selection to groups only
The `selectGroupsOnly()` method can be used to restrict bulk selection to only records within the same group, preventing bulk selection across multiple groups at once:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->toolbarActions([
// ...
])
->selectGroupsOnly();
}
```
### Improving the performance of bulk actions
By default, a bulk action will load all Eloquent records into memory before passing them to the `action()` function.
If you are processing a large number of records, you may want to use the `chunkSelectedRecords()` method to fetch a smaller number of records at a time. This will reduce the memory usage of your application:
```php
use Filament\Actions\BulkAction;
use Illuminate\Support\LazyCollection;
BulkAction::make()
->chunkSelectedRecords(250)
->action(function (LazyCollection $records) {
// Process the records...
})
```
You can still loop through the `$records` collection as normal, but the collection will be a `LazyCollection` instead of a normal collection.
You can also prevent Filament from fetching the Eloquent models in the first place, and instead just pass the IDs of the selected records to the `action()` function. This is useful if you are processing a large number of records, and you don't need to load them into memory:
```php
use Filament\Actions\BulkAction;
use Illuminate\Support\Collection;
BulkAction::make()
->fetchSelectedRecords(false)
->action(function (Collection $records) {
// Process the records...
})
```
## Header actions
Both 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="4.x" />
## Toolbar actions
Both actions and [bulk actions](#bulk-actions) can be rendered in the toolbar of the table. You can put them in the `$table->toolbarActions()` method:
```php
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->toolbarActions([
// ...
]);
}
```
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/toolbar" alt="Table with toolbar actions" version="4.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/overview#triggering-actions) in the documentation.
## Grouping actions
You may use an `ActionGroup` object to group multiple table actions together in a dropdown:
```php
use Filament\Actions\ActionGroup;
use Filament\Actions\DeleteAction;
use Filament\Actions\EditAction;
use Filament\Actions\ViewAction;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->recordActions([
ActionGroup::make([
ViewAction::make(),
EditAction::make(),
DeleteAction::make(),
]),
// ...
]);
}
```
You may find out more about customizing action groups in the [Actions documentation](../actions/grouping-actions).
<AutoScreenshot name="tables/actions/group" alt="Table with action group" version="4.x" />
@@ -0,0 +1,470 @@
---
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="4.x" />
<AutoScreenshot name="tables/layout/demo/mobile" alt="Table with responsive layout on mobile" version="4.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="4.x" />
<AutoScreenshot name="tables/layout/split/mobile" alt="Table with a split layout on mobile" version="4.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="4.x" />
<AutoScreenshot name="tables/layout/split-desktop/mobile" alt="Table with a stacked layout on mobile" version="4.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="4.x" />
<AutoScreenshot name="tables/layout/grow-disabled/mobile" alt="Table with a column that doesn't grow on mobile" version="4.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="4.x" />
<AutoScreenshot name="tables/layout/stack/mobile" alt="Table with a stack on mobile" version="4.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="4.x" />
<AutoScreenshot name="tables/layout/stack-hidden-on-mobile/mobile" alt="Table with no stack on mobile" version="4.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="4.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="4.x" />
<AutoScreenshot name="tables/layout/collapsible/mobile" alt="Table with collapsible content on mobile" version="4.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="4.x" />
<AutoScreenshot name="tables/layout/grid/mobile" alt="Table with grid layout on mobile" version="4.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">
@foreach ($getComponents() as $layoutComponent)
{{ $layoutComponent
->record($getRecord())
->recordKey($getRecordKey())
->rowLoop($getRowLoop())
->renderInLayout() }}
@endforeach
</div>
```
@@ -0,0 +1,395 @@
---
title: Summaries
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
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="4.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',
))
```
### 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'))
```
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('price')
->summarize(Sum::make()->money('EUR', decimalPlaces: 3))
```
### 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))
```
### Adding a prefix or suffix
You may add a prefix or suffix to the summary's value:
```php
use Filament\Tables\Columns\Summarizers\Sum;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Support\HtmlString;
TextColumn::make('volume')
->summarize(Sum::make()
->prefix('Total volume: ')
->suffix(new HtmlString(' m&sup3;'))
)
```
## 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.
## Conditionally hiding the summary
To hide a summary, you may pass a boolean, or a function that returns a boolean, to the `hidden()` method. If you need it, you can access the Eloquent query builder instance for that summarizer via the `$query` argument of the function:
```php
use Filament\Tables\Columns\Summarizers\Summarizer;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Builder;
TextColumn::make('sku')
->summarize(Summarizer::make()
->hidden(fn (Builder $query): bool => ! $query->exists()))
```
Alternatively, you can use the `visible()` method to achieve the opposite effect:
```php
use Filament\Tables\Columns\Summarizers\Summarizer;
use Filament\Tables\Columns\TextColumn;
use Illuminate\Database\Eloquent\Builder;
TextColumn::make('sku')
->summarize(Summarizer::make()
->visible(fn (Builder $query): bool => $query->exists()))
```
## 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 beneficial 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();
}
```
@@ -0,0 +1,375 @@
---
title: Grouping rows
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
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="4.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="4.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(),
]);
}
```
### Collapsing groups by default
By default, groups with the `collapsible()` method are expanded when the table loads.
If you want all groups to be collapsed by default when the table loads, use `$table->collapsedGroupsByDefault()`:
```php
use Filament\Tables\Grouping\Group;
use Filament\Tables\Table;
public function table(Table $table): Table
{
return $table
->groups([
Group::make('author.name')
->collapsible(),
])
->collapsedGroupsByDefault();
}
```
## 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/overview) can be used:
```php
use Filament\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();
}
```
@@ -0,0 +1,95 @@
---
title: Empty state
---
import AutoScreenshot from "@components/AutoScreenshot.astro"
## Introduction
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="4.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="4.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="4.x" />
## Setting the empty state icon
To customize the [icon](../styling/icons) 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="4.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\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="4.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\Table;
public function table(Table $table): Table
{
return $table
->emptyState(view('tables.posts.empty-state'));
}
```
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,31 @@
.fi-ta-actions {
@apply flex max-w-full shrink-0 items-center justify-end gap-3;
& > * {
@apply shrink-0;
}
&.fi-wrapped {
@apply flex-wrap;
}
&.sm\:fi-not-wrapped {
@apply sm:flex-nowrap;
}
&.fi-align-center {
@apply justify-center;
}
&.fi-align-start {
@apply justify-start;
}
&.fi-align-between {
@apply justify-between;
}
&.md\:fi-align-end {
@apply md:justify-end;
}
}
@@ -0,0 +1,128 @@
.fi-ta-cell {
@apply p-0 first-of-type:ps-1 last-of-type:pe-1 sm:first-of-type:ps-3 sm:last-of-type:pe-3;
&.fi-vertical-align-start {
@apply align-top;
}
&.fi-vertical-align-end {
@apply align-bottom;
}
&.sm\:fi-hidden {
@apply sm:hidden;
}
&.md\:fi-hidden {
@apply md:hidden;
}
&.lg\:fi-hidden {
@apply lg:hidden;
}
&.xl\:fi-hidden {
@apply xl:hidden;
}
&.\32xl\:fi-hidden {
@apply 2xl:hidden;
}
&.sm\:fi-visible {
@apply hidden sm:table-cell;
}
&.md\:fi-visible {
@apply hidden md:table-cell;
}
&.lg\:fi-visible {
@apply hidden lg:table-cell;
}
&.xl\:fi-visible {
@apply hidden xl:table-cell;
}
&.\32xl\:fi-visible {
@apply hidden 2xl:table-cell;
}
& > .fi-ta-col {
@apply flex w-full justify-start text-start disabled:pointer-events-none;
}
&:has(.fi-ta-reorder-handle) {
@apply w-1 px-3 first-of-type:ps-4 last-of-type:pe-4 sm:first-of-type:ps-6 sm:last-of-type:pe-6;
}
&:has(.fi-ta-actions) {
@apply px-3 py-4 whitespace-nowrap first-of-type:ps-4 last-of-type:pe-4 sm:first-of-type:ps-6 sm:last-of-type:pe-6;
}
&:has(.fi-ta-record-checkbox) {
@apply w-1 px-3 py-4 first-of-type:ps-4 last-of-type:pe-4 sm:first-of-type:ps-6 sm:last-of-type:pe-6;
}
& .fi-ta-placeholder {
@apply text-sm leading-6 text-gray-400 dark:text-gray-500;
}
&.fi-ta-summary-row-heading-cell {
@apply px-3 py-4 text-sm font-medium text-gray-950 dark:text-white;
}
&.fi-align-start {
@apply text-start;
}
&.fi-align-center {
@apply text-center;
}
&.fi-align-end {
@apply text-end;
}
&.fi-align-left {
@apply text-left;
}
&.fi-align-right {
@apply text-right;
}
&.fi-align-justify,
&.fi-align-between {
@apply text-justify;
}
&.fi-ta-summary-header-cell {
@apply px-3 py-2 text-sm font-medium text-gray-950 sm:first-of-type:ps-6 dark:text-white;
&.fi-wrapped {
@apply whitespace-nowrap;
}
&:not(.fi-wrapped) {
@apply whitespace-nowrap;
}
}
&.fi-ta-individual-search-cell {
@apply min-w-48 px-3 py-2;
}
& .fi-ta-reorder-handle {
@apply cursor-move;
}
&.fi-ta-selection-cell {
@apply w-1 px-3 py-4 first-of-type:ps-4 last-of-type:pe-4 sm:first-of-type:ps-6 sm:last-of-type:pe-6;
}
&.fi-ta-group-selection-cell {
@apply w-1 px-3 first-of-type:ps-4 last-of-type:pe-4 sm:first-of-type:ps-6 sm:last-of-type:pe-6;
}
}
@@ -0,0 +1,43 @@
.fi-ta-col-manager {
@apply grid gap-y-4;
& .fi-ta-col-manager-ctn {
@apply grid gap-4;
}
& .fi-ta-col-manager-header {
@apply flex items-center justify-between;
}
& .fi-ta-col-manager-heading {
@apply text-base leading-6 font-semibold text-gray-950 dark:text-white;
}
& .fi-ta-col-manager-items {
@apply -mt-6 gap-x-6;
}
& .fi-ta-col-manager-item {
@apply flex break-inside-avoid items-center gap-3 pt-6;
& .fi-ta-col-manager-label {
@apply flex w-full flex-1 items-center gap-x-3 text-sm font-medium text-gray-950 dark:text-white;
& .fi-checkbox-input {
@apply shrink-0;
}
}
& .fi-ta-col-manager-reorder-handle {
@apply cursor-move;
}
}
& .fi-ta-col-manager-group {
@apply break-inside-avoid;
& .fi-ta-col-manager-group-items {
@apply ps-8;
}
}
}
@@ -0,0 +1,16 @@
.fi-ta-checkbox {
@apply w-full;
&:not(.fi-inline) {
@apply px-3 py-4;
}
&.fi-align-center {
@apply text-center;
}
&.fi-align-end,
&.fi-align-right {
@apply text-end;
}
}
@@ -0,0 +1,38 @@
.fi-ta-color {
@apply flex w-full gap-1.5;
&.fi-wrapped {
@apply flex-wrap;
}
&:not(.fi-inline) {
@apply px-3 py-4;
}
&.fi-align-start,
&.fi-align-left {
@apply justify-start;
}
&.fi-align-center {
@apply justify-center;
}
&.fi-align-end,
&.fi-align-right {
@apply justify-end;
}
&.fi-align-justify,
&.fi-align-between {
@apply justify-between;
}
& > .fi-ta-color-item {
@apply size-6 rounded-md;
&.fi-copyable {
@apply cursor-pointer;
}
}
}
@@ -0,0 +1,42 @@
.fi-ta-icon {
@apply flex w-full gap-1.5;
&.fi-wrapped {
@apply flex-wrap;
}
&.fi-ta-icon-has-line-breaks {
@apply flex-col;
}
&:not(.fi-inline) {
@apply px-3 py-4;
}
&.fi-align-start,
&.fi-align-left {
@apply justify-start;
}
&.fi-align-center {
@apply justify-center;
}
&.fi-align-end,
&.fi-align-right {
@apply justify-end;
}
&.fi-align-justify,
&.fi-align-between {
@apply justify-between;
}
& > .fi-icon {
@apply text-gray-400 dark:text-gray-500;
&.fi-color {
@apply text-(--text) dark:text-(--dark-text);
}
}
}
@@ -0,0 +1,123 @@
.fi-ta-image {
@apply flex w-full items-center gap-1.5;
& img {
@apply max-w-none object-cover object-center;
}
&.fi-circular {
& img {
@apply rounded-full;
}
}
&.fi-ta-image-ring {
& img,
& .fi-ta-image-limited-remaining-text {
@apply ring ring-white dark:ring-gray-900;
}
&.fi-ta-image-ring-1 {
& img,
& .fi-ta-image-limited-remaining-text {
@apply ring-1;
}
}
&.fi-ta-image-ring-2 {
& img,
& .fi-ta-image-limited-remaining-text {
@apply ring-2;
}
}
&.fi-ta-image-ring-4 {
& img,
& .fi-ta-image-limited-remaining-text {
@apply ring-4;
}
}
}
&.fi-ta-image-overlap-1 {
@apply gap-x-0 -space-x-1;
}
&.fi-ta-image-overlap-2 {
@apply gap-x-0 -space-x-2;
}
&.fi-ta-image-overlap-3 {
@apply gap-x-0 -space-x-3;
}
&.fi-ta-image-overlap-4 {
@apply gap-x-0 -space-x-4;
}
&.fi-ta-image-overlap-5 {
@apply gap-x-0 -space-x-5;
}
&.fi-ta-image-overlap-6 {
@apply gap-x-0 -space-x-6;
}
&.fi-ta-image-overlap-7 {
@apply gap-x-0 -space-x-7;
}
&.fi-ta-image-overlap-8 {
@apply gap-x-0 -space-x-8;
}
&.fi-wrapped {
@apply flex-wrap;
}
&:not(.fi-inline) {
@apply px-3 py-4;
}
&.fi-align-start,
&.fi-align-left {
@apply justify-start;
}
&.fi-align-center {
@apply justify-center;
}
&.fi-align-end,
&.fi-align-right {
@apply justify-end;
}
&.fi-align-justify,
&.fi-align-between {
@apply justify-between;
}
&.fi-stacked {
& .fi-ta-image-limited-remaining-text {
@apply rounded-full bg-gray-100 dark:bg-gray-800;
}
}
& .fi-ta-image-limited-remaining-text {
@apply flex items-center justify-center text-sm font-medium text-gray-500 dark:text-gray-400;
&.fi-size-xs {
@apply text-xs;
}
&.fi-size-base,
&.fi-size-md {
@apply text-base;
}
&.fi-size-lg {
@apply text-lg;
}
}
}
@@ -0,0 +1,49 @@
.fi-ta-grid {
&.fi-gap-sm {
@apply gap-1;
}
&.sm\:fi-gap-sm {
@apply sm:gap-1;
}
&.md\:fi-gap-sm {
@apply md:gap-1;
}
&.lg\:fi-gap-sm {
@apply lg:gap-1;
}
&.xl\:fi-gap-sm {
@apply xl:gap-1;
}
&.\32xl\:fi-gap-sm {
@apply 2xl:gap-1;
}
&.fi-gap-lg {
@apply gap-3;
}
&.sm\:fi-gap-lg {
@apply sm:gap-3;
}
&.md\:fi-gap-lg {
@apply md:gap-3;
}
&.lg\:fi-gap-lg {
@apply lg:gap-3;
}
&.xl\:fi-gap-lg {
@apply xl:gap-3;
}
&.\32xl\:fi-gap-lg {
@apply 2xl:gap-3;
}
}
@@ -0,0 +1,3 @@
.fi-ta-panel {
@apply rounded-lg bg-gray-50 p-4 ring-1 ring-gray-950/5 ring-inset dark:bg-white/5 dark:ring-white/10;
}
@@ -0,0 +1,35 @@
.fi-ta-split {
@apply flex;
&.default\:fi-ta-split {
@apply items-center gap-3;
}
&.sm\:fi-ta-split,
&.md\:fi-ta-split,
&.lg\:fi-ta-split,
&.xl\:fi-ta-split,
&.\32xl\:fi-ta-split {
@apply flex-col gap-2;
}
&.sm\:fi-ta-split {
@apply sm:flex-row sm:items-center sm:gap-3;
}
&.md\:fi-ta-split {
@apply md:flex-row md:items-center md:gap-3;
}
&.lg\:fi-ta-split {
@apply lg:flex-row lg:items-center lg:gap-3;
}
&.xl\:fi-ta-split {
@apply xl:flex-row xl:items-center xl:gap-3;
}
&.\32xl\:fi-ta-split {
@apply 2xl:flex-row 2xl:items-center 2xl:gap-3;
}
}
@@ -0,0 +1,29 @@
.fi-ta-stack {
@apply flex flex-col;
&.fi-align-start,
&.fi-align-left {
@apply items-start;
}
&.fi-align-center {
@apply items-center;
}
&.fi-align-end,
&.fi-align-right {
@apply items-end;
}
&.fi-gap-sm {
@apply space-y-1;
}
&.fi-gap-md {
@apply space-y-2;
}
&.fi-gap-lg {
@apply space-y-3;
}
}
@@ -0,0 +1,7 @@
.fi-ta-select {
@apply w-full min-w-48;
&:not(.fi-inline) {
@apply px-3 py-4;
}
}
@@ -0,0 +1,23 @@
.fi-ta-icon-count-summary {
@apply grid gap-y-1.5 px-3 py-4 text-sm text-gray-500 dark:text-gray-400;
& > .fi-ta-icon-count-summary-label {
@apply font-medium text-gray-950 dark:text-white;
}
& > ul {
@apply grid gap-y-1.5;
& > li {
@apply flex items-center justify-end gap-x-1.5;
& > .fi-icon {
@apply text-gray-400 dark:text-gray-500;
&.fi-color {
@apply text-(--text) dark:text-(--dark-text);
}
}
}
}
}
@@ -0,0 +1,7 @@
.fi-ta-range-summary {
@apply grid gap-y-1 px-3 py-4 text-sm text-gray-500 dark:text-gray-400;
& > .fi-ta-range-summary-label {
@apply font-medium text-gray-950 dark:text-white;
}
}
@@ -0,0 +1,7 @@
.fi-ta-text-summary {
@apply grid gap-y-1 px-3 py-4 text-sm text-gray-500 dark:text-gray-400;
& > .fi-ta-text-summary-label {
@apply font-medium text-gray-950 dark:text-white;
}
}
@@ -0,0 +1,13 @@
.fi-ta-values-summary {
@apply grid gap-y-1 px-3 py-4 text-sm text-gray-500 dark:text-gray-400;
& > .fi-ta-values-summary-label {
@apply font-medium text-gray-950 dark:text-white;
}
& > ul {
&.fi-bulleted {
@apply list-inside list-disc;
}
}
}
@@ -0,0 +1,7 @@
.fi-ta-text-input {
@apply w-full min-w-48;
&:not(.fi-inline) {
@apply px-3 py-4;
}
}
@@ -0,0 +1,244 @@
.fi-ta-text {
@apply w-full;
&.fi-ta-text-has-descriptions,
&.fi-ta-text-list-limited {
/* Add space between content and descriptions / list limit message. */
@apply flex flex-col;
&.fi-ta-text-has-badges {
/* When the content contains badges, more gap is required to balance the spacing. */
@apply gap-y-2;
}
&:not(.fi-ta-text-has-badges) {
/* When the content does not contain badges, less gap is required to balance the spacing. */
@apply gap-y-1;
}
}
&:not(.fi-inline) {
@apply px-3 py-4;
}
ul&.fi-bulleted,
&.fi-bulleted ul {
@apply list-inside list-disc;
}
&:not(.fi-ta-text-has-line-breaks) {
ul&.fi-ta-text-has-badges,
&.fi-ta-text-has-badges ul {
/* A list of badges without line breaks need to remain on the same line, not wrap */
@apply flex gap-x-1.5;
&.fi-wrapped,
&:is(.fi-wrapped ul) {
/* When wrap is enabled, some badges can remain on the same line as others and some should wrap */
@apply flex-wrap gap-y-1;
}
}
}
ul&.fi-ta-text-has-badges,
&.fi-ta-text-has-badges ul {
&.fi-ta-text-has-line-breaks,
&:is(.fi-ta-text-has-line-breaks ul) {
/* Add vertical gap between badges in a list with line breaks */
@apply flex flex-col gap-y-1;
}
&:not(ul.fi-ta-text-has-line-breaks),
&:not(.fi-ta-text-has-line-breaks ul) {
/* A list of badges without line breaks need to remain on the same line, not wrap */
@apply flex gap-x-1.5;
&.fi-wrapped,
&:is(.fi-wrapped ul) {
/* When wrap is enabled, some badges can remain on the same line as others and some should wrap */
@apply flex-wrap gap-y-1;
}
}
}
&.fi-wrapped:not(.fi-ta-text-has-badges.fi-ta-text-has-line-breaks) {
/* If the content has badges, and they have line breaks, setting `whitespace-normal` sometimes pushes the badge
onto the line below the bullet point if there is one, and badge content does not need to wrap anyway. */
@apply whitespace-normal;
& .fi-badge,
& .fi-ta-text-list-limited-message {
/* Badge content should not wrap, but descriptions above and below badges should. The list limited
message and actions should not wrap. */
@apply whitespace-nowrap;
}
}
& > .fi-ta-text-description,
& > .fi-ta-text-list-limited-message {
@apply text-sm text-gray-500 dark:text-gray-400;
}
&.fi-align-center {
@apply text-center;
ul&,
& ul {
@apply justify-center;
}
}
&.fi-align-end,
&.fi-align-right {
@apply text-end;
ul&,
& ul {
@apply justify-end;
}
}
&.fi-align-justify,
&.fi-align-between {
@apply text-justify;
ul&,
& ul {
@apply justify-between;
}
}
}
.fi-ta-text-item {
@apply text-gray-950 dark:text-white;
& a {
@apply hover:underline focus-visible:underline;
}
&:not(.fi-bulleted li.fi-ta-text-item) {
/* Line clamping sets the `display` property of the list item to `-webkit-box` instead of `list-item`, which hides the bullet point. */
@apply line-clamp-(--line-clamp,none);
}
& > .fi-copyable {
@apply cursor-pointer;
}
&.fi-size-xs {
@apply text-xs;
}
&.fi-size-sm {
@apply text-sm leading-6;
}
&.fi-size-md {
@apply text-base;
}
&.fi-size-lg {
@apply text-lg;
}
&.fi-font-thin {
@apply font-thin;
}
&.fi-font-extralight {
@apply font-extralight;
}
&.fi-font-light {
@apply font-light;
}
&.fi-font-normal {
@apply font-normal;
}
&.fi-font-medium {
@apply font-medium;
}
&.fi-font-semibold {
@apply font-semibold;
}
&.fi-font-bold {
@apply font-bold;
}
&.fi-font-extrabold {
@apply font-extrabold;
}
&.fi-font-black {
@apply font-black;
}
&.fi-font-sans {
@apply font-sans;
}
&.fi-font-serif {
@apply font-serif;
}
&.fi-font-mono {
@apply font-mono;
}
&.fi-color {
@apply text-(--text) dark:text-(--dark-text);
li&::marker {
@apply text-gray-950;
}
@variant dark {
li&::marker {
@apply text-white;
}
}
}
&.fi-color-gray {
@apply text-gray-500 dark:text-gray-400;
li&::marker {
@apply text-gray-950;
}
@variant dark {
li&::marker {
@apply text-white;
}
}
}
& > .fi-icon,
& > span:not(.fi-badge) > .fi-icon {
@apply inline-block shrink-0 text-gray-400 dark:text-gray-500;
&.fi-color {
@apply text-color-500;
}
}
&.fi-ta-text-has-badges > .fi-badge {
@apply align-middle;
}
}
.fi-ta-col-has-column-url .fi-ta-text-item {
@apply hover:underline focus-visible:underline;
& .fi-icon {
@apply hover:no-underline focus-visible:no-underline;
}
& > .fi-badge {
@apply hover:no-underline focus-visible:no-underline;
}
}
@@ -0,0 +1,16 @@
.fi-ta-toggle {
@apply w-full;
&:not(.fi-inline) {
@apply px-3 py-4;
}
&.fi-align-center {
@apply text-center;
}
&.fi-align-end,
&.fi-align-right {
@apply text-end;
}
}
@@ -0,0 +1,272 @@
.fi-ta-ctn {
@apply relative flex rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10;
&:not(.fi-ta-ctn-with-header) {
@apply overflow-hidden;
}
&.fi-loading {
@apply animate-pulse;
}
& .fi-ta-header-ctn {
@apply -mt-px;
}
& .fi-ta-header {
@apply flex flex-col gap-3 border-b border-gray-200 p-4 sm:px-6 dark:border-white/10;
&.fi-ta-header-adaptive-actions-position {
@apply sm:flex-row sm:items-center;
& .fi-ta-actions {
@apply sm:ms-auto;
}
&:not(:has(.fi-ta-header-heading)) {
&:not(:has(.fi-ta-header-description)) {
& .fi-ta-actions {
@apply ms-auto;
}
}
}
}
& .fi-ta-header-heading {
@apply text-base leading-6 font-semibold text-gray-950 dark:text-white;
}
& .fi-ta-header-description {
@apply mt-1 text-sm text-gray-600 dark:text-gray-400;
}
}
& .fi-ta-header-toolbar {
@apply flex flex-wrap items-center justify-between gap-4 border-b border-gray-200 px-4 py-3 sm:px-6 dark:border-white/10;
& > * {
@apply flex items-center gap-x-4;
}
& > :nth-child(1) {
@apply shrink-0;
}
& > :nth-child(2) {
@apply ms-auto;
}
& .fi-ta-grouping-settings {
& .fi-dropdown {
&.sm\:fi-hidden {
@apply sm:hidden;
}
& .fi-ta-grouping-settings-fields {
@apply grid gap-y-6 p-6;
& label {
@apply grid gap-y-2 text-sm leading-6 font-medium text-gray-950 dark:text-white;
}
}
}
& > .fi-ta-grouping-settings-fields {
@apply hidden items-center gap-x-3 sm:flex;
}
}
& .fi-ta-filters-dropdown {
& .fi-ta-filters {
@apply p-6;
}
}
& .fi-ta-col-manager-dropdown {
& .fi-ta-col-manager {
@apply p-6;
}
}
}
& .fi-ta-filters {
@apply grid gap-y-4;
&.fi-ta-filters-below-content {
@apply border-t border-gray-200 p-4 sm:px-6 dark:border-white/10;
}
& .fi-ta-filters-header {
@apply flex items-center justify-between;
& .fi-ta-filters-heading {
@apply text-base leading-6 font-semibold text-gray-950 dark:text-white;
}
& .fi-loading-indicator {
@apply text-gray-400 dark:text-gray-500;
}
}
}
& .fi-ta-filters-above-content-ctn {
@apply grid border-b border-gray-200 px-4 py-4 sm:px-6 dark:border-white/10;
& .fi-ta-filters-trigger-action-ctn {
@apply ms-auto;
}
&.fi-open {
& .fi-ta-filters-trigger-action-ctn {
@apply mt-3;
}
&:has(.fi-ta-filters-apply-action-ctn) {
& .fi-ta-filters-trigger-action-ctn {
@apply -mt-7;
}
}
}
}
& .fi-ta-reorder-indicator {
@apply flex items-center gap-x-3 border-b border-gray-200 bg-gray-50 px-3 py-1.5 text-sm leading-6 font-medium text-gray-700 sm:px-6 dark:border-white/10 dark:bg-white/5 dark:text-gray-200;
& .fi-loading-indicator {
@apply text-gray-400 dark:text-gray-500;
}
}
& .fi-ta-selection-indicator {
@apply flex flex-col justify-between gap-y-1 border-b border-gray-200 bg-gray-50 px-3 py-2 sm:flex-row sm:items-center sm:px-6 sm:py-1.5 dark:border-white/10 dark:bg-white/5;
& .fi-loading-indicator {
@apply text-gray-400 dark:text-gray-500;
}
& .fi-ta-selection-indicator-actions-ctn {
@apply flex gap-x-3;
}
& > * {
@apply flex gap-x-3;
}
& > :nth-child(1) {
@apply text-sm leading-6 font-medium text-gray-700 dark:text-gray-200;
}
& > :nth-child(2) {
@apply ms-auto;
}
}
& .fi-ta-filter-indicators {
@apply flex items-start justify-between gap-x-3 border-b border-gray-200 bg-gray-50 px-3 py-1.5 sm:px-6 dark:border-white/10 dark:bg-white/5;
& > :nth-child(1) {
@apply flex flex-col gap-x-3 gap-y-1 sm:flex-row;
& .fi-ta-filter-indicators-label {
@apply text-sm leading-6 font-medium whitespace-nowrap text-gray-700 dark:text-gray-200;
}
& .fi-ta-filter-indicators-badges-ctn {
@apply flex flex-wrap gap-1.5;
}
}
& > :nth-child(2).fi-icon-btn {
@apply -mt-1;
}
}
& .fi-pagination {
@apply border-t border-gray-200 px-3 py-3 sm:px-6 dark:border-white/10;
}
& .fi-ta-table-loading-ctn {
@apply flex h-32 items-center justify-center;
}
& .fi-ta-main {
@apply min-w-0 flex-1;
}
& .fi-ta-filters-trigger-action-ctn.lg\:fi-hidden {
@apply lg:hidden;
}
& .fi-ta-filters-before-content-ctn,
& .fi-ta-filters-after-content-ctn {
@apply absolute z-20 hidden w-screen max-w-[14rem]! shrink-0 rounded-lg border-gray-200 bg-white shadow-lg ring-1 ring-gray-950/5 transition lg:static lg:z-auto lg:shadow-none lg:ring-0 dark:border-white/10 dark:bg-gray-900 dark:ring-white/10;
& .fi-ta-filters {
@apply p-6 lg:py-4;
}
&.fi-open {
@apply block;
}
&.lg\:fi-open {
@apply lg:block;
}
&.fi-opacity-0 {
@apply opacity-0;
}
&.fi-width-xs {
@apply max-w-xs!;
}
&.fi-width-sm {
@apply max-w-sm!;
}
&.fi-width-md {
@apply max-w-md!;
}
&.fi-width-lg {
@apply max-w-lg!;
}
&.fi-width-xl {
@apply max-w-xl!;
}
&.fi-width-2xl {
@apply max-w-2xl!;
}
&.fi-width-3xl {
@apply max-w-3xl!;
}
&.fi-width-4xl {
@apply max-w-4xl!;
}
&.fi-width-5xl {
@apply max-w-5xl!;
}
&.fi-width-6xl {
@apply max-w-6xl!;
}
&.fi-width-7xl {
@apply max-w-7xl!;
}
}
& .fi-ta-filters-before-content-ctn {
@apply start-0 lg:rounded-s-xl lg:rounded-e-none lg:border-e;
}
& .fi-ta-filters-after-content-ctn {
@apply end-0 lg:rounded-s-none lg:rounded-e-xl lg:border-s;
}
}
@@ -0,0 +1,333 @@
.fi-ta-content-ctn {
@apply relative divide-y divide-gray-200 overflow-x-auto dark:divide-white/10 dark:border-t-white/10;
& .fi-ta-content-header {
@apply flex items-center gap-4 gap-x-6 bg-gray-50 px-4 sm:px-6 dark:bg-white/5;
& .fi-ta-page-checkbox {
@apply my-4 shrink-0;
}
& .fi-ta-sorting-settings {
@apply flex gap-x-3 py-3;
}
}
&:not(.fi-ta-ctn-with-footer .fi-ta-content-ctn) {
@apply rounded-b-xl;
}
&:not(.fi-ta-ctn-with-header .fi-ta-content-ctn) {
@apply border-t-0;
}
& .fi-ta-content {
@apply grid;
&.fi-ta-content-grid {
@apply gap-4 p-4 sm:px-6;
&.fi-ta-content-grouped {
@apply pt-0;
}
& .fi-ta-group-header {
@apply -mx-4 border-y border-gray-200 first:border-t-0 sm:-mx-6 dark:border-white/5;
width: calc(100% + 2rem);
@variant sm {
width: calc(100% + 3rem);
}
}
& .fi-ta-record {
@apply rounded-xl shadow-sm ring-1 ring-gray-950/5 dark:bg-white/5 dark:ring-white/10;
&.fi-clickable {
@apply dark:hover:bg-white/10 dark:hover:ring-white/20;
}
&.fi-selected {
@apply dark:bg-white/10 dark:ring-white/20;
}
&:not(.fi-selected) {
@apply bg-white dark:bg-white/5 dark:ring-white/10;
}
&.fi-ta-record-with-content-prefix {
& .fi-ta-record-content {
@apply ps-2;
}
& .fi-ta-actions {
@apply ps-2;
}
}
&.fi-ta-record-with-content-suffix {
& .fi-ta-record-content {
@apply pe-2;
}
& .fi-ta-actions {
@apply pe-2;
}
}
}
}
&:not(.fi-ta-content-grid) {
@apply gap-y-px bg-gray-200 dark:bg-white/5;
& .fi-ta-record {
&.fi-clickable {
@apply dark:hover:bg-white/5;
}
&.fi-selected {
@apply before:bg-primary-600 dark:before:bg-primary-500 before:absolute before:inset-y-0 before:start-0 before:w-0.5 dark:bg-white/5;
}
& .fi-ta-record-content-ctn {
@apply md:flex-row md:items-center;
}
&:not(.fi-ta-record-with-content-prefix) {
& .fi-ta-record-content {
@apply sm:ps-6;
}
& .fi-ta-actions {
@apply sm:ps-6;
}
}
&:not(.fi-ta-record-with-content-suffix) {
& .fi-ta-record-content {
@apply sm:pe-6;
}
& .fi-ta-actions {
@apply sm:pe-6;
}
}
&.fi-ta-record-with-content-prefix {
@apply sm:ps-3;
& .fi-ta-record-content {
@apply ps-3;
}
& .fi-ta-actions {
@apply ps-3;
}
}
&.fi-ta-record-with-content-suffix {
@apply sm:pe-3;
& .fi-ta-record-content {
@apply pe-3;
}
& .fi-ta-actions {
@apply pe-3;
}
}
& .fi-ta-actions {
@apply md:ps-3;
}
}
}
& .fi-ta-group-header {
@apply col-span-full flex w-full items-center gap-x-3 bg-gray-50 px-1 py-2 sm:px-3 dark:bg-white/5;
&.fi-collapsible {
@apply cursor-pointer;
&.fi-collapsed {
& .fi-icon-btn {
@apply -rotate-180;
}
}
}
& .fi-ta-group-heading {
@apply text-sm font-medium text-gray-950 dark:text-white;
}
& .fi-ta-group-description {
@apply text-sm text-gray-500 dark:text-gray-400;
}
& .fi-ta-group-checkbox {
@apply mx-3;
}
}
& .fi-ta-table {
@apply col-span-full;
}
& .fi-ta-record {
@apply relative flex h-full items-center bg-white transition duration-75 dark:bg-gray-900;
&.fi-ta-record-with-content-prefix {
@apply ps-1;
}
&.fi-ta-record-with-content-suffix {
@apply pe-1;
}
&.fi-clickable {
@apply hover:bg-gray-50;
}
&.fi-collapsed {
@apply hidden;
}
&.fi-selected {
@apply bg-gray-50;
}
& .fi-ta-reorder-handle {
@apply mx-1 my-2;
}
& .fi-ta-record-checkbox {
@apply mx-3 my-4 shrink-0;
}
& .fi-ta-record-content-ctn {
@apply flex h-full w-full flex-col gap-y-3 py-4;
& > :nth-child(1) {
@apply flex-1;
}
& .fi-ta-record-content {
@apply block w-full;
& .fi-ta-col {
@apply flex justify-start text-start disabled:pointer-events-none;
&.fi-growable {
@apply w-full;
}
&.fi-align-center {
@apply justify-center text-center;
}
&.fi-align-end {
@apply justify-end text-end;
}
&.fi-align-left {
@apply justify-start text-left;
}
&.fi-align-right {
@apply justify-end text-right;
}
&.fi-align-justify,
&.fi-align-between {
@apply justify-between text-justify;
}
}
&.fi-collapsible {
@apply mt-3;
}
& .fi-growable {
@apply w-full flex-1;
}
& .sm\:fi-hidden {
@apply sm:hidden;
}
& .md\:fi-hidden {
@apply md:hidden;
}
& .lg\:fi-hidden {
@apply lg:hidden;
}
& .xl\:fi-hidden {
@apply xl:hidden;
}
& .\32xl\:fi-hidden {
@apply 2xl:hidden;
}
& .sm\:fi-visible {
@apply hidden sm:block;
}
& .md\:fi-visible {
@apply hidden md:block;
}
& .lg\:fi-visible {
@apply hidden lg:block;
}
& .xl\:fi-visible {
@apply hidden xl:block;
}
& .\32xl\:fi-visible {
@apply hidden 2xl:block;
}
}
}
& .fi-ta-record-collapse-btn {
@apply mx-1 my-2 shrink-0;
}
& .fi-ta-actions {
&.fi-ta-actions-before-columns-position {
@apply order-first;
}
}
&:not(.fi-ta-record-with-content-prefix) {
& .fi-ta-record-content {
@apply ps-4;
}
& .fi-ta-actions {
@apply ps-4;
}
}
&:not(.fi-ta-record-with-content-suffix) {
& .fi-ta-record-content {
@apply pe-4;
}
& .fi-ta-actions {
@apply pe-4;
}
}
&.fi-ta-record-collapsed {
& .fi-ta-record-collapse-btn {
@apply rotate-180;
}
}
}
}
}
@@ -0,0 +1,31 @@
.fi-ta-empty-state {
@apply px-6 py-12;
&:not(.fi-ta-ctn-with-content-layout .fi-ta-empty-state) {
@apply border-t border-gray-200 dark:border-white/10;
}
& .fi-ta-empty-state-content {
@apply mx-auto grid max-w-lg justify-items-center text-center;
}
& .fi-ta-empty-state-icon-bg {
@apply mb-4 rounded-full bg-gray-100 p-3 dark:bg-gray-500/20;
& .fi-icon {
@apply text-gray-500 dark:text-gray-400;
}
}
& .fi-ta-empty-state-heading {
@apply text-base leading-6 font-semibold text-gray-950 dark:text-white;
}
& .fi-ta-empty-state-description {
@apply mt-1 text-sm text-gray-500 dark:text-gray-400;
}
& .fi-ta-actions {
@apply mt-6;
}
}
@@ -0,0 +1,213 @@
.fi-ta-header-cell {
@apply px-3 py-3.5 text-start text-sm font-semibold text-gray-950 sm:first-of-type:ps-6 sm:last-of-type:pe-6 dark:text-white;
&.fi-growable {
@apply w-full;
}
&.fi-grouped {
@apply border-gray-200 dark:border-white/5 [&:not(:first-of-type)]:border-s [&:not(:last-of-type)]:border-e;
}
&.fi-align-center {
@apply text-center;
& .fi-ta-header-cell-sort-btn {
@apply justify-center;
}
}
&.fi-align-end {
@apply text-end;
& .fi-ta-header-cell-sort-btn {
@apply justify-end;
}
}
&.fi-align-left {
@apply text-left;
& .fi-ta-header-cell-sort-btn {
@apply justify-start rtl:flex-row-reverse;
}
}
&.fi-align-right {
@apply text-right;
& .fi-ta-header-cell-sort-btn {
@apply justify-end rtl:flex-row-reverse;
}
}
&.fi-align-justify,
&.fi-align-between {
@apply text-justify;
& .fi-ta-header-cell-sort-btn {
@apply justify-between;
}
}
&.fi-ta-header-cell-sorted {
& .fi-icon {
@apply text-gray-950 dark:text-white;
}
}
&:not(.fi-ta-header-cell-sorted) {
& .fi-icon {
@apply text-gray-400 dark:text-gray-500;
}
& .fi-ta-header-cell-sort-btn:hover {
& .fi-icon {
@apply text-gray-500 dark:text-gray-400;
}
}
& .fi-ta-header-cell-sort-btn:focus-visible {
& .fi-icon {
@apply text-gray-500 dark:text-gray-400;
}
}
}
&.sm\:fi-hidden {
@apply sm:hidden;
}
&.md\:fi-hidden {
@apply md:hidden;
}
&.lg\:fi-hidden {
@apply lg:hidden;
}
&.xl\:fi-hidden {
@apply xl:hidden;
}
&.\32xl\:fi-hidden {
@apply 2xl:hidden;
}
&.sm\:fi-visible {
@apply hidden sm:table-cell;
}
&.md\:fi-visible {
@apply hidden md:table-cell;
}
&.lg\:fi-visible {
@apply hidden lg:table-cell;
}
&.xl\:fi-visible {
@apply hidden xl:table-cell;
}
&.\32xl\:fi-visible {
@apply hidden 2xl:table-cell;
}
&.fi-wrapped {
@apply whitespace-normal;
}
&:not(.fi-wrapped) {
@apply whitespace-nowrap;
}
& .fi-ta-header-cell-sort-btn {
@apply flex w-full cursor-pointer items-center justify-start gap-x-1;
}
& .fi-icon {
@apply shrink-0 transition duration-75;
}
}
.fi-ta-header-group-cell {
@apply border-gray-200 px-3 py-2 text-sm font-semibold text-gray-950 sm:first-of-type:ps-6 sm:last-of-type:pe-6 dark:border-white/5 dark:text-white [&:not(:first-of-type)]:border-s [&:not(:last-of-type)]:border-e;
&.fi-align-start {
@apply text-start;
}
&.fi-align-center {
@apply text-center;
}
&.fi-align-end {
@apply text-end;
}
&.fi-align-left {
@apply text-left;
}
&.fi-align-right {
@apply text-right;
}
&.fi-align-justify,
&.fi-align-between {
@apply text-justify;
}
&.sm\:fi-hidden {
@apply sm:hidden;
}
&.md\:fi-hidden {
@apply md:hidden;
}
&.lg\:fi-hidden {
@apply lg:hidden;
}
&.xl\:fi-hidden {
@apply xl:hidden;
}
&.\32xl\:fi-hidden {
@apply 2xl:hidden;
}
&.sm\:fi-visible {
@apply hidden sm:table-cell;
}
&.md\:fi-visible {
@apply hidden md:table-cell;
}
&.lg\:fi-visible {
@apply hidden lg:table-cell;
}
&.xl\:fi-visible {
@apply hidden xl:table-cell;
}
&.\32xl\:fi-visible {
@apply hidden 2xl:table-cell;
}
&.fi-wrapped {
@apply whitespace-normal;
}
&:not(.fi-wrapped) {
@apply whitespace-nowrap;
}
}
.fi-ta-empty-header-cell {
@apply w-1;
}
@@ -0,0 +1,25 @@
@import './actions.css' layer(components);
@import './cell.css' layer(components);
@import './columns/checkbox.css' layer(components);
@import './columns/color.css' layer(components);
@import './columns/icon.css' layer(components);
@import './columns/image.css' layer(components);
@import './columns/select.css' layer(components);
@import './columns/text.css' layer(components);
@import './columns/text-input.css' layer(components);
@import './columns/toggle.css' layer(components);
@import './columns/layout/grid.css' layer(components);
@import './columns/layout/panel.css' layer(components);
@import './columns/layout/split.css' layer(components);
@import './columns/layout/stack.css' layer(components);
@import './columns/summaries/icon-count.css' layer(components);
@import './columns/summaries/range.css' layer(components);
@import './columns/summaries/text.css' layer(components);
@import './columns/summaries/values.css' layer(components);
@import './container.css' layer(components);
@import './content.css' layer(components);
@import './empty-state.css' layer(components);
@import './header-cell.css' layer(components);
@import './row.css' layer(components);
@import './table.css' layer(components);
@import './column-manager.css' layer(components);
@@ -0,0 +1,72 @@
.fi-ta-row {
@apply [@media(hover:hover)]:transition-colors [@media(hover:hover)]:duration-75;
&.fi-clickable {
@apply hover:bg-gray-50 dark:hover:bg-white/5;
}
&.fi-striped {
@apply bg-gray-50 dark:bg-white/5;
}
&.fi-collapsed {
@apply hidden;
}
&.fi-ta-group-header-row {
& > td {
@apply bg-gray-50 dark:bg-white/5;
}
}
& .fi-ta-group-header {
@apply flex w-full items-center gap-x-3 px-3 py-2;
&.fi-collapsible {
@apply cursor-pointer;
&.fi-collapsed {
& .fi-icon-btn {
@apply -rotate-180;
}
}
}
& .fi-ta-group-heading {
@apply text-sm font-medium text-gray-950 dark:text-white;
}
& .fi-ta-group-description {
@apply text-sm text-gray-500 dark:text-gray-400;
}
}
&.fi-selected {
&:not(.fi-striped) {
@apply bg-gray-50 dark:bg-white/5;
}
& > *:first-child {
@apply relative;
&::before {
@apply bg-primary-600 absolute inset-y-0 start-0 w-0.5;
content: '';
}
@variant dark {
&::before {
@apply bg-primary-500;
}
}
}
}
}
.fi-ta-reordering {
& .fi-ta-row {
&:not(.fi-ta-row-not-reorderable) {
@apply cursor-move;
}
}
}
@@ -0,0 +1,23 @@
.fi-ta-table {
@apply w-full table-auto divide-y divide-gray-200 text-start dark:divide-white/5;
& > thead {
@apply divide-y divide-gray-200 dark:divide-white/5;
& > tr {
@apply bg-gray-50 dark:bg-white/5;
&.fi-ta-table-head-groups-row {
@apply bg-gray-100 dark:bg-transparent;
}
}
}
& > tbody {
@apply divide-y divide-gray-200 whitespace-nowrap dark:divide-white/5;
}
& > tfoot {
@apply bg-gray-50 dark:bg-white/5;
}
}
@@ -0,0 +1,232 @@
export default function filamentTableColumnManager({ columns, isLive }) {
return {
error: undefined,
isLoading: false,
deferredColumns: [],
columns,
isLive,
hasReordered: false,
init() {
if (!this.columns || this.columns.length === 0) {
this.columns = []
return
}
this.deferredColumns = JSON.parse(JSON.stringify(this.columns))
},
get groupedColumns() {
const groupedColumns = {}
this.deferredColumns
.filter((column) => column.type === 'group')
.forEach((column) => {
groupedColumns[column.name] =
this.calculateGroupedColumns(column)
})
return groupedColumns
},
calculateGroupedColumns(group) {
const visibleChildren =
group?.columns?.filter((column) => !column.isHidden) ?? []
if (visibleChildren.length === 0) {
return {
hidden: true,
checked: false,
disabled: false,
indeterminate: false,
}
}
const toggleableChildren = group.columns.filter(
(column) => !column.isHidden && column.isToggleable !== false,
)
if (toggleableChildren.length === 0) {
return { checked: true, disabled: true, indeterminate: false }
}
const toggledChildren = toggleableChildren.filter(
(column) => column.isToggled,
).length
const nonToggleableChildren = group.columns.filter(
(column) => !column.isHidden && column.isToggleable === false,
)
if (toggledChildren === 0 && nonToggleableChildren.length > 0) {
return { checked: true, disabled: false, indeterminate: true }
}
if (toggledChildren === 0) {
return { checked: false, disabled: false, indeterminate: false }
}
if (toggledChildren === toggleableChildren.length) {
return { checked: true, disabled: false, indeterminate: false }
}
return { checked: true, disabled: false, indeterminate: true }
},
getColumn(name, groupName = null) {
if (groupName) {
const group = this.deferredColumns.find(
(group) =>
group.type === 'group' && group.name === groupName,
)
return group?.columns?.find((column) => column.name === name)
}
return this.deferredColumns.find((column) => column.name === name)
},
toggleGroup(groupName) {
const group = this.deferredColumns.find(
(group) => group.type === 'group' && group.name === groupName,
)
if (!group?.columns) {
return
}
const groupedColumns = this.calculateGroupedColumns(group)
if (groupedColumns.disabled) {
return
}
const toggleableChildren = group.columns.filter(
(column) => column.isToggleable !== false,
)
const anyChildOn = toggleableChildren.some(
(column) => column.isToggled,
)
const newValue = groupedColumns.indeterminate ? true : !anyChildOn
group.columns
.filter((column) => column.isToggleable !== false)
.forEach((column) => {
column.isToggled = newValue
})
this.deferredColumns = [...this.deferredColumns]
if (this.isLive) {
this.applyTableColumnManager()
}
},
toggleColumn(name, groupName = null) {
const column = this.getColumn(name, groupName)
if (!column || column.isToggleable === false) {
return
}
column.isToggled = !column.isToggled
this.deferredColumns = [...this.deferredColumns]
if (this.isLive) {
this.applyTableColumnManager()
}
},
reorderColumns(sortedIds) {
const newOrder = sortedIds.map((id) => id.split('::'))
this.reorderTopLevel(newOrder)
this.hasReordered = true
if (this.isLive) {
this.applyTableColumnManager()
}
},
reorderGroupColumns(sortedIds, groupName) {
const group = this.deferredColumns.find(
(column) =>
column.type === 'group' && column.name === groupName,
)
if (!group) {
return
}
const newOrder = sortedIds.map((id) => id.split('::'))
const reordered = []
newOrder.forEach(([type, name]) => {
const item = group.columns.find(
(column) => column.name === name,
)
if (item) {
reordered.push(item)
}
})
group.columns = reordered
this.deferredColumns = [...this.deferredColumns]
this.hasReordered = true
if (this.isLive) {
this.applyTableColumnManager()
}
},
reorderTopLevel(newOrder) {
const cloned = this.deferredColumns
const reordered = []
newOrder.forEach(([type, name]) => {
const item = cloned.find((column) => {
if (type === 'group') {
return column.type === 'group' && column.name === name
} else if (type === 'column') {
return column.type !== 'group' && column.name === name
}
return false
})
if (item) {
reordered.push(item)
}
})
this.deferredColumns = reordered
},
async applyTableColumnManager() {
this.isLoading = true
try {
this.columns = JSON.parse(JSON.stringify(this.deferredColumns))
await this.$wire.call(
'applyTableColumnManager',
this.columns,
this.hasReordered,
)
this.hasReordered = false
this.error = undefined
} catch (error) {
this.error = 'Failed to update column visibility'
console.error('Table toggle columns error:', error)
} finally {
this.isLoading = false
}
},
}
}
@@ -0,0 +1,79 @@
export default function checkboxTableColumn({ name, recordKey, state }) {
return {
error: undefined,
isLoading: false,
state,
init() {
Livewire.hook(
'commit',
({ component, commit, succeed, fail, respond }) => {
succeed(({ snapshot, effect }) => {
this.$nextTick(() => {
if (this.isLoading) {
return
}
if (
component.id !==
this.$root.closest('[wire\\:id]')?.attributes[
'wire:id'
].value
) {
return
}
const serverState = this.getServerState()
if (
serverState === undefined ||
Alpine.raw(this.state) === serverState
) {
return
}
this.state = serverState
})
})
},
)
this.$watch('state', async () => {
const serverState = this.getServerState()
if (
serverState === undefined ||
Alpine.raw(this.state) === serverState
) {
return
}
this.isLoading = true
const response = await this.$wire.updateTableColumnState(
name,
recordKey,
this.state,
)
this.error = response?.error ?? undefined
if (!this.error && this.$refs.serverState) {
this.$refs.serverState.value = this.state ? '1' : '0'
}
this.isLoading = false
})
},
getServerState() {
if (!this.$refs.serverState) {
return undefined
}
return [1, '1'].includes(this.$refs.serverState.value)
},
}
}
@@ -0,0 +1,172 @@
import { Select } from '../../../../../support/resources/js/utilities/select.js'
export default function selectTableColumn({
canOptionLabelsWrap,
canSelectPlaceholder,
getOptionLabelUsing,
getOptionsUsing,
getSearchResultsUsing,
hasDynamicOptions,
hasDynamicSearchResults,
initialOptionLabel,
isDisabled,
isHtmlAllowed,
isNative,
isSearchable,
loadingMessage,
name,
noSearchResultsMessage,
options,
optionsLimit,
placeholder,
position,
recordKey,
searchableOptionFields,
searchDebounce,
searchingMessage,
searchPrompt,
state,
}) {
return {
error: undefined,
isLoading: false,
select: null,
state,
init() {
if (!isNative) {
this.select = new Select({
element: this.$refs.select,
options,
placeholder,
state: this.state,
canOptionLabelsWrap,
canSelectPlaceholder,
initialOptionLabel,
isHtmlAllowed,
isDisabled,
isSearchable,
getOptionLabelUsing,
getOptionsUsing,
getSearchResultsUsing,
hasDynamicOptions,
hasDynamicSearchResults,
searchPrompt,
searchDebounce,
loadingMessage,
searchingMessage,
noSearchResultsMessage,
optionsLimit,
position,
searchableOptionFields,
onStateChange: (newState) => {
this.state = newState
},
})
}
Livewire.hook(
'commit',
({ component, commit, succeed, fail, respond }) => {
succeed(({ snapshot, effect }) => {
this.$nextTick(() => {
if (this.isLoading) {
return
}
if (
component.id !==
this.$root.closest('[wire\\:id]')?.attributes[
'wire:id'
].value
) {
return
}
const serverState = this.getServerState()
if (
serverState === undefined ||
this.getNormalizedState() === serverState
) {
return
}
this.state = serverState
})
})
},
)
this.$watch('state', async (newState) => {
if (
!isNative &&
this.select &&
this.select.state !== newState
) {
this.select.state = newState
this.select.updateSelectedDisplay()
this.select.renderOptions()
}
const serverState = this.getServerState()
if (
serverState === undefined ||
this.getNormalizedState() === serverState
) {
return
}
this.isLoading = true
const response = await this.$wire.updateTableColumnState(
name,
recordKey,
this.state,
)
this.error = response?.error ?? undefined
if (!this.error && this.$refs.serverState) {
this.$refs.serverState.value = this.getNormalizedState()
}
this.isLoading = false
})
},
getServerState() {
if (!this.$refs.serverState) {
return undefined
}
return [null, undefined].includes(this.$refs.serverState.value)
? ''
: this.$refs.serverState.value.replaceAll(
'\\' + String.fromCharCode(34),
String.fromCharCode(34),
)
},
getNormalizedState() {
const state = Alpine.raw(this.state)
if ([null, undefined].includes(state)) {
return ''
}
return state
},
destroy() {
if (this.select) {
this.select.destroy()
this.select = null
}
},
}
}
@@ -0,0 +1,94 @@
export default function textInputTableColumn({ name, recordKey, state }) {
return {
error: undefined,
isLoading: false,
state,
init() {
Livewire.hook(
'commit',
({ component, commit, succeed, fail, respond }) => {
succeed(({ snapshot, effect }) => {
this.$nextTick(() => {
if (this.isLoading) {
return
}
if (
component.id !==
this.$root.closest('[wire\\:id]')?.attributes[
'wire:id'
].value
) {
return
}
const serverState = this.getServerState()
if (
serverState === undefined ||
this.getNormalizedState() === serverState
) {
return
}
this.state = serverState
})
})
},
)
this.$watch('state', async () => {
const serverState = this.getServerState()
if (
serverState === undefined ||
this.getNormalizedState() === serverState
) {
return
}
this.isLoading = true
const response = await this.$wire.updateTableColumnState(
name,
recordKey,
this.state,
)
this.error = response?.error ?? undefined
if (!this.error && this.$refs.serverState) {
this.$refs.serverState.value = this.getNormalizedState()
}
this.isLoading = false
})
},
getServerState() {
if (!this.$refs.serverState) {
return undefined
}
return [null, undefined].includes(this.$refs.serverState.value)
? ''
: this.$refs.serverState.value.replaceAll(
'\\' + String.fromCharCode(34),
String.fromCharCode(34),
)
},
getNormalizedState() {
const state = Alpine.raw(this.state)
if ([null, undefined].includes(state)) {
return ''
}
return state
},
}
}
@@ -0,0 +1,79 @@
export default function toggleTableColumn({ name, recordKey, state }) {
return {
error: undefined,
isLoading: false,
state,
init() {
Livewire.hook(
'commit',
({ component, commit, succeed, fail, respond }) => {
succeed(({ snapshot, effect }) => {
this.$nextTick(() => {
if (this.isLoading) {
return
}
if (
component.id !==
this.$root.closest('[wire\\:id]')?.attributes[
'wire:id'
].value
) {
return
}
const serverState = this.getServerState()
if (
serverState === undefined ||
Alpine.raw(this.state) === serverState
) {
return
}
this.state = serverState
})
})
},
)
this.$watch('state', async () => {
const serverState = this.getServerState()
if (
serverState === undefined ||
Alpine.raw(this.state) === serverState
) {
return
}
this.isLoading = true
const response = await this.$wire.updateTableColumnState(
name,
recordKey,
this.state,
)
this.error = response?.error ?? undefined
if (!this.error && this.$refs.serverState) {
this.$refs.serverState.value = this.state ? '1' : '0'
}
this.isLoading = false
})
},
getServerState() {
if (!this.$refs.serverState) {
return undefined
}
return [1, '1'].includes(this.$refs.serverState.value)
},
}
}
@@ -0,0 +1,439 @@
import { autoUpdate, computePosition, offset, shift } from '@floating-ui/dom'
export default ({
areGroupsCollapsedByDefault,
canTrackDeselectedRecords,
currentSelectionLivewireProperty,
maxSelectableRecords,
selectsCurrentPageOnly,
$wire,
}) => ({
areFiltersOpen: false,
checkboxClickController: null,
groupVisibility: [],
isLoading: false,
selectedRecords: new Set(),
deselectedRecords: new Set(),
isTrackingDeselectedRecords: false,
shouldCheckUniqueSelection: true,
lastCheckedRecord: null,
livewireId: null,
entangledSelectedRecords: currentSelectionLivewireProperty
? $wire.$entangle(currentSelectionLivewireProperty)
: null,
cleanUpFiltersDropdown: null,
init() {
this.livewireId =
this.$root.closest('[wire\\:id]')?.attributes['wire:id'].value
$wire.$on('deselectAllTableRecords', () => this.deselectAllRecords())
$wire.$on('scrollToTopOfTable', () =>
this.$root.scrollIntoView({ block: 'start', inline: 'nearest' }),
)
if (currentSelectionLivewireProperty) {
if (maxSelectableRecords !== 1) {
this.selectedRecords = new Set(this.entangledSelectedRecords)
} else {
this.selectedRecords = new Set(
this.entangledSelectedRecords
? [this.entangledSelectedRecords]
: [],
)
}
}
this.$nextTick(() => this.watchForCheckboxClicks())
Livewire.hook('element.init', ({ component }) => {
if (component.id === this.livewireId) {
this.watchForCheckboxClicks()
}
})
},
mountAction(...args) {
$wire.set(
'isTrackingDeselectedTableRecords',
this.isTrackingDeselectedRecords,
false,
)
$wire.set('selectedTableRecords', [...this.selectedRecords], false)
$wire.set('deselectedTableRecords', [...this.deselectedRecords], false)
$wire.mountAction(...args)
},
toggleSelectRecordsOnPage() {
const keys = this.getRecordsOnPage()
if (this.areRecordsSelected(keys)) {
this.deselectRecords(keys)
return
}
this.selectRecords(keys)
},
toggleSelectRecords(keys) {
if (this.areRecordsSelected(keys)) {
this.deselectRecords(keys)
} else {
this.selectRecords(keys)
}
},
getSelectedRecordsCount() {
if (this.isTrackingDeselectedRecords) {
return (
(this.$refs.allSelectableRecordsCount?.value ??
this.deselectedRecords.size) - this.deselectedRecords.size
)
}
return this.selectedRecords.size
},
getRecordsOnPage() {
const keys = []
for (let checkbox of this.$root?.getElementsByClassName(
'fi-ta-record-checkbox',
) ?? []) {
keys.push(checkbox.value)
}
return keys
},
selectRecords(keys) {
if (maxSelectableRecords === 1) {
this.deselectAllRecords()
keys = keys.slice(0, 1)
}
for (let key of keys) {
if (this.isRecordSelected(key)) {
continue
}
if (this.isTrackingDeselectedRecords) {
this.deselectedRecords.delete(key)
continue
}
this.selectedRecords.add(key)
}
this.updatedSelectedRecords()
},
deselectRecords(keys) {
for (let key of keys) {
if (this.isTrackingDeselectedRecords) {
this.deselectedRecords.add(key)
continue
}
this.selectedRecords.delete(key)
}
this.updatedSelectedRecords()
},
updatedSelectedRecords() {
if (maxSelectableRecords !== 1) {
this.entangledSelectedRecords = [...this.selectedRecords]
return
}
this.entangledSelectedRecords = [...this.selectedRecords][0] ?? null
},
toggleSelectedRecord(key) {
if (this.isRecordSelected(key)) {
this.deselectRecords([key])
return
}
this.selectRecords([key])
},
async selectAllRecords() {
if (!canTrackDeselectedRecords || selectsCurrentPageOnly) {
this.isLoading = true
this.selectedRecords = new Set(
await $wire.getAllSelectableTableRecordKeys(),
)
this.updatedSelectedRecords()
this.isLoading = false
return
}
this.isTrackingDeselectedRecords = true
this.selectedRecords = new Set()
this.deselectedRecords = new Set()
this.updatedSelectedRecords()
},
canSelectAllRecords() {
if (selectsCurrentPageOnly) {
const recordsOnPage = this.getRecordsOnPage()
return (
!this.areRecordsSelected(recordsOnPage) &&
this.areRecordsToggleable(recordsOnPage)
)
}
const allSelectableRecordsCount = parseInt(
this.$refs.allSelectableRecordsCount?.value,
)
if (!allSelectableRecordsCount) {
return false
}
const selectedRecordsCount = this.getSelectedRecordsCount()
if (allSelectableRecordsCount === selectedRecordsCount) {
return false
}
return (
maxSelectableRecords === null ||
allSelectableRecordsCount <= maxSelectableRecords
)
},
deselectAllRecords() {
this.isTrackingDeselectedRecords = false
this.selectedRecords = new Set()
this.deselectedRecords = new Set()
this.updatedSelectedRecords()
},
isRecordSelected(key) {
if (this.isTrackingDeselectedRecords) {
return !this.deselectedRecords.has(key)
}
return this.selectedRecords.has(key)
},
areRecordsSelected(keys) {
return keys.every((key) => this.isRecordSelected(key))
},
areRecordsToggleable(keys) {
if (maxSelectableRecords === null) {
return true
}
if (maxSelectableRecords === 1) {
return true
}
const selectedRecords = keys.filter((key) => this.isRecordSelected(key))
if (selectedRecords.length === keys.length) {
return true
}
return (
this.getSelectedRecordsCount() +
(keys.length - selectedRecords.length) <=
maxSelectableRecords
)
},
toggleCollapseGroup(group) {
if (this.isGroupCollapsed(group)) {
if (areGroupsCollapsedByDefault) {
this.groupVisibility.push(group)
} else {
this.groupVisibility.splice(
this.groupVisibility.indexOf(group),
1,
)
}
} else {
if (areGroupsCollapsedByDefault) {
this.groupVisibility.splice(
this.groupVisibility.indexOf(group),
1,
)
} else {
this.groupVisibility.push(group)
}
}
},
isGroupCollapsed(group) {
if (areGroupsCollapsedByDefault) {
return !this.groupVisibility.includes(group)
}
return this.groupVisibility.includes(group)
},
resetCollapsedGroups() {
this.groupVisibility = []
},
watchForCheckboxClicks() {
if (this.checkboxClickController) {
this.checkboxClickController.abort()
}
this.checkboxClickController = new AbortController()
const { signal } = this.checkboxClickController
this.$root?.addEventListener(
'click',
(event) =>
event.target?.matches('.fi-ta-record-checkbox') &&
this.handleCheckboxClick(event, event.target),
{ signal },
)
},
handleCheckboxClick(event, checkbox) {
if (!this.lastChecked) {
this.lastChecked = checkbox
return
}
if (event.shiftKey) {
let checkboxes = Array.from(
this.$root?.getElementsByClassName('fi-ta-record-checkbox') ??
[],
)
if (!checkboxes.includes(this.lastChecked)) {
this.lastChecked = checkbox
return
}
let start = checkboxes.indexOf(this.lastChecked)
let end = checkboxes.indexOf(checkbox)
let range = [start, end].sort((a, b) => a - b)
let values = []
for (let i = range[0]; i <= range[1]; i++) {
values.push(checkboxes[i].value)
}
if (checkbox.checked) {
if (!this.areRecordsToggleable(values)) {
checkbox.checked = false
this.deselectRecords([checkbox.value])
return
}
this.selectRecords(values)
} else {
this.deselectRecords(values)
}
}
this.lastChecked = checkbox
},
toggleFiltersDropdown() {
this.areFiltersOpen = !this.areFiltersOpen
if (this.areFiltersOpen) {
const cleanUpAutoUpdate = autoUpdate(
this.$refs.filtersTriggerActionContainer,
this.$refs.filtersContentContainer,
async () => {
const { x, y } = await computePosition(
this.$refs.filtersTriggerActionContainer,
this.$refs.filtersContentContainer,
{
placement: 'bottom-end',
middleware: [offset(8), shift({ padding: 8 })],
},
)
Object.assign(this.$refs.filtersContentContainer.style, {
left: `${x}px`,
top: `${y}px`,
})
},
)
const onClickAway = (event) => {
const trigger = this.$refs.filtersTriggerActionContainer
const filters = this.$refs.filtersContentContainer
if (
(filters && filters.contains(event.target)) ||
(trigger && trigger.contains(event.target))
) {
return
}
this.areFiltersOpen = false
if (this.cleanUpFiltersDropdown) {
this.cleanUpFiltersDropdown()
this.cleanUpFiltersDropdown = null
}
}
document.addEventListener('mousedown', onClickAway)
document.addEventListener('touchstart', onClickAway, {
passive: true,
})
const onKeydown = (event) => {
if (event.key === 'Escape') {
onClickAway(event)
}
}
document.addEventListener('keydown', onKeydown)
this.cleanUpFiltersDropdown = () => {
cleanUpAutoUpdate()
document.removeEventListener('mousedown', onClickAway)
document.removeEventListener('touchstart', onClickAway, {
passive: true,
})
document.removeEventListener('keydown', onKeydown)
}
} else if (this.cleanUpFiltersDropdown) {
this.cleanUpFiltersDropdown()
this.cleanUpFiltersDropdown = null
}
},
})
@@ -0,0 +1,7 @@
import table from './components/table.js'
import columnManager from './components/column-manager.js'
document.addEventListener('alpine:init', () => {
window.Alpine.data('filamentTable', table)
window.Alpine.data('filamentTableColumnManager', columnManager)
})
@@ -0,0 +1,199 @@
<?php
return [
'column_manager' => [
'heading' => 'አምዶች',
],
'columns' => [
'actions' => [
'label' => 'እርምጃ|እርምጃዎች',
],
'text' => [
'actions' => [
'collapse_list' => 'ከ:count ያነሰ አሳይ',
'expand_list' => 'ከ:count የበለጠ አሳይ',
],
'more_list_items' => 'ከ:count በላይ',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'ለጅምላ ድርጊት ሁሉንም ይምረጡ/አይምረጡ።',
],
'bulk_select_record' => [
'label' => ':keyን ለጅምላ ድርጊት ይምረጡ/አይምረጡ።',
],
'bulk_select_group' => [
'label' => 'ቡድን :titleን ለጅምላ ድርጊት ይምረጡ/አይምረጡ።',
],
'search' => [
'label' => 'ፈልግ',
'placeholder' => 'ፈልግ',
'indicator' => 'ፈልግ',
],
],
'summary' => [
'heading' => 'ማጠቃለያ',
'subheadings' => [
'all' => 'ሁሉም :label',
'group' => 'የ:group ማጠቃለያ',
'page' => 'የዚህ ገጽ',
],
'summarizers' => [
'average' => [
'label' => 'አማካኝ',
],
'count' => [
'label' => 'ብዛት',
],
'sum' => [
'label' => 'ድምር',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'መዝገቦችን እንደገና መደርደር ጨርስ',
],
'enable_reordering' => [
'label' => 'እንደገና መደርደር',
],
'filter' => [
'label' => 'አጣራ',
],
'group' => [
'label' => 'ቡድን',
],
'open_bulk_actions' => [
'label' => 'የጅምላ ድርጊቶች',
],
'column_manager' => [
'label' => 'ዓምዶችን ቀያይር',
],
],
'empty' => [
'heading' => 'ምንም :model የሉም',
'description' => 'ለመጀመር አንድ :model ይፍጠሩ.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'ማጣርያዎችን ተግብር',
],
'remove' => [
'label' => 'ማጣሪያን ያስወግዱ',
],
'remove_all' => [
'label' => 'ሁሉንም ማጣሪያዎች ያስወግዱ',
'tooltip' => 'ሁሉንም ማጣሪያዎች ያስወግዱ',
],
'reset' => [
'label' => 'ዳግም አስጀምር',
],
],
'heading' => 'ማጣርያዎች',
'indicator' => 'የተተገበሩ ማጣርያዎች',
'multi_select' => [
'placeholder' => 'ሁሉም',
],
'select' => [
'placeholder' => 'ሁሉም',
],
'trashed' => [
'label' => 'የተሰረዙ መዝገቦች',
'only_trashed' => 'የተሰረዙ መዝገቦች ብቻ',
'with_trashed' => 'ከተሰረዙ መዝገቦች ጋር',
'without_trashed' => 'ያለ የተሰረዙ መዝገቦች',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'መድብ',
'placeholder' => 'መድብ',
],
'direction' => [
'label' => 'የቡድን አቅጣጫ',
'options' => [
'asc' => 'ከትንሽ ወደ ትልቅ',
'desc' => 'ከትልቅ ወደ ትንሽ',
],
],
],
],
'reorder_indicator' => 'መዝገቦቹን ይጎትቱ እና በቅደም ተከተል ያስቀምጡ።',
'selection_indicator' => [
'selected_count' => '1 መዝገብ ተመርጧል|:count መዝገቦች ተመርጠዋል',
'actions' => [
'select_all' => [
'label' => 'ሁሉንም :countውንም ምረጥ',
],
'deselect_all' => [
'label' => 'ሁሉንም አይምረጡ',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'ቅደምተከተል',
],
'direction' => [
'label' => 'የቅደም ተከተል አቅጣጫ',
'options' => [
'asc' => 'ከትንሽ ወደ ትልቅ',
'desc' => 'ከትልቅ ወደ ትንሽ',
],
],
],
],
'default_model_label' => 'ሪከርድ',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'الأعمدة',
'actions' => [
'apply' => [
'label' => 'تطبيق الأعمدة',
],
'reset' => [
'label' => 'إعادة ضبط التصفيات',
],
],
],
'columns' => [
'actions' => [
'label' => 'إجراء | إجراءات',
],
'select' => [
'loading_message' => 'جاري التحميل...',
'no_search_results_message' => 'لا توجد خيارات مطابقة لبحثك.',
'placeholder' => 'اختر',
'searching_message' => 'جاري البحث...',
'search_prompt' => 'ابدأ الكتابة للبحث...',
],
'text' => [
'actions' => [
'collapse_list' => 'عرض :count أقل',
'expand_list' => 'عرض :count أكثر',
],
'more_list_items' => 'و :count إضافية',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'تحديد/إلغاء تحديد كافة العناصر للإجراءات الجماعية.',
],
'bulk_select_record' => [
'label' => 'تحديد/إلغاء تحديد العنصر :key للإجراءات الجماعية.',
],
'bulk_select_group' => [
'label' => 'تحديد/إلغاء تحديد المجموعة :title للإجراءات الجماعية.',
],
'search' => [
'label' => 'بحث',
'placeholder' => 'بحث',
'indicator' => 'بحث',
],
],
'summary' => [
'heading' => 'الملخص',
'subheadings' => [
'all' => 'كافة :label',
'group' => 'ملخص :group',
'page' => 'هذه الصفحة',
],
'summarizers' => [
'average' => [
'label' => 'المتوسط',
],
'count' => [
'label' => 'العدد',
],
'sum' => [
'label' => 'المجموع',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'إنهاء إعادة ترتيب السجلات',
],
'enable_reordering' => [
'label' => 'إعادة ترتيب السجلات',
],
'filter' => [
'label' => 'تصفية',
],
'group' => [
'label' => 'مجموعة',
],
'open_bulk_actions' => [
'label' => 'الإجراءات',
],
'column_manager' => [
'label' => 'تبديل الأعمدة',
],
],
'empty' => [
'heading' => 'لا توجد :model',
'description' => 'قم بإضافة :model للبدء.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'تطبيق التصفيات',
],
'remove' => [
'label' => 'إلغاء التصفيات',
],
'remove_all' => [
'label' => 'إلغاء كافة التصفيات',
'tooltip' => 'إلغاء كافة التصفيات',
],
'reset' => [
'label' => 'إعادة ضبط التصفيات',
],
],
'heading' => 'التصفيات',
'indicator' => 'التصفيات النشطة',
'multi_select' => [
'placeholder' => 'الكل',
],
'select' => [
'placeholder' => 'الكل',
'relationship' => [
'empty_option_label' => 'لا يوجد اختيار',
],
],
'trashed' => [
'label' => 'السجلات المحذوفة',
'only_trashed' => 'السجلات المحذوفة فقط',
'with_trashed' => 'مع السجلات المحذوفة',
'without_trashed' => 'بدون السجلات المحذوفة',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'تجميع حسب',
],
'direction' => [
'label' => 'إتجاه التجميع',
'options' => [
'asc' => 'تصاعدي',
'desc' => 'تنازلي',
],
],
],
],
'reorder_indicator' => 'قم بسحب وإسقاط السجلات بالترتيب.',
'selection_indicator' => [
'selected_count' => '{1} تم تحديد سجل واحد|[3,10] تم تحديد :count سجلات |[2,*] تم تحديد :count سجل',
'actions' => [
'select_all' => [
'label' => 'تحديد كل السجلات :count',
],
'deselect_all' => [
'label' => 'إلغاء تحديد الكل',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'ترتيب حسب',
],
'direction' => [
'label' => 'اتجاه الترتيب',
'options' => [
'asc' => 'تصاعدي',
'desc' => 'تنازلي',
],
],
],
],
'default_model_label' => 'سجل',
];
@@ -0,0 +1,231 @@
<?php
return [
'column_manager' => [
'heading' => 'Sütunlar',
],
'columns' => [
'actions' => [
'label' => 'Əməliyyat|Əməliyyatlar',
],
'text' => [
'actions' => [
'collapse_list' => ':count az göstər',
'expand_list' => ':count daha çox göstər',
],
'more_list_items' => 'və :count daha',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Çoxlu hərəkətlər üçün bütün elementləri seç/seçimi yığışdır.',
],
'bulk_select_record' => [
'label' => 'Çoxlu hərəkətlər üçün :key elementini seç/seçimi yığışdır.',
],
'bulk_select_group' => [
'label' => 'Çoxlu hərəkətlər üçün :title qrupunu seç/seçimi yığışdır.',
],
'search' => [
'label' => 'Axtar',
'placeholder' => 'Axtar',
'indicator' => 'Axtar',
],
],
'summary' => [
'heading' => 'Xülasə',
'subheadings' => [
'all' => 'Bütün :label',
'group' => ':group xülasəsi',
'page' => 'Bu səhifə',
],
'summarizers' => [
'average' => [
'label' => 'Ortalama',
],
'count' => [
'label' => 'Say',
],
'sum' => [
'label' => 'Toplam',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Sıralamanı yekunlaşdır',
],
'enable_reordering' => [
'label' => 'Sıralamanı başlat',
],
'filter' => [
'label' => 'Filtrlə',
],
'group' => [
'label' => 'Qrupla',
],
'open_bulk_actions' => [
'label' => 'Çoxlu hərəkətlər',
],
'column_manager' => [
'label' => 'Sütunları göstər/gizlət',
],
],
'empty' => [
'heading' => ':model Yoxdur',
'description' => 'Başlamaq üçün bir :model yaradın.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Filtrləri tətbiq et',
],
'remove' => [
'label' => 'Filtri yığışdır',
],
'remove_all' => [
'label' => 'Bütün filtrləri yığışdır',
'tooltip' => 'Bütün filtrləri yığışdır',
],
'reset' => [
'label' => 'Sıfırla',
],
],
'heading' => 'Filtrlər',
'indicator' => 'Aktiv filtrlər',
'multi_select' => [
'placeholder' => 'Hamısı',
],
'select' => [
'placeholder' => 'Hamısı',
],
'trashed' => [
'label' => 'Silinmiş məlumatlar',
'only_trashed' => 'Sadəcə silinmiş məlumatlar',
'with_trashed' => 'Silinmiş məlumatlarla birlikdə',
'without_trashed' => 'Silinmiş məlumatlar olmadan',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Qrupla',
'placeholder' => 'Qrupla',
],
'direction' => [
'label' => 'Qrup istiqaməti',
'options' => [
'asc' => 'Artan',
'desc' => 'Azalan',
],
],
],
],
'reorder_indicator' => 'Məlumatları sıralamaq üçün sürüşdürüb buraxın.',
'selection_indicator' => [
'selected_count' => '1 məlumat seçildi|:count məlumat seçildi',
'actions' => [
'select_all' => [
'label' => 'Bütün :count məlumatı seç',
],
'deselect_all' => [
'label' => 'Bütün seçimləri yığışdır',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Buna görə sırala',
],
'direction' => [
'label' => 'Sıralama istiqaməti',
'options' => [
'asc' => 'Artan',
'desc' => 'Azalan',
],
],
],
],
];
@@ -0,0 +1,228 @@
<?php
return [
'column_manager' => [
'heading' => 'Колони',
],
'columns' => [
'text' => [
'actions' => [
'collapse_list' => 'Скрий :count повече',
'expand_list' => 'Покажи :count повече',
],
'more_list_items' => 'и още :count',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Изберете/премахнете избора на всички записи на тази страница.',
],
'bulk_select_record' => [
'label' => 'Изберете/премахнете избора на :key за масови действия.',
],
'bulk_select_group' => [
'label' => 'Изберете/премахнете избора на група :title за масови действия.',
],
'search' => [
'label' => 'Търси',
'placeholder' => 'Търси',
'indicator' => 'Търсене...',
],
],
'summary' => [
'heading' => 'Обобщение',
'subheadings' => [
'all' => 'Всички :label',
'group' => 'Обебщение на :group',
'page' => 'Текуща страница',
],
'summarizers' => [
'average' => [
'label' => 'Средно',
],
'count' => [
'label' => 'Брой',
],
'sum' => [
'label' => 'Сума',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Приключи пренареждането',
],
'enable_reordering' => [
'label' => 'Пренареди',
],
'filter' => [
'label' => 'Филтрирай',
],
'group' => [
'label' => 'Групирай',
],
'open_bulk_actions' => [
'label' => 'Отвори масови действия',
],
'column_manager' => [
'label' => 'Превключи колони',
],
],
'empty' => [
'heading' => 'Няма :model',
'description' => 'Създай нов :model за да започнеш.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Приложи',
],
'remove' => [
'label' => 'Премахни',
],
'remove_all' => [
'label' => 'Премахни всички',
'tooltip' => 'Премахни всички филтри',
],
'reset' => [
'label' => 'Нулирай',
],
],
'heading' => 'Филтри',
'indicator' => 'Филтриране',
'multi_select' => [
'placeholder' => 'Всички',
],
'select' => [
'placeholder' => 'Избери',
],
'trashed' => [
'label' => 'Изтрити записи',
'only_trashed' => 'Само изтрити записи',
'with_trashed' => 'С изтрити записи',
'without_trashed' => 'Без изтрити записи',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Групирай по',
'placeholder' => 'Избери поле за групиране',
],
'direction' => [
'label' => 'Посока на групиране',
'options' => [
'asc' => 'Възходящо',
'desc' => 'Низходящо',
],
],
],
],
'reorder_indicator' => 'Премествай записите с мишката.',
'selection_indicator' => [
'selected_count' => '1 запис избран|:count записа избрани',
'actions' => [
'select_all' => [
'label' => 'Избери всички :count',
],
'deselect_all' => [
'label' => 'Премахнете избора на всички',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Сортирай по',
],
'direction' => [
'label' => 'Посока на сортиране',
'options' => [
'asc' => 'Възходящо',
'desc' => 'Низходящо',
],
],
],
],
];
@@ -0,0 +1,136 @@
<?php
return [
'columns' => [
'text' => [
'more_list_items' => 'এবং আরো :count',
],
],
'fields' => [
'search' => [
'label' => 'খুঁজুন',
'placeholder' => 'খুঁজুন',
],
],
'actions' => [
'disable_reordering' => [
'label' => 'রেকর্ড পুনর্বিন্যাস সম্পন্ন করুন',
],
'enable_reordering' => [
'label' => 'রেকর্ড পুনর্বিন্যাস করুন',
],
'filter' => [
'label' => 'অনুসন্ধান করুন',
],
'open_bulk_actions' => [
'label' => 'কার্যক্রম গুলো দেখুন',
],
'column_manager' => [
'label' => 'কলাম টগল করুন',
],
],
'empty' => [
'heading' => 'রেকর্ড পাওয়া যায়নি',
],
'filters' => [
'actions' => [
'remove' => [
'label' => 'অনুসন্ধান সরান',
],
'remove_all' => [
'label' => 'সব অনুসন্ধান সরান',
'tooltip' => 'সব অনুসন্ধান সরান',
],
'reset' => [
'label' => 'অনুসন্ধান সরান',
],
],
'indicator' => 'সক্রিয় অনুসন্ধান',
'multi_select' => [
'placeholder' => 'সব',
],
'select' => [
'placeholder' => 'সব',
],
'trashed' => [
'label' => 'রেকর্ড মুছে ফেলুন',
'only_trashed' => 'শুধু মুছে ফেলা রেকর্ডগুলো',
'with_trashed' => 'মুছে ফেলা রেকর্ডগুলোর সাথে',
'without_trashed' => 'মুছে ফেলা রেকর্ডগুলো ছাড়া',
],
],
'reorder_indicator' => 'ক্রমানুসারে রেকর্ড টেনে আনুন।',
'selection_indicator' => [
'selected_count' => '১টি রেকর্ড নির্বাচিত | :countটি রেকর্ড নির্বাচিত',
'actions' => [
'select_all' => [
'label' => 'সব নির্বাচিত করুন',
],
'deselect_all' => [
'label' => 'সব অনির্বাচিত করুন',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'ক্রমানুসার',
],
'direction' => [
'label' => 'ক্রমানুসারের দিক',
'options' => [
'asc' => 'ঊর্ধ্বগামী',
'desc' => 'অধোগামী',
],
],
],
],
];
@@ -0,0 +1,146 @@
<?php
return [
'columns' => [
'text' => [
'more_list_items' => 'i :count više',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Odaberi/poništi odabir svih stavki za grupne radnje.',
],
'bulk_select_record' => [
'label' => 'Odaberi/poništi odabir stavke :key za grupne radnje.',
],
'search' => [
'label' => 'Pretraga',
'placeholder' => 'Tražite',
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Završi preuređivanje zapisa',
],
'enable_reordering' => [
'label' => 'Preuredi zapise',
],
'filter' => [
'label' => 'Filter',
],
'open_bulk_actions' => [
'label' => 'Otvorene akcije',
],
'column_manager' => [
'label' => 'Preklopiti kolone',
],
],
'empty' => [
'heading' => 'Nije pronađen nijedan zapis',
],
'filters' => [
'heading' => 'Filteri',
'actions' => [
'remove' => [
'label' => 'Skloni filter',
],
'remove_all' => [
'label' => 'Skloni svi filteri',
'tooltip' => 'Skloni svi filteri',
],
'reset' => [
'label' => 'Resetujte filtere',
],
],
'indicator' => 'Aktivne filteri',
'multi_select' => [
'placeholder' => 'Svi',
],
'select' => [
'placeholder' => 'Svi',
],
'trashed' => [
'label' => 'Izbrisani zapisi',
'only_trashed' => 'Samo izbrisani zapisi',
'with_trashed' => 'Sa izbrisanim zapisima',
'without_trashed' => 'Bez izbrisanih zapisa',
],
],
'reorder_indicator' => 'Prevucite i ispustite zapise u red.',
'selection_indicator' => [
'selected_count' => '1 izabran zapis|:count izabrani zapisi',
'actions' => [
'select_all' => [
'label' => 'Izaberite sve :count',
],
'deselect_all' => [
'label' => 'Poništitite izbor',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Sortirajte po',
],
'direction' => [
'label' => 'Sortirajte po smjeru',
'options' => [
'asc' => 'Uzlazno',
'desc' => 'Silazno',
],
],
],
],
];
@@ -0,0 +1,232 @@
<?php
return [
'column_manager' => [
'heading' => 'Columnes',
],
'columns' => [
'actions' => [
'label' => 'Acció|Accions',
],
'text' => [
'actions' => [
'collapse_list' => 'Mostrar-ne :count menys',
'expand_list' => 'Mostrar-ne :count més',
],
'more_list_items' => 'i :count més',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Seleccionar/desseleccionar tots els elements per les accions massives.',
],
'bulk_select_record' => [
'label' => 'Seleccionar/desseleccionar l\'element :key per accions massives.',
],
'bulk_select_group' => [
'label' => 'Seleccionar/desseleccionar grup :title per accions massives.',
],
'search' => [
'label' => 'Cerca',
'placeholder' => 'Cercar',
'indicator' => 'Cercar',
],
],
'summary' => [
'heading' => 'Resum',
'subheadings' => [
'all' => 'Tots :label',
'group' => 'Resum del :group',
'page' => 'Aquesta pàgina',
],
'summarizers' => [
'average' => [
'label' => 'Mitja',
],
'count' => [
'label' => 'Recompte',
],
'sum' => [
'label' => 'Suma',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Acabar de reorganitzar registres',
],
'enable_reordering' => [
'label' => 'Reorganitzar registres',
],
'filter' => [
'label' => 'Filtrar',
],
'group' => [
'label' => 'Grup',
],
'open_bulk_actions' => [
'label' => 'Accions massives',
],
'column_manager' => [
'label' => 'Alternar columnes',
],
],
'empty' => [
'heading' => 'No s\'han trobat registres',
'description' => 'Crea un :model per començar.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Aplicar filtres',
],
'remove' => [
'label' => 'Esborrar filtre',
],
'remove_all' => [
'label' => 'Esborrar tots els filtres',
'tooltip' => 'Esborrar tots els filtres',
],
'reset' => [
'label' => 'Restablir',
],
],
'heading' => 'Filtres',
'indicator' => 'Filtres actius',
'multi_select' => [
'placeholder' => 'Tots',
],
'select' => [
'placeholder' => 'Tots',
],
'trashed' => [
'label' => 'Registres esborrats',
'only_trashed' => 'Només registres esborrats',
'with_trashed' => 'Amb registres esborrats',
'without_trashed' => 'Sense registres esborrats',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Agrupar per',
'placeholder' => 'Agrupar per',
],
'direction' => [
'label' => 'Sentit',
'options' => [
'asc' => 'Ascendent',
'desc' => 'Descendent',
],
],
],
],
'reorder_indicator' => 'Arrossega i deixa anar els registres per ordenar-los.',
'selection_indicator' => [
'selected_count' => '1 registre seleccionat|:count registres seleccionats',
'actions' => [
'select_all' => [
'label' => 'Selecciona\'ls tots :count',
],
'deselect_all' => [
'label' => 'Desselecciona\'ls tots',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Ordenar per',
],
'direction' => [
'label' => 'Sentit',
'options' => [
'asc' => 'Ascendent',
'desc' => 'Descendent',
],
],
],
],
];
@@ -0,0 +1,251 @@
<?php
return [
'column_manager' => [
'heading' => 'ستوونەکان',
'actions' => [
'apply' => [
'label' => 'جێبەجێکردنی ستونەکان',
],
'reset' => [
'label' => 'ڕێکخستنەوە',
],
],
],
'columns' => [
'actions' => [
'label' => 'کردار|کردارەکان',
],
'text' => [
'actions' => [
'collapse_list' => 'پیشاندانی :count کەمتر',
'expand_list' => 'پیشاندانی :count زیاتر',
],
'more_list_items' => 'هەروەها :count زیاتر',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'هەڵبژاردن/لابردنی هەڵبژاردنەکان بۆ هەموو تۆمارەکان بۆ کۆمەڵەی کردارەکان.',
],
'bulk_select_record' => [
'label' => 'هەڵبژاردن/لابردنی هەڵبژێردراوەژان بۆ :key بۆ کۆمەڵەی کردارەکان.',
],
'bulk_select_group' => [
'label' => 'هەڵبژاردن/لابردنی گرووپی :title بۆ کۆمەڵەی کردارەکان.',
],
'search' => [
'label' => 'گەڕان',
'placeholder' => 'گەڕان',
'indicator' => 'گەڕان',
],
],
'summary' => [
'heading' => 'پوختە',
'subheadings' => [
'all' => 'هەموو :label',
'group' => ':group پوختە',
'page' => 'ئەم پەڕەیە',
],
'summarizers' => [
'average' => [
'label' => 'تێکڕا',
],
'count' => [
'label' => 'ژماردەکان',
],
'sum' => [
'label' => 'کۆی گشتی',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'تەواوکردنی ڕێکخستنی تۆمارەکان',
],
'enable_reordering' => [
'label' => 'ڕێکخستنی تۆمارەکان',
],
'filter' => [
'label' => 'پاڵاوتن',
],
'group' => [
'label' => 'کۆمەڵ',
],
'open_bulk_actions' => [
'label' => 'کۆمەڵی کردارەکان',
],
'column_manager' => [
'label' => 'پشاندان/لابردنی ستوونەکان',
],
],
'empty' => [
'heading' => 'هیچ تۆمارێکی :model بوونی نییە.',
'description' => 'تۆمارێکی :model دروس بکە بۆ دەستپێکردن.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'جێبەجێکردنی پاڵاوتنەکان',
],
'remove' => [
'label' => 'لابردنی پاڵاوتن',
],
'remove_all' => [
'label' => 'لابردنی هەموو پاڵاوتنەکان',
'tooltip' => 'لابردنی هەموو پاڵاوتنەکان',
],
'reset' => [
'label' => 'ڕێکخسنتەوە',
],
],
'heading' => 'پاڵاوتنەکان',
'indicator' => 'پاڵاوتنە چالاککراوەکان',
'multi_select' => [
'placeholder' => 'هەموو',
],
'select' => [
'placeholder' => 'هەموو',
'relationship' => [
'empty_option_label' => 'هیچ',
],
],
'trashed' => [
'label' => 'تۆمارە سڕاوەکان',
'only_trashed' => 'تەنها تۆمارە سڕاوەکان',
'with_trashed' => 'لەگەل تۆمارە سڕاوەکان',
'without_trashed' => 'بەبێ تۆمارە سڕاوەکان',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'کۆمەڵکردن بە',
],
'direction' => [
'label' => 'ئاڕاستەی کۆمەڵکردن',
'options' => [
'asc' => 'کەم بۆ زۆر',
'desc' => 'زۆر بۆ کەم',
],
],
],
],
'reorder_indicator' => 'تۆمارەکان هەڵبگرە و ڕیزیان بکە.',
'selection_indicator' => [
'selected_count' => '1 ڕیز هەڵبژێردراوە|:count ڕیز هەڵبژێردراوە',
'actions' => [
'select_all' => [
'label' => 'هەڵبژاردنی هەموو :count',
],
'deselect_all' => [
'label' => 'هەڵنەبژاردنی هەموو',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'کۆمەڵکردن بە',
],
'direction' => [
'label' => 'ئاڕاستەی کۆمەڵ کردن',
'options' => [
'asc' => 'کەم بۆ زۆر',
'desc' => 'زۆر بۆ کەم',
],
],
],
],
'default_model_label' => 'تۆمار',
];
@@ -0,0 +1,264 @@
<?php
return [
'column_manager' => [
'heading' => 'Sloupce',
'actions' => [
'apply' => [
'label' => 'Použít sloupce',
],
'reset' => [
'label' => 'Resetovat sloupce',
],
],
],
'columns' => [
'actions' => [
'label' => 'Akce|Akce',
],
'select' => [
'loading_message' => 'Načítává se...',
'no_search_results_message' => 'Žádné možnosti neodpovídají vašemu hledání.',
'placeholder' => 'Vyberte možnost',
'searching_message' => 'Vyhledává se...',
'search_prompt' => 'Začněte psát pro vyhledávání...',
],
'text' => [
'actions' => [
'collapse_list' => 'Zobrazit o :count méně',
'expand_list' => 'Zobrazit o :count více',
],
'more_list_items' => 'a 1 další|a :count další| a :count dalších',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Vybrat/odznačit všechny položky pro hromadné akce.',
],
'bulk_select_record' => [
'label' => 'Vybrat/odznačit položku :key pro hromadné akce.',
],
'bulk_select_group' => [
'label' => 'Vybrat/zrušit výběr skupiny :title pro hromadné akce.',
],
'search' => [
'label' => 'Vyhledávání',
'placeholder' => 'Hledat',
'indicator' => 'Hledat',
],
],
'summary' => [
'heading' => 'Shrnutí',
'subheadings' => [
'all' => 'Všechny :label',
'group' => ':group shrnutí',
'page' => 'Tato stránka',
],
'summarizers' => [
'average' => [
'label' => 'Průměr',
],
'count' => [
'label' => 'Počet',
],
'sum' => [
'label' => 'Součet',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Dokončit změnu pořadí položek',
],
'enable_reordering' => [
'label' => 'Změnit pořadí položek',
],
'filter' => [
'label' => 'Filtrovat',
],
'group' => [
'label' => 'Seskupit',
],
'open_bulk_actions' => [
'label' => 'Otevřít panel akcí',
],
'column_manager' => [
'label' => 'Skrýt/zobrazit sloupce',
],
],
'empty' => [
'heading' => 'Žádné záznamy nenalezeny',
'description' => 'Začněte vytvořením :modelu.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Použít filtry',
],
'remove' => [
'label' => 'Odstranit filtr',
],
'remove_all' => [
'label' => 'Odstranit všechny filtry',
'tooltip' => 'Odstranit všechny filtry',
],
'reset' => [
'label' => 'Resetovat filtry',
],
],
'heading' => 'Filtrovat',
'indicator' => 'Aktivní filtry',
'multi_select' => [
'placeholder' => 'Vše',
],
'select' => [
'placeholder' => 'Vše',
'relationship' => [
'empty_option_label' => 'Žádná',
],
],
'trashed' => [
'label' => 'Smazané položky',
'only_trashed' => 'Pouze smazané položky',
'with_trashed' => 'Včetně smazaných položek',
'without_trashed' => 'Bez smazaných položek',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Seskupit podle',
],
'direction' => [
'label' => 'Směr seskupení',
'options' => [
'asc' => 'Vzestupně',
'desc' => 'Sestupně',
],
],
],
],
'reorder_indicator' => 'Vyberte a přesuňte položky.',
'selection_indicator' => [
'selected_count' => '{1} 1 záznam zvolen|[2,4] :count záznamy zvoleny|[5,*] :count záznamů zvoleno',
'actions' => [
'select_all' => [
'label' => 'Označit všechny :count',
],
'deselect_all' => [
'label' => 'Odznačit všechny',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Seřadit podle',
],
'direction' => [
'label' => 'Směr řazení',
'options' => [
'asc' => 'Vzestupně',
'desc' => 'Sestupně',
],
],
],
],
'default_model_label' => 'záznam',
];
@@ -0,0 +1,146 @@
<?php
return [
'columns' => [
'tags' => [
'more' => 'Ychwanegu :count arall',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Dewis / Dad ddewis pob eitem ar gyfer gweithredoedd swmpus',
],
'bulk_select_record' => [
'label' => 'Dewis / Dad ddewis eitem :key ar gyfer gweithredoedd swmpus',
],
'search_query' => [
'label' => 'Chwilio',
'placeholder' => 'Chwilio',
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Gorffen ail archebu cofnodion',
],
'enable_reordering' => [
'label' => 'Ail archebu cofnodion',
],
'filter' => [
'label' => 'Hidlo',
],
'open_actions' => [
'label' => 'Gweithredoedd agored',
],
'column_manager' => [
'label' => 'Toglo colofnau',
],
],
'empty' => [
'heading' => 'Ni ddarganfuwyd unrhyw gofnodion',
],
'filters' => [
'actions' => [
'remove' => [
'label' => 'Tynnu hidlydd',
],
'remove_all' => [
'label' => 'Tynnu pob hidlydd',
'tooltip' => 'Tynnu pob hidlydd',
],
'reset' => [
'label' => 'Ailosod hidlyddion',
],
],
'indicator' => 'Hidlyddion Gweithredol',
'multi_select' => [
'placeholder' => 'Oll',
],
'select' => [
'placeholder' => 'Oll',
],
'trashed' => [
'label' => 'Cofnodion wedi dileu',
'only_trashed' => 'Dim ond cofnodion wedi dileu',
'with_trashed' => 'Gyda chofnodion wedi dileu',
'without_trashed' => 'Heb gofnodion wedi dileu',
],
],
'reorder_indicator' => 'Llusgo a gollwn y cofnodion mewn trefn',
'selection_indicator' => [
'selected_count' => 'Dewiswyd 1 cofnod|:count rcyfrif wedi`u dewis',
'actions' => [
'select_all' => [
'label' => 'Dewiswch bob :count',
],
'deselect_all' => [
'label' => 'Dad-ddewis popeth',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Trefnu fesul',
],
'direction' => [
'label' => 'Trefnu cyfeiriad',
'options' => [
'asc' => 'Esgynnol',
'desc' => 'Disgynnol',
],
],
],
],
];
@@ -0,0 +1,220 @@
<?php
return [
'column_manager' => [
'heading' => 'Kolonner',
],
'columns' => [
'text' => [
'actions' => [
'collapse_list' => 'Vis :count mindre',
'expand_list' => 'Vis :count flere',
],
'more_list_items' => 'og :count flere',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Vælg/fravælg alle rækker for masse handlinger.',
],
'bulk_select_record' => [
'label' => 'Vælg/fravælg :key for masse handlinger.',
],
'bulk_select_group' => [
'label' => 'Vælg/fravælg gruppe :title til massehandlinger.',
],
'search' => [
'label' => 'Søg',
'placeholder' => 'Søg',
'indicator' => 'Søg',
],
],
'summary' => [
'heading' => 'Resumé',
'subheadings' => [
'all' => 'Alle :label',
'group' => ':group resumé',
'page' => 'Denne side',
],
'summarizers' => [
'average' => [
'label' => 'Gennemsnit',
],
'count' => [
'label' => 'Antal',
],
'sum' => [
'label' => 'Sum',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Afslut omrokering',
],
'enable_reordering' => [
'label' => 'Omroker rækker',
],
'filter' => [
'label' => 'Filtrer',
],
'group' => [
'label' => 'Gruppe',
],
'open_bulk_actions' => [
'label' => 'Åbn handlinger',
],
'column_manager' => [
'label' => 'Vælg kolonner',
],
],
'empty' => [
'heading' => 'Ingen resultater',
'description' => 'Opret en :model for at komme igang.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Anvend filtre',
],
'remove' => [
'label' => 'Fjern filter',
],
'remove_all' => [
'label' => 'Fjern alle filtre',
'tooltip' => 'Fjern alle filtre',
],
'reset' => [
'label' => 'Nulstil',
],
],
'heading' => 'Filtre',
'indicator' => 'Aktive filtre',
'multi_select' => [
'placeholder' => 'Alle',
],
'select' => [
'placeholder' => 'Alle',
],
'trashed' => [
'label' => 'Slettede rækker',
'only_trashed' => 'Kun slettede rækker',
'with_trashed' => 'Med slettede rækker',
'without_trashed' => 'Uden slettede rækker',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Gruppere på',
'placeholder' => 'Gruppere på',
],
'direction' => [
'label' => 'Grupperingsretning',
'options' => [
'asc' => 'Stigende',
'desc' => 'Faldende',
],
],
],
],
'reorder_indicator' => 'Træk og slip rækkerne i den ønskede rækkefølge.',
'selection_indicator' => [
'selected_count' => '1 række valgt|:count rækker valgt',
'actions' => [
'select_all' => [
'label' => 'Vælg alle :count',
],
'deselect_all' => [
'label' => 'Fravælg alle',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Sorter efter',
],
'direction' => [
'label' => 'Sorteringsretning',
'options' => [
'asc' => 'Stigende',
'desc' => 'Faldende',
],
],
],
],
];
@@ -0,0 +1,252 @@
<?php
return [
'column_manager' => [
'heading' => 'Spalten',
'actions' => [
'apply' => [
'label' => 'Spalten anwenden',
],
'reset' => [
'label' => 'Zurücksetzen',
],
],
],
'columns' => [
'actions' => [
'label' => 'Aktion|Aktionen',
],
'text' => [
'actions' => [
'collapse_list' => ':count weniger anzeigen',
'expand_list' => ':count weitere anzeigen',
],
'more_list_items' => 'und :count weitere',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Alle Einträge für Stapelverarbeitung auswählen/abwählen.',
],
'bulk_select_record' => [
'label' => 'Eintrag :key für Stapelverarbeitung auswählen/abwählen.',
],
'bulk_select_group' => [
'label' => 'Gruppe auswählen/abwählen :title für Stapelverarbeitung.',
],
'search' => [
'label' => 'Suche',
'placeholder' => 'Suche',
'indicator' => 'Suche',
],
],
'summary' => [
'heading' => 'Zusammenfassung',
'subheadings' => [
'all' => 'Alle :label',
'group' => ':group Zusammenfassung',
'page' => 'Diese Seite',
],
'summarizers' => [
'average' => [
'label' => 'Durchschnitt',
],
'count' => [
'label' => 'Anzahl',
],
'sum' => [
'label' => 'Summe',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Sortieren beenden',
],
'enable_reordering' => [
'label' => 'Einträge sortieren',
],
'filter' => [
'label' => 'Filtern',
],
'group' => [
'label' => 'Gruppe',
],
'open_bulk_actions' => [
'label' => 'Aktionen öffnen',
],
'column_manager' => [
'label' => 'Spalten auswählen',
],
],
'empty' => [
'heading' => 'Keine :model',
'description' => 'Erstelle ein(e) :model um zu beginnen.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => ' Filter anwenden',
],
'remove' => [
'label' => 'Filter löschen',
],
'remove_all' => [
'label' => 'Alle Filter löschen',
'tooltip' => 'Alle Filter löschen',
],
'reset' => [
'label' => 'Filter zurücksetzen',
],
],
'heading' => 'Filter',
'indicator' => 'Aktive Filter',
'multi_select' => [
'placeholder' => 'Alle',
],
'select' => [
'placeholder' => 'Alle',
'relationship' => [
'empty_option_label' => 'Keine',
],
],
'trashed' => [
'label' => 'Gelöschte Einträge',
'only_trashed' => 'Nur gelöschte Einträge',
'with_trashed' => 'Mit gelöschten Einträgen',
'without_trashed' => 'Ohne gelöschte Einträge',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Gruppieren nach',
'placeholder' => 'Gruppieren nach',
],
'direction' => [
'label' => 'Gruppierungsrichtung',
'options' => [
'asc' => 'Aufsteigend',
'desc' => 'Absteigend',
],
],
],
],
'reorder_indicator' => 'Zum Sortieren die Einträge per Drag & Drop in die richtige Reihenfolge ziehen.',
'selection_indicator' => [
'selected_count' => '1 Datensatz ausgewählt|:count Datensätze ausgewählt',
'actions' => [
'select_all' => [
'label' => 'Alle :count Datensätze auswählen',
],
'deselect_all' => [
'label' => 'Auswahl aufheben',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Sortieren nach',
],
'direction' => [
'label' => 'Sortierrichtung',
'options' => [
'asc' => 'Aufsteigend',
'desc' => 'Absteigend',
],
],
],
],
'default_model_label' => 'Datensatz',
];
@@ -0,0 +1,263 @@
<?php
return [
'column_manager' => [
'heading' => 'Στήλες',
'actions' => [
'apply' => [
'label' => 'Εφαρμογή στήλων',
],
'reset' => [
'label' => 'Επαναφορά',
],
],
],
'columns' => [
'actions' => [
'label' => 'Ενέργεια|Ενέργειες',
],
'select' => [
'loading_message' => 'Φόρτωση...',
'no_search_results_message' => 'Δεν βρέθηκαν επιλογές που ταιριάζουν στην αναζήτησή σας.',
'placeholder' => 'Επιλέξτε',
'searching_message' => 'Αναζήτηση...',
'search_prompt' => 'Ξεκινήστε να πληκτρολογείτε για αναζήτηση...',
],
'text' => [
'actions' => [
'collapse_list' => 'Προβολή :count λιγότερων',
'expand_list' => 'Προβολή :count περισσότερων',
],
'more_list_items' => 'και :count περισσότερα',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Επιλέξτε όλες τις εγγραφές για μαζικές ενέργειες.',
],
'bulk_select_record' => [
'label' => 'Επιλέξτε την εγγραφή :key για μαζικές ενέργειες.',
],
'bulk_select_group' => [
'label' => 'Επιλέξτε την ομάδα :title για μαζικές ενέργειες.',
],
'search' => [
'label' => 'Αναζήτηση',
'placeholder' => 'Αναζήτηση',
'indicator' => 'Αναζήτηση',
],
],
'summary' => [
'heading' => 'Σύνοψη',
'subheadings' => [
'all' => 'Όλα :label',
'group' => 'σύνοψη :group',
'page' => 'This page',
],
'summarizers' => [
'average' => [
'label' => 'Μέσος όρος',
],
'count' => [
'label' => 'Σύνολο',
],
'sum' => [
'label' => 'Άθροισμα',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Τερματισμός αναδιάταξης',
],
'enable_reordering' => [
'label' => 'Αναδιάταξη εγγραφών',
],
'filter' => [
'label' => 'Φίλτρο',
],
'group' => [
'label' => 'Ομάδας',
],
'open_bulk_actions' => [
'label' => 'Μαζικές ενέργειες',
],
'column_manager' => [
'label' => 'Column manager',
],
],
'empty' => [
'heading' => 'Δεν υπάρχουν εγγραφές',
'description' => 'Προσθέστε ένα/μία ":model" για να ξεκινήσετε.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Εφαρμογή φίλτρου',
],
'remove' => [
'label' => 'Αφαίρεση φίτλρου',
],
'remove_all' => [
'label' => 'Αφαίρεση φίτλρων',
'tooltip' => 'Αφαίρεση φίτλρων',
],
'reset' => [
'label' => 'Επαναφορά',
],
],
'heading' => 'Φίλτρα',
'indicator' => 'Ενεργά φίλτρα',
'multi_select' => [
'placeholder' => 'Όλα',
],
'select' => [
'placeholder' => 'Όλα',
'relationship' => [
'empty_option_label' => 'Κανένα',
],
],
'trashed' => [
'label' => 'Διεγραμμένες εγγραφές',
'only_trashed' => 'Μόνο διεγραμμένες εγγραφές',
'with_trashed' => 'Σε συνδυασμό με διεγραμμένες εγγραφές',
'without_trashed' => 'Χωρίς διεγραμμένες εγγραφές',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Ομαδοποίηση βάσει',
],
'direction' => [
'label' => 'Group direction',
'options' => [
'asc' => 'Αύξουσα σειρά',
'desc' => 'Φθίνουσα σειρά',
],
],
],
],
'reorder_indicator' => 'Σύρετε και αποθέστε τις εγγραφές με τη σειρά.',
'selection_indicator' => [
'selected_count' => 'επιλογή 1 εγγραφής|επιλογή :count εγγραφών',
'actions' => [
'select_all' => [
'label' => 'Επιλογή όλων :count',
],
'deselect_all' => [
'label' => 'Αποεπιλογή όλων',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Ταξινόμηση κατά',
],
'direction' => [
'label' => 'Κατεύθυνση ταξινόμησης',
'options' => [
'asc' => 'Αύξουσα σειρά',
'desc' => 'Φθίνουσα σειρά',
],
],
],
],
'default_model_label' => 'Εγγραφή',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'Columns',
'actions' => [
'apply' => [
'label' => 'Apply columns',
],
'reset' => [
'label' => 'Reset',
],
],
],
'columns' => [
'actions' => [
'label' => 'Action|Actions',
],
'select' => [
'loading_message' => 'Loading...',
'no_search_results_message' => 'No options match your search.',
'placeholder' => 'Select an option',
'searching_message' => 'Searching...',
'search_prompt' => 'Start typing to search...',
],
'text' => [
'actions' => [
'collapse_list' => 'Show :count less',
'expand_list' => 'Show :count more',
],
'more_list_items' => 'and :count more',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Select/deselect all items for bulk actions.',
],
'bulk_select_record' => [
'label' => 'Select/deselect item :key for bulk actions.',
],
'bulk_select_group' => [
'label' => 'Select/deselect group :title for bulk actions.',
],
'search' => [
'label' => 'Search',
'placeholder' => 'Search',
'indicator' => 'Search',
],
],
'summary' => [
'heading' => 'Summary',
'subheadings' => [
'all' => 'All :label',
'group' => ':group summary',
'page' => 'This page',
],
'summarizers' => [
'average' => [
'label' => 'Average',
],
'count' => [
'label' => 'Count',
],
'sum' => [
'label' => 'Sum',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Finish reordering records',
],
'enable_reordering' => [
'label' => 'Reorder records',
],
'filter' => [
'label' => 'Filter',
],
'group' => [
'label' => 'Group',
],
'open_bulk_actions' => [
'label' => 'Bulk actions',
],
'column_manager' => [
'label' => 'Column manager',
],
],
'empty' => [
'heading' => 'No :model',
'description' => 'Create a :model to get started.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Apply filters',
],
'remove' => [
'label' => 'Remove filter',
],
'remove_all' => [
'label' => 'Remove all filters',
'tooltip' => 'Remove all filters',
],
'reset' => [
'label' => 'Reset',
],
],
'heading' => 'Filters',
'indicator' => 'Active filters',
'multi_select' => [
'placeholder' => 'All',
],
'select' => [
'placeholder' => 'All',
'relationship' => [
'empty_option_label' => 'None',
],
],
'trashed' => [
'label' => 'Deleted records',
'only_trashed' => 'Only deleted records',
'with_trashed' => 'With deleted records',
'without_trashed' => 'Without deleted records',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Group by',
],
'direction' => [
'label' => 'Group direction',
'options' => [
'asc' => 'Ascending',
'desc' => 'Descending',
],
],
],
],
'reorder_indicator' => 'Drag and drop the records into order.',
'selection_indicator' => [
'selected_count' => '1 record selected|:count records selected',
'actions' => [
'select_all' => [
'label' => 'Select all :count',
],
'deselect_all' => [
'label' => 'Deselect all',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Sort by',
],
'direction' => [
'label' => 'Sort direction',
'options' => [
'asc' => 'Ascending',
'desc' => 'Descending',
],
],
],
],
'default_model_label' => 'record',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'Columnas',
'actions' => [
'apply' => [
'label' => 'Aplicar columnas',
],
'reset' => [
'label' => 'Resetear las columnas',
],
],
],
'columns' => [
'actions' => [
'label' => 'Acción|Acciones',
],
'select' => [
'loading_message' => 'Cargando...',
'no_search_results_message' => 'No hay opciones que coincidan con su búsqueda.',
'placeholder' => 'Seleccione una opción',
'searching_message' => 'Buscando...',
'search_prompt' => 'Empiece a escribir para buscar...',
],
'text' => [
'actions' => [
'collapse_list' => 'Mostrar :count menos',
'expand_list' => 'Mostrar :count más',
],
'more_list_items' => 'y :count más',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Seleccionar/deseleccionar todos los elementos para las acciones masivas.',
],
'bulk_select_record' => [
'label' => 'Seleccionar/deseleccionar el elemento :key para las acciones masivas.',
],
'bulk_select_group' => [
'label' => 'Seleccionar/deseleccionar grupo :title para acciones masivas.',
],
'search' => [
'label' => 'Búsqueda',
'placeholder' => 'Buscar',
'indicator' => 'Buscar',
],
],
'summary' => [
'heading' => 'Resumen',
'subheadings' => [
'all' => 'Todos :label',
'group' => 'resumen del :group',
'page' => 'Esta página',
],
'summarizers' => [
'average' => [
'label' => 'Media',
],
'count' => [
'label' => 'Recuento',
],
'sum' => [
'label' => 'Suma',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Terminar de reordenar registros',
],
'enable_reordering' => [
'label' => 'Reordenar registros',
],
'filter' => [
'label' => 'Filtrar',
],
'group' => [
'label' => 'Grupo',
],
'open_bulk_actions' => [
'label' => 'Abrir acciones',
],
'column_manager' => [
'label' => 'Alternar columnas',
],
],
'empty' => [
'heading' => 'No se encontraron registros',
'description' => 'Cree un :model para empezar.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Aplicar filtros',
],
'remove' => [
'label' => 'Quitar filtro',
],
'remove_all' => [
'label' => 'Quitar todos los filtros',
'tooltip' => 'Quitar todos los filtros',
],
'reset' => [
'label' => 'Resetear los filtros',
],
],
'heading' => 'Filtros',
'indicator' => 'Filtros activos',
'multi_select' => [
'placeholder' => 'Todos',
],
'select' => [
'placeholder' => 'Todos',
'relationship' => [
'empty_option_label' => 'Ninguno',
],
],
'trashed' => [
'label' => 'Registros eliminados',
'only_trashed' => 'Solo registros eliminados',
'with_trashed' => 'Con registros eliminados',
'without_trashed' => 'Sin registros eliminados',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Agrupar por',
],
'direction' => [
'label' => 'Dirección de grupo',
'options' => [
'asc' => 'Ascendente',
'desc' => 'Descendente',
],
],
],
],
'reorder_indicator' => 'Arrastrar los registros en el orden.',
'selection_indicator' => [
'selected_count' => '1 registro seleccionado|:count registros seleccionados',
'actions' => [
'select_all' => [
'label' => 'Selecciona todos :count',
],
'deselect_all' => [
'label' => 'Deselecciona todos',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Ordenar por',
],
'direction' => [
'label' => 'Dirección del orden',
'options' => [
'asc' => 'Ascendente',
'desc' => 'Descendente',
],
],
],
],
'default_model_label' => 'registro',
];
@@ -0,0 +1,213 @@
<?php
return [
'column_manager' => [
'heading' => 'Zutabeak',
],
'columns' => [
'text' => [
'more_list_items' => 'eta :count gehiago',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Aukeratu/deselektatu denak ekintza masiboetarako.',
],
'bulk_select_record' => [
'label' => 'Aukeratu/deselektatu :key ekintza masiboetarako.',
],
'search' => [
'label' => 'Bilatu',
'placeholder' => 'Bilatu',
'indicator' => 'Bilatu',
],
],
'summary' => [
'heading' => 'Laburpena',
'subheadings' => [
'all' => 'Guztiak :label',
'group' => ':group-aren laburpena',
'page' => 'Orrialde hau',
],
'summarizers' => [
'average' => [
'label' => 'Batezbesteko',
],
'count' => [
'label' => 'Zenbatekoa',
],
'sum' => [
'label' => 'Baturak',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Erregistroen berrantolaketa amaitu',
],
'enable_reordering' => [
'label' => 'Erregistroak berrantolatu',
],
'filter' => [
'label' => 'Iragazkiak',
],
'group' => [
'label' => 'Taldekatu',
],
'open_bulk_actions' => [
'label' => 'Ireki ekintzak',
],
'column_manager' => [
'label' => 'Zutabeak aldatu',
],
],
'empty' => [
'heading' => 'Erregistroak ez daude aurkitu',
'description' => 'Sortu :model bat hasteko.',
],
'filters' => [
'actions' => [
'remove' => [
'label' => 'Iragazkia kendu',
],
'remove_all' => [
'label' => 'Iragazki guztiak kendu',
'tooltip' => 'Iragazki guztiak kendu',
],
'reset' => [
'label' => 'Berrezarri iragazkiak',
],
],
'heading' => 'Iragazkiak',
'indicator' => 'Iragazkiak aktiboak',
'multi_select' => [
'placeholder' => 'Guztiak',
],
'select' => [
'placeholder' => 'Guztiak',
],
'trashed' => [
'label' => 'Ezabatutako erregistroak',
'only_trashed' => 'Bakarrik ezabatutako erregistroak',
'with_trashed' => 'Ezabatutako erregistroekin',
'without_trashed' => 'Ezabatutako erregistro gabe',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Taldekatu',
'placeholder' => 'Taldekatu',
],
'direction' => [
'label' => 'Taldekatzearen norabidea',
'options' => [
'asc' => 'Goranzkoa',
'desc' => 'Beheranzkoa',
],
],
],
],
'reorder_indicator' => 'Erregistroak ordenan eraman ahal izateko arrastatu.',
'selection_indicator' => [
'selected_count' => ':count erregistro aukeratu da|:count erregistro aukeratuak dira',
'actions' => [
'select_all' => [
'label' => 'Hautatu guztiak :count',
],
'deselect_all' => [
'label' => 'Aukeratu guztiak kentzea',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Ordenatu',
],
'direction' => [
'label' => 'Ordenaren norabidea',
'options' => [
'asc' => 'Goranzkoa',
'desc' => 'Beheranzkoa',
],
],
],
],
];
@@ -0,0 +1,250 @@
<?php
return [
'column_manager' => [
'heading' => 'ستون‌ها',
'actions' => [
'apply' => [
'label' => 'اعمال ستون‌ها',
],
'reset' => [
'label' => 'بازنشانی ستون‌ها',
],
],
],
'columns' => [
'actions' => [
'label' => 'عملیات|عملیات‌ها',
],
'text' => [
'actions' => [
'collapse_list' => 'نمایش :count کمتر',
'expand_list' => 'نمایش :count بیشتر',
],
'more_list_items' => 'و :count تا بیشتر',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'انتخاب / عدم‌انتخاب تمامی موارد برای اقدامات گروهی',
],
'bulk_select_record' => [
'label' => 'انتخاب / عدم‌انتخاب مورد :key برای اقدامات گروهی',
],
'bulk_select_group' => [
'label' => 'انتخاب / عدم‌انتخاب گروه :title برای اقدامات گروهی.',
],
'search' => [
'label' => 'جستجو',
'placeholder' => 'جستجو',
'indicator' => 'جستجو',
],
],
'summary' => [
'heading' => 'خلاصه',
'subheadings' => [
'all' => 'تمام :label',
'group' => ':group خلاصه',
'page' => 'این صفحه',
],
'summarizers' => [
'average' => [
'label' => 'میانگین',
],
'count' => [
'label' => 'تعداد',
],
'sum' => [
'label' => 'مجموع',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'اتمام بازچینش رکوردها',
],
'enable_reordering' => [
'label' => 'بازچینش رکوردها',
],
'filter' => [
'label' => 'فیلتر',
],
'group' => [
'label' => 'گروه',
],
'open_bulk_actions' => [
'label' => 'عملیات گروهی',
],
'column_manager' => [
'label' => 'باز / بستن ستون‌ها',
],
],
'empty' => [
'heading' => ':model یافت نشد.',
'description' => 'برای شروع یک :model ایجاد کنید.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'اعمال فیلترها',
],
'remove' => [
'label' => 'حذف فیلتر',
],
'remove_all' => [
'label' => 'حذف تمام فیلترها',
'tooltip' => 'حذف تمام فیلترها',
],
'reset' => [
'label' => 'بازنشانی فیلترها',
],
],
'heading' => 'فیلترها',
'indicator' => 'فیلترهای فعال',
'multi_select' => [
'placeholder' => 'همه',
],
'select' => [
'placeholder' => 'همه',
'relationship' => [
'empty_option_label' => 'هیچ',
],
],
'trashed' => [
'label' => 'رکوردهای حذف‌‌شده',
'only_trashed' => 'فقط رکوردهای حذف‌‌شده',
'with_trashed' => 'به همراه رکوردهای حذف‌‌شده',
'without_trashed' => 'بدون رکوردهای حذف‌‌شده',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'گروه‌بندی براساس',
'placeholder' => 'گروه‌بندی براساس',
],
'direction' => [
'label' => 'ترتیب گروه',
'options' => [
'asc' => 'صعودی',
'desc' => 'نزولی',
],
],
],
],
'reorder_indicator' => 'برای تغییر ترتیب، بکشید و رها کنید.',
'selection_indicator' => [
'selected_count' => '1 آیتم انتخاب شده|:count آیتم انتخاب شده',
'actions' => [
'select_all' => [
'label' => 'انتخاب همه‌ی :count آیتم',
],
'deselect_all' => [
'label' => 'عدم انتخاب',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'مرتب‌ سازی براساس',
],
'direction' => [
'label' => 'جهت مرتب‌ سازی',
'options' => [
'asc' => 'صعودی',
'desc' => 'نزولی',
],
],
],
],
'default_model_label' => 'رکورد',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'Sarakkeet',
'actions' => [
'apply' => [
'label' => 'Aseta sarakkeet',
],
'reset' => [
'label' => 'Palauta',
],
],
],
'columns' => [
'actions' => [
'label' => 'Toiminta|Toiminnat',
],
'select' => [
'loading_message' => 'Ladataan...',
'no_search_results_message' => 'Ei hakuasi vastaavia vaihtoehtoja.',
'placeholder' => 'Valitse vaihtoehto',
'searching_message' => 'Haetaan...',
'search_prompt' => 'Aloita kirjoittaminen hakeaksesi...',
],
'text' => [
'actions' => [
'collapse_list' => 'Näytä :count vähemmän',
'expand_list' => 'Näytä :count lisää',
],
'more_list_items' => 'ja :count lisää',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Aseta/poista massatoiminnon valinta kaikista kohteista.',
],
'bulk_select_record' => [
'label' => 'Aseta/poista massatoiminnon valinta kohteelle :key.',
],
'bulk_select_group' => [
'label' => 'Aseta/poista massatoiminnon valinta ryhmälle :title.',
],
'search' => [
'label' => 'Haku',
'placeholder' => 'Hae',
'indicator' => 'Haku',
],
],
'summary' => [
'heading' => 'Yhteenveto',
'subheadings' => [
'all' => 'Kaikki :label',
'group' => ':group yhteenveto',
'page' => 'Tämä sivu',
],
'summarizers' => [
'average' => [
'label' => 'Keskiarvo',
],
'count' => [
'label' => 'Määrä',
],
'sum' => [
'label' => 'Summa',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Viimeistele tietueiden järjestely',
],
'enable_reordering' => [
'label' => 'Järjestele tietueita',
],
'filter' => [
'label' => 'Suodata',
],
'group' => [
'label' => 'Ryhmä',
],
'open_bulk_actions' => [
'label' => 'Avaa toiminnot',
],
'column_manager' => [
'label' => 'Näytä sarakkeet',
],
],
'empty' => [
'heading' => 'Ei :model',
'description' => 'Luo :model aloittaaksesi.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Aseta suodattimet',
],
'remove' => [
'label' => 'Poista suodatin',
],
'remove_all' => [
'label' => 'Tyhjennä suodattimet',
'tooltip' => 'Tyhjennä suodattimet',
],
'reset' => [
'label' => 'Palauta',
],
],
'heading' => 'Suodattimet',
'indicator' => 'Aktiiviset suodattimet',
'multi_select' => [
'placeholder' => 'Kaikki',
],
'select' => [
'placeholder' => 'Kaikki',
'relationship' => [
'empty_option_label' => 'Ei yhtään',
],
],
'trashed' => [
'label' => 'Poistetut tietueet',
'only_trashed' => 'Vain poistetut tietueet',
'with_trashed' => 'Poistettujen tietueiden kanssa',
'without_trashed' => 'Ilman poistettuja tietueita',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Ryhmittele',
],
'direction' => [
'label' => 'Ryhmitys',
'options' => [
'asc' => 'Nousevasti',
'desc' => 'Laskevasti',
],
],
],
],
'reorder_indicator' => 'Raahaa ja pudota tietueet järjestykseen.',
'selection_indicator' => [
'selected_count' => '1 tietue valittu|:count tietuetta valittu',
'actions' => [
'select_all' => [
'label' => 'Valitse kaikki :count tietuetta',
],
'deselect_all' => [
'label' => 'Poista valinnat',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Järjestele',
],
'direction' => [
'label' => 'Järjestys',
'options' => [
'asc' => 'Nousevasti',
'desc' => 'Laskevasti',
],
],
],
],
'default_model_label' => 'tietue',
];
@@ -0,0 +1,252 @@
<?php
return [
'column_manager' => [
'heading' => 'Colonnes',
'actions' => [
'apply' => [
'label' => 'Appliquer les colonnes',
],
'reset' => [
'label' => 'Réinitialiser',
],
],
],
'columns' => [
'actions' => [
'label' => 'Action|Actions',
],
'text' => [
'actions' => [
'collapse_list' => 'Afficher :count de moins',
'expand_list' => 'Afficher :count de plus',
],
'more_list_items' => ':count de plus',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Sélectionner/déselectionner tous les éléments pour les actions groupées.',
],
'bulk_select_record' => [
'label' => "Sélectionner/désélectionner l'élément :key pour les actions groupées.",
],
'bulk_select_group' => [
'label' => 'Sélectionner/désélectionner le groupe :title pour les actions groupées.',
],
'search' => [
'label' => 'Rechercher',
'placeholder' => 'Rechercher',
'indicator' => 'Recherche',
],
],
'summary' => [
'heading' => 'Résumé',
'subheadings' => [
'all' => 'Tous :label',
'group' => 'résumé de :group',
'page' => 'Cette page',
],
'summarizers' => [
'average' => [
'label' => 'Moyenne',
],
'count' => [
'label' => 'Compteur',
],
'sum' => [
'label' => 'Somme',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Fin du classement des enregistrements',
],
'enable_reordering' => [
'label' => 'Classer les enregistrements',
],
'filter' => [
'label' => 'Filtre',
],
'group' => [
'label' => 'Groupe',
],
'open_bulk_actions' => [
'label' => 'Ouvrir les actions',
],
'column_manager' => [
'label' => 'Basculer les colonnes',
],
],
'empty' => [
'heading' => 'Aucun(e) :model',
'description' => 'Créer un(e) :model pour commencer.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Appliquer les filtres',
],
'remove' => [
'label' => 'Supprimer le filtre',
],
'remove_all' => [
'label' => 'Supprimer tous les filtres',
'tooltip' => 'Supprimer tous les filtres',
],
'reset' => [
'label' => 'Réinitialiser les filtres',
],
],
'heading' => 'Filtres',
'indicator' => 'Filtres actifs',
'multi_select' => [
'placeholder' => 'Tout',
],
'select' => [
'placeholder' => 'Tout',
'relationship' => [
'empty_option_label' => 'Aucun',
],
],
'trashed' => [
'label' => 'Enregistrements supprimés',
'only_trashed' => 'Enregistrements supprimés uniquement',
'with_trashed' => 'Avec les enregistrements supprimés',
'without_trashed' => 'Sans les enregistrements supprimés',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Grouper par',
'placeholder' => 'Grouper par',
],
'direction' => [
'label' => 'Groupe',
'options' => [
'asc' => 'Croissant',
'desc' => 'Décroissant',
],
],
],
],
'reorder_indicator' => "Faites glisser et déposez les enregistrements dans l'ordre.",
'selection_indicator' => [
'selected_count' => '1 élément sélectionné|:count éléments sélectionnés',
'actions' => [
'select_all' => [
'label' => 'Sélectionner tout (:count)',
],
'deselect_all' => [
'label' => 'Désélectionner tout',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Trier par',
],
'direction' => [
'label' => 'Ordre',
'options' => [
'asc' => 'Croissant',
'desc' => 'Décroissant',
],
],
],
],
'default_model_label' => 'enregistrement',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'עמודות',
'actions' => [
'apply' => [
'label' => 'החל עמודות',
],
'reset' => [
'label' => 'איפוס',
],
],
],
'columns' => [
'actions' => [
'label' => 'פעולה|פעולות',
],
'select' => [
'loading_message' => 'טוען...',
'no_search_results_message' => 'לא נמצאו תוצאות.',
'placeholder' => 'בחר',
'searching_message' => 'מחפש...',
'search_prompt' => 'הקלד כדי לחפש...',
],
'text' => [
'actions' => [
'collapse_list' => 'הצג :count פחות',
'expand_list' => 'הצג עוד :count',
],
'more_list_items' => 'ו-:count פריטים נוספים',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'בחר/בטל בחירה של כל הפריטים לפעולות מרובות.',
],
'bulk_select_record' => [
'label' => 'בחר/בטל בחירה של פריט :key לפעולות מרובות.',
],
'bulk_select_group' => [
'label' => 'בחר/בטל בחירה של קבוצה :title לפעולות מרובות.',
],
'search' => [
'label' => 'חפש',
'placeholder' => 'חפש',
'indicator' => 'חיפוש',
],
],
'summary' => [
'heading' => 'סיכום',
'subheadings' => [
'all' => 'כל ה:label',
'group' => 'סיכום של :group',
'page' => 'בעמוד זה',
],
'summarizers' => [
'average' => [
'label' => 'ממוצע',
],
'count' => [
'label' => 'ספירה',
],
'sum' => [
'label' => 'סכום',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'סיים סידור רשומות',
],
'enable_reordering' => [
'label' => 'סדר רשומות מחדש',
],
'filter' => [
'label' => 'מסננים',
],
'group' => [
'label' => 'קבוצה',
],
'open_bulk_actions' => [
'label' => 'פתח פעולות מרובות',
],
'column_manager' => [
'label' => 'הצג עמודות',
],
],
'empty' => [
'heading' => 'לא נמצאו רשומות',
'description' => 'צור :model כדי להתחיל.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'החל מסננים',
],
'remove' => [
'label' => 'הסר מסנן',
],
'remove_all' => [
'label' => 'הסר את כל המסננים',
'tooltip' => 'הסר את כל המסננים',
],
'reset' => [
'label' => 'איפוס מסננים',
],
],
'heading' => 'מסננים',
'indicator' => 'מסננים מופעלים',
'multi_select' => [
'placeholder' => 'הכל',
],
'select' => [
'placeholder' => 'הכל',
'relationship' => [
'empty_option_label' => 'ללא',
],
],
'trashed' => [
'label' => 'רשומות שנמחקו',
'only_trashed' => 'רק רשומות שנמחקו',
'with_trashed' => 'כולל רשומות שנמחקו',
'without_trashed' => 'ללא רשומות שנמחקו',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'קבץ לפי',
],
'direction' => [
'label' => 'כיוון קיבוץ',
'options' => [
'asc' => 'עולה',
'desc' => 'יורד',
],
],
],
],
'reorder_indicator' => 'גרור ושחרר רשומות כדי לסדר מחדש.',
'selection_indicator' => [
'selected_count' => 'נבחרה רשומה אחת|נבחרו :count רשומות',
'actions' => [
'select_all' => [
'label' => 'בחר את כל ה-:count',
],
'deselect_all' => [
'label' => 'בטל בחירה',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'מיין לפי',
],
'direction' => [
'label' => 'כיוון מיון',
'options' => [
'asc' => 'סדר עולה',
'desc' => 'סדר יורד',
],
],
],
],
'default_model_label' => 'רשומה',
];
@@ -0,0 +1,68 @@
<?php
return [
'fields' => [
'search' => [
'label' => 'खोजें',
'placeholder' => 'खोजें',
],
],
'actions' => [
'filter' => [
'label' => 'फ़िल्टर',
],
'open_bulk_actions' => [
'label' => 'क्रियाएँ खोलें',
],
],
'empty' => [
'heading' => 'कोई रिकॉर्ड उपलब्ध नहीं',
],
'filters' => [
'actions' => [
'reset' => [
'label' => 'फ़िल्टर रीसेट करें',
],
],
'multi_select' => [
'placeholder' => 'सब',
],
'select' => [
'placeholder' => 'सब',
],
],
'selection_indicator' => [
'selected_count' => '1 रिकॉर्ड चयनित।|:count रिकॉर्ड चयनित।',
'actions' => [
'select_all' => [
'label' => 'सभी :count चुने',
],
'deselect_all' => [
'label' => 'सभी अचयनित करे',
],
],
],
];
@@ -0,0 +1,232 @@
<?php
return [
'column_manager' => [
'heading' => 'Kolone',
],
'columns' => [
'actions' => [
'label' => 'Akcija|Akcije',
],
'text' => [
'actions' => [
'collapse_list' => 'Prikaži :count manje',
'expand_list' => 'Prikaži :count više',
],
'more_list_items' => 'i još :count',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Odaberi/poništi odabir svih stavki za skupne radnje.',
],
'bulk_select_record' => [
'label' => 'Odaberi/poništi odabir stavke :key za skupne radnje.',
],
'bulk_select_group' => [
'label' => 'Odaberi/poništi odabir grupe :title za skupne radnje.',
],
'search' => [
'label' => 'Pretraga',
'placeholder' => 'Pretraži',
'indicator' => 'Pretraži',
],
],
'summary' => [
'heading' => 'Sažetak',
'subheadings' => [
'all' => 'Sve :label',
'group' => ':group sažetak',
'page' => 'Ova stranica',
],
'summarizers' => [
'average' => [
'label' => 'Prosjek',
],
'count' => [
'label' => 'Broj',
],
'sum' => [
'label' => 'Zbroj',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Završi mijenjanje redoslijeda zapisa',
],
'enable_reordering' => [
'label' => 'Mijenjanje redoslijeda zapisa',
],
'filter' => [
'label' => 'Filter',
],
'group' => [
'label' => 'Grupa',
],
'open_bulk_actions' => [
'label' => 'Skupne radnje',
],
'column_manager' => [
'label' => 'Prikaži/sakrij stupce',
],
],
'empty' => [
'heading' => 'Nema :model',
'description' => 'Stvori :model kako bi započeo.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Primijeni filter',
],
'remove' => [
'label' => 'Ukloni filter',
],
'remove_all' => [
'label' => 'Ukloni sve filtere',
'tooltip' => 'Ukloni sve filtere',
],
'reset' => [
'label' => 'Poništi',
],
],
'heading' => 'Filteri',
'indicator' => 'Aktivni filteri',
'multi_select' => [
'placeholder' => 'Sve',
],
'select' => [
'placeholder' => 'Sve',
],
'trashed' => [
'label' => 'Obrisani zapisi',
'only_trashed' => 'Samo obrisani zapisi',
'with_trashed' => 'S obrisanih zapisa',
'without_trashed' => 'Bez obrisanih zapisa',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Grupiraj prema',
'placeholder' => 'Grupiraj prema',
],
'direction' => [
'label' => 'Smjer grupiranja',
'options' => [
'asc' => 'Uzlazno',
'desc' => 'Silazno',
],
],
],
],
'reorder_indicator' => 'Povuci i ispusti zapise u redoslijed.',
'selection_indicator' => [
'selected_count' => '1 odabrani zapis|:count odabranih zapisa',
'actions' => [
'select_all' => [
'label' => 'Odaberi svih :count',
],
'deselect_all' => [
'label' => 'Odznači sve',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Sortiraj prema',
],
'direction' => [
'label' => 'Smjer sortiranja',
'options' => [
'asc' => 'Uzlazno',
'desc' => 'Silazno',
],
],
],
],
];
@@ -0,0 +1,248 @@
<?php
return [
'column_manager' => [
'heading' => 'Oszlopok',
'actions' => [
'apply' => [
'label' => 'Alkalmazás',
],
],
],
'columns' => [
'actions' => [
'label' => 'Művelet|Műveletek',
],
'text' => [
'actions' => [
'collapse_list' => ':count elemmel kevesebb mutatása',
'expand_list' => ':count elemmel több mutatása',
],
'more_list_items' => 'és :count több',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Az összes elem kijelölése vagy a kijelölés megszüntetése csoportos műveletekhez.',
],
'bulk_select_record' => [
'label' => ':key elem kijelölése vagy a kijelölés megszüntetése csoportos műveletekhez.',
],
'bulk_select_group' => [
'label' => ':title csoport kijelölése vagy a kijelölés megszüntetése csoportos műveletekhez.',
],
'search' => [
'label' => 'Keresés',
'placeholder' => 'Keresés',
'indicator' => 'Keresés',
],
],
'summary' => [
'heading' => 'Összesítés',
'subheadings' => [
'all' => 'Összes :label',
'group' => ':group összesítése',
'page' => 'Ezen az oldalon',
],
'summarizers' => [
'average' => [
'label' => 'Átlag',
],
'count' => [
'label' => 'Darab',
],
'sum' => [
'label' => 'Összeg',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Átrendezés befejezése',
],
'enable_reordering' => [
'label' => 'Átrendezés',
],
'filter' => [
'label' => 'Szűrés',
],
'group' => [
'label' => 'Csoportosítás',
],
'open_bulk_actions' => [
'label' => 'Csoportos műveletek',
],
'column_manager' => [
'label' => 'Oszlopok láthatósága',
],
],
'empty' => [
'heading' => 'Nincs megjeleníthető elem',
'description' => 'Hozz létre egy újat a kezdéshez.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Szűrők alkalmazása',
],
'remove' => [
'label' => 'Szűrő megszüntetése',
],
'remove_all' => [
'label' => 'Az összes szűrő megszüntetése',
'tooltip' => 'Az összes szűrő megszüntetése',
],
'reset' => [
'label' => 'Visszaállítás',
],
],
'heading' => 'Szűrők',
'indicator' => 'Aktív szűrők',
'multi_select' => [
'placeholder' => 'Mind',
],
'select' => [
'placeholder' => 'Mind',
'relationship' => [
'empty_option_label' => 'Nincs',
],
],
'trashed' => [
'label' => 'Törölt elemek',
'only_trashed' => 'Csak a törölt elemek',
'with_trashed' => 'Törölt elemekkel együtt',
'without_trashed' => 'Törölt elemek nélkül',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Csoportosítás',
'placeholder' => 'Csoportosítás',
],
'direction' => [
'label' => 'Csoportosítás iránya',
'options' => [
'asc' => 'Növekvő',
'desc' => 'Csökkenő',
],
],
],
],
'reorder_indicator' => 'Kattints az elemekre és mozgasd őket az átrendezéshez.',
'selection_indicator' => [
'selected_count' => '1 elem kiválasztva|:count elem kiválasztva',
'actions' => [
'select_all' => [
'label' => 'Mind a(z) :count elem kijelölése',
],
'deselect_all' => [
'label' => 'Kijelölés megszüntetése',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Rendezés',
],
'direction' => [
'label' => 'Rendezési irány',
'options' => [
'asc' => 'Növekvő',
'desc' => 'Csökkenő',
],
],
],
],
'default_model_label' => 'objektum',
];
@@ -0,0 +1,259 @@
<?php
return [
'column_manager' => [
'heading' => 'Սյուներ',
'actions' => [
'apply' => [
'label' => 'Կիրառել սյուները',
],
'reset' => [
'label' => 'Վերականգնել',
],
],
],
'columns' => [
'actions' => [
'label' => 'Գործողություն|Գործողություններ',
],
'select' => [
'loading_message' => 'Բեռնում...',
'no_search_results_message' => 'Ոչ մի տարբերակ չի համապատասխանում ձեր որոնմանը։',
'placeholder' => 'Ընտրեք տարբերակ',
'searching_message' => 'Որոնում...',
'search_prompt' => 'Մուտքագրեք որոնման համար...',
],
'text' => [
'actions' => [
'collapse_list' => 'Ցույց տալ :count-ով քիչ',
'expand_list' => 'Ցույց տալ :count-ով ավելին',
],
'more_list_items' => 'և ևս :count',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Ընտրել/հեռացնել բոլոր տարրերը խմբային գործողությունների համար։',
],
'bulk_select_record' => [
'label' => 'Ընտրել/հեռացնել :key տարրը խմբային գործողությունների համար։',
],
'bulk_select_group' => [
'label' => 'Ընտրել/հեռացնել :title խումբը խմբային գործողությունների համար։',
],
'search' => [
'label' => 'Որոնում',
'placeholder' => 'Որոնում',
'indicator' => 'Որոնում',
],
],
'summary' => [
'heading' => 'Ամփոփում',
'subheadings' => [
'all' => 'Բոլոր :label',
'group' => ':group ամփոփում',
'page' => 'Այս էջը',
],
'summarizers' => [
'average' => [
'label' => 'Միջին',
],
'count' => [
'label' => 'Քանակ',
],
'sum' => [
'label' => 'Գումար',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Ավարտել գրառումների վերադասավորումը',
],
'enable_reordering' => [
'label' => 'Վերադասավորել գրառումները',
],
'filter' => [
'label' => 'Ֆիլտր',
],
'group' => [
'label' => 'Խումբ',
],
'open_bulk_actions' => [
'label' => 'Խմբային գործողություններ',
],
'column_manager' => [
'label' => 'Սյուների կառավարիչ',
],
],
'empty' => [
'heading' => 'Ոչ մի :model',
'description' => 'Սկսելու համար ստեղծեք :model։',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Կիրառել ֆիլտրերը',
],
'remove' => [
'label' => 'Հեռացնել ֆիլտրը',
],
'remove_all' => [
'label' => 'Հեռացնել բոլոր ֆիլտրերը',
'tooltip' => 'Հեռացնել բոլոր ֆիլտրերը',
],
'reset' => [
'label' => 'Վերականգնել',
],
],
'heading' => 'Ֆիլտրեր',
'indicator' => 'Ակտիվ ֆիլտրեր',
'multi_select' => [
'placeholder' => 'Բոլորը',
],
'select' => [
'placeholder' => 'Բոլորը',
'relationship' => [
'empty_option_label' => 'Չկա',
],
],
'trashed' => [
'label' => 'Ջնջված գրառումներ',
'only_trashed' => 'Միայն ջնջված գրառումները',
'with_trashed' => 'Ջնջվածներով',
'without_trashed' => 'Առանց ջնջվածների',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Խմբավորել ըստ',
],
'direction' => [
'label' => 'Խմբավորման ուղղություն',
'options' => [
'asc' => 'Աճող',
'desc' => 'Նվազող',
],
],
],
],
'reorder_indicator' => 'Քաշեք և գցեք գրառումները՝ դասավորելու համար։',
'selection_indicator' => [
'selected_count' => 'Ընտրված է 1 գրառում|Ընտրված է :count գրառում',
'actions' => [
'select_all' => [
'label' => 'Ընտրել բոլորը՝ :count',
],
'deselect_all' => [
'label' => 'Չընտրել բոլորն',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Դասավորել ըստ',
],
'direction' => [
'label' => 'Դասավորման ուղղություն',
'options' => [
'asc' => 'Աճող',
'desc' => 'Նվազող',
],
],
],
],
'default_model_label' => 'տվյալ',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'Kolom',
'actions' => [
'apply' => [
'label' => 'Terapkan kolom',
],
'reset' => [
'label' => 'Atur ulang',
],
],
],
'columns' => [
'actions' => [
'label' => 'Aksi|Aksi',
],
'select' => [
'loading_message' => 'Memuat...',
'no_search_results_message' => 'Tidak ada hasil yang sesuai dengan pencarian Anda.',
'placeholder' => 'Pilih salah satu opsi',
'searching_message' => 'Sedang mencari...',
'search_prompt' => 'Ketik untuk mencari...',
],
'text' => [
'actions' => [
'collapse_list' => 'Sembunyikan :count lainnya',
'expand_list' => 'Tampilkan :count lainnya',
],
'more_list_items' => 'dan :count lainnya',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Buat/batalkan pilihan semua item untuk tindakan massal.',
],
'bulk_select_record' => [
'label' => 'Buat/batalkan pilihan item :key untuk tindakan massal.',
],
'bulk_select_group' => [
'label' => 'Buat/batalkan pilihan grup :title untuk tindakan massal.',
],
'search' => [
'label' => 'Cari',
'placeholder' => 'Cari',
'indicator' => 'Pencarian',
],
],
'summary' => [
'heading' => 'Rangkuman',
'subheadings' => [
'all' => 'Semua :label',
'group' => 'Rangkuman :group',
'page' => 'Halaman ini',
],
'summarizers' => [
'average' => [
'label' => 'Rata-rata',
],
'count' => [
'label' => 'Jumlah',
],
'sum' => [
'label' => 'Total',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Selesaikan pengurutan ulang data',
],
'enable_reordering' => [
'label' => 'Urutkan ulang data',
],
'filter' => [
'label' => 'Filter',
],
'group' => [
'label' => 'Grup',
],
'open_bulk_actions' => [
'label' => 'Tindakan',
],
'column_manager' => [
'label' => 'Pilih kolom',
],
],
'empty' => [
'heading' => 'Tidak ada data yang ditemukan',
'description' => 'Buat :model untuk memulai.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Terapkan filter',
],
'remove' => [
'label' => 'Hapus filter',
],
'remove_all' => [
'label' => 'Hapus semua filter',
'tooltip' => 'Hapus semua filter',
],
'reset' => [
'label' => 'Atur ulang filter',
],
],
'heading' => 'Filter',
'indicator' => 'Filter aktif',
'multi_select' => [
'placeholder' => 'Semua',
],
'select' => [
'placeholder' => 'Semua',
'relationship' => [
'empty_option_label' => 'Tidak ada',
],
],
'trashed' => [
'label' => 'Data yang dihapus',
'only_trashed' => 'Hanya data yang dihapus',
'with_trashed' => 'Dengan data yang dihapus',
'without_trashed' => 'Tanpa data yang dihapus',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Kelompokkan berdasar',
],
'direction' => [
'label' => 'Urutan grup',
'options' => [
'asc' => 'Naik',
'desc' => 'Turun',
],
],
],
],
'reorder_indicator' => 'Seret dan lepaskan data ke dalam urutan.',
'selection_indicator' => [
'selected_count' => ':count data dipilih',
'actions' => [
'select_all' => [
'label' => 'Pilih semua (:count)',
],
'deselect_all' => [
'label' => 'Batalkan semua pilihan',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Urutkan menurut',
],
'direction' => [
'label' => 'Arah urutan',
'options' => [
'asc' => 'Naik',
'desc' => 'Turun',
],
],
],
],
'default_model_label' => 'data',
];
@@ -0,0 +1,252 @@
<?php
return [
'column_manager' => [
'heading' => 'Colonne',
'actions' => [
'apply' => [
'label' => 'Applica colonne',
],
'reset' => [
'label' => 'Reimposta',
],
],
],
'columns' => [
'actions' => [
'label' => 'Azione|Azioni',
],
'text' => [
'actions' => [
'collapse_list' => 'Mostra :count di meno',
'expand_list' => 'Mostra :count di più',
],
'more_list_items' => 'e altri :count',
],
'select' => [
'loading_message' => 'Caricamento...',
'no_search_results_message' => 'Nessuna opzione corrisponde alla tua ricerca.',
'placeholder' => "Seleziona un'opzione",
'searching_message' => 'Ricerca...',
'search_prompt' => 'Digita per cercare...',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Seleziona/Deseleziona tutti gli elementi per le azioni di massa.',
],
'bulk_select_record' => [
'label' => "Seleziona/Deseleziona l'elemento :key per le azioni di massa.",
],
'bulk_select_group' => [
'label' => 'Seleziona/deseleziona gruppo :title per azioni collettive.',
],
'search' => [
'label' => 'Cerca',
'placeholder' => 'Cerca',
'indicator' => 'Cerca',
],
],
'summary' => [
'heading' => 'Riepilogo',
'subheadings' => [
'all' => 'Tutti gli :label',
'group' => 'Riepilogo :group',
'page' => 'Questa pagina',
],
'summarizers' => [
'average' => [
'label' => 'Media',
],
'count' => [
'label' => 'Conteggio',
],
'sum' => [
'label' => 'Somma',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Termina riordino record',
],
'enable_reordering' => [
'label' => 'Riordina record',
],
'filter' => [
'label' => 'Filtro',
],
'group' => [
'label' => 'Gruppo',
],
'open_bulk_actions' => [
'label' => 'Azioni',
],
'column_manager' => [
'label' => 'Mostra/Nascondi colonne',
],
],
'empty' => [
'heading' => 'Nessun risultato',
'description' => 'Crea un :model per iniziare.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Applica filtri',
],
'remove' => [
'label' => 'Rimuovi filtro',
],
'remove_all' => [
'label' => 'Rimuovi tutti i filtri',
'tooltip' => 'Rimuovi tutti i filtri',
],
'reset' => [
'label' => 'Reimposta',
],
],
'heading' => 'Filtri',
'indicator' => 'Filtri attivi',
'multi_select' => [
'placeholder' => 'Tutti',
],
'select' => [
'placeholder' => 'Tutti',
'relationship' => [
'empty_option_label' => 'Nessuno',
],
],
'trashed' => [
'label' => 'Record eliminati',
'only_trashed' => 'Solo record eliminati',
'with_trashed' => 'Con record eliminati',
'without_trashed' => 'Senza record eliminati',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Raggruppa per',
],
'direction' => [
'label' => 'Ordine',
'options' => [
'asc' => 'Crescente',
'desc' => 'Decrescente',
],
],
],
],
'reorder_indicator' => 'Trascina e rilascia i record in ordine.',
'selection_indicator' => [
'selected_count' => '1 record selezionato|:count record selezionati',
'actions' => [
'select_all' => [
'label' => 'Seleziona tutti :count',
],
'deselect_all' => [
'label' => 'Deseleziona tutti',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Ordina per',
],
'direction' => [
'label' => 'Ordine',
'options' => [
'asc' => 'Crescente',
'desc' => 'Decrescente',
],
],
],
],
'default_model_label' => 'record',
];
@@ -0,0 +1,264 @@
<?php
return [
'column_manager' => [
'heading' => 'カラム',
'actions' => [
'apply' => [
'label' => 'カラムに適用',
],
'reset' => [
'label' => 'リセット',
],
],
],
'columns' => [
'actions' => [
'label' => 'アクション',
],
'select' => [
'loading_message' => '読み込み中...',
'no_search_results_message' => '条件に一致するオプションがありません。',
'placeholder' => '選択してください',
'searching_message' => '検索中...',
'search_prompt' => '検索ワードを入力してください...',
],
'text' => [
'actions' => [
'collapse_list' => ':count件非表示',
'expand_list' => ':count件表示',
],
'more_list_items' => 'あと:count件あります',
],
],
'fields' => [
'bulk_select_page' => [
'label' => '一括操作の全項目の選択/解除。',
],
'bulk_select_record' => [
'label' => '一括操作のキー:keyの選択/解除。',
],
'bulk_select_group' => [
'label' => '一括操作のグループ:keyの選択/解除。',
],
'search' => [
'label' => '検索',
'placeholder' => '検索',
'indicator' => '検索',
],
],
'summary' => [
'heading' => 'サマリー',
'subheadings' => [
'all' => 'すべての:label',
'group' => ':groupのサマリー',
'page' => 'このページ',
],
'summarizers' => [
'average' => [
'label' => '平均',
],
'count' => [
'label' => 'カウント',
],
'sum' => [
'label' => '合計',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'レコードの並び替えを終了',
],
'enable_reordering' => [
'label' => 'レコードの並び替え',
],
'filter' => [
'label' => 'フィルタ',
],
'group' => [
'label' => 'グループ',
],
'open_bulk_actions' => [
'label' => '操作を開く',
],
'column_manager' => [
'label' => '列を切り替える',
],
],
'empty' => [
'heading' => ':modelが見つかりません',
'description' => ':modelを作成してください。',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'フィルタを適用',
],
'remove' => [
'label' => 'フィルタを解除',
],
'remove_all' => [
'label' => 'すべてのフィルタを解除',
'tooltip' => 'すべてのフィルタを解除',
],
'reset' => [
'label' => 'リセット',
],
],
'heading' => 'フィルタ',
'indicator' => '有効なフィルタ',
'multi_select' => [
'placeholder' => '全件',
],
'select' => [
'placeholder' => '全件',
'relationship' => [
'empty_option_label' => 'なし',
],
],
'trashed' => [
'label' => '削除済みレコード',
'only_trashed' => '削除済みレコードのみ',
'with_trashed' => '削除済みレコード含む',
'without_trashed' => '削除済みレコードを除く',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'グループ化',
],
'direction' => [
'label' => 'グループ順の方向',
'options' => [
'asc' => '昇順',
'desc' => '降順',
],
],
],
],
'reorder_indicator' => 'ドラッグ&ドロップでレコードを並び替え。',
'selection_indicator' => [
'selected_count' => '1件選択済み|:count件選択済み',
'actions' => [
'select_all' => [
'label' => ':count件すべて選択',
],
'deselect_all' => [
'label' => '全選択解除',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => '並び順',
],
'direction' => [
'label' => '並び変えの方向',
'options' => [
'asc' => '昇順',
'desc' => '降順',
],
],
],
],
'default_model_label' => 'レコード',
];
@@ -0,0 +1,228 @@
<?php
return [
'column_manager' => [
'heading' => 'სვეტები',
],
'columns' => [
'text' => [
'actions' => [
'collapse_list' => 'აჩვენე :count ნაკლები',
'expand_list' => 'აჩვენე :count მეტი',
],
'more_list_items' => 'და კიდევ :count',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'მონიშნეთ/გააუქმეთ ყველა ელემენტი საერთო ქმედებებისთვის.',
],
'bulk_select_record' => [
'label' => 'მონიშნეთ/გააუქმეთ ელემენტი :key საერთო ქმედებებისთვის.',
],
'bulk_select_group' => [
'label' => 'მონიშნეთ/გააუქმეთ ჯგუფი :title საერთო ქმედებებისთვის.',
],
'search' => [
'label' => 'ძებნა',
'placeholder' => 'ძებნა',
'indicator' => 'ძებნა',
],
],
'summary' => [
'heading' => 'შეჯამება',
'subheadings' => [
'all' => 'ყველა :label',
'group' => ':group შეჯამება',
'page' => 'ეს გვერდი',
],
'summarizers' => [
'average' => [
'label' => 'საშუალო',
],
'count' => [
'label' => 'რაოდენობა',
],
'sum' => [
'label' => 'ჯამი',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'ჩანაწერების გადალაგების დასრულება',
],
'enable_reordering' => [
'label' => 'ჩანაწერების გადალაგება',
],
'filter' => [
'label' => 'ფილტრი',
],
'group' => [
'label' => 'ჯგუფი',
],
'open_bulk_actions' => [
'label' => 'საერთო ქმედებები',
],
'column_manager' => [
'label' => 'სვეტების გადართვა',
],
],
'empty' => [
'heading' => 'არაა :model',
'description' => 'შექმენით :model რომ დაიწყოთ.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'ფილტრების გამოყენება',
],
'remove' => [
'label' => 'ფილტრის მოხსნა',
],
'remove_all' => [
'label' => 'ყველა ფილტრის მოხსნა',
'tooltip' => 'ყველა ფილტრის მოხსნა',
],
'reset' => [
'label' => 'გასუფთავება',
],
],
'heading' => 'ფილტრები',
'indicator' => 'აქტიური ფილტრები',
'multi_select' => [
'placeholder' => 'ყველა',
],
'select' => [
'placeholder' => 'ყველა',
],
'trashed' => [
'label' => 'წაშლილი ჩანაწერები',
'only_trashed' => 'მხოლოდ წაშლილი ჩანაწერები',
'with_trashed' => 'წაშლილ ჩანაწერებთან ერთად',
'without_trashed' => 'წაშლილი ჩანაწერების გარეშე',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'დაჯგუფებულია',
'placeholder' => 'დაჯგუფებულია',
],
'direction' => [
'label' => 'ჯგუფის მიმართულება',
'options' => [
'asc' => 'ზრდადი',
'desc' => 'კლებადი',
],
],
],
],
'reorder_indicator' => 'ჩანაწერების გადათრევა და ჩამოშვება რიგში.',
'selection_indicator' => [
'selected_count' => '1 ჩანაწერი მონიშნულია|:count ჩანაწერები მონიშნულია',
'actions' => [
'select_all' => [
'label' => 'მონიშნეთ ყველა :count',
],
'deselect_all' => [
'label' => 'ყველას მონიშვნის გაუქმება',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'სორტირება',
],
'direction' => [
'label' => 'სორტირება',
'options' => [
'asc' => 'ზრდადობით',
'desc' => 'კლებადობით',
],
],
],
],
];
@@ -0,0 +1,232 @@
<?php
return [
'column_manager' => [
'heading' => 'ជួរឈរ',
],
'columns' => [
'actions' => [
'label' => 'សកម្មភាព|សកម្មភាព',
],
'text' => [
'actions' => [
'collapse_list' => 'បង្ហាញ :count តិច',
'expand_list' => 'បង្ហាញ :count ច្រើនទៀត',
],
'more_list_items' => 'និង :count ច្រើនទៀត',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'ជ្រើសរើស/មិនជ្រើសរើសធាតុទាំងអស់សម្រាប់សកម្មភាពភាគច្រើន.',
],
'bulk_select_record' => [
'label' => 'ជ្រើសរើស/មិនជ្រើសរើសធាតុ :key សម្រាប់សកម្មភាពភាគច្រើន.',
],
'bulk_select_group' => [
'label' => 'ជ្រើសរើស/មិនជ្រើសរើសក្រុម :title សម្រាប់សកម្មភាពភាគច្រើន.',
],
'search' => [
'label' => 'ស្វែងរក',
'placeholder' => 'ស្វែងរក',
'indicator' => 'ស្វែងរក',
],
],
'summary' => [
'heading' => 'សង្ខេប',
'subheadings' => [
'all' => 'ទាំងអស់ :label',
'group' => ':group សង្ខេប',
'page' => 'ទំព័រនេះ',
],
'summarizers' => [
'average' => [
'label' => 'មធ្យម',
],
'count' => [
'label' => 'រាប់',
],
'sum' => [
'label' => 'បូក',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'បញ្ចប់​ការ​រៀបចំ​កំណត់ត្រា​ឡើងវិញ',
],
'enable_reordering' => [
'label' => 'តម្រៀបកំណត់ត្រាឡើងវិញ',
],
'filter' => [
'label' => 'តម្រង',
],
'group' => [
'label' => 'ក្រុម',
],
'open_bulk_actions' => [
'label' => 'សកម្មភាពភាគច្រើន',
],
'column_manager' => [
'label' => 'បិទ/បើកជួរឈរ',
],
],
'empty' => [
'heading' => 'គ្មាន​ :model',
'description' => 'បង្កើត​ :model មួយដើម្បីចាប់ផ្តើម។',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'អនុវត្តតម្រង',
],
'remove' => [
'label' => 'យកតម្រងចេញ',
],
'remove_all' => [
'label' => 'លុបចោលតម្រងទាំងអស់',
'tooltip' => 'លុបចោលតម្រងទាំងអស់',
],
'reset' => [
'label' => 'កំណត់ឡើងវិញ',
],
],
'heading' => 'តម្រង',
'indicator' => 'តម្រងសកម្ម',
'multi_select' => [
'placeholder' => 'ទាំងអស់',
],
'select' => [
'placeholder' => 'ទាំងអស់',
],
'trashed' => [
'label' => 'កំណត់ត្រាដែលបានលុប',
'only_trashed' => 'មានតែកំណត់ត្រាដែលបានលុបប៉ុណ្ណោះ។',
'with_trashed' => 'ជាមួយនឹងកំណត់ត្រាដែលបានលុប',
'without_trashed' => 'ដោយគ្មានកំណត់ត្រាដែលបានលុប',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'ដាក់ជាក្រុមដោយ',
'placeholder' => 'ដាក់ជាក្រុមដោយ',
],
'direction' => [
'label' => 'ទិសដៅក្រុម',
'options' => [
'asc' => 'ឡើង',
'desc' => 'ចុះ',
],
],
],
],
'reorder_indicator' => 'អូស និងទម្លាក់កំណត់ត្រាតាមលំដាប់លំដោយ.',
'selection_indicator' => [
'selected_count' => 'បានជ្រើសរើស 1 កំណត់ត្រា|:count រាប់កំណត់ត្រា បានជ្រើសរើស',
'actions' => [
'select_all' => [
'label' => 'ជ្រើសរើសទាំងអស់៖ :count',
],
'deselect_all' => [
'label' => 'ដកការជ្រើសរើសទាំងអស់',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'តម្រៀបតាម',
],
'direction' => [
'label' => 'តម្រៀបទិសដៅ',
'options' => [
'asc' => 'ឡើង',
'desc' => 'ចុះ',
],
],
],
],
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => '열',
'actions' => [
'apply' => [
'label' => '열 적용',
],
'reset' => [
'label' => '초기화',
],
],
],
'columns' => [
'actions' => [
'label' => '작업|작업들',
],
'select' => [
'loading_message' => '로드 중...',
'no_search_results_message' => '검색 결과가 없습니다.',
'placeholder' => '옵션을 선택하세요',
'searching_message' => '검색 중...',
'search_prompt' => '검색어를 입력하세요...',
],
'text' => [
'actions' => [
'collapse_list' => ':count 개 더 접기',
'expand_list' => ':count 개 더 펼치기',
],
'more_list_items' => ':count 항목이 더 있습니다',
],
],
'fields' => [
'bulk_select_page' => [
'label' => '일괄 작업을 위해 모든 항목을 선택/선택 취소합니다.',
],
'bulk_select_record' => [
'label' => '일괄 작업을 위해 :key 항목을 선택/선택 취소합니다.',
],
'bulk_select_group' => [
'label' => '일괄 작업의 :title 그룹을 선택/선택 취소합니다.',
],
'search' => [
'label' => '검색',
'placeholder' => '검색',
'indicator' => '검색',
],
],
'summary' => [
'heading' => '요약',
'subheadings' => [
'all' => '모든 :label',
'group' => ':group 요약',
'page' => '이 페이지',
],
'summarizers' => [
'average' => [
'label' => '평균',
],
'count' => [
'label' => '수량',
],
'sum' => [
'label' => '합계',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => '순서 변경 완료',
],
'enable_reordering' => [
'label' => '항목 순서 변경',
],
'filter' => [
'label' => '필터',
],
'group' => [
'label' => '그룹',
],
'open_bulk_actions' => [
'label' => '일괄 작업',
],
'column_manager' => [
'label' => '열 전환',
],
],
'empty' => [
'heading' => ':model 없음',
'description' => ':model 을(를) 만들어 시작하세요.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => '필터 적용',
],
'remove' => [
'label' => '필터 삭제',
],
'remove_all' => [
'label' => '모든 필터 삭제',
'tooltip' => '모든 필터 삭제',
],
'reset' => [
'label' => '초기화',
],
],
'heading' => '필터',
'indicator' => '활성화된 필터',
'multi_select' => [
'placeholder' => '전체',
],
'select' => [
'placeholder' => '전체',
'relationship' => [
'empty_option_label' => '없음',
],
],
'trashed' => [
'label' => '삭제된 항목',
'only_trashed' => '삭제된 항목만',
'with_trashed' => '삭제된 항목 포함',
'without_trashed' => '삭제된 항목 제외',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => '그룹 기준',
],
'direction' => [
'label' => '그룹 순서',
'options' => [
'asc' => '오름차순',
'desc' => '내림차순',
],
],
],
],
'reorder_indicator' => '항목을 순서대로 끌어다 놓습니다.',
'selection_indicator' => [
'selected_count' => ':count 항목 선택됨',
'actions' => [
'select_all' => [
'label' => ':count 항목 모두 선택',
],
'deselect_all' => [
'label' => '모두 선택 해제',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => '정렬 기준',
],
'direction' => [
'label' => '정렬 순서',
'options' => [
'asc' => '오름차순',
'desc' => '내림차순',
],
],
],
],
'default_model_label' => '항목',
];
@@ -0,0 +1,213 @@
<?php
return [
'column_manager' => [
'heading' => 'ستوونەکان',
],
'columns' => [
'text' => [
'more_list_items' => 'وە :count ی زیاتر',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'دیاریکردن/لابردنی دیاریکردنەکان بۆ هەموو تۆمارەکان بۆ کۆمەڵەی کردارەکان.',
],
'bulk_select_record' => [
'label' => 'دیاریکردن/لابردنی دیاریکراوەکان بۆ :key بۆ کۆمەڵەی کردارەکان.',
],
'search' => [
'label' => 'گەڕان',
'placeholder' => 'گەڕان',
'indicator' => 'گەڕان',
],
],
'summary' => [
'heading' => 'پوختە',
'subheadings' => [
'all' => 'هەموو :label',
'group' => ':group پوختە',
'page' => 'ئەم پەڕەیە',
],
'summarizers' => [
'average' => [
'label' => 'تێکڕا',
],
'count' => [
'label' => 'ژماردەکان',
],
'sum' => [
'label' => 'کۆی گشتی',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'تەواوکردنی ڕێکخستنی تۆمارەکان',
],
'enable_reordering' => [
'label' => 'ڕێکخستنی تۆمارەکان',
],
'filter' => [
'label' => 'فلتەر',
],
'group' => [
'label' => 'کۆمەڵ',
],
'open_bulk_actions' => [
'label' => 'کۆمەڵی کردارەکان',
],
'column_manager' => [
'label' => 'پشاندان/لابردنی ستوونەکان',
],
],
'empty' => [
'heading' => 'هیچ تۆمارێکی :model بوونی نییە.',
'description' => 'تۆمارێکی :model دروس بکە بۆ دەستپێکردن.',
],
'filters' => [
'actions' => [
'remove' => [
'label' => 'سڕینەوەی فلتەر',
],
'remove_all' => [
'label' => 'سڕینەوەی هەموو فلتەرەکان',
'tooltip' => 'سڕینەوەی هەموو فلتەرەکان',
],
'reset' => [
'label' => 'دۆخی سەرەتا',
],
],
'heading' => 'فلتەرەکان',
'indicator' => 'فلتەرە چالاککراوەکان',
'multi_select' => [
'placeholder' => 'هەموو',
],
'select' => [
'placeholder' => 'هەموو',
],
'trashed' => [
'label' => 'تۆمارە سڕدراوەکان',
'only_trashed' => 'تەنها تۆمارە سڕدراوەکان',
'with_trashed' => 'لەگەل تۆمارە سڕدراوەکان',
'without_trashed' => 'بەبێ تۆمارە سڕدراوەکان',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'کۆمەڵ کردن بە',
'placeholder' => 'کۆمەڵ کردن بە',
],
'direction' => [
'label' => 'ئاڕاستەی کۆمەڵ کردن',
'options' => [
'asc' => 'کەم بۆ زۆر',
'desc' => 'زۆر بۆ کەم',
],
],
],
],
'reorder_indicator' => 'تۆمارەکان هەڵبگرە و ڕیزیان بکە.',
'selection_indicator' => [
'selected_count' => '١ ڕیز دیاریکراوە|:count ڕیز دیاریکراوە',
'actions' => [
'select_all' => [
'label' => 'هەڵبژاردنی هەموو :count',
],
'deselect_all' => [
'label' => 'هەڵنەبژاردنی هەموو',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'کۆمەڵکردن بە',
],
'direction' => [
'label' => 'ئاڕاستەی کۆمەڵ کردن',
'options' => [
'asc' => 'کەم بۆ زۆر',
'desc' => 'زۆر بۆ کەم',
],
],
],
],
];
@@ -0,0 +1,227 @@
<?php
return [
'column_manager' => [
'heading' => 'Stulpeliai',
],
'columns' => [
'text' => [
'actions' => [
'collapse_list' => 'Slėpti :count',
'expand_list' => 'Rodyti dar :count',
],
'more_list_items' => 'ir dar :count',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Pažymėti/atžymėti visus įrašus masiniam veiksmui.',
],
'bulk_select_record' => [
'label' => 'Pažymėti/atžymėti įrašą :key masiniam veiksmui.',
],
'bulk_select_group' => [
'label' => 'Pažymėti/atžymėti grupę :title masiniam veiksmui.',
],
'search' => [
'label' => 'Paieška',
'placeholder' => 'Paieška',
'indicator' => 'Paieška',
],
],
'summary' => [
'heading' => 'Santrauka',
'subheadings' => [
'all' => 'Viso :label',
'group' => ':group santrauka',
'page' => 'Šis puslapis',
],
'summarizers' => [
'average' => [
'label' => 'Vidurkis',
],
'count' => [
'label' => 'Viso',
],
'sum' => [
'label' => 'Suma',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Pabaik pertvarkyti įrašus',
],
'enable_reordering' => [
'label' => 'Pertvarkyti įrašus',
],
'filter' => [
'label' => 'Filtras',
],
'group' => [
'label' => 'Grupė',
],
'open_bulk_actions' => [
'label' => 'Atidaryti veiksmus',
],
'column_manager' => [
'label' => 'Perjungti stulpelius',
],
],
'empty' => [
'heading' => 'Nerasta įrašų',
'description' => 'Norėdami pradėti, sukurkite :model.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Taikyti filtrus',
],
'remove' => [
'label' => 'Pašalinti filtrą',
],
'remove_all' => [
'label' => 'Pašalinti visus filtrus',
'tooltip' => 'Pašalinti visus filtrus',
],
'reset' => [
'label' => 'Nustatyti filtrus iš naujo',
],
],
'heading' => 'Filtrai',
'indicator' => 'Aktyvūs filtrai',
'multi_select' => [
'placeholder' => 'Visi',
],
'select' => [
'placeholder' => 'Visi',
],
'trashed' => [
'label' => 'Ištrinti įrašai',
'only_trashed' => 'Tik ištrinti įrašai',
'with_trashed' => 'Su ištrintais įrašais',
'without_trashed' => 'Be ištrintų įrašų',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Grupuoti pagal',
'placeholder' => 'Grupuoti pagal',
],
'direction' => [
'label' => 'Grupės kryptis',
'options' => [
'asc' => 'Didėjančia tvarka',
'desc' => 'Mažėjančia tvarka',
],
],
],
],
'reorder_indicator' => 'Vilkite ir paleiskite įrašų rikiavimui.',
'selection_indicator' => [
'selected_count' => '1 įrašas pasirinktas|:count įrašai pasirinkti',
'actions' => [
'select_all' => [
'label' => 'Pažymėti visus :count',
],
'deselect_all' => [
'label' => 'Atžymėti visus',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Rūšiuoti pagal',
],
'direction' => [
'label' => 'Rūšiavimo kryptis',
'options' => [
'asc' => 'Didėjimo tvarka',
'desc' => 'Mažėjimo tvarka',
],
],
],
],
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'Columns',
'actions' => [
'apply' => [
'label' => 'Apply columns',
],
'reset' => [
'label' => 'Tihṭhatna',
],
],
],
'columns' => [
'actions' => [
'label' => 'Thiltihna|Thiltihnate',
],
'select' => [
'loading_message' => 'Loading...',
'no_search_results_message' => 'I search hi a awmlo.',
'placeholder' => 'I duh thlang rawh...',
'searching_message' => 'Zawn mek ani...',
'search_prompt' => 'Zawng turin thil chhu rawh...',
],
'text' => [
'actions' => [
'collapse_list' => 'Show :count less',
'expand_list' => 'Show :count more',
],
'more_list_items' => 'and :count more',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Select/deselect all items for bulk actions.',
],
'bulk_select_record' => [
'label' => 'Select/deselect item :key for bulk actions.',
],
'bulk_select_group' => [
'label' => 'Select/deselect group :title for bulk actions.',
],
'search' => [
'label' => 'Zawnna',
'placeholder' => 'Zawnna',
'indicator' => 'Zawnna',
],
],
'summary' => [
'heading' => 'Khai khâwmna',
'subheadings' => [
'all' => ':Label a vaiin',
'group' => ':group khai khâwm',
'page' => 'Hemi phêkah',
],
'summarizers' => [
'average' => [
'label' => 'Chawhrualin',
],
'count' => [
'label' => 'Count',
],
'sum' => [
'label' => 'Belh khâwm',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Records awmna thlak a zo',
],
'enable_reordering' => [
'label' => 'Records awmna thlak',
],
'filter' => [
'label' => 'Thlit fîmna',
],
'group' => [
'label' => 'Group',
],
'open_bulk_actions' => [
'label' => 'Tamtak tihna',
],
'column_manager' => [
'label' => 'Column manager',
],
],
'empty' => [
'heading' => ':Model an awm lo',
'description' => 'A bultan nan :model siam rawh.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Thli fîm rawh',
],
'remove' => [
'label' => 'Thlit fîm hlihna',
],
'remove_all' => [
'label' => 'Thlit fîm ho hlihna',
'tooltip' => 'Thlit fîm ho hlihna',
],
'reset' => [
'label' => 'Tihṭhatna',
],
],
'heading' => 'Thlit fîmna',
'indicator' => 'Thlit fîm mek',
'multi_select' => [
'placeholder' => 'A vaiin',
],
'select' => [
'placeholder' => 'A vaiin',
'relationship' => [
'empty_option_label' => 'Awmlo',
],
],
'trashed' => [
'label' => 'Thai bo chhinchhiahna',
'only_trashed' => 'Thai bo tawh chiah',
'with_trashed' => 'Thai bo tawh telin',
'without_trashed' => 'Thai bo tello in',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Group by',
],
'direction' => [
'label' => 'Group direction',
'options' => [
'asc' => 'Hmasa',
'desc' => 'Hnuhnung',
],
],
],
],
'reorder_indicator' => 'Drag and drop the records into order.',
'selection_indicator' => [
'selected_count' => 'Record 1 select ani|Records :count select ani',
'actions' => [
'select_all' => [
'label' => 'Avaia :count thlanna',
],
'deselect_all' => [
'label' => 'Thlan sa paih na',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Thliarna',
],
'direction' => [
'label' => 'Thliarna lam',
'options' => [
'asc' => 'Hmasa',
'desc' => 'Hnuhnung',
],
],
],
],
'default_model_label' => 'record',
];
@@ -0,0 +1,217 @@
<?php
return [
'column_manager' => [
'heading' => 'Kolonnas',
],
'columns' => [
'text' => [
'more_list_items' => 'un :count vēl',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Atlasīt/noņemt atlasi no visiem ierakstiem, lai veiktu lielapjoma darbības.',
],
'bulk_select_record' => [
'label' => 'Atlasīt/noņemt atlasi no ierksta :key, lai veiktu lielapjoma darbības.',
],
'bulk_select_group' => [
'label' => 'Atlasīt/noņemt atlasi no grupas :title, lai veiktu lielapjoma darbības.',
],
'search' => [
'label' => 'Meklēt',
'placeholder' => 'Meklēt',
'indicator' => 'Meklēt',
],
],
'summary' => [
'heading' => 'Kopsavilkums',
'subheadings' => [
'all' => 'Visi :label',
'group' => ':group kopsavilkums',
'page' => 'Šī lapa',
],
'summarizers' => [
'average' => [
'label' => 'Vidēji',
],
'count' => [
'label' => 'Skaits',
],
'sum' => [
'label' => 'Summa',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Pabeigt ierakstu kārtošanu',
],
'enable_reordering' => [
'label' => 'Kārtot ierakstus',
],
'filter' => [
'label' => 'Filtrēt',
],
'group' => [
'label' => 'Grupēt',
],
'open_bulk_actions' => [
'label' => 'Lielapjoma darbības',
],
'column_manager' => [
'label' => 'Izvēlēties kolonnas',
],
],
'empty' => [
'heading' => 'Nav atrasts neviens ieraksts',
'description' => 'Izveidot :model, lai sāktu.',
],
'filters' => [
'actions' => [
'remove' => [
'label' => 'Noņemt filtru',
],
'remove_all' => [
'label' => 'Noņemt visus filtrus',
'tooltip' => 'Noņemt visus filtrus',
],
'reset' => [
'label' => 'Atiestatīt filtrus',
],
],
'heading' => 'Filtri',
'indicator' => 'Aktīvie filtri',
'multi_select' => [
'placeholder' => 'Visi',
],
'select' => [
'placeholder' => 'Visi',
],
'trashed' => [
'label' => 'Dzēstie ieraksti',
'only_trashed' => 'Tikai dzēstie ieraksti',
'with_trashed' => 'Kopā ar dzēstajiem ierakstiem',
'without_trashed' => 'Bez dzēstajiem ierakstiem',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Grupēt pēc',
'placeholder' => 'Grupēt pēc',
],
'direction' => [
'label' => 'Grupēšanas virziens',
'options' => [
'asc' => 'Augošs',
'desc' => 'Dilstošs',
],
],
],
],
'reorder_indicator' => 'Velciet un nometiet ierakstus secībā.',
'selection_indicator' => [
'selected_count' => 'Izvēlēts 1 ieraksts|:count ieraksti izvēlēti',
'actions' => [
'select_all' => [
'label' => 'Atlasīt visus :count',
],
'deselect_all' => [
'label' => 'Noņemt atlasi visiem',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Kārtot pēc',
],
'direction' => [
'label' => 'Kārtošanas virziens',
'options' => [
'asc' => 'Augošs',
'desc' => 'Dilstošs',
],
],
],
],
];
@@ -0,0 +1,228 @@
<?php
return [
'column_manager' => [
'heading' => 'Баганууд',
],
'columns' => [
'text' => [
'actions' => [
'collapse_list' => 'Харуулах :count бага',
'expand_list' => 'Харуулах :count илүү',
],
'more_list_items' => 'ба :count илүү',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Олонг сонгох/Цуцлах.',
],
'bulk_select_record' => [
'label' => 'Олонг сонгох/Цуцлах :key.',
],
'bulk_select_group' => [
'label' => 'Сонгох/цуцлах бүлэг :title багц үйлдэлд.',
],
'search' => [
'label' => 'Хайх',
'placeholder' => 'Хайх',
'indicator' => 'Хайх',
],
],
'summary' => [
'heading' => 'Нийлбэр',
'subheadings' => [
'all' => 'Бүгд :label',
'group' => ':group нийлбэр',
'page' => 'Энэ хуудас',
],
'summarizers' => [
'average' => [
'label' => 'Дундаж',
],
'count' => [
'label' => 'Тоо',
],
'sum' => [
'label' => 'Нийлбэр',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Эрэмбэлэлтийг дуусгах',
],
'enable_reordering' => [
'label' => 'Мөрүүдийг эрэмбэлэх',
],
'filter' => [
'label' => 'Шүүлтүүр',
],
'group' => [
'label' => 'Бүлэг',
],
'open_bulk_actions' => [
'label' => 'Багц үйлдэл',
],
'column_manager' => [
'label' => 'Баганыг нээх/хаах',
],
],
'empty' => [
'heading' => ':model хоосон',
'description' => 'Шинэ :model мэдээлэл үүсгэх.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Шүүлтийг батлах',
],
'remove' => [
'label' => 'Цэвэрлэх',
],
'remove_all' => [
'label' => 'Бүгдийг цэвэрлэх',
'tooltip' => 'Бүгдийг цэвэрлэх',
],
'reset' => [
'label' => 'Филтерийг болиулах',
],
],
'heading' => 'Шүүлтүүрүүд',
'indicator' => 'Филтерийг идэвхижүүлэх',
'multi_select' => [
'placeholder' => 'Бүгд',
],
'select' => [
'placeholder' => 'Бүгд',
],
'trashed' => [
'label' => 'Хогийн сав',
'only_trashed' => 'Зөвхөн устгасанг',
'with_trashed' => 'Аль алиныг',
'without_trashed' => 'Хэвийн',
],
],
'reorder_indicator' => 'Чирж эрэмбэлэх.',
'selection_indicator' => [
'selected_count' => '1 бичлэг сонгогдов|:count -г сонгов',
'actions' => [
'select_all' => [
'label' => 'Бүгдийг сонго :count',
],
'deselect_all' => [
'label' => 'Бүгдийг эс сонго',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Эрэмбэлэх',
],
'direction' => [
'label' => 'Эрэмбэлэх',
'options' => [
'asc' => 'Өсөх',
'desc' => 'Буурах',
],
],
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Бүлэглэх',
'placeholder' => 'Бүлэглэх',
],
'direction' => [
'label' => 'Бүлгийн чиглэл',
'options' => [
'asc' => 'Өсөх',
'desc' => 'Буурах',
],
],
],
],
];
@@ -0,0 +1,237 @@
<?php
return [
'column_manager' => [
'heading' => 'Kolum',
],
'columns' => [
'actions' => [
'label' => 'Tindakan|Tindakan',
],
'text' => [
'actions' => [
'collapse_list' => 'Tunjukkan kurang :count',
'expand_list' => 'Tunjukkan :count lagi',
],
'more_list_items' => 'dan :count lagi',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Pilih/nyahpilih semua item untuk tindakan pukal.',
],
'bulk_select_record' => [
'label' => 'Pilih/nyahpilih item :key untuk tindakan pukal.',
],
'bulk_select_group' => [
'label' => 'Pilih/nyahpilih kumpulan :title untuk tindakan pukal.',
],
'search' => [
'label' => 'Cari',
'placeholder' => 'Carian',
'indicator' => 'Carian',
],
],
'summary' => [
'heading' => 'Ringkasan',
'subheadings' => [
'all' => 'Semua :label',
'group' => ':group ringkasan',
'page' => 'Muka surat ini',
],
'summarizers' => [
'average' => [
'label' => 'Purata',
],
'count' => [
'label' => 'Bilangan',
],
'sum' => [
'label' => 'Jumlah',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Selesai menyusun semula rekod',
],
'enable_reordering' => [
'label' => 'Menyusun semula rekod',
],
'filter' => [
'label' => 'Tapisan',
],
'group' => [
'label' => 'Kumpulan',
],
'open_bulk_actions' => [
'label' => 'Tindakan terbuka',
],
'column_manager' => [
'label' => 'Togol lajur',
],
],
'empty' => [
'heading' => 'Tiada rekod dijumpai',
'description' => 'Cipta :model untuk bermula.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Gunakan tapisan',
],
'remove' => [
'label' => 'Buang tapisan',
],
'remove_all' => [
'label' => 'Buang semua tapisan',
'tooltip' => 'Buang semua tapisan',
],
'reset' => [
'label' => 'Tetapkan semula tapisan',
],
],
'heading' => 'Tapisan',
'indicator' => 'Tapisan aktif',
'multi_select' => [
'placeholder' => 'Semua',
],
'select' => [
'placeholder' => 'Semua',
'relationship' => [
'empty_option_label' => 'Tiada',
],
],
'trashed' => [
'label' => 'Rekod telah dipadamkan',
'only_trashed' => 'Hanya rekod yang dipadamkan',
'with_trashed' => 'Dengan rekod yang dipadam',
'without_trashed' => 'Tanpa rekod yang dipadam',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Kumpulan mengikut',
'placeholder' => 'Kumpulan mengikut',
],
'direction' => [
'label' => 'Arah kumpulan',
'options' => [
'asc' => 'Menaik',
'desc' => 'Menurun',
],
],
],
],
'reorder_indicator' => 'Seret dan lepaskan rekod mengikut susunan.',
'selection_indicator' => [
'selected_count' => '{1} 1 rekod dipilih|[2,*] :count rekod yang dipilih',
'actions' => [
'select_all' => [
'label' => 'Pilih semua :count',
],
'deselect_all' => [
'label' => 'Nyahpilih semua',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Disusun mengikut',
],
'direction' => [
'label' => 'Arah susunan',
'options' => [
'asc' => 'Menaik',
'desc' => 'Menurun',
],
],
],
],
'default_model_label' => 'rekod',
];
@@ -0,0 +1,265 @@
<?php
return [
'column_manager' => [
'heading' => 'Kolonner',
'actions' => [
'apply' => [
'label' => 'Bruk kolonner',
],
'reset' => [
'label' => 'Nullstill',
],
],
],
'columns' => [
'actions' => [
'label' => 'Handling|Handlinger',
],
'select' => [
'loading_message' => 'Laster...',
'no_search_results_message' => 'Ingen alternativer samsvarer med søket ditt.',
'placeholder' => 'Velg et alternativ',
'searching_message' => 'Søker...',
'search_prompt' => 'Skriv for å søke...',
],
'text' => [
'actions' => [
'collapse_list' => 'Vis :count mindre',
'expand_list' => 'Vis :count til',
],
'more_list_items' => 'og :count til',
],
],
'fields' => [
'bulk_select_page' => [
'label' => 'Velg/fjern alle valgte elementer for massehandlinger.',
],
'bulk_select_record' => [
'label' => 'Velg/fjern element :key for massehandlinger.',
],
'bulk_select_group' => [
'label' => 'Velg/fjern gruppen :title for massehandlinger.',
],
'search' => [
'label' => 'Søk',
'placeholder' => 'Søk',
'indicator' => 'Søk',
],
],
'summary' => [
'heading' => 'Oppsummering',
'subheadings' => [
'all' => 'Alle :label',
'group' => ':group oppsummering',
'page' => 'Denne siden',
],
'summarizers' => [
'average' => [
'label' => 'Gjennomsnitt',
],
'count' => [
'label' => 'Tell opp',
],
'sum' => [
'label' => 'Sum',
],
],
],
'actions' => [
'disable_reordering' => [
'label' => 'Fullfør omorganisering av poster',
],
'enable_reordering' => [
'label' => 'Omorganiser poster',
],
'filter' => [
'label' => 'Filter',
],
'group' => [
'label' => 'Gruppere',
],
'open_bulk_actions' => [
'label' => 'Massehandlinger',
],
'column_manager' => [
'label' => 'Veksle kolonner',
],
],
'empty' => [
'heading' => 'Ingen :model',
'description' => 'Opprett en :model for å komme igang.',
],
'filters' => [
'actions' => [
'apply' => [
'label' => 'Bruk filtre',
],
'remove' => [
'label' => 'Fjern filter',
],
'remove_all' => [
'label' => 'Fjern alle filtre',
'tooltip' => 'Fjern alle filtre',
],
'reset' => [
'label' => 'Nullstill',
],
],
'heading' => 'Filtre',
'indicator' => 'Aktive filtre',
'multi_select' => [
'placeholder' => 'Alle',
],
'select' => [
'placeholder' => 'Alle',
'relationship' => [
'empty_option_label' => 'Ingen',
],
],
'trashed' => [
'label' => 'Slettede poster',
'only_trashed' => 'Bare slettede poster',
'with_trashed' => 'Med slettede poster',
'without_trashed' => 'Uten slettede poster',
],
],
'grouping' => [
'fields' => [
'group' => [
'label' => 'Grupper etter',
],
'direction' => [
'label' => 'Grupperetning',
'options' => [
'asc' => 'Stigende',
'desc' => 'Synkende',
],
],
],
],
'reorder_indicator' => 'Dra og slipp postene i rekkefølge.',
'selection_indicator' => [
'selected_count' => '1 post valgt|:count poster valgt',
'actions' => [
'select_all' => [
'label' => 'Velg alle :count',
],
'deselect_all' => [
'label' => 'Fjern alle markeringer',
],
],
],
'sorting' => [
'fields' => [
'column' => [
'label' => 'Sorter etter',
],
'direction' => [
'label' => 'Sorteringsretning',
'options' => [
'asc' => 'Stigende',
'desc' => 'Synkende',
],
],
],
],
'default_model_label' => 'post',
];

Some files were not shown because too many files have changed in this diff Show More