WebReflection / augmentor

Extensible, general purpose, React like hooks for the masses.
https://medium.com/@WebReflection/demystifying-hooks-f55ad885609f
ISC License
134 stars 7 forks source link

comparison to haunted? #5

Closed dakom closed 5 years ago

dakom commented 5 years ago

Both this and haunted are listed on the hyperHTML page...

Seems haunted has context already... can someone please explain some of the pros/cons to using augmentor vs. haunted?

dakom commented 5 years ago

Or... maybe what I'm wondering... is if I want to use lighterhtml with haunted?

Asked here too (since it can be viewed from both perspectives): https://github.com/matthewp/haunted/issues/53

WebReflection commented 5 years ago

haunted already works with hyperHTML as mentioned in the very first line of that project.

However, haunted is for custom elements, augmentor works even in NodeJS.

dakom commented 5 years ago

True (as I also mentioned) - though I still think this issue, or at least me, needs a bit more handholding to get how the pieces fit together. I'll explain:

The haunted example uses .wire() and does not use hyperElement - and yet also looks much simpler than the Custom Elements example on the lighterhtml Readme, despite the lighterhtml professing to be simpler...

Or, brass tacks, if I do want to build web components with haunted hooks, but benefit from the speed and approach of the hyper ecosystem for rendering, and not have to think about the complexities of shadow dom and all that, what's the recommended approach?

Fwiw the haunted example using just core hyperHTML looks very appealing, just not quite sure how that fits into the "web component" dynamic if say I want to pass that over for use in a project that does not use hyper for rendering.

dakom commented 5 years ago

So... this seems to work:

import {render, html} from "lighterhtml";
import {component, useState} from "haunted";

const Counter = (el) => {
    const [count, setCount] = useState(0);

    return html`
        <div>${count}</div>
        <button onclick=${() => setCount(count + 1)}>Increment</button>
    `;
}

customElements.define('my-counter', component(Counter));

And then I can just use <my-counter /> on the html page - or probably anywhere (i.e. lighterhtml renders, hyperhtml renders, etc.)

Am I missing something?

I wasn't able to make it work on codesandbox but whatever, that site breaks lots of stuff for me here and there :P

dakom commented 5 years ago

Assuming that's right, and it's really this easy to create custom elements - what is it missing that the hyperElement example on the Readme adds?

Should I be using that el for passing somewhere as a hint (like in the wire() example)?

Also - though not hyper specific, I'm not really sure if I need to polyfill for shadow dom, or why I want a shadow dom (is it about having CSS baked in or something?) :\

dakom commented 5 years ago

Oh scratch that - I was able to get it going on codesandbox, just had to give it an empty .babelrc o_O

https://codesandbox.io/s/z6nwq40863

dakom commented 5 years ago

Wait a sec... taking it a step further (sorry - I'm just learning about web components!)... can't one just use neverland throughout, and then if/when it's decided that the components really need to be shared with the outside world, just wrap it in a thin custom element for sharing?

Proof of concept: https://codesandbox.io/s/5zw1k062mk

WebReflection commented 5 years ago

Am I missing something?

Yes, you are trashing the layout every time. You need to render if you want keyed layout, i.e. render(el, () => html...) however that platform is very bad for runtime testing, IMO, so I've created a Code Pen that does basically this:

import { component, virtual, useState } from "haunted";

import { hook } from "lighterhtml";
const { html } = hook(current => useState({current})[0]);

const Counter = (el) => {
  const [count, setCount] = useState(0);
  return html`
    <div>${count}</div>
    <button onclick=${() => setCount(count+1)}> Increment</button >
  `;
}

customElements.define('my-counter', component(Counter));

Now you have keyed result per each component.

and yet also looks much simpler than the Custom Elements example on the lighterhtml Readme

that's obviously because you are comparing apples to oranges. The lighterhtml example is with raw custom element, haunted is a library that uses custom elements, Shadow DOM and Proxy (good luck with backward compatibility, if needed).

If you take HyperHTMLElement you could:

(class extends HyperHTMLElement {
  created() { this.render(); }
  render() {
    const [i, update] = useState(0);
    this.html`${I} <button onclick=${() => update(I + 1)}>increment</button>`;
  }
}).define('my-counter');

that's it, but I don't understand what's your point here.

if I do want to build web components with haunted hooks, but benefit from the speed and approach of the hyper ecosystem for rendering, and not have to think about the complexities of shadow dom and all that, what's the recommended approach?

I use HyperHTMLElement without Shadow DOM in production so that'd be my recommendation

Fwiw the haunted example using just core hyperHTML looks very appealing, just not quite sure how that fits into the "web component" dynamic if say I want to pass that over for use in a project that does not use hyper for rendering.

hyper produces DOM nodes, so it's compatible with everything out of the box.

I'm not really sure if I need to polyfill for shadow dom

if you use haunted you're kinda doomed then 😅 due its Shadow DOM by default and Proxy

WebReflection commented 5 years ago

can't one just use neverland throughout, and then if/when it's decided that the components really need to be shared with the outside world, just wrap it in a thin custom element for sharing?

that's surely an option, nice example 👍

dakom commented 5 years ago

Hmmm small snag... tried doing both at the same time and one of them gets swallowed up:

https://codesandbox.io/s/lpzwp4o62l

dakom commented 5 years ago

(codesandbox kinda sucks for this - but I found hitting the reload button in the virtual browser to be fairly painless when it crashes after every edit, hehe)