I am converting an app from polymer 1 to polymer 3. I used juicy-html, but they have not updated to Polymer 3 and I see that there is lit-html. I am wondering how I can change this snippet to using lit-html. It is used for expanding a string like: 'Hello <span class="highlight">world</span>!'
Here is the snippet of code from my polymer 1 component.
<template is="dom-repeat" items="[[item.snippets]]">
<template is="dom-repeat" items="[[item.matches]]">
<div><template is="juicy-html" content$="[[item.text]]"></template></div>
</template>
</template>
Do I need to implement a new component for the inner div? Is there an example that I can look at?
Here is the resulting Polymer 3 element to display a highlighted text within a string:
import {html, LitElement} from '@polymer/lit-element/lit-element.js';
/**
* `search-snippet-highlight`
*
*
* @customElement
* @polymer
* @demo demo/index.html
*/
class SearchSnippetHighlight extends LitElement {
static get properties() {
return {
snippet: { type: String }
};
}
render() {
return html`
<style>.highlight { background-color: yellow; }</style>
<div .innerHTML="${this.sanitizeHtml(this.snippet)}"></div>`;
}
sanitizeHtml(input) {
return input; // TODO: actually sanitize input with sanitize-html library
}
}
window.customElements.define('search-snippet-highlight', SearchSnippetHighlight);
The equivalent of that <template>
with juicy-html
in Polymer's LitElement
(the recommended base element that uses lit-html
) is:
render() {
let content = '';
for (const s of this.item.snippets) {
for (const m of s.matches) {
content += `<div>${m.text}</div>`;
}
}
return html`<div .innerHTML="${this.sanitizeHtml(content)}"></div>`;
}
The render
function above does the following:
div
's innerHTML
, using LitElement
syntax (.PROPERTY="VALUE"
)<html>
<head>
<!-- Polyfills only needed for Firefox and Edge. -->
<script src="https://unpkg.com/@webcomponents/webcomponentsjs@latest/webcomponents-loader.js"></script>
</head>
<body>
<!-- Works only on browsers that support Javascript modules like
Chrome, Safari, Firefox 60, Edge 17 -->
<script type="module">
import {LitElement, html} from 'https://unpkg.com/@polymer/lit-element/lit-element.js?module';
class MyElement extends LitElement {
static get properties() {
return {
item: { type: Object }
}
}
constructor() {
super();
this.item = {
snippets: [
{
matches: [
{text: 'hello <span class="highlight">world</span>'},
{text: 'we are the <span class="highlight">world</span>'},
{text: 'war of the <span class="highlight">world</span>s'},
]
},
{
matches: [
{text: 'the <span class="highlight">cat</span> in the hat'},
{text: '<span class="highlight">cat</span>fish are in the water'},
{text: '<span class="highlight">cat</span>erpillars become butterflies'},
]
},
]
};
}
render() {
let content = '';
for (const s of this.item.snippets) {
for (const m of s.matches) {
content += `<div>${m.text}</div>`;
}
}
return html`
<style>.highlight { background: rgb(255, 251, 222); }</style>
<div .innerHTML="${this.sanitizeHtml(content)}"></div>`;
}
sanitizeHtml(input) {
return input; // TODO: actually sanitize input with sanitize-html library
}
}
customElements.define('my-element', MyElement);
</script>
<my-element mood="great"></my-element>
</body>
</html>