fix: use Portal to render ShareModal at document.body

AnimatedRoute's will-change:transform creates a new containing block,
which makes fixed positioning relative to that element instead of the
viewport. When the page is scrolled, the modal appears off-center.
Using createPortal to render at document.body bypasses this issue and
ensures the modal always appears centered in the viewport.

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Chever John 2026-06-30 03:02:04 +08:00
parent aba6330db7
commit 124d0e8ff7
No known key found for this signature in database
GPG Key ID: 2894D52ED1211DF0

View File

@ -1,4 +1,5 @@
import React, { useState, useCallback, useEffect, useRef } from 'react'; import React, { useState, useCallback, useEffect, useRef } from 'react';
import { createPortal } from 'react-dom';
import { motion } from 'framer-motion'; import { motion } from 'framer-motion';
import { Share2, Copy, Check, X, AlertTriangle, Building2, Eye, EyeOff, Link2, Send } from 'lucide-react'; import { Share2, Copy, Check, X, AlertTriangle, Building2, Eye, EyeOff, Link2, Send } from 'lucide-react';
import { useResponsive } from '../../hooks/useResponsive'; import { useResponsive } from '../../hooks/useResponsive';
@ -244,7 +245,7 @@ export function ShareModal({
const link = generateShareLink(); const link = generateShareLink();
const factoryLabel = factoryType === 'textile' ? '织布厂' : '水洗厂'; const factoryLabel = factoryType === 'textile' ? '织布厂' : '水洗厂';
return ( return createPortal(
<div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-3 sm:p-4"> <div className="fixed inset-0 bg-black/50 backdrop-blur-sm flex items-center justify-center z-50 p-3 sm:p-4">
<motion.div <motion.div
initial={{ opacity: 0, scale: 0.95 }} initial={{ opacity: 0, scale: 0.95 }}
@ -529,6 +530,7 @@ export function ShareModal({
</> </>
)} )}
</motion.div> </motion.div>
</div> </div>,
document.body
); );
} }