import { html as litHtml } from 'lit-html/lit-html.js'; export { render } from 'lit-html/lit-html.js'; /** * This is a wrapper around lit-html that supports dynamic strings to be added as a preprocessing * step, before a template is passed to lit's html function. * A dynamic string will be evaluated one time (on init) and passed to lit-html as being * part of the static string. * * WARNING: do not use in production!!! has a huge performance penalty as every string is * different from lit-htmls perspective so a new tag is created every time. * * A valid use case for this would be to create dynamic tag names. * * @example: * const tag = unsafeStatic('my-tag'); * html`<${tag} prop="${prop}">` * // will in turn calls lit-html html function as: * html`` * * @param {TemplateStringsArray} strings Static Parts * @param {Array[any]} values Dynamic Parts * @returns {import('lit-html').TemplateResult} */ export function html(strings, ...values) { const newVal = []; // result values to be passed on to lit-html const newStr = []; // result strings to be passed on to lit-html if (values.length === 0) { return litHtml(strings, ...values); } const isDynamicProp = p => p && p.d && typeof p.d === 'string' && Object.keys(p).length === 1; const addToCurrentString = add => { newStr[newStr.length - 1] = newStr[newStr.length - 1] + add; }; // Create the result arrays values.forEach((string, index) => { if (index === 0) { newStr.push(strings[0]); // this is either ''(if tagged starts with value) or string } // Situation 1 : dynamic string const p = values[index]; // potential dynamic string if (isDynamicProp(p)) { addToCurrentString(p.d); addToCurrentString(strings[index + 1]); } else { // Situation 2: no dynamic string, just push string and value newVal.push(p); // a 'real' value newStr.push(strings[index + 1]); } }); // Return lit template // TODO: this is the reason it's not performant TemplateStringsArray needs to be always exactly // the same => e.g. would require specific caching // @ts-ignore return litHtml(newStr, ...newVal); } export function unsafeStatic(options) { return { d: options, }; }