davidtheclark / davidtheclark/react-aria-menubutton
Keeping Menu open by default
- 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.