diff --git a/packages/schemas/src/Components/Component.php b/packages/schemas/src/Components/Component.php index a1b481704c..d357ce3328 100644 --- a/packages/schemas/src/Components/Component.php +++ b/packages/schemas/src/Components/Component.php @@ -34,9 +34,11 @@ use Filament\Support\Concerns\CanGrow; use Filament\Support\Concerns\CanOrderColumns; use Filament\Support\Concerns\CanSpanColumns; use Filament\Support\Concerns\HasExtraAttributes; +use Filament\Support\Enums\Width; use Illuminate\Database\Eloquent\Model; -use Livewire\Drawer\Utils; -use Livewire\Exceptions\RootTagMissingFromViewException; +use Illuminate\Support\Arr; +use Illuminate\Support\Js; +use Illuminate\View\ComponentAttributeBag; class Component extends ViewComponent { @@ -115,33 +117,6 @@ class Component extends ViewComponent }; } - public function toHtml(): string - { - if ($this->isLiberatedFromContainerGrid()) { - return parent::toHtml(); - } - - $key = $this->getKey(); - - if (blank($key)) { - return parent::toHtml(); - } - - $html = parent::toHtml(); - - if (blank($html)) { - return ''; - } - - try { - return Utils::insertAttributesIntoHtmlRoot($html, [ - 'wire:partial' => "schema-component::{$key}", - ]); - } catch (RootTagMissingFromViewException) { - return $html; - } - } - /** * @return array */ @@ -153,4 +128,101 @@ class Component extends ViewComponent 'record' => $this->getRecord(), ]; } + + /** + * @internal Do not use this method outside the internals of Filament. It is subject to breaking changes in minor and patch releases. + */ + public function toSchemaHtml(?bool $isVisible = null): string + { + $isVisible ??= $this->isVisible(); + + $container = $this->getContainer(); + + $isContainerEmbeddedInParentComponent = $container->isEmbeddedInParentComponent(); + $containerParentComponent = $isContainerEmbeddedInParentComponent + ? $container->getParentComponent() + : null; + $containerStatePath = $isContainerEmbeddedInParentComponent + ? $containerParentComponent->getContainer()->getStatePath() + : $container->getStatePath(); + + /** + * Instead of only rendering the hidden components, we should + * render the `
` wrappers for all fields, regardless of + * if they are hidden or not. This is to solve Livewire DOM + * diffing issues. + * + * Additionally, any `
` elements that wrap hidden + * components need to have `class="fi-hidden"`, so that they + * don't consume grid space. + */ + $hiddenJs = $this->getHiddenJs(); + $visibleJs = $this->getVisibleJs(); + + $maxWidth = $this->getMaxWidth(); + + $statePath = $isContainerEmbeddedInParentComponent + ? $containerParentComponent->getStatePath() + : $this->getStatePath(); + + $key = $this->getKey(); + + $attributes = (new ComponentAttributeBag) + ->when( + ! $container->isInline(), + fn (ComponentAttributeBag $attributes) => $attributes->gridColumn($this->getColumnSpan(), $this->getColumnStart(), $this->getColumnOrder(), ! $isVisible), + ) + ->merge([ + 'wire:key' => $this->getLivewireKey(), + ...(($pollingInterval = $this->getPollingInterval()) ? ["wire:poll.{$pollingInterval}" => "partiallyRenderSchemaComponent('{$this->getKey()}')"] : []), + ], escape: false) + ->class([ + ($maxWidth instanceof Width) ? "fi-width-{$maxWidth->value}" : $maxWidth, + ]); + + ob_start(); ?> + +
+ wire:partial="schema-component::" + + + x-data="filamentSchemaComponent({ + path: , + containerPath: , + isLive: isLive()) ?>, + $wire, + })" + getAfterStateUpdatedJs()) { ?> + x-init=" '$wire.watch(' . Js::from($statePath) . ', ($state, $old) => ($state !== undefined) && eval(' . Js::from($js) . '))', + $afterStateUpdatedJs, + )) ?>" + + "(! ({$hiddenJs})) && ({$visibleJs})", + [true, false] => "! ({$hiddenJs})", + [false, true] => $visibleJs, + default => null, + })) { ?> + x-bind:class="{ 'fi-hidden': ! () }" + x-cloak + + + toHtml() ?> + > + +
+ toHtml() ?> +
+ +
+ + $this->hasView() ? $this->render() : $this->toHtml(...), + "schema-component::{$key}" => $this->toSchemaHtml(...), ]; }); } diff --git a/packages/schemas/src/Components/Concerns/HasState.php b/packages/schemas/src/Components/Concerns/HasState.php index 278c8ee0ce..cd6206a526 100644 --- a/packages/schemas/src/Components/Concerns/HasState.php +++ b/packages/schemas/src/Components/Concerns/HasState.php @@ -14,6 +14,7 @@ use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Arr; use Illuminate\Support\Collection; use Illuminate\Support\Str; +use InvalidArgumentException; use Livewire\Livewire; use LogicException; @@ -168,7 +169,13 @@ trait HasState if (filled($components = $this->getComponentsToPartiallyRenderAfterStateUpdated())) { foreach ($components as $key) { - $this->getLivewire()->getSchemaComponent($this->resolveRelativeKey($key))->partiallyRender(); + $component = $this->getLivewire()->getSchemaComponent($this->resolveRelativeKey($key), withHidden: true); + + if (! $component) { + throw new InvalidArgumentException("Could not find component [{$key}] to partially render."); + } + + $component->partiallyRender(); } } diff --git a/packages/schemas/src/Schema.php b/packages/schemas/src/Schema.php index 56e91b9852..2b82309682 100644 --- a/packages/schemas/src/Schema.php +++ b/packages/schemas/src/Schema.php @@ -13,10 +13,8 @@ use Filament\Support\Concerns\HasAlignment; use Filament\Support\Concerns\HasDefaultDataFormattingSettings; use Filament\Support\Concerns\HasExtraAttributes; use Filament\Support\Enums\Alignment; -use Filament\Support\Enums\Width; use Illuminate\Contracts\Support\Htmlable; use Illuminate\Database\Eloquent\Model; -use Illuminate\Support\Arr; use Illuminate\Support\Js; use Illuminate\View\ComponentAttributeBag; use Livewire\Component as LivewireComponent; @@ -175,14 +173,6 @@ class Schema extends ViewComponent implements HasEmbeddedView $isInline = $this->isInline(); $isRoot = $this->isRoot(); - $isEmbeddedInParentComponent = $this->isEmbeddedInParentComponent(); - $parentComponent = $isEmbeddedInParentComponent - ? $this->getParentComponent() - : null; - $statePath = $isEmbeddedInParentComponent - ? $parentComponent->getContainer()->getStatePath() - : $this->getStatePath(); - $attributes = $this->getExtraAttributeBag() ->when( ! $isInline, @@ -212,76 +202,7 @@ class Schema extends ViewComponent implements HasEmbeddedView
isLiberatedFromContainerGrid()) { ?> - ` wrappers for all fields, regardless of - * if they are hidden or not. This is to solve Livewire DOM - * diffing issues. - * - * Additionally, any `
` elements that wrap hidden - * components need to have `class="fi-hidden"`, so that they - * don't consume grid space. - */ - $hiddenJs = $schemaComponent->getHiddenJs(); - $visibleJs = $schemaComponent->getVisibleJs(); - - $maxWidth = $schemaComponent->getMaxWidth(); - - $schemaComponentStatePath = $isEmbeddedInParentComponent - ? $parentComponent->getStatePath() - : $schemaComponent->getStatePath(); - - $attributes = (new ComponentAttributeBag) - ->when( - ! $isInline, - fn (ComponentAttributeBag $attributes) => $attributes->gridColumn($schemaComponent->getColumnSpan(), $schemaComponent->getColumnStart(), $schemaComponent->getColumnOrder(), ! $isSchemaComponentVisible), - ) - ->merge([ - 'wire:key' => $schemaComponent->getLivewireKey(), - ...(($pollingInterval = $schemaComponent->getPollingInterval()) ? ["wire:poll.{$pollingInterval}" => "partiallyRenderSchemaComponent('{$schemaComponent->getKey()}')"] : []), - ], escape: false) - ->class([ - ($maxWidth instanceof Width) ? "fi-width-{$maxWidth->value}" : $maxWidth, - ]); - ?> -
- x-data="filamentSchemaComponent({ - path: , - containerPath: , - isLive: isLive()) ?>, - $wire, - })" - getAfterStateUpdatedJs()) { ?> - x-init=" '$wire.watch(' . Js::from($schemaComponentStatePath) . ', ($state, $old) => ($state !== undefined) && eval(' . Js::from($js) . '))', - $afterStateUpdatedJs, - )) ?>" - - "(! ({$hiddenJs})) && ({$visibleJs})", - [true, false] => "! ({$hiddenJs})", - [false, true] => $visibleJs, - default => null, - })) { ?> - x-bind:class="{ 'fi-hidden': ! () }" - x-cloak - - - toHtml() ?> - > - -
- toHtml() ?> -
- -
+ toSchemaHtml(isVisible: $isSchemaComponentVisible) ?> toHtml() ?>