Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dynamic tags for lit-html not possible?

Can anyone tell me why I cannot use variables within lit-html's html method?

const h1 = 'h1';
return html`
  <${h1} class="a-heading ${classes}">
    <slot></slot>
  </${h1}>
`;

If I replace ${h1} with h1 that works without problems.

like image 271
codepleb Avatar asked Jan 09 '20 14:01

codepleb


People also ask

What is dynamic tags in HTML?

Dynamic HTML is a collective term for a combination of Hypertext Markup Language (HTML) tags and options that can make Web pages more animated and interactive than previous versions of HTML. Much of dynamic HTML is specified in HTML 4.0.

How lit HTML works?

lit-html is an HTML templating library. Templates are written in JavaScript by mixing static HTML strings and dynamic JavaScript values using template literals. lit-html enables a functional / UI-as-data programming model, fast initial rendering, and fast updates that minimally update DOM when state changes.

How do you modify a tag in HTML?

You can change the HTML tags by typing the new start tags in the Starting Tag(s) field, and the appropriate end tags in the appropriate order, in the Ending Tag(s) entry field. Select the Apply button. Note: Make sure that the starting and ending tags match; otherwise, you may receive unexpected results.


2 Answers

The reason lit-html doesn't allow for dynamic tag names is that lit-html works by replacing the expressions with special markers and then creating an HTML <template> element with the result.

The key, and slightly subtle, part here is that it does not use the values to create the template. They are interpolated into the template after the template is cloned, which is after the HTML has ben parsed. There's no way to go into a tree of DOM and change the tag name of one element. We'd have to remove the element, replace it, set up any bindings, and move any children into the new element. This would be very expensive.

We do have plans to support static bindings (once we can drop support for older Edge browsers that don't implement template literals quite correctly) which are interpolated before creating the HTML <template>, which would allow for using expressions for tag names. Static bindings would not be updatable with new data however - the value at template creation time is the only value used.

like image 109
Justin Fagnani Avatar answered Oct 26 '22 04:10

Justin Fagnani


For everyone interested in my solution: Use unsafeHTML if you can (you should not do that if you wrap any input fields within).

    import { unsafeHTML } from 'lit-html/directives/unsafe-html';
   
     // ...

    const template = `
      <h${this.rank} class="a-heading">
        <slot></slot>
      </h${this.rank}>
    `;

    return html`
      ${unsafeHTML(template)}
    `;
like image 22
codepleb Avatar answered Oct 26 '22 04:10

codepleb