Skip to content
This repository has been archived by the owner on Mar 4, 2020. It is now read-only.

feat(Chat): Allow to disable actions menu positioning #2126

Merged
merged 3 commits into from
Nov 26, 2019
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
52 changes: 31 additions & 21 deletions packages/react/src/components/Chat/ChatMessage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,9 @@ export interface ChatMessageProps
*/
onMouseEnter?: ComponentEventHandler<ChatMessageProps>

/** Allows suppression of action menu positioning for performance reasons */
positionActionMenu?: boolean

/** Reaction group applied to the message. */
reactionGroup?: ShorthandValue<ReactionGroupProps> | ShorthandCollection<ReactionProps>

Expand Down Expand Up @@ -140,6 +143,7 @@ class ChatMessage extends UIComponent<WithAsProp<ChatMessageProps>, ChatMessageS
onBlur: PropTypes.func,
onFocus: PropTypes.func,
onMouseEnter: PropTypes.func,
positionActionMenu: PropTypes.bool,
reactionGroup: PropTypes.oneOfType([
customPropTypes.collectionShorthand,
customPropTypes.itemShorthand,
Expand All @@ -152,6 +156,7 @@ class ChatMessage extends UIComponent<WithAsProp<ChatMessageProps>, ChatMessageS
accessibility: chatMessageBehavior,
as: 'div',
badgePosition: 'end',
positionActionMenu: true,
reactionGroupPosition: 'start',
}

Expand Down Expand Up @@ -206,7 +211,7 @@ class ChatMessage extends UIComponent<WithAsProp<ChatMessageProps>, ChatMessageS
actionMenu: ChatMessageProps['actionMenu'],
styles: ComponentSlotStylesPrepared,
) {
const { unstable_overflow: overflow } = this.props
const { unstable_overflow: overflow, positionActionMenu } = this.props
const { messageNode } = this.state

const actionMenuElement = Menu.create(actionMenu, {
Expand All @@ -222,32 +227,37 @@ class ChatMessage extends UIComponent<WithAsProp<ChatMessageProps>, ChatMessageS
return actionMenuElement
}

const menuRect: DOMRect = _.invoke(this.menuRef.current, 'getBoundingClientRect') || {
const menuRect: DOMRect = (positionActionMenu &&
_.invoke(this.menuRef.current, 'getBoundingClientRect')) || {
height: 0,
}
const messageRect: DOMRect = _.invoke(messageNode, 'getBoundingClientRect') || { height: 0 }
const messageRect: DOMRect = (positionActionMenu &&
_.invoke(messageNode, 'getBoundingClientRect')) || { height: 0 }

return (
<Popper
enabled={positionActionMenu}
align="end"
modifiers={{
// https://popper.js.org/popper-documentation.html#modifiers..flip.behavior
// Forces to flip only in "top-*" positions
flip: { behavior: ['top'] },
preventOverflow: {
escapeWithReference: false,
// https://popper.js.org/popper-documentation.html#modifiers..preventOverflow.priority
// Forces to stop prevent overflow on bottom and bottom
priority: ['left', 'right'],

// Is required to properly position action items
...(overflow && {
boundariesElement: 'scrollParent',
escapeWithReference: true,
padding: { top: messageRect.height - menuRect.height },
}),
},
}}
modifiers={
positionActionMenu && {
// https://popper.js.org/popper-documentation.html#modifiers..flip.behavior
// Forces to flip only in "top-*" positions
flip: { behavior: ['top'] },
preventOverflow: {
escapeWithReference: false,
// https://popper.js.org/popper-documentation.html#modifiers..preventOverflow.priority
// Forces to stop prevent overflow on bottom and bottom
priority: ['left', 'right'],

// Is required to properly position action items
...(overflow && {
boundariesElement: 'scrollParent',
escapeWithReference: true,
padding: { top: messageRect.height - menuRect.height },
}),
},
}
}
position="above"
positionFixed={overflow}
targetRef={messageNode}
Expand Down