- Home
- Primitives
- Scroll Area
- Examples
Scroll Area
Basic scroll area example demonstrating core behavior.
Examples
import * as ScrollArea from "@solidiom/scroll-area"
;<ScrollArea.Root type="hover">
<ScrollArea.Viewport style={{ height: 300 }}>
<div style={{ padding: 16 }}>
{Array.from({ length: 50 }, (_, i) => (
<p key={i}>Line {i + 1} of scrollable content.</p>
))}
</div>
</ScrollArea.Viewport>
<ScrollArea.Scrollbar orientation="vertical">
<ScrollArea.Thumb />
</ScrollArea.Scrollbar>
<ScrollArea.Scrollbar orientation="horizontal">
<ScrollArea.Thumb />
</ScrollArea.Scrollbar>
</ScrollArea.Root>The scrollbar visibility is controlled by the type prop: “auto” (overflow only), “always”, “hover” (default), or “scroll” (visible during scroll then hides after scrollHideDelay ms).
View source
export function Root(props: ScrollAreaRootProps) {
const type = props.type ?? "hover"
const scrollHideDelay = props.scrollHideDelay ?? 600
const [viewportRef, setViewportRef] = createSignal<HTMLDivElement | undefined>(undefined)
const [scrollHeight, setScrollHeight] = createSignal(0)
const [scrollWidth, setScrollWidth] = createSignal(0)
const [viewportHeight, setViewportHeight] = createSignal(0)
const [viewportWidth, setViewportWidth] = createSignal(0)
const [scrollTop, setScrollTop] = createSignal(0)
const [scrollLeft, setScrollLeft] = createSignal(0)
const [isHovered, setIsHovered] = createSignal(false)
const [isScrolling, setIsScrolling] = createSignal(false)
let scrollTimer: ReturnType<typeof setTimeout> | undefined
const updateMeasurements = () => {
const el = viewportRef()
if (!el) return
setScrollHeight(el.scrollHeight)
setScrollWidth(el.scrollWidth)
setViewportHeight(el.clientHeight)
setViewportWidth(el.clientWidth)
}
const updateScrollPosition = () => {
const el = viewportRef()
if (!el) return
setScrollTop(el.scrollTop)
setScrollLeft(el.scrollLeft)
}
const notifyScrollStart = () => {
setIsScrolling(true)
if (scrollTimer !== undefined) clearTimeout(scrollTimer)
scrollTimer = setTimeout(() => {
setIsScrolling(false)
}, scrollHideDelay)
}
return (
<ScrollAreaContext
value={{
viewportRef,
setViewportRef,
scrollHeight,
scrollWidth,
viewportHeight,
viewportWidth,
scrollTop,
scrollLeft,
type,
isHovered,
isScrolling,
scrollHideDelay,
updateMeasurements,
updateScrollPosition,
notifyScrollStart,
}}
>
<div
class={props.class}
style={{
position: "relative",
overflow: "hidden",
...(typeof props.style === "object" ? props.style : {}),
}}
onPointerEnter={() => setIsHovered(true)}
onPointerLeave={() => setIsHovered(false)}
{...applySemanticAttrs({
scope: "scroll-area",
part: "root",
})}
>
{props.children}
</div>
</ScrollAreaContext>
)
}