Appearance
State Components
Purpose
State components provide consistent UI for async data states:
- EmptyState — No data found
- ErrorState — Error with retry option
- LoadingState — Loading indicator
- SuccessState — Operation completed
- NotFoundState — 404 / resource not found
When to use
Use these components for:
- Standalone state displays
- Custom async handling (when not using AsyncContent)
- Full-page states (404, error pages)
For most cases, prefer AsyncContent or PageLayout which use these internally.
EmptyState
Displays when a list or search has no results.
tsx
import { EmptyState } from '@/shared/ui/components/states'
import { FolderOpen, Plus } from 'lucide-react'
<EmptyState
title="No projects found"
description="Create your first project to get started"
icon={FolderOpen}
action={{
label: 'Create Project',
onClick: handleCreate,
icon: Plus,
}}
/>Props
| Prop | Type | Description |
|---|---|---|
title | string | Empty state title |
description | string | Explanatory text |
icon | LucideIcon | Custom icon (default: Inbox) |
action | EmptyStateAction | Primary action button |
secondaryAction | EmptyStateAction | Secondary action |
size | 'sm' | 'md' | 'lg' | Container size |
ErrorState
Displays when an operation fails.
tsx
import { ErrorState } from '@/shared/ui/components/states'
<ErrorState
error={error}
title="Failed to load data"
onRetry={() => refetch()}
/>Props
| Prop | Type | Description |
|---|---|---|
error | Error | null | Error object |
title | string | Error title |
description | string | Error description (defaults to error.message) |
icon | LucideIcon | Custom icon |
onRetry | () => void | Retry callback |
retryText | string | Retry button text |
LoadingState
Simple loading indicator.
tsx
import { LoadingState } from '@/shared/ui/components/states'
<LoadingState message="Loading data..." />Props
| Prop | Type | Description |
|---|---|---|
message | string | Loading message |
size | 'sm' | 'md' | 'lg' | Spinner size |
SuccessState
Displays operation success.
tsx
import { SuccessState } from '@/shared/ui/components/states'
<SuccessState
title="Payment successful"
description="Your order has been confirmed"
action={{
label: 'View Order',
onClick: () => navigate('/orders'),
}}
/>Props
| Prop | Type | Description |
|---|---|---|
title | string | Success title |
description | string | Success message |
icon | LucideIcon | Custom icon |
action | Action | Primary action |
NotFoundState
404 / resource not found page.
tsx
import { NotFoundState } from '@/shared/ui/components/states'
<NotFoundState
title="Page not found"
description="The page you're looking for doesn't exist"
/>Props
| Prop | Type | Description |
|---|---|---|
title | string | Not found title |
description | string | Explanatory text |
backLink | string | Back navigation URL |
backLabel | string | Back button text |
Building blocks
StateContainer
Centered container for state content.
tsx
import { StateContainer } from '@/shared/ui/components/states'
<StateContainer size="md">
{/* Custom state content */}
</StateContainer>StateIcon
Icon with colored background circle.
tsx
import { StateIcon } from '@/shared/ui/components/states'
import { Check } from 'lucide-react'
<StateIcon icon={Check} variant="success" />Variants: empty, error, success, warning, info
Notes
- All components support i18n through
react-i18next - Default text is provided if no props are passed
- Use
StateContainerandStateIconfor custom state displays