@aiquants/virtualscroll 3.7.1 → 3.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -2,6 +2,122 @@
2
2
 
3
3
  All notable changes to `@aiquants/virtualscroll` are documented here.
4
4
 
5
+ ## 3.8.1 (2026-10-03)
6
+
7
+ ### Fixed
8
+
9
+ - **マウントのたびに一覧をもう一度描いていた**: 3.8.0 の装置の画素への揃えは、比をラッパーの取り付け (React の
10
+ 確定の段) で状態へ確定していた。比が未定 (`null`) から比へ変わるこの更新のため、クライアントでのマウントの
11
+ たびに paint の前の同期の描き直し (React の Profiler では段階 `nested-update` の確定) が 1 回足されていた。
12
+ 描き直すのは `VirtualScroll` 本体とペインで、React はその前に確定の passive effect も流す (実測でマウント
13
+ 1 回あたり約 0.8〜1.4 ms、マウントの 4〜8 %)。行が 0 件からまた行を持つときのラッパーの付け直しでも同じ
14
+ 描き直しが起きていた。ポップアップを開くたびに一覧をマウントするホストでは、開く操作ごとの確定が 1 回
15
+ 増えていた。
16
+ - **比は描画の中で読み、取り付けは確かめるだけにする**: 平行移動を揃える比はラッパーを描く部品が描画の中で
17
+ 読む。取り付けの前は React を実行しているページのウィンドウを描くウィンドウと見込み、取り付けがラッパーの
18
+ 文書のウィンドウと突き合わせる。自分のウィンドウの文書に描いた一覧は最初の確定から揃った値で描き、確定の段の
19
+ 描き直しは起きない (マウントでも行 0 件からの付け直しでも `nested-update` は 0 回)。iframe や別ウィンドウの
20
+ 文書に描いた一覧は、取り付けでそのウィンドウの比へ切り替えて paint の前に 1 回だけ同期で描き直す (3.8.0 と
21
+ 同じく、見込みの比で揃えた値は描かれない)。ブラウザの拡大縮小や密度の違う画面への移動は従来どおり
22
+ `(resolution: <比>dppx)` のメディアクエリで追い、確定の段の外の通常の更新 1 回で揃え直す。サーバー描画の
23
+ HTML は厳密値のままで、ハイドレーションも厳密値で描くので不一致は報告されず、ハイドレーションの直後に揃えた
24
+ 値へ置き換わる。ウィンドウを持たない文書へ描くとラッパーの取り付けで `Error` を投げるのも従来どおり。描かれる
25
+ 値と公開 API は変わらない。
26
+ - **テスト**: `VirtualScroll.spec.ts` +4 と 2 件の強化。`React.Profiler` で確定ごとの段階とその確定の時点の
27
+ transform を記録し、自分のウィンドウの文書へのマウントが比 1.25 でも最初の確定から格子上にあり
28
+ `nested-update` が無いこと、マウントの後の行 0 件 → 1000 件の付け直しの区間に `nested-update` が無く
29
+ 付け直した確定から格子上にあること、比の変化は `update` の確定 1 回で揃え直すこと、`renderToString` は
30
+ 厳密値を書き比 1.25 での `hydrateRoot` は不一致を報告せずハイドレーションの直後に揃え直すことを固定する
31
+ (新規 4 件)。act を使わない `flushSync` の行は確定が `mount` 1 回だけであることを、iframe の行は見込みの
32
+ ウィンドウからの切り替えが `nested-update` 1 回でその確定が iframe の比で揃っていることを足した。修正前の
33
+ ソースでは 3 件 (マウント・付け直し・`flushSync`) が red。vitest 1,030 件 / 53 ファイル (単体 999 + 統合 31。
34
+ 2026-10-03 の `vitest run --maxWorkers=2` 1 回の全数実測で、すべて通りスキップ 0)。
35
+
36
+ ## 3.8.0 (2026-10-03)
37
+
38
+ ### Added
39
+
40
+ - **スクロールバー矢印を Tab 順から外す `enableArrowButtonTabStops`**: 矢印ボタン 2 個を Tab の止まり先に
41
+ するかどうか (既定 `true` = 従来どおり)。行のロービングフォーカス (矢印 / Page / Home / End) やグリッドの
42
+ キーボードモデルのように、ホストがキーボードスクロールを自前で持つ場合に `false` を指定すると両矢印が
43
+ `tabIndex={-1}` になり、バー 1 本あたり 2 個の冗長な Tab の止まり先が消える (ネイティブのスクロールバーも
44
+ Tab の止まり先にならない)。変わるのは `tabIndex` だけで、ポインタ押下と長押しリピート・アクセシブルネーム・
45
+ スクリプトからフォーカスした矢印の Enter / Space は維持する。矢印は `role="scrollbar"` の要素の子孫で、
46
+ ARIA 1.2 はその子を presentational とするため、支援技術が矢印を独立したボタンとして示すかどうかは
47
+ ブラウザ次第 (Chromium は示し、バー全体を 1 つの操作部品として示すブラウザもある) — パッケージはそこを
48
+ 約束しない。既定を `true` に据え置くのは、ホスト側のモデルが無ければ矢印が Tab で届く唯一のスクロール
49
+ 操作部品だから (ペインは transform で動きネイティブのスクロール領域を持たず、行も Tab の止まり先ではない)。
50
+ 矢印が無効な間 (`enableArrowButtons: false` またはスクロール不要) は効果なし。同じ名前と意味で全入口に
51
+ 置いた: `ScrollBar` / `ScrollPane` の props と、`VirtualScroll` / `VirtualGrid` の `scrollBarOptions`
52
+ (グリッドは縦・横の両バーへ適用)。
53
+ - **テスト**: 単体 `arrowButtonTabStops.spec.tsx` 24 件 (新規。4 入口それぞれで、未指定と `true` 明示の
54
+ `tabIndex=0` と Tab 経路、`false` の `tabIndex=-1` と Tab / Shift+Tab が止まらずに横切ること (user-event)、
55
+ 名前付きのボタンのままで操作可能なこと、長押しリピート、スクリプトからフォーカスした矢印の
56
+ Enter / Space)、`VirtualGrid.spec.tsx` +7 (下記 Changed の両バー適用 5 件と `RangeError` の文面 2 件)、
57
+ `labels.spec.ts` +1 (`VIRTUAL_SCROLL_LABEL_KEYS` の列そのもの — 7 キーの件数と順序 — の固定。合成する側が
58
+ 自分のキー表の先頭に連結して固定するため、キーの追加・並べ替えは破壊的変更になる)、
59
+ `shippedTextSelfContained.spec.ts` 51 件 (新規 — 下記 Changed)、`VirtualScroll.spec.ts` +12 (下記 Fixed の
60
+ 装置の画素への揃え: 揃える関数の 4 件 — 比 1・1.25・1.5・2 で負・小数の入力が最も近い格子点へ揃うこと、代表値、
61
+ 冪等、0 より大きい有限数でない比の `RangeError` — と、描画の 8 件 — 比 1 の 2440.5px が整数 px になること、
62
+ 行の上端は端数のまま残ること、比 1.25・1.5・2 の格子、比の変化で揃え直して監視を新しい比で張り直すこと、
63
+ ラッパーの取り外しで監視を外し再取り付けで比を読み直すこと、iframe に描いた一覧はそのウィンドウの比を読むこと、
64
+ ウィンドウの無い文書で `Error` を投げること、act を使わない `flushSync` の描画でも戻った時点で揃っていること)。
65
+ vitest 1,026 件 / 53 ファイル (単体 995 + 統合 31。3.7.1 の取り込み後、2026-10-03 の `vitest run --maxWorkers=1` 1 回の全数実測で、
66
+ すべて通りスキップ 0)。
67
+
68
+ ### Changed
69
+
70
+ - **`VirtualGrid` の横バーも `scrollBarOptions` のバー固有メンバーに従う**: `enableThumbDrag` /
71
+ `enableTrackClick` / `enableArrowButtons` (と新設の `enableArrowButtonTabStops`) を縦バーと同じく横バーへも
72
+ 適用する。従来は横バーへ効くのが `width` / `tapScrollCircleOptions` だけで、これらを指定しても縦バーしか
73
+ 変わらなかった (仕様書に既知の制約として記録していたもの)。1 つの設定がグリッドの片側だけに効く状態を
74
+ 無くすための変更で、`tapScrollCircleOptions` は統合 2 軸サークル、`renderThumbOverlay` (可視行
75
+ インデックスを受け取る) と `enableScrollToTopBottomButtons` は行軸の機能として内包 `VirtualScroll` 専用のまま。
76
+ - **公開の流れで tarball の漏洩検査を必ず通す**: `publish:patch` / `publish:minor` / `publish:major` は
77
+ typecheck → test → 漏洩検査 (`check-publish-leaks.mjs` — 自分で `pnpm pack` を行い、その tarball そのものを検査する)
78
+ → 版上げ → 公開 の順に、素の `pnpm publish` が起動する `prepublishOnly` は漏洩検査だけを走らせる。`pnpm pack` は
79
+ `prepare` (= ビルド) を走らせるため、検査する tarball は常にビルドしたての成果物で、公開の入口が二度ビルドすることはない。
80
+ 検出が 1 件でもあれば版上げの前に止まる。配線は単体 `publishLeakGuard.spec.ts` 7 件 (新規) が固定する。
81
+ あわせて、同梱の README・CHANGELOG・`src/VirtualGrid.tsx` の注釈が参照していた、tarball に含まれない
82
+ 設計文書への参照 (3.7.0 の tarball で検査が検出した 4 件) を、参照先が決めていた内容 (`VirtualGrid` の
83
+ 有界化契約と、バーごとのタップサークルを抑止する理由) の記述へ置き換えた。
84
+ - **同梱の文章を単独で読めるようにする**: `VirtualGrid` の `getRowHeight` / `getColWidth` が契約外の値を
85
+ 返したときの `RangeError` は、読めない設計文書の節を示す代わりに、許容範囲と従い方と上限の理由を
86
+ 自分で述べる: `[VirtualGrid] getColWidth(3) returned 262145 — must be an integer in [0, 262144] (0 = hidden).
87
+ Round fractional sizes to whole pixels and split content larger than 262144 px across several columns: a larger
88
+ track could push cell positions past the 2^25 px layout-coordinate limit of browsers.` (行は `rows`)。
89
+ あわせて README・CHANGELOG・型宣言 (`.d.ts` に載る docstring) から、tarball に含まれない文書への参照
90
+ (`docs/specs` などのパス、ADR 番号、設計文書の節番号 (§)、変異台帳の ID) を除き、参照先が決めて
91
+ いた内容の記述へ置き換えた (例: `VirtualGrid` が意図的に持たない行側メンバーの一覧、`MAX_RENDERED_CELLS`
92
+ が賄う画面の大きさ)。実装のコメントには設計文書の節への参照が素の節記号と題名の形で残る (ADR 番号、
93
+ 設計・実装プランに続く節記号、リポジトリの `docs` の下の階層と `.agents`・`.worktrees` へのパスは、下記の
94
+ spec が同梱の全ファイルで拒否するため、コメントにも残さない)。単体 `shippedTextSelfContained.spec.ts` (新規)
95
+ は同梱物を `package.json` の `files` から導出し (`dist`・spec を除く `src`・README・CHANGELOG・LICENSE と
96
+ `package.json`)、本パッケージ独自の文書参照の規則 (ADR 番号、設計・実装プランに続く節記号、URL の一部では
97
+ ない `docs` の下の階層と `.agents`・`.worktrees` へのパス。規則は spec の中で定義し、モノレポの漏洩ガードの
98
+ 規則ファイルは読まない) を、全パスと全ファイルの全文へコメントも含め、エスケープを復号した形にも当てる。
99
+ 読み手向けのより厳しい規則 (数字の続く節記号、設計文書を題名で指すこと、変異台帳の ID) は、README・
100
+ CHANGELOG・型宣言・sourcemap (対応表 `mappings` を除く)・スタイルシート (コメントを除く) と、コードの
101
+ 文字列・テンプレート・JSX の文字へ当てる。検出は `ファイル:行: [規則] "一致"` の一覧で示し、`files` の
102
+ 項目が何にも一致しなければ (ビルド前の `dist` など) 名前を示して失敗する。
103
+
104
+ ### Fixed
105
+
106
+ - **行ラッパーの平行移動を装置の画素へ揃える**: 行を包むラッパーは自前の合成層 (`will-change: transform`) を
107
+ `transform: translateY(…)` で動かす。その量がスクロール位置の端数 (トラックパッドや慣性の移動量・中央揃え・
108
+ 端数の行の高さやインセット) をそのまま持つと、ブラウザは層全体を再標本化する。実画面ではペイン位置 2440.5px で
109
+ 2px の輪郭・2px の隙間・2px の輪が 3+1+3 行に滲み (下辺では隙間が消え)、文字もぼけた。平行移動は一覧を描く
110
+ ウィンドウの装置の画素の格子へ揃える (`Math.round(量 × devicePixelRatio) / devicePixelRatio`。比 1 では整数 px、
111
+ 1.25 では 0.8px、1.5 では 2/3px、2 では 0.5px の刻み)。比はラッパーの文書のウィンドウ (iframe や別ウィンドウに
112
+ 描いた一覧ではそのウィンドウ) からラッパーの取り付け時に読み、ブラウザの拡大縮小や密度の違う画面への移動で
113
+ 変わると `(resolution: <比>dppx)` のメディアクエリで読み直す。揃えるのはラッパーの平行移動だけで、行の位置
114
+ (層の中の端数の位置は描画が画素へ揃える) と、`onScroll` / `onRangeChange` / `getScrollPosition()` /
115
+ `getScrollAnchor()` が示す位置は厳密値のまま (見える位置のずれは最大で半装置画素)。`VirtualGrid` の行も
116
+ 同じラッパーで描くので縦に揃う。サーバー描画の HTML は厳密値を持ち (サーバーに画面は無い)、ハイドレーションで
117
+ 揃えた値に置き換わる。クライアントでのマウントは最初の paint の前に比を確定する。ウィンドウを持たない文書
118
+ (`document.implementation.createHTMLDocument()` で作った文書など) へ描くと、ラッパーの取り付けで `Error` を
119
+ 投げる (描かれない文書には揃える比が無い)。
120
+
5
121
  ## 3.7.1 (2026-10-01)
