flare_ui 1.0.1
flare_ui: ^1.0.1 copied to clipboard
The ultimate Flutter UI kit for modern apps. Featuring Glassmorphism, animated navigation, and premium feedback components.
import 'package:flutter/material.dart';
import 'package:flare_ui/flare_ui.dart';
import 'package:google_fonts/google_fonts.dart';
void main() {
runApp(const FlareShowcaseApp());
}
class FlareShowcaseApp extends StatelessWidget {
const FlareShowcaseApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flare UI Showcase',
debugShowCheckedModeBanner: false,
// Apply the premium FlareTheme to the entire application.
theme: ThemeData(
brightness: Brightness.dark,
scaffoldBackgroundColor: const Color(0xFF0F0F12),
textTheme: GoogleFonts.outfitTextTheme(ThemeData.dark().textTheme),
extensions: [FlareTheme.dark()],
),
home: const DashboardPage(),
);
}
}
class DashboardPage extends StatefulWidget {
const DashboardPage({super.key});
@override
State<DashboardPage> createState() => _DashboardPageState();
}
class _DashboardPageState extends State<DashboardPage> {
int _currentIndex = 0;
@override
Widget build(BuildContext context) {
return Scaffold(
extendBody: true, // Crucial for showing the glass bar over content
body: Stack(
children: [
// 1. Futuristic Background with vibrant color blobs
const BackgroundBlobs(),
// 2. Main Scrollable Content
SafeArea(
bottom: false,
child: SingleChildScrollView(
padding: const EdgeInsets.symmetric(horizontal: 24, vertical: 20),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const HeaderSection(),
const SizedBox(height: 32),
const BalanceCard(),
const SizedBox(height: 32),
const QuickActions(),
const SizedBox(height: 32),
const TransactionsSection(),
const SizedBox(height: 120), // BottomBar padding
],
),
),
),
],
),
bottomNavigationBar: FlareBottomBar(
currentIndex: _currentIndex,
onTap: (index) => setState(() => _currentIndex = index),
items: const [
FlareBarItem(icon: Icons.home_rounded),
FlareBarItem(icon: Icons.auto_graph_rounded),
FlareBarItem(icon: Icons.wallet_rounded),
FlareBarItem(icon: Icons.person_rounded),
],
),
);
}
}
class HeaderSection extends StatelessWidget {
const HeaderSection({super.key});
@override
Widget build(BuildContext context) {
return Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(
'Good evening,',
style: TextStyle(
color: Colors.white.withValues(alpha: 0.6),
fontSize: 16,
fontWeight: FontWeight.w500,
),
),
const Text(
'Ersan Q.',
style: TextStyle(
color: Colors.white,
fontSize: 28,
fontWeight: FontWeight.w800,
letterSpacing: -0.5,
),
),
],
),
FlareButton(
onPressed: () => FlareToast.show(context, message: 'Settings opened'),
isGlass: true,
padding: const EdgeInsets.all(12),
borderRadius: BorderRadius.circular(100),
child: const Icon(Icons.settings_outlined, size: 24),
),
],
);
}
}
class BalanceCard extends StatelessWidget {
const BalanceCard({super.key});
@override
Widget build(BuildContext context) {
return FlareCard(
onTap: () => FlareToast.show(context, message: 'Balance details'),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
const Text(
'Total Balance',
style: TextStyle(
color: Colors.white,
fontSize: 14,
fontWeight: FontWeight.w500,
),
),
FlareStatus(
label: '+12.5%',
type: FlareStatusType.success,
icon: Icons.trending_up_rounded,
borderRadius: BorderRadius.circular(100),
),
],
),
const SizedBox(height: 12),
const Text(
'\$14,290.50',
style: TextStyle(
color: Colors.white,
fontSize: 36,
fontWeight: FontWeight.w800,
letterSpacing: -1,
),
),
const SizedBox(height: 24),
Row(
children: [
Expanded(
child: FlareButton(
onPressed: () => FlareToast.show(context, message: 'Withdraw success'),
isGlass: false,
backgroundColor: const Color(0xFF007AFF),
child: const Text('Send'),
),
),
const SizedBox(width: 16),
Expanded(
child: FlareButton(
onPressed: () => FlareToast.show(context, message: 'Funds added'),
isGlass: true,
child: const Text('Add Money'),
),
),
],
),
],
),
);
}
}
class QuickActions extends StatelessWidget {
const QuickActions({super.key});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SectionLabel(label: 'Quick Actions'),
const SizedBox(height: 16),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
children: [
_actionIcon(context, Icons.electric_bolt_rounded, 'Utility'),
_actionIcon(context, Icons.phone_android_rounded, 'Recharge'),
_actionIcon(context, Icons.credit_card_rounded, 'Cards'),
_actionIcon(context, Icons.more_horiz_rounded, 'More'),
],
),
],
);
}
Widget _actionIcon(BuildContext context, IconData icon, String label) {
return Column(
children: [
FlareButton(
onPressed: () => FlareToast.show(context, message: '$label tapped'),
isGlass: true,
padding: const EdgeInsets.all(18),
borderRadius: BorderRadius.circular(20),
child: Icon(icon, size: 28),
),
const SizedBox(height: 8),
Text(
label,
style: TextStyle(
color: Colors.white.withValues(alpha: 0.7),
fontSize: 12,
fontWeight: FontWeight.w600,
),
),
],
);
}
}
class TransactionsSection extends StatelessWidget {
const TransactionsSection({super.key});
@override
Widget build(BuildContext context) {
return Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
const SectionLabel(label: 'Recent Activity'),
const SizedBox(height: 16),
_transactionItem(context, 'Uber Eats', '2 min ago', '-\$24.50', FlareStatusType.info),
_transactionItem(context, 'Airbnb Refund', 'Yesterday', '+\$150.00', FlareStatusType.success),
_transactionItem(context, 'Failed Sync', '2 days ago', 'Error', FlareStatusType.error),
],
);
}
Widget _transactionItem(BuildContext context, String title, String date, String amount, FlareStatusType type) {
return Padding(
padding: const EdgeInsets.only(bottom: 12),
child: FlareCard(
padding: const EdgeInsets.symmetric(horizontal: 16, vertical: 14),
borderRadius: BorderRadius.circular(20),
onTap: () {},
child: Row(
children: [
CircleAvatar(
backgroundColor: Colors.white.withValues(alpha: 0.1),
child: Icon(Icons.payment_rounded, color: Colors.white.withValues(alpha: 0.8), size: 20),
),
const SizedBox(width: 16),
Expanded(
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Text(title, style: const TextStyle(fontWeight: FontWeight.w700, fontSize: 15)),
Text(date, style: TextStyle(color: Colors.white.withValues(alpha: 0.4), fontSize: 13)),
],
),
),
Column(
crossAxisAlignment: CrossAxisAlignment.end,
children: [
Text(amount, style: const TextStyle(fontWeight: FontWeight.w800, fontSize: 15)),
const SizedBox(height: 4),
FlareStatus(
label: type.name.toUpperCase(),
type: type,
padding: const EdgeInsets.symmetric(horizontal: 6, vertical: 2),
borderRadius: BorderRadius.circular(4),
),
],
),
],
),
),
);
}
}
class SectionLabel extends StatelessWidget {
final String label;
const SectionLabel({super.key, required this.label});
@override
Widget build(BuildContext context) {
return Text(
label,
style: const TextStyle(
fontSize: 18,
fontWeight: FontWeight.w800,
color: Colors.white,
),
);
}
}
class BackgroundBlobs extends StatelessWidget {
const BackgroundBlobs({super.key});
@override
Widget build(BuildContext context) {
return Stack(
children: [
Positioned(
top: -100,
right: -50,
child: _blob(250, const Color(0xFF007AFF).withValues(alpha: 0.3)),
),
Positioned(
bottom: 100,
left: -80,
child: _blob(300, const Color(0xFFFF2D55).withValues(alpha: 0.2)),
),
Positioned(
top: 300,
left: 100,
child: _blob(200, const Color(0xFF5856D6).withValues(alpha: 0.25)),
),
],
);
}
Widget _blob(double size, Color color) {
return Container(
width: size,
height: size,
decoration: BoxDecoration(
shape: BoxShape.circle,
color: color,
),
);
}
}