EmptyState
A helpful component for displaying empty data states
A simple yet powerful component for displaying helpful messaging when there's no data to show. It combines an icon, title, description, and optional action to guide users through empty states gracefully.
Overview#
EmptyState creates a consistent, informative experience when content is unavailable. It helps users understand why nothing is displayed and what they can do next.
Use it for:
- No search results
- Empty lists or feeds
- First-time user experiences
- Unavailable data states
- Error states and fallbacks
Basic Usage#
Interactive Preview
9:41
No Data Found
Try adjusting your filters to find what you're looking for.
With Action Button#
import { EmptyState, Button } from 'prizmux'
import { Text } from 'react-native'
function EmptyList() {
return (
<EmptyState
title="No Items Yet"
description="Create your first item to get started"
icon={<Text style={{ fontSize: 48 }}>📝</Text>}
action={
<Button
title="Create Item"
fullWidth={true}
onPress={() => navigation.navigate('Create')}
/>
}
/>
)
}
import { EmptyState, Button } from 'prizmux'
import { Text } from 'react-native'
function EmptyList() {
return (
<EmptyState
title="No Items Yet"
description="Create your first item to get started"
icon={<Text style={{ fontSize: 48 }}>📝</Text>}
action={
<Button
title="Create Item"
fullWidth={true}
onPress={() => navigation.navigate('Create')}
/>
}
/>
)
}
Search Results Example#
import { EmptyState } from 'prizmux'
import { Text } from 'react-native'
import { useState } from 'react'
function SearchScreen() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
return (
<>
<SearchBar value={query} onChange={setQuery} />
{results.length === 0 ? (
<EmptyState
title="No Results Found"
description={`We couldn't find anything for "${query}"`}
icon={<Text style={{ fontSize: 48 }}>🔍</Text>}
/>
) : (
<ResultsList data={results} />
)}
</>
)
}
import { EmptyState } from 'prizmux'
import { Text } from 'react-native'
import { useState } from 'react'
function SearchScreen() {
const [query, setQuery] = useState('')
const [results, setResults] = useState([])
return (
<>
<SearchBar value={query} onChange={setQuery} />
{results.length === 0 ? (
<EmptyState
title="No Results Found"
description={`We couldn't find anything for "${query}"`}
icon={<Text style={{ fontSize: 48 }}>🔍</Text>}
/>
) : (
<ResultsList data={results} />
)}
</>
)
}
Empty Feed#
import { EmptyState, Button } from 'prizmux'
import { Text } from 'react-native'
function EmptyFeed() {
return (
<EmptyState
title="Nothing to See Here"
description="Follow some users to see posts in your feed"
icon={<Text style={{ fontSize: 48 }}>📭</Text>}
action={
<Button
title="Discover Users"
fullWidth={true}
onPress={() => navigation.navigate('Discover')}
/>
}
/>
)
}
import { EmptyState, Button } from 'prizmux'
import { Text } from 'react-native'
function EmptyFeed() {
return (
<EmptyState
title="Nothing to See Here"
description="Follow some users to see posts in your feed"
icon={<Text style={{ fontSize: 48 }}>📭</Text>}
action={
<Button
title="Discover Users"
fullWidth={true}
onPress={() => navigation.navigate('Discover')}
/>
}
/>
)
}
Props Reference#
| Prop | Type | Default | Description |
|---|---|---|---|
title | string | Required | Main headline |
description | string | Required | Supporting text |
icon | ReactNode | - | Icon or illustration |
action | ReactNode | - | Action component (usually Button) |
backgroundColor | string | — | Main background color |
titleColor | string | — | Heading text color |
descriptionColor | string | — | Subtext color |
style | ViewStyle | — | Root container styles |
containerStyle | ViewStyle | — | Inner padding container |
titleStyle | TextStyle | — | Title text sub-styles |
descriptionStyle | TextStyle | — | Description text sub-styles |
actionContainerStyle | ViewStyle | — | Action wrapper styles |
Usage#
Basic Empty State#
import { EmptyState } from 'prizmux'
import { Search } from 'lucide-react-native'
export default function SearchResults() {
return (
<EmptyState
icon={<Search size={48} />}
title="No Results"
description="Try adjusting your search terms"
/>
)
}
import { EmptyState } from 'prizmux'
import { Search } from 'lucide-react-native'
export default function SearchResults() {
return (
<EmptyState
icon={<Search size={48} />}
title="No Results"
description="Try adjusting your search terms"
/>
)
}
With Action#
import { EmptyState, Button } from 'prizmux'
import { Plus } from 'lucide-react-native'
<EmptyState
icon={<Plus size={48} />}
title="No Items"
description="Create your first item to get started"
action={
<Button
title="Create Item"
onPress={() => navigation.navigate('Create')}
/>
}
/>
import { EmptyState, Button } from 'prizmux'
import { Plus } from 'lucide-react-native'
<EmptyState
icon={<Plus size={48} />}
title="No Items"
description="Create your first item to get started"
action={
<Button
title="Create Item"
onPress={() => navigation.navigate('Create')}
/>
}
/>
No Search Results#
import { EmptyState } from 'prizmux'
import { SearchX } from 'lucide-react-native'
function SearchList() {
const [results, setResults] = useState([])
const [query, setQuery] = useState('')
return (
<>
<SearchBar value={query} onChange={setQuery} />
{results.length === 0 ? (
<EmptyState
icon={<SearchX size={48} />}
title="No Results"
description={`No items found for "${query}"`}
/>
) : (
<List data={results} />
)}
</>
)
}
import { EmptyState } from 'prizmux'
import { SearchX } from 'lucide-react-native'
function SearchList() {
const [results, setResults] = useState([])
const [query, setQuery] = useState('')
return (
<>
<SearchBar value={query} onChange={setQuery} />
{results.length === 0 ? (
<EmptyState
icon={<SearchX size={48} />}
title="No Results"
description={`No items found for "${query}"`}
/>
) : (
<List data={results} />
)}
</>
)
}
Empty Feed#
import { EmptyState, Button } from 'prizmux'
import { Inbox } from 'lucide-react-native'
<EmptyState
icon={<Inbox size={48} />}
title="Your Feed is Empty"
description="Follow users or add interests to see content"
action={
<Button
title="Find Users to Follow"
variant="primary"
onPress={() => navigation.navigate('Discover')}
/>
}
/>
import { EmptyState, Button } from 'prizmux'
import { Inbox } from 'lucide-react-native'
<EmptyState
icon={<Inbox size={48} />}
title="Your Feed is Empty"
description="Follow users or add interests to see content"
action={
<Button
title="Find Users to Follow"
variant="primary"
onPress={() => navigation.navigate('Discover')}
/>
}
/>
Error State#
import { EmptyState, Button } from 'prizmux'
import { AlertCircle } from 'lucide-react-native'
function LoadingScreen() {
const [error, setError] = useState(null)
return error ? (
<EmptyState
icon={<AlertCircle size={48} />}
title="Something Went Wrong"
description={error.message}
action={
<Button
title="Try Again"
onPress={() => retryLoad()}
/>
}
/>
) : (
<LoadingList />
)
}
import { EmptyState, Button } from 'prizmux'
import { AlertCircle } from 'lucide-react-native'
function LoadingScreen() {
const [error, setError] = useState(null)
return error ? (
<EmptyState
icon={<AlertCircle size={48} />}
title="Something Went Wrong"
description={error.message}
action={
<Button
title="Try Again"
onPress={() => retryLoad()}
/>
}
/>
) : (
<LoadingList />
)
}
Compact Variant#
<EmptyState
icon={<Archive size={32} />}
title="Archived"
description="No archived items"
variant="compact"
/>
<EmptyState
icon={<Archive size={32} />}
title="Archived"
description="No archived items"
variant="compact"
/>
No Favorites#
import { EmptyState, Button } from 'prizmux'
import { Heart } from 'lucide-react-native'
function FavoritesScreen() {
return (
<EmptyState
icon={<Heart size={48} />}
title="No Favorites Yet"
description="Items you favorite will appear here"
action={
<Button
title="Browse Items"
onPress={() => navigation.navigate('Explore')}
/>
}
/>
)
}
import { EmptyState, Button } from 'prizmux'
import { Heart } from 'lucide-react-native'
function FavoritesScreen() {
return (
<EmptyState
icon={<Heart size={48} />}
title="No Favorites Yet"
description="Items you favorite will appear here"
action={
<Button
title="Browse Items"
onPress={() => navigation.navigate('Explore')}
/>
}
/>
)
}
Offline State#
import { EmptyState, Button } from 'prizmux'
import { WifiOff } from 'lucide-react-native'
<EmptyState
icon={<WifiOff size={48} />}
title="You're Offline"
description="Check your internet connection"
action={
<Button
title="Retry"
onPress={() => refetch()}
/>
}
/>
import { EmptyState, Button } from 'prizmux'
import { WifiOff } from 'lucide-react-native'
<EmptyState
icon={<WifiOff size={48} />}
title="You're Offline"
description="Check your internet connection"
action={
<Button
title="Retry"
onPress={() => refetch()}
/>
}
/>
Notes#
- Use meaningful icons that relate to the empty state
- Keep titles concise and action-oriented
- Descriptions can provide helpful context
- Action button is optional but recommended
- Automatically scales on different screen sizes
- Works in both light and dark modes