@aiquants/virtualscroll 1.19.3 → 1.20.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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@aiquants/virtualscroll",
3
- "version": "1.19.3",
3
+ "version": "1.20.0",
4
4
  "description": "High-performance virtual scrolling component for React with variable item heights",
5
5
  "sideEffects": [
6
6
  "**/*.css"
@@ -119,6 +119,20 @@ describe("ScrollPane - conditional wheel preventDefault", () => {
119
119
  expect(event.defaultPrevented).toBe(false)
120
120
  expect(onScroll).not.toHaveBeenCalled()
121
121
  })
122
+
123
+ it("does not prevent default nor scroll on Shift+wheel when onWheelHorizontal is undefined", () => {
124
+ const { pane, onScroll } = setup()
125
+ const event = dispatchWheel(pane, { deltaX: 0, deltaY: 100, shiftKey: true })
126
+ expect(event.defaultPrevented).toBe(false)
127
+ expect(onScroll).not.toHaveBeenCalled()
128
+ })
129
+
130
+ it("does not prevent default nor scroll on horizontal-dominant wheel when onWheelHorizontal is undefined", () => {
131
+ const { pane, onScroll } = setup()
132
+ const event = dispatchWheel(pane, { deltaX: 100, deltaY: 10 })
133
+ expect(event.defaultPrevented).toBe(false)
134
+ expect(onScroll).not.toHaveBeenCalled()
135
+ })
122
136
  })
123
137
 
124
138
  /**
@@ -61,7 +61,9 @@ export type ScrollPaneProps = {
61
61
  * Callback delegating horizontal wheel/trackpad delta to an upstream owner.
62
62
  * When provided, horizontal-dominant (or shift+wheel) gestures are consumed here
63
63
  * (preventDefault + delegate) instead of being ignored; vertical behavior is unchanged.
64
- * 横方向ホイール/トラックパッド量を上流へ委譲するコールバック。指定時のみ横成分を処理する。
64
+ * When omitted, horizontal gestures and shift+wheel bypass vertical scrolling so parent native scrolling works.
65
+ * 横方向ホイール/トラックパッド量を上流へ委譲するコールバック。
66
+ * 指定時は横スクロールを委譲処理し、未指定時でも Shift+ホイール 等の横ジェスチャは縦スクロールで横取りせず親要素のスクロールへ委ねる。
65
67
  */
66
68
  onWheelHorizontal?: (deltaX: number) => void
67
69
  /** Insets applied to the scrollable content area. / スクロール可能領域に適用するインセット。 */
@@ -467,14 +469,20 @@ export const ScrollPane = forwardRef<ScrollPaneHandle, ScrollPaneProps>(
467
469
  useEffect(() => {
468
470
  // ホイールイベントのハンドラ
469
471
  const handleWheel = (event: WheelEvent) => {
470
- // 横委譲: ハンドラがある場合のみ、横優勢ジェスチャ (または shift+ホイール) を横として処理する。
471
- // ハンドラ未指定時はこのブロックを丸ごとスキップし、既存の縦挙動と完全一致する。
472
- // ctrl+wheel はブラウザのズーム (ピンチズーム/ctrl+shift+ホイール等) なので横取りせず常に素通しする。
473
- if (onWheelHorizontalRef.current && !event.ctrlKey) {
474
- const usesShiftAxis = event.shiftKey && event.deltaX === 0
475
- const horizontalDelta = usesShiftAxis ? event.deltaY : event.deltaX
476
- const verticalDelta = usesShiftAxis ? 0 : event.deltaY
477
- if (horizontalDelta !== 0 && Math.abs(horizontalDelta) >= Math.abs(verticalDelta)) {
472
+ // ctrl+wheel はブラウザのズーム (ピンチズーム/ctrl+shift+ホイール等) なので横取りせず常に素通しする
473
+ if (event.ctrlKey) {
474
+ return
475
+ }
476
+
477
+ // Shiftキー押下による軸変換(deltaX=0, deltaY!=0) または 通常のdeltaX/deltaYから横優勢判定
478
+ const usesShiftAxis = event.shiftKey && event.deltaX === 0
479
+ const horizontalDelta = usesShiftAxis ? event.deltaY : event.deltaX
480
+ const verticalDelta = usesShiftAxis ? 0 : event.deltaY
481
+ const isHorizontalDominant = horizontalDelta !== 0 && Math.abs(horizontalDelta) >= Math.abs(verticalDelta)
482
+
483
+ if (isHorizontalDominant) {
484
+ // 横委譲コールバックが指定されている場合は横スクロールとして処理
485
+ if (onWheelHorizontalRef.current) {
478
486
  event.preventDefault()
479
487
  stopInertia()
480
488
  let deltaX = horizontalDelta
@@ -484,17 +492,13 @@ export const ScrollPane = forwardRef<ScrollPaneHandle, ScrollPaneProps>(
484
492
  deltaX *= viewportSize // DOM_DELTA_PAGE
485
493
  }
486
494
  onWheelHorizontalRef.current(deltaX)
487
- return
488
495
  }
489
- }
490
-
491
- if (!isScrollable) {
496
+ // ハンドラ未指定時であっても、横優勢スクロールや Shift+ホイール は
497
+ // 縦スクロールとして横取りせず、親要素のネイティブ横スクロールへ委ねる
492
498
  return
493
499
  }
494
500
 
495
- // ctrl+wheel はブラウザのピンチズームなので横取りしない
496
- // ctrl+wheel is browser pinch-zoom, so leave it to the browser.
497
- if (event.ctrlKey) {
501
+ if (!isScrollable) {
498
502
  return
499
503
  }
500
504