# RenderStateView

## Description

A utility component that manages different rendering states for data-driven components. RenderStateView provides a clean way to handle error, loading, empty, and filled states with customizable components for each state, making it perfect for data fetching scenarios where you need to display different content based on the presence, loading state, and error state of data.

## Aliases

- RenderStateView
- State Renderer
- Data State Manager
- Conditional Renderer

## Props Breakdown

**Extends:** Standalone interface (no HTML element inheritance)

| Prop | Type | Default | Required | Description |
|------|------|---------|----------|-------------|
| `className` | `string` | - | No | Additional CSS class names |
| `data` | `T \| null` | - | No | The data to render. If the data is null, the empty component will be rendered. If the data is not null, the filled component will be rendered. |
| `isLoading` | `boolean` | - | No | Whether data is currently loading |
| `errorData` | `Error \| string \| null` | - | No | Error data to trigger error state rendering |
| `filled` | `React.ComponentType<{ data: T } & P>` | - | No | Component to render when data is present |
| `empty` | `React.ComponentType<P>` | - | No | Component to render when no data |
| `loading` | `React.ComponentType<P>` | - | No | Component to render during loading state |
| `error` | `React.ComponentType<{ error: Error \| string } & P>` | - | No | Component to render when error occurs |

This component does not add standard HTML attributes as it renders different components based on state.

## Examples

### Basic Data Loading States

```tsx
import { RenderStateView, Spinner, Text, Button } from '@delightui/components';

function BasicRenderStateExample() {
  const [users, setUsers] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  const fetchUsers = async () => {
    setIsLoading(true);
    try {
      // Simulate API call
      await new Promise(resolve => setTimeout(resolve, 2000));
      setUsers([
        { id: 1, name: 'John Doe', email: 'john@example.com' },
        { id: 2, name: 'Jane Smith', email: 'jane@example.com' }
      ]);
    } catch (error) {
      setUsers([]);
    } finally {
      setIsLoading(false);
    }
  };

  const LoadingComponent = () => (
    <div style={{ textAlign: 'center', padding: '40px' }}>
      <Spinner />
      <Text>Loading users...</Text>
    </div>
  );

  const EmptyComponent = () => (
    <div style={{ textAlign: 'center', padding: '40px' }}>
      <Text>No users found</Text>
      <Button onClick={fetchUsers} style={{ marginTop: '16px' }}>
        Load Users
      </Button>
    </div>
  );

  const FilledComponent = ({ data }: { data: any[] }) => (
    <div>
      <Text weight="Bold">Users ({data.length})</Text>
      {data.map(user => (
        <div key={user.id} style={{ padding: '8px', border: '1px solid #ccc', margin: '8px 0' }}>
          <Text weight="Bold">{user.name}</Text>
          <Text size="Small">{user.email}</Text>
        </div>
      ))}
    </div>
  );

  return (
    <div style={{ padding: '20px' }}>
      <Button onClick={fetchUsers} disabled={isLoading}>
        Fetch Users
      </Button>
      
      <RenderStateView
        data={users}
        isLoading={isLoading}
        loading={LoadingComponent}
        empty={EmptyComponent}
        filled={FilledComponent}
      />
    </div>
  );
}
```

### Product Catalog with Search

