Skip to content
LuoForge/Tungsten
Components/EmptyState·Experimental

EmptyState

since v1.1.0

Zero-data placeholder — use when a list or section has no content to show.

Designed for section-level empty states; h3 assumes h1/h2 exist above in the page

outline. Add headingLevel control before using as a page-level empty view.

Forwards ref to the root <div role="region">.

Install

Add the package and import the component.

pnpm add @hey-mike/tungsten
pnpm add @hey-mike/tungsten
import { EmptyState } from '@hey-mike/tungsten';
import { EmptyState } from '@hey-mike/tungsten';

Preview

Same fixtures used by the visual-regression suite.

Usage

apps/docs/app/snapshots/empty-state/page.tsx

import { EmptyState, Button } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';

const SearchIcon = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5}>
    <circle cx="11" cy="11" r="8" />
    <path d="m21 21-4.35-4.35" strokeLinecap="round" />
  </svg>
);

const InboxIcon = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5}>
    <path d="M22 12h-6l-2 3H10l-2-3H2" strokeLinecap="round" strokeLinejoin="round" />
    <path
      d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"
      strokeLinejoin="round"
    />
  </svg>
);

export default function EmptyStateSnapshot() {
  return (
    <VariantGrid
      title="EmptyState"
      variants={[
        {
          label: 'title-only',
          node: <EmptyState title="No results found" />,
        },
        {
          label: 'with-description',
          node: (
            <EmptyState
              title="No results found"
              description="Try adjusting your search or filters."
            />
          ),
        },
        {
          label: 'with-icon',
          node: (
            <EmptyState
              title="No results found"
              description="Try adjusting your search or filters."
              icon={<SearchIcon />}
            />
          ),
        },
        {
          label: 'with-action',
          node: (
            <EmptyState
              title="Your inbox is empty"
              description="Messages from your team will appear here."
              icon={<InboxIcon />}
              action={<Button size="sm">Invite teammates</Button>}
            />
          ),
        },
      ]}
    />
  );
}
import { EmptyState, Button } from '@hey-mike/tungsten';
import { VariantGrid } from '../_components/VariantGrid';

const SearchIcon = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5}>
    <circle cx="11" cy="11" r="8" />
    <path d="m21 21-4.35-4.35" strokeLinecap="round" />
  </svg>
);

const InboxIcon = () => (
  <svg viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth={1.5}>
    <path d="M22 12h-6l-2 3H10l-2-3H2" strokeLinecap="round" strokeLinejoin="round" />
    <path
      d="M5.45 5.11 2 12v6a2 2 0 0 0 2 2h16a2 2 0 0 0 2-2v-6l-3.45-6.89A2 2 0 0 0 16.76 4H7.24a2 2 0 0 0-1.79 1.11z"
      strokeLinejoin="round"
    />
  </svg>
);

export default function EmptyStateSnapshot() {
  return (
    <VariantGrid
      title="EmptyState"
      variants={[
        {
          label: 'title-only',
          node: <EmptyState title="No results found" />,
        },
        {
          label: 'with-description',
          node: (
            <EmptyState
              title="No results found"
              description="Try adjusting your search or filters."
            />
          ),
        },
        {
          label: 'with-icon',
          node: (
            <EmptyState
              title="No results found"
              description="Try adjusting your search or filters."
              icon={<SearchIcon />}
            />
          ),
        },
        {
          label: 'with-action',
          node: (
            <EmptyState
              title="Your inbox is empty"
              description="Messages from your team will appear here."
              icon={<InboxIcon />}
              action={<Button size="sm">Invite teammates</Button>}
            />
          ),
        },
      ]}
    />
  );
}

Props

Surface specific to <EmptyState />.

PropTypeDefaultDescription
title*string
descriptionstring
iconReactNodeIcon element to display above the title. Should use currentColor for fill/stroke to inherit the text-ink-3 theme color. Rendered at 32×32 px.
actionReactElement<unknown, string | JSXElementConstructor<any>>
classNamestring

Source