Open NullVoxPopuli opened 2 years ago
@locks status?
Another potential syntax:
<SubComponent @:myBlock={{:myBlock}} />
This implies:
:myBlock
is a value that can be passed@:
implies named block values could be accessed from this.args
@*
notations in the future@:
argument means the same as if the component wrote out:
<:myBlock>
{{yield to="somethingElse"}}
</:myBlock>
with the exception that if a value passed to @:
is falsey, the named block matching the identifier after the :
is not present.
Alternatively (or maybe in addition to, because this is about to be way more typing than the above, we could allow control-flow syntaxes outisde named-block space.
For example:
{{! the contents of "MyDemo" component }}
<ListItem @list={{@list}}>
{{#if (has-block "media")}}
<:media>
{{yield to="media"}}
</:media>
{{/if}}
</ListItem>
e.g.: if <MyDemo>
is rendered with a <:media>
block, pass those contents to <ListItem>
, otherwise render <ListItem>
as if no :media
block were used.
I just ran into this today. I needed a way to use Ember/Glimmer components to render dynamic content that is generated from a nested data structure. By nature of nested data structures we needed recursion which is supported but the parent's block(s) were not transferable to the recursive children and so they became no-ops making the system only able to handle one level of nesting in the data.
data = [
{ type: ‘text’, value: ‘This is a ‘ },
{
type: ‘link’,
children: [
{ type: ‘text’, value: ‘fancy link ‘ },
{ type: ‘icon’ },
],
},
{ type: ‘text’, value: ‘ to render.’ },
];
With something like this:
<MyFancyComponent @nodes={{this.data}} as |type Content|>
{{#if (eq type "link")}}
<MyLink><Content /></MyLink>
{{else if (eq type "icon")}}
<MyIcon />
{{/if}}
</MyFancyComponent>
But if you notice the data structure has nested nodes under children so when attempting to recurse you would normally have this:
{{yield
currentNode.type
(component MyFancyComponent nodes=currentNode.children)
}}
Which is unable to pass along the parent's yielded block thus rendering any child nodes rendering useless.
context: https://github.com/emberjs/rfcs/pull/460#issuecomment-902961346
The lack of this capability is a HUGE growing pain for the projects I'm working on and causes a lot of cruft and awkward APIs, and having this feature would simplify a ton of things.
For library / ui / design-system authors, having passable blocks would be an IMMENSE lift / relief -- and it feels very surprising that this wasn't talked about more during the original RFC (or maybe it was planned to be added later, and just no one has gotten around to it)
Related thoughts:
Example:
the first place this came up was our big table component wrapped with all the bells and whistles. Here is a more generic, yet very related, example.
A table component
A wrapper component cannot
Like,
are not possible APIs.
You can hack around this, by, in the implementation of
WrappedTable
, put anif
block around the entirety ofTable
, but that's 1. terrible, and 2. does not scale past 1 named block.I have 7 named blocks in Table component
In order to provide a wrapper table (with nice defaults, optional blocks, etc), I cannot fathom (other than actually doing the math) the amount of code it would take to if-stamement my way through implementing that.