From a8c4183aa3c445897886d1ab4a3008828fc75547 Mon Sep 17 00:00:00 2001 From: Liam Fitzgerald Date: Tue, 29 Jun 2021 15:10:41 +1000 Subject: [PATCH] VirtualScroller: working scrollbar Fixes urbit/landscape#559 --- .../src/views/components/VirtualScroller.tsx | 70 ++++++++++++++++--- 1 file changed, 59 insertions(+), 11 deletions(-) diff --git a/pkg/interface/src/views/components/VirtualScroller.tsx b/pkg/interface/src/views/components/VirtualScroller.tsx index b20a32d24a..bec4b26f52 100644 --- a/pkg/interface/src/views/components/VirtualScroller.tsx +++ b/pkg/interface/src/views/components/VirtualScroller.tsx @@ -15,6 +15,19 @@ const ScrollbarLessBox = styled(Box)` } `; +const Scrollbar = styled(Box)` + &:hover { + width: 8px; + } + z-index: 3; + width: 4px; + border-radius: 999px; + right: 0; + height: 50px; + position: absolute; + pointer: cursor; +`; + interface RendererProps { index: K; scrollWindow: any; @@ -162,6 +175,8 @@ export default class VirtualScroller extends Component) { super(props); this.state = { @@ -200,6 +215,39 @@ export default class VirtualScroller extends Component { + this.scrollRef.setPointerCapture(e.pointerId); + this.scrollDragging = true; + } + + onUp = (e: PointerEvent) => { + this.scrollRef.releasePointerCapture(e.pointerId); + this.scrollDragging = false; + } + + onMove = (e: MouseEvent) => { + if(!this.scrollDragging) { + return; + } + const scrollProgress = e.movementY / this.window.offsetHeight; + const scrollDir = this.props.origin === 'top' ? 1 : -1; + const windowScroll = scrollDir * scrollProgress * this.window.scrollHeight; + this.window.scrollBy(0, windowScroll); + } + + setScrollRef = (el: HTMLDivElement | null) => { + if(!el) { + this.scrollRef.removeEventListener('pointerdown', this.onDown); + this.scrollRef.removeEventListener('pointermove', this.onMove); + this.scrollRef.removeEventListener('pointerup', this.onUp); + this.scrollRef = null; + return; + } + this.scrollRef = el; + this.scrollRef.addEventListener('pointerdown', this.onDown); + this.scrollRef.addEventListener('pointermove', this.onMove); + this.scrollRef.addEventListener('pointerup', this.onUp); + } // manipulate scrollbar manually, to dodge change detection updateScroll = IS_IOS ? () => {} : _.throttle(() => { if(!this.window || !this.scrollRef) { @@ -207,12 +255,15 @@ export default class VirtualScroller extends Component, _prevState: VirtualScrollerState) { @@ -568,13 +619,10 @@ export default class VirtualScroller extends Component - {!IS_IOS && ( { - this.scrollRef = el; -}} -right={0} height="50px" -position="absolute" width="4px" -backgroundColor="lightGray" + {!IS_IOS && ()}