You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在@mui/x-data-grid-pro中固定DetailsPanel?

固定MUI X DataGrid Pro的DetailsPanel(横向滚动不移动)

问题原因

直接给DetailsPanel容器加position: sticky无效,是因为默认的DetailsPanel嵌套在行容器内部,它的定位基准是行而非表格的横向滚动容器,导致无法跟随滚动固定位置。

实现方案

通过自定义DOM结构,将DetailsPanel脱离行嵌套,独立渲染为固定容器,同步行的展开状态和高度:

  1. 禁用默认DetailsPanel渲染:通过detailPanel属性返回null,避免内置的嵌套结构。
  2. 独立固定容器:在DataGrid外部创建一个sticky定位的容器,仅当行展开时显示。
  3. 同步行状态与布局:监听行的展开/折叠事件,控制固定容器的显示、高度,并给表格行留出左侧空间。

代码示例

import * as React from 'react';
import { DataGridPro, GridRowParams, GridApiRef, useGridApiRef } from '@mui/x-data-grid-pro';
import { Box } from '@mui/material';

// 模拟数据
const rows = Array.from({ length: 10 }).map((_, i) => ({
  id: `${i}`,
  col1: `内容 ${i}`,
  col2: `长内容 ${i} 重复重复重复重复重复重复重复重复重复重复`,
  col3: `更多内容 ${i}`,
  col4: `额外内容 ${i}`,
  col5: `补充内容 ${i}`,
}));

const columns = [
  { field: 'col1', headerName: '列1', width: 150 },
  { field: 'col2', headerName: '列2', width: 300 },
  { field: 'col3', headerName: '列3', width: 150 },
  { field: 'col4', headerName: '列4', width: 150 },
  { field: 'col5', headerName: '列5', width: 150 },
];

export default function StickyDetailPanelDemo() {
  const apiRef = useGridApiRef();
  const [expandedRowId, setExpandedRowId] = React.useState<string | null>(null);
  const [panelHeight, setPanelHeight] = React.useState(0);

  const handleRowExpand = (params: GridRowParams) => {
    setExpandedRowId(params.id);
    // 通过API获取行的实际高度
    const rowElement = apiRef.current.getRowElement(params.id);
    if (rowElement) {
      setPanelHeight(rowElement.offsetHeight);
    }
  };

  const handleRowCollapse = () => {
    setExpandedRowId(null);
    setPanelHeight(0);
  };

  return (
    <Box style={{ position: 'relative', width: '100%', overflowX: 'auto' }}>
      {/* 固定的详情面板 */}
      {expandedRowId && (
        <Box
          sx={{
            position: 'sticky',
            left: 0,
            top: 0,
            height: panelHeight,
            bgcolor: 'background.paper',
            zIndex: 10,
            borderRight: 1,
            borderColor: 'divider',
            p: 2,
            display: 'flex',
            flexDirection: 'column',
            justifyContent: 'center',
          }}
        >
          <h4>行 {expandedRowId} 详情</h4>
          <p>这是固定的详情内容,横向滚动时不会跟随表格移动</p>
          <p>可以在这里添加任意自定义内容</p>
        </Box>
      )}

      <DataGridPro
        apiRef={apiRef}
        rows={rows}
        columns={columns}
        detailPanel={() => null} // 禁用默认详情面板
        onRowExpand={handleRowExpand}
        onRowCollapse={handleRowCollapse}
        sx={{
          '& .MuiDataGrid-row': {
            // 给固定面板留出左侧空间
            paddingLeft: expandedRowId ? '280px' : 0,
            transition: 'padding-left 0.2s',
          },
          '& .MuiDataGrid-cell': {
            borderRight: '1px solid rgba(224, 224, 224, 1)',
          },
        }}
        initialState={{
          pagination: { paginationModel: { pageSize: 5 } },
        }}
      />
    </Box>
  );
}

关键细节

  • 该方案在社区版(@mui/x-data-grid)也能生效,无需依赖Pro版即可验证功能。
  • 通过useGridApiRef可以精准获取行的DOM元素和高度,替代模拟值。
  • 若需支持多行展开,可扩展状态管理逻辑,为每个展开的行创建独立的固定面板。

内容的提问来源于stack exchange,提问作者isimisi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 21:37:40