kompkit_core 0.4.1-alpha.0
kompkit_core: ^0.4.1-alpha.0 copied to clipboard
Cross-platform utility functions for Flutter and Dart applications. Part of the KompKit ecosystem.
KompKit Core — Flutter / Dart #
Cross-platform utility functions for Flutter and Dart applications. Part of the KompKit ecosystem with identical APIs across Web (TypeScript), Android (Kotlin), and Flutter (Dart).
⚠️ Alpha: APIs may change before
1.0.0. Pin to an exact version in production.
Installation #
Add to your pubspec.yaml:
dependencies:
kompkit_core: ^0.4.1-alpha.0
Then run:
flutter pub get
Published on pub.dev/packages/kompkit_core
Quick Start #
import 'package:kompkit_core/kompkit_core.dart';
// Debounce — delay until calls stop
final onSearch = debounce<String>(
(query) => print('Searching: $query'),
const Duration(milliseconds: 300),
);
// Email validation
print(isEmail('user@example.com')); // true
print(isEmail('invalid@')); // false
// Currency formatting (en-US / USD default)
print(formatCurrency(1234.56)); // "$1,234.56"
print(formatCurrency(1234.56, currency: 'EUR', locale: 'es-ES')); // "1.234,56 €"
// Clamp a value to a range
print(clamp(15.0, 0.0, 10.0)); // 10.0
// Throttle — at most once per interval
final onScroll = throttle<double>(
(offset) => print('offset: $offset'),
const Duration(milliseconds: 200),
);
API Reference #
debounce #
Delays execution until calls stop for the given wait duration. The last call within the wait period executes; all earlier ones are cancelled.
Debounced<T> debounce<T>(void Function(T) action, Duration wait)
final onSearch = debounce<String>(
(query) => fetchResults(query),
const Duration(milliseconds: 300),
);
onSearch('k');
onSearch('ko');
onSearch('kompkit'); // only this executes, after 300ms of inactivity
onSearch.cancel(); // discard pending call — call in dispose()
Flutter StatefulWidget example:
class SearchWidget extends StatefulWidget {
@override
State<SearchWidget> createState() => _SearchWidgetState();
}
class _SearchWidgetState extends State<SearchWidget> {
late final Debounced<String> _onSearch;
@override
void initState() {
super.initState();
_onSearch = debounce<String>(
(query) => setState(() { /* update results */ }),
const Duration(milliseconds: 300),
);
}
@override
void dispose() {
_onSearch.cancel();
super.dispose();
}
@override
Widget build(BuildContext context) {
return TextField(onChanged: _onSearch.call);
}
}
throttle #
Limits execution to at most once per wait duration. The first call executes immediately; subsequent calls within the cooldown are ignored.
Throttled<T> throttle<T>(void Function(T) action, Duration wait)
final onScroll = throttle<double>(
(offset) => print('scroll: $offset'),
const Duration(milliseconds: 200),
);
onScroll(0.0); // executes immediately
onScroll(50.0); // ignored — within 200ms cooldown
onScroll.cancel(); // reset state — call in dispose()
Flutter StatefulWidget with ScrollController:
class ScrollTracker extends StatefulWidget {
@override
State<ScrollTracker> createState() => _ScrollTrackerState();
}
class _ScrollTrackerState extends State<ScrollTracker> {
final _controller = ScrollController();
late final Throttled<double> _onScroll;
double _offset = 0;
@override
void initState() {
super.initState();
_onScroll = throttle<double>(
(offset) => setState(() => _offset = offset),
const Duration(milliseconds: 200),
);
_controller.addListener(() => _onScroll(_controller.offset));
}
@override
void dispose() {
_onScroll.cancel();
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Column(
children: [
Text('Offset: ${_offset.toStringAsFixed(1)}'),
Expanded(
child: ListView.builder(
controller: _controller,
itemCount: 100,
itemBuilder: (_, i) => ListTile(title: Text('Item $i')),
),
),
],
);
}
}
isEmail #
Validates an email address.
bool isEmail(String value)
isEmail('user@example.com') // true
isEmail('invalid@') // false
isEmail(' user@domain.org ') // true (trimmed)
formatCurrency #
Formats a number as a localized currency string.
String formatCurrency(double amount, {String currency = 'USD', String locale = 'en-US'})
formatCurrency(1234.56) // "$1,234.56"
formatCurrency(1234.56, currency: 'EUR', locale: 'es-ES') // "1.234,56 €"
formatCurrency(1234.56, currency: 'JPY', locale: 'ja-JP') // "¥1,235"
- Accepts BCP 47 locale strings; normalizes
en-US→en_USfor theintlpackage internally - Throws on invalid
currencycodes
clamp #
Constrains a value within an inclusive [min, max] range.
double clamp(double value, double min, double max)
clamp(5.0, 0.0, 10.0) // 5.0
clamp(-3.0, 0.0, 10.0) // 0.0
clamp(15.0, 0.0, 10.0) // 10.0
final opacity = clamp(userInput, 0.0, 1.0);
final volume = clamp(rawVolume, 0.0, 100.0);
Lifecycle and cancellation #
Both debounce and throttle return objects with a cancel() method. Always call cancel() in dispose() to prevent callbacks from firing after a widget is removed:
@override
void dispose() {
_debouncedSearch.cancel();
_throttledScroll.cancel();
super.dispose();
}
Platform support #
| Platform | Supported |
|---|---|
| Flutter iOS | ✅ |
| Flutter Android | ✅ |
| Flutter Web | ✅ |
| Flutter Desktop (Windows, macOS, Linux) | ✅ |
| Dart VM (server-side) | ✅ |
| Dart Web (compiled to JS) | ✅ |
Compatibility: Flutter 3.0+ · Dart SDK ≥ 3.0.0
Documentation #
- Flutter Guide — Detailed usage with complete widget examples
- Main README — Project overview and cross-platform APIs
- Architecture — API parity contract and platform differences
- Recipes — Real-world usage patterns across all platforms
- API Reference — DartDoc generated documentation (generated locally via
dart doc)
Testing #
flutter test # Flutter projects
dart test # Dart-only projects
flutter test --coverage # with coverage report