SpreadsheetGrid
ガイド

カスタムレンダリング

セル / ヘッダー / トップ・ボトムバー / エディタ / コンテキストメニューを React で自由に描画する

グリッドの見た目と挙動は、通常の React コンポーネントで差し替えられます。すべて「関数を渡すとコンテキストが届く」スタイルで、状態管理はグリッド側が持ちます。

カスタムセル(renderCell)

column.renderCell にレンダラを渡すと、セル内容を自由に描画できます。コンテキストには value / row のほか、そのセルへ直接書き込める setValue が入っているため、ボタンやトグルなどのインタラクティブなセルも作れます。

ToolbarRows: 5 / 5Columns: 4 / 4Sort: なし
#
1
2
3
4
5
Rows: 5 / 5Columns: 4 / 4
Active: なしSelection: なしCells: 0 / Rows: 0Cols: 0
{
  key: 'status', title: 'ステータス', width: 120,
  renderCell: ({ value }) => (
    <span className={badgeClass(value)}>{String(value)}</span>
  ),
},
{
  key: 'stock', title: '在庫', width: 160,
  renderCell: ({ value, setValue }) => (
    <>
      <button onClick={() => setValue(Number(value) - 1)}>−</button>
      <span>{Number(value)}</span>
      <button onClick={() => setValue(Number(value) + 1)}>+</button>
    </>
  ),
}
  • コンテキストの全フィールドは CellRenderContext<T>(row / rowIndex / sourceRowIndex / rowKey / colIndex / value / column / isActive / isSelected / isEditing / readOnly / setValue)です。
  • renderCell は表示の差し替えです。編集(ダブルクリック時のエディタ)は従来どおり editor が担当し、共存できます(デモのステータス列 = バッジ表示 + select エディタ)。
  • 表示文字列を変えるだけなら、より軽い valueFormatter を使ってください。条件付きの色付けだけなら cellClassName が最軽量です。

セルのメモ(cellNote)

column.cellNote が文字列を返したセルの右上に印(三角)を出し、マウスを乗せるとその文字列をツールチップで表示します。FarPoint SPREAD のセルメモ / Excel のメモに当たる機能で、renderCell を使わずに「このセルには補足がある」ことを示せます。プレイグラウンドの cellNote トグルで試せます。

{
  key: 'partNo', title: '品番', width: 140,
  cellNote: ({ row }) =>
    [row.isNew && '今回の取込で追加された構成です。', row.otherUses > 0 && `他 ${row.otherUses} 箇所でも使用`]
      .filter(Boolean)
      .join('\n'),  // \n で改行。空文字なら印は出ない
}
  • 印の色はトークン --ssg-note-indicator で変えられます。入力エラー(validate)と同じセルでは、エラーの小さい赤い三角がメモの三角の上に重なって両方見え、ツールチップは「エラー → 改行 → メモ」の順になります。
  • 背景色などは従来どおり cellClassName で付けます(メモは印とツールチップだけ)。
  • CSV / コピー / エクスポートには含まれません。詳細は API リファレンス を参照してください。

カスタムヘッダー(renderHeader)

column.renderHeader で列ヘッダーのラベル部分を差し替えます(上のデモの「📋 タスク」列)。ソート・メニュー・リサイズなどのヘッダー機能はそのまま維持されます。

{
  key: 'name', title: 'タスク', width: 180,
  renderHeader: ({ column }) => (
    <span>📋 {column.title}</span>
  ),
}

トップバー / ボトムバー(renderTopBar / renderBottomBar)

renderTopBar / renderBottomBar でバーを丸ごと React で差し替えられます。渡ってくる SpreadsheetGridSlotContext に、グローバルフィルターの読み書き(globalFilterText / setGlobalFilterText)、rows / filteredRows、選択状態、そして整形済みの派生 summary である derivedSummary が入っているため、ヘルパーを import せずに実用的なバーが書けます。

🍀 マイ在庫一覧6 / 6 件
#
1
2
3
4
5
6
Rows: 6 / 6Filter: なしCells: 0 / Rows: 0数値のセル範囲を選択すると合計 / 平均が出ます
<SpreadsheetGrid
  renderTopBar={(ctx) => (
    <div className="my-toolbar">
      <input
        value={ctx.globalFilterText}
        onChange={(e) => ctx.setGlobalFilterText(e.target.value)}
        placeholder="検索"
      />
      <span>{ctx.filteredRows.length} / {ctx.rows.length} 件</span>
    </div>
  )}
  renderBottomBar={(ctx) => (
    <div className="my-statusbar">
      <span>{ctx.derivedSummary.rowSummaryText}</span>
      <span>{ctx.derivedSummary.selectionStatsText}</span>
    </div>
  )}
  ...
