| 1 | import { ScrollArea as Primitive } from "radix-ui"; |
| 2 | import type { ComponentProps } from "react"; |
| 3 | |
| 4 | import { cn } from "../../lib/cn"; |
| 5 | |
| 6 | // shadcn/ui's scroll area, styled with g1t's tokens: a box that scrolls |
| 7 | // with a thin bar of its own, the same on every platform, for a list in a |
| 8 | // panel or a sidebar. Plain `overflow-y-auto` with `[scrollbar-width:thin]` |
| 9 | // does for most of the site; this is for where the bar must sit inside |
| 10 | // rounded corners or stay out of the way until hovered. |
| 11 | |
| 12 | export function ScrollArea({ className, children, ...props }: ComponentProps<typeof Primitive.Root>) { |
| 13 | return ( |
| 14 | <Primitive.Root data-slot="scroll-area" className={cn("relative overflow-hidden", className)} {...props}> |
| 15 | <Primitive.Viewport data-slot="scroll-area-viewport" className="size-full rounded-[inherit] outline-none focus-visible:ring-2 focus-visible:ring-accent"> |
| 16 | {children} |
| 17 | </Primitive.Viewport> |
| 18 | <ScrollBar /> |
| 19 | <Primitive.Corner /> |
| 20 | </Primitive.Root> |
| 21 | ); |
| 22 | } |
| 23 | |
| 24 | export function ScrollBar({ className, orientation = "vertical", ...props }: ComponentProps<typeof Primitive.Scrollbar>) { |
| 25 | return ( |
| 26 | <Primitive.Scrollbar |
| 27 | data-slot="scroll-area-scrollbar" |
| 28 | orientation={orientation} |
| 29 | className={cn( |
| 30 | "flex touch-none p-px transition-colors select-none", |
| 31 | orientation === "vertical" && "h-full w-2 border-l border-l-transparent", |
| 32 | orientation === "horizontal" && "h-2 flex-col border-t border-t-transparent", |
| 33 | className, |
| 34 | )} |
| 35 | {...props} |
| 36 | > |
| 37 | <Primitive.Thumb data-slot="scroll-area-thumb" className="relative flex-1 rounded-full bg-line-strong" /> |
| 38 | </Primitive.Scrollbar> |
| 39 | ); |
| 40 | } |