diff --git a/src/LiveComponent/src/EventListener/DeferLiveComponentSubscriber.php b/src/LiveComponent/src/EventListener/DeferLiveComponentSubscriber.php index 19928e8bd95..d7e598cfa76 100644 --- a/src/LiveComponent/src/EventListener/DeferLiveComponentSubscriber.php +++ b/src/LiveComponent/src/EventListener/DeferLiveComponentSubscriber.php @@ -52,6 +52,7 @@ public function onPreRender(PreRenderEvent $event): void return; } + $componentTemplate = $event->getMetadata()->getTemplate(); $event->setTemplate('@LiveComponent/deferred.html.twig'); $variables = $event->getVariables(); @@ -66,6 +67,8 @@ public function onPreRender(PreRenderEvent $event): void $variables['loadingTag'] = $mountedComponent->getExtraMetadata('loading-tag'); } + $variables['componentTemplate'] = $componentTemplate; + $event->setVariables($variables); } diff --git a/src/LiveComponent/src/Test/TestLiveComponent.php b/src/LiveComponent/src/Test/TestLiveComponent.php index 4e9234e4bea..ac9404a7203 100644 --- a/src/LiveComponent/src/Test/TestLiveComponent.php +++ b/src/LiveComponent/src/Test/TestLiveComponent.php @@ -43,7 +43,7 @@ public function __construct( private UrlGeneratorInterface $router, ) { $this->client->catchExceptions(false); - $this->data['attributes']['data-live-id'] ??= 'in-a-real-scenario-it-would-already-have-one---provide-one-yourself-if-needed'; + $this->data['attributes']['id'] ??= 'in-a-real-scenario-it-would-already-have-one---provide-one-yourself-if-needed'; } public function render(): RenderedComponent diff --git a/src/LiveComponent/templates/deferred.html.twig b/src/LiveComponent/templates/deferred.html.twig index 0705be8e4ee..b55ec440e06 100644 --- a/src/LiveComponent/templates/deferred.html.twig +++ b/src/LiveComponent/templates/deferred.html.twig @@ -2,6 +2,11 @@ {% block loadingContent %} {% if loadingTemplate != null %} {{ include(loadingTemplate) }} + {% else %} + {% from componentTemplate import placeholder %} + {% if placeholder is defined %} + {{ placeholder(__props|default) }} + {% endif %} {% endif %} {% endblock %} diff --git a/src/LiveComponent/tests/Fixtures/Component/DeferredComponentWithPlaceholder.php b/src/LiveComponent/tests/Fixtures/Component/DeferredComponentWithPlaceholder.php new file mode 100644 index 00000000000..e7daba08a2f --- /dev/null +++ b/src/LiveComponent/tests/Fixtures/Component/DeferredComponentWithPlaceholder.php @@ -0,0 +1,18 @@ + + {# for row in this.rows ... #} + + +{% macro placeholder(props) %} + {%- for i in 1..props.rows -%} + + {%- endfor -%} +{% endmacro %} diff --git a/src/LiveComponent/tests/Fixtures/templates/render_component_with_placeholder.html.twig b/src/LiveComponent/tests/Fixtures/templates/render_component_with_placeholder.html.twig new file mode 100644 index 00000000000..c9b8d4ab6d2 --- /dev/null +++ b/src/LiveComponent/tests/Fixtures/templates/render_component_with_placeholder.html.twig @@ -0,0 +1 @@ + diff --git a/src/LiveComponent/tests/Fixtures/templates/render_deferred_component_with_placeholder.html.twig b/src/LiveComponent/tests/Fixtures/templates/render_deferred_component_with_placeholder.html.twig new file mode 100644 index 00000000000..ce06cae0f64 --- /dev/null +++ b/src/LiveComponent/tests/Fixtures/templates/render_deferred_component_with_placeholder.html.twig @@ -0,0 +1 @@ + diff --git a/src/LiveComponent/tests/Functional/EventListener/DeferLiveComponentSubscriberTest.php b/src/LiveComponent/tests/Functional/EventListener/DeferLiveComponentSubscriberTest.php index d243ccba1e8..420fce3b89b 100644 --- a/src/LiveComponent/tests/Functional/EventListener/DeferLiveComponentSubscriberTest.php +++ b/src/LiveComponent/tests/Functional/EventListener/DeferLiveComponentSubscriberTest.php @@ -77,6 +77,27 @@ public function testItIncludesGivenTemplateWhileLoadingDeferredComponent(): void $this->assertStringContainsString('Long awaited data', $div->html()); } + public function testItIncludesComponentTemplateBlockAsPlaceholder(): void + { + $div = $this->browser() + ->visit('/render-template/render_deferred_component_with_placeholder') + ->assertSuccessful() + ->crawler() + ->filter('div'); + + $this->assertSame('', trim($div->html())); + } + + public function testItDoesNotIncludesPlaceholderWhenRendered(): void + { + $div = $this->browser() + ->visit('/render-template/render_component_with_placeholder') + ->assertSuccessful() + ->crawler(); + + $this->assertStringNotContainsString('', $div->html()); + } + public function testItAllowsToSetCustomLoadingHtmlTag(): void { $crawler = $this->browser() diff --git a/src/LiveComponent/tests/Functional/EventListener/InterceptChildComponentRenderSubscriberTest.php b/src/LiveComponent/tests/Functional/EventListener/InterceptChildComponentRenderSubscriberTest.php index 3dfd77bb270..19cd1740b79 100644 --- a/src/LiveComponent/tests/Functional/EventListener/InterceptChildComponentRenderSubscriberTest.php +++ b/src/LiveComponent/tests/Functional/EventListener/InterceptChildComponentRenderSubscriberTest.php @@ -128,7 +128,7 @@ public function testItUsesKeysToRenderChildrenLiveIds(): void ->assertSuccessful() ->assertHtml() ->assertElementCount('ul li', 3) - // check for the live-id we expect based on the key + // check for the id we expect based on the key ->assertContains('id="live-521026374-the-key0"') ->assertNotContains('key="the-key0"') ->visit($urlWithChangedFingerprints) diff --git a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php index ff891610c50..aa61825e805 100644 --- a/src/TwigComponent/tests/Integration/ComponentExtensionTest.php +++ b/src/TwigComponent/tests/Integration/ComponentExtensionTest.php @@ -14,7 +14,6 @@ use Symfony\Bundle\FrameworkBundle\Test\KernelTestCase; use Symfony\UX\TwigComponent\Tests\Fixtures\User; use Twig\Environment; -use Twig\Error\RuntimeError; /** * @author Kevin Bond