/>
  • derivedSummary には行/列/フィルター/ソートの summary 文字列、選択セルの件数などが入っています(SpreadsheetGridDerivedSummary)。
  • 2 セル以上を選んでいるときは selectionAggregates に選択範囲の集計(平均 / データの個数 / 合計 / 最小 / 最大)が入っています(GridSelectionAggregates)。既定ボトムバーはこのうち平均 / データの個数 / 合計を右側(Active / Selection の隣の空き)に出します(showSelectionAggregates={false} で非表示。詳細は API リファレンス)。
  • ctx や rows / filteredRows を子コンポーネントの props にそのまま渡す(<MyBar ctx={ctx} /> / <MyBar rows={ctx.filteredRows} />)のは避け、使う値だけを渡してください(件数なら ctx.filteredRows.length や derivedSummary)。React 19.2 以降の開発ビルドは props の差分を取るために大きな配列を走査するため、100 万行規模ではソート 1 回に数十秒かかることがあります(本番ビルドには影響しません)。上の例のようにバーの中で直接 ctx を読む分には問題ありません。
  • 丸ごと差し替えずに調整したい場合は表示制御 props を使います: showTopBar / showBottomBar(マスタースイッチ)、既定バーの部品単位では showTopBarSummary / showTopBarFilter / showFilterChipBar など。一覧は API リファレンス を参照してください。

カスタムエディタ(type: 'custom')

組み込みエディタ(text / number / select / date / checkbox)で足りないときは、編集 UI 自体を描画できます。ctx.commit(value) で確定、ctx.cancel() でキャンセルです。非 string を commit するとパーサをバイパスしてドメイン値がそのまま書き込まれます。

ToolbarRows: 4 / 4Columns: 3 / 3Sort: なし
#
1
2
3
4
Rows: 4 / 4Columns: 3 / 3
Active: なしSelection: なしCells: 0 / Rows: 0Cols: 0
{
  key: 'rating', title: '評価', width: 180, editable: true,
  renderCell: ({ value }) => <Stars n={Number(value)} />,
  editor: {
    type: 'custom',
    render: (ctx) => (
      <StarPicker
        value={Number(ctx.value)}
        onPick={(n) => ctx.commit(n)}   // 数値のまま書き込み
        onCancel={() => ctx.cancel()}
      />
    ),
  },
}
  • フォーカス管理とキーバインドは利用側の責務です(ctx には row / initialText(印字キー開始時の 1 文字)なども入ります)。

コンテキストメニュー(右クリック)

enableContextMenu + getContextMenuItems で、セル / 行番号ガターの右クリックメニューを定義できます。ライブラリは既定項目を一切持たない完全カスタム設計で、空配列を返すとブラウザ標準メニューにフォールスルーします。

ToolbarRows: 4 / 4Columns: 2 / 2Sort: なし
#
1
2
3
4
Rows: 4 / 4Columns: 2 / 2
Active: なしSelection: なしCells: 0 / Rows: 0Cols: 0

セルまたは行番号を右クリックしてください

<SpreadsheetGrid
  enableContextMenu
  getContextMenuItems={({ target, isTargetSelected }) => {
    if (target.type !== 'cell' && target.type !== 'rowHeader') return [];
    return [
      { kind: 'label', label: '行操作' },
      { label: '行を複製', onSelect: () => duplicate(target.row) },
      { kind: 'separator' },
      { label: '行を削除', danger: true, onSelect: () => remove(target.row) },
    ];
  }}
  ...
/>

項目は判別共用体(action / label / separator / custom)で、custom は自由描画のエスケープハッチです。詳細は API リファレンス を参照してください。

どの手段を選ぶか

やりたいこと手段
表示文字列の整形(3 桁区切りなど)valueFormatter
条件付きの色・背景cellClassName + CSS
セルに補足のメモ(右上の印 + ツールチップ)cellNote
セルに独自 UI(バッジ / バー / ボタン)renderCell
編集 UI そのものを差し替えeditor: { type: 'custom' }
ヘッダーラベルの装飾renderHeader
バーの部品の表示切替showTopBar* / showBottomBar* 系 props
バーを丸ごと自作renderTopBar / renderBottomBar
右クリックメニューgetContextMenuItems
色・寸法トークンの一括調整テーマとスタイリング

On this page