Skip to content

ScrollArea ​

Augments native scroll functionality for custom, cross-browser styling.
Tags
v1.2.0-beta.50
v1.2.0-beta.49
v1.2.0-beta.48
v1.2.0-beta.47
v1.2.0-beta.46
v1.2.0-beta.45
v1.2.0-beta.44
v1.2.0-beta.43
v1.2.0-beta.42
v1.2.0-beta.41
v1.2.0-beta.40
v1.2.0-beta.39
v1.2.0-beta.38
v1.2.0-beta.37
v1.2.0-beta.36
v1.2.0-beta.35
v1.2.0-beta.34
v1.2.0-beta.33
v1.2.0-beta.32
v1.2.0-beta.31
v1.2.0-beta.30
v1.2.0-beta.29
v1.2.0-beta.28
v1.2.0-beta.27
v1.2.0-beta.26
v1.2.0-beta.25
v1.2.0-beta.24
v1.2.0-beta.23
v1.2.0-beta.22
v1.2.0-beta.21
v1.2.0-beta.20
v1.2.0-beta.19
v1.2.0-beta.18
v1.2.0-beta.17
v1.2.0-beta.16
v1.2.0-beta.15
v1.2.0-beta.14
v1.2.0-beta.13
v1.2.0-beta.12
v1.2.0-beta.11
v1.2.0-beta.10
v1.2.0-beta.9
v1.2.0-beta.8
v1.2.0-beta.7
v1.2.0-beta.6
v1.2.0-beta.5
v1.2.0-beta.4
v1.2.0-beta.3
v1.2.0-beta.2
v1.2.0-beta.1
vue
vue
<script setup lang="ts">
import { ScrollAreaRoot, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport } from '@oku-ui/primitives'

const tags = Array.from({ length: 50 }).map((_, i, a) => `v1.2.0-beta.${a.length - i}`)
</script>

<template>
  <ScrollAreaRoot
    class="w-[200px] h-[225px] rounded overflow-hidden shadow-[0_2px_10px] shadow-blackA7 bg-white"
    style="--scrollbar-size: 10px"
  >
    <ScrollAreaViewport class="w-full h-full rounded">
      <div class="py-[15px] px-5">
        <div class="text-mauve12 text-[15px] leading-[18px] font-semibold">
          Tags
        </div>
        <div
          v-for="tag in tags"
          :key="tag"
          class="text-mauve12 text-[13px] leading-[18px] mt-2.5 pt-2.5 border-t border-t-mauve6"
        >
          {{ tag }}
        </div>
      </div>
    </ScrollAreaViewport>
    <ScrollAreaScrollbar
      class="flex select-none touch-none p-0.5 bg-blackA6 transition-colors duration-[160ms] ease-out hover:bg-blackA8 data-[orientation=vertical]:w-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:h-2.5"
      orientation="vertical"
    >
      <ScrollAreaThumb
        class="flex-1 bg-mauve10 rounded-[10px] relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]"
      />
    </ScrollAreaScrollbar>
    <ScrollAreaScrollbar
      class="flex select-none touch-none p-0.5 bg-blackA6 transition-colors duration-[160ms] ease-out hover:bg-blackA8 data-[orientation=vertical]:w-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:h-2.5"
      orientation="horizontal"
    >
      <ScrollAreaThumb
        class="flex-1 bg-mauve10 rounded-[10px] relative before:content-[''] before:absolute before:top-1/2 before:left-1/2 before:-translate-x-1/2 before:-translate-y-1/2 before:w-full before:h-full before:min-w-[44px] before:min-h-[44px]"
      />
    </ScrollAreaScrollbar>
  </ScrollAreaRoot>
</template>

Features ​

  • Scrollbar sits on top of the scrollable content, taking up no space.
  • Scrolling is native; no underlying position movements via CSS transformations.
  • Shims pointer behaviors only when interacting with the controls, so keyboard controls are unaffected.
  • Supports Right to Left direction.

Installation ​

Install the component from your command line.

sh
sh
$ npm add @oku-ui/primitives

Anatomy ​

Import all parts and piece them together.

vue
vue
<script setup>
import { ScrollAreaRoot, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport } from '@oku-ui/primitives'
</script>

<template>
  <ScrollAreaRoot>
    <ScrollAreaViewport />
    <ScrollAreaScrollbar orientation="horizontal">
      <ScrollAreaThumb />
    </ScrollAreaScrollbar>
    <ScrollAreaScrollbar orientation="vertical">
      <ScrollAreaThumb />
    </ScrollAreaScrollbar>
    <ScrollAreaCorner />
  </ScrollAreaRoot>
</template>

API Reference ​

Root ​

Contains all the parts of a scroll area.

PropDefaultType
dir
'ltr' | 'rtl'
scrollHideDelay
number
type
'scroll' | 'auto' | 'always' | 'hover'

Viewport ​

The viewport area of the scroll area.

Scrollbar ​

The vertical scrollbar. Add a second Scrollbar with an orientation prop to enable horizontal scrolling.

PropDefaultType
orientation
'horizontal' | 'vertical'
Data AttributeValue
[data-state]"visible" | "hidden"
[data-orientation]"vertical" | "horizontal"

Thumb ​

The thumb to be used in ScrollAreaScrollbar.

PropDefaultType
forceMount
boolean

Used to force mounting when more control is needed. Useful when controlling animation with React animation libraries.

Data AttributeValue
[data-state]"visible" | "hidden"

Corner ​

The corner where both vertical and horizontal scrollbars meet.

Accessibility ​

In most cases, it's best to rely on native scrolling and work with the customization options available in CSS. When that isn't enough, ScrollArea provides additional customizability while maintaining the browser's native scroll behavior (as well as accessibility features, like keyboard scrolling).

Keyboard Interactions ​

Scrolling via keyboard is supported by default because the component relies on native scrolling. Specific keyboard interactions may differ between platforms, so we do not specify them here or add specific event listeners to handle scrolling via key events.