Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/davigmacode/flutter_widget_event
Just like MaterialState but with convenient name and more spices.
https://github.com/davigmacode/flutter_widget_event
Last synced: about 1 month ago
JSON representation
Just like MaterialState but with convenient name and more spices.
- Host: GitHub
- URL: https://github.com/davigmacode/flutter_widget_event
- Owner: davigmacode
- License: bsd-3-clause
- Created: 2022-10-10T04:48:57.000Z (about 2 years ago)
- Default Branch: main
- Last Pushed: 2024-08-06T06:06:18.000Z (5 months ago)
- Last Synced: 2024-08-06T08:03:21.961Z (5 months ago)
- Language: Dart
- Size: 115 KB
- Stars: 2
- Watchers: 3
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
[![Pub Version](https://img.shields.io/pub/v/widget_event)](https://pub.dev/packages/widget_event) ![GitHub](https://img.shields.io/github/license/davigmacode/flutter_widget_event) [![GitHub](https://badgen.net/badge/icon/buymeacoffee?icon=buymeacoffee&color=yellow&label)](https://www.buymeacoffee.com/davigmacode) [![GitHub](https://badgen.net/badge/icon/ko-fi?icon=kofi&color=red&label)](https://ko-fi.com/davigmacode)
Just like MaterialState but with convenient name and more spices.
## Features
* Convenient name
* Extendable event
* More helpers## Usage
To read more about classes and other references used by `widget_event`, see the [API Reference](https://pub.dev/documentation/widget_event/latest/).
```dart
// Let's say, we have a custom widget with custom [style] property,
// we want to dynamically change the [style] value when some event happen
// on that widget, for example on pressedclass MyStyle {
const MyStyle({
this.color = Colors.blue,
this.opacity = 1,
});final Color color;
final double opacity;
}class MyWidget extends StatefulWidget {
const MyWidget({
Key? key,
this.style,
this.onPressed,
}) : super(key: key);final MyStyle? style;
final VoidCallback? onPressed;@override
State createState() => MyWidgetState();
}class MyWidgetState extends State {
@override
Widget build(BuildContext context) {
return Container(
color: style?.color ?? Colors.red,
child: TextField(
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(
color: style?.color ?? Colors.black54,
),
),
label: const Text('Password'),
),
),
);
}
}
``````dart
// The fastest way to achieve that is to change [MyStyle?]
// to [DrivenProperty?], and use [WidgetEventMixin]
// with [MyWidgetState] to watch [WidgetEvent] values.class MyWidget extends StatefulWidget {
const MyWidget({
Key? key,
this.style,
this.onPressed,
}) : super(key: key);final DrivenProperty? style;
final VoidCallback? onPressed;@override
State createState() => MyWidgetState();
}class MyWidgetState extends State with WidgetEventMixin {
@override
Widget build(BuildContext context) {
final MyStyle? style = widget.style?.resolve(widgetEvents);
return Container(
color: style?.color ?? Colors.red,
child: TextField(
onTap: () {
widgetEvents.toggle(WidgetEvent.pressed, true);
},
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(
color: style?.color ?? Colors.black54,
),
),
label: const Text('Password'),
),
),
);
}
}// Then we can fill [style] with event driven value
final myWidget = MyWidget(
style: DrivenProperty.by((events) {
if (events.isPressed) {
return const MyStyle(color: Colors.amber);
}
return null;
}),
);// But we can't fill [style] with [MyStyle] directly anymore
final myWidget = MyWidget(
// this will raise a type check error
style: const MyStyle(color: Colors.amber),
);// Once more the fastest way to fill [style]
// with a single value for all events is
final myWidget = MyWidget(
style: DrivenProperty.all(
const MyStyle(color: Colors.amber),
),
);
``````dart
// What if we want the event driven [style]
// and we want to directly fill the [style] with [MyStyle] too,
// so just create a custom [DrivenProperty]abstract class DrivenMyStyle extends MyStyle implements DrivenProperty {
const DrivenMyStyle();@override
MyStyle? resolve(Set events);static MyStyle? evaluate(MyStyle? value, Set events) {
return DrivenProperty.evaluate(value, events);
}static DrivenMyStyle by(DrivenPropertyResolver callback) {
return _DrivenMyStyle(callback);
}static DrivenMyStyle all(MyStyle? value) {
return _DrivenMyStyle((events) => value);
}
}class _DrivenMyStyle extends DrivenMyStyle {
_DrivenMyStyle(this._resolver) : super();final DrivenPropertyResolver _resolver;
@override
MyStyle? resolve(Set events) => _resolver(events);
}// Also we can add helpers to [MyStyle]
class MyStyle {
const MyStyle({
this.color = Colors.blue,
this.opacity = 1,
});final Color color;
final double opacity;static DrivenMyStyle driven(
DrivenPropertyResolver callback,
) {
return DrivenMyStyle.by(callback);
}
}// And finally a little modification on the [MyWidget]
// to evaluate value from [MyStyle] or [DrivenMyStyle]
class MyWidget extends StatefulWidget {
const MyWidget({
Key? key,
this.style,
this.onPressed,
}) : super(key: key);final MyStyle? style;
final VoidCallback? onPressed;@override
State createState() => MyWidgetState();
}class MyWidgetState extends State with WidgetEventMixin {
@override
Widget build(BuildContext context) {
final MyStyle? style = MyStyle.evaluate(widget.style, widgetEvents);
return Container(
color: style?.color ?? Colors.red,
child: TextField(
onTap: () {
widgetEvents.toggle(WidgetEvent.pressed, true);
},
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(
color: style?.color ?? Colors.black54,
),
),
label: const Text('Password'),
),
),
);
}
}// Finally we can directly fill with [MyStyle]
final myWidget = MyWidget(
style: const MyStyle(color: Colors.amber),
);// Or with event driven value
final myWidget = MyWidget(
style: MyStyle.driven((events) {
if (events.isPressed) {
return const MyStyle(color: Colors.amber);
}
return null;
}),
);
``````dart
// Wait, but how if we need a custom event, here is the recipesclass MyWidgetEvent extends WidgetEvent {
const MyWidgetEvent(String value) : super(value);static const edited = MyWidgetEvent('edited');
static bool isEdited(Set events) {
return events.contains(MyWidgetEvent.edited);
}
}class MyWidget extends StatefulWidget {
const MyWidget({
Key? key,
this.style,
this.onPressed,
}) : super(key: key);final MyStyle? style;
final VoidCallback? onPressed;@override
State createState() => MyWidgetState();
}class MyWidgetState extends State with WidgetEventMixin {
@override
Widget build(BuildContext context) {
final MyStyle? style = MyStyle.evaluate(widget.style, widgetEvents);
return Container(
color: style?.color ?? Colors.red,
child: TextField(
onTap: () {
widgetEvents.toggle(WidgetEvent.pressed, true);
},
onChanged: (value) {
widgetEvents.toggle(MyWidgetEvent.edited, true);
},
decoration: InputDecoration(
border: OutlineInputBorder(
borderSide: BorderSide(
color: style?.color ?? Colors.black54,
),
),
label: const Text('Password'),
),
),
);
}
}final myWidget = MyWidget(
style: MyStyle.driven((events) {
if (MyWidgetEvent.isEdited(events)) {
return const MyStyle(color: Colors.amber);
}
return null;
}),
);
```## Sponsoring
If this package or any other package I created is helping you, please consider to sponsor me so that I can take time to read the issues, fix bugs, merge pull requests and add features to these packages.