AniUI

EmptyState

A placeholder for empty screens, search results, and error states. Every list needs one.

No results found

Try adjusting your search or filters to find what you're looking for.

import { EmptyState } from "@/components/ui/empty-state";
import { Ionicons } from "@expo/vector-icons";
<EmptyState
  icon={<Ionicons name="search-outline" size={48} color="#a1a1aa" />}
  title="No results found"
  description="Try adjusting your search or filters to find what you're looking for."
  action={{ label: "Clear Filters", onPress: () => {} }}
/>

Installation

npx @aniui/cli add empty-state

Usage

screen.tsx
import { EmptyState } from "@/components/ui/empty-state";
import { Ionicons } from "@expo/vector-icons";
<EmptyState
  icon={<Ionicons name="search-outline" size={48} color="#a1a1aa" />}
  title="No results found"
  description="Try adjusting your search or filters to find what you're looking for."
  action={{ label: "Clear Filters", onPress: () => {} }}
/>

No Search Results

Show when a search or filter returns empty.

No results found

Try adjusting your search or filters.

<EmptyState
  icon={<SearchIcon />}
  title="No results found"
  description="Try adjusting your search or filters."
  action={{ label: "Clear Filters", onPress: () => {} }}
/>

Empty List

Show when a list has no items yet.

No messages yet

When you receive messages, they'll appear here.

<EmptyState
  icon={<InboxIcon />}
  title="No messages yet"
  description="When you receive messages, they'll appear here."
/>

Error State

Show when data fails to load, with a retry action.

Something went wrong

We couldn't load your data. Please try again.

<EmptyState
  icon={<AlertIcon />}
  title="Something went wrong"
  description="We couldn't load your data. Please try again."
  action={{ label: "Retry", onPress: () => {} }}
/>

Props

PropTypeDefault
title
string
required
description
string
icon
ReactNode
action
{ label: string; onPress: () => void }
className
string

Source

components/ui/empty-state.tsx
import React from "react";
import { View, Text, Pressable } from "react-native";
import { cn } from "@/lib/utils";

export interface EmptyStateProps extends React.ComponentPropsWithoutRef<typeof View> {
  className?: string;
  icon?: React.ReactNode;
  title: string;
  description?: string;
  action?: { label: string; onPress: () => void };
}
export function EmptyState({ className, icon, title, description, action, ...props }: EmptyStateProps) {
  return (
    <View className={cn("items-center justify-center px-8 py-16", className)} {...props}>
      {icon && <View className="mb-4">{icon}</View>}
      <Text className="text-lg font-semibold text-foreground text-center mb-1">{title}</Text>
      {description && <Text className="text-sm text-muted-foreground text-center mb-6 max-w-[280px]">{description}</Text>}
      {action && (
        <Pressable
          onPress={action.onPress}
          className="rounded-lg bg-primary px-6 py-2.5 min-h-12 items-center justify-center"
          accessible={true}
          accessibilityRole="button"
        >
          <Text className="text-sm font-medium text-primary-foreground">{action.label}</Text>
        </Pressable>
      )}
    </View>
  );
}