```tsx
import { RenderStateView, Input, Text, Card, Button, Image } from '@delightui/components';

function ProductCatalogExample() {
  const [products, setProducts] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [searchTerm, setSearchTerm] = useState('');

  const searchProducts = async (term: string) => {
    setIsLoading(true);
    try {
      await new Promise(resolve => setTimeout(resolve, 1000));
      
      const allProducts = [
        { id: 1, name: 'Wireless Headphones', price: 199.99, image: '/images/headphones.jpg' },
        { id: 2, name: 'Smart Watch', price: 299.99, image: '/images/watch.jpg' },
        { id: 3, name: 'Bluetooth Speaker', price: 89.99, image: '/images/speaker.jpg' }
      ];
      
      const filtered = term 
        ? allProducts.filter(p => p.name.toLowerCase().includes(term.toLowerCase()))
        : [];
        
      setProducts(filtered);
    } finally {
      setIsLoading(false);
    }
  };

  const LoadingSpinner = () => (
    <div style={{ textAlign: 'center', padding: '60px' }}>
      <Text>🔍 Searching products...</Text>
    </div>
  );

  const EmptyState = () => (
    <div style={{ textAlign: 'center', padding: '60px' }}>
      <Text size="large">No products found</Text>
      <Text>Try searching for "headphones", "watch", or "speaker"</Text>
    </div>
  );

  const ProductGrid = ({ data }: { data: any[] }) => (
    <div style={{ 
      display: 'grid', 
      gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', 
      gap: '20px',
      marginTop: '20px'
    }}>
      {data.map(product => (
        <Card key={product.id}>
          <Image 
            src={product.image} 
            alt={product.name}
            width="100%"
            height={200}
            fit="Cover"
          />
          <div style={{ padding: '16px' }}>
            <Text weight="Bold">{product.name}</Text>
            <Text size="large" weight="Bold" style={{ color: '#2e7d32' }}>
              ${product.price}
            </Text>
            <Button style={{ marginTop: '8px', width: '100%' }}>
              Add to Cart
            </Button>
          </div>
        </Card>
      ))}
    </div>
  );

  return (
    <div style={{ padding: '20px' }}>
      <Input
        value={searchTerm}
        onValueChange={setSearchTerm}
        placeholder="Search products..."
        trailingIcon={
          <Button 
            size="Small" 
            onClick={() => searchProducts(searchTerm)}
            disabled={isLoading}
          >
            Search
          </Button>
        }
      />

      <RenderStateView
        data={products}
        isLoading={isLoading}
        loading={LoadingSpinner}
        empty={EmptyState}
        filled={ProductGrid}
      />
    </div>
  );
}
```

### Dashboard Analytics

```tsx
import { RenderStateView, Text, Card, ProgressBar, Button } from '@delightui/components';

function DashboardAnalyticsExample() {
  const [analytics, setAnalytics] = useState<any>(null);
  const [isLoading, setIsLoading] = useState(false);

  const loadAnalytics = async () => {
    setIsLoading(true);
    try {
      await new Promise(resolve => setTimeout(resolve, 1500));
      setAnalytics({
        pageViews: 125840,
        uniqueVisitors: 45230,
        bounceRate: 32.5,
        conversionRate: 4.2,
        revenueGrowth: 12.8,
        topPages: [
          { page: '/home', views: 25000 },
          { page: '/products', views: 18500 },
          { page: '/about', views: 12300 }
        ]
      });
    } finally {
      setIsLoading(false);
    }
  };

  const LoadingDashboard = () => (
    <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(250px, 1fr))', gap: '20px' }}>
      {[1, 2, 3, 4].map(i => (
        <Card key={i} style={{ padding: '20px', textAlign: 'center' }}>
          <div style={{ width: '60px', height: '60px', backgroundColor: '#f0f0f0', borderRadius: '50%', margin: '0 auto 16px' }} />
          <div style={{ width: '100px', height: '20px', backgroundColor: '#f0f0f0', margin: '0 auto 8px' }} />
          <div style={{ width: '80px', height: '16px', backgroundColor: '#f0f0f0', margin: '0 auto' }} />
        </Card>
      ))}
    </div>
  );

  const EmptyDashboard = () => (
    <Card style={{ textAlign: 'center', padding: '60px' }}>
      <Text size="large">📊 No Analytics Data</Text>
      <Text>Analytics data is not available at the moment.</Text>
      <Button onClick={loadAnalytics} style={{ marginTop: '16px' }}>
        Reload Analytics
      </Button>
    </Card>
  );

  const AnalyticsDashboard = ({ data }: { data: any }) => (
    <div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '20px', marginBottom: '30px' }}>
        <Card style={{ padding: '20px', textAlign: 'center' }}>
          <Text size="small" color="secondary">Page Views</Text>
          <Text size="xl" weight="Bold">{data.pageViews.toLocaleString()}</Text>
        </Card>
        
        <Card style={{ padding: '20px', textAlign: 'center' }}>
          <Text size="small" color="secondary">Unique Visitors</Text>
          <Text size="xl" weight="Bold">{data.uniqueVisitors.toLocaleString()}</Text>
        </Card>
        
        <Card style={{ padding: '20px', textAlign: 'center' }}>
          <Text size="small" color="secondary">Bounce Rate</Text>
          <Text size="xl" weight="Bold">{data.bounceRate}%</Text>
        </Card>
        
        <Card style={{ padding: '20px', textAlign: 'center' }}>
          <Text size="small" color="secondary">Conversion Rate</Text>
          <Text size="xl" weight="Bold">{data.conversionRate}%</Text>
        </Card>
      </div>

      <Card style={{ padding: '20px' }}>
        <Text weight="Bold" style={{ marginBottom: '16px' }}>Top Pages</Text>
        {data.topPages.map((page: any, index: number) => (
          <div key={index} style={{ marginBottom: '12px' }}>
            <div style={{ display: 'flex', justifyContent: 'space-between', marginBottom: '4px' }}>
              <Text>{page.page}</Text>
              <Text weight="Bold">{page.views.toLocaleString()}</Text>
            </div>
            <ProgressBar 
              value={(page.views / data.topPages[0].views) * 100}
              max={100}
            />
          </div>
        ))}
      </Card>
    </div>
  );

  return (
    <div style={{ padding: '20px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
        <Text size="xl" weight="Bold">Analytics Dashboard</Text>
        <Button onClick={loadAnalytics} disabled={isLoading}>
          Refresh Data
        </Button>
      </div>

      <RenderStateView
        data={analytics}
        isLoading={isLoading}
        loading={LoadingDashboard}
        empty={EmptyDashboard}
        filled={AnalyticsDashboard}
      />
    </div>
  );
}
```

