AG-Grid でヘッダーの下にアクションエリアを表示する方法

はじめに

【全部俺】 Web フロントエンドエンジニアのメモ Advent Calendar 2022 13 日目の記事です。
AG-Grid でテーブルのヘッダー行の下にアクションができる固定行を表示する方法を解説します。
(React 版 v28 を使用しています。)

ヘッダー行の下にアクションができる行とは?

正式な名称がわからないので説明的ですが、下記のような UI です。 (もし名前ご存知でしたら教えてください)
Gmail のスクリーンショット。メールを選択すると、テーブル内の最上部に「このメッセージ内のメッセージ50件すべてが選択されています。」という行(セル)が増える
AG-Grid ではこの機能は搭載されていませんでした。そこで、AG-Grid の様々な機能を活用して無理やり実装してみました。
React Data Grid: Full Width Rows
https://www.ag-grid.com/react-data-grid/full-width-rows/#understanding-full-width
React Data Grid: Row Pinning
https://www.ag-grid.com/react-data-grid/row-pinning/
React Data Grid: Row Selection
https://www.ag-grid.com/react-data-grid/row-selection/

サンプル

どれか行を選択すると、上から件数と選択された ID を表示するセルが表示されます。
(個人的には選択するとすべての行が動いてしまうので避けたい実装ではありますが、Gmail と挙動を合わせてみました)
import { AgGridReact } from "ag-grid-react";
import { useCallback, useMemo } from "react";

import type {
  ColDef,
  IsFullWidthRowParams,
  RowHeightParams,
  RowSelectedEvent,
} from "ag-grid-community";

type Data = { id: number; name: string };

// 表示するコンポーネント
const FullWidthCell = ({ api }: IsFullWidthRowParams) => {
  const length = useMemo(() => api.getSelectedRows().length, [api]);
  const selectedIds = useMemo(
    () => api.getSelectedRows().map((v) => v.id),
    [api]
  );

  return (
    <div
      style={{
        borderBottom: `1px solid #eee`,
        width: "100%",
        height: "100%",
        paddingLeft: 24,
      }}
    >
      {length}件を選択中。 {selectedIds.join(",")}
    </div>
  );
};

export const DataGrid = (): JSX.Element => {
  const rowData: Array<Data> = [
    { id: 1, name: "Item 1" },
    { id: 2, name: "Item 2" },
    { id: 3, name: "Item 3" },
    { id: 4, name: "Item 4" },
    { id: 5, name: "Item 5" },
  ];

  const columnDefs: ColDef<Data>[] = [
    {
      field: "check",
      headerCheckboxSelection: true,
      checkboxSelection: true,
    },
    { field: "id" },
    { field: "name" },
  ];

  // 上部に固定
  const isFullWidthRow = useCallback(
    (params: IsFullWidthRowParams) => params.rowNode.rowPinned === "top",
    []
  );

  // 高さを固定
  const getRowHeight = useCallback(
    (params: RowHeightParams) => (params.node.rowPinned ? 40 : undefined),
    []
  );

  // 選択時に有効を切り替え
  const onRowSelected = useCallback((event: RowSelectedEvent) => {
    event.api.setPinnedTopRowData(
      event.api.getSelectedRows().length > 0 ? [true] : undefined
    );
  }, []);

  return (
    <AgGridReact<Data>
      rowData={rowData}
      columnDefs={columnDefs}
      fullWidthCellRenderer={FullWidthCell}
      isFullWidthRow={isFullWidthRow}
      getRowHeight={getRowHeight}
      onRowSelected={onRowSelected}
      domLayout="autoHeight"
      rowSelection="multiple"
      rowMultiSelectWithClick
    />
  );
};

まとめ

AG-Grid でヘッダーの下にアクションエリアを表示できました。なんとなく辛みがあるので、AG-Grid に実装してほしいです。

ホームプロフィール外部リンクのため、別ウインドウで開きますプライバシーポリシー

© 2023 Oishi Takanori / Made with Gatsby.js