Card
A container with header, content and footer parts.
import { … } from '@inlaylab/ivorie/card'import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IV_FIELD_IMPORTS } from '@inlaylab/ivorie/field';
import { IV_INPUT_IMPORTS } from '@inlaylab/ivorie/input';
import { IvButton } from '@inlaylab/ivorie/button';
@Component({
selector: 'demo-card',
imports: [IV_CARD_IMPORTS, IV_FIELD_IMPORTS, IV_INPUT_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-sm">
<iv-card-header>
<iv-card-title>Profile</iv-card-title>
<iv-card-description>Update your name and email address.</iv-card-description>
</iv-card-header>
<iv-card-content class="flex flex-col gap-4">
<iv-field>
<label ivLabel for="card-name">Name</label>
<input ivInput id="card-name" value="Maya Ross" />
</iv-field>
<iv-field>
<label ivLabel for="card-email">Email</label>
<input ivInput id="card-email" type="email" value="maya@acme.dev" />
</iv-field>
</iv-card-content>
<iv-card-footer class="gap-2">
<button ivButton variant="outline">Cancel</button>
<button ivButton class="ml-auto">Save changes</button>
</iv-card-footer>
</iv-card>
`,
})
export default class CardDemo {}
Installation
npx ivorie add cardimport { … } from '@inlaylab/ivorie/card'Usage
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';<iv-card>
<iv-card-header>
<iv-card-title>Account</iv-card-title>
<iv-card-description>Manage your preferences.</iv-card-description>
</iv-card-header>
<iv-card-content>Body</iv-card-content>
</iv-card>Examples
Action
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IvButton } from '@inlaylab/ivorie/button';
@Component({
selector: 'demo-card-action',
imports: [IV_CARD_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-sm">
<iv-card-header>
<iv-card-title>API keys</iv-card-title>
<iv-card-description>Keys used to authenticate requests.</iv-card-description>
<iv-card-action>
<button ivButton size="sm" variant="outline">Add key</button>
</iv-card-action>
</iv-card-header>
</iv-card>
`,
})
export default class CardActionDemo {}
Footer
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IvButton } from '@inlaylab/ivorie/button';
@Component({
selector: 'demo-card-footer',
imports: [IV_CARD_IMPORTS, IvButton],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-sm">
<iv-card-header>
<iv-card-title>Delete account</iv-card-title>
<iv-card-description>This action cannot be undone.</iv-card-description>
</iv-card-header>
<iv-card-footer class="gap-2">
<button ivButton variant="outline">Cancel</button>
<button ivButton variant="destructive" class="ml-auto">Delete</button>
</iv-card-footer>
</iv-card>
`,
})
export default class CardFooterDemo {}
Small
1,284 visits
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
@Component({
selector: 'demo-card-small',
imports: [IV_CARD_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card size="sm" class="w-full max-w-sm">
<iv-card-header>
<iv-card-title>Quick stats</iv-card-title>
<iv-card-description>Last 7 days.</iv-card-description>
</iv-card-header>
<iv-card-content>
<p class="text-sm">1,284 visits</p>
</iv-card-content>
</iv-card>
`,
})
export default class CardSmallDemo {}
Image
Unlimited projects, custom themes and priority support.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
@Component({
selector: 'demo-card-image',
imports: [IV_CARD_IMPORTS],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-sm">
<img src="app.svg" alt="Ivorie" class="h-32 w-full object-contain p-4" />
<iv-card-header>
<iv-card-title>Ivorie Pro</iv-card-title>
</iv-card-header>
<iv-card-content>
<p class="text-muted-foreground text-sm">Unlimited projects, custom themes and priority support.</p>
</iv-card-content>
</iv-card>
`,
})
export default class CardImageDemo {}
Header divider
Table goes here.
import { ChangeDetectionStrategy, Component } from '@angular/core';
import { IV_CARD_IMPORTS } from '@inlaylab/ivorie/card';
import { IvButton } from '@inlaylab/ivorie/button';
import { LucideEllipsis } from '@lucide/angular';
@Component({
selector: 'demo-card-header-divider',
imports: [IV_CARD_IMPORTS, IvButton, LucideEllipsis],
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<iv-card class="w-full max-w-sm">
<iv-card-header class="border-b">
<iv-card-title>Users</iv-card-title>
<iv-card-action>
<button ivButton size="icon-sm" variant="ghost" aria-label="More">
<svg lucideEllipsis></svg>
</button>
</iv-card-action>
</iv-card-header>
<iv-card-content>
<p class="text-sm">Table goes here.</p>
</iv-card-content>
</iv-card>
`,
})
export default class CardHeaderDividerDemo {}
API
Every part also accepts class.
iv-card
| Name | Type | Default | Description |
|---|---|---|---|
size |
'default' | 'sm' |
'default' |
sm reduces gap, padding and font size in all child parts. Set it only on the card. |
Other parts
No inputs besides class: iv-card-header, iv-card-title, iv-card-description, iv-card-action, iv-card-content, iv-card-footer.
Accessibility
A card has no role. Use a real heading element for the title if the page outline needs one.
Notes
- Put
iv-card-actioninsideiv-card-header. It sits top right. - Make
iv-card-footera direct child ofiv-card. - An
imgas first or last child gets rounded corners. - Add
class="border-b"toiv-card-headerfor a divider.