mirror of
https://github.com/filamentphp/filament.git
synced 2026-09-21 21:55:11 +08:00
feat: Add RepeatableEntry table layout and TableColumn component (#17865)
* Add RepeatableEntry table layout and TableColumn component with tests * chore: fix code style * consistency with repeater * Update EntriesDemo.php --------- Co-authored-by: oddvalue <oddvalue@users.noreply.github.com> Co-authored-by: Dan Harrin <git@danharrin.com>
This commit is contained in:
co-authored by
oddvalue
Dan Harrin
parent
73fd07ee07
commit
7c5cd978d7
@@ -9,6 +9,7 @@ use Filament\Infolists\Components\IconEntry;
|
||||
use Filament\Infolists\Components\ImageEntry;
|
||||
use Filament\Infolists\Components\KeyValueEntry;
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
use Filament\Schemas\Components\Flex;
|
||||
use Filament\Schemas\Components\Group;
|
||||
@@ -714,6 +715,25 @@ class EntriesDemo extends Component implements HasSchemas
|
||||
->columns(2)
|
||||
->grid(2),
|
||||
]),
|
||||
Group::make()
|
||||
->id('repeatableTable')
|
||||
->extraAttributes([
|
||||
'class' => 'p-16 max-w-5xl',
|
||||
])
|
||||
->schema([
|
||||
RepeatableEntry::make('comments')
|
||||
->table([
|
||||
TableColumn::make('Author'),
|
||||
TableColumn::make('Title'),
|
||||
TableColumn::make('Published'),
|
||||
])
|
||||
->schema([
|
||||
TextEntry::make('author'),
|
||||
TextEntry::make('title'),
|
||||
IconEntry::make('is_published')
|
||||
->boolean(),
|
||||
]),
|
||||
]),
|
||||
Group::make()
|
||||
->id('suffixAction')
|
||||
->extraAttributes([
|
||||
@@ -736,11 +756,13 @@ class EntriesDemo extends Component implements HasSchemas
|
||||
'author' => ['name' => 'Jane Doe'],
|
||||
'title' => 'Wow!',
|
||||
'content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod, nisl eget aliquam ultricies, nunc nisl aliquet nunc, quis aliquam nisl.',
|
||||
'is_published' => true,
|
||||
],
|
||||
[
|
||||
'author' => ['name' => 'John Doe'],
|
||||
'title' => 'This isn\'t working. Help!',
|
||||
'content' => 'Lorem ipsum dolor sit amet, consectetur adipiscing elit. Nullam euismod, nisl eget aliquam ultricies, nunc nisl aliquet nunc, quis aliquam nisl.',
|
||||
'is_published' => false,
|
||||
],
|
||||
],
|
||||
]);
|
||||
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 51 KiB |
Binary file not shown.
|
After Width: | Height: | Size: 55 KiB |
@@ -2228,6 +2228,15 @@ export default {
|
||||
deviceScaleFactor: 3,
|
||||
},
|
||||
},
|
||||
'infolists/entries/repeatable/table': {
|
||||
url: 'infolists/entries',
|
||||
selector: '#repeatableTable',
|
||||
viewport: {
|
||||
width: 1920,
|
||||
height: 640,
|
||||
deviceScaleFactor: 3,
|
||||
},
|
||||
},
|
||||
'infolists/entries/actions/suffix': {
|
||||
url: 'infolists/entries',
|
||||
selector: '#suffixAction',
|
||||
|
||||
@@ -158,24 +158,22 @@
|
||||
@endphp
|
||||
|
||||
@if ($schemaComponent->isVisible())
|
||||
<td
|
||||
@if (! (($schemaComponent instanceof Action) || ($schemaComponent instanceof ActionGroup)))
|
||||
@php
|
||||
$schemaComponentStatePath = $schemaComponent->getStatePath();
|
||||
@endphp
|
||||
@php
|
||||
$schemaComponentStatePath = $schemaComponent->getStatePath();
|
||||
@endphp
|
||||
|
||||
x-data="filamentSchemaComponent({
|
||||
path: @js($schemaComponentStatePath),
|
||||
containerPath: @js($itemStatePath),
|
||||
isLive: @js($schemaComponent->isLive()),
|
||||
$wire,
|
||||
})"
|
||||
@if ($afterStateUpdatedJs = $schemaComponent->getAfterStateUpdatedJs())
|
||||
x-init="{{ implode(';', array_map(
|
||||
fn (string $js): string => '$wire.watch(' . Js::from($schemaComponentStatePath) . ', ($state, $old) => ($state !== undefined) && eval(' . Js::from($js) . '))',
|
||||
$afterStateUpdatedJs,
|
||||
)) }}"
|
||||
@endif
|
||||
<td
|
||||
x-data="filamentSchemaComponent({
|
||||
path: @js($schemaComponentStatePath),
|
||||
containerPath: @js($itemStatePath),
|
||||
isLive: @js($schemaComponent->isLive()),
|
||||
$wire,
|
||||
})"
|
||||
@if ($afterStateUpdatedJs = $schemaComponent->getAfterStateUpdatedJs())
|
||||
x-init="{{ implode(';', array_map(
|
||||
fn (string $js): string => '$wire.watch(' . Js::from($schemaComponentStatePath) . ', ($state, $old) => ($state !== undefined) && eval(' . Js::from($js) . '))',
|
||||
$afterStateUpdatedJs,
|
||||
)) }}"
|
||||
@endif
|
||||
>
|
||||
{{ $schemaComponent }}
|
||||
|
||||
@@ -80,3 +80,66 @@ RepeatableEntry::make('comments')
|
||||
```
|
||||
|
||||
<UtilityInjection set="infolistEntries" version="4.x">As well as allowing a static value, the `contained()` method also accepts a function to dynamically calculate it. You can inject various utilities into the function as parameters.</UtilityInjection>
|
||||
|
||||
## Table repeatable layout
|
||||
|
||||
You can present repeatable items in a table format using the `table()` method, which accepts an array of `TableColumn` objects. These objects represent the columns of the table, which correspond to any components in the schema of the entry:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\IconEntry;
|
||||
use Filament\Infolists\Components\RepeatableEntry;
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
use Filament\Infolists\Components\TextEntry;
|
||||
|
||||
RepeatableEntry::make('comments')
|
||||
->table([
|
||||
TableColumn::make('Author'),
|
||||
TableColumn::make('Title'),
|
||||
TableColumn::make('Published'),
|
||||
])
|
||||
->schema([
|
||||
TextEntry::make('author.name'),
|
||||
TextEntry::make('title'),
|
||||
IconEntry::make('is_published')
|
||||
->boolean(),
|
||||
])
|
||||
```
|
||||
|
||||
<AutoScreenshot name="infolists/entries/repeatable/table" alt="Repeatable entry with table layout" version="4.x" />
|
||||
|
||||
The labels displayed in the header of the table are passed to the `TableColumn::make()` method. If you want to provide an accessible label for a column but do not wish to display it, you can use the `hiddenHeaderLabel()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
|
||||
TableColumn::make('Name')
|
||||
->hiddenHeaderLabel()
|
||||
```
|
||||
|
||||
You can enable wrapping of the column header using the `wrapHeader()` method:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
|
||||
TableColumn::make('Name')
|
||||
->wrapHeader()
|
||||
```
|
||||
|
||||
You can also adjust the alignment of the column header using the `alignment()` method, passing an `Alignment` option of `Alignment::Start`, `Alignment::Center`, or `Alignment::End`:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
|
||||
TableColumn::make('Name')
|
||||
->alignment(Alignment::Start)
|
||||
```
|
||||
|
||||
You can set a fixed column width using the `width()` method, passing a string value that represents the width of the column. This value is passed directly to the `style` attribute of the column header:
|
||||
|
||||
```php
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
|
||||
TableColumn::make('Name')
|
||||
->width('200px')
|
||||
```
|
||||
|
||||
@@ -13,3 +13,132 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
.fi-in-table-repeatable {
|
||||
@apply grid gap-3;
|
||||
|
||||
& > table {
|
||||
@apply block w-full divide-y divide-gray-200 rounded-xl bg-white shadow-sm ring-1 ring-gray-950/5 dark:divide-white/10 dark:bg-gray-900 dark:ring-white/10;
|
||||
|
||||
& > thead {
|
||||
@apply hidden whitespace-nowrap;
|
||||
|
||||
& > tr {
|
||||
& > th {
|
||||
@apply border-gray-200 bg-gray-50 px-3 py-2 text-start text-sm font-semibold text-gray-950 first-of-type:rounded-tl-xl last-of-type:rounded-tr-xl dark:border-white/5 dark:bg-white/5 dark:text-white [&:not(:first-of-type)]:border-s [&:not(:last-of-type)]:border-e;
|
||||
|
||||
&.fi-align-center {
|
||||
@apply text-center;
|
||||
}
|
||||
|
||||
&.fi-align-end,
|
||||
&.fi-align-right {
|
||||
@apply text-end;
|
||||
}
|
||||
|
||||
&.fi-wrapped {
|
||||
@apply whitespace-normal;
|
||||
}
|
||||
|
||||
&:not(.fi-wrapped) {
|
||||
@apply whitespace-nowrap;
|
||||
}
|
||||
|
||||
&.fi-in-table-repeatable-empty-header-cell {
|
||||
@apply w-1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& > tbody {
|
||||
@apply block divide-y divide-gray-200 dark:divide-white/5;
|
||||
|
||||
& > tr {
|
||||
@apply grid gap-6 p-6;
|
||||
|
||||
& > td {
|
||||
@apply block;
|
||||
|
||||
&.fi-hidden {
|
||||
@apply hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@supports (container-type: inline-size) {
|
||||
@apply @container;
|
||||
|
||||
& > table {
|
||||
@apply @xl:table;
|
||||
|
||||
& > thead {
|
||||
@apply @xl:table-header-group;
|
||||
}
|
||||
|
||||
& > tbody {
|
||||
@apply @xl:table-row-group;
|
||||
|
||||
& > tr {
|
||||
@apply @xl:table-row @xl:p-0;
|
||||
|
||||
& > td {
|
||||
@apply @xl:table-cell @xl:px-3 @xl:py-2;
|
||||
|
||||
&.fi-hidden {
|
||||
@apply @xl:table-cell;
|
||||
}
|
||||
|
||||
& .fi-in-entry {
|
||||
@apply @xl:gap-y-0;
|
||||
}
|
||||
|
||||
& .fi-in-entry-label {
|
||||
@apply @xl:hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
& .fi-in-table-repeatable-actions {
|
||||
@apply @xl:px-3 @xl:py-2;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@supports not (container-type: inline-size) {
|
||||
& > table {
|
||||
@apply lg:table;
|
||||
|
||||
& > thead {
|
||||
@apply lg:table-header-group;
|
||||
}
|
||||
|
||||
& > tbody {
|
||||
@apply lg:table-row-group;
|
||||
|
||||
& > tr {
|
||||
@apply lg:table-row lg:p-0;
|
||||
|
||||
& > td {
|
||||
@apply lg:table-cell lg:px-3 lg:py-2;
|
||||
|
||||
&.fi-hidden {
|
||||
@apply lg:table-cell;
|
||||
}
|
||||
|
||||
& .fi-in-entry {
|
||||
@apply lg:gap-y-0;
|
||||
}
|
||||
|
||||
& .fi-in-entry-label {
|
||||
@apply lg:hidden;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ class CodeEntry extends Entry implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -45,7 +45,7 @@ class ColorEntry extends Entry implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -259,7 +259,7 @@ class IconEntry extends Entry implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -448,7 +448,7 @@ class ImageEntry extends Entry implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -2,11 +2,17 @@
|
||||
|
||||
namespace Filament\Infolists\Components;
|
||||
|
||||
use Closure;
|
||||
use Exception;
|
||||
use Filament\Infolists\Components\RepeatableEntry\TableColumn;
|
||||
use Filament\Schemas\Components\Component;
|
||||
use Filament\Schemas\Components\Concerns\HasContainerGridLayout;
|
||||
use Filament\Schemas\Schema;
|
||||
use Filament\Support\Components\Contracts\HasEmbeddedView;
|
||||
use Filament\Support\Concerns\CanBeContained;
|
||||
use Filament\Support\Enums\Alignment;
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Js;
|
||||
|
||||
class RepeatableEntry extends Entry implements HasEmbeddedView
|
||||
@@ -14,6 +20,41 @@ class RepeatableEntry extends Entry implements HasEmbeddedView
|
||||
use CanBeContained;
|
||||
use HasContainerGridLayout;
|
||||
|
||||
/**
|
||||
* @var array<TableColumn> | Closure | null
|
||||
*/
|
||||
protected array | Closure | null $tableColumns = null;
|
||||
|
||||
/**
|
||||
* Configure table columns for display
|
||||
*
|
||||
* @param array<TableColumn> | Closure | null $columns
|
||||
*/
|
||||
public function table(array | Closure | null $columns): static
|
||||
{
|
||||
$this->tableColumns = $columns;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get configured table columns
|
||||
*
|
||||
* @return ?array<TableColumn>
|
||||
*/
|
||||
public function getTableColumns(): ?array
|
||||
{
|
||||
return $this->evaluate($this->tableColumns);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determine if component should render as table
|
||||
*/
|
||||
public function isTable(): bool
|
||||
{
|
||||
return filled($this->getTableColumns());
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array<Schema>
|
||||
*/
|
||||
@@ -50,6 +91,10 @@ class RepeatableEntry extends Entry implements HasEmbeddedView
|
||||
|
||||
public function toEmbeddedHtml(): string
|
||||
{
|
||||
if ($this->isTable()) {
|
||||
return $this->toEmbeddedTableHtml();
|
||||
}
|
||||
|
||||
$items = $this->getItems();
|
||||
|
||||
$attributes = $this->getExtraAttributeBag()
|
||||
@@ -74,7 +119,7 @@ class RepeatableEntry extends Entry implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
@@ -98,4 +143,100 @@ class RepeatableEntry extends Entry implements HasEmbeddedView
|
||||
|
||||
<?php return $this->wrapEmbeddedHtml(ob_get_clean());
|
||||
}
|
||||
|
||||
protected function toEmbeddedTableHtml(): string
|
||||
{
|
||||
$items = $this->getItems();
|
||||
$tableColumns = $this->getTableColumns();
|
||||
|
||||
$attributes = $this->getExtraAttributeBag()
|
||||
->class([
|
||||
'fi-in-table-repeatable',
|
||||
]);
|
||||
|
||||
if (empty($items)) {
|
||||
$attributes = $attributes
|
||||
->merge([
|
||||
'x-tooltip' => filled($tooltip = $this->getEmptyTooltip())
|
||||
? '{
|
||||
content: ' . Js::from($tooltip) . ',
|
||||
theme: $store.theme,
|
||||
}'
|
||||
: null,
|
||||
], escape: false);
|
||||
|
||||
$placeholder = $this->getPlaceholder();
|
||||
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
<?php } ?>
|
||||
</div>
|
||||
|
||||
<?php return $this->wrapEmbeddedHtml(ob_get_clean());
|
||||
}
|
||||
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<table>
|
||||
<thead>
|
||||
<tr>
|
||||
<?php foreach ($tableColumns as $column) { ?>
|
||||
<th
|
||||
class="<?= Arr::toCssClasses([
|
||||
'fi-wrapped' => $column->canHeaderWrap(),
|
||||
(($columnAlignment = $column->getAlignment()) instanceof Alignment) ? ('fi-align-' . $columnAlignment->value) : $columnAlignment,
|
||||
]) ?>"
|
||||
<?php if (filled($columnWidth = $column->getWidth())) { ?>
|
||||
style="width: <?= $columnWidth ?>"
|
||||
<?php } ?>
|
||||
>
|
||||
<?php if (! $column->isHeaderLabelHidden()) { ?>
|
||||
<?= e($column->getLabel()) ?>
|
||||
<?php } else { ?>
|
||||
<span class="fi-sr-only">
|
||||
<?= e($column->getLabel()) ?>
|
||||
</span>
|
||||
<?php } ?>
|
||||
</th>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
</thead>
|
||||
|
||||
<tbody>
|
||||
<?php foreach ($items as $item) { ?>
|
||||
<tr>
|
||||
<?php $counter = 0 ?>
|
||||
|
||||
<?php foreach ($item->getComponents(withHidden: true) as $component) { ?>
|
||||
<?php throw_unless(
|
||||
$component instanceof Component,
|
||||
new Exception('Table repeatable entries must only contain schema components, but [' . $component::class . '] was used.'),
|
||||
) ?>
|
||||
|
||||
<?php if (count($tableColumns) > $counter) { ?>
|
||||
<?php $counter++ ?>
|
||||
|
||||
<?php if ($component->isVisible()) { ?>
|
||||
<td>
|
||||
<?= $component->toHtml() ?>
|
||||
</td>
|
||||
<?php } else { ?>
|
||||
<td class="fi-hidden"></td>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
<?php } ?>
|
||||
</tr>
|
||||
<?php } ?>
|
||||
</tbody>
|
||||
</table>
|
||||
</div>
|
||||
|
||||
<?php return $this->wrapEmbeddedHtml(ob_get_clean());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
namespace Filament\Infolists\Components\RepeatableEntry;
|
||||
|
||||
use Closure;
|
||||
use Filament\Support\Components\Component;
|
||||
use Filament\Support\Concerns\CanWrapHeader;
|
||||
use Filament\Support\Concerns\HasAlignment;
|
||||
use Filament\Support\Concerns\HasWidth;
|
||||
use Illuminate\Contracts\Support\Htmlable;
|
||||
|
||||
class TableColumn extends Component
|
||||
{
|
||||
use CanWrapHeader;
|
||||
use HasAlignment;
|
||||
use HasWidth;
|
||||
|
||||
protected string $evaluationIdentifier = 'column';
|
||||
|
||||
protected bool | Closure $isHeaderLabelHidden = false;
|
||||
|
||||
public function __construct(protected string | Htmlable | Closure $label) {}
|
||||
|
||||
public static function make(string | Htmlable | Closure $label): static
|
||||
{
|
||||
$static = app(static::class, ['label' => $label]);
|
||||
|
||||
$static->configure();
|
||||
|
||||
return $static;
|
||||
}
|
||||
|
||||
public function hiddenHeaderLabel(bool | Closure $condition = true): static
|
||||
{
|
||||
$this->isHeaderLabelHidden = $condition;
|
||||
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function getLabel(): string | Htmlable
|
||||
{
|
||||
return $this->evaluate($this->label);
|
||||
}
|
||||
|
||||
public function isHeaderLabelHidden(): bool
|
||||
{
|
||||
return (bool) $this->evaluate($this->isHeaderLabelHidden);
|
||||
}
|
||||
}
|
||||
@@ -189,7 +189,7 @@ class TextEntry extends Entry implements HasAffixActions, HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-in-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
Vendored
+1
-1
File diff suppressed because one or more lines are too long
@@ -48,7 +48,7 @@ class ColorColumn extends Column implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-ta-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -290,7 +290,7 @@ class IconColumn extends Column implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-ta-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -443,7 +443,7 @@ class ImageColumn extends Column implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-ta-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
@@ -198,7 +198,7 @@ class TextColumn extends Column implements HasEmbeddedView
|
||||
ob_start(); ?>
|
||||
|
||||
<div <?= $attributes->toHtml() ?>>
|
||||
<?php if (filled($placeholder !== null)) { ?>
|
||||
<?php if (filled($placeholder)) { ?>
|
||||
<p class="fi-ta-placeholder">
|
||||
<?= e($placeholder) ?>
|
||||
</p>
|
||||
|
||||
Reference in New Issue
Block a user