6
122
 
7
123
  ### Fixed
@@ -92,13 +208,13 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
92
208
  単調時の 56%。x は `hxRef` 単一書き手のため無事)。修正は**軸別位置権威の x 側への整列**:
93
209
  `getVy` を埋め込みハンドル `getScrollPosition()` (= `applyVy` の `scrollBy` が updater を解決する
94
210
  ペイン内部 ref と同一権威) の読みへ変更 — 「各軸の `getPos` は適用シームと同一権威を読む」を
95
- ドライバ契約として登記 (グリッド仕様 §3.6 ADR-31 行 / MV-XY38-39)。`applyVy`・x 経路・
211
+ ドライバ契約とした。`applyVy`・x 経路・
96
212
  `computeTapScrollVelocity`・フックのループ意味論はバイト不変。
97
213
  - **デモ / ゲート**: エンジンデモに `/grid-tap` ルートを新設 (VirtualGrid + 統合サークル)。
98
214
  実ブラウザ E2E `grid-tap-scroll.spec.ts` (ページ内 rAF サンプラーで純 x / 純 y 1 秒保持の
99
215
  フレーム単調性 + 前進下限) と、決定的 rAF ハーネスの配線単体ゲート
100
216
  `gridTapAxisAuthority.spec.tsx` 3 件 (純 y / 斜め xy / 純 x の毎フレーム一様前進 —
101
- 鏡像退行変異 MV-XY38/39 で red 実証) を追加。単体 819 / 819 (46 ファイル)。
217
+ y の読みを鏡像へ戻す変異 2 本で red を実証) を追加。単体 819 / 819 (46 ファイル)。
102
218
 
