Skip to content

Instantly share code, notes, and snippets.

@DarlonHenrique
Created August 16, 2023 19:25
Show Gist options
  • Save DarlonHenrique/7389e740e52e62065b5802d251958c95 to your computer and use it in GitHub Desktop.
Save DarlonHenrique/7389e740e52e62065b5802d251958c95 to your computer and use it in GitHub Desktop.
simple scrollview with a custom Scrollbar Using React native, native wind, typescript and math
import { StyledComponent } from "nativewind"
import { ReactNode, useState } from "react"
import {
LayoutChangeEvent,
NativeScrollEvent,
NativeSyntheticEvent,
ScrollView,
View,
} from "react-native"
interface CustomScrollViewProps {
children: ReactNode
className?: string
}
export function CustomScrollView({
children,
...props
}: CustomScrollViewProps) {
const scrollElementHeightPercent = 20
const [contentOffSet, setContentOffSet] = useState({ x: 0, y: 0 })
const [contentHeight, setContentHeight] = useState(0)
const [scrollViewHeight, setScrollViewHeight] = useState(0)
const scrollPercentage = Number(((contentOffSet.y / (contentHeight - scrollViewHeight)) * 100 - scrollElementHeightPercent).toFixed(0))
function handleOnScroll(event: NativeSyntheticEvent<NativeScrollEvent>) {
setContentOffSet(event.nativeEvent.contentOffset)
}
function handleContentSizeChange(_: number, contentHeight: number) {
setContentHeight(contentHeight)
}
function handleLayoutChange(event: LayoutChangeEvent) {
setScrollViewHeight(event.nativeEvent.layout.height)
}
return (
<StyledComponent component={View} className="flex-1 relative" {...props}>
<View className="absolute rounded right-0 bg-alternative-light90 w-1 h-full">
<View
style={{
top: `${scrollPercentage <= 0 ? 0 : scrollPercentage}%`,
height: `${scrollElementHeightPercent}%`
}}
className={`absolute z-50 right-0 rounded bg-primary h-[20px] w-1`}
/>
</View>
<StyledComponent
alwaysBounceVertical={false}
bounces={false}
showsVerticalScrollIndicator={false}
onScroll={handleOnScroll}
onContentSizeChange={handleContentSizeChange}
onLayout={handleLayoutChange}
component={ScrollView}
scrollEventThrottle={16}
className="h-1/2 pr-2"
>
{children}
</StyledComponent>
</StyledComponent>
)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment