managarten/apps/picture/packages/mobile-ui/components/ui/ErrorBanner
Wuesteon d36b321d9d style: auto-format codebase with Prettier
Applied formatting to 1487+ files using pnpm format:write
  - TypeScript/JavaScript files
  - Svelte components
  - Astro pages
  - JSON configs
  - Markdown docs

  13 files still need manual review (Astro JSX comments)
2025-11-27 18:33:16 +01:00
..
ErrorBanner.tsx style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00
index.ts refactor: restructure 2025-11-26 03:03:24 +01:00
README.md style: auto-format codebase with Prettier 2025-11-27 18:33:16 +01:00

ErrorBanner

Floating banner component for displaying error, warning, info, or success messages with dismiss functionality.

Features

  • 4 variants: error, warning, info, success
  • Auto-positioned at top of screen
  • Dismissable
  • Icon support
  • Custom colors
  • Shadow/elevation
  • TypeScript support

Installation

npx @memoro/ui add error-banner

Dependencies: text, icon

Usage

Error Banner

import { ErrorBanner } from '@/components/ui/ErrorBanner/ErrorBanner';

const [error, setError] = useState<string | null>(null);

{
	error && <ErrorBanner message={error} onDismiss={() => setError(null)} />;
}

Success Banner

<ErrorBanner
	message="Changes saved successfully"
	variant="success"
	onDismiss={() => setSuccess(null)}
/>

Warning Banner

<ErrorBanner
	message="Your session will expire soon"
	variant="warning"
	onDismiss={() => setWarning(null)}
/>

Info Banner

<ErrorBanner message="New features available" variant="info" onDismiss={() => setInfo(null)} />

Custom Colors

<ErrorBanner
	message="Custom message"
	backgroundColor="#8B5CF6" // purple
	textColor="#FFFFFF"
	onDismiss={() => {}}
/>

Custom Icon

<ErrorBanner message="Network error" icon="cloud-offline" variant="error" onDismiss={() => {}} />

Custom Position

<ErrorBanner
	message="Bottom banner"
	top={undefined}
	style={{ bottom: 20, top: undefined }}
	onDismiss={() => {}}
/>

Props

Prop Type Default Description
message string - Required - Message text
onDismiss () => void - Required - Dismiss callback
variant 'error' | 'warning' | 'info' | 'success' 'error' Banner style variant
top number 60 Distance from top of screen
horizontalMargin number 16 Left/right margins
backgroundColor string - Custom background (overrides variant)
textColor string '#FFFFFF' Text and icon color
icon string - Custom icon (overrides variant)
style ViewStyle - Additional styles

Variants

Variant Color Default Icon
error Red (#EF4444) alert-circle
warning Amber (#F59E0B) warning
info Blue (#3B82F6) information-circle
success Green (#10B981) checkmark-circle

Examples

Network Error

<ErrorBanner
	message="No internet connection"
	icon="cloud-offline"
	variant="error"
	onDismiss={handleDismiss}
/>

Form Validation Error

<ErrorBanner
	message="Please fill in all required fields"
	variant="error"
	onDismiss={() => setError(null)}
/>

Save Success

<ErrorBanner
	message="Your changes have been saved"
	variant="success"
	onDismiss={() => setSuccess(null)}
/>

Low Storage Warning

<ErrorBanner
	message="Storage space running low"
	variant="warning"
	icon="warning"
	onDismiss={() => {}}
/>

Auto-Dismiss Pattern

const [error, setError] = useState<string | null>(null);

useEffect(() => {
	if (error) {
		const timer = setTimeout(() => setError(null), 5000);
		return () => clearTimeout(timer);
	}
}, [error]);

return <>{error && <ErrorBanner message={error} onDismiss={() => setError(null)} />}</>;

Multiple Banners (Stacked)

{
	error && (
		<ErrorBanner message={error} variant="error" top={60} onDismiss={() => setError(null)} />
	);
}
{
	warning && (
		<ErrorBanner
			message={warning}
			variant="warning"
			top={140} // Below error banner
			onDismiss={() => setWarning(null)}
		/>
	);
}

Positioning

  • Default: Absolute position at top: 60px
  • Z-Index: 1000 (appears above most content)
  • Horizontal: 16px margins on left/right
  • Width: Automatically fills available width

To position at bottom:

<ErrorBanner message="Bottom banner" style={{ top: undefined, bottom: 20 }} onDismiss={() => {}} />

Animation Tip

For smooth enter/exit animations, use a library like react-native-reanimated:

import Animated, { FadeInDown, FadeOutUp } from 'react-native-reanimated';

{
	error && (
		<Animated.View entering={FadeInDown} exiting={FadeOutUp}>
			<ErrorBanner message={error} onDismiss={() => setError(null)} />
		</Animated.View>
	);
}

Common Patterns

API Error Handler

const handleApiError = (error: Error) => {
	setError(error.message || 'Something went wrong');
};

try {
	await api.call();
} catch (error) {
	handleApiError(error);
}

Form Submission

const handleSubmit = async () => {
	try {
		await submitForm();
		setSuccess('Form submitted successfully');
	} catch (error) {
		setError('Failed to submit form');
	}
};

Dependencies

  • Text component
  • Icon component

Notes

  • Uses absolute positioning - ensure parent container has appropriate layout
  • Shadow works on both iOS and Android (shadowColor for iOS, elevation for Android)
  • Dismiss button has 8px hit slop for easier tapping
  • Banner is full-width with horizontal margins
  • Text auto-wraps if message is long
  • Close icon provides visual feedback on press (opacity change)