### User Profile Management

```tsx
import { RenderStateView, Text, Card, Button, Image, Form, FormField, Input } from '@delightui/components';

function UserProfileExample() {
  const [profile, setProfile] = useState<any>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [isEditing, setIsEditing] = useState(false);

  const loadProfile = async () => {
    setIsLoading(true);
    try {
      await new Promise(resolve => setTimeout(resolve, 1000));
      setProfile({
        name: 'John Doe',
        email: 'john.doe@example.com',
        avatar: '/images/avatar.jpg',
        role: 'Senior Developer',
        department: 'Engineering',
        joinDate: '2022-03-15',
        projects: 24
      });
    } finally {
      setIsLoading(false);
    }
  };

  const ProfileSkeleton = () => (
    <Card style={{ padding: '30px' }}>
      <div style={{ display: 'flex', alignItems: 'center', gap: '20px', marginBottom: '20px' }}>
        <div style={{ width: '80px', height: '80px', backgroundColor: '#f0f0f0', borderRadius: '50%' }} />
        <div>
          <div style={{ width: '150px', height: '24px', backgroundColor: '#f0f0f0', marginBottom: '8px' }} />
          <div style={{ width: '200px', height: '16px', backgroundColor: '#f0f0f0' }} />
        </div>
      </div>
      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(2, 1fr)', gap: '16px' }}>
        {[1, 2, 3, 4].map(i => (
          <div key={i}>
            <div style={{ width: '80px', height: '16px', backgroundColor: '#f0f0f0', marginBottom: '4px' }} />
            <div style={{ width: '120px', height: '20px', backgroundColor: '#f0f0f0' }} />
          </div>
        ))}
      </div>
    </Card>
  );

  const EmptyProfile = () => (
    <Card style={{ textAlign: 'center', padding: '60px' }}>
      <Text size="large">👤 No Profile Found</Text>
      <Text>Unable to load profile information.</Text>
      <Button onClick={loadProfile} style={{ marginTop: '16px' }}>
        Retry Loading
      </Button>
    </Card>
  );

  const ProfileDisplay = ({ data }: { data: any }) => (
    <Card style={{ padding: '30px' }}>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'flex-start', marginBottom: '20px' }}>
        <div style={{ display: 'flex', alignItems: 'center', gap: '20px' }}>
          <Image
            src={data.avatar}
            alt={data.name}
            width={80}
            height={80}
            fit="Cover"
            style={{ borderRadius: '50%' }}
          />
          <div>
            <Text size="xl" weight="Bold">{data.name}</Text>
            <Text color="secondary">{data.email}</Text>
            <Text>{data.role} • {data.department}</Text>
          </div>
        </div>
        <Button onClick={() => setIsEditing(true)}>
          Edit Profile
        </Button>
      </div>

      <div style={{ display: 'grid', gridTemplateColumns: 'repeat(auto-fit, minmax(200px, 1fr))', gap: '20px' }}>
        <div>
          <Text size="small" color="secondary">Join Date</Text>
          <Text weight="Bold">{data.joinDate}</Text>
        </div>
        <div>
          <Text size="small" color="secondary">Projects</Text>
          <Text weight="Bold">{data.projects}</Text>
        </div>
        <div>
          <Text size="small" color="secondary">Department</Text>
          <Text weight="Bold">{data.department}</Text>
        </div>
        <div>
          <Text size="small" color="secondary">Role</Text>
          <Text weight="Bold">{data.role}</Text>
        </div>
      </div>
    </Card>
  );

  return (
    <div style={{ padding: '20px' }}>
      <Text size="xl" weight="Bold" style={{ marginBottom: '20px' }}>
        User Profile
      </Text>

      <RenderStateView
        data={profile}
        isLoading={isLoading}
        loading={ProfileSkeleton}
        empty={EmptyProfile}
        filled={ProfileDisplay}
      />

      {!profile && !isLoading && (
        <Button onClick={loadProfile} style={{ marginTop: '20px' }}>
          Load Profile
        </Button>
      )}
    </div>
  );
}
```

