{"id":15047003,"url":"https://github.com/legytma/schema_widget","last_synced_at":"2026-03-11T23:02:43.053Z","repository":{"id":42731127,"uuid":"236007623","full_name":"Legytma/schema_widget","owner":"Legytma","description":"The schema_widget flutter package is a widget generator based on JSON parsers capable of producing complex screens and using custom business rules.","archived":false,"fork":false,"pushed_at":"2022-03-27T07:34:07.000Z","size":6723,"stargazers_count":5,"open_issues_count":10,"forks_count":0,"subscribers_count":2,"default_branch":"master","last_synced_at":"2025-02-02T04:51:19.291Z","etag":null,"topics":["dynamic-widget","flutter-package","json-parser","json-schema"],"latest_commit_sha":null,"homepage":"https://schema.legytma.com.br","language":"Dart","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Legytma.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null},"funding":{"github":null,"patreon":null,"open_collective":"legytma1","ko_fi":null,"tidelift":null,"community_bridge":null,"liberapay":null,"issuehunt":null,"otechie":null,"custom":["https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=C2RD44ZSJRRWC\u0026item_name=Legytma\u0026currency_code=USD\u0026source=url"]}},"created_at":"2020-01-24T13:27:54.000Z","updated_at":"2023-05-22T16:47:58.000Z","dependencies_parsed_at":"2022-09-12T11:13:30.258Z","dependency_job_id":null,"html_url":"https://github.com/Legytma/schema_widget","commit_stats":null,"previous_names":[],"tags_count":10,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Legytma%2Fschema_widget","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Legytma%2Fschema_widget/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Legytma%2Fschema_widget/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Legytma%2Fschema_widget/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Legytma","download_url":"https://codeload.github.com/Legytma/schema_widget/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":238892315,"owners_count":19548169,"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":["dynamic-widget","flutter-package","json-parser","json-schema"],"created_at":"2024-09-24T20:53:51.728Z","updated_at":"2025-10-29T21:30:41.794Z","avatar_url":"https://github.com/Legytma.png","language":"Dart","funding_links":["https://opencollective.com/legytma1","https://www.paypal.com/cgi-bin/webscr?cmd=_donations\u0026business=C2RD44ZSJRRWC\u0026item_name=Legytma\u0026currency_code=USD\u0026source=url"],"categories":[],"sub_categories":[],"readme":"[![GitHub issues](https://img.shields.io/github/issues/Legytma/schema_widget)](https://github.com/Legytma/schema_widget/issues \"GitHub issues\")\r\n[![GitHub forks](https://img.shields.io/github/forks/Legytma/schema_widget)](https://github.com/Legytma/schema_widget/network \"GitHub forks\")\r\n[![GitHub stars](https://img.shields.io/github/stars/Legytma/schema_widget)](https://github.com/Legytma/schema_widget/stargazers \"GitHub stars\")\r\n[![GitHub license](https://img.shields.io/github/license/Legytma/schema_widget)](https://github.com/Legytma/schema_widget/blob/master/LICENSE \"GitHub license\")\r\n[![Pub](https://img.shields.io/pub/v/schema_widget)](https://pub.dev/packages/schema_widget \"Pub\")\r\n[![Likes](https://badges.bar/schema_widget/likes)](https://pub.dev/packages/schema_widget/score \"Likes\")\r\n[![Pub Points](https://badges.bar/schema_widget/pub%20points)](https://pub.dev/packages/schema_widget/score \"Pub Points\")\r\n[![Popularity](https://badges.bar/schema_widget/popularity)](https://pub.dev/packages/schema_widget/score \"Popularity\")\r\n[![style: effective dart](https://img.shields.io/badge/style-effective_dart-40c4ff.svg)](https://github.com/tenhobi/effective_dart \"style: effective dart\")\r\n![GitHub tag (latest SemVer)](https://img.shields.io/github/v/tag/Legytma/schema_widget \"GitHub tag (latest SemVer)\")\r\n![GitHub top language](https://img.shields.io/github/languages/top/Legytma/schema_widget \"GitHub top language\")\r\n![GitHub contributors](https://img.shields.io/github/contributors/Legytma/schema_widget \"GitHub contributors\")\r\n![GitHub last commit](https://img.shields.io/github/last-commit/Legytma/schema_widget \"GitHub last commit\")\r\n![Flutter CI](https://github.com/Legytma/schema_widget/workflows/Flutter%20CI/badge.svg \"Flutter CI\")\r\n\r\n# Convert JSON to Widget validating with JSON Schema for Flutter apps\r\n\r\n- [What is it](#what-is-it \"What is it\")\r\n  - [Author](#author \"Author\")\r\n  - [Motivation](#motivation \"Motivation\")\r\n  - [How this work](#how-this-work \"How this work\")\r\n    - [`TypeSchemaParser`](#typeschemaparser \"TypeSchemaParser\")\r\n- [TYPE SCHEMA PARSER SUPPORT](TYPE_SCHEMA_PARSER_SUPPORT.md \"TYPE SCHEMA PARSER SUPPORT\")\r\n- [Getting Started](#getting-started \"Getting Started\")\r\n  - [Installation](#installation \"Installation\")\r\n  - [Usage](#usage \"Usage\")\r\n- [CHANGELOG](CHANGELOG.md \"CHANGELOG\")\r\n- [Next steps](#next-steps \"Next steps\")\r\n- [LICENSE](LICENSE \"LICENSE\")\r\n\r\n## What is it\r\n\r\nThe [schema_widget](https://pub.dev/packages/schema_widget \"schema_widget\") is a Flutter package implemented with base on [dynamic_widget](https://pub.dev/packages/dynamic_widget \"dynamic_widget\") package that produces widgets dynamically interpreting JSON objects.\r\n\r\n### Author\r\n\r\nWrited by [Alex Manoel Ferreira Silva ![Support - Recommend/Endorse me on LinkedIn](https://img.shields.io/badge/Support-Recommed%2FEndorse%20me%20on%20Linkedin-blue?style=for-the-badge\u0026logo=linkedin)](https://www.linkedin.com/in/windol/ \"Support - Recommend/Endorse me on LinkedIn\")\r\n\r\nUnder\r\n[![Legytma Soluções Inteligentes](https://legytma.com.br/wp-content/uploads/2019/12/Legytma-Soluções-Inteligentes-e1599223582681.png) ![Company - Legytma Soluções Inteligentes in LinkedIn](https://img.shields.io/badge/Company-Legytma%20Solu%C3%A7%C3%B5es%20Inteligentes%20in%20LinkedIn-blue?style=for-the-badge\u0026logo=linkedin)](https://www.linkedin.com/company/legytma \"Company - Legytma Soluções Inteligentes in LinkedIn\")\r\n\r\n### Motivation\r\n\r\nA major difficulty for any application developer is to ensure that all users keep their applications up to date to ensure the same user experience and to reduce the time required to fix bugs.\r\n\r\nThe most commonly used alternative to accelerate this process is [Code Push](https://github.com/Microsoft/code-push) which allows the application update without the need for a new deploy in the store. However in Code Push GitHub itself there is a [Code Push Support for Flutter](https://github.com/Microsoft/code-push/issues/624#issuecomment-532358395) request with comment saying that support depends on implementing dynamic update support in Flutter, there is also a reference to [Flutter Roadmap](https://github.com/flutter/flutter/wiki/Roadmap#changes) saying that support for This type of update is postponed according to the official comment [Code Push / Hot Update / out of band updates](https://github.com/flutter/flutter/issues/14330#issuecomment-485565194), which explains the reasons that led to the decision.\r\n\r\nOne possible solution to this deadlock is to implement a JSON interpreter that enables screen redesign, which can be obtained using [dynamic_widget](https://pub.dev/packages/dynamic_widget \"dynamic_widget\"). Although [dynamic_widget](https://pub.dev/packages/dynamic_widget \"dynamic_widget\") provides an easy way to extend support for other widgets through separate implementations. It limits the use of events and does not allow the use of complex business rules.\r\n\r\n### How this work\r\n\r\nThe basic operation of [schema_widget](https://pub.dev/packages/schema_widget \"schema_widget\") is very similar to that of [dynamic_widget](https://pub.dev/packages/dynamic_widget \"dynamic_widget\"). Both interpret JSON and instantiate the widget for it.\r\nThe main difference with [schema_widget](https://pub.dev/packages/schema_widget \"schema_widget\") is that it allows the creation of parsers for any type of object and the use of pre-implemented rules. For this reason, it makes it possible to create much more complex business rules.\r\n\r\nThe [schema_widget](https://pub.dev/packages/schema_widget \"schema_widget\") package provides the `SchemaWidget` class, in most cases this will be the only class used. All methods in this class are static.\r\n\r\nTo add a new parser, the following methods can be used:\r\n\r\nDefault parsers: This method loads all the default parsers from [schema_widget](https://pub.dev/packages/schema_widget \"schema_widget\").\r\n\r\n```dart\r\n  SchemaWidget.registerParsers();\r\n```\r\n\r\nSynchronous: This method can be used to load a custom parser that can be loaded synchronously.\r\n\r\n```dart\r\n  TypeSchemaParser typeSchemaParserInstance = CustomTypeSchemaParser();\r\n\r\n  SchemaWidget.registerTypeParser(typeSchemaParserInstance);\r\n```\r\n\r\nAsynchronous: This method can be used to load a custom parser that needs to be loaded asynchronously.\r\n\r\n```dart\r\n  String typeName = \"Custom\";\r\n  Future\u003cTypeSchemaParser\u003e futureTypeSchemaParserInstance = () async =\u003e CustomTypeSchemaParser();\r\n\r\n  SchemaWidget.registerTypeParserAsync(typeName, futureTypeSchemaParserInstance);\r\n```\r\n\r\nIn addition to parsers, any type of function and object for use by parsers can also be registered. For this, the `SchemaWidget.registerLogic(logicName, logic)` method must be used. The logic name must be unique, otherwise the previously registered logic will be replaced.\r\n\r\nExample:\r\n\r\n```dart\r\n  const string1 = \"Hello World\";\r\n  const map1 = {\"foo\": \"bar\"};\r\n  const object1 = Foo();\r\n  var func1 = () =\u003e \"Hello World\";\r\n  var asyncFunc1 = () async =\u003e \"Hello World\";\r\n  var object2 = Bar();\r\n\r\n  SchemaWidget.registerLogic(\"string1\", string1);\r\n  SchemaWidget.registerLogic(\"map1\", map1);\r\n  SchemaWidget.registerLogic(\"object1\", object1);\r\n  SchemaWidget.registerLogic(\"func1\", func1);\r\n  SchemaWidget.registerLogic(\"asyncFunc1\", asyncFunc1);\r\n  SchemaWidget.registerLogic(\"otherExemple\", object2);\r\n```\r\n\r\nBoth parsers and logics are registered using the [get_it](https://pub.dev/packages/get_it \"get_it\") package to manage everything.\r\nAfter registering all the parsers and logic necessary for use. It may be necessary to wait for `GetIt` to finish loading asynchronous parsers. For this, `GetIt` makes `GetIt.I.allReady()` available for use in a `FutureBuilder` for the purpose of creating widgets only after all parsers are loaded as shown in the following example.\r\n\r\n```dart\r\nclass MyApp extends StatelessWidget {\r\n  MyApp({Key key}) : super(key: key) {\r\n    SchemaWidget.registerParsers();\r\n    SchemaWidget.registerLogic(\"funcHelloWorld\", () =\u003e Text(\"Hello World\"));\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return FutureBuilder(\r\n      future: GetIt.I.allReady(ignorePendingAsyncCreation: false),\r\n      builder: (BuildContext context, AsyncSnapshot snapshot) {\r\n        if (!snapshot.hasData) {\r\n          return CircularProgressIndicator();\r\n        }\r\n\r\n        return SchemaWidget.parse\u003cWidget\u003e(\r\n          context,\r\n          {\r\n            \"type\": \"Scaffold\",\r\n            \"appBar\": {\r\n              \"type\": \"AppBar\",\r\n              \"title\": {\r\n                \"type\": \"Text\",\r\n                \"data\": \"Hello World Example\",\r\n              },\r\n            },\r\n            \"body\": {\r\n              \"type\": \"Center\",\r\n              \"child\": \"funcHelloWorld\",\r\n            },\r\n          },\r\n        );\r\n      },\r\n    );\r\n  }\r\n}\r\n```\r\n\r\nAlternatively, `SchemaWidget` itself can be used to execute `SchemaWidget.registerParsers()` and `SchemaWidget.parse\u003cWidget\u003e()`, reducing the complexity of the code.\r\n\r\n```dart\r\nclass MyApp extends StatelessWidget {\r\n  MyApp({Key key}) : super(key: key) {\r\n    SchemaWidget.registerLogic(\"funcHelloWorld\", () =\u003e Text(\"Hello World\"));\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return SchemaWidget(\r\n      {\r\n        \"type\": \"Scaffold\",\r\n        \"appBar\": {\r\n          \"type\": \"AppBar\",\r\n          \"title\": {\r\n            \"type\": \"Text\",\r\n            \"data\": \"Hello World Example\",\r\n          },\r\n        },\r\n        \"body\": {\r\n          \"type\": \"Center\",\r\n          \"child\": \"funcHelloWorld\",\r\n        },\r\n      },\r\n    );\r\n  }\r\n}\r\n```\r\n\r\n#### `TypeSchemaParser`\r\n\r\nEverything in [schema_widget](https://pub.dev/packages/schema_widget \"schema_widget\") is based on `TypeSchemaParser`.\r\n\r\n`TypeSchemaParser` is the implementation of a JSON interpreter that converts it into a complex object.\r\n\r\n## Getting Started\r\n\r\n- For help over SchemaWidget usage, view the [example](https://github.com/Legytma/schema_form/tree/master/example);\r\n- For help over class documentation, view the [documentation](https://pub.dev/documentation/schema_widget/latest);\r\n- For help getting started with Flutter, view our online [documentation](https://flutter.io/);\r\n- For help on editing package code, view the [documentation](https://flutter.io/developing-packages/).\r\n\r\n### Installation\r\n\r\n- Add this to your package's pubspec.yaml file:\r\n\r\n```yaml\r\ndependencies:\r\n  get_it:\r\n  schema_widget: ^2.0.0-beta.0\r\n```\r\n\r\n- Install packages from the command line:\r\n  with Flutter:\r\n\r\n```shell script\r\n$ flutter packages get\r\n```\r\n\r\n- Import it into the code file:\r\n\r\n```dart\r\n import 'package:schema_widget/schema_widget.dart';\r\n```\r\n\r\n### Usage\r\n\r\n```dart\r\nimport 'dart:async';\r\n\r\nimport 'package:flutter/material.dart';\r\nimport 'package:schema_widget/schema_widget.dart';\r\n\r\nvoid main() {\r\n  runApp(MyApp());\r\n}\r\n\r\nclass MyApp extends StatelessWidget {\r\n  final GlobalKey\u003cNavigatorState\u003e _navigatorKey = GlobalKey\u003cNavigatorState\u003e();\r\n\r\n  MyApp({Key key}) : super(key: key) {\r\n    SchemaWidget.registerLogic(\r\n      \"onGenerateRoute\",\r\n      _onGenerateRoute,\r\n    );\r\n    SchemaWidget.registerLogic(\r\n      \"onUnknownRoute\",\r\n      _onUnknownRoute,\r\n    );\r\n    SchemaWidget.registerLogic(\r\n      \"navigatorKey\",\r\n      _navigatorKey,\r\n    );\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return SchemaWidget(\r\n      loadSchemas: false,\r\n      {\r\n        \"type\": \"MaterialApp\",\r\n        \"title\": 'SchemaWidget Demo',\r\n        \"theme\": {\r\n          \"primarySwatch\": {\r\n            \"primary\": 0xFF2196F3,\r\n            \"swatch\": {\r\n              \"50\": 0xFFE3F2FD,\r\n              \"100\": 0xFFBBDEFB,\r\n              \"200\": 0xFF90CAF9,\r\n              \"300\": 0xFF64B5F6,\r\n              \"400\": 0xFF42A5F5,\r\n              \"500\": 0xFF2196F3,\r\n              \"600\": 0xFF1E88E5,\r\n              \"700\": 0xFF1976D2,\r\n              \"800\": 0xFF1565C0,\r\n              \"900\": 0xFF0D47A1,\r\n            },\r\n          },\r\n        },\r\n        \"navigatorKey\": \"navigatorKey\",\r\n        \"initialRoute\": \"home\",\r\n        \"onGenerateRoute\": \"onGenerateRoute\",\r\n        \"onUnknownRoute\": \"onUnknownRoute\"\r\n      },\r\n    );\r\n  }\r\n\r\n  Route _onGenerateRoute(RouteSettings settings) {\r\n    return MaterialPageRoute(\r\n      builder: (buildContext) =\u003e MyHomePage(),\r\n      settings: settings,\r\n    );\r\n  }\r\n\r\n  Route _onUnknownRoute(RouteSettings settings) {\r\n    return MaterialPageRoute(\r\n      builder: (buildContext) =\u003e MyHomePage(),\r\n      settings: settings.copyWith(name: \"home\"),\r\n    );\r\n  }\r\n}\r\n\r\nclass MyHomePage extends StatelessWidget {\r\n  MyHomePage({Key key}) : super(key: key) {\r\n    SchemaWidget.registerLogic(\"funcHelloWorld\", () =\u003e Text(\"Hello World\"));\r\n  }\r\n\r\n  @override\r\n  Widget build(BuildContext context) {\r\n    return SchemaWidget(\r\n      {\r\n        \"type\": \"Scaffold\",\r\n        \"appBar\": {\r\n          \"type\": \"AppBar\",\r\n          \"title\": {\r\n            \"type\": \"Text\",\r\n            \"data\": \"Hello World Example\",\r\n          },\r\n        },\r\n        \"body\": {\r\n          \"type\": \"Center\",\r\n          \"child\": \"funcHelloWorld\",\r\n        },\r\n      },\r\n    );\r\n  }\r\n}\r\n```\r\n\r\n## Next steps\r\n\r\n- [x] Publish Package;\r\n- [x] Make MVP;\r\n- [x] Minimal documentation;\r\n- [x] Change event binding of click event;\r\n- [x] Add list of default supported Widgets;\r\n- [x] Add list of default supported Types;\r\n- [ ] Create content about;\r\n- [ ] Publish complementar packages;\r\n- [ ] Create example full functional apps;\r\n- [ ] Make a commercial product using the package;\r\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flegytma%2Fschema_widget","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Flegytma%2Fschema_widget","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Flegytma%2Fschema_widget/lists"}