symfony / ux

Symfony UX initiative: a JavaScript ecosystem for Symfony
https://ux.symfony.com/
MIT License
861 stars 315 forks source link

[TwigComponents] Isolate child block in seperate component #2009

Open tilpoe opened 4 months ago

tilpoe commented 4 months ago

Hey, just a quick question, because i didn't find any issues about it:

I want to build an alert component with AlertTitle, AlertDescription and AlertIcon as seperate components that should be used as child components of the root Alert component.

The root component looks kind of like this:

// alert/root.html.twig
<div>
    {% block icon %}{% endblock %}
    <div>
        {% block title %}{% endblock %}
        {% block content %}{% endblock %}
    </div>
</div>

I thought i could just outsource the <twig:block name='icon'/> tag into the seperate component:

// alert/icon.html.twig
<twig:block name='icon'>
    <div>...</div>
</twig>

so that the icon is automatically rendered inside of the root component where its supposed to be rendered and i could just use the component like

<twig:alert:root>
    <twig:alert:icon />
</twig:alert:root>

instead of

<twig:alert:root>
    <twig:block name='icon'><twig:alert:icon /></twig:block/>
</twig:alert:root>

because i don't really like the visual bloat of the second variant. But as i found out it doesn't work that way, and the alert:icon component is rendered inside the content block of the alert:root component instead of the icon block.

So the question is: is there a away to outsource the twig blocks definition into the seperate components to avoid having to explicitly set the blocks everytime?

Thanks in advance and if anything is unclear, let me know.

smnandre commented 4 months ago
<twig:alert:root>
    <twig:block name='icon'><twig:alert:icon /></twig:block/>
</twig:alert:root>

This is the right choice here. But you also can use, once per component, the "magical" content block. If you pass content inside a component, it will be assigned to the content block (if you declare it)

For the others you have to name them.

So this works:

<twig:alert:root>
    <twig:alert:icon />
</twig:alert:root>

... but it's equivalent to

<twig:alert:root>
   <twig:block name="content">
        <twig:alert:icon />
    </twig:block>
</twig:alert:root>