@aiquants/virtualscroll 1.18.0 → 1.18.3
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/README.md +85 -16
- package/dist/ScrollBar.d.cts +100 -0
- package/dist/ScrollBar.d.ts.map +1 -0
- package/dist/ScrollPane.d.cts +93 -0
- package/dist/ScrollPane.d.ts.map +1 -0
- package/dist/TapScrollCircle.d.cts +62 -0
- package/dist/TapScrollCircle.d.ts.map +1 -0
- package/dist/VirtualScroll.d.cts +155 -0
- package/dist/{src/VirtualScroll.d.ts → VirtualScroll.d.ts} +46 -3
- package/dist/VirtualScroll.d.ts.map +1 -0
- package/dist/cli.js +97 -24
- package/dist/cli.server.d.cts +13 -0
- package/dist/cli.server.d.ts +14 -0
- package/dist/cli.server.d.ts.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/{src/index.d.ts → index.d.cts} +9 -10
- package/dist/index.d.ts +10 -2
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +1862 -1352
- package/dist/{src/logger.d.ts → logger.d.cts} +48 -1
- package/dist/logger.d.ts +146 -0
- package/dist/logger.d.ts.map +1 -0
- package/dist/tapScrollCircleSampleVisual.d.cts +2 -0
- package/dist/tapScrollCircleSampleVisual.d.ts.map +1 -0
- package/dist/{src/useFenwickMapTree.d.ts → useFenwickMapTree.d.cts} +138 -16
- package/dist/useFenwickMapTree.d.ts +451 -0
- package/dist/useFenwickMapTree.d.ts.map +1 -0
- package/dist/useHeightCache.d.cts +15 -0
- package/dist/useHeightCache.d.ts.map +1 -0
- package/dist/{src/useLruCache.d.ts → useLruCache.d.cts} +8 -2
- package/dist/useLruCache.d.ts +24 -0
- package/dist/useLruCache.d.ts.map +1 -0
- package/dist/{src/utils.d.ts → utils.d.cts} +3 -1
- package/dist/utils.d.ts +15 -0
- package/dist/{src/utils.d.ts.map → utils.d.ts.map} +1 -1
- package/package.json +12 -6
- package/dist/src/ScrollBar.d.ts.map +0 -1
- package/dist/src/ScrollPane.d.ts.map +0 -1
- package/dist/src/TapScrollCircle.d.ts.map +0 -1
- package/dist/src/VirtualScroll.d.ts.map +0 -1
- package/dist/src/cli.server.d.ts +0 -2
- package/dist/src/cli.server.d.ts.map +0 -1
- package/dist/src/index.d.ts.map +0 -1
- package/dist/src/logger.d.ts.map +0 -1
- package/dist/src/tapScrollCircleSampleVisual.d.ts.map +0 -1
- package/dist/src/useFenwickMapTree.d.ts.map +0 -1
- package/dist/src/useHeightCache.d.ts.map +0 -1
- package/dist/src/useLruCache.d.ts.map +0 -1
- package/dist/virtualscroll.css +0 -1
- package/dist/vite.config.d.ts +0 -3
- package/dist/vite.config.d.ts.map +0 -1
- /package/dist/{src/ScrollBar.d.ts → ScrollBar.d.ts} +0 -0
- /package/dist/{src/ScrollPane.d.ts → ScrollPane.d.ts} +0 -0
- /package/dist/{src/TapScrollCircle.d.ts → TapScrollCircle.d.ts} +0 -0
- /package/dist/{src/tapScrollCircleSampleVisual.d.ts → tapScrollCircleSampleVisual.d.ts} +0 -0
- /package/dist/{src/useHeightCache.d.ts → useHeightCache.d.ts} +0 -0
package/README.md
CHANGED
|
@@ -10,6 +10,7 @@ High-performance virtual scrolling component for React with variable item height
|
|
|
10
10
|
- 🎯 **Precise Scrolling**: Accurate scroll positioning and smooth navigation
|
|
11
11
|
<!-- - 🔄 **LRU Caching**: Built-in cache for optimal memory usage -->
|
|
12
12
|
- 📱 **Touch Support**: Full support for touch devices
|
|
13
|
+
- ↔️ **Horizontal Delegation**: Opt-in `onWheelHorizontal` hands horizontal wheel / trackpad (and shift+wheel) gestures to the parent — build frozen-column data grids
|
|
13
14
|
- 🎨 **Customizable**: Flexible styling and theming options
|
|
14
15
|
- 🌀 **Ultrafast Tap Scroll**: Adaptive tap scroll circle that scales speed up to 120× for massive datasets
|
|
15
16
|
- 🔧 **TypeScript**: Full TypeScript support with comprehensive type definitions
|
|
@@ -24,9 +25,28 @@ yarn add @aiquants/virtualscroll
|
|
|
24
25
|
pnpm add @aiquants/virtualscroll
|
|
25
26
|
```
|
|
26
27
|
|
|
28
|
+
> **Note:** the `virtualscroll demo` CLI is for source checkouts only — the demo app is not bundled in the published npm package. To run it, clone the repository and run `pnpm install && pnpm dev` inside `demo/`.
|
|
29
|
+
|
|
27
30
|
## Basic Usage
|
|
28
31
|
|
|
32
|
+
> **Required:** import the package stylesheet once in your app. The components rely on
|
|
33
|
+
> the `.aqvs-*` layout classes shipped in this file — without it the list overflows its
|
|
34
|
+
> viewport and the scrollbar is mislaid.
|
|
35
|
+
> 必須: パッケージの CSS を一度だけ読み込んでください。レイアウトは `.aqvs-*` クラスに
|
|
36
|
+
> 依存するため、未読み込みだとビューポート外にはみ出し正しく表示されません。
|
|
37
|
+
>
|
|
38
|
+
> ```ts
|
|
39
|
+
> // In your app entry (JS/TS)
|
|
40
|
+
> import '@aiquants/virtualscroll/styles/virtualscroll.css'
|
|
41
|
+
> ```
|
|
42
|
+
> ```css
|
|
43
|
+
> /* or from your global CSS (e.g. with Tailwind) */
|
|
44
|
+
> @import '@aiquants/virtualscroll/styles/virtualscroll.css' layer(components);
|
|
45
|
+
> ```
|
|
46
|
+
|
|
29
47
|
```tsx
|
|
48
|
+
// Load the stylesheet once, e.g. in your app entry point
|
|
49
|
+
import '@aiquants/virtualscroll/styles/virtualscroll.css'
|
|
30
50
|
import { VirtualScroll } from '@aiquants/virtualscroll'
|
|
31
51
|
import { useCallback } from 'react'
|
|
32
52
|
|
|
@@ -76,21 +96,75 @@ function App() {
|
|
|
76
96
|
}
|
|
77
97
|
```
|
|
78
98
|
|
|
99
|
+
## Horizontal Scrolling
|
|
100
|
+
|
|
101
|
+
`VirtualScroll` virtualizes and scrolls the **vertical** axis only. To add a horizontal axis — e.g. a
|
|
102
|
+
data grid whose columns extend past the viewport — pass `onWheelHorizontal`. Horizontal-dominant
|
|
103
|
+
wheel / trackpad gestures (and shift+wheel) are then delegated to your handler, which drives a
|
|
104
|
+
horizontal offset you own. Vertical scrolling is untouched, and omitting the prop keeps the exact
|
|
105
|
+
previous behavior (backward compatible).
|
|
106
|
+
|
|
107
|
+
A common pattern freezes a left column and translates the remaining columns via a shared CSS
|
|
108
|
+
variable (so rows don't re-render on horizontal scroll), reusing the package's `ScrollBar` with the
|
|
109
|
+
`horizontal` prop for the bottom bar:
|
|
110
|
+
|
|
111
|
+
```tsx
|
|
112
|
+
import { ScrollBar, VirtualScroll } from '@aiquants/virtualscroll'
|
|
113
|
+
import { useCallback, useState } from 'react'
|
|
114
|
+
|
|
115
|
+
const clamp = (v: number, max: number) => Math.max(0, Math.min(v, max))
|
|
116
|
+
|
|
117
|
+
function Grid() {
|
|
118
|
+
const [hscroll, setHscroll] = useState(0)
|
|
119
|
+
const maxHScroll = /* contentWidth - visibleWidth */ 632
|
|
120
|
+
const onWheelHorizontal = useCallback((dx: number) => setHscroll((h) => clamp(h + dx, maxHScroll)), [maxHScroll])
|
|
121
|
+
|
|
122
|
+
// `--hx` on the container is inherited by every row; numeric tracks translate via CSS only.
|
|
123
|
+
return (
|
|
124
|
+
<div style={{ ['--hx' as string]: `${hscroll}px`, display: 'flex', flexDirection: 'column' }}>
|
|
125
|
+
<div style={{ height: 440 }}>
|
|
126
|
+
<VirtualScroll itemCount={rows.length} getItem={getItem} getItemHeight={getItemHeight} viewportSize={440} onWheelHorizontal={onWheelHorizontal}>
|
|
127
|
+
{(row) => (
|
|
128
|
+
<div style={{ display: 'flex' }}>
|
|
129
|
+
<div style={{ width: 180, flexShrink: 0 }}>{row.label}{/* frozen column */}</div>
|
|
130
|
+
<div style={{ flex: 1, overflow: 'hidden' }}>
|
|
131
|
+
<div style={{ transform: 'translateX(calc(-1 * var(--hx)))' }}>{/* numeric columns */}</div>
|
|
132
|
+
</div>
|
|
133
|
+
</div>
|
|
134
|
+
)}
|
|
135
|
+
</VirtualScroll>
|
|
136
|
+
</div>
|
|
137
|
+
<ScrollBar
|
|
138
|
+
horizontal
|
|
139
|
+
contentSize={1200}
|
|
140
|
+
viewportSize={568}
|
|
141
|
+
scrollPosition={hscroll}
|
|
142
|
+
onScroll={(next) => { const c = clamp(typeof next === 'function' ? next(hscroll) : next, maxHScroll); setHscroll(c); return c }}
|
|
143
|
+
/>
|
|
144
|
+
</div>
|
|
145
|
+
)
|
|
146
|
+
}
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
A runnable version lives in the demo at **`/horizontal`** (`pnpm demo:dev`), and
|
|
150
|
+
[`@aiquants/directory-tree`](../directory-tree)'s TreeGrid mode uses this exact pattern in production.
|
|
151
|
+
|
|
79
152
|
## API Reference
|
|
80
153
|
|
|
81
154
|
### VirtualScroll Props
|
|
82
155
|
|
|
83
156
|
| Prop | Type | Required | Description |
|
|
84
|
-
|
|
|
157
|
+
| --- | --- | --- | --- |
|
|
85
158
|
| `children` | `(item: T, index: number) => ReactNode` | ✅ | Render function for items |
|
|
86
159
|
| `itemCount` | `number` | ✅ | Total number of items |
|
|
87
160
|
| `getItem` | `(index: number) => T` | ✅ | Function to get item at index |
|
|
88
161
|
| `getItemHeight` | `(index: number) => number` | ✅ | Function to get item height |
|
|
89
162
|
| `viewportSize` | `number` | ✅ | Height of the visible area |
|
|
90
|
-
| `overscanCount` | `number` | ❌ | Number of items to render outside viewport (default:
|
|
163
|
+
| `overscanCount` | `number` | ❌ | Number of items to render outside viewport (default: 15) |
|
|
91
164
|
| `className` | `string` | ❌ | CSS class name |
|
|
92
165
|
| `onScroll` | `(position: number, totalHeight: number) => void` | ❌ | Scroll event handler |
|
|
93
166
|
| `onRangeChange` | `(range: VirtualScrollRange) => void` | ❌ | Range change handler |
|
|
167
|
+
| `onWheelHorizontal` | `(deltaX: number) => void` | ❌ | Opt-in horizontal wheel delegation. When set, horizontal-dominant wheel / trackpad gestures (and shift+wheel) are delegated to this handler so the parent can implement horizontal scrolling; vertical behavior is unchanged, and it is a no-op when omitted (fully backward compatible). See [Horizontal Scrolling](#horizontal-scrolling). |
|
|
94
168
|
| `background` | `ReactNode` | ❌ | Background element |
|
|
95
169
|
| `initialScrollIndex` | `number` | ❌ | Initial scroll index |
|
|
96
170
|
| `initialScrollOffset` | `number` | ❌ | Initial scroll offset |
|
|
@@ -103,7 +177,7 @@ function App() {
|
|
|
103
177
|
### VirtualScrollScrollBarOptions
|
|
104
178
|
|
|
105
179
|
| Property | Type | Description |
|
|
106
|
-
|
|
|
180
|
+
| --- | --- | --- |
|
|
107
181
|
| `width` | `number` | Width of the scrollbar |
|
|
108
182
|
| `enableThumbDrag` | `boolean` | Enable dragging the scrollbar thumb |
|
|
109
183
|
| `enableTrackClick` | `boolean` | Enable clicking the scrollbar track |
|
|
@@ -115,7 +189,7 @@ function App() {
|
|
|
115
189
|
### VirtualScrollBehaviorOptions
|
|
116
190
|
|
|
117
191
|
| Property | Type | Description |
|
|
118
|
-
|
|
|
192
|
+
| --- | --- | --- |
|
|
119
193
|
| `enablePointerDrag` | `boolean` | Enable dragging the content area to scroll |
|
|
120
194
|
| `enableKeyboardNavigation` | `boolean` | Enable keyboard navigation (default: true) |
|
|
121
195
|
| `wheelSpeedMultiplier` | `number` | Multiplier for mouse wheel scrolling speed |
|
|
@@ -126,7 +200,7 @@ function App() {
|
|
|
126
200
|
### VirtualScrollHandle Methods
|
|
127
201
|
|
|
128
202
|
| Method | Type | Description |
|
|
129
|
-
|
|
|
203
|
+
| --- | --- | --- |
|
|
130
204
|
| `scrollTo` | `(position: number) => void` | Scroll to specific position |
|
|
131
205
|
| `scrollToIndex` | `(index: number, options?: { align?: "top" \| "bottom" \| "center"; offset?: number }) => void` | Scroll to specific item index with optional alignment and offset |
|
|
132
206
|
| `getScrollPosition` | `() => number` | Get current scroll position |
|
|
@@ -138,7 +212,7 @@ function App() {
|
|
|
138
212
|
### VirtualScrollRange
|
|
139
213
|
|
|
140
214
|
| Property | Type | Description |
|
|
141
|
-
|
|
|
215
|
+
| --- | --- | --- |
|
|
142
216
|
| `renderingStartIndex` | `number` | Index of the first item being rendered (including overscan) |
|
|
143
217
|
| `renderingEndIndex` | `number` | Index of the last item being rendered (including overscan) |
|
|
144
218
|
| `visibleStartIndex` | `number` | Index of the first fully or partially visible item |
|
|
@@ -151,7 +225,9 @@ function App() {
|
|
|
151
225
|
### With Ref and Scroll Control
|
|
152
226
|
|
|
153
227
|
```tsx
|
|
154
|
-
|
|
228
|
+
// Load the stylesheet once, e.g. in your app entry point
|
|
229
|
+
import '@aiquants/virtualscroll/styles/virtualscroll.css'
|
|
230
|
+
import { ScrollBarThumbOverlayRenderProps, VirtualScroll, VirtualScrollHandle, VirtualScrollRange } from '@aiquants/virtualscroll'
|
|
155
231
|
import { useCallback, useRef, useState } from 'react'
|
|
156
232
|
|
|
157
233
|
const items = Array.from({ length: 100000 }, (_, index) => ({
|
|
@@ -176,15 +252,8 @@ function AdvancedExample() {
|
|
|
176
252
|
virtualScrollRef.current?.scrollToIndex(index, { align: "center" })
|
|
177
253
|
}
|
|
178
254
|
|
|
179
|
-
const handleRangeChange = useCallback((
|
|
180
|
-
|
|
181
|
-
_renderingEndIndex: number,
|
|
182
|
-
visibleStart: number,
|
|
183
|
-
_visibleEndIndex: number,
|
|
184
|
-
_scrollPosition: number,
|
|
185
|
-
_totalHeight: number,
|
|
186
|
-
) => {
|
|
187
|
-
setVisibleStartIndex(visibleStart)
|
|
255
|
+
const handleRangeChange = useCallback((range: VirtualScrollRange) => {
|
|
256
|
+
setVisibleStartIndex(range.visibleStartIndex)
|
|
188
257
|
}, [])
|
|
189
258
|
|
|
190
259
|
const renderThumbOverlay = useCallback((props: ScrollBarThumbOverlayRenderProps) => {
|
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import { ReactNode } from 'react';
|
|
2
|
+
import { TapScrollCircleRenderProps } from './TapScrollCircle.cjs';
|
|
3
|
+
/**
|
|
4
|
+
* Options to customize the auxiliary tap scroll circle.
|
|
5
|
+
*
|
|
6
|
+
* タップスクロール用サークルをカスタマイズするためのオプション。
|
|
7
|
+
*/
|
|
8
|
+
export type ScrollBarTapCircleOptions = {
|
|
9
|
+
/** Enable or disable the tap scroll circle. / タップサークルを有効化または無効化。 */
|
|
10
|
+
enabled?: boolean;
|
|
11
|
+
/** Circle diameter in pixels. / サークルの直径 (ピクセル)。 */
|
|
12
|
+
size?: number;
|
|
13
|
+
/** Horizontal offset in pixels. / 水平方向オフセット (ピクセル)。 */
|
|
14
|
+
offsetX?: number;
|
|
15
|
+
/** Vertical offset in pixels. / 垂直方向オフセット (ピクセル)。 */
|
|
16
|
+
offsetY?: number;
|
|
17
|
+
/** Additional class names for the circle. / サークルの追加クラス名。 */
|
|
18
|
+
className?: string;
|
|
19
|
+
/** Maximum drag distance used for visual feedback. / ビジュアルフィードバックに利用する最大ドラッグ距離。 */
|
|
20
|
+
maxVisualDistance?: number;
|
|
21
|
+
/** Maximum speed multiplier relative to viewport size. / ビューポートサイズに対する最大速度倍率。 */
|
|
22
|
+
maxSpeedMultiplier?: number;
|
|
23
|
+
/** Minimum speed multiplier relative to viewport size. / ビューポートサイズに対する最小速度倍率。 */
|
|
24
|
+
minSpeedMultiplier?: number;
|
|
25
|
+
/** Base opacity multiplier for the circle visuals. / サークル表示の基準透明度倍率。 */
|
|
26
|
+
opacity?: number;
|
|
27
|
+
/** Custom visual renderer for the tap circle. / タップサークルのカスタムビジュアルのレンダラー。 */
|
|
28
|
+
renderVisual?: (props: TapScrollCircleRenderProps) => ReactNode;
|
|
29
|
+
/** Optional exponential cap configuration for max speed. / 最大速度に指数関数的な上限を設定するためのオプション設定。 */
|
|
30
|
+
maxSpeedCurve?: {
|
|
31
|
+
/** Steepness factor for the exponential curve. / 指数関数の急峻さを決定する要素。 */
|
|
32
|
+
exponentialSteepness: number;
|
|
33
|
+
/** Scale factor for the exponential curve. / 指数関数のスケールファクター。 */
|
|
34
|
+
exponentialScale?: number;
|
|
35
|
+
/** Additional eased offset to apply to the curve. / 曲線に適用する追加のイーズドオフセット。 */
|
|
36
|
+
easedOffset?: number;
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
/** Custom event name emitted when external interactions should cancel tap scrolling. / 外部操作によってタップスクロールをキャンセルすべき際に発行されるカスタムイベント名。 */
|
|
40
|
+
export declare const TAP_SCROLL_CANCEL_EVENT = "virtualscroll:tap-scroll-cancel";
|
|
41
|
+
/**
|
|
42
|
+
* Props for the ScrollBar component.
|
|
43
|
+
*
|
|
44
|
+
* ScrollBar コンポーネントの Props。
|
|
45
|
+
*/
|
|
46
|
+
export type ScrollBarThumbOverlayRenderProps = {
|
|
47
|
+
orientation: "vertical" | "horizontal";
|
|
48
|
+
scrollPosition: number;
|
|
49
|
+
maxScrollPosition: number;
|
|
50
|
+
contentSize: number;
|
|
51
|
+
viewportSize: number;
|
|
52
|
+
thumbSize: number;
|
|
53
|
+
thumbPosition: number;
|
|
54
|
+
thumbCenter: number;
|
|
55
|
+
trackSize: number;
|
|
56
|
+
isDragging: boolean;
|
|
57
|
+
isTapScrollActive: boolean;
|
|
58
|
+
visibleStartIndex?: number;
|
|
59
|
+
visibleEndIndex?: number;
|
|
60
|
+
};
|
|
61
|
+
export type ScrollBarProps = {
|
|
62
|
+
/** The total size of the content. / コンテンツの総サイズ。 */
|
|
63
|
+
contentSize: number;
|
|
64
|
+
/** The size of the visible area. / 表示領域のサイズ。 */
|
|
65
|
+
viewportSize: number;
|
|
66
|
+
/** The current scroll position. / 現在のスクロール位置。 */
|
|
67
|
+
scrollPosition: number;
|
|
68
|
+
/** A callback function invoked to adjust scroll position. Accepts next position or updater. / スクロール位置を調整するためのコールバック。次位置または更新関数を受け取る。 */
|
|
69
|
+
onScroll?: (scrollPosition: number | ((prevPosition: number) => number), prevPosition?: number) => number | undefined;
|
|
70
|
+
/** Whether grabbing the scrollbar thumb is allowed. / スクロールバーのつまみ操作を許可するかどうか。 */
|
|
71
|
+
enableThumbDrag?: boolean;
|
|
72
|
+
/** Whether clicking on the track moves the scrollbar. / スクロールバーのトラッククリック操作を許可するかどうか。 */
|
|
73
|
+
enableTrackClick?: boolean;
|
|
74
|
+
/** Whether arrow buttons control the scroll position. / 矢印ボタンによるスクロール操作を許可するかどうか。 */
|
|
75
|
+
enableArrowButtons?: boolean;
|
|
76
|
+
/** Whether the scrollbar is horizontal. / スクロールバーが水平かどうか。 */
|
|
77
|
+
horizontal?: boolean;
|
|
78
|
+
/** The width of the scrollbar. / スクロールバーの幅。 */
|
|
79
|
+
scrollBarWidth?: number;
|
|
80
|
+
/** Additional class names for the component. / コンポーネントの追加のクラス名。 */
|
|
81
|
+
className?: string;
|
|
82
|
+
/** The ID of the element that the scrollbar controls. / スクロールバーが制御する要素の ID。 */
|
|
83
|
+
ariaControls?: string;
|
|
84
|
+
/** Configuration for the tap scroll circle. / タップサークルの設定。 */
|
|
85
|
+
tapScrollCircleOptions?: ScrollBarTapCircleOptions;
|
|
86
|
+
/** Total number of scrollable items (optional). / スクロール対象アイテムの総数(任意)。 */
|
|
87
|
+
itemCount?: number;
|
|
88
|
+
/** Optional renderer for thumb-adjacent overlays. / サム付近に重ねるオーバーレイのレンダラー。 */
|
|
89
|
+
renderThumbOverlay?: (props: ScrollBarThumbOverlayRenderProps) => ReactNode;
|
|
90
|
+
/** The index of the first visible item. / 最初の可視アイテムのインデックス。 */
|
|
91
|
+
visibleStartIndex?: number;
|
|
92
|
+
/** The index of the last visible item. / 最後の可視アイテムのインデックス。 */
|
|
93
|
+
visibleEndIndex?: number;
|
|
94
|
+
};
|
|
95
|
+
/**
|
|
96
|
+
* A custom scrollbar component.
|
|
97
|
+
*
|
|
98
|
+
* カスタムスクロールバーコンポーネント。
|
|
99
|
+
*/
|
|
100
|
+
export declare const ScrollBar: ({ contentSize, viewportSize, scrollPosition, onScroll, enableThumbDrag, enableTrackClick, enableArrowButtons, horizontal, scrollBarWidth, className, ariaControls, tapScrollCircleOptions, itemCount, renderThumbOverlay, visibleStartIndex, visibleEndIndex, }: ScrollBarProps) => import("react").JSX.Element;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ScrollBar.d.ts","sourceRoot":"","sources":["../src/ScrollBar.tsx"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
import { ScrollBarTapCircleOptions, ScrollBarThumbOverlayRenderProps } from './ScrollBar.cjs';
|
|
2
|
+
/**
|
|
3
|
+
* Props for the ScrollPane component.
|
|
4
|
+
*
|
|
5
|
+
* ScrollPane コンポーネントの Props。
|
|
6
|
+
*/
|
|
7
|
+
export type ScrollPaneContentInsets = {
|
|
8
|
+
top?: number;
|
|
9
|
+
bottom?: number;
|
|
10
|
+
};
|
|
11
|
+
export type ScrollPaneProps = {
|
|
12
|
+
/**
|
|
13
|
+
* A function that renders the content of the scroll pane.
|
|
14
|
+
* It receives the current scroll position as an argument.
|
|
15
|
+
*
|
|
16
|
+
* スクロールペインのコンテンツをレンダリングする関数です。
|
|
17
|
+
* 現在のスクロール位置を引数として受け取ります。
|
|
18
|
+
*/
|
|
19
|
+
children: (scrollPosition: number) => React.ReactNode;
|
|
20
|
+
/** The total size of the content. / コンテンツの総サイズ。 */
|
|
21
|
+
contentSize: number;
|
|
22
|
+
/** The size of the visible area. / 表示領域のサイズ。 */
|
|
23
|
+
viewportSize: number;
|
|
24
|
+
/** The width of the scrollbar. / スクロールバーの幅。 */
|
|
25
|
+
scrollBarWidth?: number;
|
|
26
|
+
/** Whether grabbing the scrollbar thumb is allowed. / スクロールバーのつまみ操作を許可するかどうか。 */
|
|
27
|
+
enableThumbDrag?: boolean;
|
|
28
|
+
/** A callback function that is called when the scroll position changes. / スクロール位置が変更されたときに呼び出されるコールバック関数。 */
|
|
29
|
+
onScroll?: (scrollPosition: number, prevPosition: number) => void;
|
|
30
|
+
/** Additional class names for the component. / コンポーネントの追加のクラス名。 */
|
|
31
|
+
className?: string;
|
|
32
|
+
/** Custom styles for the component. / コンポーネントのカスタムスタイル。 */
|
|
33
|
+
style?: React.CSSProperties;
|
|
34
|
+
/** A background element to be rendered behind the content. / コンテンツの背後にレンダリングされる背景要素。 */
|
|
35
|
+
background?: React.ReactNode;
|
|
36
|
+
/** Configuration for the tap scroll circle. / タップサークルの設定。 */
|
|
37
|
+
tapScrollCircleOptions?: ScrollBarTapCircleOptions;
|
|
38
|
+
/** Configuration for inertia scroll behavior. / 慣性スクロールの設定。 */
|
|
39
|
+
inertiaOptions?: ScrollPaneInertiaOptions;
|
|
40
|
+
/** Total number of scrollable items (optional). / スクロール対象アイテムの総数(任意)。 */
|
|
41
|
+
itemCount?: number;
|
|
42
|
+
/** Whether clicking the scrollbar track moves the thumb. / スクロールバートラックのクリック操作を許可するかどうか。 */
|
|
43
|
+
enableTrackClick?: boolean;
|
|
44
|
+
/** Whether arrow buttons control the scroll position. / 矢印ボタンのスクロール操作を許可するかどうか。 */
|
|
45
|
+
enableArrowButtons?: boolean;
|
|
46
|
+
/** Whether dragging the content area scrolls the pane. / コンテンツ領域のドラッグでスクロールさせるかどうか。 */
|
|
47
|
+
enablePointerDrag?: boolean;
|
|
48
|
+
/** Optional renderer for thumb overlays. / サム付近に表示するオーバーレイのレンダラー。 */
|
|
49
|
+
renderThumbOverlay?: (props: ScrollBarThumbOverlayRenderProps) => React.ReactNode;
|
|
50
|
+
/** Multiplier applied to wheel delta for faster or slower scrolling. / スクロール速度を調整するためのホイールデルタの倍率。 */
|
|
51
|
+
wheelSpeedMultiplier?: number;
|
|
52
|
+
/**
|
|
53
|
+
* Callback delegating horizontal wheel/trackpad delta to an upstream owner.
|
|
54
|
+
* When provided, horizontal-dominant (or shift+wheel) gestures are consumed here
|
|
55
|
+
* (preventDefault + delegate) instead of being ignored; vertical behavior is unchanged.
|
|
56
|
+
* 横方向ホイール/トラックパッド量を上流へ委譲するコールバック。指定時のみ横成分を処理する。
|
|
57
|
+
*/
|
|
58
|
+
onWheelHorizontal?: (deltaX: number) => void;
|
|
59
|
+
/** Insets applied to the scrollable content area. / スクロール可能領域に適用するインセット。 */
|
|
60
|
+
contentInsets?: ScrollPaneContentInsets;
|
|
61
|
+
/** The index of the first visible item. / 最初の可視アイテムのインデックス。 */
|
|
62
|
+
visibleStartIndex?: number;
|
|
63
|
+
/** The index of the last visible item. / 最後の可視アイテムのインデックス。 */
|
|
64
|
+
visibleEndIndex?: number;
|
|
65
|
+
/** A function to render an overlay on top of the scroll pane. / スクロールペインの上にオーバーレイをレンダリングする関数。 */
|
|
66
|
+
renderOverlay?: () => React.ReactNode;
|
|
67
|
+
/** Initial scroll position. / 初期のスクロール位置。 */
|
|
68
|
+
initialScrollPosition?: number;
|
|
69
|
+
};
|
|
70
|
+
export type ScrollPaneInertiaOptions = {
|
|
71
|
+
/** Maximum velocity applied when inertia starts. / 慣性開始時に適用する最大速度。 */
|
|
72
|
+
maxVelocity?: number;
|
|
73
|
+
/** Minimum velocity threshold to continue inertia. / 慣性を継続するための最小速度しきい値。 */
|
|
74
|
+
minVelocity?: number;
|
|
75
|
+
/** Deceleration applied on every frame. / 各フレームで適用される減速度。 */
|
|
76
|
+
deceleration?: number;
|
|
77
|
+
/** Sampling window in milliseconds for pointer velocity calculation. / ポインタの速度計算に用いるミリ秒単位のサンプリング期間。 */
|
|
78
|
+
velocitySampleWindow?: number;
|
|
79
|
+
/** Minimum velocity required to start inertia. / 慣性を開始するために必要な最小速度。 */
|
|
80
|
+
startVelocityThreshold?: number;
|
|
81
|
+
};
|
|
82
|
+
export type ScrollPaneHandle = {
|
|
83
|
+
scrollTo: (newPosition: number | ((prev: number) => number)) => number;
|
|
84
|
+
getScrollPosition: () => number;
|
|
85
|
+
getContentSize: () => number;
|
|
86
|
+
getViewportSize: () => number;
|
|
87
|
+
};
|
|
88
|
+
/**
|
|
89
|
+
* A component that provides a scrollable view with a custom scrollbar.
|
|
90
|
+
*
|
|
91
|
+
* カスタムスクロールバーを備えたスクロール可能なビューを提供するコンポーネントです。
|
|
92
|
+
*/
|
|
93
|
+
export declare const ScrollPane: import('react').ForwardRefExoticComponent<ScrollPaneProps & import('react').RefAttributes<ScrollPaneHandle>>;
|
|
@@ -0,0 +1 @@
|
|
|
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,gDAAgD;IAChD,YAAY,EAAE,MAAM,CAAA;IACpB,+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,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,qEAAqE;IACrE,kBAAkB,CAAC,EAAE,CAAC,KAAK,EAAE,gCAAgC,KAAK,KAAK,CAAC,SAAS,CAAA;IACjF,qGAAqG;IACrG,oBAAoB,CAAC,EAAE,MAAM,CAAA;IAC7B;;;;;OAKG;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;CACjC,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;AA4CD,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,8GA2vBtB,CAAA"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { CSSProperties, ReactNode } from 'react';
|
|
2
|
+
export type TapScrollCircleDragState = {
|
|
3
|
+
/** Whether the pointer is actively dragging. / ポインターがドラッグ中かどうか。 */
|
|
4
|
+
active: boolean;
|
|
5
|
+
/** Signed horizontal offset from the circle center. / サークル中心からの符号付き水平方向オフセット。 */
|
|
6
|
+
offsetX: number;
|
|
7
|
+
/** Signed vertical offset from the circle center. / サークル中心からの符号付き垂直オフセット。 */
|
|
8
|
+
offsetY: number;
|
|
9
|
+
/** Absolute distance between pointer and center. / ポインターと中心の距離。 */
|
|
10
|
+
distance: number;
|
|
11
|
+
/** Drag direction relative to the circle. / サークルに対するドラッグ方向。 */
|
|
12
|
+
direction: -1 | 0 | 1;
|
|
13
|
+
/** The ID of the pointer that initiated the drag. / ドラッグを開始したポインターの ID。 */
|
|
14
|
+
pointerId: number | null;
|
|
15
|
+
};
|
|
16
|
+
export type TapScrollCircleProps = {
|
|
17
|
+
/** Called whenever the drag state updates. / ドラッグ状態が更新された際に呼び出されるコールバック。 */
|
|
18
|
+
onDragChange: (state: TapScrollCircleDragState) => void;
|
|
19
|
+
/** Additional class names for styling. / 追加のスタイル用クラス名。 */
|
|
20
|
+
className?: string;
|
|
21
|
+
/** Maximum distance used for visual stretching. / 視覚的な伸縮に使用する最大距離。 */
|
|
22
|
+
maxVisualDistance?: number;
|
|
23
|
+
/** Diameter of the circle in pixels. / サークルの直径 (ピクセル)。 */
|
|
24
|
+
size?: number;
|
|
25
|
+
/** Additional inline styles. / 追加のインラインスタイル。 */
|
|
26
|
+
style?: CSSProperties;
|
|
27
|
+
/** Base opacity applied to the circle. / サークル全体に適用する基準透明度。 */
|
|
28
|
+
opacity: number;
|
|
29
|
+
/** Custom rendering logic for the visual contents. / ビジュアル内容を描画するカスタムロジック。 */
|
|
30
|
+
renderVisual?: (props: TapScrollCircleRenderProps) => ReactNode;
|
|
31
|
+
};
|
|
32
|
+
export type TapScrollCircleHandle = {
|
|
33
|
+
/**
|
|
34
|
+
* Resets the drag state and releases pointer capture if active.
|
|
35
|
+
*
|
|
36
|
+
* ドラッグ状態をリセットし、必要に応じてポインタキャプチャを解除する。
|
|
37
|
+
*/
|
|
38
|
+
reset: () => void;
|
|
39
|
+
/**
|
|
40
|
+
* Returns the underlying DOM element of the tap circle.
|
|
41
|
+
*
|
|
42
|
+
* タップサークルの DOM 要素を返す。
|
|
43
|
+
*/
|
|
44
|
+
getElement: () => HTMLDivElement | null;
|
|
45
|
+
};
|
|
46
|
+
export type TapScrollCircleRenderProps = {
|
|
47
|
+
/** Current drag state snapshot. / 現在のドラッグ状態のスナップショット。 */
|
|
48
|
+
dragState: TapScrollCircleDragState;
|
|
49
|
+
/** Normalized distance within [0, 1]. / 正規化距離 (0 から 1 の範囲)。 */
|
|
50
|
+
normalizedDistance: number;
|
|
51
|
+
/** Relative scale based on size. / サイズに基づく相対スケール。 */
|
|
52
|
+
sizeScale: number;
|
|
53
|
+
/** Circle diameter in pixels. / サークル直径 (ピクセル)。 */
|
|
54
|
+
size: number;
|
|
55
|
+
/** Applied opacity value. / 適用中の不透明度値。 */
|
|
56
|
+
opacity: number;
|
|
57
|
+
};
|
|
58
|
+
/**
|
|
59
|
+
* A circular touch handle that stretches toward the drag direction.
|
|
60
|
+
* タップした方向へ伸縮するタッチ操作用サークル。
|
|
61
|
+
*/
|
|
62
|
+
export declare const TapScrollCircle: import('react').NamedExoticComponent<TapScrollCircleProps & import('react').RefAttributes<TapScrollCircleHandle>>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"TapScrollCircle.d.ts","sourceRoot":"","sources":["../src/TapScrollCircle.tsx"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,SAAS,EAAqC,MAAM,OAAO,CAAA;AAIxF,MAAM,MAAM,wBAAwB,GAAG;IACnC,mEAAmE;IACnE,MAAM,EAAE,OAAO,CAAA;IACf,iFAAiF;IACjF,OAAO,EAAE,MAAM,CAAA;IACf,6EAA6E;IAC7E,OAAO,EAAE,MAAM,CAAA;IACf,mEAAmE;IACnE,QAAQ,EAAE,MAAM,CAAA;IAChB,+DAA+D;IAC/D,SAAS,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;IACrB,2EAA2E;IAC3E,SAAS,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3B,CAAA;AAED,MAAM,MAAM,oBAAoB,GAAG;IAC/B,4EAA4E;IAC5E,YAAY,EAAE,CAAC,KAAK,EAAE,wBAAwB,KAAK,IAAI,CAAA;IACvD,0DAA0D;IAC1D,SAAS,CAAC,EAAE,MAAM,CAAA;IAClB,sEAAsE;IACtE,iBAAiB,CAAC,EAAE,MAAM,CAAA;IAC1B,0DAA0D;IAC1D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,gDAAgD;IAChD,KAAK,CAAC,EAAE,aAAa,CAAA;IACrB,8DAA8D;IAC9D,OAAO,EAAE,MAAM,CAAA;IACf,8EAA8E;IAC9E,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,0BAA0B,KAAK,SAAS,CAAA;CAClE,CAAA;AAED,MAAM,MAAM,qBAAqB,GAAG;IAChC;;;;OAIG;IACH,KAAK,EAAE,MAAM,IAAI,CAAA;IACjB;;;;OAIG;IACH,UAAU,EAAE,MAAM,cAAc,GAAG,IAAI,CAAA;CAC1C,CAAA;AAcD,MAAM,MAAM,0BAA0B,GAAG;IACrC,yDAAyD;IACzD,SAAS,EAAE,wBAAwB,CAAA;IACnC,+DAA+D;IAC/D,kBAAkB,EAAE,MAAM,CAAA;IAC1B,qDAAqD;IACrD,SAAS,EAAE,MAAM,CAAA;IACjB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAA;IACZ,0CAA0C;IAC1C,OAAO,EAAE,MAAM,CAAA;CAClB,CAAA;AAgCD;;;GAGG;AACH,eAAO,MAAM,eAAe,mHAqP3B,CAAA"}
|
|
@@ -0,0 +1,155 @@
|
|
|
1
|
+
import { default as React, ReactNode } from 'react';
|
|
2
|
+
import { ScrollPaneHandle, ScrollPaneProps } from './ScrollPane.cjs';
|
|
3
|
+
import { useFenwickMapTree } from './useFenwickMapTree.cjs';
|
|
4
|
+
/**
|
|
5
|
+
* Represents the current state of the rendered range and scroll metrics.
|
|
6
|
+
*
|
|
7
|
+
* 現在のレンダリング範囲とスクロールメトリクスの状態を表します。
|
|
8
|
+
*/
|
|
9
|
+
export type VirtualScrollRange = {
|
|
10
|
+
/** Start index for rendering (includes overscan) / 描画開始インデックス(オーバースキャン含む) */
|
|
11
|
+
renderingStartIndex: number;
|
|
12
|
+
/** End index for rendering (includes overscan) / 描画終了インデックス(オーバースキャン含む) */
|
|
13
|
+
renderingEndIndex: number;
|
|
14
|
+
/** Index of the first item strictly visible in the viewport / ビューポート内に見えている最初のアイテムのインデックス */
|
|
15
|
+
visibleStartIndex: number;
|
|
16
|
+
/** Index of the last item strictly visible in the viewport / ビューポート内に見えている最後のアイテムのインデックス */
|
|
17
|
+
visibleEndIndex: number;
|
|
18
|
+
/** Current logical scroll position / 現在の論理スクロール位置 */
|
|
19
|
+
scrollPosition: number;
|
|
20
|
+
/** Total height of the scroll content / スクロールコンテンツの総高さ */
|
|
21
|
+
totalHeight: number;
|
|
22
|
+
};
|
|
23
|
+
/**
|
|
24
|
+
* Handle interface for controlling the VirtualScroll component externally.
|
|
25
|
+
*
|
|
26
|
+
* 外部から VirtualScroll コンポーネントを制御するためのハンドルインターフェース。
|
|
27
|
+
*/
|
|
28
|
+
export type VirtualScrollHandle = ScrollPaneHandle & {
|
|
29
|
+
/** Scrolls to a specific item index / 指定したアイテムインデックスへスクロール */
|
|
30
|
+
scrollToIndex: (index: number, options?: {
|
|
31
|
+
align?: "top" | "bottom" | "center";
|
|
32
|
+
offset?: number;
|
|
33
|
+
}) => void;
|
|
34
|
+
/** Gets the total height managed by the Fenwick Tree / Fenwick Tree で管理されている総高さを取得 */
|
|
35
|
+
getFenwickTreeTotalHeight: () => number;
|
|
36
|
+
/** Gets the number of items in the Fenwick Tree / Fenwick Tree 内のアイテム数を取得 */
|
|
37
|
+
getFenwickSize: () => number;
|
|
38
|
+
/** Focuses an item at the specified index / 指定したインデックスのアイテムにフォーカス */
|
|
39
|
+
focusItemAtIndex: (index: number, options?: {
|
|
40
|
+
ensureVisible?: boolean;
|
|
41
|
+
}) => void;
|
|
42
|
+
/** Gets the current scroll range information / 現在のスクロール範囲情報を取得 */
|
|
43
|
+
getRange: () => VirtualScrollRange;
|
|
44
|
+
/**
|
|
45
|
+
* Manually updates the size of a specific item. Contract: after calling this,
|
|
46
|
+
* `getItemHeight(index)` must return the same `size`; `getItemHeight` is the source of truth,
|
|
47
|
+
* so if it keeps returning the old value, rows inside the current rendering window (including
|
|
48
|
+
* overscan) are reverted to the `getItemHeight` value by height reconciliation on the next render.
|
|
49
|
+
*
|
|
50
|
+
* 特定のアイテムのサイズを手動で更新。契約: 呼び出し後は `getItemHeight(index)` も同じ値を
|
|
51
|
+
* 返すこと。`getItemHeight` が正であるため、旧値を返し続けると描画ウィンドウ (オーバースキャン
|
|
52
|
+
* 含む) 内の行は次レンダーの高さ照合で `getItemHeight` の値へ巻き戻る。
|
|
53
|
+
*/
|
|
54
|
+
updateItemSize: (index: number, size: number) => void;
|
|
55
|
+
};
|
|
56
|
+
export type VirtualScrollScrollBarOptions = {
|
|
57
|
+
width?: number;
|
|
58
|
+
enableThumbDrag?: boolean;
|
|
59
|
+
enableTrackClick?: boolean;
|
|
60
|
+
enableArrowButtons?: boolean;
|
|
61
|
+
enableScrollToTopBottomButtons?: boolean;
|
|
62
|
+
renderThumbOverlay?: ScrollPaneProps["renderThumbOverlay"];
|
|
63
|
+
tapScrollCircleOptions?: ScrollPaneProps["tapScrollCircleOptions"];
|
|
64
|
+
};
|
|
65
|
+
export type VirtualScrollBehaviorOptions = {
|
|
66
|
+
enablePointerDrag?: boolean;
|
|
67
|
+
enableKeyboardNavigation?: boolean;
|
|
68
|
+
wheelSpeedMultiplier?: number;
|
|
69
|
+
inertiaOptions?: ScrollPaneProps["inertiaOptions"];
|
|
70
|
+
clipItemHeight?: boolean;
|
|
71
|
+
/**
|
|
72
|
+
* When `true`, the underlying Fenwick tree fully re-samples on every `getItemHeight` change
|
|
73
|
+
* instead of applying an incremental tail resize.
|
|
74
|
+
*
|
|
75
|
+
* Set this to `true` whenever an `itemCount` change may represent a middle insertion/deletion
|
|
76
|
+
* (not just a tail append/remove): an incremental resize assumes items are added/removed at the
|
|
77
|
+
* tail and keeps each existing index's measured height, so a middle insert would leave the
|
|
78
|
+
* `getItemHeight` index↔height mapping applied to the wrong rows. Alternatively, remount
|
|
79
|
+
* VirtualScroll with a new `key` when the list structure changes.
|
|
80
|
+
*
|
|
81
|
+
* `true` のとき、内部 Fenwick 木は `getItemHeight` 変更のたびに増分的な末尾リサイズではなく全面
|
|
82
|
+
* 再サンプリングを行う。`itemCount` の変更が末尾追記/削除ではなく中間挿入/削除を含みうる場合は
|
|
83
|
+
* `true` にすること。増分リサイズは要素が末尾で増減する前提で各既存インデックスの実測高さを保持する
|
|
84
|
+
* ため、中間挿入があると `getItemHeight` の index↔高さ 対応が誤った行に適用されてしまう。代替として、
|
|
85
|
+
* リスト構造が変わるときに新しい `key` で VirtualScroll を再マウントしてもよい。
|
|
86
|
+
*/
|
|
87
|
+
resetOnGetItemHeightChange?: boolean;
|
|
88
|
+
};
|
|
89
|
+
/**
|
|
90
|
+
* Props for the VirtualScroll component.
|
|
91
|
+
*
|
|
92
|
+
* VirtualScroll コンポーネントの Props。
|
|
93
|
+
*/
|
|
94
|
+
export type VirtualScrollProps<T> = {
|
|
95
|
+
itemCount: number;
|
|
96
|
+
getItem: (index: number) => T;
|
|
97
|
+
getItemKey?: (index: number) => React.Key;
|
|
98
|
+
/**
|
|
99
|
+
* Returns the height of the item at `index`. The index↔height mapping must be stable for a
|
|
100
|
+
* given list ordering: when `itemCount` grows/shrinks, VirtualScroll assumes items are
|
|
101
|
+
* appended to / removed from the tail and preserves the measured height of each existing index.
|
|
102
|
+
* If a list mutation inserts or removes items in the middle (shifting later indices), enable
|
|
103
|
+
* `behaviorOptions.resetOnGetItemHeightChange` or remount with a new `key`; otherwise cached
|
|
104
|
+
* heights stay attached to indices that now point at different items.
|
|
105
|
+
*
|
|
106
|
+
* `index` のアイテム高さを返す。index↔高さ の対応は同じ並び順の間は安定である必要がある。`itemCount`
|
|
107
|
+
* が増減するとき VirtualScroll は要素が末尾で追加/削除されると仮定し、既存インデックスの実測高さを
|
|
108
|
+
* 保持する。中間挿入/削除 (以降のインデックスがずれる) を伴うリスト変更では
|
|
109
|
+
* `behaviorOptions.resetOnGetItemHeightChange` を有効化するか新しい `key` で再マウントすること。
|
|
110
|
+
* さもないとキャッシュ済み高さが別のアイテムを指すインデックスに残る。
|
|
111
|
+
*/
|
|
112
|
+
getItemHeight: (index: number) => number;
|
|
113
|
+
viewportSize: number;
|
|
114
|
+
overscanCount?: number;
|
|
115
|
+
className?: string;
|
|
116
|
+
onScroll?: (scrollPosition: number, totalHeight: number) => void;
|
|
117
|
+
onRangeChange?: (range: VirtualScrollRange) => void;
|
|
118
|
+
background?: ReactNode;
|
|
119
|
+
children: (item: T, index: number) => ReactNode;
|
|
120
|
+
initialScrollIndex?: number;
|
|
121
|
+
initialScrollOffset?: number;
|
|
122
|
+
callbackThrottleMs?: number;
|
|
123
|
+
contentInsets?: ScrollPaneProps["contentInsets"];
|
|
124
|
+
onItemFocus?: (index: number) => void;
|
|
125
|
+
scrollBarOptions?: VirtualScrollScrollBarOptions;
|
|
126
|
+
behaviorOptions?: VirtualScrollBehaviorOptions;
|
|
127
|
+
/** Delegates horizontal wheel/trackpad delta to an upstream owner (e.g. a frozen-column grid). / 横ホイール量を上流へ委譲する。 */
|
|
128
|
+
onWheelHorizontal?: (deltaX: number) => void;
|
|
129
|
+
};
|
|
130
|
+
/**
|
|
131
|
+
* Retrieves a high-resolution timestamp when available.
|
|
132
|
+
*
|
|
133
|
+
* 高精度タイムスタンプを可能なら取得。
|
|
134
|
+
*/
|
|
135
|
+
/**
|
|
136
|
+
* Calculates rendering boundaries from current scroll metrics.
|
|
137
|
+
*
|
|
138
|
+
* 現在のスクロール情報から描画範囲を算出。
|
|
139
|
+
*/
|
|
140
|
+
export declare const computeRenderingRanges: (scrollPosition: number, viewportSize: number, overscanCount: number, itemSize: number, getItemHeight: (index: number) => number, fenwickTree: ReturnType<typeof useFenwickMapTree>, totalHeight: number) => {
|
|
141
|
+
renderingStartIndex: number;
|
|
142
|
+
renderingEndIndex: number;
|
|
143
|
+
visibleStartIndex: number;
|
|
144
|
+
visibleEndIndex: number;
|
|
145
|
+
};
|
|
146
|
+
/**
|
|
147
|
+
* A highly performant virtual scroll component that supports variable item heights.
|
|
148
|
+
* Uses a Fenwick Tree (Binary Indexed Tree) for efficient offset calculation and range queries.
|
|
149
|
+
*
|
|
150
|
+
* 可変のアイテム高さをサポートする高性能な仮想スクロールコンポーネント。
|
|
151
|
+
* オフセット計算と範囲クエリを効率化するために Fenwick Tree (Binary Indexed Tree) を使用しています。
|
|
152
|
+
*/
|
|
153
|
+
export declare const VirtualScroll: <T>(props: VirtualScrollProps<T> & {
|
|
154
|
+
ref?: React.Ref<VirtualScrollHandle>;
|
|
155
|
+
}) => React.ReactElement;
|