davidtheclark / react-aria-menubutton

A fully accessible, easily themeable, React-powered menu button

Home Page:https://davidtheclark.github.io/react-aria-menubutton/demo

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Anchor tag in <MenuItem> doesn't work properly

markusenglund opened this issue · comments

I want to be able to have a MenuItem act as an external link. Example:

  constructor() {
    super();
    this.state = { isOpen: false };
  }
  render() {
    return (
      <Wrapper
        onSelection={() => {}}
        onMenuToggle={({ isOpen }) => {
          this.setState({ isOpen });
        }}
      >
        <Button>
          Example
        </Button>
        <Menu className="dropdown-menu">
          <MenuItem
            className="dropdown-item"
            tag="a"
            href="https://example.com/"
            target="_blank"
            rel="noopener noreferrer"
          >
            Whatup
          </MenuItem>
        </Menu>
      </Wrapper>
    );
  }
}

This doesn't work properly. Clicking the link with the mouse works fine, but selecting it with the enter key doesn't cause the link to open. I think this package should support that. If others agree, I can make a pull request.

Browser: Google Chrome 63.0.3239.52 beta
OS: Linux Mint 18.2

I'd be curious to see this in action. Do you have a codepen or live demo to check out?

@marcysutton Here it is in the project I'm working on: https://fcc-clone.herokuapp.com/ - the 'community' dropdown in the header is the interesting part. It's using a fork of react-aria-menubutton: https://github.com/yogaboll/react-aria-menubutton.

The only thing I've changed to the package is that I added the line if (this.props.tag === "a") return; in the MenuItem.js file. This seems to work fine as far as I can tell.

That's probably because by returning you're skipping the event.preventDefault() and allowing the link to open a URL. I'd go one step further and filter based on the target attribute in addition to tag so you don't impact other menuitems.

I'd also add a new window icon to each item to show that URLs open in new windows so the user expects a change in context. Probably a "opens in a new window" offscreen label of some kind, as well.

Yeah, you're right about it skipping event.preventDefault().

I don't quite understand what you mean in your second sentence. Do you mean target as in target="_blank" or event.target? I don't see how either would help. All MenuItems that are not <a> should work as normal already.

Good points @marcysutton!

@yogaboll I'd also add that it would be helpful if you could reproduce this behavior in the demos of the master branch here (not your fork). That's how we could determine whether the bug is in your code or the library code.

I've reproduced it on the master branch by only adding a tag and href to the MenuItems in basicDemo.js like this:

     return (
       <li className="AriaMenuButton-menuItemWrapper" key={i}>
         <MenuItem className={itemClass} tag="a" href="http://example.com" value={word} text={word}>
           {display}
         </MenuItem>
       </li>
     );

The current behaviour is

  • If you click a MenuItem with the mouse, it calls the onSelection callback and then redirects you to the link in the href
  • If you tab to it and click enter or spacebar only the onSelection callback is called and nothing else happens.

Thanks for this package by the way. I get a lot of use from it!

@yogaboll Ah, makes sense.

The only thing I've changed to the package is that I added the line if (this.props.tag === "a") return; in the MenuItem.js file.

That sounds good. I might add another condition: if (this.props.tag === 'a' && this.props.href) return;. Think that will work?

Open to a PR implementing this. Thanks!

Is it right that this is fixed/should be closed, now that #75 is merged?