Status & display: alert, stat, timeline, chip, divider, empty
SvAlert (inline info/success/warning/danger messages with actions), SvStat (KPI cards with auto-coloured up/down deltas, invertible), SvTimeline (activity feed), SvChip (removable/clickable pills with avatars), SvDivider (labeled + vertical) and SvEmptyState. The status + display layer for dashboards and detail screens.
A live, editable Svelte 5 component example from the SvGrid gallery (Range & Feedback). Read the SvGrid UI component docs for the full API.
About this example
The status and display kit of SvGrid UI in Svelte 5: SvAlert for inline info, success, warning and danger messages with actions, SvStat for KPI cards with a delta coloured up or down and invertible for metrics where down is good, SvTimeline for an activity feed, SvChip for removable or clickable pills with avatars, SvDivider with a label and vertical mode, and SvEmptyState with a title and description. All theme-driven.
Status & display kit: SvAlert (inline messages), SvStat (KPI cards), SvTimeline (activity feed), SvChip (removable/clickable pills), SvDivider (labeled separators) and SvEmptyState. All theme-driven.
Imports, features and API used
Imports: @svgrid/grid
Frequently asked questions
How does SvStat colour the delta?
A positive delta reads green with an up arrow and a negative one red with a down arrow. invert swaps the colours for metrics such as churn where a decrease is good.
Can an alert carry actions?
Yes. Buttons placed in the alert's action slot render inline with the message, and the danger variant is what the demo uses for a destructive confirmation.
How is a chip removed?
Set removable and handle onRemove; the chip shows an x button and your handler drops it from the list.
Related documentation
Related articles
- Status Badge Cells in SvGrid - Turn a plain text status column into colored, accessible pill badges without breaking sort, filter, or virtualization - using SvGrid's snippet cell renderer.
- Empty, Loading, and Error States for a Svelte Data Grid - How to handle the three non-data states in a Svelte grid - empty (with two subtypes), skeleton loading that does not flash, and recoverable errors that keep existing rows visible.
- $state Deep Dive for Data-Heavy Svelte Apps - A working engineer's guide to $state, $state.raw, and $state.snapshot - when each one is the right tool, and the exact failure modes when you pick the wrong one.
Source code (339-status-display.svelte)
<script lang="ts">
/**
* Status & display kit: SvAlert (inline messages), SvStat (KPI cards),
* SvTimeline (activity feed), SvChip (removable/clickable pills), SvDivider
* (labeled separators) and SvEmptyState. All theme-driven.
*/
import { SvAlert, SvEmptyState, SvDivider, SvChip, SvStat, SvTimeline, SvButton, SvAvatar, type TimelineItem } from '@svgrid/grid'
let tags = $state(['Design', 'Frontend', 'Urgent'])
const removeTag = (t: string) => (tags = tags.filter((x) => x !== t))
const activity: TimelineItem[] = [
{ title: 'Order #1042 placed', time: '09:12', color: '#16a34a', icon: '✓' },
{ title: 'Payment captured', time: '09:13', description: '$248.00 via card ending 4242', color: '#2563eb' },
{ title: 'Picked & packed', time: '11:40', color: '#7c3aed' },
{ title: 'Shipped', time: '14:05', description: 'Tracking 1Z…88, DHL Express', color: '#0891b2' },
{ title: 'Out for delivery', time: 'Tomorrow', color: '#d97706' },
]
</script>
<div class="wrap">
<header><h2>Status & display</h2><p>Inline alerts, KPI stats, activity timelines, chips, dividers and empty states.</p></header>
<section>
<h3>Alerts</h3>
<div class="stack">
<SvAlert variant="info" title="Heads up">A new version is available. <a href="#">Refresh</a> to update.</SvAlert>
<SvAlert variant="success" soft>Your changes were saved.</SvAlert>
<SvAlert variant="warning" title="Storage almost full" dismissible>You've used 92% of your quota.</SvAlert>
<SvAlert variant="danger" title="Payment failed" dismissible>
We couldn't charge your card.
{#snippet actions()}<SvButton size="sm" variant="danger">Update card</SvButton><SvButton size="sm" variant="ghost">Dismiss</SvButton>{/snippet}
</SvAlert>
</div>
</section>
<section>
<h3>Stats</h3>
<div class="stats">
<SvStat label="Revenue" value="$48.2k" delta={12.4} hint="vs last month" />
<SvStat label="Active users" value="3,914" delta={4.1} hint="vs last week" />
<SvStat label="Churn" value="1.8%" delta={-0.6} invert hint="lower is better" />
<SvStat label="Avg. latency" value="182ms" delta={-14} invert hint="p95" />
</div>
</section>
<div class="cols">
<section>
<h3>Activity timeline</h3>
<SvTimeline items={activity} />
</section>
<section>
<h3>Chips & dividers</h3>
<div class="chips">
{#each tags as t (t)}<SvChip variant="accent" removable onRemove={() => removeTag(t)}>{t}</SvChip>{/each}
{#if tags.length === 0}<span class="muted">All cleared.</span>{/if}
</div>
<SvDivider label="Assignee" align="start" />
<div class="chips">
<SvChip>{#snippet leading()}<SvAvatar size="sm" name="Ada Lovelace" />{/snippet}Ada Lovelace</SvChip>
<SvChip variant="success" solid>Approved</SvChip>
<SvChip variant="warning">Pending</SvChip>
</div>
<SvDivider />
<div class="row">
Filters <SvDivider orientation="vertical" /> 3 active <SvDivider orientation="vertical" /> <a href="#">Clear</a>
</div>
</section>
</div>
<section>
<h3>Empty state</h3>
<div class="panel">
<SvEmptyState title="No invoices yet" description="Invoices you create will show up here. Start by adding your first one.">
<SvButton>New invoice</SvButton>
<SvButton variant="ghost">Import</SvButton>
</SvEmptyState>
</div>
</section>
</div>
<style>
.wrap { padding: 20px; max-width: 940px; display: flex; flex-direction: column; gap: 22px; }
header h2 { margin: 0 0 4px; font-size: 20px; font-weight: 700; }
header p { margin: 0; color: var(--sg-muted, #64748b); font-size: 13.5px; }
section h3 { margin: 0 0 12px; font-size: 13px; text-transform: uppercase; letter-spacing: 0.03em; color: var(--sg-muted, #64748b); }
.stack { display: flex; flex-direction: column; gap: 10px; max-width: 620px; }
.stats { display: grid; grid-template-columns: repeat(auto-fit, minmax(180px, 1fr)); gap: 12px; }
.cols { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1fr); gap: 28px; }
@media (max-width: 760px) { .cols { grid-template-columns: 1fr; } }
.chips { display: flex; flex-wrap: wrap; gap: 8px; align-items: center; margin-bottom: 6px; }
.row { display: flex; align-items: center; font-size: 13px; color: var(--sg-muted, #64748b); }
.muted { color: var(--sg-muted, #94a3b8); font-size: 13px; }
.panel { border: 1px solid var(--sg-border, #e2e8f0); border-radius: 12px; }
a { color: var(--sg-accent, #2563eb); }
</style>More Range & Feedback examples
- Range & feedback - SvSlider (single or dual-thumb range, ticks, keyboard, vertical) and SvGauge (radial arc with threshold bands, needle, half sweep). Theme-driven value controls, standalone or in-grid.
- Slider - SvSlider: a filter block - a dual-thumb price range plus single sliders for rating and distance, with ticks and live formatted readouts.
- Gauge - SvGauge: a KPI dashboard - radial gauges with colored threshold bands, a live-updating needle, and a needle-less storage tile.
- Progress (linear + circular) - SvProgress and SvCircularProgress: determinate + indeterminate progress with color intents, sizes, labels, striped fill, a buffered track, and a custom ring center. WAI-ARIA progressbar, reduced-motion aware.
- Feedback & display: badge, avatar, skeleton, card - SvBadge (status pills), SvAvatar (image + initials/colour-hash fallback + presence dot), SvSkeleton (shimmer loaders) and SvCard (surface) - the display layer for dashboards and detail panels. Toggle loading to swap content for skeletons.