diff --git a/ts/components/CallingLobby.tsx b/ts/components/CallingLobby.tsx index bd138f9954..f5d47b30f8 100644 --- a/ts/components/CallingLobby.tsx +++ b/ts/components/CallingLobby.tsx @@ -2,7 +2,6 @@ // SPDX-License-Identifier: AGPL-3.0-only import React from 'react'; -import FocusTrap from 'focus-trap-react'; import classNames from 'classnames'; import { SetLocalAudioType, @@ -204,85 +203,83 @@ export const CallingLobby = ({ } return ( - -
- {shouldShowLocalVideo ? ( -
); }; diff --git a/ts/components/Tooltip.tsx b/ts/components/Tooltip.tsx index a2536b85a6..4ccba759eb 100644 --- a/ts/components/Tooltip.tsx +++ b/ts/components/Tooltip.tsx @@ -3,12 +3,62 @@ import React from 'react'; import classNames from 'classnames'; +import { noop } from 'lodash'; import { Manager, Reference, Popper } from 'react-popper'; import type { StrictModifiers } from '@popperjs/core'; import { Theme, themeClassName } from '../util/theme'; +import { refMerger } from '../util/refMerger'; import { offsetDistanceModifier } from '../util/popperUtil'; -import { SmartTooltipEventWrapper } from '../state/smart/TooltipEventWrapper'; +type EventWrapperPropsType = { + children: React.ReactNode; + onHoverChanged: (_: boolean) => void; +}; + +// React doesn't reliably fire `onMouseLeave` or `onMouseOut` events if wrapping a +// disabled button. This uses native browser events to avoid that. +// +// See . +const TooltipEventWrapper = React.forwardRef< + HTMLSpanElement, + EventWrapperPropsType +>(({ onHoverChanged, children }, ref) => { + const wrapperRef = React.useRef(null); + + const on = React.useCallback(() => { + onHoverChanged(true); + }, [onHoverChanged]); + + const off = React.useCallback(() => { + onHoverChanged(false); + }, [onHoverChanged]); + + React.useEffect(() => { + const wrapperEl = wrapperRef.current; + + if (!wrapperEl) { + return noop; + } + + wrapperEl.addEventListener('mouseenter', on); + wrapperEl.addEventListener('mouseleave', off); + + return () => { + wrapperEl.removeEventListener('mouseenter', on); + wrapperEl.removeEventListener('mouseleave', off); + }; + }, [on, off]); + + return ( + (ref, wrapperRef)} + > + {children} + + ); +}); export enum TooltipPlacement { Top = 'top', @@ -47,12 +97,9 @@ export const Tooltip: React.FC = ({ {({ ref }) => ( - + {children} - + )} ; - onHoverChanged: (_: boolean) => void; -}; - -// React doesn't reliably fire `onMouseLeave` or `onMouseOut` events if wrapping a -// disabled button. This uses native browser events to avoid that. -// -// See . -export const TooltipEventWrapper: React.FC = ({ - onHoverChanged, - children, - interactionMode, - innerRef, -}) => { - const wrapperRef = useRef(null); - - const on = useCallback(() => { - onHoverChanged(true); - }, [onHoverChanged]); - - const off = useCallback(() => { - onHoverChanged(false); - }, [onHoverChanged]); - - const onFocus = useCallback(() => { - if (interactionMode === 'keyboard') { - on(); - } - }, [on, interactionMode]); - - useEffect(() => { - const wrapperEl = wrapperRef.current; - - if (!wrapperEl) { - return noop; - } - - wrapperEl.addEventListener('mouseenter', on); - wrapperEl.addEventListener('mouseleave', off); - - return () => { - wrapperEl.removeEventListener('mouseenter', on); - wrapperEl.removeEventListener('mouseleave', off); - }; - }, [on, off]); - - return ( - (innerRef, wrapperRef)} - > - {children} - - ); -}; diff --git a/ts/state/smart/TooltipEventWrapper.tsx b/ts/state/smart/TooltipEventWrapper.tsx deleted file mode 100644 index 393e5bcae6..0000000000 --- a/ts/state/smart/TooltipEventWrapper.tsx +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2021 Signal Messenger, LLC -// SPDX-License-Identifier: AGPL-3.0-only - -import React, { Ref } from 'react'; -import { connect } from 'react-redux'; - -import { mapDispatchToProps } from '../actions'; -import { StateType } from '../reducer'; - -import { TooltipEventWrapper } from '../../components/TooltipEventWrapper'; -import { getInteractionMode } from '../selectors/user'; - -type ExternalProps = { - // Matches Popper's RefHandler type - innerRef: Ref; - children: React.ReactNode; - onHoverChanged: (_: boolean) => void; -}; - -const mapStateToProps = (state: StateType, props: ExternalProps) => { - return { - ...props, - interactionMode: getInteractionMode(state), - }; -}; - -const smart = connect(mapStateToProps, mapDispatchToProps); - -export const SmartTooltipEventWrapper = smart(TooltipEventWrapper); diff --git a/ts/util/lint/exceptions.json b/ts/util/lint/exceptions.json index 7ed3778bd9..8debd74577 100644 --- a/ts/util/lint/exceptions.json +++ b/ts/util/lint/exceptions.json @@ -12763,12 +12763,19 @@ }, { "rule": "React-useRef", - "path": "ts/components/TooltipEventWrapper.tsx", - "line": " const wrapperRef = useRef(null);", + "path": "ts/components/Tooltip.js", + "line": " const wrapperRef = react_1.default.useRef(null);", "reasonCategory": "usageTrusted", - "updated": "2021-10-21T16:10:14.143Z", + "updated": "2020-12-04T00:11:08.128Z", "reasonDetail": "Used to add (and remove) event listeners." }, + { + "rule": "React-useRef", + "path": "ts/components/Tooltip.tsx", + "line": " const wrapperRef = React.useRef(null);", + "reasonCategory": "usageTrusted", + "updated": "2021-07-30T16:57:33.618Z" + }, { "rule": "React-createRef", "path": "ts/components/conversation/ConversationHeader.js",