103
219
  ## 3.6.0 (2026-09-18)
104
220
 
@@ -110,15 +226,15 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
110
226
  帯幅非依存・凍結トグル不変)、**既定オフセットは両軸 −200** (到達性導出 — バー既定 −80/0 では
111
227
  ない)。opt-out は従来どおり `tapScrollCircleOptions: { enabled: false }` — 今後は**唯一の
112
228
  サークルを殺す**。封鎖コンテンツ面積は半減 (40 px ディスク 1 枚)。既定 ON の挙動置換を
113
- **minor** とする判断は ADR-32 登記: 置換対象が出荷済み欠陥・再解釈フィールド
229
+ **minor** とした理由: 置換対象が出荷済み欠陥・再解釈フィールド
114
230
  (`offsetX`/`offsetY` — バー相対 → コーナー相対) への in-repo 依存ゼロ・型削除ゼロ (いずれか
115
231
  1 つでも崩れていれば 4.0.0 だった)。
116
232
  - **速度則**: 方向余弦分解 `v = (s_x(r)·ox/r, s_y(r)·oy/r)` — `s_a` は無改造
117
- `computeTapScrollSpeed` の軸別評価 (純軸ドラッグは各バー則と画素法則恒等 = T1)。新規純関数
233
+ `computeTapScrollSpeed` の軸別評価 (純軸ドラッグは各バーの速度則と画素単位で恒等)。新規純関数
118
234
  `computeTapScrollVelocity` + 型 `TapScrollVelocityInput` / `TapScrollAxisSpeedParams` を
119
235
  **バレル export ×3**。`TapScrollCircle.axis` は `"x" | "y" | "xy"` の射影部分空間へ一般化
120
236
  (既定 `"y"` 不変・state 型不変 — `"xy"` の `direction` は径方向係合 `{0, 1}`)。
