perf: clean tab drag passthrough cleanup from effect

This commit is contained in:
Neil
2026-05-30 07:01:11 -07:00
parent 200115e9b8
commit ed76560f6b
3 changed files with 23 additions and 5 deletions
@@ -2,6 +2,7 @@ import { beforeEach, describe, expect, it, vi } from 'vitest'
const setTabGroupSplitRatioMock = vi.fn()
const recordFeatureInteractionMock = vi.fn()
const setDragRootNodeMock = vi.fn()
const useAppStoreMock = vi.fn(
(
selector: (state: {
@@ -37,7 +38,8 @@ vi.mock('./useTabDragSplit', () => ({
onDragMove: vi.fn(),
onDragOver: vi.fn(),
onDragStart: vi.fn(),
sensors: []
sensors: [],
setDragRootNode: setDragRootNodeMock
})
}))
@@ -47,6 +49,7 @@ describe('TabGroupSplitLayout', () => {
beforeEach(() => {
setTabGroupSplitRatioMock.mockClear()
recordFeatureInteractionMock.mockClear()
setDragRootNodeMock.mockClear()
useAppStoreMock.mockClear()
})
@@ -238,7 +238,10 @@ export default function TabGroupSplitLayout({
state. The leftmost pane suppresses its own `border-l` via
`touchesLeftEdge`, so the seam is always exactly 1px — previously
both painted and stacked into a 2px bar below the drag strip. */}
<div className="flex flex-col flex-1 min-w-0 min-h-0 overflow-hidden border-l border-border">
<div
ref={dragSplit.setDragRootNode}
className="flex flex-col flex-1 min-w-0 min-h-0 overflow-hidden border-l border-border"
>
<div
className="h-[4px] shrink-0 bg-card"
style={{ WebkitAppRegion: 'drag' } as React.CSSProperties}
@@ -1,7 +1,7 @@
/* oxlint-disable max-lines -- Why: the drag-split hook co-locates drop-zone
* resolution, same-group reordering, and cross-group handoff so state
* transitions stay readable in one place. */
import { useCallback, useEffect, useRef, useState } from 'react'
import { useCallback, useRef, useState } from 'react'
import {
closestCenter,
pointerWithin,
@@ -204,6 +204,7 @@ export function useTabDragSplit({
onDragOver: (event: DragOverEvent) => void
onDragStart: (event: DragStartEvent) => void
sensors: ReturnType<typeof useSensors>
setDragRootNode: (node: HTMLDivElement | null) => void
} {
const reorderUnifiedTabs = useAppStore((state) => state.reorderUnifiedTabs)
const dropUnifiedTab = useAppStore((state) => state.dropUnifiedTab)
@@ -235,7 +236,17 @@ export function useTabDragSplit({
releaseWebviewDragPassthroughRef.current = acquireWebviewsDragPassthrough()
}, [releaseWebviewDragPassthrough])
useEffect(() => () => releaseWebviewDragPassthrough(), [releaseWebviewDragPassthrough])
const setDragRootNode = useCallback(
(node: HTMLDivElement | null): void => {
if (node) {
return
}
// Why: this root owns the dnd-kit gesture that temporarily puts browser
// webviews in pointer passthrough, so root teardown must release it.
releaseWebviewDragPassthrough()
},
[releaseWebviewDragPassthrough]
)
const clearDragState = useCallback(() => {
releaseWebviewDragPassthrough()
@@ -465,6 +476,7 @@ export function useTabDragSplit({
onDragMove,
onDragOver,
onDragStart,
sensors
sensors,
setDragRootNode
}
}