Skip to content
Corsair UI
Browse the docs

ComponentsNo. 45 of 109

Scroll Area

A scrolling box with thin themed scrollbars that keeps native scrolling.

Installation

pnpm dlx shadcn@latest add @corsair-ui/scroll-area

No setup needed: the CLI finds @corsair-ui in the shadcn registry directory. The files land in your project as source: edit them like your own code. More in Installation.

Also adds
utils
npm
@radix-ui/react-scroll-areaclsxtailwind-merge

Examples

Vertical

Tags (40)

  • tortuga/charts
  • tortuga/soundings
  • tortuga/tides
  • tortuga/wrecks
  • tortuga/reefs
  • nassau/charts
  • nassau/soundings
  • nassau/tides
  • nassau/wrecks
  • nassau/reefs
  • port-royal/charts
  • port-royal/soundings
  • port-royal/tides
  • port-royal/wrecks
  • port-royal/reefs
  • havana/charts
  • havana/soundings
  • havana/tides
  • havana/wrecks
  • havana/reefs
  • cartagena/charts
  • cartagena/soundings
  • cartagena/tides
  • cartagena/wrecks
  • cartagena/reefs
  • maracaibo/charts
  • maracaibo/soundings
  • maracaibo/tides
  • maracaibo/wrecks
  • maracaibo/reefs
  • portobelo/charts
  • portobelo/soundings
  • portobelo/tides
  • portobelo/wrecks
  • portobelo/reefs
  • veracruz/charts
  • veracruz/soundings
  • veracruz/tides
  • veracruz/wrecks
  • veracruz/reefs

Horizontal

With <ScrollBar orientation="horizontal" />.

  • Revenge

    Sloop

    12 guns

  • Queen Anne's Revenge

    Frigate

    40 guns

  • Adventure

    Brigantine

    8 guns

  • Whydah

    Galley

    28 guns

  • Fancy

    Frigate

    46 guns

  • Ranger

    Sloop

    10 guns

  • Royal Fortune

    Ship of the line

    42 guns

API

PropTypeDefault
type

When the scrollbars show.

"hover" | "always" | "scroll" | "auto""hover"
ScrollBar orientation

Add a horizontal one for sideways content.

"vertical" | "horizontal""vertical"

Built on Radix Scroll Area; every prop it takes is passed through.

Accessibility

  • Native scrolling: wheel, touch, and arrow and Page keys once focus is inside.
  • Safari does not put the box in the Tab order: keep something focusable inside when keyboard users must reach it all.
  • The scrollbars are hidden from screen readers; wrap the box in a labelled section when it needs a name.

Compatibility

Tailwind CSS
3.4 and 4, both checked in CI
React
19
Rendering
Client component ("use client")

Source

1 file, installed as source you own
scroll-area.tsxView on GitHub
"use client";
import * as ScrollAreaPrimitive from "@radix-ui/react-scroll-area";
import type { ComponentProps } from "react";
import { cn } from "@/registry/default/lib/utils";
/**
 * A box that scrolls its content with thin, themed scrollbars instead of the
 * platform ones, while keeping native scrolling: wheel, touch, and the arrow
 * and Page keys once focus is inside. The scrollbars show on hover by
 * default; `type` switches to "always", "scroll" (while scrolling) or
 * "auto" (when the content overflows). The viewport shows a focus ring when
 * it takes keyboard focus: current Chrome and Firefox put an overflowing
 * scroll container in the Tab order on their own, Safari does not, so keep
 * something focusable inside (links, buttons) when keyboard users must reach
 * all of the content, and wrap it in a labelled `<section>` when it needs a
 * name. Scrolling itself has no animation.
 *
 * @example
 * <ScrollArea className="h-72 w-48 rounded-md border">
 *   <div className="p-4">{tags.map((tag) => <p key={tag}>{tag}</p>)}</div>
 * </ScrollArea>
 *
 * <ScrollArea className="w-96 whitespace-nowrap">
 *   <div className="flex gap-4">…</div>
 *   <ScrollBar orientation="horizontal" />
 * </ScrollArea>
 */
function ScrollArea({
  className,
  children,
  type = "hover",
  ...props
}: ComponentProps<typeof ScrollAreaPrimitive.Root>) {
  return (
    <ScrollAreaPrimitive.Root
      data-slot="scroll-area"
      type={type}
      className={cn("relative", className)}
      {...props}
    >
      <ScrollAreaPrimitive.Viewport
        data-slot="scroll-area-viewport"
        className={cn(
          "size-full rounded-[inherit] outline-none",
          "transition-[color,box-shadow] motion-reduce:transition-none",
          "focus-visible:ring-ring/50 focus-visible:ring-[3px]"
        )}
      >
        {children}
      </ScrollAreaPrimitive.Viewport>
      <ScrollBar />
      <ScrollAreaPrimitive.Corner data-slot="scroll-area-corner" />
    </ScrollAreaPrimitive.Root>
  );
}
/**
 * A scrollbar for one direction. ScrollArea already has a vertical one; add
 * `<ScrollBar orientation="horizontal" />` inside it for sideways content.
 * The thumb can be dragged; it is hidden from screen readers, which scroll
 * the content directly.
 */
function ScrollBar({
  className,
  orientation = "vertical",
  ...props
}: ComponentProps<typeof ScrollAreaPrimitive.ScrollAreaScrollbar>) {
  return (
    <ScrollAreaPrimitive.ScrollAreaScrollbar
      data-slot="scroll-area-scrollbar"
      orientation={orientation}
      className={cn(
        "flex touch-none p-px transition-colors select-none motion-reduce:transition-none",
        "data-[orientation=vertical]:h-full data-[orientation=vertical]:w-2.5 data-[orientation=vertical]:border-l data-[orientation=vertical]:border-l-transparent",
        "data-[orientation=horizontal]:h-2.5 data-[orientation=horizontal]:flex-col data-[orientation=horizontal]:border-t data-[orientation=horizontal]:border-t-transparent",
        className
      )}
      {...props}
    >
      <ScrollAreaPrimitive.ScrollAreaThumb
        data-slot="scroll-area-thumb"
        className="bg-border relative flex-1 rounded-full"
      />
    </ScrollAreaPrimitive.ScrollAreaScrollbar>
  );
}
export { ScrollArea, ScrollBar };