exxen 0.1.0
exxen: ^0.1.0 copied to clipboard
Exxen is a Flutter package that offers extensions to make your code cleaner, reusable, and easier to maintain. It is compatible with WebAssembly (WASM).
import 'package:flutter/material.dart';
import 'package:exxen/exxen.dart';
void main() {
runApp(const MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Exxen Demo',
theme: ThemeData(
colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple),
useMaterial3: true,
),
home: const MyHomePage(title: 'Exxen Demo'),
);
}
}
class MyHomePage extends StatefulWidget {
const MyHomePage({super.key, required this.title});
final String title;
@override
State<MyHomePage> createState() => _MyHomePageState();
}
class _MyHomePageState extends State<MyHomePage> {
int _counter = 0;
void _incrementCounter() {
setState(() => _counter++);
/// context.showSnackBar is the same as
/// ScaffoldMessenger.of(context).showSnackBar(SnackBar(content: Text(...)))
context.showSnackBar('Counter is $_counter');
}
/// A rounded card built entirely out of exxensions.
Widget _section(String title, List<Widget> children) => <Widget>[
/// context.textTheme.titleMedium.bold chains straight off the text theme
title.toText(style: context.textTheme.titleMedium.bold),
...children,
]
/// .gap(8) inserts a SizedBox(height: 8) between every child
.gap(8)
.toColumn(crossAxisAlignment: CrossAxisAlignment.start)
/// 16.all is the same as EdgeInsets.all(16)
.paddingAll(16)
.decorated(
color: context.colorScheme.surfaceContainerHighest,
/// 12.radius is the same as BorderRadius.circular(12)
borderRadius: 12.radius,
);
@override
Widget build(BuildContext context) {
final now = DateTime.now();
return Scaffold(
appBar: AppBar(
/// context.colorScheme is the same as Theme.of(context).colorScheme
backgroundColor: context.colorScheme.inversePrimary,
title: Text(widget.title),
),
body: <Widget>[
_section('Counter', <Widget>[
'You have pushed the button this many times:'.toText(),
/// 'text'.toText() is the same as Text('text')
'$_counter'.toText(style: context.textTheme.headlineMedium),
]),
_section('Context', <Widget>[
'Dark mode: ${context.isDarkMode}'.toText(),
'Mobile layout: ${context.isMobile}'.toText(),
'Screen: ${context.screenWidth.toStringAsFixed(0)}'
' x ${context.screenHeight.toStringAsFixed(0)}'
.toText(),
]),
_section('String', <Widget>[
'oğuzhan arslantaş'.toTitleCase.toText(),
'Initials: ${'Oğuzhan Arslantaş'.initials()}'.toText(),
'Turkish upper case: ${'istanbul'.toTurkishUpperCase}'.toText(),
'Masked card: ${'4242424242424242'.mask()}'.toText(),
]),
_section('Date', <Widget>[
now.toDateTimeString().toText(),
'1 hour ago: ${1.hours.ago.timeAgo}'.toText(),
]),
_section('Color', <Widget>[
<Color>[
context.colorScheme.primary.lighten(0.2),
context.colorScheme.primary,
context.colorScheme.primary.darken(0.2),
]
/// Color.box() paints a small preview square
.map((color) => color.box(size: 32, borderRadius: 8.radius))
.toList()
.gap(8, direction: Axis.horizontal)
.toRow(),
'Primary as hex: ${context.colorScheme.primary.toHex()}'.toText(),
]),
]
/// .gap(16).toListView() is the same as
/// ListView(children: [...]) with a SizedBox between every child
.gap(16)
.toListView(padding: 16.all),
floatingActionButton: FloatingActionButton(
onPressed: _incrementCounter,
tooltip: 'Increment',
child: const Icon(Icons.add),
),
/// LayoutSnapperButton leaves its hero tag empty, so it can sit next to
/// the FloatingActionButton above without a duplicate hero error.
persistentFooterButtons: const <Widget>[LayoutSnapperButton()],
);
}
}