davidtheclark / davidtheclark/react-aria-menubutton

Keeping Menu open by default

Open
#112 0 comments 4 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
452
Forks
76
PR merge metrics
No merged PRs in 30d

Description

Hello and thank you for your work. This library has been of great help to me.

### Use case

I'm using `react-aria-menubutton` to help me handle keyboard navigation in my forms. One of them lives inside a modal. When the modal is open, I want my menu to be visible immediately, without having to trigger it by pressing a button.

### What I tried

#### Passing `isOpen`

The type definitions say I could pass `isOpen` to `Wrapper`.

https://github.com/DefinitelyTyped/DefinitelyTyped/blob/ec03e77d0a0c84d599b46211befac932160d5a0f/types/react-aria-menubutton/index.d.ts#L44

This doesn't seem to be the case. React passes that prop down to the underlying `div` and displays a warning.

```
Warning: React does not recognize the `isOpen` prop on a DOM element. If you intentionally want it to appear in the DOM as a custom attribute, spell it as lowercase `isopen` instead. If you accidentally passed it from a parent component, remove it from the DOM element.
```

#### Passing `open`

The type definitions allow me to pass a prop called `open`, but it doesn't come directly from `WrapperProps`. It's inherited from `AllHTMLAttributes` and has no effect.

#### Using `openMenu`

When I add an `id=menu` to my `Wrapper` and try to open the menu programmatically, I get a runtime exception.

I'm using a function component. It doesn't matter if I use `useEffect` or `useLayoutEffect` to run the effect — at the time they're executed, my menu hasn't mounted yet, and an element of `id=menu` doesn't exist.

```ts
React.useLayoutEffect(() => {
openMenu('menu');
});

React.useEffect(() => {
openMenu('menu');
});

return (

...
)
```

I tried providing a `ref` to `Wrapper` and calling `openMenu` only when I know the underlying HTMLElement is mounted, but unfortunately `Wrapper` doesn't forward React refs. The only workaround that seems to be working is to do:

```ts
React.useLayoutEffect(() => {
if (document.getElementById('menu')) {
ARIA.openMenu('menu');
}
});
```

which works, but because it relies on a low-level DOM API, it goes against the declarative model of React.

### The question

How can I render my menu open from the start?

### Related

- #48 suggests `Wrapper` should accept `isOpen`
- #16 suggests `isOpen` is not meant to manipulate state and mentions [`startOpen`](https://github.com/davidtheclark/react-aria-menubutton/commit/129ed7ac1a48c2652304806d5408eb717721ec12) that doesn't exist today

Contributor guide

No contributing guide indexed for this repository

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.