flutter_essentials_plus 1.0.2
flutter_essentials_plus: ^1.0.2 copied to clipboard
A modern collection of extensions, validators, formatters, and helper utilities that reduce Flutter boilerplate while keeping code clean, readable, and maintainable.
import 'package:flutter/material.dart';
import 'package:flutter_essentials_plus/flutter_essentials_plus.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Essentials Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key});
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
final _formKey = GlobalKey<FormState>();
bool _isLoading = false;
int _animationKey = 0;
final Debouncer _debouncer =
Debouncer(delay: const Duration(milliseconds: 500));
Widget _sectionHeader(String title) {
return Padding(
padding: const EdgeInsets.only(top: 32, bottom: 12),
child: Text(
title,
style: const TextStyle(
fontWeight: FontWeight.bold,
fontSize: 22,
color: Colors.deepPurple),
),
);
}
@override
Widget build(BuildContext context) {
final now = DateTime.now();
return Scaffold(
appBar: AppBar(
title: const Text('All Extensions Demo'),
),
body: LoadingOverlay(
isLoading: _isLoading,
child: Form(
key: _formKey,
child: SingleChildScrollView(
padding: context.safeArea + const EdgeInsets.all(16),
child: Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
_sectionHeader('1. Context Extensions'),
Text('context.screenSize: ${context.screenSize}'),
Text('context.isDark: ${context.isDark}'),
Text('context.isLandscape: ${context.isLandscape}'),
Text('context.isPortrait: ${context.isPortrait}'),
Text('context.breakpoint: ${context.breakpoint}'),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton(
onPressed: () => context.hideKeyboard(),
child: const Text('hideKeyboard()')),
ElevatedButton(
onPressed: () => context.push(Scaffold(
appBar: AppBar(),
body: const Center(child: Text('Pushed Page')))),
child: const Text('push(page)'),
),
ElevatedButton(
onPressed: () => context.showSnackBar(
const SnackBar(content: Text('Snackbar!'))),
child: const Text('showSnackBar()'),
),
ElevatedButton(
onPressed: () => context.showBottomSheet(
builder: (_) => Container(
height: 200,
color: Colors.white,
child: const Center(child: Text('Bottom Sheet'))),
),
child: const Text('showBottomSheet()'),
),
ElevatedButton(
onPressed: () => context.showDialog(
builder: (_) =>
const AlertDialog(title: Text('Dialog')),
),
child: const Text('showDialog()'),
),
ElevatedButton(
onPressed: () async {
setState(() => _isLoading = true);
await Future.delayed(2.seconds);
setState(() => _isLoading = false);
},
child: const Text('Test LoadingOverlay'),
),
],
),
_sectionHeader('2. String Extensions'),
Text('text.capitalize: ${"hello world".capitalize}'),
Text('text.camelCase: ${"hello_world".camelCase}'),
Text(
'text.truncate(30): ${"This is a very long string that should be truncated".truncate(30)}'),
Text('text.maskEmail(): ${"test@example.com".maskEmail()}'),
Text('text.isEmail: ${"test@example.com".isEmail}'),
Text('text.isAlphaNumeric: ${"HelloWorld123".isAlphaNumeric}'),
Text(
'text.extractEmails: ${"Contact test@test.com or admin@test.com".extractEmails()}'),
_sectionHeader('3. Number Extensions'),
Text('1000.format(): ${1000.format()}'),
Text('1500000.formatCurrency(): ${1500000.formatCurrency()}'),
Text('125648.bytesToReadable(): ${125648.bytesToReadable()}'),
Text('30.seconds: ${30.seconds}'),
_sectionHeader('4. DateTime Extensions'),
Text('date.timeAgo: ${now.subtract(2.hours).timeAgo}'),
Text('date.isToday: ${now.isToday}'),
Text('date.monthName: ${now.monthName}'),
Text('date.isWeekend: ${now.isWeekend}'),
_sectionHeader('5. Widget Extensions'),
const Text("Hello chained widgets!")
.paddingAll(16)
.center()
.card()
.shadow()
.animateFade(),
const SizedBox(height: 16),
Wrap(
spacing: 16,
runSpacing: 16,
children: [
const Text("widget.opacity(.5)").opacity(0.5),
const Text("widget.rotate()").rotate(quarterTurns: 1),
const Text("widget.scale()").scale(1.2),
const Text("widget.blur()").blur(sigmaX: 2.0, sigmaY: 2.0),
const Text("widget.clipRadius()")
.paddingAll(8)
.clipRadius(8.0),
const Text("widget.loading(true)").loading(true),
],
),
_sectionHeader('7. Validators'),
TextFormField(
decoration:
const InputDecoration(labelText: 'Validators.email'),
validator: Validators.email()),
TextFormField(
decoration:
const InputDecoration(labelText: 'Validators.cnic'),
validator: Validators.cnic()),
ElevatedButton(
onPressed: () => _formKey.currentState?.validate(),
child: const Text('Test Validators'),
),
_sectionHeader('8. Formatting'),
Text(
'Formatters.currency(150000): ${Formatters.currency(150000)}'),
Text(
"Formatters.iban('PK00BANK000000000000'): ${Formatters.iban('PK00BANK000000000000')}"),
Text(
'Formatters.fileSize(1048576): ${Formatters.fileSize(1048576)}'),
Text('Formatters.distance(1500): ${Formatters.distance(1500)}'),
_sectionHeader('9. Helper Widgets'),
Wrap(
spacing: 16,
runSpacing: 16,
children: [
DebounceButton(
onPressed: () async {
await Future.delayed(1.seconds);
},
child: const Text('Debounce Button')),
const ExpandableText(
'This is a very long text that will be truncated after a certain amount of lines. Tap read more to expand this view fully so you can see all the details.',
maxLines: 1),
const SizedBox(
width: 200,
child: PasswordStrength(password: 'StrongP@ss123!')),
OtpTimer(seconds: 5, onResend: () {}),
const AvatarGenerator('John Doe'),
const ShimmerBox(width: 100, height: 20),
ShimmerEffect(
child: Row(
mainAxisSize: MainAxisSize.min,
children: [
Container(
width: 40,
height: 40,
decoration: const BoxDecoration(
color: Colors.white, shape: BoxShape.circle)),
const SizedBox(width: 8),
Column(
crossAxisAlignment: CrossAxisAlignment.start,
children: [
Container(
width: 60, height: 10, color: Colors.white),
const SizedBox(height: 4),
Container(
width: 40, height: 10, color: Colors.white),
],
),
],
),
),
RetryButton(onRetry: () {}),
const CopyText('Copy this text!'),
const GradientBorder(
gradient:
LinearGradient(colors: [Colors.red, Colors.blue]),
child: Padding(
padding: EdgeInsets.all(8),
child: Text('Gradient Border'))),
const NetworkImagePlaceholder(
'https://via.placeholder.com/150',
width: 50,
height: 50),
ResponsiveBuilder(
mobile: (_) => const Text('Mobile View'),
tablet: (_) => const Text('Tablet View'),
desktop: (_) => const Text('Desktop View'),
),
],
),
const SizedBox(height: 16),
const EmptyState(
title: 'No Data Found',
subtitle: 'Please check back later.'),
const SizedBox(height: 16),
ErrorState(message: 'Failed to fetch data.', onRetry: () {}),
const SizedBox(height: 16),
AsyncBuilder<String>(
future: Future.delayed(2.seconds, () => "Async Loaded Data"),
builder: (context, data) => Text('AsyncBuilder Result: $data',
style: const TextStyle(color: Colors.green)),
),
Row(
mainAxisAlignment: MainAxisAlignment.spaceBetween,
crossAxisAlignment: CrossAxisAlignment.end,
children: [
_sectionHeader('10. Animations'),
Padding(
padding: const EdgeInsets.only(bottom: 12),
child: ElevatedButton.icon(
onPressed: () => setState(() => _animationKey++),
icon: const Icon(Icons.replay, size: 16),
label: const Text('Replay'),
),
),
],
),
Wrap(
key: ValueKey(_animationKey),
spacing: 24,
runSpacing: 24,
children: [
const Text('fade()').fade(),
const Text('slide()').slide(),
const Text('zoom()').zoom(),
const Text('animatedRotate()').animatedRotate(),
const Text('flip()').flip(),
const Text('shake()').shake(),
const Text('animatedScale()').animatedScale(),
const Text('bounce()').bounce(),
const Text('elastic()').elastic(),
const Text('wiggle()').wiggle(),
],
),
_sectionHeader('11. Utilities'),
Text('UUID: ${UuidGenerator.generate()}'),
Text('Random String: ${RandomGenerator.string(10)}'),
Text('Platform is mobile: ${PlatformHelper.isMobile}'),
Wrap(
spacing: 8,
runSpacing: 8,
children: [
ElevatedButton(
onPressed: () => Logger.info('This is an info log!'),
child: const Text('Logger.info')),
ElevatedButton(
onPressed: () => ClipboardHelper.copy('Copied text!'),
child: const Text('Clipboard.copy')),
ElevatedButton(
onPressed: () async {
final v = await InternetHelper.hasConnection();
if (context.mounted)
context.showSnackBar(
SnackBar(content: Text('Internet: $v')));
},
child: const Text('Check Internet')),
ElevatedButton(
onPressed: () async {
final v = await BatteryHelper.getLevel();
if (context.mounted)
context.showSnackBar(
SnackBar(content: Text('Battery: $v%')));
},
child: const Text('Check Battery')),
ElevatedButton(
onPressed: () => _debouncer.run(() =>
context.showSnackBar(const SnackBar(
content: Text('Debounced action!')))),
child: const Text('Test Debouncer')),
],
),
_sectionHeader('12. Color Extensions'),
Row(
children: [
Container(
width: 50, height: 50, color: Colors.blue.lighten()),
const SizedBox(width: 10),
Container(
width: 50, height: 50, color: Colors.blue.darken()),
const SizedBox(width: 10),
Text('Hex: ${Colors.blue.hex}'),
const SizedBox(width: 10),
Container(
width: 50, height: 50, color: ColorExtensions.random()),
],
),
const SizedBox(height: 10),
Container(
height: 50,
decoration: BoxDecoration(
gradient: Colors.red.gradientTo(Colors.blue))),
_sectionHeader('13. Iterable Extensions'),
Text('[1, 2, 3].firstOrNull: ${[1, 2, 3].firstOrNull}'),
Text('[1, 2, 3].random(): ${[1, 2, 3].random()}'),
Text('[1, 2, 3].shuffleCopy(): ${[1, 2, 3].shuffleCopy()}'),
Text('[1, 2, 3, 4, 5].chunk(2): ${[1, 2, 3, 4, 5].chunk(2)}'),
Text('[{id: 1}, {id: 1}].groupBy: ${[
{'id': 1},
{'id': 1}
].groupBy((e) => e['id'])}'),
Text('[1, 1, 2, 2, 3].unique(): ${[1, 1, 2, 2, 3].unique()}'),
Text('[3, 1, 2].sorted(): ${[3, 1, 2].sorted()}'),
_sectionHeader('14. Map Extensions'),
Text("{'a': 1}.getInt('a'): ${{'a': 1}.getInt('a')}"),
Text("{'a': 1, 'b': null}.removeNulls(): ${{
'a': 1,
'b': null
}.removeNulls()}"),
Text("{'a': 1}.deepCopy(): ${{'a': 1}.deepCopy()}"),
const SizedBox(height: 50),
],
),
),
),
),
);
}
}