Alert
Display contextual feedback messages for typical user actions with flexible alert components. Supports multiple variants, colors, icons, titles, and dismissible functionality.
Import
tsx
import { Alert, Pulse } from '@odyssee/components';Basic Usage
Code Éditable
Résultat
Variants
The Alert component supports three variants: solid, soft, and bordered.
Code Éditable
Résultat
Colors
Alerts support multiple color schemes: primary, secondary, success, danger, warning, info, light, and dark.
Code Éditable
Résultat
With Title
Code Éditable
Résultat
With Icon
Code Éditable
Résultat
With List Content
Code Éditable
Résultat
Dismissible Alert
Make alerts dismissible with a close button.
tsx
const isVisible = Pulse.signal(true);
const dismissibleAlert = (
<Alert
variant="solid"
color="success"
dismissible={true}
isVisible={isVisible}
onDismiss={() => isVisible(false)}
>
File has been successfully uploaded.
</Alert>
);With Actions
Add action buttons to alerts.
tsx
const alertWithActions = (
<Alert
variant="soft"
color="info"
title="New software update"
>
<p>A new software update is available.</p>
<div class="mt-3 flex gap-2">
<button class="px-3 py-1 bg-blue-600 text-white rounded text-sm">
Update now
</button>
<button class="px-3 py-1 text-gray-600 hover:bg-gray-100 rounded text-sm">
Remind me later
</button>
</div>
</Alert>
);Reactive Visibility
Control alert visibility with Pulse signals.
tsx
const showAlert = Pulse.signal(false);
// Show alert after some action
const handleAction = () => {
showAlert(true);
// Auto-hide after 3 seconds
setTimeout(() => {
showAlert(false);
}, 3000);
};
const reactiveAlert = (
<Alert
variant="solid"
color="success"
isVisible={showAlert}
>
Action completed successfully!
</Alert>
);Complete Example
Here's a comprehensive example with multiple features:
tsx
import { Alert, Button, Pulse } from '@odyssee/components';
const NotificationSystem = () => {
const alerts = Pulse.signal<Array<{
id: number;
type: 'success' | 'error' | 'warning' | 'info';
message: string;
}>>([]);
const addAlert = (type: string, message: string) => {
const id = Date.now();
alerts([...alerts(), { id, type, message }]);
// Auto-dismiss after 5 seconds
setTimeout(() => {
removeAlert(id);
}, 5000);
};
const removeAlert = (id: number) => {
alerts(alerts().filter(alert => alert.id !== id));
};
const container = (
<div class="space-y-3">
{/* Action buttons */}
<div class="flex gap-2">
<Button
color="success"
size="sm"
onClick={() => addAlert('success', 'Operation successful!')}
>
Show Success
</Button>
<Button
color="danger"
size="sm"
onClick={() => addAlert('error', 'An error occurred!')}
>
Show Error
</Button>
<Button
color="warning"
size="sm"
onClick={() => addAlert('warning', 'Warning message!')}
>
Show Warning
</Button>
</div>
{/* Alerts container */}
<div id="alerts-container" class="space-y-2"></div>
</div>
) as Pulse.JSX.Element;
// Reactive rendering of alerts
Pulse.effect(() => {
const alertsContainer = container.querySelector('#alerts-container');
if (!alertsContainer) return;
alertsContainer.innerHTML = '';
alerts().forEach(alert => {
const alertElement = Alert({
variant: 'solid',
color: alert.type === 'error' ? 'danger' : alert.type,
dismissible: true,
onDismiss: () => removeAlert(alert.id),
children: alert.message
});
alertsContainer.appendChild(alertElement as Pulse.JSX.Element);
});
});
return container;
};Props
| Prop | Type | Default | Description |
|---|---|---|---|
variant | "solid" | "soft" | "bordered" | "soft" | Alert variant style |
color | "primary" | "secondary" | "success" | "danger" | "warning" | "info" | "light" | "dark" | "info" | Alert color scheme |
title | string | - | Alert title text |
icon | string | - | Icon to display (emoji or text) |
dismissible | boolean | false | Show dismiss button |
isVisible | boolean | Signal<boolean> | true | Control visibility |
onDismiss | () => void | - | Dismiss callback |
children | string | HTMLElement | Array<string | HTMLElement> | - | Alert content |
className | string | - | Additional CSS classes |
id | string | - | HTML id attribute |
Accessibility
The Alert component follows accessibility best practices:
- ✅ Uses semantic HTML with proper
roleattributes - ✅
role="alert"for important messages - ✅
aria-live="polite"for non-critical alerts - ✅ Dismiss button has
aria-label="Close" - ✅ Sufficient color contrast ratios
- ✅ Keyboard navigation support
ARIA Attributes
tsx
const accessibleAlert = (
<Alert
color="danger"
role="alert"
aria-live="assertive"
>
Critical error message
</Alert>
);Best Practices
✅ Do
- Use appropriate colors for context (danger for errors, success for completions)
- Provide clear, concise messages
- Use titles to summarize the alert content
- Make alerts dismissible for non-critical messages
- Auto-dismiss temporary notifications
tsx
// Good: Clear context and message
const goodAlert = (
<Alert
color="success"
title="Profile Updated"
dismissible={true}
>
Your profile information has been saved successfully.
</Alert>
);❌ Don't
- Don't use too many alerts at once
- Don't make critical alerts dismissible
- Don't use vague messages
- Don't forget to handle dismissal in reactive apps
tsx
// Bad: Vague and no context
const badAlert = (
<Alert color="info">
Something happened.
</Alert>
);
// Better: Clear and specific
const betterAlert = (
<Alert
color="success"
icon="✓"
title="Upload Complete"
>
Your document "report.pdf" has been uploaded successfully.
</Alert>
);Use Cases
Form Validation Errors
tsx
const formErrors = Pulse.signal<string[]>([]);
Pulse.effect(() => {
if (formErrors().length > 0) {
const errorAlert = Alert({
variant: 'soft',
color: 'danger',
title: 'Please fix the following errors:',
children: (
<ul class="list-disc ml-4 mt-2">
{formErrors().map(error => <li>{error}</li>)}
</ul>
) as Pulse.JSX.Element
});
}
});Success Messages
tsx
const showSuccess = (message: string) => {
const alert = Alert({
variant: 'solid',
color: 'success',
icon: '✓',
dismissible: true,
children: message
});
document.getElementById('notifications')?.appendChild(
alert as Pulse.JSX.Element
);
};Warning Notifications
tsx
const warningAlert = (
<Alert
variant: 'bordered',
color: 'warning',
icon: '⚠️',
title: 'Session Expiring Soon'
>
Your session will expire in 5 minutes. Please save your work.
</Alert>
);Styling & Theming
All alert styles use Tailwind CSS classes and support dark mode automatically.
Custom Styling
tsx
const customAlert = (
<Alert
className="shadow-lg border-l-4"
color="primary"
>
Custom styled alert
</Alert>
);Related Components
- Button - Add action buttons to alerts
- Modal - For more prominent notifications
- Badge - For inline status indicators
Version: 1.0.0
Last Updated: January 2025