You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
svelte-kit-vice/src/uix/soma/components/scroll-area
dev c703e2e7ff
fix(scroll-area): split mount-vs-visibility — the real type='scroll' / 'hover' bug
5 months ago
..
components fix(scroll-area): split mount-vs-visibility — the real type='scroll' / 'hover' bug 5 months ago
README.md Advance Eidos component migration 5 months ago
exports.ts Move Soma public types out of providers 5 months ago
index.ts soma: 10 new components, README docs for all 22, PrimitiveAnchorAttributes 6 months ago
langs.ts soma: gesture layer, drawer component, full audit fixes across 26 components 6 months ago
scroll-area-provider.svelte.test.ts fix(scroll-area): split mount-vs-visibility — the real type='scroll' / 'hover' bug 5 months ago
scroll-area-provider.svelte.ts fix(scroll-area): split mount-vs-visibility — the real type='scroll' / 'hover' bug 5 months ago
types.ts Move Soma public types out of providers 5 months ago

README.md

ScrollArea

Custom scrollbar component that replaces native scrollbars with styled ones. Supports both axes simultaneously, visibility modes, thumb drag, position tracking, and ARIA scrollbar semantics.

Anatomy

<ScrollArea.Provider>
	<ScrollArea.Viewport>
		<!-- scrollable content -->
	</ScrollArea.Viewport>

	<ScrollArea.Scrollbar orientation="vertical">
		<ScrollArea.Thumb />
	</ScrollArea.Scrollbar>

	<ScrollArea.Scrollbar orientation="horizontal">
		<ScrollArea.Thumb />
	</ScrollArea.Scrollbar>

	<ScrollArea.Corner />
</ScrollArea.Provider>

Native scrollbars are hidden via CSS. Custom scrollbars are positioned absolutely within the root container.

Parts

Part Element Description
Provider <div> Root container. Manages type, delay, overflow tracking. Position: relative.
Viewport <div> Scrollable content area. Native scrollbars hidden. Reports scroll position and content size.
Scrollbar <div> Custom scrollbar track. One per axis. ARIA scrollbar role. Handles click-to-scroll.
Thumb <div> Draggable scroll thumb. Size proportional to viewport/content ratio. Pointer capture drag.
Corner <div> Fills space where horizontal and vertical scrollbars meet. Only visible when both axes overflow.

ARIA

Part Attribute Value
Scrollbar role scrollbar
Scrollbar aria-controls ID of Viewport
Scrollbar aria-valuenow Current scroll percentage (0-100)
Scrollbar aria-valuemin 0
Scrollbar aria-valuemax 100
Scrollbar aria-orientation horizontal | vertical

Data Attributes

Part Attribute Values
Provider data-scroll-area Always present
Provider data-overflow-x Present when content overflows horizontally
Provider data-overflow-y Present when content overflows vertically
Viewport data-scroll-area-viewport Always present
Viewport data-at-top Present when scrolled to top
Viewport data-at-bottom Present when scrolled to bottom
Viewport data-at-left Present when scrolled to left edge
Viewport data-at-right Present when scrolled to right edge
Viewport data-overflow-x Present when content overflows horizontally
Viewport data-overflow-y Present when content overflows vertically
Scrollbar data-scroll-area-scrollbar Always present
Scrollbar data-state visible | hidden
Scrollbar data-orientation horizontal | vertical
Scrollbar data-hover Present when hovered
Scrollbar data-dragging Present when thumb is being dragged
Scrollbar data-overflow-x Present when content overflows horizontally
Scrollbar data-overflow-y Present when content overflows vertically
Thumb data-scroll-area-thumb Always present
Thumb data-state visible | hidden
Thumb data-orientation horizontal | vertical
Thumb data-hover Present when scrollbar is hovered
Thumb data-dragging Present when being dragged
Corner data-scroll-area-corner Always present
Corner data-state visible | hidden

CSS Variables

Variable Part Description
--scroll-area-corner-width Provider Corner width (scrollbar size when both axes overflow)
--scroll-area-corner-height Provider Corner height
--scroll-area-scrollbar-size Provider (consumer sets) Scrollbar track width/height (default 8px)
--scroll-area-thumb-width Thumb Computed thumb width
--scroll-area-thumb-height Thumb Computed thumb height

