diff --git a/app/components/PcFundTable.jsx b/app/components/PcFundTable.jsx index 5a4430b..5308ac4 100644 --- a/app/components/PcFundTable.jsx +++ b/app/components/PcFundTable.jsx @@ -1077,8 +1077,9 @@ export default function PcFundTable({ const totalHeaderWidth = headerGroup?.headers?.reduce((acc, h) => acc + h.column.getSize(), 0) ?? 0; return ( -
- - {/* 表头 */} - {renderTableHeader(false)} + {/* 表头 */} + {renderTableHeader(false)} - {/* 表体 */} - - item.code)} - strategy={verticalListSortingStrategy} + {/* 表体 */} + - - {table.getRowModel().rows.map((row, index) => ( - -
- {row.getVisibleCells().map((cell) => { - const columnId = cell.column.id || cell.column.columnDef?.accessorKey; - const isNameColumn = columnId === 'fundName'; - const rightAlignedColumns = new Set([ - 'latestNav', - 'estimateNav', - 'yesterdayChangePercent', - 'estimateChangePercent', - 'totalChangePercent', - 'holdingAmount', - 'todayProfit', - 'holdingProfit', - ]); - const align = isNameColumn - ? '' - : rightAlignedColumns.has(columnId) - ? 'text-right' - : 'text-center'; - const cellClassName = - (cell.column.columnDef.meta && cell.column.columnDef.meta.cellClassName) || ''; - const style = getCommonPinningStyles(cell.column, false); - const isPinned = cell.column.getIsPinned(); - return ( -
- {flexRender( - cell.column.columnDef.cell, - cell.getContext(), - )} -
- ); - })} -
-
- ))} -
-
-
+ item.code)} + strategy={verticalListSortingStrategy} + > + + {table.getRowModel().rows.map((row, index) => ( + +
+ {row.getVisibleCells().map((cell) => { + const columnId = cell.column.id || cell.column.columnDef?.accessorKey; + const isNameColumn = columnId === 'fundName'; + const rightAlignedColumns = new Set([ + 'latestNav', + 'estimateNav', + 'yesterdayChangePercent', + 'estimateChangePercent', + 'totalChangePercent', + 'holdingAmount', + 'todayProfit', + 'holdingProfit', + ]); + const align = isNameColumn + ? '' + : rightAlignedColumns.has(columnId) + ? 'text-right' + : 'text-center'; + const cellClassName = + (cell.column.columnDef.meta && cell.column.columnDef.meta.cellClassName) || ''; + const style = getCommonPinningStyles(cell.column, false); + const isPinned = cell.column.getIsPinned(); + return ( +
+ {flexRender( + cell.column.columnDef.cell, + cell.getContext(), + )} +
+ ); + })} +
+
+ ))} +
+
+ - {table.getRowModel().rows.length === 0 && ( -
-
- 暂无数据 + {table.getRowModel().rows.length === 0 && ( +
+
+ 暂无数据 +
-
- )} - {resetConfirmOpen && ( - } - confirmVariant="primary" - onConfirm={handleResetSizing} - onCancel={() => setResetConfirmOpen(false)} - confirmText="重置" - /> + )} + {resetConfirmOpen && ( + } + confirmVariant="primary" + onConfirm={handleResetSizing} + onCancel={() => setResetConfirmOpen(false)} + confirmText="重置" + /> + )} + {showPortalHeader && ReactDOM.createPortal( +
+
+ {headerGroup?.headers.map((header) => { + const style = getCommonPinningStyles(header.column, true); + const isNameColumn = + header.column.id === 'fundName' || + header.column.columnDef?.accessorKey === 'fundName'; + const align = isNameColumn ? '' : 'text-center'; + return ( +
+ {header.isPlaceholder + ? null + : flexRender( + header.column.columnDef.header, + header.getContext(), + )} +
+ ); + })} +
+
, + document.body + )} +
+ {!!(cardDialogRow && getFundCardProps) && ( + )} - { - if (!open && !blockDialogClose) setCardDialogRow(null); - }} - > - e.preventDefault() : undefined} - > - - - 基金详情 - - -
- {cardDialogRow && getFundCardProps ? ( - - ) : null} -
-
-
+ - {showPortalHeader && ReactDOM.createPortal( -
-
- {headerGroup?.headers.map((header) => { - const style = getCommonPinningStyles(header.column, true); - const isNameColumn = - header.column.id === 'fundName' || - header.column.columnDef?.accessorKey === 'fundName'; - const align = isNameColumn ? '' : 'text-center'; - return ( -
- {header.isPlaceholder - ? null - : flexRender( - header.column.columnDef.header, - header.getContext(), - )} -
- ); - })} -
-
, - document.body - )} -
); } + +function FundDetailDialog({ blockDialogClose, cardDialogRow, getFundCardProps, setCardDialogRow}) { + return ( + { + if (!open && !blockDialogClose) setCardDialogRow(null); + }} + > + e.preventDefault() : undefined} + > + + + 基金详情 + + +
+ {cardDialogRow && getFundCardProps ? ( + + ) : null} +
+
+
+ ) +} diff --git a/app/hooks/useBodyScrollLock.js b/app/hooks/useBodyScrollLock.js index dca2a0b..5d90c53 100644 --- a/app/hooks/useBodyScrollLock.js +++ b/app/hooks/useBodyScrollLock.js @@ -15,9 +15,11 @@ function lockBodyScroll() { originalBodyPosition = document.body.style.position || ""; originalBodyTop = document.body.style.top || ""; - document.body.style.position = "fixed"; - document.body.style.top = `-${lockedScrollY}px`; - document.body.style.width = "100%"; + requestAnimationFrame(() => { + document.body.style.top = `-${lockedScrollY}px`; + document.body.style.width = "100%"; + document.body.style.position = "fixed"; + }); } } @@ -28,12 +30,15 @@ function unlockBodyScroll() { // 只有全部弹框都关闭时才恢复滚动位置 if (scrollLockCount === 0) { + const scrollY = lockedScrollY; + document.body.style.position = originalBodyPosition; document.body.style.top = originalBodyTop; document.body.style.width = ""; - // 恢复到锁定前的滚动位置,而不是跳到顶部 - window.scrollTo(0, lockedScrollY); + requestAnimationFrame(() => { + window.scrollTo(0, scrollY); + }); } } @@ -57,4 +62,4 @@ export function useBodyScrollLock(open) { } }; }, [open]); -} \ No newline at end of file +} diff --git a/components/ui/dialog.jsx b/components/ui/dialog.jsx index eb8f219..a908a0a 100644 --- a/components/ui/dialog.jsx +++ b/components/ui/dialog.jsx @@ -1,7 +1,6 @@ "use client" import * as React from "react" -import { XIcon } from "lucide-react" import { Dialog as DialogPrimitive } from "radix-ui" import { cn } from "@/lib/utils" @@ -86,6 +85,8 @@ function DialogContent({ e.preventDefault()} + onCloseAutoFocus={(e) => e.preventDefault()} className={cn( "fixed top-[50%] left-[50%] z-50 w-full max-w-[calc(100%-2rem)] translate-x-[-50%] translate-y-[-50%] gap-4 rounded-[16px] border border-[var(--border)] text-[var(--foreground)] p-6 dialog-content-shadow outline-none duration-200 data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=closed]:zoom-out-95 data-[state=open]:animate-in data-[state=open]:fade-in-0 data-[state=open]:zoom-in-95 sm:max-w-lg", "mobile-dialog-glass",