hybridsjs / hybrids

Extraordinary JavaScript UI framework with unique declarative and functional architecture
https://hybrids.js.org
MIT License
3.05k stars 85 forks source link

how to create a component method #227

Closed Qsppl closed 10 months ago

Qsppl commented 10 months ago

Due to the specificity of the "focusin"/"focusout" events, we must process only the last of the events generated in two consecutive macro tasks (including the macro task in which the first event was generated) from the moment the first event occurred.

This is easily solved by placing the event handler in a wrapper function.

native js example: https://codepen.io/qsppl/pen/poYvEVj?editors=1010 image

You cannot use a single deboucer for all components at once, since components can be nested within each other and then a single deboucer will not work correctly. image

This should be a method of the html element, but we can't assign that value to it. image

smalluban commented 10 months ago

You can generate debounce instance in connect callback. If this is repeatetive pattern, the best way would be to create a factory for it:

function debounceFactory(fn, options) {
  return {
    value: (_, value = fn) => value,
    connect(host, key) {
      host[key] = debounce(fn, options);
      return () => host[key].cancel();
    },
  };
}

const My component = {
  focusCallback: debounceFactory(...),
};

The above factory generates debounce for each instance of the component, and also protects from early access to the function before connecting to document.

Qsppl commented 10 months ago

I tried to create a descriptor directly, then I tried to use a factory to create a descriptor, but it all returns the same error as when using a function as a property value. image

One of the previous examples returns the same error. image

Even the types do not indicate that a function can be used as the value of the 'value' property. image

But it works if you declare the descriptor properties "get" and "set". image

Did you make a typo in the example or did I break something?

P.S. I don't use descriptor factories because it's too difficult for them to specify types. Now it didn’t work out for me at all. Maybe create some kind of generic interface for factories? image

smalluban commented 10 months ago

Sorry, I used upcoming syntax, sure it should be get / set, so it should look like this:

function debounceFactory(fn, options) {
  return {
    set: (_, value = fn) => value,
    connect(host, key) {
      host[key] = debounce(fn, options);
      return () => host[key].cancel();
    },
  };
}

about TS, there is Descriptor<T> type, so it is straight forward to define factories in Typescript.

Qsppl commented 10 months ago

Thanks, it works