### Shopping Cart States

```tsx
import { RenderStateView, Text, Button, Card, Image } from '@delightui/components';

function ShoppingCartExample() {
  const [cartItems, setCartItems] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  const loadCart = async () => {
    setIsLoading(true);
    try {
      await new Promise(resolve => setTimeout(resolve, 800));
      setCartItems([
        { id: 1, name: 'Wireless Mouse', price: 29.99, quantity: 2, image: '/images/mouse.jpg' },
        { id: 2, name: 'USB Cable', price: 12.99, quantity: 1, image: '/images/cable.jpg' }
      ]);
    } finally {
      setIsLoading(false);
    }
  };

  const clearCart = () => {
    setCartItems([]);
  };

  const CartLoading = () => (
    <Card style={{ padding: '30px', textAlign: 'center' }}>
      <Text>🛒 Loading your cart...</Text>
    </Card>
  );

  const EmptyCart = () => (
    <Card style={{ padding: '60px', textAlign: 'center' }}>
      <Text size="xl">🛒</Text>
      <Text size="large" weight="Bold">Your cart is empty</Text>
      <Text>Add some items to get started!</Text>
      <Button onClick={loadCart} style={{ marginTop: '20px' }}>
        Load Sample Items
      </Button>
    </Card>
  );

  const CartWithItems = ({ data }: { data: any[] }) => {
    const total = data.reduce((sum, item) => sum + (item.price * item.quantity), 0);

    return (
      <div>
        <Card style={{ padding: '20px', marginBottom: '20px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
            <Text size="large" weight="Bold">Shopping Cart ({data.length} items)</Text>
            <Button type="Outlined" onClick={clearCart}>
              Clear Cart
            </Button>
          </div>

          {data.map(item => (
            <div key={item.id} style={{ 
              display: 'flex', 
              alignItems: 'center', 
              gap: '16px', 
              padding: '16px 0',
              borderBottom: '1px solid #eee'
            }}>
              <Image
                src={item.image}
                alt={item.name}
                width={60}
                height={60}
                fit="Cover"
                style={{ borderRadius: '8px' }}
              />
              <div style={{ flex: 1 }}>
                <Text weight="Bold">{item.name}</Text>
                <Text size="small">Quantity: {item.quantity}</Text>
              </div>
              <Text weight="Bold">${(item.price * item.quantity).toFixed(2)}</Text>
            </div>
          ))}
        </Card>

        <Card style={{ padding: '20px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '16px' }}>
            <Text size="large" weight="Bold">Total: ${total.toFixed(2)}</Text>
          </div>
          <Button style={{ width: '100%' }}>
            Proceed to Checkout
          </Button>
        </Card>
      </div>
    );
  };

  return (
    <div style={{ padding: '20px', maxWidth: '600px' }}>
      <RenderStateView
        data={cartItems}
        isLoading={isLoading}
        loading={CartLoading}
        empty={EmptyCart}
        filled={CartWithItems}
      />
    </div>
  );
}
```

### File Upload Manager

```tsx
import { RenderStateView, Text, Button, Card, ProgressBar } from '@delightui/components';

function FileUploadManagerExample() {
  const [files, setFiles] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);

  const uploadFiles = async () => {
    setIsLoading(true);
    try {
      await new Promise(resolve => setTimeout(resolve, 2000));
      setFiles([
        { id: 1, name: 'document.pdf', size: '2.4 MB', status: 'completed', uploadDate: '2024-01-15' },
        { id: 2, name: 'image.jpg', size: '1.8 MB', status: 'completed', uploadDate: '2024-01-15' }
      ]);
    } finally {
      setIsLoading(false);
    }
  };

  const UploadingState = () => (
    <Card style={{ padding: '40px', textAlign: 'center' }}>
      <Text>📤 Uploading files...</Text>
      <ProgressBar value={65} max={100} style={{ marginTop: '16px' }} />
      <Text size="small" style={{ marginTop: '8px' }}>65% complete</Text>
    </Card>
  );

  const NoFilesState = () => (
    <Card style={{ padding: '60px', textAlign: 'center', border: '2px dashed #ccc' }}>
      <Text size="xl">📁</Text>
      <Text size="large" weight="Bold">No files uploaded</Text>
      <Text>Drag and drop files here or click to upload</Text>
      <Button onClick={uploadFiles} style={{ marginTop: '20px' }}>
        Upload Sample Files
      </Button>
    </Card>
  );

  const FilesList = ({ data }: { data: any[] }) => (
    <div>
      <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center', marginBottom: '20px' }}>
        <Text size="large" weight="Bold">Uploaded Files ({data.length})</Text>
        <Button onClick={uploadFiles}>
          Upload More
        </Button>
      </div>

      {data.map(file => (
        <Card key={file.id} style={{ padding: '16px', marginBottom: '12px' }}>
          <div style={{ display: 'flex', justifyContent: 'space-between', alignItems: 'center' }}>
            <div>
              <Text weight="Bold">{file.name}</Text>
              <Text size="small" color="secondary">
                {file.size} • Uploaded {file.uploadDate}
              </Text>
            </div>
            <div style={{ display: 'flex', gap: '8px' }}>
              <Button size="Small" type="Outlined">Download</Button>
              <Button size="Small" style="Destructive">Delete</Button>
            </div>
          </div>
        </Card>
      ))}
    </div>
  );

  return (
    <div style={{ padding: '20px', maxWidth: '600px' }}>
      <Text size="xl" weight="Bold" style={{ marginBottom: '20px' }}>
        File Manager
      </Text>

      <RenderStateView
        data={files}
        isLoading={isLoading}
        loading={UploadingState}
        empty={NoFilesState}
        filled={FilesList}
      />
    </div>
  );
}
```

### Error State Handling

```tsx
import { RenderStateView, Text, Button, Card } from '@delightui/components';

function ErrorStateExample() {
  const [data, setData] = useState<any>(null);
  const [isLoading, setIsLoading] = useState(false);
  const [errorData, setErrorData] = useState<Error | string | null>(null);

  const fetchData = async (shouldFail = false) => {
    setIsLoading(true);
    setErrorData(null);
    setData(null);
    
    try {
      await new Promise(resolve => setTimeout(resolve, 1000));
      if (shouldFail) {
        throw new Error('Network connection failed');
      }
      setData({ message: 'Data loaded successfully!', timestamp: new Date().toISOString() });
    } catch (err) {
      setErrorData(err instanceof Error ? err : 'Unknown error occurred');
    } finally {
      setIsLoading(false);
    }
  };

  const LoadingComponent = () => (
    <Card style={{ padding: '40px', textAlign: 'center' }}>
      <Text>⏳ Loading data...</Text>
    </Card>
  );

  const ErrorComponent = ({ error }: { error: Error | string }) => (
    <Card style={{ padding: '40px', textAlign: 'center', backgroundColor: '#ffebee' }}>
      <Text size="large">❌ Error Occurred</Text>
      <Text>{typeof error === 'string' ? error : error.message}</Text>
      <div style={{ marginTop: '20px', display: 'flex', gap: '12px', justifyContent: 'center' }}>
        <Button onClick={() => fetchData(false)}>Retry</Button>
        <Button type="Outlined" onClick={() => setErrorData(null)}>Dismiss</Button>
      </div>
    </Card>
  );

  const EmptyComponent = () => (
    <Card style={{ padding: '40px', textAlign: 'center' }}>
      <Text>📭 No data available</Text>
      <Button onClick={() => fetchData(false)} style={{ marginTop: '16px' }}>
        Load Data
      </Button>
    </Card>
  );

  const SuccessComponent = ({ data }: { data: any }) => (
    <Card style={{ padding: '40px', textAlign: 'center', backgroundColor: '#e8f5e8' }}>
      <Text size="large">✅ Success!</Text>
      <Text>{data.message}</Text>
      <Text size="small">Loaded at: {data.timestamp}</Text>
    </Card>
  );

  return (
    <div style={{ padding: '20px', maxWidth: '400px' }}>
      <Text size="xl" weight="Bold" style={{ marginBottom: '20px' }}>
        Error State Demo
      </Text>

      <div style={{ marginBottom: '20px', display: 'flex', gap: '12px' }}>
        <Button onClick={() => fetchData(false)}>Load Success</Button>
        <Button onClick={() => fetchData(true)}>Trigger Error</Button>
        <Button type="Outlined" onClick={() => { setData(null); setErrorData(null); }}>
          Reset
        </Button>
      </div>

      <RenderStateView
        data={data}
        isLoading={isLoading}
        errorData={errorData}
        loading={LoadingComponent}
        error={ErrorComponent}
        empty={EmptyComponent}
        filled={SuccessComponent}
      />
    </div>
  );
}
```

