Scroll shadow
FreeA scroll area whose edges fade only where there is more to see, easing in and out as you reach either end.
pnpm dlx shadcn@latest add https://caliperui.site/r/scroll-shadow.json- Amara Okafor
- Tomás Ferreira
- Kiara Murayama
- Rafael Abreu
- Priya Raman
- Inês Carvalho
- Lukas Weber
- Aoife Byrne
- Noor Haddad
- David Okonkwo
- Sofía Ortega
- Hannah Brooks
AllOpenWaiting on customerNeeds reviewEscalatedClosed this weekArchived
When to use #
Use it for
- Lists and panels with a fixed height.
- Horizontal chip rows and tab bars that can overflow.
Skip it when
- The page itself; the browser already shows where you are.
Installation #
terminal
pnpm dlx shadcn@latest add https://caliperui.site/r/scroll-shadow.json
Adds its 2 files to components/ui/, each with its own stylesheet, and installs their packages. No account needed. The first part also adds Caliper UI’s tokens; import them once as in Installation.
Usage #
This is the code behind the preview above.
example.tsx
import { ScrollShadow } from "@/components/ui/scroll-shadow" const people = ["Amara Okafor", "Tomás Ferreira", "Kiara Murayama", "Rafael Abreu", "Priya Raman", "Inês Carvalho", "Lukas Weber", "Aoife Byrne", "Noor Haddad", "David Okonkwo", "Sofía Ortega", "Hannah Brooks"]; export function ScrollShadowDemo() { return ( <div className="grid w-full max-w-sm gap-4"> <ScrollShadow label="Reviewers" className="h-56 rounded-[12px] shadow-[inset_0_0_0_1px_var(--border)]"> <ul className="grid"> {people.map((name) => ( <li key={name} className="border-b border-border px-4 py-2.5 text-sm last:border-0">{name}</li> ))} </ul> </ScrollShadow> <ScrollShadow orientation="horizontal" label="Filters" className="pb-1"> <div className="flex w-max gap-2"> {["All", "Open", "Waiting on customer", "Needs review", "Escalated", "Closed this week", "Archived"].map((chip) => ( <span key={chip} className="rounded-full bg-muted px-3 py-1.5 text-xs font-medium whitespace-nowrap">{chip}</span> ))} </div> </ScrollShadow> </div> ); }
API reference #
ScrollShadow
component
Also accepts the native props of its root element and a ref.
PropTypeDefaultDescription
orientation"horizontal" | "vertical""vertical"
sizenumber32How far the fade reaches, in pixels.
labelstring—Names the region for screen readers and makes it focusable for arrow-key scrolling.
Accessibility #
It is built on native elements and keeps aria-label in step with state.
No custom key handling; Tab and the native activation keys do the work.
Motion #
It declares no animation in its component source. Any transition comes from its stylesheet, which uses the duration tokens that collapse to instant under prefers-reduced-motion.