121
- - **登記デルタ (グリッド仕様 §3.6 の一覧が正典)**: キャンセルイベント無条件リセット (旧: 縦は
237
+ - **バーのタップループとの挙動差**: キャンセルイベント無条件リセット (旧: 縦は
122
238
  paneId フィルタ → 一様に無条件 = 厳密 fail-closed) / 片軸境界はループ非停止・境界フラグ毎
123
239
  フレーム (反転で同一保持中に端から退却) / 軸上ピンの純軸ドラッグはループをパーク (角度付き
124
240
  pointermove で再開) / pendingColAnchor は**適用済み** hx デルタのみで解除 (バーの要求時規則
@@ -128,8 +244,7 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
128
244
  意図縦 ⇒ 交差 829 px/s (2 s で ≈ 8+ 列 @200 px 列)、意図横 ⇒ 交差 1,533 px/s (2 s で
129
245
  ≈ **96 行** @32 px 行)。受入閾値 (タッチ実機・クローズドループ): 中央値 ≤ 1 列 (意図縦) /
130
246
  ≤ 6 行 (意図横) — 超過時は連続リマップ `φ_ε(θ) = θ − ε·sin 4θ` を 3.6.0 既定として出荷する
131
- 事前コミット。異方性下ではコンテンツ速度角 ≠ ドラッグ角 (全手掛かりはドラッグ角を表示 —
132
- 登記)。遮蔽 / 到達性の閾値表はグリッド仕様 §3.6。
247
+ 事前コミット。異方性下ではコンテンツ速度角 ≠ ドラッグ角 (全手掛かりはドラッグ角を表示)。
133
248
  - **`axis="x"` の引き transform 修正**: `translateY` → `translateX` (「右ドラッグで下へ動く」
134
249
  出荷済み quirk — 裸バー opt-in 経由でのみ到達・in-repo 消費者ゼロ)。`"y"` はバイト恒等。
135
250
  - **forced-colors**: `.aqvs-tap-scroll-circle` へパッケージ初の `forced-colors: active` 輪郭
@@ -144,26 +259,26 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
144
259
  `stretchMainSize` (縦バー限定でインライン主軸寸をスキップ — 横バーは stretch が主軸を寸法
145
260
  決めできないため書込み維持) を `ScrollPane` が `isSelfMeasuringViewport` で結線。幾何は
146
261
  `viewportSize` の数値由来で無傷。回帰ゲート = 実 Chromium ラダー E2E
147
- (800→1300→800→600→1000 双方向回復)。ScrollPane 仕様 §2.5 に機構を登記。
148
- - 単体 815 / 815 (45 ファイル) 全緑・変異台帳 MV-XY 37 行 + MV-SM 3 行 (物理 43 変異) 全 red 実測。
262
+ (800→1300→800→600→1000 双方向回復)。
263
+ - 単体 815 / 815 (45 ファイル) 全緑・変異 43 本すべての red を実測。
149
264
 
150
265
  ## 3.5.0 (2026-09-14)
151
266
 
152
267
  - **新機能 — `VirtualGrid` の両軸末尾凍結 (`frozenTrailingCols` / `frozenTrailingRows`)**:
153
- 末尾凍結はエンジン機能 (ADR-18 — route A)。列側は幅減算 + 右クリップ — スクロール帯幅を
268
+ 末尾凍結はエンジン側の機能。列側は幅減算 + 右クリップ — スクロール帯幅を
154
269
  `viewport − W_F − W_T` へ一般化し (`scrollBandWidthRef` の単一 ref 源)、末尾セルは右アンカー
155
270
  クリップ `.aqvs-grid-row-trailing` / `-inner` の**帯ローカル left** で描画する (アンカー機構の
156
271
  外 — 先頭帯の鏡像)。行側は `.aqvs-grid-main` の**下**の第 2 帯外バンド `.aqvs-grid-trailing-rows`
157
272
  (クリップ高 = H_T_vis インライン、inner は木高 H_T の bottom 定着 — 帯上端 = extent − H_T_vis
158
273
  が全構成で成立)。帯行は `renderRow` 逐語再利用で 4 象限コーナー全種が無償成立。複合帯の
159
- 優先順位は LEADING > TRAILING > MIDDLE (ADR-19): 中帯が最初に潰れ (`bandWidth ≤ 0` は正準空窓
274
+ 優先順位は LEADING > TRAILING > MIDDLE: 中帯が最初に潰れ (`bandWidth ≤ 0` は正準空窓
160
275
  start > end)、末尾が 2 番目 (CSS `max()` 左端 / bottom 定着 inner)、可視クリップの単一情報源は
161
276
  `trailingVisibleSize` (消費先はテンプレート高 / hbar `paddingRight` / `getFrozenSize` の vis
162
277
  export の 3 点ちょうど)。
163
278
  - **契約**: 両 props は [0, `MAX_FROZEN_TRAILING_COLS` / `MAX_FROZEN_TRAILING_ROWS` = 128] の整数
164
- fail-fast (RangeError)・動的クランプは `min(T, count − 先頭実効)` で**先頭がカウント空間で勝つ**
165
- (ADR-19-1)。**登記済み帰結**: 先頭 + 末尾の帯寸がビューポートを超えるとき、隠れた末尾セルは
166
- どのスクロール位置でも可視化できない (文書化されたクランプ — `scrollToCell` の末尾 no-op は
279
+ fail-fast (RangeError)・動的クランプは `min(T, count − 先頭実効)` で**先頭がカウント空間で勝つ**。
280
+ **文書化した帰結**: 先頭 + 末尾の帯寸がビューポートを超えるとき、隠れた末尾セルはどの
281
+ スクロール位置でも可視化できない (文書化されたクランプ — `scrollToCell` の末尾 no-op は
167
282
  そこでも正確)。T = 0 は DOM 構造・インライン属性までバイト恒等 (F = 0 / R = 0 恒等の双子)。
168
283
  `scrollToCell` / `initialScrollAnchor` の末尾狙いは当該軸 no-op (列は既存アンカー残置)、
169
284
  `updateRowSize` / `focusRowAtIndex` は 3 分岐 (末尾帯行は `trailingRowEpoch` 繰上げ / 帯行 DOM
@@ -175,15 +290,15 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
175
290
  - **`--aqvs-grid-trailing-width`**: 新設のパッケージスコープ CSS 変数 (0px フォールバック)。
176
291
  T > 0 のときのみ書かれ T = 0 で除去される**単一書き手**規律。`.aqvs-grid-row-scroll` の
177
292
  `right` は `var(--aqvs-grid-trailing-width, 0px)` へ差替え (T = 0 は計算結果までバイト恒等)。
178
- - **ADR-25 — `data-aqvs-frozen-row` の付与を F_eff > 0 へゲート分離**: 従来は凍結分岐と結合して
293
+ - **`data-aqvs-frozen-row` の付与を F_eff > 0 へゲート分離**: 従来は凍結分岐と結合して
179
294
  いたため、末尾のみ (F = 0 ∧ T > 0) のグリッドが凍結列ゼロで全行に属性を出す嘘になるところ
180
295
  だった。class `aqvs-grid-row-frozen-host` は「横帯モード」の描画トレイトとして残る。既存構成
181
296
  (F > 0 / T = 0) への挙動変化ゼロ。
182
- - **ADR-23 — T の実行時変更は埋め込み VirtualScroll を再マウントしない**: `key` は R 専用のまま、
297
+ - **T の実行時変更は埋め込み VirtualScroll を再マウントしない**: `key` は R 専用のまま、
183
298
  itemCount が**末尾**で伸縮するだけ (getItem / getItemKey / getItemHeight = i + R 不変)。視点は
184
299
  トグルを跨いで無償保存される。**保留アンカーの帰結 (文書化)**: T 増加で末尾帯入りする行を
185
300
  狙った保留行アンカーは最終スクロール行へクランプされる (itemCount 変化ごとの再ピン留め +
186
- `sanitizeIndex` — 「保留アンカーは R 再マウントで死ぬ」の鏡像)。MV-TR-A1..A4 ゲートで実測確定
301
+ `sanitizeIndex` — 「保留アンカーは R 再マウントで死ぬ」の鏡像)。専用ゲート 4 件で実測確定
187
302
  (740/740 全緑)。
188
303
 
189
304
  ## 3.4.0 (2026-09-03)
@@ -196,7 +311,7 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
196
311
  ゲートを `ScrollBar.spec.tsx` に追加 (695/695 全緑)。
197
312
 
198
313
  - **新機能 — `VirtualGrid` の凍結先頭行 (`frozenLeadingRows`)**: 帯外バンド + インデックス
199
- シフト方式 (行凍結設計プラン §2)。凍結行 [0, R) はグリッド所有の `.aqvs-grid-frozen-rows`
314
+ シフト方式。凍結行 [0, R) はグリッド所有の `.aqvs-grid-frozen-rows`
200
315
  バンドとして pane の外 (上) に描画し、行本体は `renderRow` をそのまま再利用 — F > 0 の
201
316
  凍結セル構造 (静的セル / row-scroll クリップ / hx 残差 var) が帯行内でも成立し**凍結行 ×
202
317
  凍結列の 4 象限コーナーが無償で成立**。埋め込み VirtualScroll にはシフト済み行空間
@@ -233,14 +348,14 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
233
348
  全行を再レンダーさせていた perf 欠陥の是正 (+R 挙動は不変)。(3) getScrollAnchor ハンドル
234
349
  docstring に縮退帯 null (H_F がビューポートを埋め itemCount 0 → null) を明記。
235
350
  - **検証**: 専用 spec `VirtualGridFrozenRows.spec.tsx` 19 (パッケージ 694/694、42 ファイル)
236
- と変異 MV-FR30〜FR45 red 実測 (FR40 は ×2 変異とも red。getItemKey +R シフト撤去のみ
237
- GT-2 として ⚠️ 等価登記 — 現状仕様 §5 台帳、全 102 変異 = 101 red + 1 ⚠️ 等価。
351
+ と変異 16 本の red 実測 (うち 1 本は 2 通りの変異とも red。getItemKey の +R シフト撤去だけは
352
+ 観測上の等価変異として記録 — 全 102 変異 = 101 red + 1 等価。
238
353
  `VirtualGridFrozen.spec.tsx` の `getFrozenSize` deep-equal ピン 4 件も rows / height 込みへ
239
354
  更新)。
240
355
 
241
356
  ## 3.3.0 (単独未公開 — 3.4.0 に同梱して公開)
242
357
 
243
- - **新機能 — `VirtualGrid` の凍結先頭列 (`frozenLeadingCols`)**: 設計 §8 の 3 形状要件を実装。
358
+ - **新機能 — `VirtualGrid` の凍結先頭列 (`frozenLeadingCols`)**: 次の 3 形状要件を実装。
244
359
  (a) スクロール帯の窓探索は木座標 W_F + hx 始まり (幅 0 凍結列の床クランプ込み)、(b) 残差は
245
360
  静的クリップ (`.aqvs-grid-row-scroll`) 内の inner が `calc(残差 − W_F)` で運ぶ (クリップと
246
361
  transform の分離は構造要件)、(c) 凍結帯はアンカー機構の外の静的 subtree (木絶対 left 直接
@@ -249,11 +364,10 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
249
364
  **F = 0 は DOM 構造まで従来と恒等** (既存 648 テスト無変更 green)。契約: [0, 128] の整数
250
365
  fail-fast (`MAX_FROZEN_LEADING_COLS` 新 export)・colCount 超過は動的クランプ (全列凍結)・
251
366
  凍結列狙いの scrollToCell / initialScrollAnchor の x は no-op・`getFrozenSize()` ハンドル新設。
252
- 検証: 専用 spec 27 (パッケージ 675/675) + 変異 MV-FR1〜FR29 全 red 実測 (現状仕様 §5 台帳 —
253
- R1 敵対レビューの実証欠陥 2 件 (全列凍結の両帯重複 / ヒール共有バッチの上書き非対称) と
254
- 実証穴 2 件 (帯ガード無ゲート / CSS 特異度) を封鎖済み)。publish 振付: 3.2.0 と 3.3.0 は
255
- 積層未リリースのため、版ラベル整合には凍結列コミットの親で 3.2.0 → HEAD で 3.3.0 の
256
- 2 段 publish が必要 (現状仕様 §8 の正準記録)。
367
+ 検証: 専用 spec 27 (パッケージ 675/675) + 変異 29 本すべての red 実測 (R1 敵対レビューの
368
+ 実証欠陥 2 件 (全列凍結の両帯重複 / ヒール共有バッチの上書き非対称) と実証穴 2 件 (帯ガード
369
+ 無ゲート / CSS 特異度) を封鎖済み)。publish 振付: 3.2.0 と 3.3.0 は積層未リリースのため、
370
+ 版ラベル整合には凍結列コミットの親で 3.2.0 → HEAD で 3.3.0 の 2 段 publish が必要。
257
371
 
258
372
  ## 3.2.0 (単独未公開 — 3.4.0 に同梱して公開)
259
373
 
@@ -269,14 +383,19 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
269
383
  の消費者はグリッド所有 `.aqvs-grid-row` の translateX (ペイン構造クラスを侵さない)。ヘッダー
270
384
  同期は範囲通知 (`VirtualGridRange`) + 消費側の窓原点相対方式。行側パリティ引継ぎ:
271
385
  `horizontalKeyInputs` / `horizontalKeyStep` / `contentInsets` / `background` / `onRowFocus` /
272
- `focusRowAtIndex` / `behaviorOptions.defaultColWidth` (全メンバー分類表は
273
- `docs/specs/2026.09.01 [AI] virtualscroll-virtual-grid.md` §3.1 / §3.2)。設計正典:
274
- `docs/plans/2026.09.01 [AI] virtualgrid-horizontal-axis-design-plan.md` (v6 認証済み)。
386
+ `focusRowAtIndex` / `behaviorOptions.defaultColWidth`。意図的に持たない行側メンバーは
387
+ `initialScrollIndex` / `initialScrollOffset` (`initialScrollAnchor` が唯一の口)・`onWheelHorizontal` /
388
+ `onPanHorizontal` (横軸はグリッドの所有)・ハンドルの `scrollToIndex` (`scrollToCell` が上位互換) /
389
+ `getFenwickTreeTotalHeight` / `getFenwickSize`。有界化契約 (両軸):
390
+ 祖先スケール z と描画窓スパン windowSpan (≤ viewport + (2 × overscan + 2) × `MAX_TRACK_SIZE`) に
391
+ ついて `z × (ANCHOR_REBASE_DISTANCE + windowSpan) ≤ 2^24` である限りアンカー基準の DOM 座標
392
+ (セル / 行の位置と残差 transform) は完全精度帯に収まり、overscan が既定の 3 で viewport が
393
+ 2^13 px 以下なら z = 5.31 まで成り立つ。
275
394
  - **シーム — `ScrollPane` / `VirtualScroll` に `onPanHorizontal`**: ポインタパン横成分の委譲
276
395
  (onWheelHorizontal のパン対・同符号・per-move 増分・押下時横 scale 除算)。指定時は横移動でも
277
396
  ドラッグが発動する。未指定の既存消費者への影響ゼロ。❗ 横軸を `Omit<>` で封じるラッパー
278
397
  (directory-tree) は 3.2.0 更新時に本シームを封印リストへ追加し (pass-through review)、
279
- **select-box / daily-report の影響なし確認**も同時に行うこと (設計 §11)。
398
+ **select-box / daily-report の影響なし確認**も同時に行うこと。
280
399
  - **改修 — `ScrollBar` 横タップサークル**: `enableHorizontalTapCircle` (opt-in — 単体既定不変)
281
400
  で横バーにもタップスクロールサークルを描画。`TapScrollCircle` の方向・距離・デッドゾーン
282
401
  導出を軸パラメータ化 (`axis` prop)。
@@ -293,17 +412,17 @@ All notable changes to `@aiquants/virtualscroll` are documented here.
293
412
  アクセサ identity を再構築キーへ届くよう修正 (従来は構造的に不発)。`defaultColWidth` は実行時
294
413
  変更にも追随。liveRegion は行側契約へ整列 (既定 400ms・不正値は警告 + 無効化 — 黙示代替も変異で
295
414
  封止)。横タップサークルへ `itemCount = colCount` を自動配線しタップ速度の log10(colCount) 則
296
- (設計 B7 対策) を実現、`tapScrollCircleOptions` も横バーへ透過。self-heal バーストは窓非依存の
297
- 「連続する非収束」計数 (解消は収束パスのみ — 窓端を動かす振幅の振動アクセサにも回避されず、
298
- 停止後はどの窓かでの収束 1 回で再武装。逐次の正当な治癒は誤認しない)。
415
+ を実現 (10^13 列ではサム 1 px ≈ 200 億列で、サムでは列を狙えないため)、`tapScrollCircleOptions` も
416
+ 横バーへ透過。self-heal バーストは窓非依存の「連続する非収束」計数 (解消は収束パスのみ —
417
+ 窓端を動かす振幅の振動アクセサにも回避されず、停止後はどの窓かでの収束 1 回で再武装。逐次の
418
+ 正当な治癒は誤認しない)。
299
419
  - **品質**: vitest 648 / 648 = 単体 618 + 統合 30 (VirtualGrid 59 + 横シーム 10 + Fenwick baseValue 4
300
- の新設ゲート込み)・変異 56 本 (MV-A〜MV-BD — アンカー / 残差 / 上限 / 打切り / clamp / パン符号・発動・scale /
420
+ の新設ゲート込み)・変異 56 本 (アンカー / 残差 / 上限 / 打切り / clamp / パン符号・発動・scale /
301
421
  タップ軸 / バー追従 / 幅エポック / 分母見積り / self-heal / 境界規約 / baseValue / contentProps
302
422
  持込 / 総幅同期 / 具現化計数 / リサイズ無効化 / 実測引継ぎ / identity 追随 / 暴走ガード /
303
423
  再ピン留め / 手動解除 / 同 tick 鮮度 / debounce 検証・黙示代替 / keyStep 透過 / overscan 15 化 /
304
424
  見積り基点 / 解除 3 サイト / 速度則配線 / 収束解消 / 蓄積撤去 / 停止恒久化 / tap オプション透過 /
305
- 非表示行スキップ / gBCR 計測復帰) 全 red 実測。台帳は
306
- `docs/specs/2026.09.01 [AI] virtualscroll-virtual-grid.md` §5。
425
+ 非表示行スキップ / gBCR 計測復帰) 全 red 実測。
307
426
 
308
427
  ## 3.1.1 (2026-08-28)
309
428
 
@@ -403,7 +522,7 @@ A-5 のうち**固定リピートタイマは実装を見送り**ました: 長
403
522
  ### Notes
404
523
 
405
524
  - デモに `/overscroll` (ページに縦あふれを持つ連鎖検証ルート) を追加。
406
- - ❗ E2E 作者向けの罠 (テスト仕様書 §6 に詳細): 離散的な合成ホイールを**ペインより上**のページ要素で
525
+ - ❗ E2E 作者向けの罠: 離散的な合成ホイールを**ペインより上**のページ要素で
407
526
  打つと、compositor が先にページをスクロールし、イベント配送時の hit-test が「ずり上がってきた行」に
408
527
  当たって 1 ノッチがページとペインの両方へ入る (実測: listener 内の rect が移動済みの座標を示す)。
409
528
  実ジェスチャはスクロールラッチで保護される。陽性コントロールの打点は**ペインより下**に取ること。
@@ -446,7 +565,7 @@ A-5 のうち**固定リピートタイマは実装を見送り**ました: 長
446
565
  - 2.5.0 の既知の限界に「両 ref を layout effect へ移すとタップスクロールの走破が短くなる退行が実機
447
566
  E2E で出る」と記録していましたが、**8 回 x 3 系列の A/B/A 対照実験で反証されました**。当時観測した
448
567
  失敗は書き込み位置と無関係のコールドスタート負荷フレーク (rAF が ~10fps へ落ち、`deltaSeconds` が
449
- 100ms キャップに張り付いてサンプル数の前提が崩れる — テスト仕様書 §6.1 に記載済みの既知モード) で、
568
+ 100ms キャップに張り付いてサンプル数の前提が崩れる既知のモード) で、
450
569
  render 本体書き込みの有無に関わらず同率 (6-7/8) で失敗します。「3 回失敗 → revert → 3 回成功」は
451
570
  負荷の時間的クラスタリングが生んだ錯覚でした。全 1,893 回のクランプ監査で committed 値と
452
571
  render 新値の食い違いは 0 件です。
@@ -549,7 +668,7 @@ A-5 のうち**固定リピートタイマは実装を見送り**ました: 長
549
668
  - 行は依然としてタブ順に入りません (`tabIndex={-1}`)。キーボードのみで横スクロールへ到達させたい消費側は
550
669
  `handle.focusItemAtIndex(0)` などでフォーカスの入口を用意してください (ロービングタブインデックスの
551
670
  導入は全消費側のタブ順を変えるため見送り)。デモ (`/horizontal`) にその実演ボタンを追加しました。
552
- - 既知の限界 (いずれも仕様書 §11.4 に記載): 行内でドラッグ選択/ダブルクリックすると選択が残り、それを
671
+ - 既知の限界: 行内でドラッグ選択/ダブルクリックすると選択が残り、それを
553
672
  畳むキーボード手段が無いため `Shift + ←/→` が効かないままになる / Shadow DOM 内の選択は検出できない /
554
673
  横スクロールは支援技術へ何も伝わらない / 縦スクロールでフォーカス行が仮想化で消えるとフォーカスが
555
674
  `<body>` へ落ちる / 位置を量子化する消費側では `horizontalKeyStep` が量子未満だと 1px も動かない /
package/README.md CHANGED
@@ -13,7 +13,7 @@ High-performance virtual scrolling component for React with variable item height
13
13
  - ↔️ **Horizontal Delegation**: Opt-in `onWheelHorizontal` hands horizontal wheel / trackpad (and shift+wheel) gestures to the parent — build frozen-column data grids
14
14
  - 🎨 **Customizable**: Flexible styling and theming options
15
15
  - 🌀 **Ultrafast Tap Scroll**: Adaptive tap scroll circle that scales speed up to 120× for massive datasets
16
- - ♿ **Accessibility opt-ins**: Escape row-return (`enableEscapeRowReturn`) and a screen-reader live region (`liveRegion`) announcing the visible range with your own wording
16
+ - ♿ **Accessibility opt-ins**: Escape row-return (`enableEscapeRowReturn`), a screen-reader live region (`liveRegion`) announcing the visible range with your own wording, and scrollbar arrows out of the Tab order for apps with their own keyboard scrolling (`enableArrowButtonTabStops`)
17
17
  - 🌐 **Localization**: The built-in chrome strings (scrollbar arrow labels, scroll-to-edge pills, empty state) ship in English (default) and Japanese via `locale`, with per-key `labels` overrides. See [Localization](#localization)
18
18
  - 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
19
19
 
@@ -135,6 +135,34 @@ the rendered row count and scrollability all derive from it, so all five would b
135
135
  spilling over the next element, a dead band at the bottom, an end you can never reach, a thumb that
136
136
  leaves the viewport, or a list that ignores the wheel entirely).
137
137
 
138
+ ## Device-pixel snapping
139
+
140
+ The rows move inside one wrapper that is translated with `transform: translateY(…)` on its own compositor
141
+ layer (`will-change: transform`). That translate is snapped to the device-pixel grid of the window the list
142
+ is painted in, `Math.round(offset × devicePixelRatio) / devicePixelRatio`: whole CSS pixels at a ratio of 1,
143
+ steps of 0.8 px at 1.25, 2/3 px at 1.5 and 0.5 px at 2. Fractional scroll positions (trackpad and inertia
144
+ deltas, centred alignment, fractional row heights or insets) therefore never move the layer by a fraction of
145
+ a device pixel. A layer moved by a fraction is resampled as a whole: 2 px borders, outlines, focus rings and
146
+ the gaps between them smear across neighbouring pixel rows, and text blurs.
147
+
148
+ - The ratio comes from the window of the list's own document, and it is read while the wrapper renders.
149
+ Before the wrapper is attached, the component expects the window of the page that runs React, and the
150
+ attach confirms it. A list rendered into its own window's document is therefore snapped in its first
151
+ commit, with no extra render. A list rendered into an iframe or a second window switches to that
152
+ window's ratio when the wrapper attaches, with one extra synchronous render before the browser paints.
153
+ The ratio is read again whenever it changes (browser zoom, or moving the window to a screen of another
154
+ density), through a `(resolution: <ratio>dppx)` media query.
155
+ - Only the wrapper translate is snapped. Row positions inside it keep their exact values (the browser paints
156
+ fractional positions inside a layer on whole pixels already), and every position the component reports
157
+ (`onScroll`, `onRangeChange`, `getScrollPosition()`, `getScrollAnchor()`) stays exact. The rows are drawn
158
+ at most half a device pixel away from the exact scroll position. `VirtualGrid` rows are drawn by the same
159
+ wrapper, so they are snapped vertically as well.
160
+ - Server-rendered HTML carries the exact offset, since there is no screen on the server. Hydration renders
161
+ the same exact offset, so it reports no mismatch, and the snapped offset replaces it right after hydration.
162
+ - Rendering into a document without a window (for example one made with
163
+ `document.implementation.createHTMLDocument()`) throws when the wrapper attaches: nothing is painted there,
164
+ so there is no ratio to snap to.
165
+
138
166
  ## Horizontal Scrolling
139
167
 
140
168
  `VirtualScroll` virtualizes and scrolls the **vertical** axis only. To add a horizontal axis — e.g. a
@@ -327,6 +355,35 @@ itself has focus (an `Escape` on the row means whatever *you* decide — e.g. de
327
355
  does act it calls `preventDefault()` only and does not stop propagation, the same contract as the
328
356
  arrow keys.
329
357
 
358
+ ## Scrollbar arrows and the Tab order
359
+
360
+ The scrollbar's two arrow buttons are Tab stops by default, because they are the only scrolling
361
+ control a keyboard user can reach with Tab: the pane moves its content by transform (there is no
362
+ native scroller for the browser to make focusable) and the rows are not Tab stops. Focus an arrow
363
+ and Enter / Space scrolls one step.
364
+
365
+ When your app already provides keyboard scrolling — roving focus with Arrow / Page / Home / End on
366
+ the rows, a grid keyboard model — the arrows only add two redundant stops per bar. Take them out of
367
+ the Tab order:
368
+
369
+ ```tsx
370
+ <VirtualScroll
371
+ scrollBarOptions={{ enableArrowButtonTabStops: false }} // the rows own keyboard scrolling
372
+ ...
373
+ />
374
+ ```
375
+
376
+ `false` sets `tabIndex={-1}` and changes nothing else: pointer presses and press-and-hold repeat keep
377
+ working, the arrows keep their accessible names, and Enter / Space still scroll an arrow you focus
378
+ from script — the position native scrollbars are in, which are never Tab stops either. What the
379
+ package does not promise is that assistive technology lists the arrows as buttons of their own:
380
+ they are descendants of the `role="scrollbar"` element, whose children ARIA 1.2 makes
381
+ presentational. Chromium exposes them anyway; other browsers may present the whole bar as one
382
+ control. The option has one name and one meaning everywhere: `ScrollBar` and `ScrollPane` props,
383
+ and `scrollBarOptions` of `VirtualScroll` and `VirtualGrid` (the grid applies it to both of its
384
+ bars). While the arrows are disabled (`enableArrowButtons: false`, or nothing to scroll) it has no
385
+ effect — a disabled button is never focusable.
386
+
330
387
  ## Screen-reader live region
331
388
 
332
389
  Virtualization removes off-screen rows from the DOM, so a screen-reader user scrolling the list
@@ -440,8 +497,14 @@ trillion columns sit comfortably inside).
440
497
  </VirtualGrid>
441
498
  ```
442
499
 
443
- Contracts (see the design plan under `docs/plans/` for the full bounding theorem):
500
+ Contracts:
444
501
 
502
+ - Bounding contract (both axes): the anchored coordinates the grid writes to the DOM — cell and
503
+ row offsets and the residual transforms — stay in the full-precision band while
504
+ `z × (ANCHOR_REBASE_DISTANCE + windowSpan) <= 2^24`, where `z` is the ancestor `scale(z)`,
505
+ `ANCHOR_REBASE_DISTANCE` is 2^20 px and `windowSpan <= viewport + (2 × overscan + 2) × MAX_TRACK_SIZE`
506
+ is the rendered window. The next two contracts are its premises (the z ≈ 5.3 they yield assumes
507
+ a viewport of at most 2^13 px).
445
508
  - `getRowHeight` / `getColWidth` return integer px, `0` = hidden, `<= MAX_TRACK_SIZE`
446
509
  (2^18 px) — oversized tracks fail fast with a `RangeError` (a single unbounded track would
447
510
  pierce the measured browser layout wall at 2^25 px).
@@ -459,11 +522,18 @@ Contracts (see the design plan under `docs/plans/` for the full bounding theorem
459
522
  - Row-side parity carries: `horizontalKeyInputs` / `horizontalKeyStep` (arrow keys reach the
460
523
  grid-owned horizontal axis), `contentInsets`, `background`, `onRowFocus` /
461
524
  `focusRowAtIndex`, and `behaviorOptions.defaultColWidth` (explicit Fenwick baseValue — skips
462
- width sampling). The full member-by-member classification lives in
463
- `docs/specs/2026.09.01 [AI] virtualscroll-virtual-grid.md`.
525
+ width sampling). Deliberately not offered: `initialScrollIndex` / `initialScrollOffset` (use
526
+ `initialScrollAnchor`), `onWheelHorizontal` / `onPanHorizontal` (the grid owns its horizontal
527
+ axis and consumes those deltas itself), and on the handle `scrollToIndex` (use `scrollToCell`)
528
+ and `getFenwickTreeTotalHeight` / `getFenwickSize` (use `getContentSize` and the counts you pass).
464
529
  - `locale` / `labels` (see [Localization](#localization)) are forwarded to BOTH the embedded
465
530
  `VirtualScroll` (vertical arrows and the "No items" empty state shown for 0 rows, an all-frozen row
466
531
  set or a degenerate band) and the horizontal `ScrollBar` (left / right arrows).
532
+ - `scrollBarOptions`: the bar-local members — `width`, `enableThumbDrag`, `enableTrackClick`,
533
+ `enableArrowButtons` and `enableArrowButtonTabStops` — apply to BOTH bars alike, so no setting
534
+ covers only half of the grid. `tapScrollCircleOptions` configures the single two-axis circle;
535
+ `renderThumbOverlay` (fed with visible row indices) and `enableScrollToTopBottomButtons` are
536
+ row-axis features of the embedded `VirtualScroll`.
467
537
  - Frozen leading columns (v3.3.0): `frozenLeadingCols` pins the first F columns as a static
468
538
  band OUTSIDE the anchor machinery (direct tree-absolute lefts; scroll cells live inside a
469
539
  static clip whose inner carries the `residual - W_F` origin-shift transform). Integer in
@@ -503,7 +573,7 @@ Contracts (see the design plan under `docs/plans/` for the full bounding theorem
503
573
  the tree height H_T). Band rows reuse the normal row renderer, so every corner of the
504
574
  3 x 3 region grid comes for free. Integers in `[0, MAX_FROZEN_TRAILING_COLS]` /
505
575
  `[0, MAX_FROZEN_TRAILING_ROWS]` (128) — `RangeError` otherwise; the dynamic clamp is
506
- `min(T, count - effectiveLeading)`: the LEADING band wins the count space (ADR-19-1), and
576
+ `min(T, count - effectiveLeading)`: the LEADING band wins the count space, and
507
577
  when the leading + trailing extents exceed the viewport, occluded trailing cells cannot be
508
578
  scrolled into view (a documented clamp — `scrollToCell` / `initialScrollAnchor` targeting a
509
579
  trailing track stay no-ops on that axis, the column no-op leaving any armed column anchor in
@@ -629,6 +699,7 @@ exists in the DOM.
629
699
  | `enableThumbDrag` | `boolean` | Enable dragging the scrollbar thumb (default: true) |
630
700
  | `enableTrackClick` | `boolean` | Enable clicking the scrollbar track (default: true) |
631
701
  | `enableArrowButtons` | `boolean` | Enable arrow buttons on the scrollbar (default: true) |
702
+ | `enableArrowButtonTabStops` | `boolean` | Keep the two arrow buttons in the Tab order (default: true). Set `false` when your app already owns keyboard scrolling of the list: the arrows then get `tabIndex={-1}` and stay pointer-operable and named. See [Scrollbar arrows and the Tab order](#scrollbar-arrows-and-the-tab-order) |
632
703
  | `enableScrollToTopBottomButtons` | `boolean` | Enable the auto-hiding Top/Bottom pills (texts from `labels.scrollToTop` / `labels.scrollToBottom`; default: false) |
633
704
  | `renderThumbOverlay` | `(props: ScrollBarThumbOverlayRenderProps) => ReactNode` | Render prop to anchor custom UI near the scrollbar thumb |
634
705
  | `tapScrollCircleOptions` | `ScrollBarTapCircleOptions` | Customization for the auxiliary tap scroll circle |
@@ -80,6 +80,40 @@ export type ScrollBarProps = {
80
80
  enableTrackClick?: boolean;
81
81
  /** Whether arrow buttons control the scroll position. / 矢印ボタンによるスクロール操作を許可するかどうか。 */
82
82
  enableArrowButtons?: boolean;
83
+ /**
84
+ * Whether the two arrow buttons are Tab stops (default `true`).
85
+ *
86
+ * `false` renders both with `tabIndex={-1}`, which takes them out of the sequential focus order
87
+ * and changes nothing else: pointer presses and press-and-hold repeat, the accessible names and
88
+ * Enter / Space on an arrow focused from script all keep working. The arrows are descendants of
89
+ * the `role="scrollbar"` root, whose children ARIA 1.2 makes presentational, so whether assistive
90
+ * technology lists them as buttons of their own is the browser's choice (Chromium does); this
91
+ * option changes nothing about that. Set it to `false` when the host already owns keyboard
92
+ * scrolling of this viewport (roving row focus with Arrow / Page / Home / End, a grid keyboard
93
+ * model): the arrows then duplicate that path and cost every keyboard user two extra Tab presses
94
+ * per bar — native scrollbars are never Tab stops either. The default stays `true` because
95
+ * without such a host model the arrows are the only scrolling control a keyboard user can reach
96
+ * with Tab: `ScrollPane` / `VirtualScroll` move their content by transform, so there is no native
97
+ * scroller the browser could make focusable, and their rows are not Tab stops. No effect while
98
+ * the arrows are disabled (`enableArrowButtons: false`, or nothing to scroll) — a disabled button
99
+ * is never focusable.
100
+ *
101
+ * 矢印ボタン 2 個を Tab の止まり先にするかどうか (既定 `true`)。
102
+ *
103
+ * `false` は両方を `tabIndex={-1}` で描画し、順次フォーカス移動の順序から外すだけの指定。
104
+ * ポインタ押下と長押しリピート、アクセシブルネーム、スクリプトからフォーカスした矢印での
105
+ * Enter / Space はすべて維持。矢印は `role="scrollbar"` のルートの子孫で、ARIA 1.2 はその子を
106
+ * presentational とするため、支援技術が矢印を独立したボタンとして示すかどうかはブラウザの選択
107
+ * (Chromium は示す) であり、本オプションはそこに関与しない。ホストがこのビューポートのキーボード
108
+ * スクロールを既に持つ場合 (行のロービングフォーカスと矢印 / Page / Home / End、グリッドのキーボードモデル) に
109
+ * `false` を指定 — 矢印はその経路の重複となり、キーボード利用者にバー 1 本あたり 2 回の余分な Tab を
110
+ * 課すため (ネイティブのスクロールバーも Tab の止まり先にならない)。既定を `true` に据え置く理由は、
111
+ * ホスト側のモデルが無ければ矢印がキーボード利用者の Tab で届く唯一のスクロール操作部品であること
112
+ * (`ScrollPane` / `VirtualScroll` はコンテンツを transform で動かすため、ブラウザがフォーカス可能に
113
+ * できるネイティブのスクロール領域が無く、行も Tab の止まり先ではない)。矢印が無効な間
114
+ * (`enableArrowButtons: false` またはスクロール不要) は効果なし — disabled のボタンはそもそもフォーカス不能。
115
+ */
116
+ enableArrowButtonTabStops?: boolean;
83
117
  /** Whether the scrollbar is horizontal. / スクロールバーが水平かどうか。 */
84
118
  horizontal?: boolean;
85
119
  /**
@@ -266,5 +300,5 @@ export declare const computeAutoTapScrollMaxSpeedMultiplier: (itemCount?: number
266
300
  *
267
301
  * カスタムスクロールバーコンポーネント。
268
302
  */
269
- export declare const ScrollBar: ({ contentSize, viewportSize, scrollPosition, onScroll, enableThumbDrag, enableTrackClick, enableArrowButtons, horizontal, enableHorizontalTapCircle, stretchMainSize, scrollBarWidth, className, ariaControls, tapScrollCircleOptions, itemCount, renderThumbOverlay, visibleStartIndex, visibleEndIndex, locale, labels, }: ScrollBarProps) => import("react").JSX.Element;
303
+ export declare const ScrollBar: ({ contentSize, viewportSize, scrollPosition, onScroll, enableThumbDrag, enableTrackClick, enableArrowButtons, enableArrowButtonTabStops, horizontal, enableHorizontalTapCircle, stretchMainSize, scrollBarWidth, className, ariaControls, tapScrollCircleOptions, itemCount, renderThumbOverlay, visibleStartIndex, visibleEndIndex, locale, labels, }: ScrollBarProps) => import("react").JSX.Element;
270
304
  export {};
@@ -80,6 +80,40 @@ export type ScrollBarProps = {
80
80
  enableTrackClick?: boolean;
81
81
  /** Whether arrow buttons control the scroll position. / 矢印ボタンによるスクロール操作を許可するかどうか。 */
82
82
  enableArrowButtons?: boolean;
83
+ /**
84
+ * Whether the two arrow buttons are Tab stops (default `true`).
85
+ *
86
+ * `false` renders both with `tabIndex={-1}`, which takes them out of the sequential focus order
87
+ * and changes nothing else: pointer presses and press-and-hold repeat, the accessible names and
88
+ * Enter / Space on an arrow focused from script all keep working. The arrows are descendants of
89
+ * the `role="scrollbar"` root, whose children ARIA 1.2 makes presentational, so whether assistive
90
+ * technology lists them as buttons of their own is the browser's choice (Chromium does); this
91
+ * option changes nothing about that. Set it to `false` when the host already owns keyboard
92
+ * scrolling of this viewport (roving row focus with Arrow / Page / Home / End, a grid keyboard
93
+ * model): the arrows then duplicate that path and cost every keyboard user two extra Tab presses
94
+ * per bar — native scrollbars are never Tab stops either. The default stays `true` because
95
+ * without such a host model the arrows are the only scrolling control a keyboard user can reach
96
+ * with Tab: `ScrollPane` / `VirtualScroll` move their content by transform, so there is no native
97
+ * scroller the browser could make focusable, and their rows are not Tab stops. No effect while
98
+ * the arrows are disabled (`enableArrowButtons: false`, or nothing to scroll) — a disabled button
99
+ * is never focusable.
100
+ *
101
+ * 矢印ボタン 2 個を Tab の止まり先にするかどうか (既定 `true`)。
102
+ *
103
+ * `false` は両方を `tabIndex={-1}` で描画し、順次フォーカス移動の順序から外すだけの指定。
104
+ * ポインタ押下と長押しリピート、アクセシブルネーム、スクリプトからフォーカスした矢印での
105
+ * Enter / Space はすべて維持。矢印は `role="scrollbar"` のルートの子孫で、ARIA 1.2 はその子を
106
+ * presentational とするため、支援技術が矢印を独立したボタンとして示すかどうかはブラウザの選択
107
+ * (Chromium は示す) であり、本オプションはそこに関与しない。ホストがこのビューポートのキーボード
108
+ * スクロールを既に持つ場合 (行のロービングフォーカスと矢印 / Page / Home / End、グリッドのキーボードモデル) に
109
+ * `false` を指定 — 矢印はその経路の重複となり、キーボード利用者にバー 1 本あたり 2 回の余分な Tab を
110
+ * 課すため (ネイティブのスクロールバーも Tab の止まり先にならない)。既定を `true` に据え置く理由は、
111
+ * ホスト側のモデルが無ければ矢印がキーボード利用者の Tab で届く唯一のスクロール操作部品であること
112
+ * (`ScrollPane` / `VirtualScroll` はコンテンツを transform で動かすため、ブラウザがフォーカス可能に
113
+ * できるネイティブのスクロール領域が無く、行も Tab の止まり先ではない)。矢印が無効な間
114
+ * (`enableArrowButtons: false` またはスクロール不要) は効果なし — disabled のボタンはそもそもフォーカス不能。
115
+ */
116
+ enableArrowButtonTabStops?: boolean;
83
117
  /** Whether the scrollbar is horizontal. / スクロールバーが水平かどうか。 */
84
118
  horizontal?: boolean;
85
119
  /**
@@ -266,6 +300,6 @@ export declare const computeAutoTapScrollMaxSpeedMultiplier: (itemCount?: number
266
300
  *
267
301
  * カスタムスクロールバーコンポーネント。
268
302
  */
269
- export declare const ScrollBar: ({ contentSize, viewportSize, scrollPosition, onScroll, enableThumbDrag, enableTrackClick, enableArrowButtons, horizontal, enableHorizontalTapCircle, stretchMainSize, scrollBarWidth, className, ariaControls, tapScrollCircleOptions, itemCount, renderThumbOverlay, visibleStartIndex, visibleEndIndex, locale, labels, }: ScrollBarProps) => import("react").JSX.Element;
303
+ export declare const ScrollBar: ({ contentSize, viewportSize, scrollPosition, onScroll, enableThumbDrag, enableTrackClick, enableArrowButtons, enableArrowButtonTabStops, horizontal, enableHorizontalTapCircle, stretchMainSize, scrollBarWidth, className, ariaControls, tapScrollCircleOptions, itemCount, renderThumbOverlay, visibleStartIndex, visibleEndIndex, locale, labels, }: ScrollBarProps) => import("react").JSX.Element;
270
304
  export {};
271
305
  //# sourceMappingURL=ScrollBar.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollBar.d.ts","sourceRoot":"","sources":["../src/ScrollBar.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScrollBar.d.ts","sourceRoot":"","sources":["../src/ScrollBar.tsx"],"names":[],"mappings":"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"}