Fix tooltip placement bugs by upgrading Popper

This commit is contained in:
Evan Hahn 2021-08-03 12:04:49 -05:00 committed by GitHub
parent 26b7652492
commit 3b476fb60d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 85 additions and 136 deletions

View File

@ -5,6 +5,10 @@
Signal Desktop makes use of the following open source projects.
## @popperjs/core
License: MIT
## @sindresorhus/is
MIT License
@ -2478,10 +2482,6 @@ Signal Desktop makes use of the following open source projects.
License: MIT
## popper.js
License: MIT
## protobufjs
This license applies to all parts of protobuf.js except those files

View File

@ -69,6 +69,7 @@
"fs-xattr": "0.3.0"
},
"dependencies": {
"@popperjs/core": "2.9.2",
"@signalapp/signal-client": "0.8.1",
"@sindresorhus/is": "0.8.0",
"@types/pino": "6.3.6",
@ -123,7 +124,6 @@
"pify": "3.0.0",
"pino": "6.11.1",
"pino-multi-stream": "5.3.0",
"popper.js": "1.15.0",
"protobufjs": "6.10.2",
"proxy-agent": "4.0.1",
"quill": "1.3.7",
@ -135,7 +135,7 @@
"react-dropzone": "10.1.7",
"react-hot-loader": "4.12.11",
"react-measure": "2.3.0",
"react-popper": "1.3.7",
"react-popper": "2.2.5",
"react-quill": "2.0.0-beta.2",
"react-redux": "7.1.0",
"react-router-dom": "5.0.1",

View File

@ -1,4 +1,4 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -260,7 +260,12 @@ export const StickerFrame = React.memo(
previewActive &&
previewPopperRoot
? createPortal(
<Popper placement="bottom">
<Popper
placement="bottom"
modifiers={[
{ name: 'offset', options: { offset: [undefined, 8] } },
]}
>
{({ ref, style, arrowProps, placement }) => (
<StickerPreview
ref={ref}

View File

@ -1,4 +1,4 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
@import '../mixins';
@ -39,26 +39,6 @@
border-radius: 0 6px 6px 0;
}
.bottom {
composes: base;
margin-top: 8px;
}
.top {
composes: base;
margin-bottom: 8px;
}
.left {
composes: base;
margin-right: 8px;
}
.right {
composes: base;
margin-left: 8px;
}
.arrow {
position: absolute;
width: 0;

View File

@ -1,9 +1,9 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
import { PopperArrowProps } from 'react-popper';
import { Placement } from 'popper.js';
import { Placement } from '@popperjs/core';
import * as styles from './StickerPreview.scss';
import { MessageBubble } from './MessageBubble';
import { MessageSticker, Props as MessageStickerProps } from './MessageSticker';
@ -26,22 +26,6 @@ const renderMessages = (
</>
);
const getBaseClass = (placement?: Placement) => {
if (placement === 'top') {
return styles.top;
}
if (placement === 'right') {
return styles.right;
}
if (placement === 'left') {
return styles.left;
}
return styles.bottom;
};
const getArrowClass = (placement?: Placement) => {
if (placement === 'top') {
return styles.arrowBottom;
@ -64,7 +48,7 @@ export const StickerPreview = React.memo(
const i18n = useI18n();
return (
<div className={getBaseClass(placement)} ref={ref} style={style}>
<div className={styles.base} ref={ref} style={style}>
{arrowProps ? (
<div
ref={arrowProps.ref}

View File

@ -4989,7 +4989,6 @@ button.module-image__border-overlay:focus {
height: 56px;
border-radius: 30px;
position: relative;
margin: 4px 0;
z-index: 2;
animation: {
@ -9908,8 +9907,6 @@ $contact-modal-padding: 18px;
}
&[data-placement='top'] {
margin-bottom: 12px;
.module-tooltip-arrow {
bottom: 0;
}
@ -9921,8 +9918,6 @@ $contact-modal-padding: 18px;
}
&[data-placement='right'] {
margin-left: 12px;
.module-tooltip-arrow {
left: 0;
}
@ -9934,8 +9929,6 @@ $contact-modal-padding: 18px;
}
&[data-placement='bottom'] {
margin-top: 12px;
.module-tooltip-arrow {
top: 0;
}
@ -9947,8 +9940,6 @@ $contact-modal-padding: 18px;
}
&[data-placement='left'] {
margin-right: 12px;
.module-tooltip-arrow {
right: 0;
}

View File

@ -103,7 +103,7 @@ export const MediaQualitySelector = ({
</Reference>
{menuShowing && popperRoot
? createPortal(
<Popper placement="top-start" positionFixed>
<Popper placement="top-start" strategy="fixed">
{({ ref, style, placement }) => (
<div
className="MediaQualitySelector__popper"

View File

@ -7,6 +7,7 @@ import { noop } from 'lodash';
import { Manager, Reference, Popper } from 'react-popper';
import { Theme, themeClassName } from '../util/theme';
import { multiRef } from '../util/multiRef';
import { offsetDistanceModifier } from '../util/popperUtil';
type EventWrapperPropsType = {
children: React.ReactNode;
@ -96,7 +97,7 @@ export const Tooltip: React.FC<PropsType> = ({
</TooltipEventWrapper>
)}
</Reference>
<Popper placement={direction}>
<Popper placement={direction} modifiers={[offsetDistanceModifier(12)]}>
{({ arrowProps, placement, ref, style }) =>
showTooltip && (
<div

View File

@ -63,6 +63,7 @@ import { createRefMerger } from '../_util';
import { emojiToData } from '../emoji/lib';
import { SmartReactionPicker } from '../../state/smart/ReactionPicker';
import { getCustomColorStyle } from '../../util/getCustomColorStyle';
import { offsetDistanceModifier } from '../../util/popperUtil';
type Trigger = {
handleContextClick: (event: React.MouseEvent<HTMLDivElement>) => void;
@ -1429,7 +1430,7 @@ export class Message extends React.Component<Props, State> {
{reactionPickerRoot &&
createPortal(
// eslint-disable-next-line consistent-return
<Popper placement="top">
<Popper placement="top" modifiers={[offsetDistanceModifier(4)]}>
{({ ref, style }) => (
<SmartReactionPicker
ref={ref}

View File

@ -1,4 +1,4 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -129,7 +129,7 @@ export const EmojiButton = React.memo(
</Reference>
{open && popperRoot
? createPortal(
<Popper placement="top-start" positionFixed>
<Popper placement="top-start" strategy="fixed">
{({ ref, style }) => (
<EmojiPicker
ref={ref}

View File

@ -1,4 +1,4 @@
// Copyright 2019-2020 Signal Messenger, LLC
// Copyright 2019-2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import * as React from 'react';
@ -10,6 +10,7 @@ import { StickerPicker } from './StickerPicker';
import { countStickers } from './lib';
import { StickerPackType, StickerType } from '../../state/ducks/stickers';
import { LocalizerType } from '../../types/Util';
import { offsetDistanceModifier } from '../../util/popperUtil';
export type OwnProps = {
readonly i18n: LocalizerType;
@ -202,7 +203,11 @@ export const StickerButton = React.memo(
)}
</Reference>
{!open && !showIntroduction && installedPack ? (
<Popper placement={position} key={installedPack.id}>
<Popper
placement={position}
key={installedPack.id}
modifiers={[offsetDistanceModifier(6)]}
>
{({ ref, style, placement, arrowProps }) => (
<button
type="button"
@ -239,7 +244,7 @@ export const StickerButton = React.memo(
</Popper>
) : null}
{!open && showIntroduction ? (
<Popper placement={position}>
<Popper placement={position} modifiers={[offsetDistanceModifier(6)]}>
{({ ref, style, placement, arrowProps }) => (
<button
type="button"

View File

@ -19,6 +19,7 @@ import {
import { Emoji } from '../../components/emoji/Emoji';
import { EmojiPickDataType } from '../../components/emoji/EmojiPicker';
import { getBlotTextPartitions, matchBlotTextPartitions } from '../util';
import { sameWidthModifier } from '../../util/popperUtil';
const Keyboard = Quill.import('modules/keyboard');
@ -265,25 +266,7 @@ export class EmojiCompletion {
}
const element = createPortal(
<Popper
placement="top"
modifiers={{
width: {
enabled: true,
fn: oldData => {
const data = oldData;
const { width, left } = data.offsets.reference;
data.styles.width = `${width}px`;
data.offsets.popper.width = width;
data.offsets.popper.left = left;
return data;
},
order: 840,
},
}}
>
<Popper placement="top-start" modifiers={[sameWidthModifier]}>
{({ ref, style }) => (
<div
ref={ref}

View File

@ -14,6 +14,7 @@ import { Avatar } from '../../components/Avatar';
import { LocalizerType } from '../../types/Util';
import { MemberRepository } from '../memberRepository';
import { matchBlotTextPartitions } from '../util';
import { sameWidthModifier } from '../../util/popperUtil';
export type MentionCompletionOptions = {
i18n: LocalizerType;
@ -218,25 +219,7 @@ export class MentionCompletion {
}
const element = createPortal(
<Popper
placement="top"
modifiers={{
width: {
enabled: true,
fn: oldData => {
const data = oldData;
const { width, left } = data.offsets.reference;
data.styles.width = `${width}px`;
data.offsets.popper.width = width;
data.offsets.popper.left = left;
return data;
},
order: 840,
},
}}
>
<Popper placement="top-start" modifiers={[sameWidthModifier]}>
{({ ref, style }) => (
<div
ref={ref}

33
ts/util/popperUtil.ts Normal file
View File

@ -0,0 +1,33 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import type { Modifier } from '@popperjs/core';
import type { OffsetModifier } from '@popperjs/core/lib/modifiers/offset';
/**
* Shorthand for the [offset modifier][0] when you just wanna set the distance.
*
* [0]: https://popper.js.org/docs/v2/modifiers/offset/
*/
export const offsetDistanceModifier = (
distance: number
): Partial<OffsetModifier> => ({
name: 'offset',
options: { offset: [undefined, distance] },
});
/**
* Make the popper element the same width as the reference, even when you resize.
*
* Should probably be used with the "top-start", "top-end", "bottom-start", or
* "bottom-end" placement.
*/
export const sameWidthModifier: Modifier<'sameWidth', unknown> = {
name: 'sameWidth',
enabled: true,
phase: 'write',
fn({ state }) {
// eslint-disable-next-line no-param-reassign
state.elements.popper.style.width = `${state.rects.reference.width}px`;
},
};

View File

@ -1580,6 +1580,11 @@
"@nodelib/fs.scandir" "2.1.3"
fastq "^1.6.0"
"@popperjs/core@2.9.2":
version "2.9.2"
resolved "https://registry.yarnpkg.com/@popperjs/core/-/core-2.9.2.tgz#adea7b6953cbb34651766b0548468e743c6a2353"
integrity sha512-VZMYa7+fXHdwIq1TDhSXoVmSPEGM/aa+6Aiq3nVVJ9bXr24zScr+NlKFKC3iPljA7ho/GAZr+d2jOf5GIRC30Q==
"@protobufjs/aspromise@^1.1.1", "@protobufjs/aspromise@^1.1.2":
version "1.1.2"
resolved "https://registry.yarnpkg.com/@protobufjs/aspromise/-/aspromise-1.1.2.tgz#9b8b0cc663d669a7d8f6f5d0893a14d348f30fbf"
@ -6542,18 +6547,6 @@ deep-equal@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5"
deep-equal@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.1.1.tgz#b5c98c942ceffaf7cb051e24e1434a25a2e6076a"
integrity sha512-yd9c5AdiqVcR+JjcwUQb9DkhJc8ngNr0MahEBGvDiJw8puWab2yZlh+nkasOnZP+EGTAP6rRp2JzJhJZzvNF8g==
dependencies:
is-arguments "^1.0.4"
is-date-object "^1.0.1"
is-regex "^1.0.4"
object-is "^1.0.1"
object-keys "^1.1.1"
regexp.prototype.flags "^1.2.0"
deep-extend@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.6.0.tgz#c4fa7c95404a17a9c3e8ca7e1537312b736330ac"
@ -10398,11 +10391,6 @@ is-alphanumerical@^1.0.0:
is-alphabetical "^1.0.0"
is-decimal "^1.0.0"
is-arguments@^1.0.4:
version "1.0.4"
resolved "https://registry.yarnpkg.com/is-arguments/-/is-arguments-1.0.4.tgz#3faf966c7cba0ff437fb31f6250082fcf0448cf3"
integrity sha512-xPh0Rmt8NE65sNzvyUmWgI1tz3mKq74lGA0mL8LYZcoIzKOzDh6HmrYm3d18k60nHerC8A9Km8kYu87zfSFnLA==
is-arrayish@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d"
@ -12966,11 +12954,6 @@ object-inspect@^1.7.0, object-inspect@^1.8.0:
resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-1.8.0.tgz#df807e5ecf53a609cc6bfe93eac3cc7be5b3a9d0"
integrity sha512-jLdtEOB112fORuypAyl/50VRVIBIdVQOSUUGQHzJ4xBSbit81zRarz7GThkEFZy1RceYrWYcPcBFPQwHyAc1gA==
object-is@^1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/object-is/-/object-is-1.0.2.tgz#6b80eb84fe451498f65007982f035a5b445edec4"
integrity sha512-Epah+btZd5wrrfjkJZq1AOB9O6OxUQto45hzFd7lXGrpHPGE0W1k+426yrZV+k6NJOzLNNW/nVsmZdIWsAqoOQ==
object-keys@^1.0.11, object-keys@^1.0.12, object-keys@^1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.1.1.tgz#1c47f272df277f3b1daf061677d9c82e2322c60e"
@ -13914,7 +13897,7 @@ polished@^3.3.1:
dependencies:
"@babel/runtime" "^7.4.5"
popper.js@1.15.0, popper.js@^1.14.4, popper.js@^1.14.7:
popper.js@^1.14.4, popper.js@^1.14.7:
version "1.15.0"
resolved "https://registry.yarnpkg.com/popper.js/-/popper.js-1.15.0.tgz#5560b99bbad7647e9faa475c6b8056621f5a4ff2"
integrity sha512-w010cY1oCUmI+9KwwlWki+r5jxKfTFDVoadl7MSrIujHU5MJ5OR6HTDj6Xo8aoR/QsA56x8jKjA59qGH4ELtrA==
@ -14749,6 +14732,11 @@ react-fast-compare@2.0.4:
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-2.0.4.tgz#e84b4d455b0fec113e0402c329352715196f81f9"
integrity sha512-suNP+J1VU1MWFKcyt7RtjiSWUjvidmQSlqu+eHslq+342xCbGTYmC0mEhPCOHxlW0CywylOC1u2DFAT+bv4dBw==
react-fast-compare@^3.0.1:
version "3.2.0"
resolved "https://registry.yarnpkg.com/react-fast-compare/-/react-fast-compare-3.2.0.tgz#641a9da81b6a6320f270e89724fb45a0b39e43bb"
integrity sha512-rtGImPZ0YyLrscKI9xTpV8psd6I8VAtjKCzQDlzyDvqJA8XOW78TXYQwNRNd8g8JZnDu8q9Fu/1v4HPAVwVdHA==
react-focus-lock@^1.18.3:
version "1.19.1"
resolved "https://registry.yarnpkg.com/react-focus-lock/-/react-focus-lock-1.19.1.tgz#2f3429793edaefe2d077121f973ce5a3c7a0651a"
@ -14845,17 +14833,12 @@ react-popper-tooltip@^2.8.3:
"@babel/runtime" "^7.4.5"
react-popper "^1.3.3"
react-popper@1.3.7:
version "1.3.7"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-1.3.7.tgz#f6a3471362ef1f0d10a4963673789de1baca2324"
integrity sha512-nmqYTx7QVjCm3WUZLeuOomna138R1luC4EqkW3hxJUrAe+3eNz3oFCLYdnPwILfn0mX1Ew2c3wctrjlUMYYUww==
react-popper@2.2.5:
version "2.2.5"
resolved "https://registry.yarnpkg.com/react-popper/-/react-popper-2.2.5.tgz#1214ef3cec86330a171671a4fbcbeeb65ee58e96"
integrity sha512-kxGkS80eQGtLl18+uig1UIf9MKixFSyPxglsgLBxlYnyDf65BiY9B3nZSc6C9XUNDgStROB0fMQlTEz1KxGddw==
dependencies:
"@babel/runtime" "^7.1.2"
create-react-context "^0.3.0"
deep-equal "^1.1.1"
popper.js "^1.14.4"
prop-types "^15.6.1"
typed-styles "^0.0.7"
react-fast-compare "^3.0.1"
warning "^4.0.2"
react-popper@^1.3.3: