Skip to content

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

PropTypeDescription
titlestringEmpty state title
descriptionstringExplanatory text
iconLucideIconCustom icon (default: Inbox)
actionEmptyStateActionPrimary action button
secondaryActionEmptyStateActionSecondary 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

PropTypeDescription
errorError | nullError object
titlestringError title
descriptionstringError description (defaults to error.message)
iconLucideIconCustom icon
onRetry() => voidRetry callback
retryTextstringRetry button text

LoadingState

Simple loading indicator.

tsx
import { LoadingState } from '@/shared/ui/components/states'

<LoadingState message="Loading data..." />

Props

PropTypeDescription
messagestringLoading 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

PropTypeDescription
titlestringSuccess title
descriptionstringSuccess message
iconLucideIconCustom icon
actionActionPrimary 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

PropTypeDescription
titlestringNot found title
descriptionstringExplanatory text
backLinkstringBack navigation URL
backLabelstringBack 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 StateContainer and StateIcon for custom state displays