lit/lit-element

Render user defined template

Closed this issue · 2 comments

Hello chaps,

I just wondered if it is currently possible to render user defined template?
An example of what I mean is I am creating a custom select component and a want the user to be able to define in markup the template for each item:
(Note <template> element)

<custom-select>
  <template>
     <strong>${item.name}</strong> is ${item.age} years old!
  </template>
</custom-select>

And in my component something simulair to:

render() {
  return html`<ul>
    <li>${
      this.data.map(item => template(item));
    }</li></ul>`
}

I'm not sure if this is possible, I may have a rethink of how to design....

Because we don't yet have a good interoperable way to define templates with data interpolation in the platform, it's not yet possible to define a custom element that accepts a generic <template> that will be cloned AND bound to data by the custom element (see the Template Instantiation proposal for ideas being discussed for filling this gap in the platform).

For now we have to resort to having custom elements accept a "templating-library-specific" template as part of its API.

So for example, it is easy to define a LitElement which accepts a property that expects a Lit TemplateResult or even a function that returns a TemplateResult bound to instance-specific data. In practice this would look something like this:

@customElement('custom-select')
class CustomSelect extends LitElement {
  @property()
  data: Items[] | undefined = undefined;
  @property()
  template: (item: Item) => TemplateResult | undefined = undefined;
  render() {
    return html`
      <ul>
        <li>${this.data.map(item => this.template(item))}</li>
      </ul>
    `;
  }
}
const template = (item) => html`<strong>${item.name}</strong> is ${item.age} years old!`;
html`<custom-select .template=${template}></custom-select>`

We do have some ideas about defining a protocol of sorts for a template-library-agnostic function signature to pass these sort of templates to custom elements, such that the template library used by the user is abstracted from the library used inside the custom element, so maybe follow this issue for advancements on that idea: lit/lit#1478