diff --git a/client/components/Nav/NavDropdownMenu.jsx b/client/components/Nav/NavDropdownMenu.jsx
index 7fb8eda34f..ee3e5082aa 100644
--- a/client/components/Nav/NavDropdownMenu.jsx
+++ b/client/components/Nav/NavDropdownMenu.jsx
@@ -1,6 +1,7 @@
import classNames from 'classnames';
import PropTypes from 'prop-types';
import React, { useContext, useMemo } from 'react';
+import { useFloating, autoUpdate, shift } from '@floating-ui/react';
import TriangleIcon from '../../images/down-filled-triangle.svg';
import { MenuOpenContext, NavBarContext, ParentMenuContext } from './contexts';
@@ -19,11 +20,31 @@ export function useMenuProps(id) {
return { isOpen, handlers };
}
+const isSafari = () =>
+ /^((?!chrome|android).)*safari/i.test(navigator.userAgent);
+
function NavDropdownMenu({ id, title, children }) {
const { isOpen, handlers } = useMenuProps(id);
+ const middleware = isSafari()
+ ? [
+ shift({
+ mainAxis: false
+ })
+ ]
+ : [shift()];
+
+ const { refs, floatingStyles } = useFloating({
+ whileElementsMounted: autoUpdate,
+ placement: 'bottom-start',
+ middleware
+ });
+
return (
-
+
-
+
{children}
diff --git a/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap b/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap
index 85387dd9ae..7044c59c0f 100644
--- a/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap
+++ b/client/modules/IDE/components/Header/__snapshots__/Nav.unit.test.jsx.snap
@@ -501,6 +501,7 @@ exports[`Nav renders editor version for desktop 1`] = `
-
-
-
- =16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/react-dom": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz",
+ "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==",
+ "dependencies": {
+ "@floating-ui/dom": "^1.0.0"
+ },
+ "peerDependencies": {
+ "react": ">=16.8.0",
+ "react-dom": ">=16.8.0"
+ }
+ },
+ "node_modules/@floating-ui/utils": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
+ "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
+ },
"node_modules/@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -42978,6 +43027,11 @@
"integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==",
"dev": true
},
+ "node_modules/tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
"node_modules/table": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
@@ -48419,6 +48473,46 @@
"integrity": "sha512-cEee/Z+I12mZcFJshKcCqC8tuX5hG3s+d+9nZ3LabqKF1vKdF41B92pJVCBggjAGORAeOzyyDDKrZwIkLffeOQ==",
"dev": true
},
+ "@floating-ui/core": {
+ "version": "1.6.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/core/-/core-1.6.2.tgz",
+ "integrity": "sha512-+2XpQV9LLZeanU4ZevzRnGFg2neDeKHgFLjP6YLW+tly0IvrhqT4u8enLGjLH3qeh85g19xY5rsAusfwTdn5lg==",
+ "requires": {
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "@floating-ui/dom": {
+ "version": "1.6.5",
+ "resolved": "https://registry.npmjs.org/@floating-ui/dom/-/dom-1.6.5.tgz",
+ "integrity": "sha512-Nsdud2X65Dz+1RHjAIP0t8z5e2ff/IRbei6BqFrl1urT8sDVzM1HMQ+R0XcU5ceRfyO3I6ayeqIfh+6Wb8LGTw==",
+ "requires": {
+ "@floating-ui/core": "^1.0.0",
+ "@floating-ui/utils": "^0.2.0"
+ }
+ },
+ "@floating-ui/react": {
+ "version": "0.26.17",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react/-/react-0.26.17.tgz",
+ "integrity": "sha512-ESD+jYWwqwVzaIgIhExrArdsCL1rOAzryG/Sjlu8yaD3Mtqi3uVyhbE2V7jD58Mo52qbzKz2eUY/Xgh5I86FCQ==",
+ "requires": {
+ "@floating-ui/react-dom": "^2.1.0",
+ "@floating-ui/utils": "^0.2.0",
+ "tabbable": "^6.0.0"
+ }
+ },
+ "@floating-ui/react-dom": {
+ "version": "2.1.0",
+ "resolved": "https://registry.npmjs.org/@floating-ui/react-dom/-/react-dom-2.1.0.tgz",
+ "integrity": "sha512-lNzj5EQmEKn5FFKc04+zasr09h/uX8RtJRNj5gUXsSQIXHVWTVh+hVAg1vOMCexkX8EgvemMvIFpQfkosnVNyA==",
+ "requires": {
+ "@floating-ui/dom": "^1.0.0"
+ }
+ },
+ "@floating-ui/utils": {
+ "version": "0.2.2",
+ "resolved": "https://registry.npmjs.org/@floating-ui/utils/-/utils-0.2.2.tgz",
+ "integrity": "sha512-J4yDIIthosAsRZ5CPYP/jQvUAQtlZTTD/4suA08/FEnlxqW3sKS9iAhgsa9VYLZ6vDHn/ixJgIqRQPotoBjxIw=="
+ },
"@gar/promisify": {
"version": "1.1.3",
"resolved": "https://registry.npmjs.org/@gar/promisify/-/promisify-1.1.3.tgz",
@@ -77583,6 +77677,11 @@
"integrity": "sha512-AsS729u2RHUfEra9xJrE39peJcc2stq2+poBXX8bcM08Y6g9j/i/PUzwNQqkaJde7Ntg1TO7bSREbR5sdosQ+g==",
"dev": true
},
+ "tabbable": {
+ "version": "6.2.0",
+ "resolved": "https://registry.npmjs.org/tabbable/-/tabbable-6.2.0.tgz",
+ "integrity": "sha512-Cat63mxsVJlzYvN51JmVXIgNoUokrIaT2zLclCXjRd8boZ0004U4KCs/sToJ75C6sdlByWxpYnb5Boif1VSFew=="
+ },
"table": {
"version": "6.7.1",
"resolved": "https://registry.npmjs.org/table/-/table-6.7.1.tgz",
diff --git a/package.json b/package.json
index cea49d57c4..6255e451c8 100644
--- a/package.json
+++ b/package.json
@@ -158,6 +158,7 @@
"@babel/core": "^7.14.6",
"@babel/register": "^7.14.5",
"@emmetio/codemirror-plugin": "^1.2.4",
+ "@floating-ui/react": "^0.26.17",
"@gatsbyjs/webpack-hot-middleware": "^2.25.3",
"@pmmmwh/react-refresh-webpack-plugin": "^0.5.11",
"@redux-devtools/core": "^3.11.0",