Baseweb: Missing addEventListener and removeEventListener for Button type, Button should extend HTMLButtonElement

Created on 17 Jan 2020  路  7Comments  路  Source: uber/baseweb

The Button element does not include types for addEventListener or removeEventListener, so Typescript will complain when using those functions.

Current Behavior

Typescript shows an error when using a HTMLButtonElement property that is not part of Button:

"Property 'addEventListener' does not exist on type 'Button'.ts(2339)"

The consumer cannot create a new type which extends both Button and HTMLButtonElement because the focus() function on Button doesn't match the focus function on HTMLButtonElement. If Button extended HTMLButtonElement then they would have to match.

Expected Behavior

Button should extend HTMLButtonElement

Your Environment

| Tech | Version |
| ------- | ------- |
| Base UI | v9.42.0 |

  • [x] I have searched the issues of this repository and believe that this is not a duplicate.
bug help wanted

All 7 comments

thank you for opening the issue @ajbogh - any chance you can help to contribute a fix for this?

thank you for opening the issue @ajbogh - any chance you can help to contribute a fix for this?

I'll see what I can do but I have to timebox the problem. If I don't link a PR then I'll keep this open for someone else.

thank you

I looked into this for a little time but couldn't come up with a good solution. Extending the interfaces at a naive level doesn't seem to fix the problem. Admittedly, I lack the advanced knowledge of Typescript to define a more complex solution.

@ajbogh can you help me understand what's your use case for the addEventListener handler?

@gergelyke In the standard Fusion scaffold the welcome.js file includes the following code:

function useHover(ref: React.RefObject<Button>) {
  const [value, setValue] = useState(false);
  const handleMouseOver = () => setValue(true);
  const handleMouseOut = () => setValue(false);
  useEffect(() => {
    const node = ref.current;
    if (node) {
      node.addEventListener('mouseover', handleMouseOver);
      node.addEventListener('mouseout', handleMouseOut);
      return () => {
        node.removeEventListener('mouseover', handleMouseOver);
        node.removeEventListener('mouseout', handleMouseOut);
      };
    }
  }, [ref]);
  return value;
}

In order to make it typed without errors you have to change it to

function useHover(ref: React.RefObject<any>) {

In my opinion, this is a button element that should act like a button and should include all executable properties of an HTML button. The implementation is performed by Fusion which expects it to include the event listeners.

that makes sense, thank you for the additional info!

Was this page helpful?
0 / 5 - 0 ratings