| import React from 'react'; | |
| import { StyleSheet, View } from 'react-native'; | |
| import { useTheme, Text, IconButton, Button, Surface } from 'react-native-paper'; | |
| export interface EmptyStateProps { | |
| /** MaterialCommunityIcons icon name */ | |
| icon: string; | |
| /** Title displayed prominently */ | |
| title: string; | |
| /** Optional description below the title */ | |
| description?: string; | |
| /** Label for the optional action button */ | |
| actionLabel?: string; | |
| /** Callback when the action button is pressed */ | |
| onAction?: () => void; | |
| } | |
| /** | |
| * Reusable empty-state placeholder with an icon, title, description, | |
| * and an optional call-to-action button. | |
| */ | |
| export function EmptyState({ | |
| icon, | |
| title, | |
| description, | |
| actionLabel, | |
| onAction, | |
| }: EmptyStateProps) { | |
| const theme = useTheme(); | |
| return ( | |
| <Surface | |
| style={[styles.container, { backgroundColor: theme.colors.surface }]} | |
| elevation={0} | |
| > | |
| <View style={styles.content}> | |
| <IconButton | |
| icon={icon} | |
| size={64} | |
| iconColor={theme.colors.onSurfaceVariant} | |
| style={styles.icon} | |
| disabled | |
| /> | |
| <Text | |
| variant="titleMedium" | |
| style={[styles.title, { color: theme.colors.onSurface }]} | |
| > | |
| {title} | |
| </Text> | |
| {description ? ( | |
| <Text | |
| variant="bodyMedium" | |
| style={[styles.description, { color: theme.colors.onSurfaceVariant }]} | |
| > | |
| {description} | |
| </Text> | |
| ) : null} | |
| {actionLabel && onAction ? ( | |
| <Button | |
| mode="contained" | |
| onPress={onAction} | |
| style={styles.actionButton} | |
| > | |
| {actionLabel} | |
| </Button> | |
| ) : null} | |
| </View> | |
| </Surface> | |
| ); | |
| } | |
| const styles = StyleSheet.create({ | |
| container: { | |
| flex: 1, | |
| borderRadius: 12, | |
| }, | |
| content: { | |
| alignItems: 'center', | |
| justifyContent: 'center', | |
| padding: 24, | |
| gap: 8, | |
| }, | |
| icon: { | |
| margin: 0, | |
| }, | |
| title: { | |
| textAlign: 'center', | |
| }, | |
| description: { | |
| textAlign: 'center', | |
| maxWidth: 280, | |
| }, | |
| actionButton: { | |
| marginTop: 8, | |
| }, | |
| }); | |