diff --git a/package-lock.json b/package-lock.json index 4e4e73a731..40098db070 100644 --- a/package-lock.json +++ b/package-lock.json @@ -71,7 +71,7 @@ "react": "17.0.2", "react-dom": "17.0.2", "react-emoji-render": "1.2.4", - "react-focus-lock": "2.5.1", + "react-focus-lock": "2.9.4", "react-i18next": "10.11.4", "react-linkify": "1.0.0-alpha", "react-native": "0.68.6", @@ -10508,9 +10508,9 @@ } }, "node_modules/focus-lock": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.9.2.tgz", - "integrity": "sha512-YtHxjX7a0IC0ZACL5wsX8QdncXofWpGPNoVMuI/nZUrPGp6LmNI6+D5j0pPj+v8Kw5EpweA+T5yImK0rnWf7oQ==", + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.6.tgz", + "integrity": "sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg==", "dependencies": { "tslib": "^2.0.3" }, @@ -15415,14 +15415,14 @@ } }, "node_modules/react-clientside-effect": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz", - "integrity": "sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", "dependencies": { "@babel/runtime": "^7.12.13" }, "peerDependencies": { - "react": "^15.3.0 || ^16.0.0 || ^17.0.0" + "react": "^15.3.0 || ^16.0.0 || ^17.0.0 || ^18.0.0" } }, "node_modules/react-devtools-core": { @@ -15484,19 +15484,25 @@ } }, "node_modules/react-focus-lock": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.1.tgz", - "integrity": "sha512-gOToRZKVEymGEjFaTRUKgJsdYQrNosoiK7yZnXnnd8bYew4vMzk3Rxb0Q4nyrGwsFuUmgQiSAulQirA0J+v4hA==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.4.tgz", + "integrity": "sha512-7pEdXyMseqm3kVjhdVH18sovparAzLg5h6WvIx7/Ck3ekjhrrDMEegHSa3swwC8wgfdd7DIdUVRGeiHT9/7Sgg==", "dependencies": { "@babel/runtime": "^7.0.0", - "focus-lock": "^0.9.1", + "focus-lock": "^0.11.6", "prop-types": "^15.6.2", - "react-clientside-effect": "^1.2.2", - "use-callback-ref": "^1.2.1", - "use-sidecar": "^1.0.1" + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, "node_modules/react-freeze": { @@ -18563,15 +18569,18 @@ } }, "node_modules/use-callback-ref": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", - "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==", + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "dependencies": { + "tslib": "^2.0.0" + }, "engines": { - "node": ">=8.5.0" + "node": ">=10" }, "peerDependencies": { - "@types/react": "^16.8.0 || ^17.0.0", - "react": "^16.8.0 || ^17.0.0" + "@types/react": "^16.8.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" }, "peerDependenciesMeta": { "@types/react": { @@ -18630,25 +18639,26 @@ "integrity": "sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ==" }, "node_modules/use-sidecar": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz", - "integrity": "sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "dependencies": { "detect-node-es": "^1.1.0", - "tslib": "^1.9.3" + "tslib": "^2.0.0" }, "engines": { - "node": ">=8.5.0" + "node": ">=10" }, "peerDependencies": { - "react": "^16.8.0 || ^17.0.0" + "@types/react": "^16.9.0 || ^17.0.0 || ^18.0.0", + "react": "^16.8.0 || ^17.0.0 || ^18.0.0" + }, + "peerDependenciesMeta": { + "@types/react": { + "optional": true + } } }, - "node_modules/use-sidecar/node_modules/tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - }, "node_modules/use-subscription": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/use-subscription/-/use-subscription-1.5.1.tgz", @@ -27441,9 +27451,9 @@ "integrity": "sha512-1gIBiWJNR0tKUNv8gZuk7l9rVX06OuLzY9AoGio7y/JT4V1IZErEMEq2TJS+PFcw/y0RshZ1J/27VfK1UQzYVg==" }, "focus-lock": { - "version": "0.9.2", - "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.9.2.tgz", - "integrity": "sha512-YtHxjX7a0IC0ZACL5wsX8QdncXofWpGPNoVMuI/nZUrPGp6LmNI6+D5j0pPj+v8Kw5EpweA+T5yImK0rnWf7oQ==", + "version": "0.11.6", + "resolved": "https://registry.npmjs.org/focus-lock/-/focus-lock-0.11.6.tgz", + "integrity": "sha512-KSuV3ur4gf2KqMNoZx3nXNVhqCkn42GuTYCX4tXPEwf0MjpFQmNMiN6m7dXaUXgIoivL6/65agoUMg4RLS0Vbg==", "requires": { "tslib": "^2.0.3" } @@ -31161,9 +31171,9 @@ } }, "react-clientside-effect": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.5.tgz", - "integrity": "sha512-2bL8qFW1TGBHozGGbVeyvnggRpMjibeZM2536AKNENLECutp2yfs44IL8Hmpn8qjFQ2K7A9PnYf3vc7aQq/cPA==", + "version": "1.2.6", + "resolved": "https://registry.npmjs.org/react-clientside-effect/-/react-clientside-effect-1.2.6.tgz", + "integrity": "sha512-XGGGRQAKY+q25Lz9a/4EPqom7WRjz3z9R2k4jhVKA/puQFH/5Nt27vFZYql4m4NVNdUvX8PS3O7r/Zzm7cjUlg==", "requires": { "@babel/runtime": "^7.12.13" } @@ -31207,16 +31217,16 @@ } }, "react-focus-lock": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.5.1.tgz", - "integrity": "sha512-gOToRZKVEymGEjFaTRUKgJsdYQrNosoiK7yZnXnnd8bYew4vMzk3Rxb0Q4nyrGwsFuUmgQiSAulQirA0J+v4hA==", + "version": "2.9.4", + "resolved": "https://registry.npmjs.org/react-focus-lock/-/react-focus-lock-2.9.4.tgz", + "integrity": "sha512-7pEdXyMseqm3kVjhdVH18sovparAzLg5h6WvIx7/Ck3ekjhrrDMEegHSa3swwC8wgfdd7DIdUVRGeiHT9/7Sgg==", "requires": { "@babel/runtime": "^7.0.0", - "focus-lock": "^0.9.1", + "focus-lock": "^0.11.6", "prop-types": "^15.6.2", - "react-clientside-effect": "^1.2.2", - "use-callback-ref": "^1.2.1", - "use-sidecar": "^1.0.1" + "react-clientside-effect": "^1.2.6", + "use-callback-ref": "^1.3.0", + "use-sidecar": "^1.1.2" } }, "react-freeze": { @@ -33521,9 +33531,12 @@ "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==" }, "use-callback-ref": { - "version": "1.2.5", - "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.2.5.tgz", - "integrity": "sha512-gN3vgMISAgacF7sqsLPByqoePooY3n2emTH59Ur5d/M8eg4WTWu1xp8i8DHjohftIyEx0S08RiYxbffr4j8Peg==" + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/use-callback-ref/-/use-callback-ref-1.3.0.tgz", + "integrity": "sha512-3FT9PRuRdbB9HfXhEq35u4oZkvpJ5kuYbpqhCfmiZyReuRgpnhDlbr2ZEnnuS0RrJAPn6l23xjFg9kpDM+Ms7w==", + "requires": { + "tslib": "^2.0.0" + } }, "use-composed-ref": { "version": "1.2.1", @@ -33554,19 +33567,12 @@ "integrity": "sha512-HtHatS2U4/h32NlkhupDsPlrbiD27gSH5swBdtXbCAlc6pfOFzaj0FehW/FO12rx8j2Vy4/lJScCiJyM01E+bQ==" }, "use-sidecar": { - "version": "1.0.5", - "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.0.5.tgz", - "integrity": "sha512-k9jnrjYNwN6xYLj1iaGhonDghfvmeTmYjAiGvOr7clwKfPjMXJf4/HOr7oT5tJwYafgp2tG2l3eZEOfoELiMcA==", + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/use-sidecar/-/use-sidecar-1.1.2.tgz", + "integrity": "sha512-epTbsLuzZ7lPClpz2TyryBfztm7m+28DlEv2ZCQ3MDr5ssiwyOwGH/e5F9CkfWjJ1t4clvI58yF822/GUkjjhw==", "requires": { "detect-node-es": "^1.1.0", - "tslib": "^1.9.3" - }, - "dependencies": { - "tslib": { - "version": "1.14.1", - "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", - "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==" - } + "tslib": "^2.0.0" } }, "use-subscription": { diff --git a/package.json b/package.json index 03f87a679e..7d4c0a7aeb 100644 --- a/package.json +++ b/package.json @@ -76,7 +76,7 @@ "react": "17.0.2", "react-dom": "17.0.2", "react-emoji-render": "1.2.4", - "react-focus-lock": "2.5.1", + "react-focus-lock": "2.9.4", "react-i18next": "10.11.4", "react-linkify": "1.0.0-alpha", "react-native": "0.68.6", diff --git a/react/features/base/popover/components/Popover.web.tsx b/react/features/base/popover/components/Popover.web.tsx index 4b42cf8a47..691972e2dd 100644 --- a/react/features/base/popover/components/Popover.web.tsx +++ b/react/features/base/popover/components/Popover.web.tsx @@ -6,6 +6,7 @@ import { IReduxState } from '../../../app/types'; import DialogPortal from '../../../toolbox/components/web/DialogPortal'; import Drawer from '../../../toolbox/components/web/Drawer'; import JitsiPortal from '../../../toolbox/components/web/JitsiPortal'; +import { isElementInTheViewport } from '../../ui/functions.web'; import { getContextMenuStyle } from '../functions.web'; /** @@ -258,7 +259,16 @@ class Popover extends Component { 'aria-labelledby': headingId, 'aria-label': !headingId && headingLabel ? headingLabel : undefined }} - returnFocus = { true }> + returnFocus = { + + // If we return the focus to an element outside the viewport the page will scroll to + // this element which in our case is undesirable and the element is outside of the + // viewport on purpose (to be hidden). For example if we return the focus to the toolbox + // when it is hidden the whole page will move up in order to show the toolbox. This is + // usually followed up with displaying the toolbox (because now it is on focus) but + // because of the animation the whole scenario looks like jumping large video. + isElementInTheViewport + }> {this._renderContent()} diff --git a/react/features/base/ui/components/web/BaseDialog.tsx b/react/features/base/ui/components/web/BaseDialog.tsx index 80b4735db2..55a4ff8cd6 100644 --- a/react/features/base/ui/components/web/BaseDialog.tsx +++ b/react/features/base/ui/components/web/BaseDialog.tsx @@ -5,6 +5,7 @@ import { keyframes } from 'tss-react'; import { makeStyles } from 'tss-react/mui'; import { withPixelLineHeight } from '../../../styles/functions.web'; +import { isElementInTheViewport } from '../../functions.web'; import { DialogTransitionContext } from './DialogTransition'; @@ -184,7 +185,16 @@ const BaseDialog = ({ onClick = { onBackdropClick } /> + returnFocus = { + + // If we return the focus to an element outside the viewport the page will scroll to + // this element which in our case is undesirable and the element is outside of the + // viewport on purpose (to be hidden). For example if we return the focus to the toolbox + // when it is hidden the whole page will move up in order to show the toolbox. This is + // usually followed up with displaying the toolbox (because now it is on focus) but + // because of the animation the whole scenario looks like jumping large video. + isElementInTheViewport + }>
= 0 && left >= 0 && right <= innerWidth) { + return true; + } + + return false; +} diff --git a/react/features/toolbox/components/web/Drawer.tsx b/react/features/toolbox/components/web/Drawer.tsx index bf20da4813..bb53208b37 100644 --- a/react/features/toolbox/components/web/Drawer.tsx +++ b/react/features/toolbox/components/web/Drawer.tsx @@ -2,6 +2,7 @@ import React, { KeyboardEvent, ReactNode, useCallback } from 'react'; import ReactFocusLock from 'react-focus-lock'; import { makeStyles } from 'tss-react/mui'; +import { isElementInTheViewport } from '../../../base/ui/functions.web'; import { DRAWER_MAX_HEIGHT } from '../../constants'; @@ -107,7 +108,16 @@ function Drawer({ 'aria-modal': true, 'aria-labelledby': `#${headingId}` }} - returnFocus = { true }> + returnFocus = { + + // If we return the focus to an element outside the viewport the page will scroll to + // this element which in our case is undesirable and the element is outside of the + // viewport on purpose (to be hidden). For example if we return the focus to the toolbox + // when it is hidden the whole page will move up in order to show the toolbox. This is + // usually followed up with displaying the toolbox (because now it is on focus) but + // because of the animation the whole scenario looks like jumping large video. + isElementInTheViewport + }> {children}