### API Error Handling

```tsx
import { RenderStateView, Text, Button, Card } from '@delightui/components';

function ApiErrorExample() {
  const [users, setUsers] = useState<any[]>([]);
  const [isLoading, setIsLoading] = useState(false);
  const [apiError, setApiError] = useState<Error | null>(null);

  const fetchUsers = async () => {
    setIsLoading(true);
    setApiError(null);
    
    try {
      const response = await fetch('/api/users');
      if (!response.ok) {
        throw new Error(`HTTP ${response.status}: ${response.statusText}`);
      }
      const userData = await response.json();
      setUsers(userData);
    } catch (err) {
      setApiError(err instanceof Error ? err : new Error('Network request failed'));
      setUsers([]);
    } finally {
      setIsLoading(false);
    }
  };

  const LoadingUsers = () => (
    <Card style={{ padding: '30px', textAlign: 'center' }}>
      <Text>👥 Loading users...</Text>
    </Card>
  );

  const ApiErrorDisplay = ({ error }: { error: Error }) => (
    <Card style={{ padding: '30px', textAlign: 'center', backgroundColor: '#fff3e0' }}>
      <Text size="large">⚠️ API Error</Text>
      <Text>{error.message}</Text>
      <Text size="small" style={{ marginTop: '8px' }}>
        Please check your network connection and try again
      </Text>
      <Button onClick={fetchUsers} style={{ marginTop: '16px' }}>
        Retry Request
      </Button>
    </Card>
  );

  const NoUsers = () => (
    <Card style={{ padding: '30px', textAlign: 'center' }}>
      <Text>👤 No users found</Text>
      <Button onClick={fetchUsers} style={{ marginTop: '16px' }}>
        Load Users
      </Button>
    </Card>
  );

  const UsersList = ({ data }: { data: any[] }) => (
    <div>
      <Text weight="Bold" style={{ marginBottom: '16px' }}>
        Users ({data.length})
      </Text>
      {data.map(user => (
        <Card key={user.id} style={{ padding: '16px', marginBottom: '8px' }}>
          <Text weight="Bold">{user.name}</Text>
          <Text size="small">{user.email}</Text>
        </Card>
      ))}
    </div>
  );

  return (
    <div style={{ padding: '20px', maxWidth: '500px' }}>
      <Text size="xl" weight="Bold" style={{ marginBottom: '20px' }}>
        API Error Handling
      </Text>

      <Button onClick={fetchUsers} disabled={isLoading} style={{ marginBottom: '20px' }}>
        Fetch Users
      </Button>

      <RenderStateView
        data={users}
        isLoading={isLoading}
        errorData={apiError}
        loading={LoadingUsers}
        error={ApiErrorDisplay}
        empty={NoUsers}
        filled={UsersList}
      />
    </div>
  );
}
```