cs && refactor layout components

This commit is contained in:
Dan Harrin
2024-10-17 14:37:22 +01:00
parent e64c9fa6c6
commit e123bfcb2b
24 changed files with 350 additions and 235 deletions
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
@@ -2,9 +2,9 @@
namespace Filament\Forms\Components\Concerns;
use Closure;
use Filament\Schema\Components\Component;
use Filament\Schema\Components\Utilities\Set;
use Closure;
use Illuminate\Support\Arr;
trait CanFixIndistinctState
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -2,8 +2,8 @@
namespace Filament\Schema\Concerns;
use Filament\Schema\Components\Component;
use Closure;
use Filament\Schema\Components\Component;
trait HasStateBindingModifiers
{
+1 -1
View File
File diff suppressed because one or more lines are too long
@@ -0,0 +1,35 @@
.fi-ta-split {
@apply flex;
&.default\:fi-ta-split {
@apply items-center gap-3;
}
&.sm\:fi-ta-split,
&.md\:fi-ta-split,
&.lg\:fi-ta-split,
&.xl\:fi-ta-split,
&.\32xl\:fi-ta-split {
@apply flex-col gap-2;
}
&.sm\:fi-ta-split {
@apply sm:flex-row sm:items-center sm:gap-3;
}
&.md\:fi-ta-split {
@apply md:flex-row md:items-center md:gap-3;
}
&.lg\:fi-ta-split {
@apply lg:flex-row lg:items-center lg:gap-3;
}
&.xl\:fi-ta-split {
@apply xl:flex-row xl:items-center xl:gap-3;
}
&.\32xl\:fi-ta-split {
@apply 2xl:flex-row 2xl:items-center 2xl:gap-3;
}
}
@@ -0,0 +1,29 @@
.fi-ta-stack {
@apply flex flex-col;
&.fi-align-start,
&.fi-align-left {
@apply items-start;
}
&.fi-align-center {
@apply items-center;
}
&.fi-align-end,
&.fi-align-right {
@apply items-end;
}
&.fi-gap-sm {
@apply space-y-1;
}
&.fi-gap-md {
@apply space-y-2;
}
&.fi-gap-lg {
@apply space-y-3;
}
}
@@ -252,7 +252,11 @@
}
& .fi-ta-col-wrp {
@apply flex w-full justify-start text-start disabled:pointer-events-none;
@apply flex justify-start text-start disabled:pointer-events-none;
&.fi-growable {
@apply w-full;
}
&.fi-align-center {
@apply justify-center text-center;
@@ -281,7 +285,10 @@
& .fi-ta-record-collapse-btn {
@apply mx-1 my-2 shrink-0;
&:is(.fi-ta-record.fi-ta-record-collapsed .fi-ta-record-collapse-btn) {
&:is(
.fi-ta-record.fi-ta-record-collapsed
.fi-ta-record-collapse-btn
) {
@apply rotate-180;
}
}
+2
View File
@@ -21,6 +21,8 @@ import '../css/components/tables/columns/image.css'
import '../css/components/tables/columns/text.css'
import '../css/components/tables/columns/layout/grid.css'
import '../css/components/tables/columns/layout/panel.css'
import '../css/components/tables/columns/layout/split.css'
import '../css/components/tables/columns/layout/stack.css'
import '../css/components/tables/container.css'
import '../css/components/tables/content.css'
import '../css/components/tables/empty-state.css'
@@ -179,12 +179,14 @@ class SupportServiceProvider extends PackageServiceProvider
$span = array_filter($span);
$start = array_filter($start);
$span['default'] ??= 1;
if (($span['default'] ?? null) === 1) {
unset($span['default']);
}
return $this
->class([
'fi-grid-col',
'fi-hidden' => $isHidden || ($span['default'] === 'hidden'),
'fi-hidden' => $isHidden || (($span['default'] ?? null) === 'hidden'),
...array_map(
fn (string $breakpoint): string => match ($breakpoint) {
'default' => '',
+7 -5
View File
@@ -459,10 +459,12 @@ Now, render the components in the Blade file:
```blade
<div class="px-4 py-3 bg-gray-100 rounded-lg">
<x-filament-tables::columns.layout
:components="$getComponents()"
:record="$getRecord()"
:record-key="$recordKey"
/>
@foreach ($getComponents() as $layoutComponent)
{{ $layoutComponent
->record($getRecord())
->recordKey($getRecordKey())
->rowLoop($getRowLoop())
->renderInLayout() }}
@endforeach
</div>
```
@@ -1,23 +0,0 @@
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->grid($columns = $getGridColumns())
->class([
'fi-ta-grid',
(($columns['default'] ?? 1) === 1) ? 'fi-gap-sm' : 'fi-gap-lg',
($columns['sm'] ?? null) ? (($columns['sm'] === 1) ? 'sm:fi-gap-sm' : 'sm:fi-gap-lg') : null,
($columns['md'] ?? null) ? (($columns['md'] === 1) ? 'md:fi-gap-sm' : 'md:fi-gap-lg') : null,
($columns['lg'] ?? null) ? (($columns['lg'] === 1) ? 'lg:fi-gap-sm' : 'lg:fi-gap-lg') : null,
($columns['xl'] ?? null) ? (($columns['xl'] === 1) ? 'xl:fi-gap-sm' : 'xl:fi-gap-lg') : null,
($columns['2xl'] ?? null) ? (($columns['2xl'] === 1) ? '2xl:fi-gap-sm' : '2xl:fi-gap-lg') : null,
])
}}
>
<x-filament-tables::columns.layout
:components="$getComponents()"
grid
:record="$getRecord()"
:record-key="$getRecordKey()"
/>
</div>
@@ -1,13 +0,0 @@
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class(['fi-ta-panel'])
}}
>
<x-filament-tables::columns.layout
:components="$getComponents()"
:record="$getRecord()"
:record-key="$getRecordKey()"
/>
</div>
@@ -1,24 +0,0 @@
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'fi-ta-split flex',
match ($getFromBreakpoint()) {
'sm' => 'flex-col gap-2 sm:flex-row sm:items-center sm:gap-3',
'md' => 'flex-col gap-2 md:flex-row md:items-center md:gap-3',
'lg' => 'flex-col gap-2 lg:flex-row lg:items-center lg:gap-3',
'xl' => 'flex-col gap-2 xl:flex-row xl:items-center xl:gap-3',
'2xl' => 'flex-col gap-2 2xl:flex-row 2xl:items-center 2xl:gap-3',
default => 'items-center gap-3',
},
])
}}
>
<x-filament-tables::columns.layout
:components="$getComponents()"
:record="$getRecord()"
:record-key="$getRecordKey()"
:row-loop="$getRowLoop()"
/>
</div>
@@ -1,39 +0,0 @@
@php
use Filament\Support\Enums\Alignment;
$alignment = $getAlignment() ?? Alignment::Start;
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
@endphp
<div
{{
$attributes
->merge($getExtraAttributes(), escape: false)
->class([
'flex flex-col',
match ($alignment) {
Alignment::Start, Alignment::Left => 'items-start',
Alignment::Center => 'items-center',
Alignment::End, Alignment::Right => 'items-end',
Alignment::Justify, Alignment::Between => null,
default => $alignment,
},
match ($space = $getSpace()) {
1 => 'space-y-1',
2 => 'space-y-2',
3 => 'space-y-3',
default => $space,
},
])
}}
>
<x-filament-tables::columns.layout
:components="$getComponents()"
:record="$getRecord()"
:record-key="$getRecordKey()"
:row-loop="$getRowLoop()"
/>
</div>
@@ -1,7 +1,3 @@
@php
use Illuminate\View\ComponentAttributeBag;
@endphp
@props([
'components',
'record',
@@ -10,76 +6,11 @@
])
@foreach ($components as $layoutComponent)
@php
$layoutComponent->record($record);
$layoutComponent->rowLoop($rowLoop);
$layoutComponent->recordKey($recordKey);
@endphp
@if ($layoutComponent->isVisible())
<div
{{
(new ComponentAttributeBag)
->gridColumn(
$layoutComponent->getColumnSpan(),
$layoutComponent->getColumnStart(),
)
->class([
'fi-growable' => $layoutComponent->canGrow(),
(filled($layoutComponentHiddenFrom = $layoutComponent->getHiddenFrom()) ? "{$layoutComponentHiddenFrom}:fi-hidden" : ''),
(filled($layoutComponentVisibleFrom = $layoutComponent->getVisibleFrom()) ? "{$layoutComponentVisibleFrom}:fi-visible" : ''),
])
}}
>
@if ($layoutComponent instanceof \Filament\Tables\Columns\Column)
@php
$layoutComponent->inline();
$layoutComponentAction = $layoutComponent->getAction();
$layoutComponentUrl = $layoutComponent->getUrl();
$isLayoutComponentClickDisabled = $layoutComponent->isClickDisabled();
$layoutComponentWrapperTag = match (true) {
$layoutComponentUrl && (! $isLayoutComponentClickDisabled) => 'a',
$layoutComponentAction && (! $isLayoutComponentClickDisabled) => 'button',
default => 'div',
};
if ($layoutComponentWrapperTag === 'button') {
if ($layoutComponentAction instanceof \Filament\Actions\Action) {
$layoutComponentWireClickAction = "mountTableAction('{$layoutComponentAction->getName()}', '{$recordKey}')";
} elseif ($layoutComponentAction) {
$layoutComponentWireClickAction = "callTableColumnAction('{$layoutComponent->getName()}', '{$recordKey}')";
}
}
@endphp
<{{ $layoutComponentWrapperTag }}
@if (filled($layoutComponentTooltip = $layoutComponent->getTooltip()))
x-tooltip="{
content: @js($layoutComponentTooltip),
theme: $store.theme,
}"
@endif
@if ($layoutComponentWrapperTag === 'a')
{{ \Filament\Support\generate_href_html($layoutComponentUrl, $layoutComponent->shouldOpenUrlInNewTab()) }}
@elseif ($layoutComponentWrapperTag === 'button')
type="button"
wire:click="{{ $layoutComponentWireClickAction }}"
wire:loading.attr="disabled"
wire:target="{{ $layoutComponentWireClickAction }}"
@endif
@class([
'fi-ta-col-wrp',
((($layoutComponentAlignment = $layoutComponent->getAlignment()) instanceof \Filament\Support\Enums\Alignment) ? "fi-align-{$layoutComponentAlignment->value}" : (is_string($layoutComponentAlignment) ? $layoutComponentAlignment : '')),
'fi-ta-col-wrap-has-column-url' => ($layoutComponentWrapperTag === 'a') && filled($layoutComponentUrl),
])
>
{{ $layoutComponent }}
</{{ $layoutComponentWrapperTag }}>
@else
{{ $layoutComponent }}
@endif
</div>
@endif
{{
$layoutComponent
->record($record)
->recordKey($recordKey)
->rowLoop($rowLoop)
->renderInLayout()
}}
@endforeach
+30 -21
View File
@@ -904,12 +904,15 @@
{{ \Filament\Support\generate_href_html($recordUrl, $openRecordUrlInNewTab) }}
class="fi-ta-record-content"
>
<x-filament-tables::columns.layout
:components="$columnsLayout"
:record="$record"
:record-key="$recordKey"
:row-loop="$loop"
/>
@foreach ($columnsLayout as $columnsLayoutComponent)
{{
$columnsLayoutComponent
->record($record)
->recordKey($recordKey)
->rowLoop($loop)
->renderInLayout()
}}
@endforeach
</a>
@elseif ($recordAction)
@php
@@ -925,21 +928,27 @@
wire:target="{{ $recordWireClickAction }}"
class="fi-ta-record-content"
>
<x-filament-tables::columns.layout
:components="$columnsLayout"
:record="$record"
:record-key="$recordKey"
:row-loop="$loop"
/>
@foreach ($columnsLayout as $columnsLayoutComponent)
{{
$columnsLayoutComponent
->record($record)
->recordKey($recordKey)
->rowLoop($loop)
->renderInLayout()
}}
@endforeach
</button>
@else
<div class="fi-ta-record-content">
<x-filament-tables::columns.layout
:components="$columnsLayout"
:record="$record"
:record-key="$recordKey"
:row-loop="$loop"
/>
@foreach ($columnsLayout as $columnsLayoutComponent)
{{
$columnsLayoutComponent
->record($record)
->recordKey($recordKey)
->rowLoop($loop)
->renderInLayout()
}}
@endforeach
</div>
@endif
@@ -1634,9 +1643,9 @@
@if (filled($columnTooltip = $column->getTooltip()))
x-tooltip
="{
content: @js($columnTooltip),
theme: $store.theme,
}"
content: @js($columnTooltip),
theme: $store.theme,
}"
@endif
@if ($columnWrapperTag === 'a')
{{ \Filament\Support\generate_href_html($columnUrl ?: $recordUrl, $columnUrl ? $column->shouldOpenUrlInNewTab() : $openRecordUrlInNewTab) }}
+74
View File
@@ -3,6 +3,7 @@
namespace Filament\Tables\Columns;
use Exception;
use Filament\Actions\Action;
use Filament\Support\Components\ViewComponent;
use Filament\Support\Concerns\CanAggregateRelatedModels;
use Filament\Support\Concerns\CanGrow;
@@ -12,8 +13,14 @@ use Filament\Support\Concerns\HasExtraAttributes;
use Filament\Support\Concerns\HasPlaceholder;
use Filament\Support\Concerns\HasTooltip;
use Filament\Support\Concerns\HasVerticalAlignment;
use Filament\Support\Enums\Alignment;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Js;
use Illuminate\View\ComponentAttributeBag;
use function Filament\Support\generate_href_html;
class Column extends ViewComponent
{
@@ -118,4 +125,71 @@ class Column extends ViewComponent
default => parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType),
};
}
public function renderInLayout(): ?HtmlString
{
if ($this->isHidden()) {
return null;
}
$attributes = (new ComponentAttributeBag)
->gridColumn(
$this->getColumnSpan(),
$this->getColumnStart(),
)
->class([
'fi-growable' => $this->canGrow(),
(filled($hiddenFrom = $this->getHiddenFrom()) ? "{$hiddenFrom}:fi-hidden" : ''),
(filled($visibleFrom = $this->getVisibleFrom()) ? "{$visibleFrom}:fi-visible" : ''),
]);
$this->inline();
$action = $this->getAction();
$url = $this->getUrl();
$isClickDisabled = $this->isClickDisabled();
$wrapperTag = match (true) {
$url && (! $isClickDisabled) => 'a',
$action && (! $isClickDisabled) => 'button',
default => 'div',
};
$attributes = $attributes
->merge([
'x-tooltip' => filled($tooltip = $this->getTooltip())
? '{
content: ' . Js::from($tooltip) . ',
theme: $store.theme,
}'
: null,
'type' => ($wrapperTag === 'button') ? 'button' : null,
'wire:click' => $wireClickAction = match (true) {
($wrapperTag !== 'button') => null,
$action instanceof Action => "mountTableAction('{$action->getName()}', '{$this->getRecordKey()}')",
filled($action) => "callTableColumnAction('{$this->getName()}', '{$this->getRecordKey()}')",
default => null,
},
'wire:loading.attr' => ($wrapperTag === 'button') ? 'disabled' : null,
'wire:target' => $wireClickAction,
], escape: false)
->class([
'fi-ta-col-wrp',
((($alignment = $this->getAlignment()) instanceof Alignment) ? "fi-align-{$alignment->value}" : (is_string($alignment) ? $alignment : '')),
'fi-ta-col-wrap-has-column-url' => ($wrapperTag === 'a') && filled($url),
]);
ob_start(); ?>
<<?= $wrapperTag ?>
<?php if ($wrapperTag === 'a') {
echo generate_href_html($url, $this->shouldOpenUrlInNewTab())->toHtml();
} ?>
<?= $attributes->toHtml() ?>
>
<?= $this->toHtml() ?>
</<?= $wrapperTag ?>>
<?php return new HtmlString(ob_get_clean());
}
}
@@ -16,6 +16,8 @@ use Filament\Tables\Columns\Concerns\HasRecord;
use Filament\Tables\Columns\Concerns\HasRowLoopObject;
use Filament\Tables\Table;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\HtmlString;
use Illuminate\View\ComponentAttributeBag;
class Component extends ViewComponent
{
@@ -158,4 +160,30 @@ class Component extends ViewComponent
default => parent::resolveDefaultClosureDependencyForEvaluationByType($parameterType),
};
}
public function renderInLayout(): ?HtmlString
{
if ($this->isHidden()) {
return null;
}
$attributes = (new ComponentAttributeBag)
->gridColumn(
$this->getColumnSpan(),
$this->getColumnStart(),
)
->class([
'fi-growable' => $this->canGrow(),
(filled($hiddenFrom = $this->getHiddenFrom()) ? "{$hiddenFrom}:fi-hidden" : ''),
(filled($visibleFrom = $this->getVisibleFrom()) ? "{$visibleFrom}:fi-visible" : ''),
]);
ob_start(); ?>
<div <?= $attributes->toHtml() ?>>
<?= $this->toHtml() ?>
</div>
<?php return new HtmlString(ob_get_clean());
}
}
+34 -6
View File
@@ -2,13 +2,10 @@
namespace Filament\Tables\Columns\Layout;
class Grid extends Component
{
/**
* @var view-string
*/
protected string $view = 'filament-tables::columns.layout.grid';
use Filament\Support\Components\Contracts\HasEmbeddedView;
class Grid extends Component implements HasEmbeddedView
{
/**
* @var array<string, int | null> | null
*/
@@ -59,4 +56,35 @@ class Grid extends Component
{
return $this->columns;
}
public function toEmbeddedHtml(): string
{
$columns = $this->getGridColumns();
$attributes = $this->getExtraAttributeBag()
->grid($columns)
->class([
'fi-ta-grid',
(($columns['default'] ?? 1) === 1) ? 'fi-gap-sm' : 'fi-gap-lg',
($columns['sm'] ?? null) ? (($columns['sm'] === 1) ? 'sm:fi-gap-sm' : 'sm:fi-gap-lg') : null,
($columns['md'] ?? null) ? (($columns['md'] === 1) ? 'md:fi-gap-sm' : 'md:fi-gap-lg') : null,
($columns['lg'] ?? null) ? (($columns['lg'] === 1) ? 'lg:fi-gap-sm' : 'lg:fi-gap-lg') : null,
($columns['xl'] ?? null) ? (($columns['xl'] === 1) ? 'xl:fi-gap-sm' : 'xl:fi-gap-lg') : null,
($columns['2xl'] ?? null) ? (($columns['2xl'] === 1) ? '2xl:fi-gap-sm' : '2xl:fi-gap-lg') : null,
]);
$record = $this->getRecord();
$recordKey = $this->getRecordKey();
$rowLoop = $this->getRowLoop();
ob_start(); ?>
<div <?= $attributes->toHtml() ?>>
<?php foreach ($this->getComponents() as $component) { ?>
<?= $component->record($record)->recordKey($recordKey)->rowLoop($rowLoop)->renderInLayout() ?>
<?php } ?>
</div>
<?php return ob_get_clean();
}
}
+22 -6
View File
@@ -3,15 +3,11 @@
namespace Filament\Tables\Columns\Layout;
use Closure;
use Filament\Support\Components\Contracts\HasEmbeddedView;
use Filament\Tables\Columns\Column;
class Panel extends Component
class Panel extends Component implements HasEmbeddedView
{
/**
* @var view-string
*/
protected string $view = 'filament-tables::columns.layout.panel';
/**
* @param array<Column | Component> | Closure $schema
*/
@@ -30,4 +26,24 @@ class Panel extends Component
return $static;
}
public function toEmbeddedHtml(): string
{
$attributes = $this->getExtraAttributeBag()
->class(['fi-ta-panel']);
$record = $this->getRecord();
$recordKey = $this->getRecordKey();
$rowLoop = $this->getRowLoop();
ob_start(); ?>
<div <?= $attributes->toHtml() ?>>
<?php foreach ($this->getComponents() as $component) { ?>
<?= $component->record($record)->recordKey($recordKey)->rowLoop($rowLoop)->renderInLayout() ?>
<?php } ?>
</div>
<?php return ob_get_clean();
}
}
+25 -6
View File
@@ -3,18 +3,14 @@
namespace Filament\Tables\Columns\Layout;
use Closure;
use Filament\Support\Components\Contracts\HasEmbeddedView;
use Filament\Support\Concerns\HasFromBreakpoint;
use Filament\Tables\Columns\Column;
class Split extends Component
class Split extends Component implements HasEmbeddedView
{
use HasFromBreakpoint;
/**
* @var view-string
*/
protected string $view = 'filament-tables::columns.layout.split';
/**
* @param array<Column | Component> | Closure $schema
*/
@@ -33,4 +29,27 @@ class Split extends Component
return $static;
}
public function toEmbeddedHtml(): string
{
$attributes = $this->getExtraAttributeBag()
->class([
'fi-ta-split',
filled($fromBreakpoint = $this->getFromBreakpoint()) ? "{$fromBreakpoint}:fi-ta-split" : 'default:fi-ta-split',
]);
$record = $this->getRecord();
$recordKey = $this->getRecordKey();
$rowLoop = $this->getRowLoop();
ob_start(); ?>
<div <?= $attributes->toHtml() ?>>
<?php foreach ($this->getComponents() as $component) { ?>
<?= $component->record($record)->recordKey($recordKey)->rowLoop($rowLoop)->renderInLayout() ?>
<?php } ?>
</div>
<?php return ob_get_clean();
}
}
+38 -6
View File
@@ -3,20 +3,17 @@
namespace Filament\Tables\Columns\Layout;
use Closure;
use Filament\Support\Components\Contracts\HasEmbeddedView;
use Filament\Support\Concerns\HasAlignment;
use Filament\Support\Enums\Alignment;
use Filament\Tables\Columns\Column;
use Filament\Tables\Columns\Concerns\HasSpace;
class Stack extends Component
class Stack extends Component implements HasEmbeddedView
{
use HasAlignment;
use HasSpace;
/**
* @var view-string
*/
protected string $view = 'filament-tables::columns.layout.stack';
/**
* @param array<Column | Component> | Closure $schema
*/
@@ -35,4 +32,39 @@ class Stack extends Component
return $static;
}
public function toEmbeddedHtml(): string
{
$alignment = $this->getAlignment() ?? Alignment::Start;
if (! $alignment instanceof Alignment) {
$alignment = filled($alignment) ? (Alignment::tryFrom($alignment) ?? $alignment) : null;
}
$attributes = $this->getExtraAttributeBag()
->class([
'fi-ta-stack',
($alignment instanceof Alignment) ? "fi-align-{$alignment->value}" : $alignment,
match ($space = $this->getSpace()) {
1 => 'fi-gap-sm',
2 => 'fi-gap-md',
3 => 'fi-gap-lg',
default => $space,
},
]);
$record = $this->getRecord();
$recordKey = $this->getRecordKey();
$rowLoop = $this->getRowLoop();
ob_start(); ?>
<div <?= $attributes->toHtml() ?>>
<?php foreach ($this->getComponents() as $component) { ?>
<?= $component->record($record)->recordKey($recordKey)->rowLoop($rowLoop)->renderInLayout() ?>
<?php } ?>
</div>
<?php return ob_get_clean();
}
}