Fix: 优化表格展示减少抖动现象

This commit is contained in:
奇趣保罗 2025-11-05 20:16:02 +08:00
parent 9766bc2411
commit fe90dfb7d2
1 changed files with 12 additions and 12 deletions

View File

@ -138,22 +138,22 @@ export default function Editor() {
onError: (m) => setPageError(m), onError: (m) => setPageError(m),
}); });
const colWidth = useMemo(() => `${100 / (languages.length + 2)}%`, [languages.length]); const tableWidth = useMemo(() => (languages.length * 200) + 36 + 60 + 200, [languages.length]);
const virtuosoComponents = useMemo(() => ({ const virtuosoComponents = useMemo(() => ({
Table: (props: React.TableHTMLAttributes<HTMLTableElement>) => <table className="min-w-full text-sm table-fixed" {...props} />, Table: ({ style, ...props }: React.TableHTMLAttributes<HTMLTableElement>) => <table className="min-w-full text-sm table-fixed" {...props} style={{ ...style, width: tableWidth }} />,
TableHead: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <thead className="bg-muted" {...props} />, TableHead: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <thead className="bg-muted" {...props} />,
TableRow: (props: React.HTMLAttributes<HTMLTableRowElement>) => <tr className="border-t" {...props} />, TableRow: (props: React.HTMLAttributes<HTMLTableRowElement>) => <tr className="border-t" {...props} />,
TableBody: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <tbody {...props} />, TableBody: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <tbody {...props} />,
TableFoot: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <tfoot {...props} />, TableFoot: (props: React.HTMLAttributes<HTMLTableSectionElement>) => <tfoot {...props} />,
}), []); }), [tableWidth]);
const allSelected = useMemo(() => entries.length > 0 && selected.size === entries.length, [entries, selected]); const allSelected = useMemo(() => entries.length > 0 && selected.size === entries.length, [entries, selected]);
const MAX_AI_ITEMS = 50; const MAX_AI_ITEMS = 50;
const headerContent = useCallback(() => ( const headerContent = useCallback(() => (
<tr> <tr>
<th style={{ width: 36 }} className="px-3 py-2"> <th style={{ width: 36 }} className="sticky left-0 text-left px-3 py-2 bg-muted">
<Checkbox <Checkbox
checked={allSelected} checked={allSelected}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
@ -167,11 +167,11 @@ export default function Editor() {
</th> </th>
<th style={{ width: 200 }} className="text-left px-3 py-2"></th> <th style={{ width: 200 }} className="text-left px-3 py-2"></th>
{languages.map((lang) => ( {languages.map((lang) => (
<th key={lang} style={{ width: colWidth }} className="text-left px-3 py-2">{lang}</th> <th key={lang} style={{ width: 200 }} className="text-left px-3 py-2">{lang}</th>
))} ))}
<th style={{ width: 80 }} className="text-left px-3 py-2"></th> <th style={{ width: 60 }} className="sticky right-0 text-left px-3 py-2 bg-muted"></th>
</tr> </tr>
), [languages, colWidth, allSelected, entries]); ), [languages, allSelected, entries]);
const renderItemContent = useCallback((_idx: number, entry: FlatEntry) => { const renderItemContent = useCallback((_idx: number, entry: FlatEntry) => {
const handleCopy = () => { const handleCopy = () => {
@ -181,7 +181,7 @@ export default function Editor() {
return ( return (
<> <>
<td style={{ width: 36 }} className="px-3 py-2"> <td className="sticky left-0 px-3 py-2 bg-white">
<Checkbox <Checkbox
checked={selected.has(entry.path)} checked={selected.has(entry.path)}
onCheckedChange={(checked) => { onCheckedChange={(checked) => {
@ -193,7 +193,7 @@ export default function Editor() {
}} }}
/> />
</td> </td>
<td style={{ width: 200 }} className="px-3 py-2 font-mono"> <td className="px-3 py-2 font-mono">
<button type="button" className="w-full text-left min-h-8 leading-8 px-2 rounded hover:bg-accent" onClick={handleCopy} title="点击复制"> <button type="button" className="w-full text-left min-h-8 leading-8 px-2 rounded hover:bg-accent" onClick={handleCopy} title="点击复制">
{entry.path} {entry.path}
</button> </button>
@ -203,7 +203,7 @@ export default function Editor() {
const isSaving = inline.isSavingCell(entry.path, lang); const isSaving = inline.isSavingCell(entry.path, lang);
const displayValue = inline.getDisplayValue(entry.path, lang); const displayValue = inline.getDisplayValue(entry.path, lang);
return ( return (
<td key={`${entry.path}:${lang}`} style={{ width: colWidth }} className="px-3 py-2 text-foreground/90 align-top"> <td key={`${entry.path}:${lang}`} className="px-3 py-2 text-foreground/90 align-top">
{isEditing ? ( {isEditing ? (
<Input <Input
ref={inline.inputRef} ref={inline.inputRef}
@ -227,7 +227,7 @@ export default function Editor() {
</td> </td>
); );
})} })}
<td style={{ width: "5em" }} className="px-3 py-2 align-top"> <td className="sticky right-0 px-3 py-2 align-top bg-white">
<DropdownMenu> <DropdownMenu>
<DropdownMenuTrigger asChild> <DropdownMenuTrigger asChild>
<Button size="sm" variant="outline"> <Button size="sm" variant="outline">
@ -285,7 +285,7 @@ export default function Editor() {
</td> </td>
</> </>
); );
}, [languages, colWidth, inline, projectId, structure, setStructure, setValuesByLang, copy]); }, [languages, inline, projectId, structure, setStructure, setValuesByLang, copy]);
useEffect(() => { useEffect(() => {
if (!projectId || languages.length === 0) return; if (!projectId || languages.length === 0) return;