Search code examples
reactjsreact-hooksuse-ref

How to programmatically expand React Reach UI (@reach/menu-button) Menu?


I am using introduction package called intro.js and after certain step I would like to click on my dropdown menu and present the dropdown menu. The issue I am having is that .click event doesn't work, while .focus does. I have console.log() which fires but the dropdown never opens for some reason. Here is the code:

import "./styles.css";
import React, {useRef} from 'react'
import { Steps, Hints } from "intro.js-react";
import {
  Menu,
  MenuList,
  MenuButton,
  MenuItem,
  useMenuButtonContext,
} from "@reach/menu-button";



export default function App() {

  const myRef = useRef(null)

  const [state, setState] = React.useState({
      stepsEnabled: true,
      initialStep: 0,
      steps: [
        {
          element: ".hello",
          intro: "Hello step"
        },
        {
          element: ".world",
          intro: "World step"
        }
      ],
      hintsEnabled: true,
      hints: [
        {
          element: ".hello",
          hint: "Hello hint",
          hintPosition: "middle-right"
        }
      ]
    })



  // This event fires after 2 seconds of closing the introduction tour
  const onExit = () => {
    setTimeout(() => {myRef.current.click(), console.log("this is the first message")}, 2000);
  }


  return (
    <div className="App">
        <Steps
          enabled={state.stepsEnabled}
          steps={state.steps}
          initialStep={state.initialStep}
          onExit={onExit}
        />
             <h1 className="hello">Hello,</h1>
        <hr />
        <h1 className="world">World!</h1>
        <hr />
      <Menu>
      <MenuButton id="example-button" ref={myRef} onClick={()=> console.log('clicked')}>
        Actions <span aria-hidden="true">▾</span>
      </MenuButton>
      <MenuList>
        <MenuItem >
          Download
        </MenuItem>
        <MenuItem >
          Create a Copy
        </MenuItem>
        <MenuItem >
          Mark as Draft
        </MenuItem>
        <MenuItem >
          Delete
        </MenuItem>
      </MenuList>
    </Menu>
    </div>
  );
}

Basically once I close the introduction tour (modal) I would like to to have dropdown open. Here is a link to Codesandbox of this example: https://codesandbox.io/s/relaxed-swartz-8b8s6?file=/src/App.js

P.s Sorry for bad code format and no refactoring, this is only a PoC!


Solution

  • According to the docs (scroll to the end), MenuButton uses mousedown. I tried dispatching the mousedown event and it expanded the menu:

    const onExit = () => {
        setTimeout(() => {
          myRef.current.dispatchEvent(new Event("mousedown", { bubbles: true }));
        }, 2000);
    };
    

    Edit elastic-resonance-bvup6