[增添]添加了datasource的setting数据库以及默认值
This commit is contained in:
65
vendor/filament/infolists/.stubs.php
vendored
Normal file
65
vendor/filament/infolists/.stubs.php
vendored
Normal file
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
namespace Livewire\Features\SupportTesting {
|
||||
|
||||
class Testable {
|
||||
public function mountInfolistAction(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function unmountInfolistAction(): static {}
|
||||
|
||||
public function setInfolistActionData(array $data): static {}
|
||||
|
||||
public function assertInfolistActionDataSet(array $data): static {}
|
||||
|
||||
public function callInfolistAction(string $component, string | array $name, array $data = [], array $arguments = [], string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function callMountedInfolistAction(array $arguments = []): static {}
|
||||
|
||||
public function assertInfolistActionExists(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionDoesNotExist(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionVisible(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionHidden(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionEnabled(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionDisabled(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionMounted(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionNotMounted(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionHalted(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertHasInfolistActionErrors(array $keys = []): static {}
|
||||
|
||||
public function assertHasNoInfolistActionErrors(array $keys = []): static {}
|
||||
|
||||
public function assertInfolistActionHasIcon(string $component, string | array $name, string $icon, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionDoesNotHaveIcon(string $component, string | array $name, string $icon, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionHasLabel(string $component, string | array $name, string $label, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionDoesNotHaveLabel(string $component, string | array $name, string $label, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionHasColor(string $component, string | array $name, string | array $color, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionDoesNotHaveColor(string $component, string | array $name, string | array $color, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionHasUrl(string $component, string | array $name, string $url, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionDoesNotHaveUrl(string $component, string | array $name, string $url, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionShouldOpenUrlInNewTab(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function assertInfolistActionShouldNotOpenUrlInNewTab(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function getNestedInfolistActionComponentAndName(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
|
||||
public function parseNestedInfolistActionComponentAndName(string $component, string | array $name, string $infolistName = 'infolist'): static {}
|
||||
}
|
||||
|
||||
}
|
||||
39
vendor/filament/infolists/composer.json
vendored
Normal file
39
vendor/filament/infolists/composer.json
vendored
Normal file
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "filament/infolists",
|
||||
"description": "Easily add beautiful read-only infolists 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.1",
|
||||
"filament/actions": "self.version",
|
||||
"filament/support": "self.version",
|
||||
"illuminate/console": "^10.45|^11.0",
|
||||
"illuminate/contracts": "^10.45|^11.0",
|
||||
"illuminate/database": "^10.45|^11.0",
|
||||
"illuminate/filesystem": "^10.45|^11.0",
|
||||
"illuminate/support": "^10.45|^11.0",
|
||||
"illuminate/view": "^10.45|^11.0",
|
||||
"spatie/laravel-package-tools": "^1.9"
|
||||
},
|
||||
"autoload": {
|
||||
"psr-4": {
|
||||
"Filament\\Infolists\\": "src"
|
||||
}
|
||||
},
|
||||
"extra": {
|
||||
"laravel": {
|
||||
"providers": [
|
||||
"Filament\\Infolists\\InfolistsServiceProvider"
|
||||
]
|
||||
}
|
||||
},
|
||||
"config": {
|
||||
"sort-packages": true
|
||||
},
|
||||
"minimum-stability": "dev",
|
||||
"prefer-stable": true
|
||||
}
|
||||
174
vendor/filament/infolists/docs/01-installation.md
vendored
Normal file
174
vendor/filament/infolists/docs/01-installation.md
vendored
Normal file
@@ -0,0 +1,174 @@
|
||||
---
|
||||
title: Installation
|
||||
---
|
||||
|
||||
**The Infolist Builder package is pre-installed with the [Panel Builder](/docs/panels).** This guide is for using the Infolist Builder package in a custom TALL Stack application (Tailwind, Alpine, Livewire, Laravel).
|
||||
|
||||
## Requirements
|
||||
|
||||
Filament requires the following to run:
|
||||
|
||||
- PHP 8.1+
|
||||
- Laravel v10.0+
|
||||
- Livewire v3.0+
|
||||
|
||||
## Installation
|
||||
|
||||
Require the Infolist Builder package using Composer:
|
||||
|
||||
```bash
|
||||
composer require filament/infolists:"^3.2" -W
|
||||
```
|
||||
|
||||
## New Laravel projects
|
||||
|
||||
To quickly get started with Filament in a new Laravel project, run the following commands to install [Livewire](https://livewire.laravel.com), [Alpine.js](https://alpinejs.dev), and [Tailwind CSS](https://tailwindcss.com):
|
||||
|
||||
> Since these commands will overwrite existing files in your application, only run this in a new Laravel project!
|
||||
|
||||
```bash
|
||||
php artisan filament:install --scaffold --infolists
|
||||
|
||||
npm install
|
||||
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Existing Laravel projects
|
||||
|
||||
Run the following command to install the Infolist Builder package assets:
|
||||
|
||||
```bash
|
||||
php artisan filament:install --infolists
|
||||
```
|
||||
|
||||
### Installing Tailwind CSS
|
||||
|
||||
Run the following command to install Tailwind CSS with the Tailwind Forms and Typography plugins:
|
||||
|
||||
```bash
|
||||
npm install tailwindcss @tailwindcss/forms @tailwindcss/typography postcss postcss-nesting autoprefixer --save-dev
|
||||
```
|
||||
|
||||
Create a new `tailwind.config.js` file and add the Filament `preset` *(includes the Filament color scheme and the required Tailwind plugins)*:
|
||||
|
||||
```js
|
||||
import preset from './vendor/filament/support/tailwind.config.preset'
|
||||
|
||||
export default {
|
||||
presets: [preset],
|
||||
content: [
|
||||
'./app/Filament/**/*.php',
|
||||
'./resources/views/filament/**/*.blade.php',
|
||||
'./vendor/filament/**/*.blade.php',
|
||||
],
|
||||
}
|
||||
```
|
||||
|
||||
### Configuring styles
|
||||
|
||||
Add Tailwind's CSS layers to your `resources/css/app.css`:
|
||||
|
||||
```css
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
@tailwind utilities;
|
||||
```
|
||||
|
||||
Create a `postcss.config.js` file in the root of your project and register Tailwind CSS, PostCSS Nesting and Autoprefixer as plugins:
|
||||
|
||||
```js
|
||||
export default {
|
||||
plugins: {
|
||||
'tailwindcss/nesting': 'postcss-nesting',
|
||||
tailwindcss: {},
|
||||
autoprefixer: {},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
### Automatically refreshing the browser
|
||||
You may also want to update your `vite.config.js` file to refresh the page automatically when Livewire components are updated:
|
||||
|
||||
```js
|
||||
import { defineConfig } from 'vite'
|
||||
import laravel, { refreshPaths } from 'laravel-vite-plugin'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [
|
||||
laravel({
|
||||
input: ['resources/css/app.css', 'resources/js/app.js'],
|
||||
refresh: [
|
||||
...refreshPaths,
|
||||
'app/Livewire/**',
|
||||
],
|
||||
}),
|
||||
],
|
||||
})
|
||||
```
|
||||
|
||||
### Compiling assets
|
||||
|
||||
Compile your new CSS and Javascript assets using `npm run dev`.
|
||||
|
||||
### Configuring your layout
|
||||
|
||||
Create a new `resources/views/components/layouts/app.blade.php` layout file for Livewire components:
|
||||
|
||||
```blade
|
||||
<!DOCTYPE html>
|
||||
<html lang="{{ str_replace('_', '-', app()->getLocale()) }}">
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
|
||||
<meta name="application-name" content="{{ config('app.name') }}">
|
||||
<meta name="csrf-token" content="{{ csrf_token() }}">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
|
||||
<title>{{ config('app.name') }}</title>
|
||||
|
||||
<style>
|
||||
[x-cloak] {
|
||||
display: none !important;
|
||||
}
|
||||
</style>
|
||||
|
||||
@filamentStyles
|
||||
@vite('resources/css/app.css')
|
||||
</head>
|
||||
|
||||
<body class="antialiased">
|
||||
{{ $slot }}
|
||||
|
||||
@filamentScripts
|
||||
@vite('resources/js/app.js')
|
||||
</body>
|
||||
</html>
|
||||
```
|
||||
|
||||
## Publishing configuration
|
||||
|
||||
You can publish the package configuration using the following command (optional):
|
||||
|
||||
```bash
|
||||
php artisan vendor:publish --tag=filament-config
|
||||
```
|
||||
|
||||
## Upgrading
|
||||
|
||||
Filament automatically upgrades to the latest non-breaking version when you run `composer update`. After any updates, all Laravel caches need to be cleared, and frontend assets need to be republished. You can do this all at once using the `filament:upgrade` command, which should have been added to your `composer.json` file when you ran `filament:install` the first time:
|
||||
|
||||
```json
|
||||
"post-autoload-dump": [
|
||||
// ...
|
||||
"@php artisan filament:upgrade"
|
||||
],
|
||||
```
|
||||
|
||||
Please note that `filament:upgrade` does not actually handle the update process, as Composer does that already. If you're upgrading manually without a `post-autoload-dump` hook, you can run the command yourself:
|
||||
|
||||
```bash
|
||||
composer update
|
||||
|
||||
php artisan filament:upgrade
|
||||
```
|
||||
97
vendor/filament/infolists/docs/02-getting-started.md
vendored
Normal file
97
vendor/filament/infolists/docs/02-getting-started.md
vendored
Normal file
@@ -0,0 +1,97 @@
|
||||
---
|
||||
title: Getting started
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Filament's infolist package allows you to [render a read-only list of data about a particular entity](adding-an-infolist-to-a-livewire-component). It's also used within other Filament packages, such as the [Panel Builder](../panels) for displaying [app resources](../panels/resources/getting-started) and [relation managers](../panels/resources/relation-managers), as well as for [action modals](../actions). Learning the features of the Infolist Builder will be incredibly time-saving when both building your own custom Livewire applications and using Filament's other packages.
|
||||
|
||||
This guide will walk you through the basics of building infolists with Filament's infolist package. If you're planning to add a new infolist to your own Livewire component, you should [do that first](adding-an-infolist-to-a-livewire-component) and then come back. If you're adding an infolist to an [app resource](../panels/resources/getting-started), or another Filament package, you're ready to go!
|
||||
|
||||
## Defining entries
|
||||
|
||||
The first step to building an infolist is to define the entries that will be displayed in the list. You can do this by calling the `schema()` method on an `Infolist` object. This method accepts an array of entry objects.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
$infolist
|
||||
->schema([
|
||||
TextEntry::make('title'),
|
||||
TextEntry::make('slug'),
|
||||
TextEntry::make('content'),
|
||||
]);
|
||||
```
|
||||
|
||||
Each entry is a piece of information that should be displayed in the infolist. The `TextEntry` is used for displaying text, but there are [other entry types available](entries/getting-started#available-entries).
|
||||
|
||||
Infolists within the Panel Builder and other packages usually have 2 columns by default. For custom infolists, you can use the `columns()` method to achieve the same effect:
|
||||
|
||||
```php
|
||||
$infolist
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->columns(2);
|
||||
```
|
||||
|
||||
Now, the `content` entry will only consume half of the available width. We can use the `columnSpan()` method to make it span the full width:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
[
|
||||
TextEntry::make('title'),
|
||||
TextEntry::make('slug')
|
||||
TextEntry::make('content')
|
||||
->columnSpan(2), // or `columnSpan('full')`,
|
||||
]
|
||||
```
|
||||
|
||||
You can learn more about columns and spans in the [layout documentation](layout/grid). You can even make them responsive!
|
||||
|
||||
## Using layout components
|
||||
|
||||
The Infolist Builder allows you to use [layout components](layout/getting-started#available-layout-components) inside the schema array to control how entries are displayed. `Section` is a layout component, and it allows you to add a heading and description to a set of entries. It can also allow entries inside it to collapse, which saves space in long infolists.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
[
|
||||
TextEntry::make('title'),
|
||||
TextEntry::make('slug'),
|
||||
TextEntry::make('content')
|
||||
->columnSpan(2)
|
||||
->markdown(),
|
||||
Section::make('Media')
|
||||
->description('Images used in the page layout.')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
]
|
||||
```
|
||||
|
||||
In this example, you can see how the `Section` component has its own `schema()` method. You can use this to nest other entries and layout components inside:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
Section::make('Media')
|
||||
->description('Images used in the page layout.')
|
||||
->schema([
|
||||
ImageEntry::make('hero_image'),
|
||||
TextEntry::make('alt_text'),
|
||||
])
|
||||
```
|
||||
|
||||
This section now contains an [`ImageEntry`](entries/image) and a [`TextEntry`](entries/text). You can learn more about those entries and their functionalities on the respective docs pages.
|
||||
|
||||
## Next steps with the infolists package
|
||||
|
||||
Now you've finished reading this guide, where to next? Here are some suggestions:
|
||||
|
||||
- [Explore the available entries to display data in your infolist.](entries/getting-started#available-entries)
|
||||
- [Discover how to build complex, responsive layouts without touching CSS.](layout/getting-started)
|
||||
328
vendor/filament/infolists/docs/03-entries/01-getting-started.md
vendored
Normal file
328
vendor/filament/infolists/docs/03-entries/01-getting-started.md
vendored
Normal file
@@ -0,0 +1,328 @@
|
||||
---
|
||||
title: Getting started
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Entry classes can be found in the `Filament\Infolists\Components` namespace. You can put them inside the `$infolist->schema()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Infolist;
|
||||
|
||||
public function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->schema([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
If you're inside a [panel builder resource](../../panels/resources), the `infolist()` method should be static:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Infolist;
|
||||
|
||||
public static function infolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->schema([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Entries may be created using the static `make()` method, passing its unique name. You may use "dot notation" to access entries within relationships.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
|
||||
TextEntry::make('author.name')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/simple" alt="Entries in an infolist" version="3.x" />
|
||||
|
||||
## Available entries
|
||||
|
||||
- [Text entry](text)
|
||||
- [Icon entry](icon)
|
||||
- [Image entry](image)
|
||||
- [Color entry](color)
|
||||
- [Key-value entry](key-value)
|
||||
- [Repeatable entry](repeatable)
|
||||
|
||||
You may also [create your own custom entries](custom) to display data however you wish.
|
||||
|
||||
## Setting a label
|
||||
|
||||
By default, the label of the entry, which is displayed in the header of the infolist, is generated from the name of the entry. You may customize this using the `label()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->label('Post title')
|
||||
```
|
||||
|
||||
Optionally, you can have the label automatically translated [using Laravel's localization features](https://laravel.com/docs/localization) with the `translateLabel()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->translateLabel() // Equivalent to `label(__('Title'))`
|
||||
```
|
||||
|
||||
## Entry URLs
|
||||
|
||||
When an entry is clicked, you may open a URL.
|
||||
|
||||
### Opening URLs
|
||||
|
||||
To open a URL, you may use the `url()` method, passing a callback or static URL to open. Callbacks accept a `$record` parameter which you may use to customize the URL:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))
|
||||
```
|
||||
|
||||
You may also choose to open the URL in a new tab:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->url(fn (Post $record): string => route('posts.edit', ['post' => $record]))
|
||||
->openUrlInNewTab()
|
||||
```
|
||||
|
||||
## Setting a default value
|
||||
|
||||
To set a default value for entries with an empty state, you may use the `default()` method. This method will treat the default state as if it were real, so entries like [image](image) or [color](color) will display the default image or color.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->default('Untitled')
|
||||
```
|
||||
|
||||
## Adding placeholder text if an entry is empty
|
||||
|
||||
Sometimes you may want to display placeholder text for entries with an empty state, which is styled as a lighter gray text. This differs from the [default value](#setting-a-default-value), as the placeholder is always text and not treated as if it were real state.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->placeholder('Untitled')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/placeholder" alt="Entry with a placeholder for empty state" version="3.x" />
|
||||
|
||||
## Adding helper text below the entry
|
||||
|
||||
Sometimes, you may wish to provide extra information for the user of the infolist. For this purpose, you may add helper text below the entry.
|
||||
|
||||
The `helperText()` method is used to add helper text:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('name')
|
||||
->helperText('Your full name here, including any middle names.')
|
||||
```
|
||||
|
||||
This method accepts a plain text string, or an instance of `Illuminate\Support\HtmlString` or `Illuminate\Contracts\Support\Htmlable`. This allows you to render HTML, or even markdown, in the helper text:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
TextEntry::make('name')
|
||||
->helperText(new HtmlString('Your <strong>full name</strong> here, including any middle names.'))
|
||||
|
||||
TextEntry::make('name')
|
||||
->helperText(str('Your **full name** here, including any middle names.')->inlineMarkdown()->toHtmlString())
|
||||
|
||||
TextEntry::make('name')
|
||||
->helperText(view('name-helper-text'))
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/helper-text" alt="Entry with helper text" version="3.x" />
|
||||
|
||||
## Adding a hint next to the label
|
||||
|
||||
As well as [helper text](#adding-helper-text-below-the-entry) below the entry, you may also add a "hint" next to the label of the entry. This is useful for displaying additional information about the entry, such as a link to a help page.
|
||||
|
||||
The `hint()` method is used to add a hint:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint('Documentation? What documentation?!')
|
||||
```
|
||||
|
||||
This method accepts a plain text string, or an instance of `Illuminate\Support\HtmlString` or `Illuminate\Contracts\Support\Htmlable`. This allows you to render HTML, or even markdown, in the helper text:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint(new HtmlString('<a href="/documentation">Documentation</a>'))
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint(str('[Documentation](/documentation)')->inlineMarkdown()->toHtmlString())
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint(view('api-key-hint'))
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/hint" alt="Entry with hint" version="3.x" />
|
||||
|
||||
### Changing the text color of the hint
|
||||
|
||||
You can change the text color of the hint. By default, it's gray, but you may use `danger`, `info`, `primary`, `success` and `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint(str('[Documentation](/documentation)')->inlineMarkdown()->toHtmlString())
|
||||
->hintColor('primary')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/hint-color" alt="Entry with hint color" version="3.x" />
|
||||
|
||||
### Adding an icon aside the hint
|
||||
|
||||
Hints may also have an [icon](https://blade-ui-kit.com/blade-icons?set=1#search) rendered next to them:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint(str('[Documentation](/documentation)')->inlineMarkdown()->toHtmlString())
|
||||
->hintIcon('heroicon-m-question-mark-circle')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/hint-icon" alt="Entry with hint icon" version="3.x" />
|
||||
|
||||
#### Adding a tooltip to a hint icon
|
||||
|
||||
Additionally, you can add a tooltip to display when you hover over the hint icon, using the `tooltip` parameter of `hintIcon()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->hint(str('[Documentation](/documentation)')->inlineMarkdown()->toHtmlString())
|
||||
->hintIcon('heroicon-m-question-mark-circle', tooltip: 'Read it!')
|
||||
```
|
||||
|
||||
## Hiding entries
|
||||
|
||||
To hide an entry conditionally, you may use the `hidden()` and `visible()` methods, whichever you prefer:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('role')
|
||||
->hidden(! auth()->user()->isAdmin())
|
||||
// or
|
||||
TextEntry::make('role')
|
||||
->visible(auth()->user()->isAdmin())
|
||||
```
|
||||
|
||||
## Calculated state
|
||||
|
||||
Sometimes you need to calculate the state of an entry, instead of directly reading it from a database entry.
|
||||
|
||||
By passing a callback function to the `state()` method, you can customize the returned state for that entry:
|
||||
|
||||
```php
|
||||
Infolists\Components\TextEntry::make('amount_including_vat')
|
||||
->state(function (Model $record): float {
|
||||
return $record->amount * (1 + $record->vat_rate);
|
||||
})
|
||||
```
|
||||
|
||||
## Tooltips
|
||||
|
||||
You may specify a tooltip to display when you hover over an entry:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->tooltip('Shown at the top of the page')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/tooltips" alt="Entry with tooltip" version="3.x" />
|
||||
|
||||
This method also accepts a closure that can access the current infolist record:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
TextEntry::make('title')
|
||||
->tooltip(fn (Model $record): string => "By {$record->author->name}")
|
||||
```
|
||||
|
||||
## Custom attributes
|
||||
|
||||
The HTML of entries can be customized, by passing an array of `extraAttributes()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('slug')
|
||||
->extraAttributes(['class' => 'bg-gray-200'])
|
||||
```
|
||||
|
||||
These get merged onto the outer `<div>` element of each entry in that entry.
|
||||
|
||||
You can also pass extra HTML attributes to the entry wrapper which surrounds the label, entry, and any other text:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('slug')
|
||||
->extraEntryWrapperAttributes(['class' => 'entry-locked'])
|
||||
```
|
||||
|
||||
## Global settings
|
||||
|
||||
If you wish to change the default behavior of all entries globally, then you can call the static `configureUsing()` method inside a service provider's `boot()` method, to which you pass a Closure to modify the entries using. For example, if you wish to make all `TextEntry` components [`words(10)`](text#limiting-word-count), you can do it like so:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::configureUsing(function (TextEntry $entry): void {
|
||||
$entry
|
||||
->words(10);
|
||||
});
|
||||
```
|
||||
|
||||
Of course, you are still able to overwrite this on each entry individually:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('name')
|
||||
->words(null)
|
||||
```
|
||||
420
vendor/filament/infolists/docs/03-entries/02-text.md
vendored
Normal file
420
vendor/filament/infolists/docs/03-entries/02-text.md
vendored
Normal file
@@ -0,0 +1,420 @@
|
||||
---
|
||||
title: Text entry
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Text entries display simple text:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/simple" alt="Text entry" version="3.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\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('status')
|
||||
->badge()
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'draft' => 'gray',
|
||||
'reviewing' => 'warning',
|
||||
'published' => 'success',
|
||||
'rejected' => 'danger',
|
||||
})
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/badge" alt="Text entry as badge" version="3.x" />
|
||||
|
||||
You may add other things to the badge, like an [icon](#adding-an-icon).
|
||||
|
||||
## Date formatting
|
||||
|
||||
You may use the `date()` and `dateTime()` methods to format the entry's state using [PHP date formatting tokens](https://www.php.net/manual/en/datetime.format.php):
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('created_at')
|
||||
->dateTime()
|
||||
```
|
||||
|
||||
You may use the `since()` method to format the entry's state using [Carbon's `diffForHumans()`](https://carbon.nesbot.com/docs/#api-humandiff):
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('created_at')
|
||||
->since()
|
||||
```
|
||||
|
||||
## Number formatting
|
||||
|
||||
The `numeric()` method allows you to format an entry as a number:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::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\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('stock')
|
||||
->numeric(decimalPlaces: 0)
|
||||
```
|
||||
|
||||
By default, your app's locale will be used to format the number suitably. If you would like to customize the locale used, you can pass it to the `locale` argument:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('stock')
|
||||
->numeric(locale: 'nl')
|
||||
```
|
||||
|
||||
Alternatively, you can set the default locale used across your app using the `Number::useLocale()` method in the `boot()` method of a service provider:
|
||||
|
||||
```php
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
Number::useLocale('nl');
|
||||
```
|
||||
|
||||
## Currency formatting
|
||||
|
||||
The `money()` method allows you to easily format monetary values, in any currency:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('price')
|
||||
->money('EUR')
|
||||
```
|
||||
|
||||
There is also a `divideBy` argument for `money()` that allows you to divide the original value by a number before formatting it. This could be useful if your database stores the price in cents, for example:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('price')
|
||||
->money('EUR', divideBy: 100)
|
||||
```
|
||||
|
||||
By default, your app's locale will be used to format the money suitably. If you would like to customize the locale used, you can pass it to the `locale` argument:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('price')
|
||||
->money('EUR', locale: 'nl')
|
||||
```
|
||||
|
||||
Alternatively, you can set the default locale used across your app using the `Number::useLocale()` method in the `boot()` method of a service provider:
|
||||
|
||||
```php
|
||||
use Illuminate\Support\Number;
|
||||
|
||||
Number::useLocale('nl');
|
||||
```
|
||||
|
||||
## Limiting text length
|
||||
|
||||
You may `limit()` the length of the entry's value:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('description')
|
||||
->limit(50)
|
||||
```
|
||||
|
||||
You may also reuse the value that is being passed to `limit()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('description')
|
||||
->limit(50)
|
||||
->tooltip(function (TextEntry $component): ?string {
|
||||
$state = $component->getState();
|
||||
|
||||
if (strlen($state) <= $component->getCharacterLimit()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Only render the tooltip if the entry contents exceeds the length limit.
|
||||
return $state;
|
||||
})
|
||||
```
|
||||
|
||||
## Limiting word count
|
||||
|
||||
You may limit the number of `words()` displayed in the entry:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('description')
|
||||
->words(10)
|
||||
```
|
||||
|
||||
## Limiting text to a specific number of lines
|
||||
|
||||
You may want to limit text to a specific number of lines instead of limiting it to a fixed length. Clamping text to a number of lines is useful in responsive interfaces where you want to ensure a consistent experience across all screen sizes. This can be achieved using the `lineClamp()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('description')
|
||||
->lineClamp(2)
|
||||
```
|
||||
|
||||
## Listing multiple values
|
||||
|
||||
By default, if there are multiple values inside your text entry, they will be comma-separated. You may use the `listWithLineBreaks()` method to display them on new lines instead:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/list" alt="Text entry with multiple values" version="3.x" />
|
||||
|
||||
### Adding bullet points to the list
|
||||
|
||||
You may add a bullet point to each list item using the `bulleted()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
->bulleted()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/bullet-list" alt="Text entry with multiple values and bullet points" version="3.x" />
|
||||
|
||||
### 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\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
->limitList(3)
|
||||
```
|
||||
|
||||
#### Expanding the limited list
|
||||
|
||||
You can allow the limited items to be expanded and collapsed, using the `expandableLimitedList()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('authors.name')
|
||||
->listWithLineBreaks()
|
||||
->limitList(3)
|
||||
->expandableLimitedList()
|
||||
```
|
||||
|
||||
Please note that this is only a feature for `listWithLineBreaks()` or `bulleted()`, where each item is on its own line.
|
||||
|
||||
### Using a list separator
|
||||
|
||||
If you want to "explode" a text string from your model into multiple list items, you can do so with the `separator()` method. This is useful for displaying comma-separated tags [as badges](#displaying-as-a-badge), for example:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('tags')
|
||||
->badge()
|
||||
->separator(',')
|
||||
```
|
||||
|
||||
## Rendering HTML
|
||||
|
||||
If your entry value is HTML, you may render it using `html()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('description')
|
||||
->html()
|
||||
```
|
||||
|
||||
If you use this method, then the HTML will be sanitized to remove any potentially unsafe content before it is rendered. If you'd like to opt out of this behavior, you can wrap the HTML in an `HtmlString` object by formatting it:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Illuminate\Support\HtmlString;
|
||||
|
||||
TextEntry::make('description')
|
||||
->formatStateUsing(fn (string $state): HtmlString => new HtmlString($state))
|
||||
```
|
||||
|
||||
Or, you can return a `view()` object from the `formatStateUsing()` method, which will also not be sanitized:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Illuminate\Contracts\View\View;
|
||||
|
||||
TextEntry::make('description')
|
||||
->formatStateUsing(fn (string $state): View => view(
|
||||
'filament.infolists.components.description-entry-content',
|
||||
['state' => $state],
|
||||
))
|
||||
```
|
||||
|
||||
### Rendering Markdown as HTML
|
||||
|
||||
If your entry value is Markdown, you may render it using `markdown()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('description')
|
||||
->markdown()
|
||||
```
|
||||
|
||||
## Custom formatting
|
||||
|
||||
You may instead pass a custom formatting callback to `formatStateUsing()`, which accepts the `$state` of the entry, and optionally its `$record`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('status')
|
||||
->formatStateUsing(fn (string $state): string => __("statuses.{$state}"))
|
||||
```
|
||||
|
||||
## Customizing the color
|
||||
|
||||
You may set a color for the text, either `danger`, `gray`, `info`, `primary`, `success` or `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('status')
|
||||
->color('primary')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/color" alt="Text entry in the primary color" version="3.x" />
|
||||
|
||||
## Adding an icon
|
||||
|
||||
Text entries may also have an [icon](https://blade-ui-kit.com/blade-icons?set=1#search):
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/icon" alt="Text entry with icon" version="3.x" />
|
||||
|
||||
You may set the position of an icon using `iconPosition()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
|
||||
TextEntry::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
->iconPosition(IconPosition::After) // `IconPosition::Before` or `IconPosition::After`
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/icon-after" alt="Text entry with icon after" version="3.x" />
|
||||
|
||||
The icon color defaults to the text color, but you may customize the icon color separately using `iconColor()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('email')
|
||||
->icon('heroicon-m-envelope')
|
||||
->iconColor('primary')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/icon-color" alt="Text entry with icon in the primary color" version="3.x" />
|
||||
|
||||
## Customizing the text size
|
||||
|
||||
Text columns have small font size by default, but you may change this to `TextEntrySize::ExtraSmall`, `TextEntrySize::Medium`, or `TextEntrySize::Large`.
|
||||
|
||||
For instance, you may make the text larger using `size(TextEntrySize::Large)`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('title')
|
||||
->size(TextEntry\TextEntrySize::Large)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/large" alt="Text entry in a large font size" version="3.x" />
|
||||
|
||||
## Customizing the font weight
|
||||
|
||||
Text entries 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\Infolists\Components\TextEntry;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
|
||||
TextEntry::make('title')
|
||||
->weight(FontWeight::Bold)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/bold" alt="Text entry in a bold font" version="3.x" />
|
||||
|
||||
## Customizing the font family
|
||||
|
||||
You can change the text font family to any of the following options: `FontFamily::Sans`, `FontFamily::Serif` or `FontFamily::Mono`.
|
||||
|
||||
For instance, you may make the font monospaced using `fontFamily(FontFamily::Mono)`:
|
||||
|
||||
```php
|
||||
use Filament\Support\Enums\FontFamily;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->fontFamily(FontFamily::Mono)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/mono" alt="Text entry in a monospaced font" version="3.x" />
|
||||
|
||||
## Allowing the text to be copied to the clipboard
|
||||
|
||||
You may make the text copyable, such that clicking on the entry copies the text to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('apiKey')
|
||||
->label('API key')
|
||||
->copyable()
|
||||
->copyMessage('Copied!')
|
||||
->copyMessageDuration(1500)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/text/copyable" alt="Text entry with a button to copy it" version="3.x" />
|
||||
101
vendor/filament/infolists/docs/03-entries/03-icon.md
vendored
Normal file
101
vendor/filament/infolists/docs/03-entries/03-icon.md
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
---
|
||||
title: Icon entry
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Icon entries render an [icon](https://blade-ui-kit.com/blade-icons?set=1#search) representing their contents:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
|
||||
IconEntry::make('status')
|
||||
->icon(fn (string $state): string => match ($state) {
|
||||
'draft' => 'heroicon-o-pencil',
|
||||
'reviewing' => 'heroicon-o-clock',
|
||||
'published' => 'heroicon-o-check-circle',
|
||||
})
|
||||
```
|
||||
|
||||
In the function, `$state` is the value of the entry, and `$record` can be used to access the underlying Eloquent record.
|
||||
|
||||
<AutoScreenshot name="infolists/entries/icon/simple" alt="Icon entry" version="3.x" />
|
||||
|
||||
## Customizing the color
|
||||
|
||||
Icon entries may also have a set of icon colors, using the same syntax. They may be either `danger`, `gray`, `info`, `primary`, `success` or `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
|
||||
IconEntry::make('status')
|
||||
->color(fn (string $state): string => match ($state) {
|
||||
'draft' => 'info',
|
||||
'reviewing' => 'warning',
|
||||
'published' => 'success',
|
||||
default => 'gray',
|
||||
})
|
||||
```
|
||||
|
||||
In the function, `$state` is the value of the entry, and `$record` can be used to access the underlying Eloquent record.
|
||||
|
||||
<AutoScreenshot name="infolists/entries/icon/color" alt="Icon entry with color" version="3.x" />
|
||||
|
||||
## Customizing the size
|
||||
|
||||
The default icon size is `IconEntrySize::Large`, but you may customize the size to be either `IconEntrySize::ExtraSmall`, `IconEntrySize::Small`, `IconEntrySize::Medium`, `IconEntrySize::ExtraLarge` or `IconEntrySize::TwoExtraLarge`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
|
||||
IconEntry::make('status')
|
||||
->size(IconEntry\IconEntrySize::Medium)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/icon/medium" alt="Medium-sized icon entry" version="3.x" />
|
||||
|
||||
## Handling booleans
|
||||
|
||||
Icon entries can display a check or cross icon based on the contents of the database entry, either true or false, using the `boolean()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
|
||||
IconEntry::make('is_featured')
|
||||
->boolean()
|
||||
```
|
||||
|
||||
> If this column in the model class is already cast as a `bool` or `boolean`, Filament is able to detect this, and you do not need to use `boolean()` manually.
|
||||
|
||||
<AutoScreenshot name="infolists/entries/icon/boolean" alt="Icon entry to display a boolean" version="3.x" />
|
||||
|
||||
### Customizing the boolean icons
|
||||
|
||||
You may customize the icon representing each state. Icons are the name of a Blade component present. By default, [Heroicons](https://heroicons.com) are installed:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
|
||||
IconEntry::make('is_featured')
|
||||
->boolean()
|
||||
->trueIcon('heroicon-o-check-badge')
|
||||
->falseIcon('heroicon-o-x-mark')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/icon/boolean-icon" alt="Icon entry to display a boolean with custom icons" version="3.x" />
|
||||
|
||||
### Customizing the boolean colors
|
||||
|
||||
You may customize the icon color representing each state. These may be either `danger`, `gray`, `info`, `primary`, `success` or `warning`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
|
||||
IconEntry::make('is_featured')
|
||||
->boolean()
|
||||
->trueColor('info')
|
||||
->falseColor('warning')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/icon/boolean-color" alt="Icon entry to display a boolean with custom colors" version="3.x" />
|
||||
229
vendor/filament/infolists/docs/03-entries/04-image.md
vendored
Normal file
229
vendor/filament/infolists/docs/03-entries/04-image.md
vendored
Normal file
@@ -0,0 +1,229 @@
|
||||
---
|
||||
title: Image entry
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Images can be easily displayed within your infolist:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('header_image')
|
||||
```
|
||||
|
||||
The entry must contain the path to the image, relative to the root directory of its storage disk, or an absolute URL to it.
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/simple" alt="Image entry" version="3.x" />
|
||||
|
||||
## Managing the image disk
|
||||
|
||||
By default, the `public` disk will be used to retrieve images. You may pass a custom disk name to the `disk()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('header_image')
|
||||
->disk('s3')
|
||||
```
|
||||
|
||||
## Private images
|
||||
|
||||
Filament can generate temporary URLs to render private images, you may set the `visibility()` to `private`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('header_image')
|
||||
->visibility('private')
|
||||
```
|
||||
|
||||
## Customizing the size
|
||||
|
||||
You may customize the image size by passing a `width()` and `height()`, or both with `size()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('header_image')
|
||||
->width(200)
|
||||
|
||||
ImageEntry::make('header_image')
|
||||
->height(50)
|
||||
|
||||
ImageEntry::make('author.avatar')
|
||||
->size(40)
|
||||
```
|
||||
|
||||
## Square image
|
||||
|
||||
You may display the image using a 1:1 aspect ratio:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('author.avatar')
|
||||
->height(40)
|
||||
->square()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/square" alt="Square image entry" version="3.x" />
|
||||
|
||||
## Circular image
|
||||
|
||||
You may make the image fully rounded, which is useful for rendering avatars:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('author.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/circular" alt="Circular image entry" version="3.x" />
|
||||
|
||||
## Adding a default image URL
|
||||
|
||||
You can display a placeholder image if one doesn't exist yet, by passing a URL to the `defaultImageUrl()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('avatar')
|
||||
->defaultImageUrl(url('/images/placeholder.png'))
|
||||
```
|
||||
|
||||
## Stacking images
|
||||
|
||||
You may display multiple images as a stack of overlapping images by using `stacked()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/stacked" alt="Stacked image entry" version="3.x" />
|
||||
|
||||
### Customizing the stacked ring width
|
||||
|
||||
The default ring width is `3`, but you may customize it to be from `0` to `8`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
->ring(5)
|
||||
```
|
||||
|
||||
### Customizing the stacked overlap
|
||||
|
||||
The default overlap is `4`, but you may customize it to be from `0` to `8`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
->overlap(2)
|
||||
```
|
||||
|
||||
## Setting a limit
|
||||
|
||||
You may limit the maximum number of images you want to display by passing `limit()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/limited" alt="Limited image entry" version="3.x" />
|
||||
|
||||
### Showing the remaining images count
|
||||
|
||||
When you set a limit you may also display the count of remaining images by passing `limitedRemainingText()`.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
->limitedRemainingText()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/limited-remaining-text" alt="Limited image entry with remaining text" version="3.x" />
|
||||
|
||||
#### Showing the limited remaining text separately
|
||||
|
||||
By default, `limitedRemainingText()` will display the count of remaining images as a number stacked on the other images. If you prefer to show the count as a number after the images, you may use the `isSeparate: true` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
->limitedRemainingText(isSeparate: true)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/image/limited-remaining-text-separately" alt="Limited image entry with remaining text separately" version="3.x" />
|
||||
|
||||
#### Customizing the limited remaining text size
|
||||
|
||||
By default, the size of the remaining text is `sm`. You can customize this to be `xs`, `md` or `lg` using the `size` parameter:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('colleagues.avatar')
|
||||
->height(40)
|
||||
->circular()
|
||||
->stacked()
|
||||
->limit(3)
|
||||
->limitedRemainingText(size: 'lg')
|
||||
```
|
||||
|
||||
## Custom attributes
|
||||
|
||||
You may customize the extra HTML attributes of the image using `extraImgAttributes()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('logo')
|
||||
->extraImgAttributes([
|
||||
'alt' => 'Logo',
|
||||
'loading' => 'lazy',
|
||||
]),
|
||||
```
|
||||
|
||||
## Prevent file existence checks
|
||||
|
||||
When the infolist is loaded, it will automatically detect whether the images exist. This is all done on the backend. When using remote storage with many images, this can be time-consuming. You can use the `checkFileExistence(false)` method to disable this feature:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
|
||||
ImageEntry::make('attachment')
|
||||
->checkFileExistence(false)
|
||||
```
|
||||
31
vendor/filament/infolists/docs/03-entries/05-color.md
vendored
Normal file
31
vendor/filament/infolists/docs/03-entries/05-color.md
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
---
|
||||
title: Color entry
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The color entry allows you to show the color preview from a CSS color definition, typically entered using the color picker field, in one of the supported formats (HEX, HSL, RGB, RGBA).
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ColorEntry;
|
||||
|
||||
ColorEntry::make('color')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/color/simple" alt="Color entry" version="3.x" />
|
||||
|
||||
## Allowing the color to be copied to the clipboard
|
||||
|
||||
You may make the color copyable, such that clicking on the preview copies the CSS value to the clipboard, and optionally specify a custom confirmation message and duration in milliseconds. This feature only works when SSL is enabled for the app.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ColorEntry;
|
||||
|
||||
ColorEntry::make('color')
|
||||
->copyable()
|
||||
->copyMessage('Copied!')
|
||||
->copyMessageDuration(1500)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/color/copyable" alt="Color entry with a button to copy it" version="3.x" />
|
||||
53
vendor/filament/infolists/docs/03-entries/06-key-value.md
vendored
Normal file
53
vendor/filament/infolists/docs/03-entries/06-key-value.md
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
---
|
||||
title: Key-value entry
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The key-value entry allows you to render key-value pairs of data, from a one-dimensional JSON object / PHP array.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\KeyValueEntry;
|
||||
|
||||
KeyValueEntry::make('meta')
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/key-value/simple" alt="Key-value entry" version="3.x" />
|
||||
|
||||
If you're saving the data in Eloquent, you should be sure to add an `array` [cast](https://laravel.com/docs/eloquent-mutators#array-and-json-casting) to the model property:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Post extends Model
|
||||
{
|
||||
protected $casts = [
|
||||
'meta' => 'array',
|
||||
];
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Customizing the key column's label
|
||||
|
||||
You may customize the label for the key column using the `keyLabel()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\KeyValueEntry;
|
||||
|
||||
KeyValueEntry::make('meta')
|
||||
->keyLabel('Property name')
|
||||
```
|
||||
|
||||
## Customizing the value column's label
|
||||
|
||||
You may customize the label for the value column using the `valueLabel()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\KeyValueEntry;
|
||||
|
||||
KeyValueEntry::make('meta')
|
||||
->valueLabel('Property value')
|
||||
```
|
||||
58
vendor/filament/infolists/docs/03-entries/07-repeatable.md
vendored
Normal file
58
vendor/filament/infolists/docs/03-entries/07-repeatable.md
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
---
|
||||
title: Repeatable entry
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The repeatable entry allows you to repeat a set of entries and layout components for items in an array or relationship.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
RepeatableEntry::make('comments')
|
||||
->schema([
|
||||
TextEntry::make('author.name'),
|
||||
TextEntry::make('title'),
|
||||
TextEntry::make('content')
|
||||
->columnSpan(2),
|
||||
])
|
||||
->columns(2)
|
||||
```
|
||||
|
||||
As you can see, the repeatable entry has an embedded `schema()` which gets repeated for each item.
|
||||
|
||||
<AutoScreenshot name="infolists/entries/repeatable/simple" alt="Repeatable entry" version="3.x" />
|
||||
|
||||
## Grid layout
|
||||
|
||||
You may organize repeatable items into columns by using the `grid()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
|
||||
RepeatableEntry::make('comments')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->grid(2)
|
||||
```
|
||||
|
||||
This method accepts the same options as the `columns()` method of the [grid](../layout/grid). This allows you to responsively customize the number of grid columns at various breakpoints.
|
||||
|
||||
<AutoScreenshot name="infolists/entries/repeatable/grid" alt="Repeatable entry in grid layout" version="3.x" />
|
||||
|
||||
## Removing the styled container
|
||||
|
||||
By default, each item in a repeatable entry is wrapped in a container styled as a card. You may remove the styled container using `contained()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
|
||||
RepeatableEntry::make('comments')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->contained(false)
|
||||
```
|
||||
69
vendor/filament/infolists/docs/03-entries/08-custom.md
vendored
Normal file
69
vendor/filament/infolists/docs/03-entries/08-custom.md
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
---
|
||||
title: Custom entries
|
||||
---
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
<LaracastsBanner
|
||||
title="Build a Custom Infolist Entry"
|
||||
description="Watch the Build Advanced Components for Filament series on Laracasts - it will teach you how to build components, and you'll get to know all the internal tools to help you."
|
||||
url="https://laracasts.com/series/build-advanced-components-for-filament/episodes/8"
|
||||
series="building-advanced-components"
|
||||
/>
|
||||
|
||||
## View entries
|
||||
|
||||
You may render a custom view for an entry using the `view()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\ViewEntry;
|
||||
|
||||
ViewEntry::make('status')
|
||||
->view('filament.infolists.entries.status-switcher')
|
||||
```
|
||||
|
||||
This assumes that you have a `resources/views/filament/infolists/entries/status-switcher.blade.php` file.
|
||||
|
||||
## Custom classes
|
||||
|
||||
You may create your own custom entry classes and entry views, which you can reuse across your project, and even release as a plugin to the community.
|
||||
|
||||
> If you're just creating a simple custom entry to use once, you could instead use a [view entry](#view-entries) to render any custom Blade file.
|
||||
|
||||
To create a custom entry class and view, you may use the following command:
|
||||
|
||||
```bash
|
||||
php artisan make:infolist-entry StatusSwitcher
|
||||
```
|
||||
|
||||
This will create the following entry class:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Entry;
|
||||
|
||||
class StatusSwitcher extends Entry
|
||||
{
|
||||
protected string $view = 'filament.infolists.entries.status-switcher';
|
||||
}
|
||||
```
|
||||
|
||||
It will also create a view file at `resources/views/filament/infolists/entries/status-switcher.blade.php`.
|
||||
|
||||
## Accessing the state
|
||||
|
||||
Inside your view, you may retrieve the state of the entry using the `$getState()` function:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $getState() }}
|
||||
</div>
|
||||
```
|
||||
|
||||
## Accessing the Eloquent record
|
||||
|
||||
Inside your view, you may access the Eloquent record using the `$getRecord()` function:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $getRecord()->name }}
|
||||
</div>
|
||||
```
|
||||
78
vendor/filament/infolists/docs/04-layout/01-getting-started.md
vendored
Normal file
78
vendor/filament/infolists/docs/04-layout/01-getting-started.md
vendored
Normal file
@@ -0,0 +1,78 @@
|
||||
---
|
||||
title: Getting started
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Infolists are not limited to just displaying entries. You can also use "layout components" to organize them into an infinitely nestable structure.
|
||||
|
||||
Layout component classes can be found in the `Filament\Infolists\Components` namespace. They reside within the schema of your infolist, alongside any [entries](../entries/getting-started).
|
||||
|
||||
Components may be created using the static `make()` method. Usually, you will then define the child component `schema()` to display inside:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Grid;
|
||||
|
||||
Grid::make(2)
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
## Available layout components
|
||||
|
||||
Filament ships with some layout components, suitable for arranging your form fields depending on your needs:
|
||||
|
||||
- [Grid](grid)
|
||||
- [Fieldset](fieldset)
|
||||
- [Tabs](tabs)
|
||||
- [Section](section)
|
||||
- [Split](split)
|
||||
|
||||
You may also [create your own custom layout components](custom) to organize fields in whatever way you wish.
|
||||
|
||||
## Setting an ID
|
||||
|
||||
You may define an ID for the component using the `id()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make()
|
||||
->id('main-section')
|
||||
```
|
||||
|
||||
## Adding extra HTML attributes
|
||||
|
||||
You can pass extra HTML attributes to the component, which will be merged onto the outer DOM element. Pass an array of attributes to the `extraAttributes()` method, where the key is the attribute name and the value is the attribute value:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Group;
|
||||
|
||||
Section::make()
|
||||
->extraAttributes(['class' => 'custom-section-style'])
|
||||
```
|
||||
|
||||
Classes will be merged with the default classes, and any other attributes will override the default attributes.
|
||||
|
||||
## Global settings
|
||||
|
||||
If you wish to change the default behavior of a component globally, then you can call the static `configureUsing()` method inside a service provider's `boot()` method, to which you pass a Closure to modify the component using. For example, if you wish to make all section components have [2 columns](grid) by default, you can do it like so:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::configureUsing(function (Section $section): void {
|
||||
$section
|
||||
->columns(2);
|
||||
});
|
||||
```
|
||||
|
||||
Of course, you are still able to overwrite this on each field individually:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make()
|
||||
->columns(1)
|
||||
```
|
||||
103
vendor/filament/infolists/docs/04-layout/02-grid.md
vendored
Normal file
103
vendor/filament/infolists/docs/04-layout/02-grid.md
vendored
Normal file
@@ -0,0 +1,103 @@
|
||||
---
|
||||
title: Grid
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
Filament's grid system allows you to create responsive, multi-column layouts using any layout component.
|
||||
|
||||
## Responsively setting the number of grid columns
|
||||
|
||||
All layout components have a `columns()` method that you can use in a couple of different ways:
|
||||
|
||||
- You can pass an integer like `columns(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, `columns(['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).
|
||||
|
||||
## Controlling how many columns a component should span
|
||||
|
||||
In addition to specifying how many columns a layout component should have, you may also specify how many columns a component should fill within the parent grid, using the `columnSpan()` method. This method accepts an integer or an array of breakpoints and column spans:
|
||||
|
||||
- `columnSpan(2)` will make the component fill up to 2 columns on all breakpoints.
|
||||
- `columnSpan(['md' => 2, 'xl' => 4])` will make the component fill up to 2 columns on medium devices, and up to 4 columns on extra large devices. The default breakpoint for smaller devices uses 1 column, unless you use a `default` array key.
|
||||
- `columnSpan('full')` or `columnSpanFull()` or `columnSpan(['default' => 'full'])` will make the component fill the full width of the parent grid, regardless of how many columns it has.
|
||||
|
||||
## An example of a responsive grid layout
|
||||
|
||||
In this example, we have an infolist with a [section](section) layout component. Since all layout components support the `columns()` method, we can use it to create a responsive grid layout within the section itself.
|
||||
|
||||
We pass an array to `columns()` as we want to specify different numbers of columns for different breakpoints. On devices smaller than the `sm` [Tailwind breakpoint](https://tailwindcss.com/docs/responsive-design#overview), we want to have 1 column, which is default. On devices larger than the `sm` breakpoint, we want to have 3 columns. On devices larger than the `xl` breakpoint, we want to have 6 columns. On devices larger than the `2xl` breakpoint, we want to have 8 columns.
|
||||
|
||||
Inside the section, we have a [text entry](../entries/text). Since text entries are infolist components and all form components have a `columnSpan()` method, we can use it to specify how many columns the text entry should fill. On devices smaller than the `sm` breakpoint, we want the text entry to fill 1 column, which is default. On devices larger than the `sm` breakpoint, we want the text entry to fill 2 columns. On devices larger than the `xl` breakpoint, we want the text entry to fill 3 columns. On devices larger than the `2xl` breakpoint, we want the text entry to fill 4 columns.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
Section::make()
|
||||
->columns([
|
||||
'sm' => 3,
|
||||
'xl' => 6,
|
||||
'2xl' => 8,
|
||||
])
|
||||
->schema([
|
||||
TextEntry::make('name')
|
||||
->columnSpan([
|
||||
'sm' => 2,
|
||||
'xl' => 3,
|
||||
'2xl' => 4,
|
||||
]),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
## Grid component
|
||||
|
||||
All layout components support the `columns()` method, but you also have access to an additional `Grid` component. If you feel that your form schema would benefit from an explicit grid syntax with no extra styling, it may be useful to you. Instead of using the `columns()` method, you can pass your column configuration directly to `Grid::make()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Grid;
|
||||
|
||||
Grid::make([
|
||||
'default' => 1,
|
||||
'sm' => 2,
|
||||
'md' => 3,
|
||||
'lg' => 4,
|
||||
'xl' => 6,
|
||||
'2xl' => 8,
|
||||
])
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
## Setting the starting column of a component in a grid
|
||||
|
||||
If you want to start a component in a grid at a specific column, you can use the `columnStart()` method. This method accepts an integer, or an array of breakpoints and which column the component should start at:
|
||||
|
||||
- `columnStart(2)` will make the component start at column 2 on all breakpoints.
|
||||
- `columnStart(['md' => 2, 'xl' => 4])` will make the component start at column 2 on medium devices, and at column 4 on extra large devices. The default breakpoint for smaller devices uses 1 column, unless you use a `default` array key.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
Section::make()
|
||||
->columns([
|
||||
'sm' => 3,
|
||||
'xl' => 6,
|
||||
'2xl' => 8,
|
||||
])
|
||||
->schema([
|
||||
TextEntry::make('name')
|
||||
->columnStart([
|
||||
'sm' => 2,
|
||||
'xl' => 3,
|
||||
'2xl' => 4,
|
||||
]),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
In this example, the grid has 3 columns on small devices, 6 columns on extra large devices, and 8 columns on extra extra large devices. The text entry will start at column 2 on small devices, column 3 on extra large devices, and column 4 on extra extra large devices. This is essentially producing a layout whereby the text entry always starts halfway through the grid, regardless of how many columns the grid has.
|
||||
33
vendor/filament/infolists/docs/04-layout/03-fieldset.md
vendored
Normal file
33
vendor/filament/infolists/docs/04-layout/03-fieldset.md
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
---
|
||||
title: Fieldset
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
You may want to group entries into a Fieldset. Each fieldset has a label, a border, and a two-column grid by default:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Fieldset;
|
||||
|
||||
Fieldset::make('Label')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/fieldset/simple" alt="Fieldset" version="3.x" />
|
||||
|
||||
## Using grid columns within a fieldset
|
||||
|
||||
You may use the `columns()` method to customize the [grid](grid) within the fieldset:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Fieldset;
|
||||
|
||||
Fieldset::make('Label')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->columns(3)
|
||||
```
|
||||
240
vendor/filament/infolists/docs/04-layout/04-tabs.md
vendored
Normal file
240
vendor/filament/infolists/docs/04-layout/04-tabs.md
vendored
Normal file
@@ -0,0 +1,240 @@
|
||||
---
|
||||
title: Tabs
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Some infolists can be long and complex. You may want to use tabs to reduce the number of components that are visible at once:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Tab 1')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 2')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 3')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/tabs/simple" alt="Tabs" version="3.x" />
|
||||
|
||||
## Setting the default active tab
|
||||
|
||||
The first tab will be open by default. You can change the default open tab using the `activeTab()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Tab 1')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 2')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 3')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
])
|
||||
->activeTab(2)
|
||||
```
|
||||
|
||||
## Setting a tab icon
|
||||
|
||||
Tabs may have an [icon](https://blade-ui-kit.com/blade-icons?set=1#search), which you can set using the `icon()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Notifications')
|
||||
->icon('heroicon-m-bell')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/tabs/icons" alt="Tabs with icons" version="3.x" />
|
||||
|
||||
### Setting the tab icon position
|
||||
|
||||
The icon of the tab may be positioned before or after the label using the `iconPosition()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Notifications')
|
||||
->icon('heroicon-m-bell')
|
||||
->iconPosition(IconPosition::After)
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/tabs/icons-after" alt="Tabs with icons after their labels" version="3.x" />
|
||||
|
||||
## Setting a tab badge
|
||||
|
||||
Tabs may have a badge, which you can set using the `badge()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Notifications')
|
||||
->badge(5)
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/tabs/badges" alt="Tabs with badges" version="3.x" />
|
||||
|
||||
If you'd like to change the color for a badge, you can use the `badgeColor()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Notifications')
|
||||
->badge(5)
|
||||
->badgeColor('success')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
## Using grid columns within a tab
|
||||
|
||||
You may use the `columns()` method to customize the [grid](grid) within the tab:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Tab 1')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->columns(3),
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
## Removing the styled container
|
||||
|
||||
By default, tabs and their content are wrapped in a container styled as a card. You may remove the styled container using `contained()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Tab 1')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 2')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 3')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
])
|
||||
->contained(false)
|
||||
```
|
||||
|
||||
## Persisting the current tab
|
||||
|
||||
By default, the current tab is not persisted in the browser's local storage. You can change this behavior using the `persistTab()` method. You must also pass in a unique `id()` for the tabs component, to distinguish it from all other sets of tabs in the app. This ID will be used as the key in the local storage to store the current tab:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
// ...
|
||||
])
|
||||
->persistTab()
|
||||
->id('order-tabs')
|
||||
```
|
||||
|
||||
### Persisting the current tab in the URL's query string
|
||||
|
||||
By default, the current tab is not persisted in the URL's query string. You can change this behavior using the `persistTabInQueryString()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Tab 1')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 2')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 3')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
])
|
||||
->persistTabInQueryString()
|
||||
```
|
||||
|
||||
By default, the current tab is persisted in the URL's query string using the `tab` key. You can change this key by passing it to the `persistTabInQueryString()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Tabs;
|
||||
|
||||
Tabs::make('Tabs')
|
||||
->tabs([
|
||||
Tabs\Tab::make('Tab 1')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 2')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
Tabs\Tab::make('Tab 3')
|
||||
->schema([
|
||||
// ...
|
||||
]),
|
||||
])
|
||||
->persistTabInQueryString('settings-tab')
|
||||
```
|
||||
250
vendor/filament/infolists/docs/04-layout/05-section.md
vendored
Normal file
250
vendor/filament/infolists/docs/04-layout/05-section.md
vendored
Normal file
@@ -0,0 +1,250 @@
|
||||
---
|
||||
title: Section
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
You may want to separate your entries into sections, each with a heading and description. To do this, you can use a section component:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Rate limiting')
|
||||
->description('Prevent abuse by limiting the number of requests per period')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/simple" alt="Section" version="3.x" />
|
||||
|
||||
You can also use a section without a header, which just wraps the components in a simple card:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make()
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/without-header" alt="Section without header" version="3.x" />
|
||||
|
||||
## Adding actions to the section's header or footer
|
||||
|
||||
Sections can have actions in their [header](#adding-actions-to-the-sections-header) or [footer](#adding-actions-to-the-sections-footer).
|
||||
|
||||
### Adding actions to the section's header
|
||||
|
||||
You may add [actions](../actions) to the section's header using the `headerActions()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Rate limiting')
|
||||
->headerActions([
|
||||
Action::make('edit')
|
||||
->action(function () {
|
||||
// ...
|
||||
}),
|
||||
])
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/header/actions" alt="Section with header actions" version="3.x" />
|
||||
|
||||
> [Make sure the section has a heading or ID](#adding-actions-to-a-section-without-heading)
|
||||
|
||||
### Adding actions to the section's footer
|
||||
|
||||
In addition to [header actions](#adding-an-icon-to-the-sections-header), you may add [actions](../actions) to the section's footer using the `footerActions()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Rate limiting')
|
||||
->footerActions([
|
||||
Action::make('edit')
|
||||
->action(function () {
|
||||
// ...
|
||||
}),
|
||||
])
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/footer/actions" alt="Section with footer actions" version="3.x" />
|
||||
|
||||
> [Make sure the section has a heading or ID](#adding-actions-to-a-section-without-heading)
|
||||
|
||||
#### Aligning section footer actions
|
||||
|
||||
Footer actions are aligned to the inline start by default. You may customize the alignment using the `footerActionsAlignment()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
Section::make('Rate limiting')
|
||||
->footerActions([
|
||||
Action::make('edit')
|
||||
->action(function () {
|
||||
// ...
|
||||
}),
|
||||
])
|
||||
->footerActionsAlignment(Alignment::End)
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
### Adding actions to a section without heading
|
||||
|
||||
If your section does not have a heading, Filament has no way of locating the action inside it. In this case, you must pass a unique `id()` to the section:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make()
|
||||
->id('rateLimitingSection')
|
||||
->headerActions([
|
||||
// ...
|
||||
])
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
## Adding an icon to the section's header
|
||||
|
||||
You may add an icon to the section's header using the `icon()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Cart')
|
||||
->description('The items you have selected for purchase')
|
||||
->icon('heroicon-m-shopping-bag')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/icons" alt="Section with icon" version="3.x" />
|
||||
|
||||
## Positioning the heading and description aside
|
||||
|
||||
You may use the `aside()` method to align the heading and description on the left, and the infolist components inside a card on the right:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Rate limiting')
|
||||
->description('Prevent abuse by limiting the number of requests per period')
|
||||
->aside()
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/aside" alt="Section with heading and description aside" version="3.x" />
|
||||
|
||||
## Collapsing sections
|
||||
|
||||
Sections may be `collapsible()` to optionally hide content in long infolists:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Cart')
|
||||
->description('The items you have selected for purchase')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->collapsible()
|
||||
```
|
||||
|
||||
Your sections may be `collapsed()` by default:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Cart')
|
||||
->description('The items you have selected for purchase')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->collapsed()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/collapsed" alt="Collapsed section" version="3.x" />
|
||||
|
||||
### Persisting collapsed sections
|
||||
|
||||
You can persist whether a section is collapsed in local storage using the `persistCollapsed()` method, so it will remain collapsed when the user refreshes the page:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Cart')
|
||||
->description('The items you have selected for purchase')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->collapsible()
|
||||
->persistCollapsed()
|
||||
```
|
||||
|
||||
To persist the collapse state, the local storage needs a unique ID to store the state. This ID is generated based on the heading of the section. If your section does not have a heading, or if you have multiple sections with the same heading that you do not want to collapse together, you can manually specify the `id()` of that section to prevent an ID conflict:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Cart')
|
||||
->description('The items you have selected for purchase')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->collapsible()
|
||||
->persistCollapsed()
|
||||
->id('order-cart')
|
||||
```
|
||||
|
||||
## Compact section styling
|
||||
|
||||
When nesting sections, you can use a more compact styling:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Rate limiting')
|
||||
->description('Prevent abuse by limiting the number of requests per period')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->compact()
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/section/compact" alt="Compact section" version="3.x" />
|
||||
|
||||
## Using grid columns within a section
|
||||
|
||||
You may use the `columns()` method to easily create a [grid](grid) within the section:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
|
||||
Section::make('Heading')
|
||||
->schema([
|
||||
// ...
|
||||
])
|
||||
->columns(2)
|
||||
```
|
||||
37
vendor/filament/infolists/docs/04-layout/06-split.md
vendored
Normal file
37
vendor/filament/infolists/docs/04-layout/06-split.md
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
---
|
||||
title: Split
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
The `Split` component allows you to define layouts with flexible widths, using flexbox.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Section;
|
||||
use Filament\Infolists\Components\Split;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
|
||||
Split::make([
|
||||
Section::make([
|
||||
TextEntry::make('title')
|
||||
->weight(FontWeight::Bold),
|
||||
TextEntry::make('content')
|
||||
->markdown()
|
||||
->prose(),
|
||||
]),
|
||||
Section::make([
|
||||
TextEntry::make('created_at')
|
||||
->dateTime(),
|
||||
TextEntry::make('published_at')
|
||||
->dateTime(),
|
||||
])->grow(false),
|
||||
])->from('md')
|
||||
```
|
||||
|
||||
In this example, the first section will `grow()` to consume available horizontal space, without affecting the amount of space needed to render the second section. This creates a sidebar effect.
|
||||
|
||||
The `from()` method is used to control the [Tailwind breakpoint](https://tailwindcss.com/docs/responsive-design#overview) (`sm`, `md`, `lg`, `xl`, `2xl`) at which the split layout should be used. In this example, the split layout will be used on medium devices and larger. On smaller devices, the sections will stack on top of each other.
|
||||
|
||||
<AutoScreenshot name="infolists/layout/split/simple" alt="Split" version="3.x" />
|
||||
73
vendor/filament/infolists/docs/04-layout/07-custom.md
vendored
Normal file
73
vendor/filament/infolists/docs/04-layout/07-custom.md
vendored
Normal file
@@ -0,0 +1,73 @@
|
||||
---
|
||||
title: Custom layouts
|
||||
---
|
||||
import LaracastsBanner from "@components/LaracastsBanner.astro"
|
||||
|
||||
<LaracastsBanner
|
||||
title="Build a Custom Infolist Layout"
|
||||
description="Watch the Build Advanced Components for Filament series on Laracasts - it will teach you how to build components, and you'll get to know all the internal tools to help you."
|
||||
url="https://laracasts.com/series/build-advanced-components-for-filament/episodes/9"
|
||||
series="building-advanced-components"
|
||||
/>
|
||||
|
||||
## View components
|
||||
|
||||
Aside from [building custom layout components](#custom-layout-classes), you may create "view" components which allow you to create custom layouts without extra PHP classes.
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\View;
|
||||
|
||||
View::make('filament.infolists.components.box')
|
||||
```
|
||||
|
||||
This assumes that you have a `resources/views/filament/infolists/components/box.blade.php` file.
|
||||
|
||||
## Custom layout classes
|
||||
|
||||
You may create your own custom component classes and views, which you can reuse across your project, and even release as a plugin to the community.
|
||||
|
||||
> If you're just creating a simple custom component to use once, you could instead use a [view component](#view) to render any custom Blade file.
|
||||
|
||||
To create a custom column class and view, you may use the following command:
|
||||
|
||||
```bash
|
||||
php artisan make:infolist-layout Box
|
||||
```
|
||||
|
||||
This will create the following layout component class:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Component;
|
||||
|
||||
class Box extends Component
|
||||
{
|
||||
protected string $view = 'filament.infolists.components.box';
|
||||
|
||||
public static function make(): static
|
||||
{
|
||||
return app(static::class);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
It will also create a view file at `resources/views/filament/infolists/components/box.blade.php`.
|
||||
|
||||
## Rendering the component's schema
|
||||
|
||||
Inside your view, you may render the component's `schema()` using the `$getChildComponentContainer()` function:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
```
|
||||
|
||||
## Accessing the Eloquent record
|
||||
|
||||
Inside your view, you may access the Eloquent record using the `$getRecord()` function:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
{{ $getRecord()->name }}
|
||||
</div>
|
||||
```
|
||||
224
vendor/filament/infolists/docs/05-actions.md
vendored
Normal file
224
vendor/filament/infolists/docs/05-actions.md
vendored
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
title: Actions
|
||||
---
|
||||
import AutoScreenshot from "@components/AutoScreenshot.astro"
|
||||
|
||||
## Overview
|
||||
|
||||
Filament's infolists can use [Actions](../actions). They are buttons that can be added to any infolist component. Also, you can [render anonymous sets of actions](#adding-anonymous-actions-to-an-infolist-without-attaching-them-to-a-component) on their own, that are not attached to a particular infolist component.
|
||||
|
||||
## Defining a infolist component action
|
||||
|
||||
Action objects inside an infolist component are instances of `Filament/Infolists/Components/Actions/Action`. You must pass a unique name to the action's `make()` method, which is used to identify it amongst others internally within Filament. You can [customize the trigger button](../actions/trigger-button) of an action, and even [open a modal](../actions/modals) with little effort:
|
||||
|
||||
```php
|
||||
use App\Actions\ResetStars;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
|
||||
Action::make('resetStars')
|
||||
->icon('heroicon-m-x-mark')
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->action(function (ResetStars $resetStars) {
|
||||
$resetStars();
|
||||
})
|
||||
```
|
||||
|
||||
### Adding an affix action to a entry
|
||||
|
||||
Certain entries support "affix actions", which are buttons that can be placed before or after its content. The following entries support affix actions:
|
||||
|
||||
- [Text entry](entries/text-entry)
|
||||
|
||||
To define an affix action, you can pass it to either `prefixAction()` or `suffixAction()`:
|
||||
|
||||
```php
|
||||
use App\Models\Product;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('cost')
|
||||
->prefix('€')
|
||||
->suffixAction(
|
||||
Action::make('copyCostToPrice')
|
||||
->icon('heroicon-m-clipboard')
|
||||
->requiresConfirmation()
|
||||
->action(function (Product $record) {
|
||||
$record->price = $record->cost;
|
||||
$record->save();
|
||||
})
|
||||
)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/actions/suffix" alt="Text entry with suffix action" version="3.x" />
|
||||
|
||||
#### Passing multiple affix actions to a entry
|
||||
|
||||
You may pass multiple affix actions to an entry by passing them in an array to either `prefixActions()` or `suffixActions()`. Either method can be used, or both at once, Filament will render all the registered actions in order:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('cost')
|
||||
->prefix('€')
|
||||
->prefixActions([
|
||||
Action::make('...'),
|
||||
Action::make('...'),
|
||||
Action::make('...'),
|
||||
])
|
||||
->suffixActions([
|
||||
Action::make('...'),
|
||||
Action::make('...'),
|
||||
])
|
||||
```
|
||||
|
||||
### Adding a hint action to an entry
|
||||
|
||||
All entries support "hint actions", which are rendered aside the entry's [hint](entries/getting-started#adding-a-hint-next-to-the-label). To add a hint action to a entry, you may pass it to `hintAction()`:
|
||||
|
||||
```php
|
||||
use App\Models\Product;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('cost')
|
||||
->prefix('€')
|
||||
->hintAction(
|
||||
Action::make('copyCostToPrice')
|
||||
->icon('heroicon-m-clipboard')
|
||||
->requiresConfirmation()
|
||||
->action(function (Product $record) {
|
||||
$record->price = $record->cost;
|
||||
$record->save();
|
||||
})
|
||||
)
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/actions/hint" alt="Text entry with hint action" version="3.x" />
|
||||
|
||||
#### Passing multiple hint actions to a entry
|
||||
|
||||
You may pass multiple hint actions to a entry by passing them in an array to `hintActions()`. Filament will render all the registered actions in order:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
TextEntry::make('cost')
|
||||
->prefix('€')
|
||||
->hintActions([
|
||||
Action::make('...'),
|
||||
Action::make('...'),
|
||||
Action::make('...'),
|
||||
])
|
||||
```
|
||||
|
||||
### Adding an action to a custom infolist component
|
||||
|
||||
If you wish to render an action within a custom infolist component, `ViewEntry` object, or `View` component object, you may do so using the `registerActions()` method:
|
||||
|
||||
```php
|
||||
use App\Models\Post;
|
||||
use Filament\Forms\Components\TextInput;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Infolists\Components\ViewEntry;
|
||||
use Filament\Infolists\Set;
|
||||
|
||||
ViewEntry::make('status')
|
||||
->view('filament.infolists.entries.status-switcher')
|
||||
->registerActions([
|
||||
Action::make('createStatus')
|
||||
->form([
|
||||
TextInput::make('name')
|
||||
->required(),
|
||||
])
|
||||
->icon('heroicon-m-plus')
|
||||
->action(function (array $data, Post $record) {
|
||||
$record->status()->create($data);
|
||||
}),
|
||||
])
|
||||
```
|
||||
|
||||
Now, to render the action in the view of the custom component, you need to call `$getAction()`, passing the name of the action you registered:
|
||||
|
||||
```blade
|
||||
<div>
|
||||
<select></select>
|
||||
|
||||
{{ $getAction('createStatus') }}
|
||||
</div>
|
||||
```
|
||||
|
||||
### Adding "anonymous" actions to an infolist without attaching them to a component
|
||||
|
||||
You may use an `Actions` component to render a set of actions anywhere in the form, avoiding the need to register them to any particular component:
|
||||
|
||||
```php
|
||||
use App\Actions\Star;
|
||||
use App\Actions\ResetStars;
|
||||
use Filament\Infolists\Components\Actions;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
|
||||
Actions::make([
|
||||
Action::make('star')
|
||||
->icon('heroicon-m-star')
|
||||
->requiresConfirmation()
|
||||
->action(function (Star $star) {
|
||||
$star();
|
||||
}),
|
||||
Action::make('resetStars')
|
||||
->icon('heroicon-m-x-mark')
|
||||
->color('danger')
|
||||
->requiresConfirmation()
|
||||
->action(function (ResetStars $resetStars) {
|
||||
$resetStars();
|
||||
}),
|
||||
]),
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/actions/anonymous/simple" alt="Anonymous actions" version="3.x" />
|
||||
|
||||
#### Making the independent infolist actions consume the full width of the infolist
|
||||
|
||||
You can stretch the independent infolist actions to consume the full width of the infolist using `fullWidth()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions;
|
||||
|
||||
Actions::make([
|
||||
// ...
|
||||
])->fullWidth(),
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/actions/anonymous/full-width" alt="Anonymous actions consuming the full width" version="3.x" />
|
||||
|
||||
#### Controlling the horizontal alignment of independent infolist actions
|
||||
|
||||
Independent infolist actions are aligned to the start of the component by default. You may change this by passing `Alignment::Center` or `Alignment::End` to `alignment()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
Actions::make([
|
||||
// ...
|
||||
])->alignment(Alignment::Center),
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/actions/anonymous/horizontally-aligned-center" alt="Anonymous actions horizontally aligned to the center" version="3.x" />
|
||||
|
||||
#### Controlling the vertical alignment of independent infolist actions
|
||||
|
||||
Independent infolist actions are vertically aligned to the start of the component by default. You may change this by passing `Alignment::Center` or `Alignment::End` to `verticalAlignment()`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Actions;
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
|
||||
Actions::make([
|
||||
// ...
|
||||
])->verticalAlignment(VerticalAlignment::End),
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/layout/actions/anonymous/vertically-aligned-end" alt="Anonymous actions vertically aligned to the end" version="3.x" />
|
||||
93
vendor/filament/infolists/docs/06-advanced.md
vendored
Normal file
93
vendor/filament/infolists/docs/06-advanced.md
vendored
Normal file
@@ -0,0 +1,93 @@
|
||||
---
|
||||
title: Advanced infolists
|
||||
---
|
||||
|
||||
## Inserting Livewire components into an infolist
|
||||
|
||||
You may insert a Livewire component directly into an infolist:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Livewire;
|
||||
use App\Livewire\Foo;
|
||||
|
||||
Livewire::make(Foo::class)
|
||||
```
|
||||
|
||||
If you are rendering multiple of the same Livewire component, please make sure to pass a unique `key()` to each:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Livewire;
|
||||
use App\Livewire\Foo;
|
||||
|
||||
Livewire::make(Foo::class)
|
||||
->key('foo-first')
|
||||
|
||||
Livewire::make(Foo::class)
|
||||
->key('foo-second')
|
||||
|
||||
Livewire::make(Foo::class)
|
||||
->key('foo-third')
|
||||
```
|
||||
|
||||
### Passing parameters to a Livewire component
|
||||
|
||||
You can pass an array of parameters to a Livewire component:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Livewire;
|
||||
use App\Livewire\Foo;
|
||||
|
||||
Livewire::make(Foo::class, ['bar' => 'baz'])
|
||||
```
|
||||
|
||||
Now, those parameters will be passed to the Livewire component's `mount()` method:
|
||||
|
||||
```php
|
||||
class Foo extends Component
|
||||
{
|
||||
public function mount(string $bar): void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, they will be available as public properties on the Livewire component:
|
||||
|
||||
```php
|
||||
class Foo extends Component
|
||||
{
|
||||
public string $bar;
|
||||
}
|
||||
```
|
||||
|
||||
#### Accessing the current record in the Livewire component
|
||||
|
||||
You can access the current record in the Livewire component using the `$record` parameter in the `mount()` method, or the `$record` property:
|
||||
|
||||
```php
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Foo extends Component
|
||||
{
|
||||
public function mount(Model $record): void
|
||||
{
|
||||
// ...
|
||||
}
|
||||
|
||||
// or
|
||||
|
||||
public Model $record;
|
||||
}
|
||||
```
|
||||
|
||||
### Lazy loading a Livewire component
|
||||
|
||||
You may allow the component to [lazily load](https://livewire.laravel.com/docs/lazy#rendering-placeholder-html) using the `lazy()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\Livewire;
|
||||
use App\Livewire\Foo;
|
||||
|
||||
Livewire::make(Foo::class)->lazy()
|
||||
```
|
||||
113
vendor/filament/infolists/docs/07-adding-an-infolist-to-a-livewire-component.md
vendored
Normal file
113
vendor/filament/infolists/docs/07-adding-an-infolist-to-a-livewire-component.md
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
---
|
||||
title: Adding an infolist to a Livewire component
|
||||
---
|
||||
|
||||
## Setting up the Livewire component
|
||||
|
||||
First, generate a new Livewire component:
|
||||
|
||||
```bash
|
||||
php artisan make:livewire ViewProduct
|
||||
```
|
||||
|
||||
Then, render your Livewire component on the page:
|
||||
|
||||
```blade
|
||||
@livewire('view-product')
|
||||
```
|
||||
|
||||
Alternatively, you can use a full-page Livewire component:
|
||||
|
||||
```php
|
||||
use App\Livewire\ViewProduct;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
Route::get('products/{product}', ViewProduct::class);
|
||||
```
|
||||
|
||||
You must use the `InteractsWithInfolists` and `InteractsWithForms` traits, and implement the `HasInfolists` and `HasForms` interfaces on your Livewire component class:
|
||||
|
||||
```php
|
||||
use Filament\Forms\Concerns\InteractsWithForms;
|
||||
use Filament\Forms\Contracts\HasForms;
|
||||
use Filament\Infolists\Concerns\InteractsWithInfolists;
|
||||
use Filament\Infolists\Contracts\HasInfolists;
|
||||
use Livewire\Component;
|
||||
|
||||
class ViewProduct extends Component implements HasForms, HasInfolists
|
||||
{
|
||||
use InteractsWithInfolists;
|
||||
use InteractsWithForms;
|
||||
|
||||
// ...
|
||||
}
|
||||
```
|
||||
|
||||
## Adding the infolist
|
||||
|
||||
Next, add a method to the Livewire component which accepts an `$infolist` object, modifies it, and returns it:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Infolist;
|
||||
|
||||
public function productInfolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->record($this->product)
|
||||
->schema([
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Finally, render the infolist in the Livewire component's view:
|
||||
|
||||
```blade
|
||||
{{ $this->productInfolist }}
|
||||
```
|
||||
|
||||
## Passing data to the infolist
|
||||
|
||||
You can pass data to the infolist in two ways:
|
||||
|
||||
Either pass an Eloquent model instance to the `record()` method of the infolist, to automatically map all the model attributes and relationships to the entries in the infolist's schema:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Infolist;
|
||||
|
||||
public function productInfolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->record($this->product)
|
||||
->schema([
|
||||
TextEntry::make('name'),
|
||||
TextEntry::make('category.name'),
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
|
||||
Alternatively, you can pass an array of data to the `state()` method of the infolist, to manually map the data to the entries in the infolist's schema:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Infolist;
|
||||
|
||||
public function productInfolist(Infolist $infolist): Infolist
|
||||
{
|
||||
return $infolist
|
||||
->state([
|
||||
'name' => 'MacBook Pro',
|
||||
'category' => [
|
||||
'name' => 'Laptops',
|
||||
],
|
||||
// ...
|
||||
])
|
||||
->schema([
|
||||
TextEntry::make('name'),
|
||||
TextEntry::make('category.name'),
|
||||
// ...
|
||||
]);
|
||||
}
|
||||
```
|
||||
270
vendor/filament/infolists/docs/08-testing.md
vendored
Normal file
270
vendor/filament/infolists/docs/08-testing.md
vendored
Normal file
@@ -0,0 +1,270 @@
|
||||
---
|
||||
title: Testing
|
||||
---
|
||||
|
||||
## Overview
|
||||
|
||||
All examples in this guide will be written using [Pest](https://pestphp.com). To use Pest's Livewire plugin for testing, you can follow the installation instructions in the Pest documentation on plugins: [Livewire plugin for Pest](https://pestphp.com/docs/plugins#livewire). However, you can easily adapt this to PHPUnit.
|
||||
|
||||
Since the Infolist Builder works on Livewire components, you can use the [Livewire testing helpers](https://livewire.laravel.com/docs/testing). However, we have custom testing helpers that you can use with infolists:
|
||||
|
||||
## Actions
|
||||
|
||||
You can call an action by passing its infolist component key, and then the name of the action to `callInfolistAction()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can send invoices', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->callInfolistAction('customer', 'send', infolistName: 'infolist');
|
||||
|
||||
expect($invoice->refresh())
|
||||
->isSent()->toBeTrue();
|
||||
});
|
||||
```
|
||||
|
||||
To pass an array of data into an action, use the `data` parameter:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can send invoices', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->callInfolistAction('customer', 'send', data: [
|
||||
'email' => $email = fake()->email(),
|
||||
])
|
||||
->assertHasNoInfolistActionErrors();
|
||||
|
||||
expect($invoice->refresh())
|
||||
->isSent()->toBeTrue()
|
||||
->recipient_email->toBe($email);
|
||||
});
|
||||
```
|
||||
|
||||
If you ever need to only set an action's data without immediately calling it, you can use `setInfolistActionData()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can send invoices', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->mountInfolistAction('customer', 'send')
|
||||
->setInfolistActionData('customer', 'send', data: [
|
||||
'email' => $email = fake()->email(),
|
||||
])
|
||||
});
|
||||
```
|
||||
|
||||
### Execution
|
||||
|
||||
To check if an action has been halted, you can use `assertInfolistActionHalted()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('stops sending if invoice has no email address', function () {
|
||||
$invoice = Invoice::factory(['email' => null])->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->callInfolistAction('customer', 'send')
|
||||
->assertInfolistActionHalted('customer', 'send');
|
||||
});
|
||||
```
|
||||
|
||||
### Errors
|
||||
|
||||
`assertHasNoInfolistActionErrors()` is used to assert that no validation errors occurred when submitting the action form.
|
||||
|
||||
To check if a validation error has occurred with the data, use `assertHasInfolistActionErrors()`, similar to `assertHasErrors()` in Livewire:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can validate invoice recipient email', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->callInfolistAction('customer', 'send', data: [
|
||||
'email' => Str::random(),
|
||||
])
|
||||
->assertHasInfolistActionErrors(['email' => ['email']]);
|
||||
});
|
||||
```
|
||||
|
||||
To check if an action is pre-filled with data, you can use the `assertInfolistActionDataSet()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can send invoices to the primary contact by default', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
$recipientEmail = $invoice->company->primaryContact->email;
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->mountInfolistAction('customer', 'send')
|
||||
->assertInfolistActionDataSet([
|
||||
'email' => $recipientEmail,
|
||||
])
|
||||
->callMountedInfolistAction()
|
||||
->assertHasNoInfolistActionErrors();
|
||||
|
||||
expect($invoice->refresh())
|
||||
->isSent()->toBeTrue()
|
||||
->recipient_email->toBe($recipientEmail);
|
||||
});
|
||||
```
|
||||
|
||||
### Action state
|
||||
|
||||
To ensure that an action exists or doesn't in an infolist, you can use the `assertInfolistActionExists()` or `assertInfolistActionDoesNotExist()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can send but not unsend invoices', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionExists('customer', 'send')
|
||||
->assertInfolistActionDoesNotExist('customer', 'unsend');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure an action is hidden or visible for a user, you can use the `assertInfolistActionHidden()` or `assertInfolistActionVisible()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can only print customers', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionHidden('customer', 'send')
|
||||
->assertInfolistActionVisible('customer', 'print');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure an action is enabled or disabled for a user, you can use the `assertInfolistActionEnabled()` or `assertInfolistActionDisabled()` methods:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can only print a customer for a sent invoice', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionDisabled('customer', 'send')
|
||||
->assertInfolistActionEnabled('customer', 'print');
|
||||
});
|
||||
```
|
||||
|
||||
To check if an action is hidden to a user, you can use the `assertInfolistActionHidden()` method:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('can not send invoices', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionHidden('customer', 'send');
|
||||
});
|
||||
```
|
||||
|
||||
### Button appearance
|
||||
|
||||
To ensure an action has the correct label, you can use `assertInfolistActionHasLabel()` and `assertInfolistActionDoesNotHaveLabel()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('send action has correct label', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionHasLabel('customer', 'send', 'Email Invoice')
|
||||
->assertInfolistActionDoesNotHaveLabel('customer', 'send', 'Send');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure an action's button is showing the correct icon, you can use `assertInfolistActionHasIcon()` or `assertInfolistActionDoesNotHaveIcon()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('when enabled the send button has correct icon', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionEnabled('customer', 'send')
|
||||
->assertInfolistActionHasIcon('customer', 'send', 'envelope-open')
|
||||
->assertInfolistActionDoesNotHaveIcon('customer', 'send', 'envelope');
|
||||
});
|
||||
```
|
||||
|
||||
To ensure that an action's button is displaying the right color, you can use `assertInfolistActionHasColor()` or `assertInfolistActionDoesNotHaveColor()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('actions display proper colors', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionHasColor('customer', 'delete', 'danger')
|
||||
->assertInfolistActionDoesNotHaveColor('customer', 'print', 'danger');
|
||||
});
|
||||
```
|
||||
|
||||
### URL
|
||||
|
||||
To ensure an action has the correct URL, you can use `assertInfolistActionHasUrl()`, `assertInfolistActionDoesNotHaveUrl()`, `assertInfolistActionShouldOpenUrlInNewTab()`, and `assertInfolistActionShouldNotOpenUrlInNewTab()`:
|
||||
|
||||
```php
|
||||
use function Pest\Livewire\livewire;
|
||||
|
||||
it('links to the correct Filament sites', function () {
|
||||
$invoice = Invoice::factory()->create();
|
||||
|
||||
livewire(EditInvoice::class, [
|
||||
'invoice' => $invoice,
|
||||
])
|
||||
->assertInfolistActionHasUrl('customer', 'filament', 'https://filamentphp.com/')
|
||||
->assertInfolistActionDoesNotHaveUrl('customer', 'filament', 'https://github.com/filamentphp/filament')
|
||||
->assertInfolistActionShouldOpenUrlInNewTab('customer', 'filament')
|
||||
->assertInfolistActionShouldNotOpenUrlInNewTab('customer', 'github');
|
||||
});
|
||||
```
|
||||
38
vendor/filament/infolists/resources/lang/ar/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/ar/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'عرض :count أقل',
|
||||
'expand_list' => 'عرض :count أكثر',
|
||||
],
|
||||
|
||||
'more_list_items' => 'و :count إضافية',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'المفتاح',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'القيمة',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'لا توجد مدخلات',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/az/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/az/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 'və :count daha',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/bg/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/bg/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Покажи :count по-малко',
|
||||
'expand_list' => 'Покажи още :count',
|
||||
],
|
||||
|
||||
'more_list_items' => 'и още :count',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Ключ',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Стойност',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Няма записи',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/ca/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/ca/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Mostrar-ne :count menys',
|
||||
'expand_list' => 'Mostrar-ne :count més',
|
||||
],
|
||||
|
||||
'more_list_items' => 'i :count més',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Clau',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Valor',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'No hi ha entrades',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/ckb/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/ckb/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 'وە :count ی زیاتر',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/da/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/da/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Vis :count mindre',
|
||||
'expand_list' => 'Vis :count flere',
|
||||
],
|
||||
|
||||
'more_list_items' => 'og :count flere',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Nøgle',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Værdi',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Ingen data',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/de/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/de/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Zeige :count weniger',
|
||||
'expand_list' => 'Zeige :count weitere',
|
||||
],
|
||||
|
||||
'more_list_items' => 'und :count mehr',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Schlüssel',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Wert',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Keine Einträge',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/en/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/en/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Show :count less',
|
||||
'expand_list' => 'Show :count more',
|
||||
],
|
||||
|
||||
'more_list_items' => 'and :count more',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Key',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Value',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'No entries',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/es/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/es/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Mostrar :count menos',
|
||||
'expand_list' => 'Mostrar :count más',
|
||||
],
|
||||
|
||||
'more_list_items' => 'y :count más',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Clave',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Valor',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'No hay entradas',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/fa/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/fa/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 'و :count عدد دیگر',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/fi/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/fi/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Näytä :count vähemmän',
|
||||
'expand_list' => 'Näytä :count lisää',
|
||||
],
|
||||
|
||||
'more_list_items' => 'ja :count lisää',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Avain',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Arvo',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Ei tietueita',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/fr/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/fr/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Afficher :count de moins',
|
||||
'expand_list' => 'Afficher :count de plus',
|
||||
],
|
||||
|
||||
'more_list_items' => 'et :count de plus',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Clé',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Valeur',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Aucune entrée',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/hr/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/hr/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 'i :count još',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/hu/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/hu/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => ':count elemmel kevesebb mutatása',
|
||||
'expand_list' => ':count elemmel több mutatása',
|
||||
],
|
||||
|
||||
'more_list_items' => ':count és több',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Kulcs',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Érték',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Nincs megjeleníthető elem',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/ja/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/ja/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => ':count件非表示',
|
||||
'expand_list' => ':count件表示',
|
||||
],
|
||||
|
||||
'more_list_items' => 'あと:count件あります',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'キー',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => '値',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'エントリがありません',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/km/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/km/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'បង្ហាញ :count តិច',
|
||||
'expand_list' => 'បង្ហាញ :count ច្រើនទៀត',
|
||||
],
|
||||
|
||||
'more_list_items' => 'និង :count ច្រើនទៀត',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'សោ',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'តម្លៃ',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'គ្មានទិន្ន័យទេ',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/ko/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/ko/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => ':count 개 더 접기',
|
||||
'expand_list' => ':count 개 더 펼치기',
|
||||
],
|
||||
|
||||
'more_list_items' => '그리고 :count 개 더',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => '키',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => '값',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => '항목 없음',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/ku/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/ku/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 'وە :count ی زیاتر',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/lt/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/lt/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Rodyti dar :count',
|
||||
'expand_list' => 'Slėpti :count',
|
||||
],
|
||||
|
||||
'more_list_items' => 'ir dar :count',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Raktas',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Reikšmė',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Nėra įrašų',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/nl/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/nl/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => ':count minder tonen',
|
||||
'expand_list' => ':count meer tonen',
|
||||
],
|
||||
|
||||
'more_list_items' => 'en :count meer',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Sleutel',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Waarde',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Geen gegevens',
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/no/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/no/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Vis :count mindre',
|
||||
'expand_list' => 'Vis :count til',
|
||||
],
|
||||
|
||||
'more_list_items' => 'og :count til',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Nøkkel',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Verdi',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Ingen oppføringer',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/np/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/np/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 'र :count थप वस्तुहरू छन्',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/pt_BR/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/pt_BR/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Mostrar menos :count',
|
||||
'expand_list' => 'Mostrar mais :count',
|
||||
],
|
||||
|
||||
'more_list_items' => 'e mais :count',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Chave',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Valor',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Sem dados',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/pt_PT/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/pt_PT/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Mostrar menos :count',
|
||||
'expand_list' => 'Mostrar mais :count',
|
||||
],
|
||||
|
||||
'more_list_items' => 'e mais :count',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Chave',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Valor',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Sem dados',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/ru/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/ru/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Скрыть :count',
|
||||
'expand_list' => 'Показать еще :count',
|
||||
],
|
||||
|
||||
'more_list_items' => 'и еще :count',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Ключ',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Значение',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Нет записей',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/sk/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/sk/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Zobraziť o :count menej',
|
||||
'expand_list' => 'Zobraziť o :count viac',
|
||||
],
|
||||
|
||||
'more_list_items' => 'a o :count viac',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Kľúč',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Hodnota',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Žiadne záznamy',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/sv/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/sv/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Visa :count färre',
|
||||
'expand_list' => 'Visa :count till',
|
||||
],
|
||||
|
||||
'more_list_items' => 'och :count till',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Namn',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Värde',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Inga objekt',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/th/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/th/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'แสดงให้น้อยกว่านี้ :count รายการ',
|
||||
'expand_list' => 'แสดงอีก :count รายการ',
|
||||
],
|
||||
|
||||
'more_list_items' => 'และอีก :count รายการ',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'คีย์',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'ค่า',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'ไม่มีรายการ',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/tr/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/tr/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => 've :count daha',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/uk/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/uk/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Сховати :count',
|
||||
'expand_list' => 'Показати ще :count',
|
||||
],
|
||||
|
||||
'more_list_items' => 'ще :count',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Ключ',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Значення',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Немає записів',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/uz/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/uz/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => ':countta kam ko\'rsatish',
|
||||
'expand_list' => 'Yana :counttasini k\'rsatish',
|
||||
],
|
||||
|
||||
'more_list_items' => 'va yana :countta',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Kalit so\'zi',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Qiymati',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Ma\'lumot yo\'q',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/vi/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/vi/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => 'Hiển thị :count ít hơn',
|
||||
'expand_list' => 'Hiển thị :count thêm',
|
||||
],
|
||||
|
||||
'more_list_items' => 'và :count thêm',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => 'Khóa',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => 'Giá trị',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => 'Không có mục',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
9
vendor/filament/infolists/resources/lang/zh_CN/components.php
vendored
Normal file
9
vendor/filament/infolists/resources/lang/zh_CN/components.php
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'text_entry' => [
|
||||
'more_list_items' => '还有 :count 条记录',
|
||||
],
|
||||
|
||||
];
|
||||
38
vendor/filament/infolists/resources/lang/zh_TW/components.php
vendored
Normal file
38
vendor/filament/infolists/resources/lang/zh_TW/components.php
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
'entries' => [
|
||||
|
||||
'text' => [
|
||||
|
||||
'actions' => [
|
||||
'collapse_list' => '少顯示 :count 筆',
|
||||
'expand_list' => '多顯示 :count 筆',
|
||||
],
|
||||
|
||||
'more_list_items' => '多 :count 筆',
|
||||
|
||||
],
|
||||
|
||||
'key_value' => [
|
||||
|
||||
'columns' => [
|
||||
|
||||
'key' => [
|
||||
'label' => '索引',
|
||||
],
|
||||
|
||||
'value' => [
|
||||
'label' => '值',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
'placeholder' => '無項目',
|
||||
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
];
|
||||
53
vendor/filament/infolists/resources/views/component-container.blade.php
vendored
Normal file
53
vendor/filament/infolists/resources/views/component-container.blade.php
vendored
Normal file
@@ -0,0 +1,53 @@
|
||||
@php
|
||||
use Filament\Support\Enums\MaxWidth;
|
||||
@endphp
|
||||
|
||||
<dl>
|
||||
<x-filament::grid
|
||||
:default="$getColumns('default')"
|
||||
:sm="$getColumns('sm')"
|
||||
:md="$getColumns('md')"
|
||||
:lg="$getColumns('lg')"
|
||||
:xl="$getColumns('xl')"
|
||||
:two-xl="$getColumns('2xl')"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($getExtraAttributeBag())
|
||||
->class(['fi-fo-component-ctn gap-6'])
|
||||
"
|
||||
>
|
||||
@foreach ($getComponents() as $infolistComponent)
|
||||
<x-filament::grid.column
|
||||
:default="$infolistComponent->getColumnSpan('default')"
|
||||
:sm="$infolistComponent->getColumnSpan('sm')"
|
||||
:md="$infolistComponent->getColumnSpan('md')"
|
||||
:lg="$infolistComponent->getColumnSpan('lg')"
|
||||
:xl="$infolistComponent->getColumnSpan('xl')"
|
||||
:twoXl="$infolistComponent->getColumnSpan('2xl')"
|
||||
:defaultStart="$infolistComponent->getColumnStart('default')"
|
||||
:smStart="$infolistComponent->getColumnStart('sm')"
|
||||
:mdStart="$infolistComponent->getColumnStart('md')"
|
||||
:lgStart="$infolistComponent->getColumnStart('lg')"
|
||||
:xlStart="$infolistComponent->getColumnStart('xl')"
|
||||
:twoXlStart="$infolistComponent->getColumnStart('2xl')"
|
||||
@class([
|
||||
match ($maxWidth = $infolistComponent->getMaxWidth()) {
|
||||
MaxWidth::ExtraSmall, 'xs' => 'max-w-xs',
|
||||
MaxWidth::Small, 'sm' => 'max-w-sm',
|
||||
MaxWidth::Medium, 'md' => 'max-w-md',
|
||||
MaxWidth::Large, 'lg' => 'max-w-lg',
|
||||
MaxWidth::ExtraLarge, 'xl' => 'max-w-xl',
|
||||
MaxWidth::TwoExtraLarge, '2xl' => 'max-w-2xl',
|
||||
MaxWidth::ThreeExtraLarge, '3xl' => 'max-w-3xl',
|
||||
MaxWidth::FourExtraLarge, '4xl' => 'max-w-4xl',
|
||||
MaxWidth::FiveExtraLarge, '5xl' => 'max-w-5xl',
|
||||
MaxWidth::SixExtraLarge, '6xl' => 'max-w-6xl',
|
||||
MaxWidth::SevenExtraLarge, '7xl' => 'max-w-7xl',
|
||||
default => $maxWidth,
|
||||
},
|
||||
])
|
||||
>
|
||||
{{ $infolistComponent }}
|
||||
</x-filament::grid.column>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</dl>
|
||||
34
vendor/filament/infolists/resources/views/components/actions.blade.php
vendored
Normal file
34
vendor/filament/infolists/resources/views/components/actions.blade.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
@php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
|
||||
$verticalAlignment = $getVerticalAlignment();
|
||||
|
||||
if (! $verticalAlignment instanceof VerticalAlignment) {
|
||||
$verticalAlignment = filled($verticalAlignment) ? (VerticalAlignment::tryFrom($verticalAlignment) ?? $verticalAlignment) : null;
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-actions flex h-full flex-col',
|
||||
match ($verticalAlignment) {
|
||||
VerticalAlignment::Start => 'justify-start',
|
||||
VerticalAlignment::Center => 'justify-center',
|
||||
VerticalAlignment::End => 'justify-end',
|
||||
default => $verticalAlignment,
|
||||
},
|
||||
])
|
||||
}}
|
||||
>
|
||||
<x-filament::actions
|
||||
:actions="$getChildComponentContainer()->getComponents()"
|
||||
:alignment="$getAlignment()"
|
||||
:full-width="$isFullWidth()"
|
||||
/>
|
||||
</div>
|
||||
5
vendor/filament/infolists/resources/views/components/actions/action-container.blade.php
vendored
Normal file
5
vendor/filament/infolists/resources/views/components/actions/action-container.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
@foreach ($getActions() as $action)
|
||||
@if ($action->isVisible())
|
||||
{{ $action }}
|
||||
@endif
|
||||
@endforeach
|
||||
52
vendor/filament/infolists/resources/views/components/affixes.blade.php
vendored
Normal file
52
vendor/filament/infolists/resources/views/components/affixes.blade.php
vendored
Normal file
@@ -0,0 +1,52 @@
|
||||
@props([
|
||||
'prefixActions' => [],
|
||||
'suffixActions' => [],
|
||||
])
|
||||
|
||||
@php
|
||||
$prefixActions = array_filter(
|
||||
$prefixActions,
|
||||
fn (\Filament\Infolists\Components\Actions\Action $prefixAction): bool => $prefixAction->isVisible(),
|
||||
);
|
||||
|
||||
$suffixActions = array_filter(
|
||||
$suffixActions,
|
||||
fn (\Filament\Infolists\Components\Actions\Action $suffixAction): bool => $suffixAction->isVisible(),
|
||||
);
|
||||
|
||||
$affixActionsClasses = 'flex items-center gap-3 self-stretch';
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{ $attributes->class(['fi-in-affixes flex']) }}
|
||||
>
|
||||
@if (count($prefixActions))
|
||||
<div
|
||||
@class([
|
||||
$affixActionsClasses,
|
||||
'pe-2',
|
||||
])
|
||||
>
|
||||
@foreach ($prefixActions as $prefixAction)
|
||||
{{ $prefixAction }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div class="min-w-0 flex-1">
|
||||
{{ $slot }}
|
||||
</div>
|
||||
|
||||
@if (count($suffixActions))
|
||||
<div
|
||||
@class([
|
||||
$affixActionsClasses,
|
||||
'ps-2',
|
||||
])
|
||||
>
|
||||
@foreach ($suffixActions as $suffixAction)
|
||||
{{ $suffixAction }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
56
vendor/filament/infolists/resources/views/components/color-entry.blade.php
vendored
Normal file
56
vendor/filament/infolists/resources/views/components/color-entry.blade.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
|
||||
@php
|
||||
$arrayState = $getState();
|
||||
|
||||
if ($arrayState instanceof \Illuminate\Support\Collection) {
|
||||
$arrayState = $arrayState->all();
|
||||
}
|
||||
|
||||
$arrayState = \Illuminate\Support\Arr::wrap($arrayState);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-color flex flex-wrap gap-1.5',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (count($arrayState))
|
||||
@foreach ($arrayState as $state)
|
||||
@php
|
||||
$itemIsCopyable = $isCopyable($state);
|
||||
$copyableState = $getCopyableState($state) ?? $state;
|
||||
$copyMessage = $getCopyMessage($state);
|
||||
$copyMessageDuration = $getCopyMessageDuration($state);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
@if ($itemIsCopyable)
|
||||
x-data="{}"
|
||||
x-on:click="
|
||||
window.navigator.clipboard.writeText(@js($copyableState))
|
||||
$tooltip(@js($copyMessage), {
|
||||
theme: $store.theme,
|
||||
timeout: @js($copyMessageDuration),
|
||||
})
|
||||
"
|
||||
@endif
|
||||
@class([
|
||||
'fi-in-color-item h-6 w-6 rounded-md',
|
||||
'cursor-pointer' => $itemIsCopyable,
|
||||
])
|
||||
@style([
|
||||
"background-color: {$state}" => $state,
|
||||
])
|
||||
></div>
|
||||
@endforeach
|
||||
@elseif (($placeholder = $getPlaceholder()) !== null)
|
||||
<x-filament-infolists::entries.placeholder>
|
||||
{{ $placeholder }}
|
||||
</x-filament-infolists::entries.placeholder>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
5
vendor/filament/infolists/resources/views/components/entries/placeholder.blade.php
vendored
Normal file
5
vendor/filament/infolists/resources/views/components/entries/placeholder.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<div
|
||||
class="fi-in-placeholder text-sm leading-6 text-gray-400 dark:text-gray-500"
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
5
vendor/filament/infolists/resources/views/components/entry-wrapper/helper-text.blade.php
vendored
Normal file
5
vendor/filament/infolists/resources/views/components/entry-wrapper/helper-text.blade.php
vendored
Normal file
@@ -0,0 +1,5 @@
|
||||
<div
|
||||
{{ $attributes->class(['fi-in-entry-wrp-helper-text text-sm text-gray-500']) }}
|
||||
>
|
||||
{{ $slot }}
|
||||
</div>
|
||||
66
vendor/filament/infolists/resources/views/components/entry-wrapper/hint.blade.php
vendored
Normal file
66
vendor/filament/infolists/resources/views/components/entry-wrapper/hint.blade.php
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
@props([
|
||||
'actions' => [],
|
||||
'color' => 'gray',
|
||||
'icon' => null,
|
||||
'tooltip' => null,
|
||||
])
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes->class([
|
||||
'fi-in-entry-wrp-hint flex items-center gap-x-3 text-sm',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (! \Filament\Support\is_slot_empty($slot))
|
||||
<span
|
||||
@class([
|
||||
'fi-in-entry-wrp-hint-label',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-500',
|
||||
default => 'fi-color-custom text-custom-600 dark:text-custom-400',
|
||||
},
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'infolists::components.entry-wrapper.hint.label',
|
||||
),
|
||||
])
|
||||
>
|
||||
{{ $slot }}
|
||||
</span>
|
||||
@endif
|
||||
|
||||
@if ($icon)
|
||||
<x-filament::icon
|
||||
x-data="{}"
|
||||
:icon="$icon"
|
||||
:x-tooltip="filled($tooltip) ? '{ content: ' . \Illuminate\Support\Js::from($tooltip) . ', theme: $store.theme }' : null"
|
||||
@class([
|
||||
'fi-in-entry-wrp-hint-icon h-5 w-5',
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500 dark:text-custom-400',
|
||||
},
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 500],
|
||||
alias: 'infolists::components.entry-wrapper.hint.icon',
|
||||
),
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
|
||||
@if (count($actions))
|
||||
<div class="fi-in-entry-wrp-hint-action flex items-center gap-3">
|
||||
@foreach ($actions as $action)
|
||||
{{ $action }}
|
||||
@endforeach
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
161
vendor/filament/infolists/resources/views/components/entry-wrapper/index.blade.php
vendored
Normal file
161
vendor/filament/infolists/resources/views/components/entry-wrapper/index.blade.php
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
@props([
|
||||
'action' => null,
|
||||
'alignment' => null,
|
||||
'entry' => null,
|
||||
'hasInlineLabel' => null,
|
||||
'helperText' => null,
|
||||
'hint' => null,
|
||||
'hintActions' => null,
|
||||
'hintColor' => null,
|
||||
'hintIcon' => null,
|
||||
'hintIconTooltip' => null,
|
||||
'id' => null,
|
||||
'label' => null,
|
||||
'labelPrefix' => null,
|
||||
'labelSrOnly' => null,
|
||||
'labelSuffix' => null,
|
||||
'shouldOpenUrlInNewTab' => null,
|
||||
'statePath' => null,
|
||||
'tooltip' => null,
|
||||
'url' => null,
|
||||
])
|
||||
|
||||
@php
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
if ($entry) {
|
||||
$action ??= $entry->getAction();
|
||||
$alignment ??= $entry->getAlignment();
|
||||
$hasInlineLabel ??= $entry->hasInlineLabel();
|
||||
$helperText ??= $entry->getHelperText();
|
||||
$hint ??= $entry->getHint();
|
||||
$hintActions ??= $entry->getHintActions();
|
||||
$hintColor ??= $entry->getHintColor();
|
||||
$hintIcon ??= $entry->getHintIcon();
|
||||
$hintIconTooltip ??= $entry->getHintIconTooltip();
|
||||
$id ??= $entry->getId();
|
||||
$label ??= $entry->getLabel();
|
||||
$labelSrOnly ??= $entry->isLabelHidden();
|
||||
$shouldOpenUrlInNewTab ??= $entry->shouldOpenUrlInNewTab();
|
||||
$statePath ??= $entry->getStatePath();
|
||||
$tooltip ??= $entry->getTooltip();
|
||||
$url ??= $entry->getUrl();
|
||||
}
|
||||
|
||||
if (! $alignment instanceof Alignment) {
|
||||
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
|
||||
}
|
||||
|
||||
$hintActions = array_filter(
|
||||
$hintActions ?? [],
|
||||
fn (\Filament\Infolists\Components\Actions\Action $hintAction): bool => $hintAction->isVisible(),
|
||||
);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($entry?->getExtraEntryWrapperAttributes() ?? [])
|
||||
->class(['fi-in-entry-wrp'])
|
||||
}}
|
||||
>
|
||||
@if ($label && $labelSrOnly)
|
||||
<dt class="sr-only">
|
||||
{{ $label }}
|
||||
</dt>
|
||||
@endif
|
||||
|
||||
<div
|
||||
@class([
|
||||
'grid gap-y-2',
|
||||
'sm:grid-cols-3 sm:items-start sm:gap-x-4' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
@if (($label && (! $labelSrOnly)) || $labelPrefix || $labelSuffix || filled($hint) || $hintIcon)
|
||||
<div class="flex items-center justify-between gap-x-3">
|
||||
@if ($label && (! $labelSrOnly))
|
||||
<x-filament-infolists::entry-wrapper.label
|
||||
:prefix="$labelPrefix"
|
||||
:suffix="$labelSuffix"
|
||||
>
|
||||
{{ $label }}
|
||||
</x-filament-infolists::entry-wrapper.label>
|
||||
@elseif ($labelPrefix)
|
||||
{{ $labelPrefix }}
|
||||
@elseif ($labelSuffix)
|
||||
{{ $labelSuffix }}
|
||||
@endif
|
||||
|
||||
@if (filled($hint) || $hintIcon || count($hintActions))
|
||||
<x-filament-infolists::entry-wrapper.hint
|
||||
:actions="$hintActions"
|
||||
:color="$hintColor"
|
||||
:icon="$hintIcon"
|
||||
:tooltip="$hintIconTooltip"
|
||||
>
|
||||
{{ $hint }}
|
||||
</x-filament-infolists::entry-wrapper.hint>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
|
||||
<div
|
||||
@class([
|
||||
'grid auto-cols-fr gap-y-2',
|
||||
'sm:col-span-2' => $hasInlineLabel,
|
||||
])
|
||||
>
|
||||
<dd
|
||||
@if (filled($tooltip))
|
||||
x-data="{}"
|
||||
x-tooltip="{
|
||||
content: @js($tooltip),
|
||||
theme: $store.theme,
|
||||
}"
|
||||
@endif
|
||||
@class([
|
||||
match ($alignment) {
|
||||
Alignment::Start => 'text-start',
|
||||
Alignment::Center => 'text-center',
|
||||
Alignment::End => 'text-end',
|
||||
Alignment::Justify, Alignment::Between => 'text-justify',
|
||||
Alignment::Left => 'text-left',
|
||||
Alignment::Right => 'text-right',
|
||||
default => $alignment,
|
||||
},
|
||||
])
|
||||
>
|
||||
@if ($url)
|
||||
<a
|
||||
{{ \Filament\Support\generate_href_html($url, $shouldOpenUrlInNewTab) }}
|
||||
class="block"
|
||||
>
|
||||
{{ $slot }}
|
||||
</a>
|
||||
@elseif ($action)
|
||||
@php
|
||||
$wireClickAction = $action->getLivewireClickHandler();
|
||||
@endphp
|
||||
|
||||
<button
|
||||
type="button"
|
||||
wire:click="{{ $wireClickAction }}"
|
||||
wire:loading.attr="disabled"
|
||||
wire:target="{{ $wireClickAction }}"
|
||||
class="block"
|
||||
>
|
||||
{{ $slot }}
|
||||
</button>
|
||||
@else
|
||||
{{ $slot }}
|
||||
@endif
|
||||
</dd>
|
||||
|
||||
@if (filled($helperText))
|
||||
<x-filament-infolists::entry-wrapper.helper-text>
|
||||
{{ $helperText }}
|
||||
</x-filament-infolists::entry-wrapper.helper-text>
|
||||
@endif
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
16
vendor/filament/infolists/resources/views/components/entry-wrapper/label.blade.php
vendored
Normal file
16
vendor/filament/infolists/resources/views/components/entry-wrapper/label.blade.php
vendored
Normal file
@@ -0,0 +1,16 @@
|
||||
@props([
|
||||
'prefix' => null,
|
||||
'suffix' => null,
|
||||
])
|
||||
|
||||
<dt
|
||||
{{ $attributes->class(['fi-in-entry-wrp-label inline-flex items-center gap-x-3']) }}
|
||||
>
|
||||
{{ $prefix }}
|
||||
|
||||
<span class="text-sm font-medium leading-6 text-gray-950 dark:text-white">
|
||||
{{ $slot }}
|
||||
</span>
|
||||
|
||||
{{ $suffix }}
|
||||
</dt>
|
||||
13
vendor/filament/infolists/resources/views/components/fieldset.blade.php
vendored
Normal file
13
vendor/filament/infolists/resources/views/components/fieldset.blade.php
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
<x-filament::fieldset
|
||||
:label="$getLabel()"
|
||||
:label-hidden="$isLabelHidden()"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
"
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</x-filament::fieldset>
|
||||
11
vendor/filament/infolists/resources/views/components/grid.blade.php
vendored
Normal file
11
vendor/filament/infolists/resources/views/components/grid.blade.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
11
vendor/filament/infolists/resources/views/components/group.blade.php
vendored
Normal file
11
vendor/filament/infolists/resources/views/components/group.blade.php
vendored
Normal file
@@ -0,0 +1,11 @@
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
68
vendor/filament/infolists/resources/views/components/icon-entry.blade.php
vendored
Normal file
68
vendor/filament/infolists/resources/views/components/icon-entry.blade.php
vendored
Normal file
@@ -0,0 +1,68 @@
|
||||
@php
|
||||
use Filament\Infolists\Components\IconEntry\IconEntrySize;
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
|
||||
@php
|
||||
$arrayState = $getState();
|
||||
|
||||
if ($arrayState instanceof \Illuminate\Support\Collection) {
|
||||
$arrayState = $arrayState->all();
|
||||
}
|
||||
|
||||
$arrayState = \Illuminate\Support\Arr::wrap($arrayState);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-icon flex flex-wrap gap-1.5',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (count($arrayState))
|
||||
@foreach ($arrayState as $state)
|
||||
@if ($icon = $getIcon($state))
|
||||
@php
|
||||
$color = $getColor($state) ?? 'gray';
|
||||
$size = $getSize($state) ?? IconEntrySize::Large;
|
||||
@endphp
|
||||
|
||||
<x-filament::icon
|
||||
:icon="$icon"
|
||||
@class([
|
||||
'fi-in-icon-item',
|
||||
match ($size) {
|
||||
IconEntrySize::ExtraSmall, 'xs' => 'fi-in-icon-item-size-xs h-3 w-3',
|
||||
IconEntrySize::Small, 'sm' => 'fi-in-icon-item-size-sm h-4 w-4',
|
||||
IconEntrySize::Medium, 'md' => 'fi-in-icon-item-size-md h-5 w-5',
|
||||
IconEntrySize::Large, 'lg' => 'fi-in-icon-item-size-lg h-6 w-6',
|
||||
IconEntrySize::ExtraLarge, 'xl' => 'fi-in-icon-item-size-xl h-7 w-7',
|
||||
IconEntrySize::TwoExtraLarge, IconEntrySize::ExtraExtraLarge, '2xl' => 'fi-in-icon-item-size-2xl h-8 w-8',
|
||||
default => $size,
|
||||
},
|
||||
match ($color) {
|
||||
'gray' => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'fi-color-custom text-custom-500 dark:text-custom-400',
|
||||
},
|
||||
is_string($color) ? 'fi-color-' . $color : null,
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 500],
|
||||
alias: 'infolists::components.icon-entry.item',
|
||||
) => $color !== 'gray',
|
||||
])
|
||||
/>
|
||||
@endif
|
||||
@endforeach
|
||||
@elseif (($placeholder = $getPlaceholder()) !== null)
|
||||
<x-filament-infolists::entries.placeholder>
|
||||
{{ $placeholder }}
|
||||
</x-filament-infolists::entries.placeholder>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
141
vendor/filament/infolists/resources/views/components/image-entry.blade.php
vendored
Normal file
141
vendor/filament/infolists/resources/views/components/image-entry.blade.php
vendored
Normal file
@@ -0,0 +1,141 @@
|
||||
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
|
||||
@php
|
||||
$state = $getState();
|
||||
|
||||
if ($state instanceof \Illuminate\Support\Collection) {
|
||||
$state = $state->all();
|
||||
}
|
||||
|
||||
$state = \Illuminate\Support\Arr::wrap($state);
|
||||
|
||||
$limit = $getLimit();
|
||||
$limitedState = array_slice($state, 0, $limit);
|
||||
$isCircular = $isCircular();
|
||||
$isSquare = $isSquare();
|
||||
$isStacked = $isStacked();
|
||||
$overlap = $isStacked ? ($getOverlap() ?? 2) : null;
|
||||
$ring = $isStacked ? ($getRing() ?? 2) : null;
|
||||
$height = $getHeight() ?? ($isStacked ? '2.5rem' : '8rem');
|
||||
$width = $getWidth() ?? (($isCircular || $isSquare) ? $height : null);
|
||||
|
||||
$stateCount = count($state);
|
||||
$limitedStateCount = count($limitedState);
|
||||
|
||||
$defaultImageUrl = $getDefaultImageUrl();
|
||||
|
||||
if ((! $limitedStateCount) && filled($defaultImageUrl)) {
|
||||
$limitedState = [null];
|
||||
|
||||
$limitedStateCount = 1;
|
||||
}
|
||||
|
||||
$ringClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'ring-white dark:ring-gray-900',
|
||||
match ($ring) {
|
||||
0 => null,
|
||||
1 => 'ring-1',
|
||||
2 => 'ring-2',
|
||||
3 => 'ring',
|
||||
4 => 'ring-4',
|
||||
default => $ring,
|
||||
},
|
||||
]);
|
||||
|
||||
$hasLimitedRemainingText = $hasLimitedRemainingText() && ($limitedStateCount < $stateCount);
|
||||
$isLimitedRemainingTextSeparate = $isLimitedRemainingTextSeparate();
|
||||
|
||||
$limitedRemainingTextSizeClasses = match ($getLimitedRemainingTextSize()) {
|
||||
'xs' => 'text-xs',
|
||||
'sm', null => 'text-sm',
|
||||
'base', 'md' => 'text-base',
|
||||
'lg' => 'text-lg',
|
||||
default => $size,
|
||||
};
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-image flex items-center gap-x-2.5',
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if ($limitedStateCount)
|
||||
<div
|
||||
@class([
|
||||
'flex flex-wrap',
|
||||
match ($overlap) {
|
||||
0 => null,
|
||||
1 => '-space-x-1',
|
||||
2 => '-space-x-2',
|
||||
3 => '-space-x-3',
|
||||
4 => '-space-x-4',
|
||||
5 => '-space-x-5',
|
||||
6 => '-space-x-6',
|
||||
7 => '-space-x-7',
|
||||
8 => '-space-x-8',
|
||||
default => 'gap-1.5',
|
||||
},
|
||||
])
|
||||
>
|
||||
@foreach ($limitedState as $stateItem)
|
||||
<img
|
||||
src="{{ filled($stateItem) ? $getImageUrl($stateItem) : $defaultImageUrl }}"
|
||||
{{
|
||||
$getExtraImgAttributeBag()
|
||||
->class([
|
||||
'max-w-none object-cover object-center',
|
||||
'rounded-full' => $isCircular,
|
||||
$ringClasses,
|
||||
])
|
||||
->style([
|
||||
"height: {$height}" => $height,
|
||||
"width: {$width}" => $width,
|
||||
])
|
||||
}}
|
||||
/>
|
||||
@endforeach
|
||||
|
||||
@if ($hasLimitedRemainingText && (! $isLimitedRemainingTextSeparate) && $isCircular)
|
||||
<div
|
||||
style="
|
||||
@if ($height) height: {{ $height }}; @endif
|
||||
@if ($width) width: {{ $width }}; @endif
|
||||
"
|
||||
@class([
|
||||
'flex items-center justify-center bg-gray-100 font-medium text-gray-500 dark:bg-gray-800 dark:text-gray-400',
|
||||
'rounded-full' => $isCircular,
|
||||
$limitedRemainingTextSizeClasses,
|
||||
$ringClasses,
|
||||
])
|
||||
@style([
|
||||
"height: {$height}" => $height,
|
||||
"width: {$width}" => $width,
|
||||
])
|
||||
>
|
||||
<span class="-ms-0.5">
|
||||
+{{ $stateCount - $limitedStateCount }}
|
||||
</span>
|
||||
</div>
|
||||
@endif
|
||||
</div>
|
||||
|
||||
@if ($hasLimitedRemainingText && ($isLimitedRemainingTextSeparate || (! $isCircular)))
|
||||
<div
|
||||
@class([
|
||||
'font-medium text-gray-500 dark:text-gray-400',
|
||||
$limitedRemainingTextSizeClasses,
|
||||
])
|
||||
>
|
||||
+{{ $stateCount - $limitedStateCount }}
|
||||
</div>
|
||||
@endif
|
||||
@elseif (($placeholder = $getPlaceholder()) !== null)
|
||||
<x-filament-infolists::entries.placeholder>
|
||||
{{ $placeholder }}
|
||||
</x-filament-infolists::entries.placeholder>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
58
vendor/filament/infolists/resources/views/components/key-value-entry.blade.php
vendored
Normal file
58
vendor/filament/infolists/resources/views/components/key-value-entry.blade.php
vendored
Normal file
@@ -0,0 +1,58 @@
|
||||
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-in-key-value w-full rounded-lg bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-white/5 dark:ring-white/10'])
|
||||
}}
|
||||
>
|
||||
<table
|
||||
class="w-full table-auto divide-y divide-gray-200 dark:divide-white/5"
|
||||
>
|
||||
<thead>
|
||||
<tr>
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-2 text-start text-sm font-medium text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
{{ $getKeyLabel() }}
|
||||
</th>
|
||||
|
||||
<th
|
||||
scope="col"
|
||||
class="px-3 py-2 text-start text-sm font-medium text-gray-700 dark:text-gray-200"
|
||||
>
|
||||
{{ $getValueLabel() }}
|
||||
</th>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody
|
||||
class="divide-y divide-gray-200 font-mono text-base dark:divide-white/5 sm:text-sm sm:leading-6"
|
||||
>
|
||||
@forelse (($getState() ?? []) as $key => $value)
|
||||
<tr
|
||||
class="divide-x divide-gray-200 dark:divide-white/5 rtl:divide-x-reverse"
|
||||
>
|
||||
<td class="w-1/2 px-3 py-1.5">
|
||||
{{ $key }}
|
||||
</td>
|
||||
|
||||
<td class="w-1/2 px-3 py-1.5">
|
||||
{{ $value }}
|
||||
</td>
|
||||
</tr>
|
||||
@empty
|
||||
<tr>
|
||||
<td
|
||||
colspan="2"
|
||||
class="px-3 py-2 text-center font-sans text-sm text-gray-400 dark:text-gray-500"
|
||||
>
|
||||
{{ $getPlaceholder() }}
|
||||
</td>
|
||||
</tr>
|
||||
@endforelse
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
7
vendor/filament/infolists/resources/views/components/livewire.blade.php
vendored
Normal file
7
vendor/filament/infolists/resources/views/components/livewire.blade.php
vendored
Normal file
@@ -0,0 +1,7 @@
|
||||
<div>
|
||||
@if (filled($key = $getKey()))
|
||||
@livewire($getComponent(), $getComponentProperties(), key($key))
|
||||
@else
|
||||
@livewire($getComponent(), $getComponentProperties())
|
||||
@endif
|
||||
</div>
|
||||
48
vendor/filament/infolists/resources/views/components/repeatable-entry.blade.php
vendored
Normal file
48
vendor/filament/infolists/resources/views/components/repeatable-entry.blade.php
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
@php
|
||||
$isContained = $isContained();
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-repeatable',
|
||||
'fi-contained' => $isContained,
|
||||
])
|
||||
}}
|
||||
>
|
||||
@if (count($childComponentContainers = $getChildComponentContainers()))
|
||||
<ul>
|
||||
<x-filament::grid
|
||||
:default="$getGridColumns('default')"
|
||||
:sm="$getGridColumns('sm')"
|
||||
:md="$getGridColumns('md')"
|
||||
:lg="$getGridColumns('lg')"
|
||||
:xl="$getGridColumns('xl')"
|
||||
:two-xl="$getGridColumns('2xl')"
|
||||
class="gap-4"
|
||||
>
|
||||
@foreach ($childComponentContainers as $container)
|
||||
<li
|
||||
@class([
|
||||
'fi-in-repeatable-item block',
|
||||
'rounded-xl bg-white p-4 shadow-sm ring-1 ring-gray-950/5 dark:bg-white/5 dark:ring-white/10' => $isContained,
|
||||
])
|
||||
>
|
||||
{{ $container }}
|
||||
</li>
|
||||
@endforeach
|
||||
</x-filament::grid>
|
||||
</ul>
|
||||
@elseif (($placeholder = $getPlaceholder()) !== null)
|
||||
<x-filament-infolists::entries.placeholder>
|
||||
{{ $placeholder }}
|
||||
</x-filament-infolists::entries.placeholder>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
30
vendor/filament/infolists/resources/views/components/section.blade.php
vendored
Normal file
30
vendor/filament/infolists/resources/views/components/section.blade.php
vendored
Normal file
@@ -0,0 +1,30 @@
|
||||
@php
|
||||
$isAside = $isAside();
|
||||
@endphp
|
||||
|
||||
<x-filament::section
|
||||
:aside="$isAside"
|
||||
:collapsed="$isCollapsed()"
|
||||
:collapsible="$isCollapsible() && (! $isAside)"
|
||||
:compact="$isCompact()"
|
||||
:content-before="$isContentBefore()"
|
||||
:description="$getDescription()"
|
||||
:footer-actions="$getFooterActions()"
|
||||
:footer-actions-alignment="$getFooterActionsAlignment()"
|
||||
:header-actions="$getHeaderActions()"
|
||||
:heading="$getHeading()"
|
||||
:icon="$getIcon()"
|
||||
:icon-color="$getIconColor()"
|
||||
:icon-size="$getIconSize()"
|
||||
:persist-collapsed="$shouldPersistCollapsed()"
|
||||
:attributes="
|
||||
\Filament\Support\prepare_inherited_attributes($attributes)
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
"
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</x-filament::section>
|
||||
63
vendor/filament/infolists/resources/views/components/split.blade.php
vendored
Normal file
63
vendor/filament/infolists/resources/views/components/split.blade.php
vendored
Normal file
@@ -0,0 +1,63 @@
|
||||
@php
|
||||
use Filament\Support\Enums\VerticalAlignment;
|
||||
|
||||
$verticalAlignment = $getVerticalAlignment();
|
||||
|
||||
if (! $verticalAlignment instanceof VerticalAlignment) {
|
||||
$verticalAlignment = filled($verticalAlignment) ? (VerticalAlignment::tryFrom($verticalAlignment) ?? $verticalAlignment) : null;
|
||||
}
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-split flex gap-6',
|
||||
match ($getFromBreakpoint()) {
|
||||
'sm' => 'flex-col sm:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'sm:items-center',
|
||||
VerticalAlignment::End => 'sm:items-end',
|
||||
default => 'sm:items-start',
|
||||
},
|
||||
'md' => 'flex-col md:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'md:items-center',
|
||||
VerticalAlignment::End => 'md:items-end',
|
||||
default => 'md:items-start',
|
||||
},
|
||||
'lg' => 'flex-col lg:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'lg:items-center',
|
||||
VerticalAlignment::End => 'lg:items-end',
|
||||
default => 'lg:items-start',
|
||||
},
|
||||
'xl' => 'flex-col xl:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'xl:items-center',
|
||||
VerticalAlignment::End => 'xl:items-end',
|
||||
default => 'xl:items-start',
|
||||
},
|
||||
'2xl' => 'flex-col 2xl:flex-row ' . match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => '2xl:items-center',
|
||||
VerticalAlignment::End => '2xl:items-end',
|
||||
default => '2xl:items-start',
|
||||
},
|
||||
default => match ($verticalAlignment) {
|
||||
VerticalAlignment::Center => 'items-center',
|
||||
VerticalAlignment::End => 'items-end',
|
||||
default => 'items-start',
|
||||
},
|
||||
},
|
||||
])
|
||||
}}
|
||||
>
|
||||
@foreach ($getChildComponentContainers() as $container)
|
||||
@foreach ($container->getComponents() as $component)
|
||||
<div
|
||||
@class([
|
||||
'w-full flex-1' => $component->canGrow(),
|
||||
])
|
||||
>
|
||||
{{ $component }}
|
||||
</div>
|
||||
@endforeach
|
||||
@endforeach
|
||||
</div>
|
||||
105
vendor/filament/infolists/resources/views/components/tabs.blade.php
vendored
Normal file
105
vendor/filament/infolists/resources/views/components/tabs.blade.php
vendored
Normal file
@@ -0,0 +1,105 @@
|
||||
@php
|
||||
use Filament\Infolists\Components\Tabs\Tab;
|
||||
|
||||
$isContained = $isContained();
|
||||
@endphp
|
||||
|
||||
<div
|
||||
x-cloak
|
||||
x-data="{
|
||||
tab: @if ($isTabPersisted() && filled($persistenceId = $getId())) $persist(null).as('tabs-{{ $persistenceId }}') @else null @endif,
|
||||
|
||||
getTabs: function () {
|
||||
if (! this.$refs.tabsData) {
|
||||
return []
|
||||
}
|
||||
|
||||
return JSON.parse(this.$refs.tabsData.value)
|
||||
},
|
||||
|
||||
updateQueryString: function () {
|
||||
if (! @js($isTabPersistedInQueryString())) {
|
||||
return
|
||||
}
|
||||
|
||||
const url = new URL(window.location.href)
|
||||
url.searchParams.set(@js($getTabQueryStringKey()), this.tab)
|
||||
|
||||
history.pushState(null, document.title, url.toString())
|
||||
},
|
||||
}"
|
||||
x-init="
|
||||
$watch('tab', () => updateQueryString())
|
||||
|
||||
const tabs = getTabs()
|
||||
|
||||
if (! tab || ! tabs.includes(tab)) {
|
||||
tab = tabs[@js($getActiveTab()) - 1]
|
||||
}
|
||||
|
||||
Livewire.hook('commit', ({ component, commit, succeed, fail, respond }) => {
|
||||
succeed(({ snapshot, effect }) => {
|
||||
$nextTick(() => {
|
||||
if (component.id !== @js($this->getId())) {
|
||||
return
|
||||
}
|
||||
|
||||
const tabs = getTabs()
|
||||
|
||||
if (! tabs.includes(tab)) {
|
||||
tab = tabs[@js($getActiveTab()) - 1]
|
||||
}
|
||||
})
|
||||
})
|
||||
})
|
||||
"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'id' => $getId(),
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->merge($getExtraAlpineAttributes(), escape: false)
|
||||
->class([
|
||||
'fi-in-tabs flex flex-col',
|
||||
'fi-contained rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:bg-gray-900 dark:ring-white/10' => $isContained,
|
||||
])
|
||||
}}
|
||||
>
|
||||
<input
|
||||
type="hidden"
|
||||
value="{{
|
||||
collect($getChildComponentContainer()->getComponents())
|
||||
->filter(static fn (Tab $tab): bool => $tab->isVisible())
|
||||
->map(static fn (Tab $tab) => $tab->getId())
|
||||
->values()
|
||||
->toJson()
|
||||
}}"
|
||||
x-ref="tabsData"
|
||||
/>
|
||||
|
||||
<x-filament::tabs :contained="$isContained" :label="$getLabel()">
|
||||
@foreach ($getChildComponentContainer()->getComponents() as $tab)
|
||||
@php
|
||||
$tabId = $tab->getId();
|
||||
@endphp
|
||||
|
||||
<x-filament::tabs.item
|
||||
:alpine-active="'tab === \'' . $tabId . '\''"
|
||||
:badge="$tab->getBadge()"
|
||||
:badge-color="$tab->getBadgeColor()"
|
||||
:badge-icon="$tab->getBadgeIcon()"
|
||||
:badge-icon-position="$tab->getBadgeIconPosition()"
|
||||
:icon="$tab->getIcon()"
|
||||
:icon-position="$tab->getIconPosition()"
|
||||
:x-on:click="'tab = \'' . $tabId . '\''"
|
||||
>
|
||||
{{ $tab->getLabel() }}
|
||||
</x-filament::tabs.item>
|
||||
@endforeach
|
||||
</x-filament::tabs>
|
||||
|
||||
@foreach ($getChildComponentContainer()->getComponents() as $tab)
|
||||
{{ $tab }}
|
||||
@endforeach
|
||||
</div>
|
||||
29
vendor/filament/infolists/resources/views/components/tabs/tab.blade.php
vendored
Normal file
29
vendor/filament/infolists/resources/views/components/tabs/tab.blade.php
vendored
Normal file
@@ -0,0 +1,29 @@
|
||||
@php
|
||||
$id = $getId();
|
||||
$isContained = $getContainer()->getParentComponent()->isContained();
|
||||
|
||||
$activeTabClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-active',
|
||||
'p-6' => $isContained,
|
||||
'mt-6' => ! $isContained,
|
||||
]);
|
||||
|
||||
$inactiveTabClasses = 'invisible absolute h-0 overflow-hidden p-0';
|
||||
@endphp
|
||||
|
||||
<div
|
||||
x-bind:class="tab === @js($id) ? @js($activeTabClasses) : @js($inactiveTabClasses)"
|
||||
{{
|
||||
$attributes
|
||||
->merge([
|
||||
'aria-labelledby' => $id,
|
||||
'id' => $id,
|
||||
'role' => 'tabpanel',
|
||||
'tabindex' => '0',
|
||||
], escape: false)
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-in-tabs-tab outline-none'])
|
||||
}}
|
||||
>
|
||||
{{ $getChildComponentContainer() }}
|
||||
</div>
|
||||
310
vendor/filament/infolists/resources/views/components/text-entry.blade.php
vendored
Normal file
310
vendor/filament/infolists/resources/views/components/text-entry.blade.php
vendored
Normal file
@@ -0,0 +1,310 @@
|
||||
@php
|
||||
use Filament\Infolists\Components\TextEntry\TextEntrySize;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Filament\Support\Enums\FontFamily;
|
||||
use Filament\Support\Enums\FontWeight;
|
||||
use Filament\Support\Enums\IconPosition;
|
||||
@endphp
|
||||
|
||||
<x-dynamic-component :component="$getEntryWrapperView()" :entry="$entry">
|
||||
@php
|
||||
$alignment = $getAlignment();
|
||||
$isBadge = $isBadge();
|
||||
$isBulleted = $isBulleted();
|
||||
$iconPosition = $getIconPosition();
|
||||
$isListWithLineBreaks = $isListWithLineBreaks();
|
||||
$isLimitedListExpandable = $isLimitedListExpandable();
|
||||
$isProse = $isProse();
|
||||
$isMarkdown = $isMarkdown();
|
||||
$url = $getUrl();
|
||||
|
||||
if (! $alignment instanceof Alignment) {
|
||||
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
|
||||
}
|
||||
|
||||
$arrayState = $getState();
|
||||
|
||||
if ($arrayState instanceof \Illuminate\Support\Collection) {
|
||||
$arrayState = $arrayState->all();
|
||||
}
|
||||
|
||||
$listLimit = 1;
|
||||
|
||||
if (is_array($arrayState)) {
|
||||
if ($listLimit = $getListLimit()) {
|
||||
$limitedArrayStateCount = (count($arrayState) > $listLimit) ? (count($arrayState) - $listLimit) : 0;
|
||||
|
||||
if (! $isListWithLineBreaks) {
|
||||
$arrayState = array_slice($arrayState, 0, $listLimit);
|
||||
}
|
||||
}
|
||||
|
||||
$listLimit ??= count($arrayState);
|
||||
|
||||
if ((! $isListWithLineBreaks) && (! $isBadge)) {
|
||||
$arrayState = implode(
|
||||
', ',
|
||||
array_map(
|
||||
fn ($value) => $value instanceof \Filament\Support\Contracts\HasLabel ? $value->getLabel() : $value,
|
||||
$arrayState,
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$arrayState = \Illuminate\Support\Arr::wrap($arrayState);
|
||||
@endphp
|
||||
|
||||
<div
|
||||
{{
|
||||
$attributes
|
||||
->merge($getExtraAttributes(), escape: false)
|
||||
->class(['fi-in-text w-full'])
|
||||
}}
|
||||
>
|
||||
@if ($arrayState)
|
||||
<x-filament-infolists::affixes
|
||||
:prefix-actions="$getPrefixActions()"
|
||||
:suffix-actions="$getSuffixActions()"
|
||||
>
|
||||
<{{ $isListWithLineBreaks ? 'ul' : 'div' }}
|
||||
@class([
|
||||
'flex' => ! $isBulleted,
|
||||
'flex-col' => (! $isBulleted) && $isListWithLineBreaks,
|
||||
'list-inside list-disc' => $isBulleted,
|
||||
'gap-1.5' => $isBadge,
|
||||
'flex-wrap' => $isBadge && (! $isListWithLineBreaks),
|
||||
match ($alignment) {
|
||||
Alignment::Start => 'text-start',
|
||||
Alignment::Center => 'text-center',
|
||||
Alignment::End => 'text-end',
|
||||
Alignment::Left => 'text-left',
|
||||
Alignment::Right => 'text-right',
|
||||
Alignment::Justify, Alignment::Between => 'text-justify',
|
||||
default => $alignment,
|
||||
},
|
||||
match ($alignment) {
|
||||
Alignment::Start, Alignment::Left => 'justify-start',
|
||||
Alignment::Center => 'justify-center',
|
||||
Alignment::End, Alignment::Right => 'justify-end',
|
||||
Alignment::Between, Alignment::Justify => 'justify-between',
|
||||
default => null,
|
||||
} => $isBulleted || (! $isListWithLineBreaks),
|
||||
match ($alignment) {
|
||||
Alignment::Start, Alignment::Left => 'items-start',
|
||||
Alignment::Center => 'items-center',
|
||||
Alignment::End, Alignment::Right => 'items-end',
|
||||
Alignment::Between, Alignment::Justify => 'items-stretch',
|
||||
default => null,
|
||||
} => $isListWithLineBreaks && (! $isBulleted),
|
||||
])
|
||||
@if ($isListWithLineBreaks && $isLimitedListExpandable)
|
||||
x-data="{ isLimited: true }"
|
||||
@endif
|
||||
>
|
||||
@foreach ($arrayState as $state)
|
||||
@if (filled($formattedState = $formatState($state)) &&
|
||||
(! ($isListWithLineBreaks && (! $isLimitedListExpandable) && ($loop->iteration > $listLimit))))
|
||||
@php
|
||||
$color = $getColor($state);
|
||||
$copyableState = $getCopyableState($state) ?? $state;
|
||||
$copyMessage = $getCopyMessage($state);
|
||||
$copyMessageDuration = $getCopyMessageDuration($state);
|
||||
$fontFamily = $getFontFamily($state);
|
||||
$icon = $getIcon($state);
|
||||
$iconColor = $getIconColor($state);
|
||||
$itemIsCopyable = $isCopyable($state);
|
||||
$lineClamp = $getLineClamp($state);
|
||||
$size = $getSize($state);
|
||||
$weight = $getWeight($state);
|
||||
|
||||
$proseClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-in-text-item-prose prose max-w-none dark:prose-invert [&>*:first-child]:mt-0 [&>*:last-child]:mb-0',
|
||||
'pt-2' => ! $isLabelHidden(),
|
||||
match ($size) {
|
||||
TextEntrySize::ExtraSmall, 'xs' => 'prose-xs',
|
||||
TextEntrySize::Small, 'sm', null => 'prose-sm',
|
||||
TextEntrySize::Medium, 'base', 'md' => 'prose-base',
|
||||
TextEntrySize::Large, 'lg' => 'prose-lg',
|
||||
default => $size,
|
||||
},
|
||||
]);
|
||||
|
||||
$iconClasses = \Illuminate\Support\Arr::toCssClasses([
|
||||
'fi-in-text-item-icon h-5 w-5 shrink-0',
|
||||
match ($iconColor) {
|
||||
'gray', null => 'text-gray-400 dark:text-gray-500',
|
||||
default => 'text-custom-500',
|
||||
},
|
||||
]);
|
||||
|
||||
$iconStyles = \Illuminate\Support\Arr::toCssStyles([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$iconColor,
|
||||
shades: [500],
|
||||
alias: 'infolists::components.text-entry.item.icon',
|
||||
) => $iconColor !== 'gray',
|
||||
]);
|
||||
@endphp
|
||||
|
||||
<{{ $isListWithLineBreaks ? 'li' : 'div' }}
|
||||
@if ($itemIsCopyable)
|
||||
x-on:click="
|
||||
window.navigator.clipboard.writeText(@js($copyableState))
|
||||
$tooltip(@js($copyMessage), {
|
||||
theme: $store.theme,
|
||||
timeout: @js($copyMessageDuration),
|
||||
})
|
||||
"
|
||||
@endif
|
||||
@if ($isListWithLineBreaks && ($loop->iteration > $listLimit))
|
||||
x-cloak
|
||||
x-show="! isLimited"
|
||||
x-transition
|
||||
@endif
|
||||
@class([
|
||||
'flex' => ! $isBulleted,
|
||||
'max-w-max' => ! ($isBulleted || $isBadge),
|
||||
'w-max' => $isBadge,
|
||||
'cursor-pointer' => $itemIsCopyable,
|
||||
match ($color) {
|
||||
null => 'text-gray-950 dark:text-white',
|
||||
'gray' => 'text-gray-500 dark:text-gray-400',
|
||||
default => 'text-custom-600 dark:text-custom-400',
|
||||
} => $isBulleted,
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'infolists::components.text-entry.item.container',
|
||||
) => $isBulleted && (! in_array($color, [null, 'gray'])),
|
||||
])
|
||||
>
|
||||
@if ($isBadge)
|
||||
<x-filament::badge
|
||||
:color="$color"
|
||||
:icon="$icon"
|
||||
:icon-position="$iconPosition"
|
||||
>
|
||||
{{ $formattedState }}
|
||||
</x-filament::badge>
|
||||
@else
|
||||
<div
|
||||
@class([
|
||||
'fi-in-text-item inline-flex items-center gap-1.5',
|
||||
'group/item' => $url,
|
||||
match ($color) {
|
||||
null, 'gray' => null,
|
||||
default => 'fi-color-custom',
|
||||
},
|
||||
is_string($color) ? "fi-color-{$color}" : null,
|
||||
])
|
||||
>
|
||||
@if ($icon && in_array($iconPosition, [IconPosition::Before, 'before']))
|
||||
<x-filament::icon
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
:style="$iconStyles"
|
||||
/>
|
||||
@endif
|
||||
|
||||
<div
|
||||
@class([
|
||||
'group-hover/item:underline group-focus-visible/item:underline' => $url,
|
||||
$proseClasses => $isProse || $isMarkdown,
|
||||
'line-clamp-[--line-clamp]' => $lineClamp,
|
||||
match ($size) {
|
||||
TextEntrySize::ExtraSmall, 'xs' => 'text-xs',
|
||||
TextEntrySize::Small, 'sm', null => 'text-sm leading-6',
|
||||
TextEntrySize::Medium, 'base', 'md' => 'text-base',
|
||||
TextEntrySize::Large, 'lg' => 'text-lg',
|
||||
default => $size,
|
||||
},
|
||||
match ($color) {
|
||||
null => 'text-gray-950 dark:text-white',
|
||||
'gray' => 'text-gray-500 dark:text-gray-400',
|
||||
default => 'text-custom-600 dark:text-custom-400',
|
||||
},
|
||||
match ($weight) {
|
||||
FontWeight::Thin, 'thin' => 'font-thin',
|
||||
FontWeight::ExtraLight, 'extralight' => 'font-extralight',
|
||||
FontWeight::Light, 'light' => 'font-light',
|
||||
FontWeight::Medium, 'medium' => 'font-medium',
|
||||
FontWeight::SemiBold, 'semibold' => 'font-semibold',
|
||||
FontWeight::Bold, 'bold' => 'font-bold',
|
||||
FontWeight::ExtraBold, 'extrabold' => 'font-extrabold',
|
||||
FontWeight::Black, 'black' => 'font-black',
|
||||
default => $weight,
|
||||
},
|
||||
match ($fontFamily) {
|
||||
FontFamily::Sans, 'sans' => 'font-sans',
|
||||
FontFamily::Serif, 'serif' => 'font-serif',
|
||||
FontFamily::Mono, 'mono' => 'font-mono',
|
||||
default => $fontFamily,
|
||||
},
|
||||
])
|
||||
@style([
|
||||
\Filament\Support\get_color_css_variables(
|
||||
$color,
|
||||
shades: [400, 600],
|
||||
alias: 'infolists::components.text-entry.item.label',
|
||||
) => ! in_array($color, [null, 'gray']),
|
||||
"--line-clamp: {$lineClamp}" => $lineClamp,
|
||||
])
|
||||
>
|
||||
{{ $formattedState }}
|
||||
</div>
|
||||
|
||||
@if ($icon && in_array($iconPosition, [IconPosition::After, 'after']))
|
||||
<x-filament::icon
|
||||
:icon="$icon"
|
||||
:class="$iconClasses"
|
||||
:style="$iconStyles"
|
||||
/>
|
||||
@endif
|
||||
</div>
|
||||
@endif
|
||||
</{{ $isListWithLineBreaks ? 'li' : 'div' }}>
|
||||
@endif
|
||||
@endforeach
|
||||
|
||||
@if ($limitedArrayStateCount ?? 0)
|
||||
<{{ $isListWithLineBreaks ? 'li' : 'div' }}>
|
||||
@if ($isLimitedListExpandable)
|
||||
<x-filament::link
|
||||
color="gray"
|
||||
tag="button"
|
||||
x-on:click.prevent="isLimited = false"
|
||||
x-show="isLimited"
|
||||
>
|
||||
{{ trans_choice('filament-infolists::components.entries.text.actions.expand_list', $limitedArrayStateCount) }}
|
||||
</x-filament::link>
|
||||
|
||||
<x-filament::link
|
||||
color="gray"
|
||||
tag="button"
|
||||
x-cloak
|
||||
x-on:click.prevent="isLimited = true"
|
||||
x-show="! isLimited"
|
||||
>
|
||||
{{ trans_choice('filament-infolists::components.entries.text.actions.collapse_list', $limitedArrayStateCount) }}
|
||||
</x-filament::link>
|
||||
@else
|
||||
<span
|
||||
class="text-sm text-gray-500 dark:text-gray-400"
|
||||
>
|
||||
{{ trans_choice('filament-infolists::components.entries.text.more_list_items', $limitedArrayStateCount) }}
|
||||
</span>
|
||||
@endif
|
||||
</{{ $isListWithLineBreaks ? 'li' : 'div' }}>
|
||||
@endif
|
||||
</{{ $isListWithLineBreaks ? 'ul' : 'div' }}>
|
||||
</x-filament-infolists::affixes>
|
||||
@elseif (($placeholder = $getPlaceholder()) !== null)
|
||||
<x-filament-infolists::entries.placeholder>
|
||||
{{ $placeholder }}
|
||||
</x-filament-infolists::entries.placeholder>
|
||||
@endif
|
||||
</div>
|
||||
</x-dynamic-component>
|
||||
14
vendor/filament/infolists/src/Commands/Aliases/MakeEntryCommand.php
vendored
Normal file
14
vendor/filament/infolists/src/Commands/Aliases/MakeEntryCommand.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Commands\Aliases;
|
||||
|
||||
use Filament\Infolists\Commands;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand(name: 'infolists:entry')]
|
||||
class MakeEntryCommand extends Commands\MakeEntryCommand
|
||||
{
|
||||
protected $hidden = true;
|
||||
|
||||
protected $signature = 'infolists:entry {name} {--F|force}';
|
||||
}
|
||||
14
vendor/filament/infolists/src/Commands/Aliases/MakeLayoutComponentCommand.php
vendored
Normal file
14
vendor/filament/infolists/src/Commands/Aliases/MakeLayoutComponentCommand.php
vendored
Normal file
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Commands\Aliases;
|
||||
|
||||
use Filament\Infolists\Commands;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
#[AsCommand(name: 'infolists:layout')]
|
||||
class MakeLayoutComponentCommand extends Commands\MakeLayoutComponentCommand
|
||||
{
|
||||
protected $hidden = true;
|
||||
|
||||
protected $signature = 'infolists:layout {name} {--F|force}';
|
||||
}
|
||||
76
vendor/filament/infolists/src/Commands/MakeEntryCommand.php
vendored
Normal file
76
vendor/filament/infolists/src/Commands/MakeEntryCommand.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Commands;
|
||||
|
||||
use Filament\Support\Commands\Concerns\CanManipulateFiles;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
use function Laravel\Prompts\text;
|
||||
|
||||
#[AsCommand(name: 'make:infolist-entry')]
|
||||
class MakeEntryCommand extends Command
|
||||
{
|
||||
use CanManipulateFiles;
|
||||
|
||||
protected $description = 'Create a new infolist entry class and view';
|
||||
|
||||
protected $signature = 'make:infolist-entry {name?} {--F|force}';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$entry = (string) str($this->argument('name') ?? text(
|
||||
label: 'What is the entry name?',
|
||||
placeholder: 'StatusSwitcher',
|
||||
required: true,
|
||||
))
|
||||
->trim('/')
|
||||
->trim('\\')
|
||||
->trim(' ')
|
||||
->replace('/', '\\');
|
||||
$entryClass = (string) str($entry)->afterLast('\\');
|
||||
$entryNamespace = str($entry)->contains('\\') ?
|
||||
(string) str($entry)->beforeLast('\\') :
|
||||
'';
|
||||
|
||||
$view = str($entry)
|
||||
->prepend('infolists\\components\\')
|
||||
->explode('\\')
|
||||
->map(fn ($segment) => Str::kebab($segment))
|
||||
->implode('.');
|
||||
|
||||
$path = app_path(
|
||||
(string) str($entry)
|
||||
->prepend('Infolists\\Components\\')
|
||||
->replace('\\', '/')
|
||||
->append('.php'),
|
||||
);
|
||||
$viewPath = resource_path(
|
||||
(string) str($view)
|
||||
->replace('.', '/')
|
||||
->prepend('views/')
|
||||
->append('.blade.php'),
|
||||
);
|
||||
|
||||
if (! $this->option('force') && $this->checkForCollision([
|
||||
$path,
|
||||
])) {
|
||||
return static::INVALID;
|
||||
}
|
||||
|
||||
$this->copyStubToApp('Entry', $path, [
|
||||
'class' => $entryClass,
|
||||
'namespace' => 'App\\Infolists\\Components' . ($entryNamespace !== '' ? "\\{$entryNamespace}" : ''),
|
||||
'view' => $view,
|
||||
]);
|
||||
|
||||
if (! $this->fileExists($viewPath)) {
|
||||
$this->copyStubToApp('EntryView', $viewPath);
|
||||
}
|
||||
|
||||
$this->components->info("Filament infolist entry [{$path}] created successfully.");
|
||||
|
||||
return static::SUCCESS;
|
||||
}
|
||||
}
|
||||
76
vendor/filament/infolists/src/Commands/MakeLayoutComponentCommand.php
vendored
Normal file
76
vendor/filament/infolists/src/Commands/MakeLayoutComponentCommand.php
vendored
Normal file
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Commands;
|
||||
|
||||
use Filament\Support\Commands\Concerns\CanManipulateFiles;
|
||||
use Illuminate\Console\Command;
|
||||
use Illuminate\Support\Str;
|
||||
use Symfony\Component\Console\Attribute\AsCommand;
|
||||
|
||||
use function Laravel\Prompts\text;
|
||||
|
||||
#[AsCommand(name: 'make:infolist-layout')]
|
||||
class MakeLayoutComponentCommand extends Command
|
||||
{
|
||||
use CanManipulateFiles;
|
||||
|
||||
protected $description = 'Create a new infolist layout component class and view';
|
||||
|
||||
protected $signature = 'make:infolist-layout {name?} {--F|force}';
|
||||
|
||||
public function handle(): int
|
||||
{
|
||||
$component = (string) str($this->argument('name') ?? text(
|
||||
label: 'What is the layout name?',
|
||||
placeholder: 'Wizard',
|
||||
required: true,
|
||||
))
|
||||
->trim('/')
|
||||
->trim('\\')
|
||||
->trim(' ')
|
||||
->replace('/', '\\');
|
||||
$componentClass = (string) str($component)->afterLast('\\');
|
||||
$componentNamespace = str($component)->contains('\\') ?
|
||||
(string) str($component)->beforeLast('\\') :
|
||||
'';
|
||||
|
||||
$view = str($component)
|
||||
->prepend('infolists\\components\\')
|
||||
->explode('\\')
|
||||
->map(fn ($segment) => Str::kebab($segment))
|
||||
->implode('.');
|
||||
|
||||
$path = app_path(
|
||||
(string) str($component)
|
||||
->prepend('Infolists\\Components\\')
|
||||
->replace('\\', '/')
|
||||
->append('.php'),
|
||||
);
|
||||
$viewPath = resource_path(
|
||||
(string) str($view)
|
||||
->replace('.', '/')
|
||||
->prepend('views/')
|
||||
->append('.blade.php'),
|
||||
);
|
||||
|
||||
if (! $this->option('force') && $this->checkForCollision([
|
||||
$path,
|
||||
])) {
|
||||
return static::INVALID;
|
||||
}
|
||||
|
||||
$this->copyStubToApp('LayoutComponent', $path, [
|
||||
'class' => $componentClass,
|
||||
'namespace' => 'App\\Infolists\\Components' . ($componentNamespace !== '' ? "\\{$componentNamespace}" : ''),
|
||||
'view' => $view,
|
||||
]);
|
||||
|
||||
if (! $this->fileExists($viewPath)) {
|
||||
$this->copyStubToApp('LayoutComponentView', $viewPath);
|
||||
}
|
||||
|
||||
$this->components->info("Filament infolist layout component [{$path}] created successfully.");
|
||||
|
||||
return static::SUCCESS;
|
||||
}
|
||||
}
|
||||
69
vendor/filament/infolists/src/ComponentContainer.php
vendored
Normal file
69
vendor/filament/infolists/src/ComponentContainer.php
vendored
Normal file
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists;
|
||||
|
||||
use Filament\Support\Components\ViewComponent;
|
||||
use Filament\Support\Concerns\HasExtraAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Livewire\Component;
|
||||
|
||||
class ComponentContainer extends ViewComponent
|
||||
{
|
||||
use Concerns\BelongsToLivewire;
|
||||
use Concerns\BelongsToParentComponent;
|
||||
use Concerns\CanBeHidden;
|
||||
use Concerns\Cloneable;
|
||||
use Concerns\HasColumns;
|
||||
use Concerns\HasComponents;
|
||||
use Concerns\HasEntryWrapper;
|
||||
use Concerns\HasInlineLabels;
|
||||
use Concerns\HasState;
|
||||
use HasExtraAttributes;
|
||||
|
||||
protected string $view = 'filament-infolists::component-container';
|
||||
|
||||
protected string $evaluationIdentifier = 'container';
|
||||
|
||||
protected string $viewIdentifier = 'container';
|
||||
|
||||
final public function __construct(?Component $livewire = null)
|
||||
{
|
||||
$this->livewire($livewire);
|
||||
}
|
||||
|
||||
public static function make(?Component $livewire = null): static
|
||||
{
|
||||
$static = app(static::class, ['livewire' => $livewire]);
|
||||
$static->configure();
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function resolveDefaultClosureDependencyForEvaluationByName(string $parameterName): array
|
||||
{
|
||||
return match ($parameterName) {
|
||||
'record' => [$this->getRecord()],
|
||||
default => parent::resolveDefaultClosureDependencyForEvaluationByName($parameterName),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function resolveDefaultClosureDependencyForEvaluationByType(string $parameterType): array
|
||||
{
|
||||
$record = $this->getRecord();
|
||||
|
||||
if (! $record) {
|
||||
return parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType);
|
||||
}
|
||||
|
||||
return match ($parameterType) {
|
||||
Model::class, $record::class => [$record],
|
||||
default => parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType),
|
||||
};
|
||||
}
|
||||
}
|
||||
62
vendor/filament/infolists/src/Components/Actions.php
vendored
Normal file
62
vendor/filament/infolists/src/Components/Actions.php
vendored
Normal file
@@ -0,0 +1,62 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components;
|
||||
|
||||
use Closure;
|
||||
use Filament\Infolists\Components\Actions\Action;
|
||||
use Filament\Support\Concerns\HasAlignment;
|
||||
use Filament\Support\Concerns\HasVerticalAlignment;
|
||||
|
||||
class Actions extends Component
|
||||
{
|
||||
use HasAlignment;
|
||||
use HasVerticalAlignment;
|
||||
|
||||
protected string $view = 'filament-infolists::components.actions';
|
||||
|
||||
protected bool | Closure $isFullWidth = false;
|
||||
|
||||
/**
|
||||
* @param array<Action> $actions
|
||||
*/
|
||||
final public function __construct(array $actions)
|
||||
{
|
||||
$this->actions($actions);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<Action> $actions
|
||||
*/
|
||||
public static function make(array $actions): static
|
||||
{
|
||||
$static = app(static::class, ['actions' => $actions]);
|
||||
$static->configure();
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<Action> $actions
|
||||
*/
|
||||
public function actions(array $actions): static
|
||||
{
|
||||
$this->childComponents(array_map(
|
||||
fn (Action $action): Component => $action->toInfolistComponent(),
|
||||
$actions,
|
||||
));
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function fullWidth(bool | Closure $isFullWidth = true): static
|
||||
{
|
||||
$this->isFullWidth = $isFullWidth;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isFullWidth(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isFullWidth);
|
||||
}
|
||||
}
|
||||
100
vendor/filament/infolists/src/Components/Actions/Action.php
vendored
Normal file
100
vendor/filament/infolists/src/Components/Actions/Action.php
vendored
Normal file
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Actions;
|
||||
|
||||
use Exception;
|
||||
use Filament\Actions\MountableAction;
|
||||
use Filament\Actions\StaticAction;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Action extends MountableAction
|
||||
{
|
||||
use Concerns\BelongsToInfolist;
|
||||
|
||||
public function getLivewireCallMountedActionName(): string
|
||||
{
|
||||
return 'callMountedInfolistAction';
|
||||
}
|
||||
|
||||
public function getLivewireClickHandler(): ?string
|
||||
{
|
||||
if (! $this->isLivewireClickHandlerEnabled()) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (is_string($this->action)) {
|
||||
return $this->action;
|
||||
}
|
||||
|
||||
if ($event = $this->getLivewireEventClickHandler()) {
|
||||
return $event;
|
||||
}
|
||||
|
||||
$component = $this->getComponent();
|
||||
|
||||
if (! $component) {
|
||||
return "mountInfolistAction('{$this->getName()}')";
|
||||
}
|
||||
|
||||
$componentKey = $component->getKey();
|
||||
|
||||
if (blank($componentKey)) {
|
||||
$componentClass = $this->getComponent()::class;
|
||||
|
||||
throw new Exception("The infolist component [{$componentClass}] must have a [key()] set in order to use actions. This [key()] must be a unique identifier for the component.");
|
||||
}
|
||||
|
||||
return "mountInfolistAction('{$this->getName()}', '{$componentKey}', '{$component->getInfolist()->getName()}')";
|
||||
}
|
||||
|
||||
public function toInfolistComponent(): ActionContainer
|
||||
{
|
||||
return ActionContainer::make($this);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function resolveDefaultClosureDependencyForEvaluationByName(string $parameterName): array
|
||||
{
|
||||
return match ($parameterName) {
|
||||
'component', 'infolistComponent' => [$this->getComponent()],
|
||||
'record' => [$this->getComponent()->getRecord()],
|
||||
'infolist' => [$this->getInfolist()],
|
||||
default => parent::resolveDefaultClosureDependencyForEvaluationByName($parameterName),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function resolveDefaultClosureDependencyForEvaluationByType(string $parameterType): array
|
||||
{
|
||||
$record = $this->getRecord();
|
||||
|
||||
if (! $record) {
|
||||
return parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType);
|
||||
}
|
||||
|
||||
return match ($parameterType) {
|
||||
Model::class, $record::class => [$record],
|
||||
default => parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType),
|
||||
};
|
||||
}
|
||||
|
||||
public function prepareModalAction(StaticAction $action): StaticAction
|
||||
{
|
||||
$action = parent::prepareModalAction($action);
|
||||
|
||||
if (! $action instanceof Action) {
|
||||
return $action;
|
||||
}
|
||||
|
||||
return $action->component($this->getComponent());
|
||||
}
|
||||
|
||||
public function getInfolistName(): string
|
||||
{
|
||||
return 'mountedInfolistActionsInfolist';
|
||||
}
|
||||
}
|
||||
33
vendor/filament/infolists/src/Components/Actions/ActionContainer.php
vendored
Normal file
33
vendor/filament/infolists/src/Components/Actions/ActionContainer.php
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Actions;
|
||||
|
||||
use Filament\Infolists\Components\Component;
|
||||
|
||||
class ActionContainer extends Component
|
||||
{
|
||||
protected string $view = 'filament-infolists::components.actions.action-container';
|
||||
|
||||
final public function __construct(Action $action)
|
||||
{
|
||||
$this->action($action);
|
||||
}
|
||||
|
||||
public static function make(Action $action): static
|
||||
{
|
||||
$static = app(static::class, ['action' => $action]);
|
||||
$static->configure();
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
public function getKey(): string
|
||||
{
|
||||
return parent::getKey() ?? "{$this->getStatePath()}.{$this->getAction()->getName()}Action";
|
||||
}
|
||||
|
||||
public function isHidden(): bool
|
||||
{
|
||||
return $this->getAction()->isHidden();
|
||||
}
|
||||
}
|
||||
41
vendor/filament/infolists/src/Components/Actions/Concerns/BelongsToInfolist.php
vendored
Normal file
41
vendor/filament/infolists/src/Components/Actions/Concerns/BelongsToInfolist.php
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Actions\Concerns;
|
||||
|
||||
use Exception;
|
||||
use Filament\Infolists\Components\Component;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Livewire\Component as LivewireComponent;
|
||||
|
||||
trait BelongsToInfolist
|
||||
{
|
||||
protected ?Component $component = null;
|
||||
|
||||
public function component(?Component $component): static
|
||||
{
|
||||
$this->component = $component;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getComponent(): ?Component
|
||||
{
|
||||
return $this->component;
|
||||
}
|
||||
|
||||
public function getLivewire(): LivewireComponent
|
||||
{
|
||||
$livewire = $this->getComponent()->getInfolist()->getLivewire();
|
||||
|
||||
if (! $livewire) {
|
||||
throw new Exception('An infolist tried to mount an action but was not mounted to Livewire.');
|
||||
}
|
||||
|
||||
return $livewire;
|
||||
}
|
||||
|
||||
public function getRecord(): ?Model
|
||||
{
|
||||
return $this->getComponent()->getInfolist()->getRecord();
|
||||
}
|
||||
}
|
||||
10
vendor/filament/infolists/src/Components/Card.php
vendored
Normal file
10
vendor/filament/infolists/src/Components/Card.php
vendored
Normal file
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components;
|
||||
|
||||
/**
|
||||
* @deprecated Use `Section` with an empty heading instead.
|
||||
*/
|
||||
class Card extends Section
|
||||
{
|
||||
}
|
||||
15
vendor/filament/infolists/src/Components/ColorEntry.php
vendored
Normal file
15
vendor/filament/infolists/src/Components/ColorEntry.php
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components;
|
||||
|
||||
use Filament\Support\Concerns\CanBeCopied;
|
||||
|
||||
class ColorEntry extends Entry
|
||||
{
|
||||
use CanBeCopied;
|
||||
|
||||
/**
|
||||
* @var view-string
|
||||
*/
|
||||
protected string $view = 'filament-infolists::components.color-entry';
|
||||
}
|
||||
61
vendor/filament/infolists/src/Components/Component.php
vendored
Normal file
61
vendor/filament/infolists/src/Components/Component.php
vendored
Normal file
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components;
|
||||
|
||||
use Filament\Infolists\Concerns\HasColumns;
|
||||
use Filament\Support\Components\ViewComponent;
|
||||
use Filament\Support\Concerns\CanGrow;
|
||||
use Filament\Support\Concerns\HasExtraAttributes;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
|
||||
class Component extends ViewComponent
|
||||
{
|
||||
use CanGrow;
|
||||
use Concerns\BelongsToContainer;
|
||||
use Concerns\CanBeHidden;
|
||||
use Concerns\CanSpanColumns;
|
||||
use Concerns\Cloneable;
|
||||
use Concerns\HasActions;
|
||||
use Concerns\HasChildComponents;
|
||||
use Concerns\HasEntryWrapper;
|
||||
use Concerns\HasId;
|
||||
use Concerns\HasInlineLabel;
|
||||
use Concerns\HasKey;
|
||||
use Concerns\HasLabel;
|
||||
use Concerns\HasMaxWidth;
|
||||
use Concerns\HasMeta;
|
||||
use Concerns\HasState;
|
||||
use HasColumns;
|
||||
use HasExtraAttributes;
|
||||
|
||||
protected string $evaluationIdentifier = 'component';
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function resolveDefaultClosureDependencyForEvaluationByName(string $parameterName): array
|
||||
{
|
||||
return match ($parameterName) {
|
||||
'record' => [$this->getRecord()],
|
||||
'state' => [$this->getState()],
|
||||
default => parent::resolveDefaultClosureDependencyForEvaluationByName($parameterName),
|
||||
};
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<mixed>
|
||||
*/
|
||||
protected function resolveDefaultClosureDependencyForEvaluationByType(string $parameterType): array
|
||||
{
|
||||
$record = $this->getRecord();
|
||||
|
||||
if (! $record) {
|
||||
return parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType);
|
||||
}
|
||||
|
||||
return match ($parameterType) {
|
||||
Model::class, $record::class => [$record],
|
||||
default => parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType),
|
||||
};
|
||||
}
|
||||
}
|
||||
34
vendor/filament/infolists/src/Components/Concerns/BelongsToContainer.php
vendored
Normal file
34
vendor/filament/infolists/src/Components/Concerns/BelongsToContainer.php
vendored
Normal file
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Filament\Infolists\ComponentContainer;
|
||||
use Filament\Infolists\Infolist;
|
||||
use Livewire\Component;
|
||||
|
||||
trait BelongsToContainer
|
||||
{
|
||||
protected ComponentContainer $container;
|
||||
|
||||
public function container(ComponentContainer $container): static
|
||||
{
|
||||
$this->container = $container;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getContainer(): ComponentContainer
|
||||
{
|
||||
return $this->container;
|
||||
}
|
||||
|
||||
public function getInfolist(): Infolist
|
||||
{
|
||||
return $this->getContainer()->getInfolist();
|
||||
}
|
||||
|
||||
public function getLivewire(): ?Component
|
||||
{
|
||||
return $this->getContainer()->getLivewire();
|
||||
}
|
||||
}
|
||||
54
vendor/filament/infolists/src/Components/Concerns/CanBeCollapsed.php
vendored
Normal file
54
vendor/filament/infolists/src/Components/Concerns/CanBeCollapsed.php
vendored
Normal file
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait CanBeCollapsed
|
||||
{
|
||||
protected bool | Closure $isCollapsed = false;
|
||||
|
||||
protected bool | Closure | null $isCollapsible = null;
|
||||
|
||||
protected bool | Closure $shouldPersistCollapsed = false;
|
||||
|
||||
public function collapsed(bool | Closure $condition = true, bool $shouldMakeComponentCollapsible = true): static
|
||||
{
|
||||
$this->isCollapsed = $condition;
|
||||
|
||||
if ($shouldMakeComponentCollapsible && ($this->isCollapsible === null)) {
|
||||
$this->collapsible();
|
||||
}
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isCollapsed(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isCollapsed);
|
||||
}
|
||||
|
||||
public function collapsible(bool | Closure | null $condition = true): static
|
||||
{
|
||||
$this->isCollapsible = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isCollapsible(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isCollapsible);
|
||||
}
|
||||
|
||||
public function persistCollapsed(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->shouldPersistCollapsed = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function shouldPersistCollapsed(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->shouldPersistCollapsed);
|
||||
}
|
||||
}
|
||||
22
vendor/filament/infolists/src/Components/Concerns/CanBeCompacted.php
vendored
Normal file
22
vendor/filament/infolists/src/Components/Concerns/CanBeCompacted.php
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait CanBeCompacted
|
||||
{
|
||||
protected bool | Closure $isCompact = false;
|
||||
|
||||
public function compact(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->isCompact = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isCompact(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isCompact);
|
||||
}
|
||||
}
|
||||
56
vendor/filament/infolists/src/Components/Concerns/CanBeHidden.php
vendored
Normal file
56
vendor/filament/infolists/src/Components/Concerns/CanBeHidden.php
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Filament\Infolists\Components\Component;
|
||||
|
||||
trait CanBeHidden
|
||||
{
|
||||
protected bool | Closure $isHidden = false;
|
||||
|
||||
protected bool | Closure $isVisible = true;
|
||||
|
||||
public function hidden(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->isHidden = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function hiddenWhenAllChildComponentsHidden(): static
|
||||
{
|
||||
$this->hidden(static function (Component $component): bool {
|
||||
foreach ($component->getChildComponentContainers() as $childComponentContainer) {
|
||||
foreach ($childComponentContainer->getComponents(withHidden: false) as $childComponent) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function visible(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->isVisible = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isHidden(): bool
|
||||
{
|
||||
if ($this->evaluate($this->isHidden)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return ! $this->evaluate($this->isVisible);
|
||||
}
|
||||
|
||||
public function isVisible(): bool
|
||||
{
|
||||
return ! $this->isHidden();
|
||||
}
|
||||
}
|
||||
360
vendor/filament/infolists/src/Components/Concerns/CanFormatState.php
vendored
Normal file
360
vendor/filament/infolists/src/Components/Concerns/CanFormatState.php
vendored
Normal file
@@ -0,0 +1,360 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Closure;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Infolists\Infolist;
|
||||
use Filament\Support\Contracts\HasLabel as LabelInterface;
|
||||
use Filament\Support\Enums\ArgumentValue;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
use Illuminate\Support\Carbon;
|
||||
use Illuminate\Support\HtmlString;
|
||||
use Illuminate\Support\Number;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
trait CanFormatState
|
||||
{
|
||||
protected ?Closure $formatStateUsing = null;
|
||||
|
||||
protected int | Closure | null $characterLimit = null;
|
||||
|
||||
protected string | Closure | null $characterLimitEnd = null;
|
||||
|
||||
protected int | Closure | null $wordLimit = null;
|
||||
|
||||
protected string | Closure | null $wordLimitEnd = null;
|
||||
|
||||
protected string | Htmlable | Closure | null $prefix = null;
|
||||
|
||||
protected string | Htmlable | Closure | null $suffix = null;
|
||||
|
||||
protected string | Closure | null $timezone = null;
|
||||
|
||||
protected bool | Closure $isHtml = false;
|
||||
|
||||
protected bool | Closure $isMarkdown = false;
|
||||
|
||||
protected bool $isDate = false;
|
||||
|
||||
protected bool $isDateTime = false;
|
||||
|
||||
protected bool $isMoney = false;
|
||||
|
||||
protected bool $isNumeric = false;
|
||||
|
||||
protected bool $isTime = false;
|
||||
|
||||
public function markdown(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->isMarkdown = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function date(?string $format = null, ?string $timezone = null): static
|
||||
{
|
||||
$this->isDate = true;
|
||||
|
||||
$format ??= Infolist::$defaultDateDisplayFormat;
|
||||
|
||||
$this->formatStateUsing(static function (TextEntry $component, $state) use ($format, $timezone): ?string {
|
||||
if (blank($state)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Carbon::parse($state)
|
||||
->setTimezone($timezone ?? $component->getTimezone())
|
||||
->translatedFormat($format);
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function dateTime(?string $format = null, ?string $timezone = null): static
|
||||
{
|
||||
$this->isDateTime = true;
|
||||
|
||||
$format ??= Infolist::$defaultDateTimeDisplayFormat;
|
||||
|
||||
$this->date($format, $timezone);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function since(?string $timezone = null): static
|
||||
{
|
||||
$this->isDateTime = true;
|
||||
|
||||
$this->formatStateUsing(static function (TextEntry $component, $state) use ($timezone): ?string {
|
||||
if (blank($state)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return Carbon::parse($state)
|
||||
->setTimezone($timezone ?? $component->getTimezone())
|
||||
->diffForHumans();
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function money(string | Closure | null $currency = null, int $divideBy = 0, string | Closure | null $locale = null): static
|
||||
{
|
||||
$this->isMoney = true;
|
||||
|
||||
$this->formatStateUsing(static function (TextEntry $component, $state) use ($currency, $divideBy, $locale): ?string {
|
||||
if (blank($state)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! is_numeric($state)) {
|
||||
return $state;
|
||||
}
|
||||
|
||||
$currency = $component->evaluate($currency) ?? Infolist::$defaultCurrency;
|
||||
|
||||
if ($divideBy) {
|
||||
$state /= $divideBy;
|
||||
}
|
||||
|
||||
return Number::currency($state, $currency, $component->evaluate($locale) ?? config('app.locale'));
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function numeric(int | Closure | null $decimalPlaces = null, string | Closure | null | ArgumentValue $decimalSeparator = ArgumentValue::Default, string | Closure | null | ArgumentValue $thousandsSeparator = ArgumentValue::Default, int | Closure | null $maxDecimalPlaces = null, string | Closure | null $locale = null): static
|
||||
{
|
||||
$this->isNumeric = true;
|
||||
|
||||
$this->formatStateUsing(static function (TextEntry $component, $state) use ($decimalPlaces, $decimalSeparator, $locale, $maxDecimalPlaces, $thousandsSeparator): ?string {
|
||||
if (blank($state)) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (! is_numeric($state)) {
|
||||
return $state;
|
||||
}
|
||||
|
||||
$decimalPlaces = $component->evaluate($decimalPlaces);
|
||||
$decimalSeparator = $component->evaluate($decimalSeparator);
|
||||
$thousandsSeparator = $component->evaluate($thousandsSeparator);
|
||||
|
||||
if (
|
||||
($decimalSeparator !== ArgumentValue::Default) ||
|
||||
($thousandsSeparator !== ArgumentValue::Default)
|
||||
) {
|
||||
return number_format(
|
||||
$state,
|
||||
$decimalPlaces,
|
||||
$decimalSeparator === ArgumentValue::Default ? '.' : $decimalSeparator,
|
||||
$thousandsSeparator === ArgumentValue::Default ? ',' : $thousandsSeparator,
|
||||
);
|
||||
}
|
||||
|
||||
return Number::format($state, $decimalPlaces, $component->evaluate($maxDecimalPlaces), $component->evaluate($locale) ?? config('app.locale'));
|
||||
});
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function time(?string $format = null, ?string $timezone = null): static
|
||||
{
|
||||
$this->isTime = true;
|
||||
|
||||
$format ??= Infolist::$defaultTimeDisplayFormat;
|
||||
|
||||
$this->date($format, $timezone);
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function timezone(string | Closure | null $timezone): static
|
||||
{
|
||||
$this->timezone = $timezone;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function limit(int | Closure | null $length = 100, string | Closure | null $end = '...'): static
|
||||
{
|
||||
$this->characterLimit = $length;
|
||||
$this->characterLimitEnd = $end;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function words(int | Closure | null $words = 100, string | Closure | null $end = '...'): static
|
||||
{
|
||||
$this->wordLimit = $words;
|
||||
$this->wordLimitEnd = $end;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function prefix(string | Htmlable | Closure | null $prefix): static
|
||||
{
|
||||
$this->prefix = $prefix;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function suffix(string | Htmlable | Closure | null $suffix): static
|
||||
{
|
||||
$this->suffix = $suffix;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function html(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->isHtml = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function formatStateUsing(?Closure $callback): static
|
||||
{
|
||||
$this->formatStateUsing = $callback;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function formatState(mixed $state): mixed
|
||||
{
|
||||
$isHtml = $this->isHtml();
|
||||
|
||||
$state = $this->evaluate($this->formatStateUsing ?? $state, [
|
||||
'state' => $state,
|
||||
]);
|
||||
|
||||
if ($isHtml) {
|
||||
$state = Str::sanitizeHtml($state);
|
||||
}
|
||||
|
||||
if ($state instanceof Htmlable) {
|
||||
$isHtml = true;
|
||||
$state = $state->toHtml();
|
||||
}
|
||||
|
||||
if ($state instanceof LabelInterface) {
|
||||
$state = $state->getLabel();
|
||||
}
|
||||
|
||||
if ($characterLimit = $this->getCharacterLimit()) {
|
||||
$state = Str::limit($state, $characterLimit, $this->getCharacterLimitEnd());
|
||||
}
|
||||
|
||||
if ($wordLimit = $this->getWordLimit()) {
|
||||
$state = Str::words($state, $wordLimit, $this->getWordLimitEnd());
|
||||
}
|
||||
|
||||
if ($isHtml && $this->isMarkdown()) {
|
||||
$state = Str::markdown($state);
|
||||
}
|
||||
|
||||
$prefix = $this->getPrefix();
|
||||
$suffix = $this->getSuffix();
|
||||
|
||||
if (
|
||||
(($prefix instanceof Htmlable) || ($suffix instanceof Htmlable)) &&
|
||||
(! $isHtml)
|
||||
) {
|
||||
$isHtml = true;
|
||||
$state = e($state);
|
||||
}
|
||||
|
||||
if (filled($prefix)) {
|
||||
if ($prefix instanceof Htmlable) {
|
||||
$prefix = $prefix->toHtml();
|
||||
} elseif ($isHtml) {
|
||||
$prefix = e($prefix);
|
||||
}
|
||||
|
||||
$state = $prefix . $state;
|
||||
}
|
||||
|
||||
if (filled($suffix)) {
|
||||
if ($suffix instanceof Htmlable) {
|
||||
$suffix = $suffix->toHtml();
|
||||
} elseif ($isHtml) {
|
||||
$suffix = e($suffix);
|
||||
}
|
||||
|
||||
$state = $state . $suffix;
|
||||
}
|
||||
|
||||
return $isHtml ? new HtmlString($state) : $state;
|
||||
}
|
||||
|
||||
public function getCharacterLimit(): ?int
|
||||
{
|
||||
return $this->evaluate($this->characterLimit);
|
||||
}
|
||||
|
||||
public function getCharacterLimitEnd(): ?string
|
||||
{
|
||||
return $this->evaluate($this->characterLimitEnd);
|
||||
}
|
||||
|
||||
public function getWordLimit(): ?int
|
||||
{
|
||||
return $this->evaluate($this->wordLimit);
|
||||
}
|
||||
|
||||
public function getWordLimitEnd(): ?string
|
||||
{
|
||||
return $this->evaluate($this->wordLimitEnd);
|
||||
}
|
||||
|
||||
public function getTimezone(): string
|
||||
{
|
||||
return $this->evaluate($this->timezone) ?? config('app.timezone');
|
||||
}
|
||||
|
||||
public function isHtml(): bool
|
||||
{
|
||||
return $this->evaluate($this->isHtml) || $this->isMarkdown() || $this->isProse();
|
||||
}
|
||||
|
||||
public function getPrefix(): string | Htmlable | null
|
||||
{
|
||||
return $this->evaluate($this->prefix);
|
||||
}
|
||||
|
||||
public function getSuffix(): string | Htmlable | null
|
||||
{
|
||||
return $this->evaluate($this->suffix);
|
||||
}
|
||||
|
||||
public function isMarkdown(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isMarkdown);
|
||||
}
|
||||
|
||||
public function isDate(): bool
|
||||
{
|
||||
return $this->isDate;
|
||||
}
|
||||
|
||||
public function isDateTime(): bool
|
||||
{
|
||||
return $this->isDateTime;
|
||||
}
|
||||
|
||||
public function isMoney(): bool
|
||||
{
|
||||
return $this->isMoney;
|
||||
}
|
||||
|
||||
public function isNumeric(): bool
|
||||
{
|
||||
return $this->isNumeric;
|
||||
}
|
||||
|
||||
public function isTime(): bool
|
||||
{
|
||||
return $this->isTime;
|
||||
}
|
||||
}
|
||||
113
vendor/filament/infolists/src/Components/Concerns/CanGetStateFromRelationships.php
vendored
Normal file
113
vendor/filament/infolists/src/Components/Concerns/CanGetStateFromRelationships.php
vendored
Normal file
@@ -0,0 +1,113 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
trait CanGetStateFromRelationships
|
||||
{
|
||||
public function hasRelationship(Model $record): bool
|
||||
{
|
||||
return $this->getRelationship($record) !== null;
|
||||
}
|
||||
|
||||
public function getRelationship(Model $record, ?string $statePath = null): ?Relation
|
||||
{
|
||||
if (blank($statePath) && (! str($this->getStatePath())->contains('.'))) {
|
||||
return null;
|
||||
}
|
||||
|
||||
$relationship = null;
|
||||
|
||||
foreach (explode('.', $statePath ?? $this->getRelationshipName()) as $nestedRelationshipName) {
|
||||
if (! $record->isRelation($nestedRelationshipName)) {
|
||||
$relationship = null;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$relationship = $record->{$nestedRelationshipName}();
|
||||
$record = $relationship->getRelated();
|
||||
}
|
||||
|
||||
return $relationship;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string> | null $relationships
|
||||
* @return array<Model>
|
||||
*/
|
||||
public function getRelationshipResults(Model $record, ?array $relationships = null): array
|
||||
{
|
||||
$results = [];
|
||||
|
||||
$relationships ??= explode('.', $this->getRelationshipName());
|
||||
|
||||
while (count($relationships)) {
|
||||
$currentRelationshipName = array_shift($relationships);
|
||||
|
||||
$currentRelationshipValue = $record->getRelationValue($currentRelationshipName);
|
||||
|
||||
if ($currentRelationshipValue instanceof Collection) {
|
||||
if (! count($relationships)) {
|
||||
$results = [
|
||||
...$results,
|
||||
...$currentRelationshipValue->all(),
|
||||
];
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
foreach ($currentRelationshipValue as $valueRecord) {
|
||||
$results = [
|
||||
...$results,
|
||||
...$this->getRelationshipResults(
|
||||
$valueRecord,
|
||||
$relationships,
|
||||
),
|
||||
];
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (! $currentRelationshipValue instanceof Model) {
|
||||
break;
|
||||
}
|
||||
|
||||
if (! count($relationships)) {
|
||||
$results[] = $currentRelationshipValue;
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
$record = $currentRelationshipValue;
|
||||
}
|
||||
|
||||
return $results;
|
||||
}
|
||||
|
||||
public function getRelationshipAttribute(?string $statePath = null): string
|
||||
{
|
||||
$statePath ??= $this->getStatePath();
|
||||
|
||||
if (! str($statePath)->contains('.')) {
|
||||
return $statePath;
|
||||
}
|
||||
|
||||
return (string) str($statePath)->afterLast('.');
|
||||
}
|
||||
|
||||
public function getRelationshipName(?string $statePath = null): ?string
|
||||
{
|
||||
$statePath ??= $this->getStatePath();
|
||||
|
||||
if (! str($statePath)->contains('.')) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return (string) str($statePath)->beforeLast('.');
|
||||
}
|
||||
}
|
||||
37
vendor/filament/infolists/src/Components/Concerns/CanOpenUrl.php
vendored
Normal file
37
vendor/filament/infolists/src/Components/Concerns/CanOpenUrl.php
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait CanOpenUrl
|
||||
{
|
||||
protected bool | Closure $shouldOpenUrlInNewTab = false;
|
||||
|
||||
protected string | Closure | null $url = null;
|
||||
|
||||
public function openUrlInNewTab(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->shouldOpenUrlInNewTab = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function url(string | Closure | null $url, bool | Closure $shouldOpenInNewTab = false): static
|
||||
{
|
||||
$this->openUrlInNewTab($shouldOpenInNewTab);
|
||||
$this->url = $url;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getUrl(): ?string
|
||||
{
|
||||
return $this->evaluate($this->url);
|
||||
}
|
||||
|
||||
public function shouldOpenUrlInNewTab(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->shouldOpenUrlInNewTab);
|
||||
}
|
||||
}
|
||||
111
vendor/filament/infolists/src/Components/Concerns/CanSpanColumns.php
vendored
Normal file
111
vendor/filament/infolists/src/Components/Concerns/CanSpanColumns.php
vendored
Normal file
@@ -0,0 +1,111 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\Concerns;
|
||||
|
||||
use Closure;
|
||||
|
||||
trait CanSpanColumns
|
||||
{
|
||||
/**
|
||||
* @var array<string, int | string | Closure | null>
|
||||
*/
|
||||
protected array $columnSpan = [
|
||||
'default' => 1,
|
||||
'sm' => null,
|
||||
'md' => null,
|
||||
'lg' => null,
|
||||
'xl' => null,
|
||||
'2xl' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* @var array<string, int | string | Closure | null>
|
||||
*/
|
||||
protected array $columnStart = [
|
||||
'default' => null,
|
||||
'sm' => null,
|
||||
'md' => null,
|
||||
'lg' => null,
|
||||
'xl' => null,
|
||||
'2xl' => null,
|
||||
];
|
||||
|
||||
/**
|
||||
* @param array<string, int | string | Closure | null> | int | string | Closure | null $span
|
||||
*/
|
||||
public function columnSpan(array | int | string | Closure | null $span): static
|
||||
{
|
||||
if (! is_array($span)) {
|
||||
$span = [
|
||||
'default' => $span,
|
||||
];
|
||||
}
|
||||
|
||||
$this->columnSpan = [
|
||||
...$this->columnSpan,
|
||||
...$span,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function columnSpanFull(): static
|
||||
{
|
||||
$this->columnSpan('full');
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array<string, int | string | Closure | null> | int | string | Closure | null $start
|
||||
*/
|
||||
public function columnStart(array | int | string | Closure | null $start): static
|
||||
{
|
||||
if (! is_array($start)) {
|
||||
$start = [
|
||||
'default' => $start,
|
||||
];
|
||||
}
|
||||
|
||||
$this->columnStart = [
|
||||
...$this->columnStart,
|
||||
...$start,
|
||||
];
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, int | string | Closure | null> | int | string | null
|
||||
*/
|
||||
public function getColumnSpan(int | string | null $breakpoint = null): array | int | string | null
|
||||
{
|
||||
$span = $this->columnSpan;
|
||||
|
||||
if ($breakpoint !== null) {
|
||||
return $this->evaluate($span[$breakpoint] ?? null);
|
||||
}
|
||||
|
||||
return array_map(
|
||||
fn (array | int | string | Closure | null $value): array | int | string | null => $this->evaluate($value),
|
||||
$span,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<string, int | string | Closure | null> | int | string | null
|
||||
*/
|
||||
public function getColumnStart(int | string | null $breakpoint = null): array | int | string | null
|
||||
{
|
||||
$start = $this->columnStart;
|
||||
|
||||
if ($breakpoint !== null) {
|
||||
return $this->evaluate($start[$breakpoint] ?? null);
|
||||
}
|
||||
|
||||
return array_map(
|
||||
fn (array | int | string | Closure | null $value): array | int | string | null => $this->evaluate($value),
|
||||
$start,
|
||||
);
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user