diff --git a/docs/data/joy/components/menu/ControlledDropdown.js b/docs/data/joy/components/menu/ControlledDropdown.js
new file mode 100644
index 00000000000000..0f2cf11d370cbf
--- /dev/null
+++ b/docs/data/joy/components/menu/ControlledDropdown.js
@@ -0,0 +1,24 @@
+import * as React from 'react';
+import Dropdown from '@mui/joy/Dropdown';
+import Menu from '@mui/joy/Menu';
+import MenuButton from '@mui/joy/MenuButton';
+import MenuItem from '@mui/joy/MenuItem';
+
+export default function ControlledDropdown() {
+ const [open, setOpen] = React.useState(false);
+
+ const handleOpenChange = React.useCallback((event, isOpen) => {
+ setOpen(isOpen);
+ }, []);
+
+ return (
+
+ Dashboard...
+
+
+ );
+}
diff --git a/docs/data/joy/components/menu/ControlledDropdown.tsx b/docs/data/joy/components/menu/ControlledDropdown.tsx
new file mode 100644
index 00000000000000..bbf8834de87f0e
--- /dev/null
+++ b/docs/data/joy/components/menu/ControlledDropdown.tsx
@@ -0,0 +1,27 @@
+import * as React from 'react';
+import Dropdown from '@mui/joy/Dropdown';
+import Menu from '@mui/joy/Menu';
+import MenuButton from '@mui/joy/MenuButton';
+import MenuItem from '@mui/joy/MenuItem';
+
+export default function ControlledDropdown() {
+ const [open, setOpen] = React.useState(false);
+
+ const handleOpenChange = React.useCallback(
+ (event: React.SyntheticEvent | null, isOpen: boolean) => {
+ setOpen(isOpen);
+ },
+ [],
+ );
+
+ return (
+
+ Dashboard...
+
+
+ );
+}
diff --git a/docs/data/joy/components/menu/ControlledDropdown.tsx.preview b/docs/data/joy/components/menu/ControlledDropdown.tsx.preview
new file mode 100644
index 00000000000000..033eadd194e94f
--- /dev/null
+++ b/docs/data/joy/components/menu/ControlledDropdown.tsx.preview
@@ -0,0 +1,8 @@
+
+ Dashboard...
+
+
\ No newline at end of file
diff --git a/docs/data/joy/components/menu/menu.md b/docs/data/joy/components/menu/menu.md
index 076120e12ececf..523e352adf56e5 100644
--- a/docs/data/joy/components/menu/menu.md
+++ b/docs/data/joy/components/menu/menu.md
@@ -98,6 +98,13 @@ For example, this is how you'd go for displaying the menu on the bottom-end of t
{{"demo": "GroupMenu.js"}}
+### Controlling the open state
+
+By default, the open/close state of the menu is managed internally by the Dropdown component.
+To control it programmatically from the outside, apply the Dropdown's `open` and `onOpenChange` props as shown below:
+
+{{"demo": "ControlledDropdown.js"}}
+
### `MenuList` composition
To get full control of the DOM structure, use the `MenuList` component.