Frappe UIFrappe UI

ScrollArea

A styled, cross-browser scroll container: overlay scrollbars that fade in on hover or scroll and stay off native scrollbar rendering differences. A general primitive, not specific to the app shell — DesktopShell uses it for its main content region, and SettingsDialog uses it for a panel body.

Item 1
Item 2
Item 3
Item 4
Item 5
Item 6
Item 7
Item 8
Item 9
Item 10
Item 11
Item 12
Item 13
Item 14
Item 15
Item 16
Item 17
Item 18
Item 19
Item 20
Item 21
Item 22
Item 23
Item 24
Item 25
Item 26
Item 27
Item 28
Item 29
Item 30
vue
<script setup lang="ts">
import { ScrollArea } from 'frappe-ui'

const items = Array.from({ length: 30 }, (_, i) => `Item ${i + 1}`)
</script>

<template>
  <ScrollArea class="h-64 w-64 rounded-5 border bg-surface-base">
    <div class="space-y-1 p-3">
      <div
        v-for="item in items"
        :key="item"
        class="rounded-4 px-2 py-1.5 text-base text-ink-gray-8 hover:bg-surface-gray-2"
      >
        {{ item }}
      </div>
    </div>
  </ScrollArea>
</template>

Pass content as the default slot; orientation picks which scrollbars render (vertical by default). Reach the real scrolling element through the exposed viewportElement when something outside needs it — driving a virtualization library, or registering the region with shellScrollContainer.

ts
const scrollArea = useTemplateRef('scrollArea')
scrollArea.value?.viewportElement // HTMLElement | null

ScrollBar

The scrollbar thumb, rendered internally by ScrollArea — not something apps mount on its own. Exported for the rare case of composing it into a custom scroll root.

Styling

data-slot="scroll-area" / "scroll-area-viewport" / "scroll-area-scrollbar" / "scroll-area-thumb" mark the root, the scrolling viewport, the scrollbar track, and the thumb, for app-level CSS.

API Reference

ScrollArea

Show types
typescript
export interface ScrollAreaProps {
  /** Which scrollbars to render. */
  orientation?: 'vertical' | 'horizontal' | 'both'
  /** Idle delay (ms) before the thumb fades out. */
  scrollHideDelay?: number
  /** Extra classes for the scrolling viewport (e.g. padding). */
  viewportClass?: string
}

export interface ScrollBarProps {
  /** Which axis this bar scrolls. */
  orientation?: 'vertical' | 'horizontal'
}

export interface ScrollAreaExposed {
  /** The element that actually scrolls. Null until mounted. */
  viewportElement: HTMLElement | null
}
orientation
= "vertical"
"vertical" | "horizontal" | "both"

Which scrollbars to render.

scrollHideDelay
= 600
number

Idle delay (ms) before the thumb fades out.

viewportClass
string

Extra classes for the scrolling viewport (e.g. padding).

default

The scrolling content.

ScrollBar

Show types
typescript
export interface ScrollAreaProps {
  /** Which scrollbars to render. */
  orientation?: 'vertical' | 'horizontal' | 'both'
  /** Idle delay (ms) before the thumb fades out. */
  scrollHideDelay?: number
  /** Extra classes for the scrolling viewport (e.g. padding). */
  viewportClass?: string
}

export interface ScrollBarProps {
  /** Which axis this bar scrolls. */
  orientation?: 'vertical' | 'horizontal'
}

export interface ScrollAreaExposed {
  /** The element that actually scrolls. Null until mounted. */
  viewportElement: HTMLElement | null
}
orientation
= "vertical"
"vertical" | "horizontal"

Which axis this bar scrolls.