Skip to content

Instantly share code, notes, and snippets.

@henriquegogo
Last active April 3, 2025 20:20
Show Gist options
  • Select an option

  • Save henriquegogo/0fb36f804b57c029ba4a7b19280bc040 to your computer and use it in GitHub Desktop.

Select an option

Save henriquegogo/0fb36f804b57c029ba4a7b19280bc040 to your computer and use it in GitHub Desktop.
Create HTML Elements with arguments and nested children
const ElementBuilder = new Proxy({}, { get: (_, tagName) => (...args) => {
const element = Object.assign(document.createElement(tagName), ...args);
element.append(...args.filter(arg => arg.constructor !== Object));
return element;
}});
const EventHandler = (fn, element) => Object.assign(element || {}, {
self: element,
update: (newProps) => element.replaceWith(fn(newProps)),
listen: (eventType, handler) => (element.dataset.event = "", element)
.addEventListener(eventType, ({ detail }) => handler(detail)),
dispatch: (eventType, detail) => document.querySelectorAll("[data-event]")
.forEach(el => el.dispatchEvent(new CustomEvent(eventType, { detail })))
});
const { div, h1, button } = ElementBuilder;
function HelloWorld(message = 'Hello World!') {
const handleEvents = (element) => {
const { self, listen, update } = EventHandler(HelloWorld, element);
listen('newdata', update);
listen('newdata', () => console.log('gotcha!'));
return self;
};
return { update, dispatch } = handleEvents(
div(
h1({
className: 'hello-world',
onclick: () => update('Bye bye') // `update` is now inside `handleEvents`
}, message),
button({
onclick: () => dispatch('newdata', 'Bye bye')
}, 'Click here')
)
);
}
document.body.append(HelloWorld());
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment