Skip to content
Velocity X Docs
← All components

Empty State

Free · MIT

Centred placeholder for an empty list, table, or panel with an icon slot, title, description, and action slot.

Category
Core UI
Framework
astro
Version
1.0.0
Peer deps
none

Install

bash
velocityx add empty-state

Free and MIT licensed — no account needed. The file lands under src/components/velocity/empty-state/ by default (override with --dest), and it's yours to edit from the moment it's written.

Demo

View the live demo on the showcase site ↗

Source

Pulled live from the registry — this is the exact file velocityx add empty-state writes into your project right now.

components/velocity/empty-state/EmptyState.astro

astro
---
//    VELOCITY COMPONENT · theming
// 
//    Colours here are Tailwind `primary-*` / `accent-*`, which resolve through
//    the Velocity preset. Out of the box they are a neutral indigo — NOT the
//    Aidxn brand — so this drops into your project without dragging our look in.
// 
//    ⚡ NOT USING VELOCITY? Run this once, in your project root:
// 
//          velocityx theme
// 
//    It writes velocity-preset.cjs + velocity-theme.css. Add the preset to your
//    tailwind.config, import the css, then set your whole brand in ONE place:
// 
//          :root {
//            --vx-brand: custom;
//            --vx-primary-600: 220 38 38;   <- your action colour
//            --vx-primary-700: 185 28 28;
//          }
// 
//    ⚠️  Raw RGB channels, space separated — NOT hex. `#DC2626` here silently
//        breaks every /opacity variant in the library (bg-primary-600/20 etc).
// 
//    Prefer not to install anything? Find-and-replace `primary-` with your own
//    scale name. Nothing else in this file depends on Velocity.
/**
 * EmptyState — centred placeholder for a table/list/panel with nothing in
 * it yet. Icon slot (defaults to a simple inbox glyph), title, description,
 * optional primary + secondary actions.
 *
 * Usage:
 *   <EmptyState title="No drafts yet" description="Side panels you start will park here.">
 *     <a slot="action" href="/new" class="...">New draft</a>
 *   </EmptyState>
 */
export interface Props {
  title: string;
  description?: string;
}
const { title, description } = Astro.props;
---

<div class="flex flex-col items-center justify-center text-center px-6 py-16 rounded-2xl border border-dashed border-secondary-300 dark:border-secondary-700">
  <div class="mb-4 inline-flex h-14 w-14 items-center justify-center rounded-2xl bg-primary-50 dark:bg-primary-500/10 text-primary-500 dark:text-primary-400">
    <slot name="icon">
      <svg aria-hidden="true" width="26" height="26" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="1.6" stroke-linecap="round" stroke-linejoin="round">
        <path d="M21 13v6a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-6" />
        <path d="M3 13h5l2 3h4l2-3h5" />
        <path d="m3 13 3.5-7.5A2 2 0 0 1 8.3 4.5h7.4a2 2 0 0 1 1.8 1l3.5 7.5" />
      </svg>
    </slot>
  </div>
  <h3 class="v-card-title text-secondary-900 dark:text-white">{title}</h3>
  {description && <p class="mt-1.5 max-w-sm text-sm text-secondary-500 dark:text-secondary-400">{description}</p>}
  <div class="mt-5 flex flex-wrap items-center justify-center gap-3">
    <slot name="action" />
  </div>
</div>

Theming

Uses the shared primary-* / accent-* scale — see Theming if colours look unstyled after install.