Step 01
Webhook received from billing service
Add this component
npx zentauri-ui add scroll-areaKeyboard accessible by default with semantic markup, visible focus treatment, and tokenized states. Add descriptive labels for icon-only or decorative usage.
Check Installation for shared peers. This component keeps styling in Tailwind classes and the --zui-* token contract.
ScrollArea wraps overflowing content in a consistent, token-driven container. Use it for activity feeds, command panels, metric rails, compact tables, and any section where browser default scrollbars feel too heavy or inconsistent.
ScrollArea standardizes overflow panels, horizontal rails, hidden scrollbars, and hover-revealed thumbs without adding a JavaScript positioning dependency.
Pick an appearance, size, orientation, scrollbar, and shadow to preview the scroll area live. Toggle Show output / Show code and the snippet updates to match the selected variant.
All appearances
Every shipped appearance token at a glance. Click any swatch to load it into the playground above.
Generated from the package prop types and variant definitions.
ScrollAreaProps
| Prop | Type | Default |
|---|---|---|
| appearance | amberaquabluecrimsoncyandefaultelectricemeraldforestglassgreenlavender+18 | default |
| orientation | bothhorizontalvertical | vertical |
| scrollbar | alwaysautohiddenhover | auto |
| shadow | falsetrue | none |
| size | lgmdsm | md |
| Prop | Type | Default |
|---|---|---|
| viewportClassName | string | undefined | none |
| Prop | Type | Default |
|---|---|---|
| children | ReactNode | none |
| className | string | undefined | none |
| id | string | undefined | none |
| onClick | MouseEventHandler<HTMLDivElement> | undefined | none |
| style | CSSProperties | undefined | none |
| title | string | undefined | none |
ScrollAreaVariantProps
| Prop | Type | Default |
|---|---|---|
| appearance | 'default' | 'outline' | 'blue' | 'cyan' | 'green' | 'lime' | 'mint' | 'ocean' | 'sapphire' | 'lavender' | 'ruby' | 'red' | 'slate' | 'zinc' | 'stone' | 'royal' | 'electric' | 'forest' | 'sunset' | 'magenta' | 'crimson' | 'aqua' | 'plum' | 'sky' | 'rose' | 'emerald' | 'violet' | 'glass' | 'muted' | 'amber' | null | undefined | none |
| orientation | 'both' | 'horizontal' | 'vertical' | null | undefined | none |
| scrollbar | 'hidden' | 'auto' | 'always' | 'hover' | null | undefined | none |
| shadow | boolean | null | undefined | none |
| size | 'md' | 'sm' | 'lg' | null | undefined | none |
Override these ScrollArea variables on :root, a theme selector, or a component wrapper.
Pattern: --zui-<component>-<slot?>-<variant?>-<property>-<state?>-dark?
:root {
--zui-scroll-area-thumb: #94a3b8;
--zui-scroll-area-track: transparent;
--zui-scroll-area-ring-focus: oklch(54.6% 0.245 262.881 / 0.28);
--zui-scroll-area-ring-offset-focus: #ffffff;
--zui-scroll-area-size: 0.625rem;
--zui-scroll-area-thumb-border: transparent;
--zui-scroll-area-outline-border: #cbd5e1;
--zui-scroll-area-glass-border: #ffffff80;
--zui-scroll-area-glass-bg: #ffffff99;
--zui-scroll-area-sky-border: oklch(62.3% 0.214 259.815 / 0.35);
--zui-scroll-area-emerald-border: oklch(59.6% 0.145 163.225 / 0.35);
--zui-scroll-area-rose-border: oklch(58.6% 0.253 17.585 / 0.3);
--zui-scroll-area-amber-border: oklch(76.9% 0.188 70.08 / 0.35);
--zui-scroll-area-violet-border: oklch(60.6% 0.25 292.717 / 0.35);
--zui-scroll-area-blue-border: #2563eb66;
--zui-scroll-area-blue-thumb: #2563eb;
--zui-scroll-area-blue-track: #2563eb14;
--zui-scroll-area-cyan-border: #0891b266;
--zui-scroll-area-cyan-thumb: #0891b2;
--zui-scroll-area-cyan-track: #0891b214;
--zui-scroll-area-green-border: #16a34a66;
--zui-scroll-area-green-thumb: #16a34a;
--zui-scroll-area-green-track: #16a34a14;
--zui-scroll-area-lime-border: #65a30d66;
--zui-scroll-area-lime-thumb: #65a30d;
--zui-scroll-area-lime-track: #65a30d14;
--zui-scroll-area-mint-border: #10b98166;
--zui-scroll-area-mint-thumb: #10b981;
--zui-scroll-area-mint-track: #10b98114;
--zui-scroll-area-ocean-border: #0284c766;
--zui-scroll-area-ocean-thumb: #0284c7;
--zui-scroll-area-ocean-track: #0284c714;
--zui-scroll-area-sapphire-border: #1d4ed866;
--zui-scroll-area-sapphire-thumb: #1d4ed8;
--zui-scroll-area-sapphire-track: #1d4ed814;
--zui-scroll-area-lavender-border: #8b5cf666;
--zui-scroll-area-lavender-thumb: #8b5cf6;
--zui-scroll-area-lavender-track: #8b5cf614;
--zui-scroll-area-ruby-border: #be123c66;
--zui-scroll-area-ruby-thumb: #be123c;
--zui-scroll-area-ruby-track: #be123c14;
--zui-scroll-area-red-border: #dc262666;
--zui-scroll-area-red-thumb: #dc2626;
--zui-scroll-area-red-track: #dc262614;
--zui-scroll-area-slate-border: #47556966;
--zui-scroll-area-slate-thumb: #475569;
--zui-scroll-area-slate-track: #47556914;
--zui-scroll-area-zinc-border: #52525b66;
--zui-scroll-area-zinc-thumb: #52525b;
--zui-scroll-area-zinc-track: #52525b14;
--zui-scroll-area-stone-border: #57534e66;
--zui-scroll-area-stone-thumb: #57534e;
--zui-scroll-area-stone-track: #57534e14;
--zui-scroll-area-royal-border: #4338ca66;
--zui-scroll-area-royal-thumb: #4338ca;
--zui-scroll-area-royal-track: #4338ca14;
--zui-scroll-area-electric-border: #0ea5e966;
--zui-scroll-area-electric-thumb: #0ea5e9;
--zui-scroll-area-electric-track: #0ea5e914;
--zui-scroll-area-forest-border: #16653466;
--zui-scroll-area-forest-thumb: #166534;
--zui-scroll-area-forest-track: #16653414;
--zui-scroll-area-sunset-border: #ea580c66;
--zui-scroll-area-sunset-thumb: #ea580c;
--zui-scroll-area-sunset-track: #ea580c14;
--zui-scroll-area-magenta-border: #c026d366;
--zui-scroll-area-magenta-thumb: #c026d3;
--zui-scroll-area-magenta-track: #c026d314;
--zui-scroll-area-crimson-border: #b91c1c66;
--zui-scroll-area-crimson-thumb: #b91c1c;
--zui-scroll-area-crimson-track: #b91c1c14;
--zui-scroll-area-aqua-border: #0f766e66;
--zui-scroll-area-aqua-thumb: #0f766e;
--zui-scroll-area-aqua-track: #0f766e14;
--zui-scroll-area-plum-border: #7e22ce66;
--zui-scroll-area-plum-thumb: #7e22ce;
--zui-scroll-area-plum-track: #7e22ce14;
}
/* Dark theme variables follow the same names with -dark appended. */
.dark {
--zui-scroll-area-ring-focus-dark: oklch(70.7% 0.165 254.624 / 0.28);
--zui-scroll-area-ring-offset-focus-dark: oklch(12.9% 0.042 264.695);
}ScrollArea gives overflowing content a consistent scrollbar treatment across product surfaces.
It supports vertical, horizontal, and two-axis scrolling, plus auto, hover, always, and hidden scrollbar visibility modes.
Use ScrollArea as a single wrapper around content. Pass className for the scroll container size and padding, viewportClassName for inner layout, and variants such as appearance, size, orientation, scrollbar, and shadow.
Use ScrollArea to standardize scrollbar appearance across different browsers and platforms. It is ideal for sidebar navigation, dropdown menus, chat feeds, log viewers, and horizontal card carousels where native scrollbars would look inconsistent or bulky.
Use aria-label when the scrollable region has standalone meaning. The component maps named regions to role=region and tabIndex=0 unless you provide your own role or tabIndex.
ScrollArea ships as a client-safe package entry because it owns interactive focus attributes, but it has no effects or runtime layout work. You can render it inside App Router preview pages while keeping SEO content server-rendered.
No. ScrollArea uses CSS overflow, CSS custom properties, and browser scrollbar styling, so it does not need a layout or positioning dependency.
Yes. Set orientation to horizontal and give the viewport content a minimum width, such as min-w-max or a fixed grid width.
Provide aria-label or role and label content when the scroll region is meaningful on its own. Named regions become keyboard-focusable by default so users can scroll them with the keyboard.