Fix click propagating from reaction viewer to container

This commit is contained in:
Josh Perez 2021-10-04 16:56:34 -04:00 committed by GitHub
parent 54e7cd21fc
commit 9a9fc60103
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
2 changed files with 62 additions and 42 deletions

View file

@ -0,0 +1,15 @@
// Copyright 2021 Signal Messenger, LLC
// SPDX-License-Identifier: AGPL-3.0-only
import React, { ReactNode } from 'react';
// Whenever you don't want click events to propagate into their parent container
export const StopPropagation = ({
children,
}: {
children: ReactNode;
}): JSX.Element => (
// eslint-disable-next-line max-len
// eslint-disable-next-line jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events
<div onClick={ev => ev.stopPropagation()}>{children}</div>
);

View file

@ -68,6 +68,7 @@ import type { SmartReactionPicker } from '../../state/smart/ReactionPicker';
import { getCustomColorStyle } from '../../util/getCustomColorStyle'; import { getCustomColorStyle } from '../../util/getCustomColorStyle';
import { offsetDistanceModifier } from '../../util/popperUtil'; import { offsetDistanceModifier } from '../../util/popperUtil';
import * as KeyboardLayout from '../../services/keyboardLayout'; import * as KeyboardLayout from '../../services/keyboardLayout';
import { StopPropagation } from '../StopPropagation';
type Trigger = { type Trigger = {
handleContextClick: (event: React.MouseEvent<HTMLDivElement>) => void; handleContextClick: (event: React.MouseEvent<HTMLDivElement>) => void;
@ -1448,30 +1449,32 @@ export class Message extends React.PureComponent<Props, State> {
</div> </div>
{reactionPickerRoot && {reactionPickerRoot &&
createPortal( createPortal(
<Popper <StopPropagation>
placement="top" <Popper
modifiers={[ placement="top"
offsetDistanceModifier(4), modifiers={[
this.popperPreventOverflowModifier(), offsetDistanceModifier(4),
]} this.popperPreventOverflowModifier(),
> ]}
{({ ref, style }) => >
renderReactionPicker({ {({ ref, style }) =>
ref, renderReactionPicker({
style, ref,
selected: selectedReaction, style,
onClose: this.toggleReactionPicker, selected: selectedReaction,
onPick: emoji => { onClose: this.toggleReactionPicker,
this.toggleReactionPicker(true); onPick: emoji => {
reactToMessage(id, { this.toggleReactionPicker(true);
emoji, reactToMessage(id, {
remove: emoji === selectedReaction, emoji,
}); remove: emoji === selectedReaction,
}, });
renderEmojiPicker, },
}) renderEmojiPicker,
} })
</Popper>, }
</Popper>
</StopPropagation>,
reactionPickerRoot reactionPickerRoot
)} )}
</Manager> </Manager>
@ -2050,24 +2053,26 @@ export class Message extends React.PureComponent<Props, State> {
</Reference> </Reference>
{reactionViewerRoot && {reactionViewerRoot &&
createPortal( createPortal(
<Popper <StopPropagation>
placement={popperPlacement} <Popper
strategy="fixed" placement={popperPlacement}
modifiers={[this.popperPreventOverflowModifier()]} strategy="fixed"
> modifiers={[this.popperPreventOverflowModifier()]}
{({ ref, style }) => ( >
<ReactionViewer {({ ref, style }) => (
ref={ref} <ReactionViewer
style={{ ref={ref}
...style, style={{
zIndex: 2, ...style,
}} zIndex: 2,
reactions={reactions} }}
i18n={i18n} reactions={reactions}
onClose={this.toggleReactionViewer} i18n={i18n}
/> onClose={this.toggleReactionViewer}
)} />
</Popper>, )}
</Popper>
</StopPropagation>,
reactionViewerRoot reactionViewerRoot
)} )}
</Manager> </Manager>