{
  "$schema": "https://ui.shadcn.com/schema/registry-item.json",
  "name": "scroll-area",
  "title": "Scroll Area",
  "description": "A native scroller with a thin themed overlay scrollbar that thickens under the pointer, and edge fades that appear only when there is more to scroll. Base UI Scroll Area underneath.",
  "dependencies": [
    "@base-ui/react"
  ],
  "registryDependencies": [
    "https://eased.dev/r/eased-tokens.json",
    "https://eased.dev/r/eased-scroll-fade.json"
  ],
  "files": [
    {
      "path": "src/registry/eased/scroll-area/scroll-area.tsx",
      "content": "\"use client\";\n\nimport { ScrollArea as Base } from \"@base-ui/react/scroll-area\";\nimport type { CSSProperties, ReactNode, Ref } from \"react\";\nimport { scrollFadeMask, type FadeAxis } from \"../_primitives/scroll-fade/scroll-fade\";\n\nexport type ScrollAreaProps = {\n  children: ReactNode;\n  /** Which way it scrolls. \"both\" draws both bars and fades all four edges. Default \"vertical\". */\n  orientation?: \"vertical\" | \"horizontal\" | \"both\";\n  /** Edge feather in px, drawn only while there is more to scroll that way; 0 turns it off. Default 20. */\n  fade?: number;\n  /** Classes for the root: size it here (`h-64`, `max-h-80`, `flex-1 min-h-0`). */\n  className?: string;\n  /** Classes for the content wrapper: put padding here so it scrolls with the content. */\n  contentClassName?: string;\n  /** The scrolling element, for `scrollTo`, scroll-linked effects or a Progressive Blur. */\n  viewportRef?: Ref<HTMLDivElement>;\n  /** Accessible name for the scrollable region, which is a keyboard tab stop when it overflows. */\n  \"aria-label\"?: string;\n  \"aria-labelledby\"?: string;\n  style?: CSSProperties;\n};\n\nconst AXIS: Record<NonNullable<ScrollAreaProps[\"orientation\"]>, FadeAxis> = { vertical: \"y\", horizontal: \"x\", both: \"both\" };\n\n// The bar is a 10px hit zone; the visible pill is 6px and drawn at 2/3 until the pointer is on\n// the bar, so it thickens under the pointer (scale, not width, so it stays on the compositor).\nconst bar =\n  \"group/bar flex touch-none p-0.5 opacity-0 select-none pointer-events-none transition-opacity duration-(--eased-duration-slow) ease-standard data-hovering:pointer-events-auto data-hovering:opacity-100 data-hovering:duration-(--eased-duration-fast) data-scrolling:pointer-events-auto data-scrolling:opacity-100 data-scrolling:duration-(--eased-duration-instant) reduced:transition-none\";\nconst pill =\n  \"rounded-pill bg-line-strong transition-[scale,background-color] duration-(--eased-duration-fast) ease-standard group-active/bar:bg-text-muted group-active/bar:scale-100 [@media(hover:hover)_and_(pointer:fine)]:group-hover/bar:scale-100 [@media(hover:hover)_and_(pointer:fine)]:group-hover/bar:bg-text-muted reduced:transition-none\";\n\n/**\n * A native scroller with Eased's overlay scrollbar and edge fades. Base UI owns the scrolling,\n * the thumb drag and the keyboard (the viewport is a tab stop that arrow keys scroll); Eased\n * draws a thin themed pill that appears while scrolling or hovering and thickens under the\n * pointer, and feathers each edge only while there is content past it.\n */\nexport function ScrollArea({\n  children,\n  orientation = \"vertical\",\n  fade = 20,\n  className = \"\",\n  contentClassName = \"\",\n  viewportRef,\n  style,\n  ...aria\n}: ScrollAreaProps) {\n  const vertical = orientation !== \"horizontal\";\n  const horizontal = orientation !== \"vertical\";\n\n  return (\n    <Base.Root\n      style={style}\n      className={`relative min-h-0 min-w-0 overflow-hidden -outline-offset-2 has-[[data-eased-viewport]:focus-visible]:outline-2 has-[[data-eased-viewport]:focus-visible]:outline-focus ${className}`}\n    >\n      <Base.Viewport\n        ref={viewportRef}\n        data-eased-viewport=\"\"\n        {...aria}\n        role={aria[\"aria-label\"] || aria[\"aria-labelledby\"] ? \"region\" : undefined}\n        style={{\n          ...(fade > 0 && scrollFadeMask(AXIS[orientation], fade)),\n          // Base UI sets overflow: scroll inline; lock the axis this area does not scroll.\n          ...(!vertical && { overflowY: \"hidden\" }),\n          ...(!horizontal && { overflowX: \"hidden\" }),\n        }}\n        className=\"size-full max-h-[inherit] overscroll-contain outline-none\"\n      >\n        <Base.Content className={contentClassName}>{children}</Base.Content>\n      </Base.Viewport>\n\n      {vertical && (\n        <Base.Scrollbar orientation=\"vertical\" className={`${bar} w-2.5 justify-end`}>\n          <Base.Thumb className=\"flex w-full justify-end\">\n            <span className={`${pill} h-full w-1.5 origin-right scale-x-[0.67]`} />\n          </Base.Thumb>\n        </Base.Scrollbar>\n      )}\n      {horizontal && (\n        <Base.Scrollbar orientation=\"horizontal\" className={`${bar} h-2.5 flex-col justify-end`}>\n          <Base.Thumb className=\"flex h-full flex-col justify-end\">\n            <span className={`${pill} h-1.5 w-full origin-bottom scale-y-[0.67]`} />\n          </Base.Thumb>\n        </Base.Scrollbar>\n      )}\n      {orientation === \"both\" && <Base.Corner />}\n    </Base.Root>\n  );\n}\n",
      "type": "registry:ui",
      "target": "@components/eased/scroll-area/scroll-area.tsx"
    }
  ],
  "docs": "Import ScrollArea from components/eased/scroll-area/scroll-area. Size it with className; give it an aria-label. The Eased tokens were merged into your global CSS; nothing to import.",
  "type": "registry:ui"
}