Skip to content

Commit ee6c10e

Browse files
fix(tab-strip): yield the reveal only to scrolling it did not cause
1 parent 1a6a708 commit ee6c10e

1 file changed

Lines changed: 15 additions & 10 deletions

File tree

‎packages/emcn/src/components/tab-strip/tab-strip.tsx‎

Lines changed: 15 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -521,6 +521,7 @@ export function TabStrip({
521521
const autoScrollRafRef = useRef<number | null>(null)
522522
const autoScrollDirectionRef = useRef(0)
523523
const revealScrollRef = useRef<AnimationPlaybackControls | null>(null)
524+
const revealScrollLeftRef = useRef(0)
524525
const focusedTabRef = useRef<{
525526
id: string
526527
element: HTMLButtonElement
@@ -607,6 +608,7 @@ export function TabStrip({
607608
revealScrollRef.current = animate(node.scrollLeft, nextLeft, {
608609
...REVEAL_SCROLL_TRANSITION,
609610
onUpdate: (left) => {
611+
revealScrollLeftRef.current = left
610612
node.scrollLeft = left
611613
},
612614
})
@@ -626,17 +628,25 @@ export function TabStrip({
626628
revealActiveTab()
627629
}
628630
updateLayout()
629-
node.addEventListener('scroll', updateOverflow, { passive: true })
631+
const handleScroll = () => {
632+
updateOverflow()
633+
// A position the reveal did not set means touch, the scrollbar, or the
634+
// keyboard took over scrolling, so the reveal yields to it.
635+
if (revealScrollRef.current && Math.abs(node.scrollLeft - revealScrollLeftRef.current) > 1) {
636+
stopRevealScroll()
637+
}
638+
}
639+
node.addEventListener('scroll', handleScroll, { passive: true })
630640
if (typeof ResizeObserver === 'undefined') {
631-
return () => node.removeEventListener('scroll', updateOverflow)
641+
return () => node.removeEventListener('scroll', handleScroll)
632642
}
633643
const observer = new ResizeObserver(updateLayout)
634644
observer.observe(node)
635645
return () => {
636646
observer.disconnect()
637-
node.removeEventListener('scroll', updateOverflow)
647+
node.removeEventListener('scroll', handleScroll)
638648
}
639-
}, [regularTabs.length, revealActiveTab, updateOverflow])
649+
}, [regularTabs.length, revealActiveTab, stopRevealScroll, updateOverflow])
640650

641651
useEffect(() => {
642652
const strip = stripRef.current
@@ -658,12 +668,7 @@ export function TabStrip({
658668
event.preventDefault()
659669
}
660670
strip.addEventListener('wheel', handleWheel, { passive: false })
661-
// Touch, pen, and scrollbar drags scroll natively without a wheel event.
662-
strip.addEventListener('pointerdown', stopRevealScroll)
663-
return () => {
664-
strip.removeEventListener('wheel', handleWheel)
665-
strip.removeEventListener('pointerdown', stopRevealScroll)
666-
}
671+
return () => strip.removeEventListener('wheel', handleWheel)
667672
}, [stopRevealScroll, updateOverflow])
668673

669674
const handleDragStart = useCallback(

0 commit comments

Comments
 (0)