{"id":18076431,"url":"https://github.com/emanuel-braz/one_context","last_synced_at":"2025-04-05T02:07:48.321Z","repository":{"id":39870855,"uuid":"260800904","full_name":"emanuel-braz/one_context","owner":"emanuel-braz","description":"pub: https://pub.dev/packages/one_context - OneContext provides a simple way to deal with Dialogs, Overlays and Navigations with no need of BuildContext.","archived":false,"fork":false,"pushed_at":"2025-01-15T02:38:11.000Z","size":190,"stargazers_count":80,"open_issues_count":9,"forks_count":26,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-03-29T01:06:12.705Z","etag":null,"topics":["context","dart","dialogs","flutter","flutter-package","without-context"],"latest_commit_sha":null,"homepage":"","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/emanuel-braz.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":"2020-05-03T00:33:40.000Z","updated_at":"2025-01-18T12:30:30.000Z","dependencies_parsed_at":"2024-11-23T17:04:14.754Z","dependency_job_id":"769e61c5-b03b-4174-b1d4-93d20ad2104a","html_url":"https://github.com/emanuel-braz/one_context","commit_stats":null,"previous_names":[],"tags_count":11,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emanuel-braz%2Fone_context","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emanuel-braz%2Fone_context/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emanuel-braz%2Fone_context/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/emanuel-braz%2Fone_context/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/emanuel-braz","download_url":"https://codeload.github.com/emanuel-braz/one_context/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":247276163,"owners_count":20912288,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","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":["context","dart","dialogs","flutter","flutter-package","without-context"],"created_at":"2024-10-31T11:09:54.555Z","updated_at":"2025-04-05T02:07:48.300Z","avatar_url":"https://github.com/emanuel-braz.png","language":"Dart","readme":"[![Fork](https://img.shields.io/github/forks/emanuel-braz/one_context?style=social)](https://github.com/emanuel-braz/one_context/fork) \u0026nbsp; [![Star](https://img.shields.io/github/stars/emanuel-braz/one_context?style=social)](https://github.com/emanuel-braz/one_context/stargazers) \u0026nbsp; [![Watches](https://img.shields.io/github/watchers/emanuel-braz/one_context?style=social)](https://github.com/emanuel-braz/one_context/) \n\n[![Pub Version](https://img.shields.io/pub/v/one_context?color=%2302569B\u0026label=pub\u0026logo=flutter)](https://pub.dev/packages/one_context) ![PRs Welcome](https://img.shields.io/badge/PRs-welcome-brightgreen.svg)\n\n\n![logo](https://user-images.githubusercontent.com/3827308/80895558-a351aa80-8cbc-11ea-87ce-11f74c899767.png)\n\n\u003e #### **One Context to rule them all**\n\n\n## OneContext provides a simple way to deal with Dialogs, Overlays, Navigations, Theme* and MediaQuery* with no need of BuildContext.\n\n\u003e If you are Flutter developer, you don’t have to learn something new. This package use the same identificators and names from framework. It’s not a specialized* implementation, so you have the power to create and do not get blocked because of that.\n\n\u003e If you are Flutter package developer, OneContext can be very useful too!  You can create a custom dialogs package with no need BuildContext, and release a version, that do not depends of the context, to the comunity.\n\n![one_context_demo](https://user-images.githubusercontent.com/3827308/81240561-13727000-8fde-11ea-8400-64e2b2861a87.gif)\n  \n\u003e BuildContext always is needed (in some cases we need to choose carefully the specific one to make things work as expected), but, to global things, like dialogs, it can be reached by OneContext package. 🎯\n\n## 🎮  Let's start \n\n## ⚠  Important: Configure MaterialApp. e.g.\n```dart\n/// important: Use [OneContext().builder] in `MaterialApp` builder, in order to show dialogs and overlays.\n/// important: Use [OneContext().key] in `MaterialApp` navigatorKey, in order to navigate.\nreturn MaterialApp(\n    builder: OneContext().builder,\n    navigatorKey: OneContext().key,\n    ...\n);\n```\n\n#### There are 2 ways to get OneContext singleton instance, OneContext() or OnceContext.intance. e.g.\n```dart\n    OneContext().pushNamed('/detail_page');\n```\n\n```dart\n    OneContext.instance.pushNamed('/detail_page');\n```\n\n#### There are controllers to use navigation, overlays and dialogs. e.g.\n```dart\n    OneContext().navigator.pushNamed(...);\n    OneContext().dialog.showDialog(...);\n    OneContext().overlay.addOverlay(...);\n```\n\n#### Or, you can use the shortcuts ;)\n```dart\n    OneContext().pushNamed(...);\n    OneContext().showDialog(...);\n    OneContext().addOverlay(...);\n    \n    // and can access info from:\n    // OneContext().mediaQuery ...\n    // OneContext().textTheme ...\n    // OneContext().theme ...\n```\n\n#### OneContext is:\n* Fast (O(1))\n* Easy to learn/use\n* It use same native function names from Flutter, to keep it simple and intuitive ;)\n\n## 💬  How to show Dialogs with no need of the BuildContext? \n\n```dart\n// example snackBar\nOneContext().showSnackBar(\n    builder: (_) =\u003e SnackBar(content: Text('My awesome snackBar!'))\n);\n```\n\n```dart\n// example dialog\nOneContext().showDialog(\n    // barrierDismissible: false,\n    builder: (_) =\u003e AlertDialog( \n        title: new Text(\"The Title\"),\n        content: new Text(\"The Body\"),\n    )\n);\n```\n\n```dart\n// example bottomSheet\nOneContext().showBottomSheet(\n    builder: (context) =\u003e Container(\n    alignment: Alignment.topCenter,\n    height: 200,\n    child: IconButton(\n        icon: Icon(Icons.arrow_drop_down),\n        iconSize: 50,\n        color: Colors.white,\n        onPressed: () =\u003e Navigator.of(context).pop('sucess')), // or OneContext().popDialog('sucess');\n    ),\n);\n```\n\n```dart\n// example modalBottomSheet\nOneContext().showModalBottomSheet\u003cString\u003e(\n    builder: (context) =\u003e Container(\n        child: Column(\n            mainAxisSize: MainAxisSize.min,\n            children: \u003cWidget\u003e[\n            ListTile(\n                leading: Icon(Icons.music_note),\n                title: Text('Music'),\n                onTap: () =\u003e OneContext().popDialog('Music'); //Navigator.of(context).pop('Music')),\n            ListTile(\n                leading: Icon(Icons.videocam),\n                title: Text('Video'),\n                onTap: () =\u003e Navigator.of(context).pop('Video'),\n            ),\n            SizedBox(height: 45)\n            ],\n        ),\n    )\n);\n```\n\n\n\n## ⛵  How to navigate? (All methods from Navigator Class are available)\n```dart\n// go to second page using named route\nOneContext().pushNamed('/second');\n```\n\n```dart\n// go to second page using MaterialPageRoute\nOneContext().push(MaterialPageRoute(builder: (_) =\u003e SecondPage()));\n```\n\n```dart\n// go back from second page\nOneContext().pop();\n```\n\n```dart\n// Pop dialogs\nOneContext().popDialog();\n```\n\n```dart\n// Retrieve data from route when it's pops\nString result = await OneContext().push\u003cString\u003e(MaterialPageRoute(builder: (_) =\u003e SecondPage()));\nprint(result);\n```\n\n\n## 🍰  How to show Overlays? \n\n```dart\n// show the default progress indicator\nOneContext().showProgressIndicator();\n```\n\n```dart\n// hide the default progress indicator\nOneContext().hideProgressIndicator();\n```\n\n```dart\n// show the default progress indicator with some colors\nOneContext().showProgressIndicator(\n    backgroundColor: Colors.blue.withOpacity(.3),\n    circularProgressIndicatorColor: Colors.white\n);\n\n// Later\nOneContext().hideProgressIndicator();\n```\n\n```dart\n// Show a custom progress indicator\nOneContext().showProgressIndicator(\n    builder: (_) =\u003e MyAwesomeProgressIndicator();\n);\n\n// Later\nOneContext().hideProgressIndicator();\n```\n\n```dart\n// Show a custom widget in overlay stack\n\nString myCustomAndAwesomeOverlayId = UniqueKey().toString();\n\nOneContext().addOverlay(\n    overlayId: myCustomAndAwesomeOverlayId,\n    builder: (_) =\u003e MyCustomAndAwesomeOverlay()\n);\n\n// Later\nOneContext().removeOverlay(myCustomAndAwesomeOverlayId);\n```\n\n## 🎨 Changing Dark and Light theme mode\n#### Breaking change: OneHotReload becomes OneNotification\n#### ⚠ Please check consideration on Theme and MediaQuery topic\n```dart\nOneNotification\u003cOneThemeChangerEvent\u003e(\n  stopBubbling: true, // avoid bubbling to ancestors\n  builder: (_, __) {\n    return MaterialApp(\n      builder: OneContext().builder,\n      themeMode: OneThemeController.initThemeMode(ThemeMode.light),\n      theme: OneThemeController.initThemeData(ThemeData(brightness: Brightness.light)),\n      darkTheme: OneThemeController.initDarkThemeData(ThemeData(brightness: Brightness.dark)),\n      ...\n    );\n);\n\n// Later...\nOneContext().oneTheme.toggleMode();\n\n// Or change only the dark theme\nOneContext().oneTheme.changeDarkThemeData(\n  ThemeData(\n    primarySwatch: Colors.amber,\n    brightness: Brightness.dark\n )\n);\n```\n\n## 🚧 Reload, Restart and Reboot the app (Need bubbling events or data?)\n#### First define the data type in type generics, after that, you can rebuild multiple ancestors widgets that listen the same data type. This is used for the package in this example, to change ThemeMode and Locale and even Restart the app entirely.\n\n```dart\nOneNotification\u003cList\u003cLocale\u003e\u003e(\n      onVisited: (context, localeList) {\n        print('widget visited!');\n      },\n      stopBubbling: true, // avoid the data bubbling to ancestors widgets\n      initialData: _localeEnglish, // [data] is null during boot of the application, but you can set initialData\n      rebuildOnNull: true, // Allow other entities reload this widget without messing up currenty data (Data is cached on first event)\n      builder: (context, localeList) {\n        return MaterialApp(\n          supportedLocales: localeList,\n        );\n      },\n    );\n```\n\n#### Need to dispatch more specialized data/event?\n```dart\n\n// My Specialized Event\nclass MySpecializedEvent {\n  final String text;\n  MySpecializedEvent(this.text);\n}\n\n// Widget\nOneNotification\u003cMySpecializedEvent\u003e(\n  builder: (context, event) {\n    return Text(event.text);\n  },\n)\n\n// Later, in children, call `OneNotifier.notify` to get ancestors notified\nOneNotifier.notify(\n  context,\n  NotificationPayload(\n    data: MySpecializedEvent('Nice!');\n  )\n);\n```\n\n#### Reload and Restart the app\n```dart\n// Place that widget on most top\nOneNotification(\n  builder: (_, __) =\u003e child\n);\n\n// Later... in children\n\n// Dont lose state\nOneNotification.softReloadRoot(context);\n\n// Lose state\nOneNotification.hardReloadRoot(context);\n```\n\n#### Reboot and load different apps\n```dart\n// Set the main() function\nvoid main() =\u003e OnePlatform.app = () =\u003e MyApp();\n\n// Later... Call reboot without recreating root app\nOnePlatform.reboot();\n\n// Later... Call reboot recreating the entire application\nOnePlatform.reboot(\n  builder: () =\u003e MyApp()\n);\n\n// You even can load an entire different app\nOnePlatform.reboot(\n  builder: () =\u003e MyApp2()\n);\n```\n\n## ⚙ Theme and MediaQuery\n```dart\nprint('Platform: ' + OneContext().theme.platform); // TargetPlatform.iOS\nprint('Orientation: ' + OneContext().mediaQuery.orientation); // Orientation.portrait\n```\n[IMPORTANT] If you need get widget rebuild on theme data changes using `OneContext().oneTheme.toggleMode();`, please consider to use the traditional way `Theme.of(context)` when getting theme data inside widget.\n\n```dart\n@override\n  Widget build(BuildContext context) {\n\n    return Container(\n      color: Theme.of(context).primaryColor, // Theme.of(context)\n      height: 100,\n      width: 100,\n    );\n  }\n\n```\n#### Or you can call `Theme.of(context);` in the begining of `build` method instead;\ne.g.\n```dart\n@override\n  Widget build(BuildContext context) {\n    \n    // Get changes by you currently context, and ensure the rebuild on theme data changes on\n    // OneContext().oneTheme.toggleMode(), OneContext().oneTheme.changeDarkThemeData() or OneContext().oneTheme.changeThemeData() events.\n    Theme.of(context);\n\n    return Container(\n      color: OneContext().theme.primaryColor, // OneContext().theme\n      height: 100,\n      width: 100,\n    );\n  }\n\n```\n\n### In initState or inside class constructor (now it's possible)\n```dart\n@override\n  void initState() {\n    super.initState();\n\n    OneContext().showDialog(\n        builder: (_) =\u003e AlertDialog(\n          title: new Text(\"On Page Load\"),\n          content: new Text(\"Hello World!\"),\n        ),\n      );\n```\n\n\n## 🚦  Warnings\n\\* OneContext().theme and OneContext().mediaQuery are global instances of the root of the widget tree. Use it with care! It can reproduce unexpected behavior if you don't understand it.\n\n\\* OneContext().context is like a root context, so, it should not be used directly, as it can reproduce unexpected behaviors, unless you have a understanding how it works. It shouldn't work well with InheritedWidget for example.\n\n\\* This package only uses specialized implementation in Overlays, to make things easy and ensure a quick start.\n\n\n## 👨‍💻👨‍💻  Contributing\n\n#### Contributions of any kind are welcome! I'll be glad to analyse and accept them! 👾\n### Sponsor\n\u003ca href=\"https://www.buymeacoffee.com/emanuelbraz\" target=\"_blank\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-blue.png\" alt=\"Buy Me A Coffee\" style=\"height: 50px !important;width: 217px !important;\" \u003e\u003c/a\u003e\n\n","funding_links":["https://www.buymeacoffee.com/emanuelbraz"],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femanuel-braz%2Fone_context","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Femanuel-braz%2Fone_context","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Femanuel-braz%2Fone_context/lists"}