Alert

In ProgressDark modeRTL

A notification banner with icon and variants.


7:21
Heads up!
You can add components to your app using the CLI.
!
Error
Your session has expired. Please log in again.
Warning
This action may have unintended consequences.
Success!
Your changes have been saved successfully.

Installation

Copy the component into your project using the CLI:

$ronakcn add alert

Usage

Import and use the component in your Flutter widget tree:

lib/pages/example.dart
import 'package:flutter/material.dart';
import '../components/alert/alert.dart';

class ExamplePage extends StatelessWidget {
  const ExamplePage({super.key});

  @override
  Widget build(BuildContext context) {
    return Scaffold(
      appBar: AppBar(title: const Text('RcnAlert Example')),
      body: Center(
        child: RcnAlert(
          // Configure props here
        ),
      ),
    );
  }
}

Variants

Alert ships with the following variants:

default

Informational alert in primary color.

7:21
Heads up!
You can add components to your app using the CLI.

destructive

Error alert in red.

7:21
!
Error
Your session has expired. Please log in again.

warning

Warning alert in amber.

7:21
Warning
This action may have unintended consequences.

success

Success alert in green.

7:21
Success!
Your changes have been saved successfully.

Props

PropTypeDefaultDescription
title*StringBold title text of the alert.
descriptionString?nullBody text below the title.
variantAlertVariantAlertVariant.infoVisual style of the alert.
iconWidget?nullCustom icon widget on the left.

Source files

lib/components/ui/alert.dart
import 'package:flutter/material.dart';

enum AlertVariant { info, destructive, warning, success }

class RcnAlert extends StatelessWidget {
  const RcnAlert({
    super.key,
    required this.title,
    this.description,
    this.variant = AlertVariant.info,
    this.icon,
  });

  final String title;
  final String? description;
  final AlertVariant variant;
  final Widget? icon;

  @override
  Widget build(BuildContext context) {
    final (bg, border, fg) = switch (variant) {
      AlertVariant.info        => (const Color(0xFF1D4ED8).withOpacity(0.08), const Color(0xFF3B82F6), const Color(0xFF1D4ED8)),
      AlertVariant.destructive => (const Color(0xFFE11D48).withOpacity(0.08), const Color(0xFFE11D48), const Color(0xFFBE123C)),
      AlertVariant.warning     => (const Color(0xFFD97706).withOpacity(0.08), const Color(0xFFF59E0B), const Color(0xFFB45309)),
      AlertVariant.success     => (const Color(0xFF059669).withOpacity(0.08), const Color(0xFF10B981), const Color(0xFF047857)),
    };

    return Container(
      padding: const EdgeInsets.all(14),
      decoration: BoxDecoration(
        color: bg,
        border: Border.all(color: border.withOpacity(0.3)),
        borderRadius: BorderRadius.circular(10),
      ),
      child: Row(
        crossAxisAlignment: CrossAxisAlignment.start,
        children: [
          icon ?? Icon(_defaultIcon(), size: 18, color: fg),
          const SizedBox(width: 10),
          Expanded(
            child: Column(
              crossAxisAlignment: CrossAxisAlignment.start,
              children: [
                Text(title, style: TextStyle(fontSize: 14, fontWeight: FontWeight.w600, color: fg)),
                if (description != null) ...[
                  const SizedBox(height: 4),
                  Text(description!, style: TextStyle(fontSize: 13, color: fg.withOpacity(0.8))),
                ],
              ],
            ),
          ),
        ],
      ),
    );
  }

  IconData _defaultIcon() => switch (variant) {
    AlertVariant.info        => Icons.info_outline,
    AlertVariant.destructive => Icons.error_outline,
    AlertVariant.warning     => Icons.warning_amber,
    AlertVariant.success     => Icons.check_circle_outline,
  };
}
Version 0.1.0 · display category