{"id":21196325,"url":"https://github.com/davigmacode/flutter_widget_event","last_synced_at":"2026-02-05T05:02:08.248Z","repository":{"id":61152500,"uuid":"548725471","full_name":"davigmacode/flutter_widget_event","owner":"davigmacode","description":"Just like MaterialState but with convenient name and more spices.","archived":false,"fork":false,"pushed_at":"2024-08-06T06:06:18.000Z","size":118,"stargazers_count":2,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-07-11T05:35:23.389Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/davigmacode.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2022-10-10T04:48:57.000Z","updated_at":"2024-08-06T06:06:22.000Z","dependencies_parsed_at":"2024-03-13T08:44:40.076Z","dependency_job_id":"647cfb5d-8373-4998-b2d6-614f9437a493","html_url":"https://github.com/davigmacode/flutter_widget_event","commit_stats":{"total_commits":17,"total_committers":1,"mean_commits":17.0,"dds":0.0,"last_synced_commit":"311fd5cc2c28273e3fa21b6791109af9cd3d8063"},"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/davigmacode/flutter_widget_event","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davigmacode%2Fflutter_widget_event","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davigmacode%2Fflutter_widget_event/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davigmacode%2Fflutter_widget_event/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davigmacode%2Fflutter_widget_event/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/davigmacode","download_url":"https://codeload.github.com/davigmacode/flutter_widget_event/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/davigmacode%2Fflutter_widget_event/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29113188,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-05T03:44:17.043Z","status":"ssl_error","status_checked_at":"2026-02-05T03:44:12.077Z","response_time":65,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-11-20T19:35:35.496Z","updated_at":"2026-02-05T05:02:08.233Z","avatar_url":"https://github.com/davigmacode.png","language":"Dart","funding_links":["https://www.buymeacoffee.com/davigmacode","https://ko-fi.com/davigmacode"],"categories":[],"sub_categories":[],"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\u0026color=yellow\u0026label)](https://www.buymeacoffee.com/davigmacode) [![GitHub](https://badgen.net/badge/icon/ko-fi?icon=kofi\u0026color=red\u0026label)](https://ko-fi.com/davigmacode)\n\nJust like MaterialState but with convenient name and more spices.\n\n## Features\n\n* Convenient name\n* Extendable event\n* More helpers\n\n## Usage\n\nTo read more about classes and other references used by `widget_event`, see the [API Reference](https://pub.dev/documentation/widget_event/latest/).\n\n```dart\n// Let's say, we have a custom widget with custom [style] property,\n// we want to dynamically change the [style] value when some event happen\n// on that widget, for example on pressed\n\nclass MyStyle {\n  const MyStyle({\n    this.color = Colors.blue,\n    this.opacity = 1,\n  });\n\n  final Color color;\n  final double opacity;\n}\n\nclass MyWidget extends StatefulWidget {\n  const MyWidget({\n    Key? key,\n    this.style,\n    this.onPressed,\n  }) : super(key: key);\n\n  final MyStyle? style;\n  final VoidCallback? onPressed;\n\n  @override\n  State\u003cMyWidget\u003e createState() =\u003e MyWidgetState();\n}\n\nclass MyWidgetState extends State\u003cMyWidget\u003e {\n  @override\n  Widget build(BuildContext context) {\n    return Container(\n      color: style?.color ?? Colors.red,\n      child: TextField(\n        decoration: InputDecoration(\n          border: OutlineInputBorder(\n            borderSide: BorderSide(\n              color: style?.color ?? Colors.black54,\n            ),\n          ),\n          label: const Text('Password'),\n        ),\n      ),\n    );\n  }\n}\n```\n\n```dart\n// The fastest way to achieve that is to change [MyStyle?]\n// to [DrivenProperty\u003cMyStyle?\u003e?], and use [WidgetEventMixin]\n// with [MyWidgetState] to watch [WidgetEvent] values.\n\nclass MyWidget extends StatefulWidget {\n  const MyWidget({\n    Key? key,\n    this.style,\n    this.onPressed,\n  }) : super(key: key);\n\n  final DrivenProperty\u003cMyStyle?\u003e? style;\n  final VoidCallback? onPressed;\n\n  @override\n  State\u003cMyWidget\u003e createState() =\u003e MyWidgetState();\n}\n\nclass MyWidgetState extends State\u003cMyWidget\u003e with WidgetEventMixin\u003cMyWidget\u003e {\n  @override\n  Widget build(BuildContext context) {\n    final MyStyle? style = widget.style?.resolve(widgetEvents);\n    return Container(\n      color: style?.color ?? Colors.red,\n      child: TextField(\n        onTap: () {\n          widgetEvents.toggle(WidgetEvent.pressed, true);\n        },\n        decoration: InputDecoration(\n          border: OutlineInputBorder(\n            borderSide: BorderSide(\n              color: style?.color ?? Colors.black54,\n            ),\n          ),\n          label: const Text('Password'),\n        ),\n      ),\n    );\n  }\n}\n\n// Then we can fill [style] with event driven value\nfinal myWidget = MyWidget(\n  style: DrivenProperty.by\u003cMyStyle?\u003e((events) {\n    if (events.isPressed) {\n      return const MyStyle(color: Colors.amber);\n    }\n    return null;\n  }),\n);\n\n// But we can't fill [style] with [MyStyle] directly anymore\nfinal myWidget = MyWidget(\n  // this will raise a type check error\n  style: const MyStyle(color: Colors.amber),\n);\n\n// Once more the fastest way to fill [style]\n// with a single value for all events is\nfinal myWidget = MyWidget(\n  style: DrivenProperty.all\u003cMyStyle?\u003e(\n    const MyStyle(color: Colors.amber),\n  ),\n);\n```\n\n```dart\n// What if we want the event driven [style]\n// and we want to directly fill the [style] with [MyStyle] too,\n// so just create a custom [DrivenProperty]\n\nabstract class DrivenMyStyle extends MyStyle implements DrivenProperty\u003cMyStyle?\u003e {\n  const DrivenMyStyle();\n\n  @override\n  MyStyle? resolve(Set\u003cWidgetEvent\u003e events);\n\n  static MyStyle? evaluate(MyStyle? value, Set\u003cWidgetEvent\u003e events) {\n    return DrivenProperty.evaluate\u003cMyStyle?\u003e(value, events);\n  }\n\n  static DrivenMyStyle by(DrivenPropertyResolver\u003cMyStyle?\u003e callback) {\n    return _DrivenMyStyle(callback);\n  }\n\n  static DrivenMyStyle all(MyStyle? value) {\n    return _DrivenMyStyle((events) =\u003e value);\n  }\n}\n\nclass _DrivenMyStyle extends DrivenMyStyle {\n  _DrivenMyStyle(this._resolver) : super();\n\n  final DrivenPropertyResolver\u003cMyStyle?\u003e _resolver;\n\n  @override\n  MyStyle? resolve(Set\u003cWidgetEvent\u003e events) =\u003e _resolver(events);\n}\n\n// Also we can add helpers to [MyStyle]\nclass MyStyle {\n  const MyStyle({\n    this.color = Colors.blue,\n    this.opacity = 1,\n  });\n\n  final Color color;\n  final double opacity;\n\n  static DrivenMyStyle driven(\n    DrivenPropertyResolver\u003cMyStyle?\u003e callback,\n  ) {\n    return DrivenMyStyle.by(callback);\n  }\n}\n\n// And finally a little modification on the [MyWidget]\n// to evaluate value from [MyStyle] or [DrivenMyStyle]\nclass MyWidget extends StatefulWidget {\n  const MyWidget({\n    Key? key,\n    this.style,\n    this.onPressed,\n  }) : super(key: key);\n\n  final MyStyle? style;\n  final VoidCallback? onPressed;\n\n  @override\n  State\u003cMyWidget\u003e createState() =\u003e MyWidgetState();\n}\n\nclass MyWidgetState extends State\u003cMyWidget\u003e with WidgetEventMixin\u003cMyWidget\u003e {\n  @override\n  Widget build(BuildContext context) {\n    final MyStyle? style = MyStyle.evaluate(widget.style, widgetEvents);\n    return Container(\n      color: style?.color ?? Colors.red,\n      child: TextField(\n        onTap: () {\n          widgetEvents.toggle(WidgetEvent.pressed, true);\n        },\n        decoration: InputDecoration(\n          border: OutlineInputBorder(\n            borderSide: BorderSide(\n              color: style?.color ?? Colors.black54,\n            ),\n          ),\n          label: const Text('Password'),\n        ),\n      ),\n    );\n  }\n}\n\n// Finally we can directly fill with [MyStyle]\nfinal myWidget = MyWidget(\n  style: const MyStyle(color: Colors.amber),\n);\n\n// Or with event driven value\nfinal myWidget = MyWidget(\n  style: MyStyle.driven((events) {\n    if (events.isPressed) {\n      return const MyStyle(color: Colors.amber);\n    }\n    return null;\n  }),\n);\n```\n\n```dart\n// Wait, but how if we need a custom event, here is the recipes\n\nclass MyWidgetEvent extends WidgetEvent {\n  const MyWidgetEvent(String value) : super(value);\n\n  static const edited = MyWidgetEvent('edited');\n\n  static bool isEdited(Set\u003cWidgetEvent\u003e events) {\n    return events.contains(MyWidgetEvent.edited);\n  }\n}\n\nclass MyWidget extends StatefulWidget {\n  const MyWidget({\n    Key? key,\n    this.style,\n    this.onPressed,\n  }) : super(key: key);\n\n  final MyStyle? style;\n  final VoidCallback? onPressed;\n\n  @override\n  State\u003cMyWidget\u003e createState() =\u003e MyWidgetState();\n}\n\nclass MyWidgetState extends State\u003cMyWidget\u003e with WidgetEventMixin\u003cMyWidget\u003e {\n  @override\n  Widget build(BuildContext context) {\n    final MyStyle? style = MyStyle.evaluate(widget.style, widgetEvents);\n    return Container(\n      color: style?.color ?? Colors.red,\n      child: TextField(\n        onTap: () {\n          widgetEvents.toggle(WidgetEvent.pressed, true);\n        },\n        onChanged: (value) {\n          widgetEvents.toggle(MyWidgetEvent.edited, true);\n        },\n        decoration: InputDecoration(\n          border: OutlineInputBorder(\n            borderSide: BorderSide(\n              color: style?.color ?? Colors.black54,\n            ),\n          ),\n          label: const Text('Password'),\n        ),\n      ),\n    );\n  }\n}\n\nfinal myWidget = MyWidget(\n  style: MyStyle.driven((events) {\n    if (MyWidgetEvent.isEdited(events)) {\n      return const MyStyle(color: Colors.amber);\n    }\n    return null;\n  }),\n);\n```\n\n## Sponsoring\n\n\u003ca href=\"https://www.buymeacoffee.com/davigmacode\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" height=\"45\"\u003e\u003c/a\u003e\n\u003ca href=\"https://ko-fi.com/davigmacode\" target=\"_blank\"\u003e\u003cimg src=\"https://storage.ko-fi.com/cdn/brandasset/kofi_s_tag_white.png\" alt=\"Ko-Fi\" height=\"45\"\u003e\u003c/a\u003e\n\nIf 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.","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavigmacode%2Fflutter_widget_event","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdavigmacode%2Fflutter_widget_event","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdavigmacode%2Fflutter_widget_event/lists"}