Keyboard

Keyboard scrolling uses native browser behavior (arrow keys, Page Up/Down, Home/End, Space) on the viewport. No custom keyboard handlers on the scrollbar.

Behavior

Visibility modes

Mode Behavior
hover Show scrollbars when pointer enters the root area. Hide after delay.
scroll Show scrollbars during active scrolling. Hide after delay.
auto Always visible when content overflows.
always Permanently visible regardless of overflow.

Thumb size

Proportional to the visible area: thumbSize = trackLength * (viewportSize / contentSize). Minimum 20px to remain clickable.

Thumb drag

Uses pointer capture for reliable tracking. The scroll position updates proportionally to thumb displacement on the track.

Click on track

Clicking on the scrollbar track (not the thumb) scrolls to that position proportionally.

Position tracking

The viewport exposes data-at-top, data-at-bottom, data-at-left, data-at-right for styling scroll shadows or sticky headers.

Usage

Basic (vertical only)

<script>
	import { ScrollArea } from '$soma/components';
</script>

<ScrollArea.Provider>
	<ScrollArea.Viewport>
		<!-- long content -->
	</ScrollArea.Viewport>
	<ScrollArea.Scrollbar orientation="vertical">
		<ScrollArea.Thumb />
	</ScrollArea.Scrollbar>
</ScrollArea.Provider>

Both axes

<ScrollArea.Provider>
	<ScrollArea.Viewport>
		<!-- wide + tall content -->
	</ScrollArea.Viewport>
	<ScrollArea.Scrollbar orientation="vertical">
		<ScrollArea.Thumb />
	</ScrollArea.Scrollbar>
	<ScrollArea.Scrollbar orientation="horizontal">
		<ScrollArea.Thumb />
	</ScrollArea.Scrollbar>
	<ScrollArea.Corner />
</ScrollArea.Provider>

Always visible

<ScrollArea.Provider type="always">
	<!-- scrollbars always shown -->
</ScrollArea.Provider>

Auto (visible when overflowing)

<ScrollArea.Provider type="auto">
	<!-- scrollbars shown only when content overflows -->
</ScrollArea.Provider>

Scroll shadows via position tracking

[data-scroll-area-viewport]:not([data-at-top]) {
	box-shadow: inset 0 8px 6px -6px rgba(0, 0, 0, 0.1);
}
[data-scroll-area-viewport]:not([data-at-bottom]) {
	box-shadow: inset 0 -8px 6px -6px rgba(0, 0, 0, 0.1);
}

Comparison with reference libraries

Feature Radix Ark Bits Soma
Parts Root, Viewport, Scrollbar, Thumb, Corner Root, Viewport, Scrollbar, Thumb, Corner Root, Viewport, Scrollbar, Thumb, Corner Provider, Viewport, Scrollbar, Thumb, Corner
Visibility modes hover/scroll/auto/always Custom (context) hover/scroll/auto/always hover/scroll/auto/always
scrollHideDelay Yes (600ms) No Yes (600ms) Yes (600ms)
dir (RTL) Yes No Yes Yes
forceMount on Scrollbar No No Yes Yes
ARIA scrollbar role Yes No (context) Implicit Yes
aria-valuenow/min/max Yes No No Yes
aria-orientation Yes Yes Implicit Yes
data-state visible/hidden Yes No Yes Yes
data-hover No Yes No Yes
data-dragging No Yes No Yes
data-overflow-x/y No Yes No Yes
data-at-top/bottom/left/right No Yes No Yes
CSS vars (corner) Yes Yes No Yes
CSS vars (thumb size) No Yes No Yes
Click on track Yes Yes Yes Yes
Thumb drag (pointer capture) Yes Yes Yes Yes
Position tracking No Yes (context API) No Yes (data-* attrs)
Both axes simultaneously Yes Yes Yes Yes
Pointer capture cleanup Yes Yes (v2.15.5) Yes Yes

Powered by TurnKey Linux.