@aiquants/virtualscroll 2.2.0 → 2.4.0

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,81 @@
2
2
 
3
3
  All notable changes to `@aiquants/virtualscroll` are documented here.
4
4
 
5
+ ## 2.4.0 (2026-08-19)
6
+
7
+ **帯の自己計測 (`viewportSize` の optional 化)。** 自分の高さを自分で測れるコンポーネントが消費側に
8
+ 自分の高さを渡させていた責務の逆転を解消します。既存消費者は `viewportSize` を渡し続ければ**現行どおり**
9
+ 動作します (非破壊)。
10
+
11
+ ### Added
12
+
13
+ - **`viewportSize` を省略できるようになりました** (`VirtualScroll` / `ScrollPane`)。省略時はペインが
14
+ `.aqvs-scroll-pane-content` の実高さを `ResizeObserver` で追跡し、クリップ窓・最大スクロール位置・
15
+ つまみ写像・描画枚数・スクロール可否のすべてがそれに追従します。
16
+
17
+ ```tsx
18
+ // ホストが高さを所有し、VirtualScroll がそれを埋める
19
+ <div className="min-h-0 flex-1">
20
+ <VirtualScroll itemCount={n} getItem={getItem} getItemHeight={getItemHeight}>{renderRow}</VirtualScroll>
21
+ </div>
22
+ ```
23
+
24
+ ホスト側がルート要素の高さを確定させること (`h-full` / `flex-1` + `min-h-0` / 明示 px /
25
+ `position: absolute` など) が前提です。高さが auto のホストでは帯が 0 のままになるため警告します。
26
+ `viewportSize` を明示する正当なケースは「帯を計測ではなく**算出**で知っている」場合のみです
27
+ (例: ドロップダウンが件数 × 行高から高さを決める)。
28
+ - **`ScrollPane` に `onViewportSizeChange` を追加。** 自己計測した帯の高さを所有者へ通知します
29
+ (`viewportSize` 指定時は呼ばれません)。`VirtualScroll` は描画枚数とアライン計算にこの値を使います。
30
+
31
+ ### Fixed
32
+
33
+ - **`viewportSize` と実際の帯が食い違ったときに何も検知できなかった問題** — 食い違いは例外も視覚的な
34
+ 破綻も出さずに 5 つの導出値を壊します (はみ出し / 死に帯 / 末尾へ永久に到達できない /
35
+ つまみが視野外へ消える / ホイールとドラッグの無効化)。`Logger.warn` で 2 種類を通知するようにしました:
36
+ 明示値がルートの実帯と 1px を超えてずれている場合と、自己計測でレイアウト済みなのに帯が 0 の場合です
37
+ (非表示 = `offsetParent === null` は正常な未計測状態として黙ります)。同じ内容は繰り返し警告しません。
38
+
39
+ ### Changed
40
+
41
+ - **DOM 契約 (追加のみ)**: 自己計測モードのとき `.aqvs-scroll-pane` に `data-self-measured="true"` が付き、
42
+ コンテンツ要素のインライン `height` は**書かれなくなります** (CSS の `height: 100%` がレイアウトを所有)。
43
+ `viewportSize` を渡している既存消費者の DOM は不変です。
44
+ - **CSS (追加のみ)**: `.aqvs-scroll-pane[data-self-measured="true"] { height: 100% }` を追加しました。
45
+ ルート要素は元々高さを持たず、明示モードではコンテンツのインライン高さに押し広げられて決まっていた
46
+ ため、高さを書かない自己計測モードではこの規則が無いと帯が 0 に潰れます (実ブラウザで実測)。
47
+ 明示モードには適用しないため、既存消費者のルート要素の箱は変わりません。
48
+
49
+ ## 2.3.0 (2026-08-19)
50
+
51
+ DOM 契約が変わるため minor: `.aqvs-scroll-to-edge-overlay` は非表示中に `inert` を、
52
+ `.aqvs-scroll-to-edge-button` は常時 `tabindex` を出力するようになります (2.2.0 でスクロールバーの
53
+ 非表示表現を `data-visible` へ移管したときと同じ基準)。表示中の見た目・操作は一切変わりません。
54
+
55
+ ### Fixed
56
+
57
+ - **非表示の Top/Bottom ピルがタブ順に残り、見えないフォーカス停止点になっていた問題 (全ホスト)** —
58
+ `scrollBarOptions.enableScrollToTopBottomButtons: true` のとき、ピルは非表示状態でも DOM に残ります
59
+ (フェードのためにアンマウントしない設計)。ところが非表示は `opacity: 0` だけで表現しており、
60
+ `opacity` はフォーカス可能性に影響しないため、**キーボード操作者は一覧を通過するたびに「何も見えないのに
61
+ フォーカスが止まる」箇所を必ず 1 つ踏んでいました**。しかもフォーカスリング (`:focus-visible`) は
62
+ `opacity: 0` の要素に描かれるため見えず、その状態で Enter / Space を押すと一覧が先頭または末尾へ飛びます
63
+ (CSS の `pointer-events: none` はポインタ操作しか止めず、キーボードからの活性化は素通しになる)。
64
+ 未スクロールの初期状態は `scrollDirection === null` で Bottom 枝が描かれるため、**ページを開いた直後から
65
+ 常に踏める**状態でした。消費側からは回避できません (ピルはコンポーネント内部で描画され、属性を足す口が無い)。
66
+
67
+ オーバーレイへ `inert` (焦点・ヒットテスト・アクセシビリティツリー露出を一括で外す) を、ピルへ
68
+ `tabIndex={isVisible ? 0 : -1}` (`inert` 未実装ブラウザ向けの下限) を出力するようにしました。どちらも
69
+ `isVisible` から導出するため値が食い違うことはありません。CSS の `pointer-events: none` はポインタ軸の
70
+ 下限として維持します (配布 CSS 未読込のホストでは `inert` が、`inert` 未実装ブラウザでは CSS が
71
+ 互いの穴を埋める)。表示中の見た目・操作・DOM 構造は一切変わりません。
72
+
73
+ ### Changed
74
+
75
+ - **スクロールバーの DOM 契約 (追加のみ)**: `.aqvs-scroll-to-edge-overlay` は非表示中に `inert` を、
76
+ `.aqvs-scroll-to-edge-button` は常時 `tabindex` を出力します。ピルの DOM スナップショットを持つ利用側は
77
+ 更新が必要です。`inert` を真偽値プロップとして扱うため **React 19 以降が前提**です
78
+ (React 18 以前では `inert="false"` となり、非表示でないときに誤って有効化されます)。
79
+
5
80
  ## 2.2.0 (2026-08-15)
