Skip to content
Navigation

Scroll Area

A scroll container with styled, token-coloured scrollbars. Use it when a region scrolls independently of the page — not as a wrapper around ordinary page content.

Added 14 October 2026

React

Codecomponents/react/scroll-area-demo.tsx
import {ScrollArea, Separator} from '@stroeer-labs/design-library/react';

const tags = Array.from({length: 24}, (_, i) => `Segment ${i + 1}`);
const cities = ['Praha', 'Brno', 'Ostrava', 'Plzeň', 'Liberec', 'Olomouc', 'České Budějovice', 'Hradec Králové'];

export function ScrollAreaDemo() {
    return (
        <div className="space-y-6">
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Vertical</p>
                <ScrollArea label="Segments" className="h-56 w-56 border border-border">
                    <div className="p-4">
                        <h4 className="mb-3 text-sm leading-none font-medium">Segments</h4>
                        {tags.map((tag) => (
                            <div key={tag}>
                                <div className="py-1.5 text-sm">{tag}</div>
                                <Separator />
                            </div>
                        ))}
                    </div>
                </ScrollArea>
            </div>
            <div className="space-y-2">
                <p className="text-xs font-medium text-muted-foreground">Horizontal</p>
                <ScrollArea orientation="horizontal" label="Cities" className="w-full max-w-md border border-border">
                    <div className="flex gap-3 p-4">
                        {cities.map((city) => (
                            <div key={city} className="flex h-20 w-32 shrink-0 items-center justify-center rounded-md bg-muted text-sm">
                                {city}
                            </div>
                        ))}
                    </div>
                </ScrollArea>
            </div>
        </div>
    );
}

Angular

Codecomponents/angular/scroll-area-demo.ts
import {Component} from '@angular/core';
import {HlmScrollAreaImports, HlmSeparatorImports} from '@stroeer-labs/design-library/angular';

// Mirrors the React scroll-area demo. The structural difference is documented in the component's PARITY
// NOTE: there is no brain primitive, so this is `<ng-scrollbar hlmScrollArea>` from ngx-scrollbar, which
// wraps its own viewport around plain projected content, rather than React's explicit
// Root > Viewport > Scrollbar > Thumb composition. Horizontal scrolling is an `[orientation]` input here
// instead of a separate ScrollBar element.
@Component({
    selector: 'dl-scroll-area-demo',
    standalone: true,
    imports: [HlmScrollAreaImports, HlmSeparatorImports],
    template: `
        <div class="space-y-6">
            <div class="space-y-2">
                <p class="text-xs font-medium text-muted-foreground">Vertical</p>
                <ng-scrollbar hlmScrollArea label="Segments" class="h-56 w-56 border border-border">
                    <div class="p-4">
                        <h4 class="mb-3 text-sm leading-none font-medium">Segments</h4>
                        @for (tag of tags; track tag) {
                            <div>
                                <div class="py-1.5 text-sm">{{ tag }}</div>
                                <hlm-separator />
                            </div>
                        }
                    </div>
                </ng-scrollbar>
            </div>
            <div class="space-y-2">
                <p class="text-xs font-medium text-muted-foreground">Horizontal</p>
                <ng-scrollbar hlmScrollArea orientation="horizontal" label="Cities" class="w-full max-w-md border border-border">
                    <div class="flex gap-3 p-4">
                        @for (city of cities; track city) {
                            <div class="flex h-20 w-32 shrink-0 items-center justify-center rounded-md bg-muted text-sm">{{ city }}</div>
                        }
                    </div>
                </ng-scrollbar>
            </div>
        </div>
    `,
})
export class ScrollAreaDemoComponent {
    protected readonly tags = Array.from({length: 24}, (_, i) => `Segment ${i + 1}`);
    protected readonly cities = ['Praha', 'Brno', 'Ostrava', 'Plzeň', 'Liberec', 'Olomouc', 'České Budějovice', 'Hradec Králové'];
}