diff --git a/packages/web/src/components/chat/Message.tsx b/packages/web/src/components/chat/Message.tsx
index 4965bb5d..a8a309cf 100644
--- a/packages/web/src/components/chat/Message.tsx
+++ b/packages/web/src/components/chat/Message.tsx
@@ -401,24 +401,34 @@ export function Message({ message, isCompact, isFirstInGroup, previousMessageId
{/* Reaction emoji picker */}
- {showReactionPicker && canAddReactions && reactionPickerBtnRef.current && createPortal(
-
,
- document.body,
- )}
+ {showReactionPicker && canAddReactions && reactionPickerBtnRef.current && (() => {
+ const PICKER_HEIGHT = 400;
+ const PICKER_WIDTH = 360;
+ const MARGIN = 8;
+ const btnRect = reactionPickerBtnRef.current!.getBoundingClientRect();
+ const spaceBelow = window.innerHeight - btnRect.bottom;
+ const spaceAbove = btnRect.top;
+ const flipAbove = spaceBelow < (PICKER_HEIGHT + MARGIN) && spaceAbove > spaceBelow;
+ const top = flipAbove
+ ? Math.max(MARGIN, btnRect.top - PICKER_HEIGHT - MARGIN)
+ : btnRect.bottom + MARGIN;
+ const left = Math.min(
+ Math.max(MARGIN, btnRect.left),
+ window.innerWidth - PICKER_WIDTH - MARGIN,
+ );
+ return createPortal(
+ ,
+ document.body,
+ );
+ })()}
{/* Action buttons on hover */}
{(isHovered || showReactionPicker || confirmingDelete) && !isEditing && (