Add support for native <template> as an alternative to renderer
Haprog opened this issue · comments
Currently this would be a very nice enhancement to the following components:
- vaadin-dialog
- vaadin-notification
- vaadin-overlay
- vaadin-select
This would be a new feature (new minor version) and should be pretty simple to implement.
And maybe it could be useful also for these, but in these it would not be as useful atm.
- vaadin-context-menu
- Could be helpful for simple use cases even though there is already
items
API. Click actions would need to be set in JS anyway or viaonclick=""
attributes in template)
- Could be helpful for simple use cases even though there is already
- vaadin-grid
- Could be useful for header and footer templates, but maybe not for main column template or row details without custom data binding.
It would be good to have this supported consistently for all cases where we currently support <template>
with Polymer bindings (e.g. all grid renderers too) but for that to make sense we would also need to add some data binding implementation that would not be dependent on Polymer (to keep it working when we move on from Polymer).
Some context
Here's a PR to vaadin-select for simplifying the demos to benefit from this kind of approach: vaadin/vaadin-select#203
These demos would become even simpler and have less JS if this feature was implemented.
E.g. this kind of demo:
<vaadin-select></vaadin-select>
<template id="selectTemplate" preserve-content>
<vaadin-list-box>
<vaadin-item>Jose</vaadin-item>
<vaadin-item>Manolo</vaadin-item>
<vaadin-item>Pedro</vaadin-item>
</vaadin-list-box>
</template>
<script>
customElements.whenDefined('vaadin-select').then(function() {
const template = document.getElementById('selectTemplate');
document.querySelector('vaadin-select').renderer = function(root) {
if (!root.firstChild) {
root.appendChild(template.content.cloneNode(true));
}
};
});
</script>
Cound then be implemented simply as something like this:
<vaadin-select>
<template native preserve-content>
<vaadin-list-box>
<vaadin-item>Jose</vaadin-item>
<vaadin-item>Manolo</vaadin-item>
<vaadin-item>Pedro</vaadin-item>
</vaadin-list-box>
</template>
</vaadin-select>
Where native
would be a new custom attribute that we would check for (if not present, it would be parsed as a Polymer template like it works now). Once we drop support for Polymer we could remove the native
and preserve-content
attributes from here.
vaadin-dialog
, vaadin-select
and vaadin-context-menu
already just pass the <template>
element over to vaadin-overlay
, so implementing this in vaadin-overlay
should automatically provide the functionality for vaadin-dialog
, vaadin-select
and vaadin-context-menu
too.
Separate implementation is needed for vaadin-notification
.
Sounds like a low-hanging fruit then 👍 Marker for the template could be something more descriptive like <template overlay-content>
(or <template class="overlay-content">
if we still want to align with <vaadin-grid>
's <template class="header">
etc)
I kind of like <template class="overlay-content">
as it's more clear that the class is custom and not a native thing, but then its semantics is kind of similar to slot=""
as it's saying where it goes (kind of a "target") and it might be confusing why this class then needs to be left out then when you want to use a Polymer template. When using a Polymer template it's also the "overlay content".
vaadin-grid-column
has:
<template class="header">
<template>
<template class="footer">
which kind of mimics default slot and two named slots. In this case for overlay content there can only be one template so it should be the default one and there shouldn't be a need to define the "target" for it. Instead for this issue we want to differentiate between Polymer template and "native" template without Polymer processing.
For the API it would be nicer to have the extra attribute for the Polymer template instead, but that's no good for backwards compatibility.
Maybe data-static
would be a better attribute name?
As a first time user I wouldn't understand what data-static
means. data
also gives a wrong impression since the template API would specifically be about static content.
When using a Polymer template it's also the "overlay content"
Yes the two template syntaxes are very similar, both are also "native" <template>
s.
After taking a second look, I think we don't need to do anything right now :) The ideal syntax (without any markers on the <template>
) already works. Using Polymer syntax for data-binding on top of that is optional and happens to work (for now) but we don't need to promote that anymore = prefer renderer
s in demos that need dynamic overlay content.
Once we no longer build on Polymer, we can change the internal implementation to use a renderer that reads from the <template>
in case we want to retain that API.
So you're saying it's ok to promote use of <template>...</template>
in demos now (for simple cases where a renderer would have worse DX and more boilerplate), even though it's currently implemented as a Polymer template, as long as we don't use the Polymer template features like data-binding in those demos?
I agree and that's kind of what I was going for initially, but I understood we don't want to do that because of Polymer.
Then I'd like to edit the above mentioned vaadin-select
PR to embrace template in demos like:
<vaadin-select>
<template>
<vaadin-list-box>
<vaadin-item>Jose</vaadin-item>
<vaadin-item>Manolo</vaadin-item>
<vaadin-item>Pedro</vaadin-item>
</vaadin-list-box>
</template>
</vaadin-select>
But what about the one "actual Polymer template" demo then? Should we just not mention anything about Polymer then or can we mention that using Polymer data binding works now but maybe say it's "deprecated" in favour of renderers when you need dynamic content?
And then maybe have a renderer example that actually has some dynamic part in it.
Can we also mention in the API docs (where we now talk about Polymer template support) that using Polymer features in templates is deprecated)? That would clarify the situation a bit. But we would still have nice template API for simple static content cases.
Closing this issue as we concluded that the API doesn't need to be changed now, but we can update demos to be simpler in some cases.
Above mentioned PR for vaadin-select to improve the demos was updated and merged. We may do similar demo updates to other components.