Giter Site home page Giter Site logo

Composability about hyperhtml HOT 6 CLOSED

webreflection avatar webreflection commented on May 13, 2024
Composability

from hyperhtml.

Comments (6)

WebReflection avatar WebReflection commented on May 13, 2024

The entirety of the DBMonster is made up composing elements, each entry is a TR with two TDs and once created it adds 5 entries per each top 5 query.

That means that in a template liek the following:

function update(render, items) {
  render `<List>${items}</List>`;
}

// performing an update like this
update(
  hyperHTML.bind(document.body),
  [any, element, you, want]
);

You can compose List.childNodes as you want/need but I also think that your specific case would be more suitable for Custom Elements.

from hyperhtml.

albertosantini avatar albertosantini commented on May 13, 2024

Sorry to resume this old thread, but, I think, my use case is the same topic

What if I have a list of nested components?
Any native hyperHTML solution without using Custom Elements?
And how to pass some data to the "component"?

Basically how should I write the line?
<baz>Here how to pass some data to the component?</baz>

A few details below.

This is the usual approach without any nested component:

<ul>${state.items.map(item => hyperHTML.wire(item, ":li")`
    <li>${item.id} / ${item.text}</li>
`)}</ul>

Here the pseudo code with the list of baz elements:

<ul>${state.items.map(item => hyperHTML.wire(item, ":li")`
    <baz>Here how to pass some data to the component?</baz>
`)}</ul>

This is the solution using custom elements:

<ul>${state.items.map(item => hyperHTML.wire(item, ":li")`
    <li-baz data-id="${item.id}"
            data-text="${item.text}">
    </li-baz>
`)}</ul>

And this is the rest of code, with Hyper class borrowed from the tests:

// hyper.js
class Hyper extends HTMLElement {
    _initHyper() {
        if ("hyper" in this) {
            return;
        }
        this.hyper = hyperHTML.wire();
        this.appendChild(this.render());
    }

    attributeChangedCallback() {
        this._initHyper();
    }

    connectedCallback() {
        this._initHyper();
    }
}

// baz.element.js
class LiBazElement extends Hyper {
    render() {
        return this.hyper`
            <li>${this.dataset.id} / ${this.dataset.text}</li>
        `;
    }
}
customElements.define("li-baz", LiBazElement);

from hyperhtml.

WebReflection avatar WebReflection commented on May 13, 2024

@albertosantini is yours a question?

from hyperhtml.

WebReflection avatar WebReflection commented on May 13, 2024

since there is at least one question that you haven't answered yourself (since the way to pass data to Custom Elements is via attributes or events)

Any native hyperHTML solution without using Custom Elements?

I'll try to answer: yes, but it depends what you are trying to do.

hyperHTML is based on static tempaltes, since tempalte literals are static.

This means if you need dynamic templates, either you create as many renderView functions as needed, to cover your cases, or you simply render a template and patch it after, it's not a big deal.

What I mean, is that once you've rendered via hyperHTML you have all the DOM utilities in this world to do whatever you want, even jQuery if you really want to.

const ul = render`
  <ul>${state.items.map(item => hyperHTML.wire(item, ":li")`
    <baz>Here how to pass some data to the component?</baz>
  `)}</ul>`;

ul.querySelectorAll('baz').forEach((baz, i) => {
  Object.assign(baz.dataset, state.items[i]);
  baz.dispatch(new CustomEvent('update'));
});

Above is just one out of many possibilities to interact with the DOM.

from hyperhtml.

albertosantini avatar albertosantini commented on May 13, 2024

Thanks a lot for the details.

This means if you need dynamic templates, either you create as many renderView functions as needed

I had been exploring that approach, but it seems I am missing last mile.

A naive implementation like:

const ul = render`
  <ul>${state.items.map(item => hyperHTML.wire(item, ":li")`
    <baz>${BazComponent.bootstrap({ id: item.id, text: item.text })}</baz>
  `)}</ul>`;

but, of course, it doesn't work because baz element is not found.

from hyperhtml.

albertosantini avatar albertosantini commented on May 13, 2024

Well, at the end of day, I think using custom components is the abstraction I want (I need), because the component is accordingly bootstrapped behind the scenes without too much dom manipulation in the user space, finally at the price of document-register-element lib.

Below a snippet showing the point.

I don't use attributes machinery for data, but an Introspected object items, shared between the components thru the service FooService; anyway I use the attribute id to find the correct element in the array.

// libaz.template.js
class LiBazTemplate {
    static update(render, state, events) {
        return render`
            <li class="pointer" id="${`libaz-id${state.id}`}" onclick="${events}">
                ${state.id} / ${state.text}
            </li>
        `;
    }
}

// libaz.element.js
class LiBazElement extends Hyper {
    constructor() {
        super();

        this.events = (e, payload) => Util.handleEvent(this, e, payload);
        this.items = FooService.getItems();
        this.state = this.items[this.dataset.id - 1];

    }

    render() {
        return LiBazTemplate.update(this.hyper, this.state, this.events);
    }

    onLibazClick() {
        const oldValue = this.state.text;

        this.state.text = "hey li-baz";
        setTimeout(() => {
            this.state.text = oldValue;
            this.render();
        }, 500);
        this.render();
    }
}
customElements.define("li-baz", LiBazElement);

Live demo: https://plnkr.co/edit/FhuB3Ssv5E9xnwoi5bA4?p=preview
Click on bar item to see the component in action and Introspected changes propagated. :)

from hyperhtml.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.