ScrollArea
A custom scrollable container with styled scrollbars for vertical and horizontal overflow.
The ScrollArea component wraps React Native's ScrollView with custom-styled scrollbar indicators. It tracks scroll position, content size, and viewport dimensions via context, and renders a ScrollBar thumb that reflects the current scroll state.
Preview
Tags
Installation
npx novaui-cli add scroll-areaImport
import { ScrollArea, ScrollBar } from 'novaui-components'Basic Usage
The ScrollArea is a compound component with these parts:
ScrollArea— Root container withrelative flex-1styling that wraps aScrollViewwithflex-1 rounded-[inherit]ScrollBar— Custom scrollbar thumb indicator positioned absolutely withabsolute touch-none p-0.5
Tags
import { View, Text } from 'react-native'
import { ScrollArea } from 'novaui-components'
import { Separator } from 'novaui-components'
const tags = [
'v1.0.0-beta.1',
'v1.0.0-beta.2',
'v1.0.0-beta.3',
'v1.0.0-rc.1',
'v1.0.0-rc.2',
'v1.0.0',
'v1.1.0',
'v1.2.0',
'v1.3.0',
'v2.0.0',
]
export function BasicScrollArea() {
return (
<ScrollArea className="h-48 w-full max-w-sm rounded-md border border-border">
<View className="p-4">
<Text className="mb-4 text-sm font-medium leading-none text-foreground">
Tags
</Text>
{tags.map((tag) => (
<View key={tag}>
<Text className="text-sm text-foreground">{tag}</Text>
<Separator className="my-2" />
</View>
))}
</View>
</ScrollArea>
)
}Horizontal Scrolling
Use horizontal on the ScrollArea and add a horizontal ScrollBar:
import { View, Text } from 'react-native'
import { ScrollArea, ScrollBar } from 'novaui-components'
const items = ['Item 1', 'Item 2', 'Item 3', 'Item 4', 'Item 5', 'Item 6']
export function HorizontalScrollArea() {
return (
<ScrollArea className="w-full max-w-md rounded-md border border-border" horizontal>
<View className="flex-row gap-4 p-4">
{items.map((item) => (
<View
key={item}
className="h-20 w-36 shrink-0 items-center justify-center rounded-md bg-muted"
>
<Text className="text-sm text-foreground">{item}</Text>
</View>
))}
</View>
<ScrollBar orientation="horizontal" />
</ScrollArea>
)
}With Custom Content
Use ScrollArea for any overflowing content such as a chat log or settings list:
import { View, Text } from 'react-native'
import { ScrollArea } from 'novaui-components'
export function ChatScrollArea() {
return (
<ScrollArea className="h-56 w-full max-w-sm rounded-lg border border-border">
<View className="flex-col gap-3 p-4">
<View className="gap-1 rounded-md bg-muted p-3">
<Text className="text-xs font-medium text-foreground">Alice</Text>
<Text className="text-sm text-muted-foreground">
Hey, how's it going?
</Text>
</View>
<View className="gap-1 rounded-md bg-primary/10 p-3 self-end">
<Text className="text-xs font-medium text-foreground">You</Text>
<Text className="text-sm text-muted-foreground">
Pretty good! Working on the UI.
</Text>
</View>
{/* ... more messages */}
</View>
</ScrollArea>
)
}Props API
ScrollArea Props
Extends React.ComponentPropsWithoutRef<typeof ScrollView>:
| Prop | Type | Default | Description |
|---|---|---|---|
className | string | - | Additional CSS classes for the outer container (base: relative flex-1) |
viewportClassName | string | - | Additional CSS classes for the inner ScrollView (base: flex-1 rounded-[inherit]) |
horizontal | boolean | false | Enable horizontal scrolling |
children | ReactNode | - | Content and optional ScrollBar components |
ScrollBar Props
Extends React.ComponentPropsWithoutRef<typeof View>:
| Prop | Type | Default | Description |
|---|---|---|---|
orientation | 'vertical' | 'horizontal' | 'vertical' | Direction of the scrollbar |
className | string | - | Additional CSS classes (vertical base: right-0 top-0 h-full w-2.5 border-l border-l-transparent, horizontal base: bottom-0 left-0 h-2.5 w-full flex-row border-t border-t-transparent) |
Best Practices
-
Set a fixed height: The
ScrollAreaneeds a constrained height (or width for horizontal) to enable scrolling. UseclassName="h-48"or similar. -
Default scrollbar: If no
ScrollBarchild is provided, a verticalScrollBaris rendered automatically. -
Hide native indicators: The component sets
showsVerticalScrollIndicator={false}andshowsHorizontalScrollIndicator={false}by default to avoid double scrollbars. -
Horizontal scroll: Pass
horizontaltoScrollAreaand add<ScrollBar orientation="horizontal" />as a child. -
Performance: The scroll event throttle is set to 16ms (60fps). For lists with many items, consider using
FlatListinstead.
Related Components
- Use
Separatorto divide items within a scrollable list - Combine with
Cardto create scrollable card content - Use
Tablefor scrollable tabular data