fix:修复移动端drawer 自动滚动到顶部的行为

This commit is contained in:
hzm
2026-03-12 08:45:39 +08:00
parent 613b5f02e8
commit 063be7d08e
5 changed files with 171 additions and 67 deletions

View File

@@ -0,0 +1,83 @@
'use client';
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerTitle, DrawerTrigger,
} from '@/components/ui/drawer';
import FundCard from './FundCard';
import { CloseIcon } from './Icons';
/**
* 移动端基金详情底部 Drawer 弹框
*
* @param {Object} props
* @param {boolean} props.open - 是否打开
* @param {(open: boolean) => void} props.onOpenChange - 打开状态变化回调
* @param {boolean} [props.blockDrawerClose] - 是否禁止关闭(如上层有弹框时)
* @param {React.MutableRefObject<boolean>} [props.ignoreNextDrawerCloseRef] - 忽略下一次关闭(用于点击到内部 dialog 时)
* @param {Object|null} props.cardSheetRow - 当前选中的行数据,用于 getFundCardProps
* @param {(row: any) => Object} [props.getFundCardProps] - 根据行数据返回 FundCard 的 props
*/
export default function MobileFundCardDrawer({
open,
onOpenChange,
blockDrawerClose = false,
ignoreNextDrawerCloseRef,
cardSheetRow,
getFundCardProps,
children,
}) {
return (
<Drawer
open={open}
onOpenChange={(nextOpen) => {
if (!nextOpen) {
if (ignoreNextDrawerCloseRef?.current) {
ignoreNextDrawerCloseRef.current = false;
return;
}
if (!blockDrawerClose) onOpenChange(false);
}
}}
>
<DrawerTrigger asChild>
{children}
</DrawerTrigger>
<DrawerContent
className="h-[77vh] max-h-[88vh] mt-0 flex flex-col"
onPointerDownOutside={(e) => {
if (blockDrawerClose) return;
if (e?.target?.closest?.('[data-slot="dialog-content"], [role="dialog"]')) {
if (ignoreNextDrawerCloseRef) ignoreNextDrawerCloseRef.current = true;
return;
}
onOpenChange(false);
}}
>
<DrawerHeader className="flex-shrink-0 flex flex-row items-center justify-between gap-2 space-y-0 px-5 pb-4 pt-2 text-left">
<DrawerTitle className="text-base font-semibold text-[var(--text)]">
基金详情
</DrawerTitle>
<DrawerClose
className="icon-button border-none bg-transparent p-1"
title="关闭"
style={{ borderColor: 'transparent', backgroundColor: 'transparent' }}
>
<CloseIcon width="20" height="20" />
</DrawerClose>
</DrawerHeader>
<div
className="flex-1 min-h-0 overflow-y-auto px-5 pb-8 pt-0"
style={{ paddingBottom: 'calc(24px + env(safe-area-inset-bottom, 0px))' }}
>
{cardSheetRow && getFundCardProps ? (
<FundCard {...getFundCardProps(cardSheetRow)} />
) : null}
</div>
</DrawerContent>
</Drawer>
);
}

View File

@@ -24,17 +24,10 @@ import {
} from '@dnd-kit/sortable';
import { CSS } from '@dnd-kit/utilities';
import { throttle } from 'lodash';
import {
Drawer,
DrawerClose,
DrawerContent,
DrawerHeader,
DrawerTitle,
} from '@/components/ui/drawer';
import FitText from './FitText';
import FundCard from './FundCard';
import MobileFundCardDrawer from './MobileFundCardDrawer';
import MobileSettingModal from './MobileSettingModal';
import { CloseIcon, DragIcon, ExitIcon, SettingsIcon, SortIcon, StarIcon } from './Icons';
import { DragIcon, ExitIcon, SettingsIcon, SortIcon, StarIcon } from './Icons';
const MOBILE_NON_FROZEN_COLUMN_IDS = [
'yesterdayChangePercent',
@@ -1082,51 +1075,14 @@ export default function MobileFundTable({
/>
)}
<Drawer
<MobileFundCardDrawer
open={!!(cardSheetRow && getFundCardProps)}
onOpenChange={(open) => {
if (!open) {
if (ignoreNextDrawerCloseRef.current) {
ignoreNextDrawerCloseRef.current = false;
return;
}
if (!blockDrawerClose) setCardSheetRow(null);
}
}}
>
<DrawerContent
className="h-[77vh] max-h-[88vh] mt-0 flex flex-col"
onPointerDownOutside={(e) => {
if (blockDrawerClose) return;
if (e?.target?.closest?.('[data-slot="dialog-content"], [role="dialog"]')) {
ignoreNextDrawerCloseRef.current = true;
return;
}
setCardSheetRow(null);
}}
>
<DrawerHeader className="flex-shrink-0 flex flex-row items-center justify-between gap-2 space-y-0 px-5 pb-4 pt-2 text-left">
<DrawerTitle className="text-base font-semibold text-[var(--text)]">
基金详情
</DrawerTitle>
<DrawerClose
className="icon-button border-none bg-transparent p-1"
title="关闭"
style={{ borderColor: 'transparent', backgroundColor: 'transparent' }}
>
<CloseIcon width="20" height="20" />
</DrawerClose>
</DrawerHeader>
<div
className="flex-1 min-h-0 overflow-y-auto px-5 pb-8 pt-0"
style={{ paddingBottom: 'calc(24px + env(safe-area-inset-bottom, 0px))' }}
>
{cardSheetRow && getFundCardProps ? (
<FundCard {...getFundCardProps(cardSheetRow)} />
) : null}
</div>
</DrawerContent>
</Drawer>
onOpenChange={(open) => { if (!open) setCardSheetRow(null); }}
blockDrawerClose={blockDrawerClose}
ignoreNextDrawerCloseRef={ignoreNextDrawerCloseRef}
cardSheetRow={cardSheetRow}
getFundCardProps={getFundCardProps}
/>
{!onlyShowHeader && showPortalHeader && ReactDOM.createPortal(renderContent(true), document.body)}
</div>

View File

@@ -106,8 +106,10 @@
html,
body {
overscroll-behavior-y: none;
height: 100%;
overflow-x: clip;
will-change: auto; /* 或者移除任何 will-change: transform */
}
body {

View File

@@ -3356,13 +3356,13 @@ export default function HomePage() {
isScanImporting;
if (isAnyModalOpen) {
document.body.style.overflow = 'hidden';
containerRef.current.style.overflow = 'hidden';
} else {
document.body.style.overflow = '';
containerRef.current.style.overflow = '';
}
return () => {
document.body.style.overflow = '';
containerRef.current.style.overflow = '';
};
}, [
settingsOpen,