{"id":24562873,"url":"https://github.com/kmartins/lid","last_synced_at":"2026-02-17T01:35:14.924Z","repository":{"id":47466743,"uuid":"290860526","full_name":"kmartins/lid","owner":"kmartins","description":"A Flutter library built to expose widgets that integrate with state notifier.","archived":false,"fork":false,"pushed_at":"2021-08-30T17:59:43.000Z","size":131,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-04-19T19:41:00.789Z","etag":null,"topics":["dart","dart-library","dart-web","dartland","flutter","flutter-package","library","state-management","state-notifier"],"latest_commit_sha":null,"homepage":"https://pub.dev/packages/flutter_lid","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kmartins.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2020-08-27T19:11:57.000Z","updated_at":"2024-04-03T15:25:22.000Z","dependencies_parsed_at":"2022-08-25T03:20:24.215Z","dependency_job_id":null,"html_url":"https://github.com/kmartins/lid","commit_stats":null,"previous_names":[],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/kmartins/lid","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kmartins%2Flid","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kmartins%2Flid/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kmartins%2Flid/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kmartins%2Flid/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kmartins","download_url":"https://codeload.github.com/kmartins/lid/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kmartins%2Flid/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29529513,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-17T00:57:22.232Z","status":"ssl_error","status_checked_at":"2026-02-17T00:54:25.811Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6: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":["dart","dart-library","dart-web","dartland","flutter","flutter-package","library","state-management","state-notifier"],"created_at":"2025-01-23T09:18:32.216Z","updated_at":"2026-02-17T01:35:14.906Z","avatar_url":"https://github.com/kmartins.png","language":"Dart","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Lid\n\n\u003cp align=\"center\"\u003e\n\u003ca href=\"https://pub.dev/packages/flutter_lid\"\u003e\u003cimg src=\"https://img.shields.io/pub/v/flutter_lid.svg\" alt=\"Pub\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/kmartins/lid/actions\"\u003e\u003cimg src=\"https://github.com/kmartins/lid/workflows/flutter_lid/badge.svg\" alt=\"build\"\u003e\u003c/a\u003e\n\u003ca href=\"https://codecov.io/gh/kmartins/lid\"\u003e\u003cimg src=\"https://codecov.io/gh/kmartins/lid/branch/main/graph/badge.svg\" alt=\"codecov\"\u003e\u003c/a\u003e\n\u003ca href=\"https://github.com/kmartins/lid\"\u003e\u003cimg src=\"https://img.shields.io/github/stars/kmartins/lid.svg?style=flat\u0026logo=github\u0026colorB=deeppink\u0026label=stars\" alt=\"Star on GitHub\"\u003e\u003c/a\u003e\n\u003ca href=\"https://opensource.org/licenses/MIT\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-purple.svg\" alt=\"License: MIT\"\u003e\u003c/a\u003e\n\nA Flutter library built to expose widgets that integrate with `state notifier`. Built to work with the [state_notifier](https://pub.dev/packages/state_notifier) state management packages.\n\nIt's very similar to widgets the [bloc](https://pub.dev/packages/flutter_bloc).\n\n## Motivation\n\nAlready exists a package to integrate with the status notifier, called [flutter_state_notifier](https://pub.dev/packages/flutter_state_notifier), but `flutter_lid` covers different cases.\n\n## Usage\n\n**Remember this package is destined to be used together with [state_notifier](https://pub.dev/packages/state_notifier)**\n\nLet's take a look at how to use `LidBuilder` to hook up a `CounterPage` widget to a `CounterState`.\n\nAdd it in your `pubspec.yaml`:\n\n```yaml\ndependencies:\n  flutter_lid:\n  state_notifier:\n```\n\n### `counter_lid.dart`\n\n```dart\nclass CounterState extends StateNotifier\u003cint\u003e {\n  CounterState() : super(0);\n\n  void increment() =\u003e state += 1;\n\n  void decrement() =\u003e state -= 1;\n}\n```\n\n### `main.dart`\n\n```dart\nvoid main() =\u003e runApp(const LidCounter());\n\nclass LidCounter extends StatelessWidget {\n  const LidCounter({Key key}) : super(key: key);\n\n  @override\n  Widget build(BuildContext context) {\n    return MaterialApp(\n      home: CounterPage(),\n    );\n  }\n}\n\nclass CounterPage extends StatelessWidget {\n  CounterPage({Key key}) : super(key: key);\n\n  final _counter = CounterState();\n\n  @override\n  Widget build(BuildContext context) {\n    return Scaffold(\n      appBar: AppBar(title: const Text('Lid Counter')),\n      body: LidBuilder\u003cint\u003e(\n        stateNotifier: _counter,\n        builder: (_, count) {\n          return Center(\n            child: Text(\n              '$count',\n              style: Theme.of(context).textTheme.headline1,\n            ),\n          );\n        },\n      ),\n      floatingActionButton: Column(\n        crossAxisAlignment: CrossAxisAlignment.end,\n        mainAxisAlignment: MainAxisAlignment.end,\n        children: \u003cWidget\u003e[\n          Padding(\n            padding: const EdgeInsets.symmetric(vertical: 4.0),\n            child: FloatingActionButton(\n              onPressed: _counter.increment,\n              child: const Icon(Icons.add),\n            ),\n          ),\n          Padding(\n            padding: const EdgeInsets.symmetric(vertical: 4.0),\n            child: FloatingActionButton(\n              onPressed: _counter.decrement,\n              child: const Icon(Icons.remove),\n            ),\n          ),\n        ],\n      ),\n    );\n  }\n}\n```\n\n## Lid Widgets\n\n**LidBuilder** is a Flutter widget which requires a `stateNotifier` and a `builder` function. `LidBuilder` handles building the widget in response to new states. `LidBuilder` is very similar to `StreamBuilder` but has a more simple API to reduce the amount of boilerplate code needed. The `builder` function will potentially be called many times and should be a [pure function](https://en.wikipedia.org/wiki/Pure_function) that returns a widget in response to the state.\n\nSee `LidListener` if you want to \"do\" anything in response to state changes such as navigation, showing a dialog, etc...\n\n```dart\nLidBuilder\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  builder: (context, state) {\n    // return widget here based on State Notifier's state\n  }\n)\n```\n\nFor fine-grained control over when the `builder` function is called `buildWhen` that can be provided that omitted, it will default `true` if previous\nstate`is different current`state`, otherwise is`false`.`buildWhen`takes the previous state and current state and returns a boolean. If`buildWhen`returns true,`builder`will be called with`state`and the widget will rebuild. If`buildWhen`returns false,`builder`will not be called with`state` and no rebuild will occur.\n\n`buildWhen` is only called once for each state change (**NOT** including `initialState`).\n\n```dart\nLidBuilder\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  buildWhen: (previousState, state) {\n    // return true/false to determine whether or not\n    // to rebuild the widget with state\n  },\n  builder: (context, state) {\n    // return widget here based on State Notifier's state\n  }\n)\n```\n\nThere is the possibility to animate between state changes. \n\n```dart\nLidBuilder\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  animate: true, // Setting to `true`, fadeIn animation will be performed between widget changes.\n  transitionBuilder: AnimatedSwitcher.defaultTransitionBuilder, // Here you can modify the default animation which is FadeIn.\n  duration: Duration(milliseconds: 300), // Sets the duration of the animation.  \n  builder: (context, state) {\n    // return widget here based on State Notifier's state\n  }\n)\n```\n\n\n**LidListener** is a Flutter widget which takes a `LidWidgetListener` and requires a `stateNotifier` and invokes the `listener` in response to state changes in the state notifier. It should be used for functionality that needs to occur once per state change such as navigation, showing a `SnackBar`, showing a `Dialog`, etc...\n\n`listener` is only called once for each state change (**NOT** including `initialState`) unlike `builder` in `LidBuilder` and is a `void` function.\n\n```dart\nLidListener\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  listener: (context, state) {\n    // do stuff here based on State Notifier's state\n  },\n  child: const SizedBox(),\n)\n```\n\nFor fine-grained control over when the `listener` function is called an optional `listenWhen` can be provided. `listenWhen` takes the previous state and current state and returns a boolean. If `listenWhen` returns true, `listener` will be called with `state`. If `listenWhen` returns false, `listener` will not be called with `state`.\n\n```dart\nLidListener\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  listenWhen: (previousState, state) {\n    // return true/false to determine whether or not\n    // to call listener with state\n  },\n  listener: (context, state) {\n    // do stuff here based on State Notifier's state\n  },\n  child: const SizedBox(),\n)\n```\n\n**MultiLidListener** is a Flutter widget that merges multiple `LidListener` widgets into one.\n`MultiLidListener` improves the readability and eliminates the need to nest multiple `LidListeners`.\nBy using `MultiLidListener` we can go from:\n\n```dart\nLidListener\u003cStateType\u003e(\n  stateNotifier: stateNotifierA, // provide the state notifier instance\n  listener: (context, state) {},\n  child: LidListener\u003cStateType\u003e(\n    stateNotifier: stateNotifierB, // provide the state notifier instance\n    listener: (context, state) {},\n    child: LidListener\u003cStateType\u003e(\n      stateNotifier: stateNotifierC,// provide the state notifier instance\n      listener: (context, state) {},\n      child: ChildA(),\n    ),\n  ),\n)\n```\n\nto:\n\n```dart\nMultiLidListener(\n  listeners: [\n    LidListener\u003cStateType\u003e(\n      stateNotifier: stateNotifierA, // provide the state notifier instance\n      listener: (context, state) {},\n    ),\n    LidListener\u003cStateType\u003e(\n      stateNotifier: stateNotifierB, // provide the state notifier instance\n      listener: (context, state) {},\n    ),\n    LidListener\u003cStateType\u003e(\n      stateNotifier: stateNotifierC, // provide the state notifier instance\n      listener: (context, state) {},\n    ),\n  ],\n  child: ChildA(),\n)\n```\n\n**LidConsumer** exposes a `builder` and `listener` in order react to new states. `LidConsumer` is analogous to a nested `LidListener` and `LidBuilder` but reduces the amount of boilerplate needed. `LidConsumer` should only be used when it is necessary to both rebuild UI and execute other reactions to state changes in the `state notifier`. `LidConsumer` takes a required `LidWidgetBuilder` and `LidWidgetListener` and `StateNotifier`, an optional `LidBuilderCondition`, and `LidListenerCondition`.\n\n```dart\nLidConsumer\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  listener: (context, state) {\n    // do stuff here based on State Notifier's state\n  },\n  builder: (context, state) {\n    // return widget here based on State Notifier's state\n  }\n)\n```\n\nAn optional `listenWhen` and `buildWhen` can be implemented for more granular control over when `listener` and `builder` are called. The `listenWhen` and `buildWhen` will be invoked on each `state` change. They each take the previous `state` and current `state` and must return a `bool` which determines whether or not the `builder` and/or `listener` function will be invoked. The previous `state` will be initialized to the `state` of the `state_notifier` when the `LidConsumer` is initialized. `listenWhen` and `buildWhen` are optional and if they aren't implemented, they will default to `true`.\n\nIf `buildWhen` é omitted then, it will default `true` if previous `state` is different current `state`, otherwise is `false`.\n\n```dart\nLidConsumer\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  listenWhen: (previous, current) {\n    // return true/false to determine whether or not\n    // to invoke listener with state\n  },\n  listener: (context, state) {\n    // do stuff here based on State Notifier's state\n  },\n  buildWhen: (previous, current) {\n    // return true/false to determine whether or not\n    // to rebuild the widget with state\n  },\n  builder: (context, state) {\n    // return widget here based on State Notifier's state\n  }\n)\n```\n\nThere is the possibility to animate between state changes. \n\n```dart\nLidConsumer\u003cStateType\u003e(\n  stateNotifier: stateNotifier, // provide the state notifier instance\n  animate: true, // Setting to `true`, fadeIn animation will be performed between widget changes.\n  transitionBuilder: AnimatedSwitcher.defaultTransitionBuilder, // Here you can modify the default animation which is FadeIn.\n  duration: Duration(milliseconds: 300), // Sets the duration of the animation.  \n  listener: (context, state) {\n    // do stuff here based on State Notifier's state\n  },\n  builder: (context, state) {\n    // return widget here based on State Notifier's state\n  }\n)\n```\n\n### LidSelector\n\n**LidSelector** is a Flutter widget which is analogous to `LidBuilder` but allows developers to filter updates by selecting a new value based on the current `stateNotifier`. Unnecessary builds are prevented if the selected value does not change. The selected value must be immutable in order for `LidSelector` to accurately determine whether `builder` should be called again.\n\n```dart\nLidSelector\u003cStateType, SelectedState\u003e(\n  selector: (state) {\n    // return selected state based on the provided state.\n  },\n  builder: (context, state) {\n    // return widget here based on the selected state.\n  },\n)\n```\n\nThere is the possibility to animate between state changes as `LidBuilder`.\n\n## Extensions \n\nThere are 3 extensions for -\u003e LidBuilder, LidListener and LidConsumer.\n\nIt's super simple to use:\n\n``` dart\n// Same as LidBuilder\nstateNotifier.toLidBuilder(  \n  buildWhen: (previousState, state) {},\n  builder: (context, state) {},\n);\n\n// Same as LidListener\nstateNotifier.toLidListener(  \n  listenWhen: (previousState, state) {},\n  listener: (context, state) {},\n  child: const SizedBox(),\n);\n\n// Same as LidConsumer\nstateNotifier.toLidConsumer(\n  listenWhen: (previous, current) {},\n  listener: (context, state) {},\n  buildWhen: (previous, current) {},\n  builder: (context, state) {}\n);\n\n// Same as LidSelector\nstateNotifier.toLidSelector\u003cbool\u003e(\n  selector: (state) {},\n  builder: (context, state) {},\n),\n```\n\n## Maintainers\n\n- [Kauê Martins](https://github.com/kmartins)\n\n## Support\n\nYou liked this package? then give it a star. If you want to help then:\n\n- Fork this repository\n- Send a Pull Request with new features\n- Share this package\n- Create issues if you find a Bug or want to suggest something","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkmartins%2Flid","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkmartins%2Flid","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkmartins%2Flid/lists"}