Skip to content

ScrollArea

A custom scrollable container providing styled scrollbar overlays with drag-to-scroll support, configurable visibility behavior, and optional fade mask gradients at scroll boundaries. Designed for editor panels, sidebars, and content areas that need polished scrolling behavior beyond native scrollbars.

Live Preview

Import

import { ScrollArea } from 'entangle-ui';

Usage

<ScrollArea maxHeight={300}>
<div>
{/* Long content that overflows */}
{items.map(item => (
<Item key={item.id} {...item} />
))}
</div>
</ScrollArea>

Scroll Direction

Control which axes can scroll using the direction prop.

{
/* Vertical only (default) */
}
<ScrollArea direction="vertical" maxHeight={200}>
<LongVerticalContent />
</ScrollArea>;
{
/* Horizontal only */
}
<ScrollArea direction="horizontal" maxWidth={400}>
<WideHorizontalContent />
</ScrollArea>;
{
/* Both axes */
}
<ScrollArea direction="both" maxHeight={300} maxWidth={500}>
<LargeContent />
</ScrollArea>;

Scrollbar Visibility

The scrollbarVisibility prop controls when custom scrollbars appear.

{
/* Auto: show on scroll/hover, hide after delay (default) */
}
<ScrollArea scrollbarVisibility="auto" maxHeight={200}>
<Content />
</ScrollArea>;
{
/* Always visible */
}
<ScrollArea scrollbarVisibility="always" maxHeight={200}>
<Content />
</ScrollArea>;
{
/* Show only on hover */
}
<ScrollArea scrollbarVisibility="hover" maxHeight={200}>
<Content />
</ScrollArea>;
{
/* Never show scrollbars (still scrollable via wheel/touch) */
}
<ScrollArea scrollbarVisibility="never" maxHeight={200}>
<Content />
</ScrollArea>;
ModeBehavior
autoShows on scroll or hover, auto-hides after delay
alwaysScrollbars always visible when content overflows
hoverShows only while the mouse is over the scroll area
neverScrollbars hidden entirely (scroll still works via wheel/touch/keyboard)

Auto-hide Delay

When using scrollbarVisibility="auto", control the delay before scrollbars fade out.

<ScrollArea scrollbarVisibility="auto" hideDelay={2000} maxHeight={200}>
<Content />
</ScrollArea>

Fade Masks

Enable gradient fade masks at scroll boundaries to visually indicate more content is available.

<ScrollArea fadeMask maxHeight={200}>
<Content />
</ScrollArea>;
{
/* Custom fade mask size */
}
<ScrollArea fadeMask fadeMaskHeight={40} maxHeight={200}>
<Content />
</ScrollArea>;

Fade masks appear at the top/bottom for vertical scrolling and left/right for horizontal scrolling. They automatically hide when the user has scrolled to the edge.

Scrollbar Customization

Fine-tune the scrollbar appearance with width, padding, and minimum thumb length.

<ScrollArea
scrollbarWidth={8}
scrollbarPadding={3}
minThumbLength={40}
maxHeight={300}
>
<Content />
</ScrollArea>

Auto Fill

When placed inside a flex or grid layout, use autoFill to make the scroll area fill its parent container.

<Flex direction="column" fullHeight>
<Header />
<ScrollArea autoFill>
<MainContent />
</ScrollArea>
<Footer />
</Flex>

Scroll Callbacks

React to scroll position changes and boundary events.

<ScrollArea
maxHeight={300}
onScroll={e => console.log('Scrolled:', e.currentTarget.scrollTop)}
onScrollTop={() => console.log('Reached top')}
onScrollBottom={() => loadMoreItems()}
>
<Content />
</ScrollArea>

The onScrollBottom callback is useful for implementing infinite scrolling patterns.

Props

Prop Type Default Description
children ReactNode Scrollable content. Required.
direction 'vertical' | 'horizontal' | 'both' 'vertical' Which axes can scroll.
scrollbarVisibility 'auto' | 'always' | 'hover' | 'never' 'auto' Scrollbar visibility behavior.
hideDelay number 1000 Delay in milliseconds before scrollbar auto-hides. Only applies when scrollbarVisibility is "auto".
scrollbarWidth number 6 Scrollbar track width in pixels.
minThumbLength number 30 Minimum scrollbar thumb length in pixels.
scrollbarPadding number 2 Padding between scrollbar track and content edge in pixels.
fadeMask boolean false Whether to show gradient fade masks at scroll boundaries.
fadeMaskHeight number 24 Height of the fade mask gradient in pixels.
maxHeight number | string Maximum height of the scroll area. Required to enable vertical scrolling.
maxWidth number | string Maximum width of the scroll area. Required to enable horizontal scrolling.
autoFill boolean false When true, sets width and height to 100% to fill the parent container.
onScroll (event: UIEvent<HTMLDivElement>) => void Callback fired when the scroll position changes.
onScrollTop () => void Callback fired when scroll reaches the top edge.
onScrollBottom () => void Callback fired when scroll reaches the bottom edge.
className string Additional CSS class names applied to the root element.
style CSSProperties Inline styles applied to the root element.
testId string Test identifier for automated testing.
ref Ref<HTMLDivElement> Ref to the scrollable viewport element.

The component also accepts all standard HTML <div> attributes on the root element.

Accessibility

  • The scrollable viewport has role="region" and tabIndex={0} for keyboard accessibility
  • Custom scrollbar tracks have role="scrollbar" with proper aria-controls, aria-orientation, aria-valuenow, aria-valuemin, and aria-valuemax attributes
  • Content remains scrollable via keyboard (arrow keys, Page Up/Down, Home/End) regardless of scrollbar visibility setting
  • Scrollbar thumb supports pointer drag interaction for precise scroll positioning