Card
Added 14 October 2026
React
Codecomponents/react/card-demo.tsx
import {Button, Card, CardAction, CardContent, CardDescription, CardFooter, CardHeader, CardIcon, CardTitle} from '@stroeer-labs/design-library/react';
import {Calendar} from 'lucide-react';
export function CardDemo() {
return (
<div className="space-y-6">
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Leading icon — CardIcon slot</p>
<Card className="w-full max-w-sm">
<CardHeader>
<CardIcon>
<Calendar />
</CardIcon>
<CardTitle>Schedule</CardTitle>
<CardDescription>When should your campaign run?</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">The optional icon sits in a leading column; title and description keep their layout.</p>
</CardContent>
</Card>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Leading icon — size="sm"</p>
<Card size="sm" className="w-full max-w-sm">
<CardHeader>
<CardIcon>
<Calendar />
</CardIcon>
<CardTitle>Schedule</CardTitle>
<CardDescription>Box and icon scale down with the sm card.</CardDescription>
</CardHeader>
</Card>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Card</p>
<Card className="w-full max-w-sm">
<CardHeader>
<CardTitle>Login to your account</CardTitle>
<CardDescription>Enter your email below to login to your account</CardDescription>
<CardAction>
<Button variant="link">Sign Up</Button>
</CardAction>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">
The header lays out title, description and an action; this content region sits below it.
</p>
</CardContent>
<CardFooter className="flex-col gap-2">
<Button className="w-full">Login</Button>
<Button variant="outline" className="w-full">
Login with Google
</Button>
</CardFooter>
</Card>
</div>
<div className="space-y-2">
<p className="text-xs font-medium text-muted-foreground">Card — size="sm"</p>
<Card size="sm" className="w-full max-w-sm">
<CardHeader>
<CardTitle>Compact card</CardTitle>
<CardDescription>Tighter padding and spacing via the sm size.</CardDescription>
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">Same parts, denser layout.</p>
</CardContent>
</Card>
</div>
<div className="space-y-3">
<p className="text-xs font-medium text-muted-foreground">Elevation</p>
<div className="grid grid-cols-1 gap-5 sm:grid-cols-3">
{(
[
{elevation: 'resting', use: 'Standalone content/section card. The default.'},
{elevation: 'interactive', use: 'Clickable list item — raises on hover.'},
{elevation: 'floating', use: 'Floats above another surface (e.g. over the map).'},
] as const
).map(({elevation, use}) => (
<div key={elevation} className="space-y-1.5">
<Card elevation={elevation} size="sm">
<CardHeader>
<CardTitle>{elevation}</CardTitle>
<CardDescription>elevation="{elevation}"</CardDescription>
</CardHeader>
</Card>
<p className="text-xs text-muted-foreground">{use}</p>
</div>
))}
</div>
</div>
</div>
);
}Angular
Codecomponents/angular/card-demo.ts
import '@angular/compiler';
import {Component} from '@angular/core';
import {NgIcon, provideIcons} from '@ng-icons/core';
import {lucideCalendar} from '@ng-icons/lucide';
import {HlmButtonImports, HlmCardImports} from '@stroeer-labs/design-library/angular';
@Component({
selector: 'dl-card-demo',
standalone: true,
imports: [HlmCardImports, HlmButtonImports, NgIcon],
viewProviders: [provideIcons({lucideCalendar})],
template: `
<div class="space-y-6">
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Leading icon — hlmCardIcon slot</p>
<hlm-card class="w-full max-w-sm">
<hlm-card-header>
<div hlmCardIcon><ng-icon name="lucideCalendar" /></div>
<h3 hlmCardTitle>Schedule</h3>
<p hlmCardDescription>When should your campaign run?</p>
</hlm-card-header>
<div hlmCardContent>
<p class="text-sm text-muted-foreground">The optional icon sits in a leading column; title and description keep their layout.</p>
</div>
</hlm-card>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Leading icon — size="sm"</p>
<hlm-card size="sm" class="w-full max-w-sm">
<hlm-card-header>
<div hlmCardIcon><ng-icon name="lucideCalendar" /></div>
<h3 hlmCardTitle>Schedule</h3>
<p hlmCardDescription>Box and icon scale down with the sm card.</p>
</hlm-card-header>
</hlm-card>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Card</p>
<hlm-card class="w-full max-w-sm">
<hlm-card-header>
<h3 hlmCardTitle>Login to your account</h3>
<p hlmCardDescription>Enter your email below to login to your account</p>
<div hlmCardAction>
<button hlmBtn variant="link">Sign Up</button>
</div>
</hlm-card-header>
<div hlmCardContent>
<p class="text-sm text-muted-foreground">
The header lays out title, description and an action; this content region sits below it.
</p>
</div>
<hlm-card-footer class="flex-col gap-2">
<button hlmBtn class="w-full">Login</button>
<button hlmBtn variant="outline" class="w-full">Login with Google</button>
</hlm-card-footer>
</hlm-card>
</div>
<div class="space-y-2">
<p class="text-xs font-medium text-muted-foreground">Card — size="sm"</p>
<hlm-card size="sm" class="w-full max-w-sm">
<hlm-card-header>
<h3 hlmCardTitle>Compact card</h3>
<p hlmCardDescription>Tighter padding and spacing via the sm size.</p>
</hlm-card-header>
<div hlmCardContent>
<p class="text-sm text-muted-foreground">Same parts, denser layout.</p>
</div>
</hlm-card>
</div>
<div class="space-y-3">
<p class="text-xs font-medium text-muted-foreground">Elevation</p>
<div class="grid grid-cols-1 gap-5 sm:grid-cols-3">
@for (item of elevations; track item.elevation) {
<div class="space-y-1.5">
<hlm-card [elevation]="item.elevation" size="sm">
<hlm-card-header>
<h3 hlmCardTitle>{{ item.elevation }}</h3>
<p hlmCardDescription>elevation="{{ item.elevation }}"</p>
</hlm-card-header>
</hlm-card>
<p class="text-xs text-muted-foreground">{{ item.use }}</p>
</div>
}
</div>
</div>
</div>
`,
})
export class CardDemoComponent {
protected readonly elevations = [
{elevation: 'resting', use: 'Standalone content/section card. The default.'},
{elevation: 'interactive', use: 'Clickable list item — raises on hover.'},
{elevation: 'floating', use: 'Floats above another surface (e.g. over the map).'},
] as const;
}