PixelEmptyState

Placeholder block for empty collections or no-results states, with optional icon, title, description, and primary action.

  • Centered dashed-border container that communicates absence without feeling like an error
  • Optional icon slot rendered with cyan accent and aria-hidden so it stays decorative
  • Action slot for a primary recovery CTA (create, refresh, retry)
  • Pixel + linear surface variants share identical API and follow the nearest PxlKitSurfaceProvider
  • SSR-safe and tree-shakable; no client state
Status
stable
Category
feedback
Since
v1.0.0

API

import { PixelEmptyState } from '@pxlkit/ui-kit';
PropTypeDefaultDescription
title (required)string—Short title (e.g. "No results").
description (required)string—Supporting description below the title.
actionReact.ReactNode—Optional CTA node (button, link).
iconReact.ReactNode—Optional decorative icon.
surface'pixel' | 'linear'—Surface override; falls back to nearest provider.

ref points to <div>.

Accessibility

WCAG target: 2.1 AA

Renders as a non-interactive <div> with a semantic <h4> for the title and a <p> for the description. The icon is marked aria-hidden so it is not announced. Any action passed via the action slot owns its own keyboard + screen reader semantics.

Usage

import { PixelEmptyState } from '@pxlkit/ui-kit';

export function Default() {
  return (
    <PixelEmptyState
      title="No results found"
      description="Try adjusting your filters or search terms to find what you are looking for."
    />
  );
}

Examples

Default

import { PixelEmptyState } from '@pxlkit/ui-kit';

export function Default() {
  return (
    <PixelEmptyState
      title="No results found"
      description="Try adjusting your filters or search terms to find what you are looking for."
    />
  );
}

With Icon

import { PixelEmptyState } from '@pxlkit/ui-kit';

const FolderIcon = () => (
  <span
    aria-hidden
    style={{
      width: 32,
      height: 32,
      borderRadius: 4,
      border: '2px solid currentColor',
      display: 'inline-block',
    }}
  />
);

export function WithIcon() {
  return (
    <PixelEmptyState
      icon={<FolderIcon />}
      title="No projects yet"
      description="Create your first project to get started organizing your work."
    />
  );
}

With Action

import { PixelEmptyState, PixelButton } from '@pxlkit/ui-kit';

export function WithAction() {
  return (
    <PixelEmptyState
      title="Your inbox is empty"
      description="When you receive new messages, they will appear here."
      action={
        <PixelButton size="sm" tone="cyan" variant="solid">
          Refresh
        </PixelButton>
      }
    />
  );
}

With Icon + Action

import { PixelEmptyState, PixelButton } from '@pxlkit/ui-kit';

const FolderIcon = () => (
  <span
    aria-hidden
    style={{
      width: 32,
      height: 32,
      borderRadius: 4,
      border: '2px solid currentColor',
      display: 'inline-block',
    }}
  />
);

export function WithIconAndAction() {
  return (
    <PixelEmptyState
      icon={<FolderIcon />}
      title="No documents"
      description="Upload a file or create a new document to begin."
      action={
        <PixelButton size="sm" tone="green" variant="solid">
          Create document
        </PixelButton>
      }
    />
  );
}

Surfaces

import { PixelEmptyState } from '@pxlkit/ui-kit';

export function Surfaces() {
  return (
    <div className="flex flex-col gap-4">
      <PixelEmptyState
        surface="linear"
        title="Linear surface"
        description="Soft dashed border with rounded corners."
      />
      <PixelEmptyState
        surface="pixel"
        title="Pixel surface"
        description="Chamfered dashed border with retro typography."
      />
    </div>
  );
}

Related