JSFiddle - React, Tailwind, and code Playground
HTML
<div id="root">
</div>
JavaScript
"use strict";
{
const LAST_ATTR_NAME = /\s+([\w-]+)\s*=\s*"?\s*$/;
const NEW_TAG = /<[\w\-]+/;
const parser = new DOMParser;
Object.assign(self,{R,render,fc});
function fc( t, frag = false ) {
const fragment = parser.parseFromString(
`<template>${t}</template>`,
"text/html")
.head
.firstElementChild
.content;
if ( frag ) {
return fragment;
}
return fragment.firstElementChild;
}
function R(parts, ...vals) {
parts = Array.from(parts);
const handlers = {};
vals = vals.map( v => {
if ( Array.isArray(v) && v.every(item => !!item.handlers && !!item.str) ) {
return join(v,handlers);
} else if ( typeof v == "object" && !!v && !(v.str && v.handlers) ) {
throw { error: `Object properties not allowed`, value: v };
} else return (v == null || v == undefined) ? '' : v;
});
let str = '';
let newHid = false;
let hidSaved = false;
let hid;
while(parts.length > 1) {
let part = parts.shift();
newHid = part.match(NEW_TAG);
if ( newHid ) {
hid = 'hid_' + Math.random();
hidSaved = false;
}
let attrNameMatches = part.match(LAST_ATTR_NAME);
let val = vals.shift();
if ( typeof val == "function" ) {
let attrName;
if ( attrNameMatches && attrNameMatches.length > 1) {
attrName = attrNameMatches[1];
attrName = attrName.replace(/^on/,'').toLowerCase();
}
const newPart = part.replace(attrNameMatches[0], '');
if ( attrName ) {
str += newPart;
} else {
str += part;
}
if ( !hidSaved ) {
handlers[hid] = [];
hidSaved = true;
str += ` data-hid="${hid}"`;
}
handlers[hid].push({
eventName: attrName, handler: val
})
} else if ( !! val && val.handlers && val.str ) {
Object.assign(handlers,val.handlers);
str += part;
...