atomicojs / atomico

Atomico a micro-library for creating webcomponents using only functions, hooks and virtual-dom.
https://atomicojs.dev
MIT License
1.16k stars 43 forks source link

Bug: AtomicoJS lose focus rendering #66

Closed cawfeecoder closed 2 years ago

cawfeecoder commented 2 years ago

Example Component:

const input = ({ placeholder, icon, value, type, onchange }) => {
  let [error, setError] = useState(true);

  return (
    <host>
      <div class={tw(containerStyles(error))}>
        {typeof icon != "undefined" ? <i class={tw(iconStyles(icon))} /> : null}
        <input
          type={type}
          class={tw(inputStyles(true))}
          placeholder={placeholder}
          oninput={() => setError(false)}
          value={value}
        ></input>
      </div>
    </host>
  );
};

Upon typing into the input box, the input box will lose focus when calling setError. This is not the case with most other frameworks (i.e. you won't lose the input because only the parent will be re-rendered and not the children).

UpperCod commented 2 years ago

Hi, I could see the commented, the problem is because value is not updated as state, let me explain:

First render: define input with the value state of the webcomponent. Second render dispatched by setError: when regenerating the DOM value it does not change but Atomico redefines it, since Atomico before the use of the value property recovers the value from the DOM in order to avoid the loss of focus.

The solution to this is to update the state of value, example:

https://webcomponents.dev/edit/ypFhstbGQqgQA4c6VN5B,

Thank you for your issue, I await your review since this way we can improve the Atomico render in these cases.

I invite you to recreate the error in webcomponents.dev so that I can better understand your issue.

cawfeecoder commented 2 years ago

@UpperCod How would this work in the case of onfocus/onblur? Those seem to correctly set the attribute, but lose focus on the element (ironically enough).

cawfeecoder commented 2 years ago

I've re-thought my component and solved my issues :D