スクロール位置インジケーター
大量行のスクロール中に「今どの行にいるか」を示すバブル / ルーラー / ジャンプ先プレビュー
大量行(特に 100 万行級)ではスクロールバー 1px の移動が数百〜数千行に相当し、移動中に現在位置を見失いがちです。scrollHint を有効にすると、次の 3 つのオーバーレイがこれに答えます(既定は完全無効の opt-in 機能です)。
- カスタムスクロールバー: ヘッダー下から始まる専用ガターに常時表示のトラックと最小 30px のサムを描画します(ドラッグ / クリックジャンプ / ホイール対応)。macOS のオーバーレイスクロールバーは自動で消え、大量行ではサムが極小になって「掴む場所」を見失うため、これを置き換えます。
- 行番号バブル: スクロール中、サムの脇に「行 N / 総行数」を表示します。任意の列値(品番など)を添えることもできます。
- 行目盛りルーラー: ボディ右端に行数スケール(切りのよい刻み。刻みが 1 万の倍数のときは「10万」等の圧縮表記に統一)をフェード表示します。
- ジャンプ先プレビュー: スクロールバーにポインタを置くと「ここに飛ぶと行 N」の点線 + ラベルを表示します(スクロールバーのクリック / ドラッグと同じ写像)。
デモ(100,000 行)
- スクロールバーのサムをドラッグすると、バブルが現在の先頭行を追従表示します。
- 右端(スクロールバー帯)にポインタを置くと、ルーラーとジャンプ先プレビューが現れます。
- 「表示内容」を切り替えると、行番号のみ /
hintColumn/renderHintの 3 形態を比較できます。
有効化
// 全部入り(バブル + ルーラー、trigger='scroll')
<SpreadsheetGrid scrollHint />
// 個別設定
<SpreadsheetGrid
scrollHint={{
bubble: true, // 行番号バブル(既定 true)
ruler: true, // ルーラー + ジャンプ先プレビュー(既定 true)
scrollbar: true, // カスタム縦スクロールバー(既定 true。false でネイティブバーのまま)
trigger: 'scroll', // 'scroll'(既定)| 'hover' | 'always'
minRows: 0, // データ量ゲート(既定 0 = 常時有効。詳細は下記)
}}
/>trigger: 'scroll' はスクロール中のみ表示し、停止から約 1 秒でフェードアウトします。止まっている間の見た目は一切変わりません。
データ量に応じた自動 ON/OFF(minRows)
数十行程度の小規模データでは、バブル / ルーラー / カスタムスクロールバーはノイズになりがちです。minRows を指定すると、表示行数がしきい値以上のときだけ scrollHint が有効になります。
// 100 行以上のときだけスクロールヒントを表示(未満はネイティブスクロールバーのまま)
<SpreadsheetGrid scrollHint={{ hintColumn: 'code', minRows: 100 }} />- 判定に使う行数はバブルの「/ 総行数」と同じ、フィルター / グルーピング適用後のビュー行数です(SSRM はサーバー総行数)。フィルターで絞り込んでしきい値を割れば、その間は自動で OFF になります。
- 既定は
0(常時有効)なので、指定しない限り従来の挙動から変わりません。 - 注意:
scrollbar有効時はしきい値またぎでガター余白が付け外しされるため、行数が変動する画面では僅かなレイアウトシフトが起きます(気になる場合はscrollbar: falseと併用してください)。
表示内容のカスタマイズ
行番号に任意の列値を添えるには hintColumn(簡易)か renderHint(完全カスタム。hintColumn より優先)を使います。
// 簡易: 行番号 + 品目コード
<SpreadsheetGrid scrollHint={{ hintColumn: 'code' }} />
// 完全カスタム: コード — 品目名
<SpreadsheetGrid
scrollHint={{
renderHint: ({ rowIndex, rowData }) =>
rowData ? `${rowData.code} — ${rowData.name}` : null,
}}
/>renderHint が null / undefined を返すと行番号のみの既定表示になります。
SSRM / グルーピングでの挙動
バブル / プレビューの対象行が SSRM の未ロード行(またはグルーピングのグループ行)の場合、rowData は undefined になり、hintColumn 指定時は自動的に行番号のみへフォールバックします(renderHint には undefined がそのまま渡るので利用側で分岐します)。
インジケーター自体は「総行数 + スクロール位置」だけで駆動されるため、clientSide / SSRM / auto-height を含む全構成でそのまま動作します。
仕組みと注意点
- 行番号は仮想化の縦ジオメトリ(100 万行の pixel scaling / auto-height の prefix-sum)と同一の写像で解決するため、常に画面表示と一致します。
- バブル / ルーラー / プレビューのオーバーレイは
pointer-events: noneで、スクロール・セル操作へ一切干渉しません。カスタムスクロールバーのガターのみポインタ操作を受けますが、コンテンツのスクロール自体はネイティブのまま(ガターはscrollTopを書くだけの鏡映し)です。 - カスタムスクロールバー有効時はネイティブ縦スクロールバーを非表示化します(Chromium / WebKit。Firefox はネイティブ縦バーが残りますがガター操作は有効)。横スクロールバーもトークンで同じ配色にスタイリングされます。
- 全行が viewport に収まりスクロール不能のときは何も表示しません。
- バブル / サム / ラベルの配色はテーマトークン(
--ssg-pill-*/--ssg-scrollhint-*)に追従し、light / dark 両テーマで機能します。
すべてのオプションは SpreadsheetGrid props を参照してください。