6
81
 
7
82
  **リセット非依存 (preflight independence)。** 2.1.0 の Top/Bottom ボタン修正と同じ根本原因 —
package/README.md CHANGED
@@ -82,7 +82,6 @@ function App() {
82
82
  itemCount={items.length}
83
83
  getItem={getItem}
84
84
  getItemHeight={getItemHeight}
85
- viewportSize={400}
86
85
  overscanCount={5}
87
86
  >
88
87
  {(item, index) => (
@@ -105,6 +104,31 @@ function App() {
105
104
  }
106
105
  ```
107
106
 
107
+ ## Sizing
108
+
109
+ `viewportSize` is **optional and best omitted**. When it is absent the component measures its own band
110
+ (the content element, via `ResizeObserver`) and every derived value follows automatically.
111
+
112
+ ```tsx
113
+ // The host owns the height; VirtualScroll fills it.
114
+ <div className="min-h-0 flex-1">
115
+ <VirtualScroll itemCount={n} getItem={getItem} getItemHeight={getItemHeight}>{renderRow}</VirtualScroll>
116
+ </div>
117
+ ```
118
+
119
+ **The host must establish a definite height** (`h-full`, `flex-1` + `min-h-0`, an explicit px height,
120
+ `position: absolute`, …). With an auto-height host the band stays 0 and the package logs a warning —
121
+ there is nothing to measure. In self-measured mode the root carries `data-self-measured="true"` and the
122
+ packaged rule `.aqvs-scroll-pane[data-self-measured="true"] { height: 100% }` stretches it to the host,
123
+ so the stylesheet import is required for this mode as well.
124
+
125
+ **Pass `viewportSize` only when the band is known by calculation, not measurement** — a dropdown whose
126
+ height comes from row count × row height, for example. If you pass a value that disagrees with the real
127
+ band by more than 1px, the package warns: the clip window, the max scroll position, the thumb mapping,
128
+ the rendered row count and scrollability all derive from it, so all five would be silently wrong (rows
129
+ spilling over the next element, a dead band at the bottom, an end you can never reach, a thumb that
130
+ leaves the viewport, or a list that ignores the wheel entirely).
131
+
108
132
  ## Horizontal Scrolling
109
133
 
110
134
  `VirtualScroll` virtualizes and scrolls the **vertical** axis only. To add a horizontal axis — e.g. a
@@ -133,7 +157,7 @@ function Grid() {
133
157
  return (
134
158
  <div style={{ ['--hx' as string]: `${hscroll}px`, display: 'flex', flexDirection: 'column' }}>
135
159
  <div style={{ height: 440 }}>
136
- <VirtualScroll itemCount={rows.length} getItem={getItem} getItemHeight={getItemHeight} viewportSize={440} onWheelHorizontal={onWheelHorizontal}>
160
+ <VirtualScroll itemCount={rows.length} getItem={getItem} getItemHeight={getItemHeight} onWheelHorizontal={onWheelHorizontal}>
137
161
  {(row) => (
138
162
  <div style={{ display: 'flex' }}>
139
163
  <div style={{ width: 180, flexShrink: 0 }}>{row.label}{/* frozen column */}</div>
@@ -204,7 +228,7 @@ exists in the DOM.
204
228
  | `itemCount` | `number` | ✅ | Total number of items |
205
229
  | `getItem` | `(index: number) => T` | ✅ | Function to get item at index |
206
230
  | `getItemHeight` | `(index: number) => number` | ✅ | Function to get item height |
207
- | `viewportSize` | `number` | | Height of the visible area |
231
+ | `viewportSize` | `number` | | Height of the visible band. **Omit it** — the component then measures its host with a `ResizeObserver`. Pass it only when you know the band by calculation rather than measurement (e.g. a dropdown sized from row count × row height). See [Sizing](#sizing) |
208
232
  | `overscanCount` | `number` | ❌ | Number of items to render outside viewport (default: 15) |
209
233
  | `className` | `string` | ❌ | CSS class name. Lands on the scroll root (`.aqvs-scroll-pane`) — see [Custom Scrollbar Styling](#custom-scrollbar-styling) |
210
234
  | `getItemKey` | `(index: number) => React.Key` | ❌ | Stable React key per index (defaults to the index) |
@@ -366,7 +390,6 @@ function AdvancedExample() {
366
390
  itemCount={items.length}
367
391
  getItem={getItem}
368
392
  getItemHeight={getItemHeight}
369
- viewportSize={400}
370
393
  onRangeChange={handleRangeChange}
371
394
  scrollBarOptions={{
372
395
  renderThumbOverlay: renderThumbOverlay
@@ -437,7 +460,11 @@ Three consequences are worth knowing:
437
460
  through the props; to re-round the corners use `!important`.
438
461
  - **Do not hand-roll the hidden state.** When the content fits the viewport, the bar and the thumb wrapper
439
462
  carry `data-visible="false"` and the packaged rule hides them (`opacity: 0; pointer-events: none`). If
440
- you override `opacity` on `.aqvs-scrollbar`, scope it to `[data-visible="true"]`.
463
+ you override `opacity` on `.aqvs-scrollbar`, scope it to `[data-visible="true"]`. The same applies to the
464
+ auto-hiding Top/Bottom pills — and there the hidden state is more than styling: `.aqvs-scroll-to-edge-overlay`
465
+ carries `inert` while hidden (and the pill `tabindex="-1"`) so it is not a phantom tab stop for keyboard
466
+ users. Forcing `opacity: 1` on the hidden overlay therefore paints a pill that cannot be clicked or focused.
467
+ Scope such rules to `[data-visible="true"]` as well.
441
468
 
442
469
  The parts you are most likely to target: `.aqvs-scroll-pane` (root), `.aqvs-scroll-pane-content` (row
443
470
  viewport), `.aqvs-scrollbar` (+ `-vertical` / `-horizontal`), `.aqvs-scrollbar-track`,
@@ -472,7 +499,6 @@ export function UltraFastExample() {
472
499
  itemCount={items.length}
473
500
  getItem={(index) => items[index]}
474
501
  getItemHeight={() => 42}
475
- viewportSize={480}
476
502
  scrollBarOptions={{
477
503
  tapScrollCircleOptions: {
478
504
  maxSpeedMultiplier: 80, // Optional: override adaptive speed when needed
@@ -19,8 +19,32 @@ export type ScrollPaneProps = {
19
19
  children: (scrollPosition: number) => React.ReactNode;
20
20
  /** The total size of the content. / コンテンツの総サイズ。 */
21
21
  contentSize: number;
22
- /** The size of the visible area. / 表示領域のサイズ。 */
23
- viewportSize: number;
22
+ /**
23
+ * Size of the visible band (px). Omit it to let the pane measure its own band.
24
+ * 可視帯の高さ (px)。省略するとペインが自分の帯を計測する。
25
+ *
26
+ * ❗ **省略が既定の使い方である。** この値は帯のクリップ窓・最大スクロール位置・つまみ写像・
27
+ * 描画枚数・スクロール可否のすべての基準であり、実際の帯と食い違うと 5 通りの壊れ方が
28
+ * **例外も警告も出さずに**発生する (はみ出し / 死に帯 / 末尾へ到達不能 / つまみが視野外へ /
29
+ * ホイールとドラッグの無効化)。自分で測れるものを消費側に渡させると、同じ正解を各画面で
30
+ * 書き直すことになり、実際に推測値や定数が代入される。
31
+ *
32
+ * 省略時は `.aqvs-scroll-pane-content` の実高さ (CSS の `height: 100%` が決める) を
33
+ * `ResizeObserver` で追跡する。**ホスト側がルート要素の高さを確定させること**が前提で
34
+ * (`h-full` / `flex-1` + `min-h-0` / 明示 px / `position: absolute` など)、高さが auto の
35
+ * ホストでは帯が 0 のままになる (開発ビルドで警告する)。
36
+ *
37
+ * 明示する正当なケースは「帯の高さを計測ではなく算出で知っている」場合のみである
38
+ * (例: ドロップダウンが件数 × 行高から高さを決める)。
39
+ */
40
+ viewportSize?: number;
41
+ /**
42
+ * Notified when the self-measured viewport size changes (not called while `viewportSize` is given).
43
+ * 自己計測したビューポート高さが変化したときに通知する (`viewportSize` 指定時は呼ばれない)。
44
+ *
45
+ * 帯の数値を必要とする親 (`VirtualScroll` は描画枚数とアライン計算に使う) がこの口で受け取る。
46
+ */
47
+ onViewportSizeChange?: (viewportSize: number) => void;
24
48
  /** The width of the scrollbar. / スクロールバーの幅。 */
25
49
  scrollBarWidth?: number;
26
50
  /** Whether grabbing the scrollbar thumb is allowed. / スクロールバーのつまみ操作を許可するかどうか。 */
@@ -19,8 +19,32 @@ export type ScrollPaneProps = {
19
19
  children: (scrollPosition: number) => React.ReactNode;
20
20
  /** The total size of the content. / コンテンツの総サイズ。 */
21
21
  contentSize: number;
22
- /** The size of the visible area. / 表示領域のサイズ。 */
23
- viewportSize: number;
22
+ /**
23
+ * Size of the visible band (px). Omit it to let the pane measure its own band.
24
+ * 可視帯の高さ (px)。省略するとペインが自分の帯を計測する。
25
+ *
26
+ * ❗ **省略が既定の使い方である。** この値は帯のクリップ窓・最大スクロール位置・つまみ写像・
27
+ * 描画枚数・スクロール可否のすべての基準であり、実際の帯と食い違うと 5 通りの壊れ方が
28
+ * **例外も警告も出さずに**発生する (はみ出し / 死に帯 / 末尾へ到達不能 / つまみが視野外へ /
29
+ * ホイールとドラッグの無効化)。自分で測れるものを消費側に渡させると、同じ正解を各画面で
30
+ * 書き直すことになり、実際に推測値や定数が代入される。
31
+ *
32
+ * 省略時は `.aqvs-scroll-pane-content` の実高さ (CSS の `height: 100%` が決める) を
33
+ * `ResizeObserver` で追跡する。**ホスト側がルート要素の高さを確定させること**が前提で
34
+ * (`h-full` / `flex-1` + `min-h-0` / 明示 px / `position: absolute` など)、高さが auto の
35
+ * ホストでは帯が 0 のままになる (開発ビルドで警告する)。
36
+ *
37
+ * 明示する正当なケースは「帯の高さを計測ではなく算出で知っている」場合のみである
38
+ * (例: ドロップダウンが件数 × 行高から高さを決める)。
39
+ */
40
+ viewportSize?: number;
41
+ /**
42
+ * Notified when the self-measured viewport size changes (not called while `viewportSize` is given).
43
+ * 自己計測したビューポート高さが変化したときに通知する (`viewportSize` 指定時は呼ばれない)。
44
+ *
45
+ * 帯の数値を必要とする親 (`VirtualScroll` は描画枚数とアライン計算に使う) がこの口で受け取る。
46
+ */
47
+ onViewportSizeChange?: (viewportSize: number) => void;
24
48
  /** The width of the scrollbar. / スクロールバーの幅。 */
25
49
  scrollBarWidth?: number;
26
50
  /** Whether grabbing the scrollbar thumb is allowed. / スクロールバーのつまみ操作を許可するかどうか。 */
@@ -1 +1 @@
1
- {"version":3,"file":"ScrollPane.d.ts","sourceRoot":"","sources":["../src/ScrollPane.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"ScrollPane.d.ts","sourceRoot":"","sources":["../src/ScrollPane.tsx"],"names":[],"mappings":"AAGA,OAAO,EAAa,KAAK,yBAAyB,EAAE,KAAK,gCAAgC,EAA2B,MAAM,iBAAiB,CAAA;AAG3I;;;;GAIG;AACH,MAAM,MAAM,uBAAuB,GAAG;IAClC,GAAG,CAAC,EAAE,MAAM,CAAA;IACZ,MAAM,CAAC,EAAE,MAAM,CAAA;CAClB,CAAA;AAED,MAAM,MAAM,eAAe,GAAG;IAC1B;;;;;;OAMG;IACH,QAAQ,EAAE,CAAC,cAAc,EAAE,MAAM,KAAK,KAAK,CAAC,SAAS,CAAA;IACrD,mDAAmD;IACnD,WAAW,EAAE,MAAM,CAAA;IACnB;;;;;;;;;;;;;;;;;OAiBG;IACH,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB;;;;;OAKG;IACH,oBAAoB,CAAC,EAAE,CAAC,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IACrD,+CAA+C;IAC/C,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB,iFAAiF;IACjF,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,CAAC,cAAc,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,KAAK,IAAI,CAAA;IACjE,mEAAmE;IACnE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,+LAA+L;IAC/L,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,2DAA2D;IAC3D,KAAK,CAAC,EAAE,KAAK,CAAC,aAAa,CAAA;IAC3B,wFAAwF;IACxF,UAAU,CAAC,EAAE,KAAK,CAAC,SAAS,CAAA;IAC5B,6DAA6D;IAC7D,sBAAsB,CAAC,EAAE,yBAAyB,CAAA;IAClD,+DAA+D;IAC/D,cAAc,CAAC,EAAE,wBAAwB,CAAA;IACzC,yEAAyE;IACzE,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,2FAA2F;IAC3F,gBAAgB,CAAC,EAAE,OAAO,CAAA;IAC1B,mFAAmF;IACnF,kBAAkB,CAAC,EAAE,OAAO,CAAA;IAC5B,uFAAuF;IACvF,iBAAiB,CAAC,EAAE,OAAO,CAAA;IAC3B;;;;;;;;;;;;;;OAcG;IACH,iBAAiB,CAAC,EAAE,SAAS,CAAC,OAAO,GAAG,KAAK,GAAG,OAAO,CAAC,EAAE,CAAA;IAC1D,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,KAAK,CAAC,SAAS,CAAA;IACjF,qGAAqG;IACrG,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B;;;;;;;OAOG;IACH,iBAAiB,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5C,4EAA4E;IAC5E,aAAa,CAAC,EAAE,uBAAuB,CAAA;IACvC,+DAA+D;IAC/D,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,8DAA8D;IAC9D,eAAe,CAAC,EAAE,MAAM,CAAA;IACxB,iGAAiG;IACjG,aAAa,CAAC,EAAE,MAAM,KAAK,CAAC,SAAS,CAAA;IACrC,6CAA6C;IAC7C,qBAAqB,CAAC,EAAE,MAAM,CAAA;IAC9B;;;;;;;;;;;;;;;;;;;OAmBG;IACH,YAAY,CAAC,EAAE,KAAK,CAAC,cAAc,GAAG;QAAE,EAAE,CAAC,EAAE,MAAM,CAAC;QAAC,IAAI,CAAC,EAAE,KAAK,CAAC,QAAQ,CAAA;KAAE,CAAA;CAC/E,CAAA;AAED,MAAM,MAAM,wBAAwB,GAAG;IACnC,sEAAsE;IACtE,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,4EAA4E;IAC5E,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,uGAAuG;IACvG,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B,uEAAuE;IACvE,sBAAsB,CAAC,EAAE,MAAM,CAAA;CAClC,CAAA;AAiFD,MAAM,MAAM,gBAAgB,GAAG;IAC3B,QAAQ,EAAE,CAAC,WAAW,EAAE,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,KAAK,MAAM,CAAC,KAAK,MAAM,CAAA;IACtE,iBAAiB,EAAE,MAAM,MAAM,CAAA;IAC/B,cAAc,EAAE,MAAM,MAAM,CAAA;IAC5B,eAAe,EAAE,MAAM,MAAM,CAAA;CAChC,CAAA;AAED;;;;GAIG;AACH,eAAO,MAAM,UAAU,8GAurCtB,CAAA"}
@@ -152,7 +152,21 @@ export type VirtualScrollProps<T> = {
152
152
  * さもないとキャッシュ済み高さが別のアイテムを指すインデックスに残る。
153
153
  */
154
154
  getItemHeight: (index: number) => number;
155
- viewportSize: number;
155
+ /**
156
+ * Size of the visible band (px). Omit it to let the component measure its own band.
157
+ * 可視帯の高さ (px)。省略するとコンポーネントが自分の帯を計測する。
158
+ *
159
+ * ❗ **省略が既定の使い方である。** この値は帯のクリップ窓・最大スクロール位置・つまみ写像・
160
+ * 描画枚数・スクロール可否のすべての基準であり、実際の帯と食い違うと 5 通りの壊れ方が
161
+ * **例外も警告も出さずに**発生する。自分で測れるものを消費側に渡させると、同じ正解を各画面で
162
+ * 書き直すことになり、実際に推測値や定数が代入される (詳細は `ScrollPaneProps.viewportSize`)。
163
+ *
164
+ * 省略時はホスト要素が高さを確定させていること (`h-full` / `flex-1` + `min-h-0` / 明示 px など)
165
+ * が前提で、高さが auto のホストでは帯が 0 のままになる (`Logger.warn` で警告する)。
166
+ * 明示する正当なケースは「帯の高さを計測ではなく算出で知っている」場合のみである
167
+ * (例: ドロップダウンが件数 × 行高から高さを決める)。
168
+ */
169
+ viewportSize?: number;
156
170
  overscanCount?: number;
157
171
  className?: string;
158
172
  /** Test id emitted as data-testid on the scroll root (DOM hooks must use data-* attributes, never class selectors). / スクロールルートに data-testid として出力されるテスト ID (DOM フックはクラスセレクタでなく data-* 属性を使う)。 */
@@ -152,7 +152,21 @@ export type VirtualScrollProps<T> = {
152
152
  * さもないとキャッシュ済み高さが別のアイテムを指すインデックスに残る。
153
153
  */
154
154
  getItemHeight: (index: number) => number;
155
- viewportSize: number;
155
+ /**
156
+ * Size of the visible band (px). Omit it to let the component measure its own band.
157
+ * 可視帯の高さ (px)。省略するとコンポーネントが自分の帯を計測する。
158
+ *
159
+ * ❗ **省略が既定の使い方である。** この値は帯のクリップ窓・最大スクロール位置・つまみ写像・
160
+ * 描画枚数・スクロール可否のすべての基準であり、実際の帯と食い違うと 5 通りの壊れ方が
161
+ * **例外も警告も出さずに**発生する。自分で測れるものを消費側に渡させると、同じ正解を各画面で
162
+ * 書き直すことになり、実際に推測値や定数が代入される (詳細は `ScrollPaneProps.viewportSize`)。
163
+ *
164
+ * 省略時はホスト要素が高さを確定させていること (`h-full` / `flex-1` + `min-h-0` / 明示 px など)
165
+ * が前提で、高さが auto のホストでは帯が 0 のままになる (`Logger.warn` で警告する)。
166
+ * 明示する正当なケースは「帯の高さを計測ではなく算出で知っている」場合のみである
167
+ * (例: ドロップダウンが件数 × 行高から高さを決める)。
168
+ */
169
+ viewportSize?: number;
156
170
  overscanCount?: number;
157
171
  className?: string;
158
172
  /** Test id emitted as data-testid on the scroll root (DOM hooks must use data-* attributes, never class selectors). / スクロールルートに data-testid として出力されるテスト ID (DOM フックはクラスセレクタでなく data-* 属性を使う)。 */
@@ -1 +1 @@
1
- {"version":3,"file":"VirtualScroll.d.ts","sourceRoot":"","sources":["../src/VirtualScroll.tsx"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"VirtualScroll.d.ts","sourceRoot":"","sources":["../src/VirtualScroll.tsx"],"names":[],"mappings":"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"}