IndiaCN UI

Empty State

A placeholder shown when there is nothing to display.

Introduction

Empty states explain why a region is blank and, where possible, what to do about it. Use one whenever a list, table or panel has no rows — a bare white area reads as a broken page.

UX4G defines three forms: an illustration with a label, a lighter version for small regions, and a version with a description and an action. All three are the same composition, so this ships as parts you assemble rather than a type prop.

Installation

npx shadcn@latest add https://indiacn.in/r/empty-state.json
import {
EmptyState,
EmptyStateMedia,
EmptyStateTitle,
EmptyStateDescription,
EmptyStateActions,
} from '@/components/ui/empty-state';

Usage

<EmptyState>
<EmptyStateMedia />
<EmptyStateTitle>No applications yet</EmptyStateTitle>
<EmptyStateDescription>
  Applications you submit will appear here for tracking.
</EmptyStateDescription>
</EmptyState>

Examples

Default

No data

EmptyStateDefault
import { FileSearch, Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {

export default function Component() {
  return (
    <EmptyState>
      <EmptyStateMedia />
      <EmptyStateTitle>No data</EmptyStateTitle>
    </EmptyState>
  );
}

With a Description

No applications yet

Applications you submit will appear here for tracking.

EmptyStateWithDescription
import { FileSearch, Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {

export default function Component() {
  return (
    <EmptyState>
      <EmptyStateMedia />
      <EmptyStateTitle>No applications yet</EmptyStateTitle>
      <EmptyStateDescription>
        Applications you submit will appear here for tracking.
      </EmptyStateDescription>
    </EmptyState>
  );
}

With an Action

No grievances filed

File a grievance and track its progress from this page.

EmptyStateWithAction
import { FileSearch, Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {

export default function Component() {
  return (
    <EmptyState>
      <EmptyStateMedia />
      <EmptyStateTitle>No grievances filed</EmptyStateTitle>
      <EmptyStateDescription>
        File a grievance and track its progress from this page.
      </EmptyStateDescription>
      <EmptyStateActions>
        <Button theme='primary' variant='filled' prefixIcon={<Plus />}>
          File a grievance
        </Button>
      </EmptyStateActions>
    </EmptyState>
  );
}

Custom Illustration

EmptyStateMedia renders the default illustration when given no children. Pass any node to replace it.

No results for “Aadhaar update”

Check the spelling or try a broader term.

EmptyStateCustomMedia
import { FileSearch, Plus } from 'lucide-react';
import { Button } from '@/components/ui/button';
import {

export default function Component() {
  return (
    <EmptyState>
      <EmptyStateMedia>
        <FileSearch className='size-16 text-neutral-300' aria-hidden />
      </EmptyStateMedia>
      <EmptyStateTitle>No results for “Aadhaar update”</EmptyStateTitle>
      <EmptyStateDescription>Check the spelling or try a broader term.</EmptyStateDescription>
    </EmptyState>
  );
}

About the illustration

UX4G's empty-state illustrations are flat SVGs with baked light-grey fills, and two of the three use linear gradients. Those would render as light shapes floating on a dark surface, and a component installed through the registry cannot ship an image file alongside itself.

So the default illustration is UX4G's empty box redrawn with theme tokens — the same geometry, coloured from neutral-50, neutral-200 and neutral-0, so it inverts with the theme. Pass your own node to EmptyStateMedia if you want the original artwork or something else entirely.

Guidelines

  • Say what is missing, not that something failed. "No applications yet" beats "Nothing found".
  • Give an action when the person can do something about it. Omit it when they cannot — an empty inbox needs no button.
  • Keep the description to one line. This is a placeholder, not documentation.

API Reference

EmptyState

Centred column, 8px gap. Accepts any div props.

EmptyStateMedia

PropTypeDefaultDescription
childrenReactNodeUX4G illustrationReplaces the default illustration

EmptyStateTitle / EmptyStateDescription

Both render Body1 (16px / 24px). The title uses neutral, the description neutral-600.

EmptyStateActions

Row of actions with a 12px gap and 8px of space above.

On this page