UIPackage

Scroll Area

Vue layout
Edit on GitHub

Custom scrollbar that always renders the same way across OSes (no flashing native scrollbars on Windows). Use for sidebars, dropdown content, and any overflow region you want to feel consistent.

Also available for React ->

Installation

$ npx shadcn-vue@latest add https://uipkge.dev/r/vue/scroll-area.json

Or with the named registry: npx shadcn-vue@latest add @uipkge/scroll-area

Examples

Props

Name Type / Values Default Required
class HTMLAttributes['class'] optional

Dependencies

Used by

Files (3)

  • app/components/ui/scroll-area/ScrollArea.vue 0.9 kB
    <script setup lang="ts">
    import type { ScrollAreaRootProps } from 'reka-ui'
    import type { HTMLAttributes } from 'vue'
    import { reactiveOmit } from '@vueuse/core'
    import { ScrollAreaCorner, ScrollAreaRoot, ScrollAreaViewport } from 'reka-ui'
    import { cn } from '@/lib/utils'
    import ScrollBar from './ScrollBar.vue'
    
    const props = defineProps<ScrollAreaRootProps & { class?: HTMLAttributes['class'] }>()
    
    const delegatedProps = reactiveOmit(props, 'class')
    </script>
    
    <template>
      <ScrollAreaRoot data-uipkge data-slot="scroll-area" v-bind="delegatedProps" :class="cn('relative', props.class)">
        <ScrollAreaViewport
          data-uipkge
          data-slot="scroll-area-viewport"
          class="focus-visible:ring-ring/50 size-full rounded-[inherit] transition-[color,box-shadow] outline-none focus-visible:ring-[3px] focus-visible:outline-1"
        >
          <slot />
        </ScrollAreaViewport>
        <ScrollBar />
        <ScrollAreaCorner />
      </ScrollAreaRoot>
    </template>
  • app/components/ui/scroll-area/ScrollBar.vue 1 kB
    <script setup lang="ts">
    import type { ScrollAreaScrollbarProps } from 'reka-ui'
    import type { HTMLAttributes } from 'vue'
    import { reactiveOmit } from '@vueuse/core'
    import { ScrollAreaScrollbar, ScrollAreaThumb } from 'reka-ui'
    import { cn } from '@/lib/utils'
    
    const props = withDefaults(defineProps<ScrollAreaScrollbarProps & { class?: HTMLAttributes['class'] }>(), {
      orientation: 'vertical',
    })
    
    const delegatedProps = reactiveOmit(props, 'class')
    </script>
    
    <template>
      <ScrollAreaScrollbar
        data-uipkge
        data-slot="scroll-area-scrollbar"
        v-bind="delegatedProps"
        :class="
          cn(
            'flex touch-none p-px transition-colors select-none',
            orientation === 'vertical' && 'h-full w-2.5 border-l border-l-transparent',
            orientation === 'horizontal' && 'h-2.5 flex-col border-t border-t-transparent',
            props.class,
          )
        "
      >
        <ScrollAreaThumb data-uipkge data-slot="scroll-area-thumb" class="bg-border relative flex-1 rounded-full" />
      </ScrollAreaScrollbar>
    </template>
  • app/components/ui/scroll-area/index.ts 0.1 kB
    export { default as ScrollArea } from './ScrollArea.vue'
    export { default as ScrollBar } from './ScrollBar.vue'

Raw manifest: https://uipkge.dev/r/vue/scroll-area.json