Empty State
A centered placeholder for pages or panels with no content yet. Combines an icon, title, description, and optional call-to-action into a single cohesive block.
Basic Usage
No messages yet
Start a conversation to see messages here.
Variations
Icon + Title Only
No results
Try a different search term.
Custom Icon / Illustration
Use the iconSlot named slot for custom SVGs or images:
Nothing here
Add your first project to get started.
Minimal (title only)
Inbox empty
Surface Variants
By default the empty state has no container chrome — it sits directly in whatever surrounds it. Use variant="outline" for a dashed-bordered placeholder (reads as a drop zone) or variant="muted" for a filled muted card.
No notifications
You're all caught up.
No results
Try a different search term.
When to Use
- Empty search results — tell users their query returned nothing
- Empty lists / tables — first-run experience before any data exists
- Empty folders or collections — invite the user to add content
- Filtered-to-zero state — combine with a "Clear filters" action
Width & Layout
The empty state fills its parent width and centers its content. Constrain the width on the parent or directly:
<x-wirekit::empty-state class="max-w-md mx-auto" title="No results" description="Try a different search." />
Props
| Prop | Type | Default | Description |
|---|---|---|---|
icon |
string|null | null |
Semantic icon alias (e.g. 'info', 'search') |
title |
string|null | null |
Primary heading text |
description |
string|null | null |
Secondary descriptive text |
level |
int | 3 |
Heading level (1–6) for the title. Match it to the surrounding document outline so screen-reader heading navigation stays correct |
variant |
string | 'default' |
Container chrome — default (none), outline (dashed border), muted (filled surface) |
animateIn |
string|null | null |
Entrance-reveal preset (e.g. 'fade', 'slide-up', 'scale-in') — inline alternative to wrapping in <x-wirekit::reveal>. See docs/animations.md for the full preset list. Respects prefers-reduced-motion: reduce. |
scope |
string|null | null |
Scoped personalization name |
Slots
| Slot | Purpose |
|---|---|
| default | Call-to-action buttons or links |
iconSlot |
Custom icon/illustration (overrides icon prop) |
Accessibility
- The title renders as a heading —
<h3>by default. Set thelevelprop (1–6) to match the surrounding document outline so the heading hierarchy stays correct:level="2"directly under a page<h1>, orlevel="1"when the empty-state represents the whole page's main content - The icon is purely decorative; its meaning is carried by the title + description. No
aria-labelis set on the icon wrapper - Call-to-action buttons inside the default slot keep their own focus styles
Keyboard Interaction
This component is purely presentational and does not respond to keyboard input.
Design Tokens
| Element | Token |
|---|---|
| Container padding | --padding-wk-x-xl / --padding-wk-y-xl |
| Icon wrapper bg | --color-wk-bg-muted |
| Icon color | --color-wk-text-muted |
| Title color | --color-wk-text |
| Title size | --text-wk-lg |
| Description color | --color-wk-text-muted |
| Description size | --text-wk-sm |
Customization
Empty State has no prop defaults (all props are contextual — you always pass title / description / icon inline). Visual customization happens on three levels:
- Inline props — override per-usage (
icon,title,description,scope) - Design tokens — change colors/spacing/typography globally by overriding
--color-wk-*,--padding-wk-*,--text-wk-*in yourapp.css - Scoped personalization — target a specific usage with the
scopeprop and register class overrides viaWireKit::personalize()
// config/wirekit.php — personalize the empty-state component
'components' => [
'empty-state' => [
// no prop defaults — customize via tokens or scopes
],
],
To replace the entire component markup (advanced), publish the view:
php artisan vendor:publish --tag=wirekit-views
# then edit resources/views/vendor/wirekit/components/empty-state.blade.php