Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: Added Form widget with form-validation support in Mirai #110

Merged
merged 27 commits into from
Aug 5, 2023

Conversation

i-asimkhan
Copy link
Contributor

Description

Added Form widget with form-validation support in Mirai

Related Issues

Closes #107

Type of Change

  • New feature (non-breaking change which adds functionality)
  • Bug fix (non-breaking change which fixes an issue)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Code refactor
  • Build configuration change
  • Documentation
  • Chore

@i-asimkhan i-asimkhan self-assigned this Apr 11, 2023
@i-asimkhan i-asimkhan added this to the v0.2.0 milestone Apr 11, 2023
* main:
  Update mirai_banner.png
  Update mirai_banner.png
  update README.md
  feat: allow inject a dio instance
@divyanshub024 divyanshub024 changed the title Added Form widget with form-validation support in Mirai feat: Added Form widget with form-validation support in Mirai Apr 13, 2023
* main:
  - 🔨 #89 removed redundant exports
  - 🔨 #89 Rearranged imports
  - 🔨 #89 minor fixes
  - 🔨 #89 review fixes
  - 🔨 #89 Fixes done for the issue
  refactor: Input validation types are renamed, and static regex expressions are moved inside the enum
  - 📝 #89 Minor fixes
  - 🚀 #89 Added box decoration parser for container
  refactor: Input formatter types are reduced to basic types (deny-allow) and updated example jsons
  fix: Renamed input validator type, text-field widget changed to stateless and validation messages in example are updated
  Added input formatters structure in Mirai to support input formatters in text fields.
  Added text form field ability to validate using regex rules and predefined types.
  Added validators for mirai text field

# Conflicts:
#	packages/mirai/lib/src/parsers/mirai_text_form_field/mirai_text_form_field.freezed.dart
#	packages/mirai/lib/src/parsers/mirai_text_form_field/mirai_text_form_field_parser.dart
#	packages/mirai/lib/src/parsers/parsers.dart
* main:
  #113 - 📝 Minor fixes - 🚧 [WIP] Add support for fromRelativeRect
  #113 - 📝 Added review changes - 🚧 [WIP] Add support for fromRelativeRect
  #113 - 🔨 implemented fromRect method for positioned widget - 🚧 [WIP] Add support for fromRelativeRect
  #113 - 🔨 Added example for stack and implemented positioned widget for stack - 🚧 [WIP] Add support for fromRect and fromRelativeRect
  - 📝 #113 Merge fixes
  - 🚀 #113 Added mirai stack parser
@divyanshub024 divyanshub024 modified the milestones: v0.2.0, v0.3.0 May 1, 2023
* main:
  V 0.2 release

# Conflicts:
#	packages/mirai/pubspec.yaml
Copy link
Contributor

@RodolfoSilva RodolfoSilva left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've also create a issue about a way to disable buttons and text fields when the form is in submiting mode.
#119

@i-asimkhan
Copy link
Contributor Author

I've also create a issue about a way to disable buttons and text fields when the form is in submiting mode. #119

@RodolfoSilva Thanks for reviewing this. Your comment regarding key #110 (comment) makes a lot of sense and further, I can discuss this with @divyanshub024 but I am more interested in your bullet regarding button-disabling. It would be great if you elaborate more on this. 👍 👍

@i-asimkhan i-asimkhan linked an issue May 9, 2023 that may be closed by this pull request
4 tasks
* main:
  Create CODE_OF_CONDUCT.md
  fix: Removed align in home screen json
@RodolfoSilva
Copy link
Contributor

RodolfoSilva commented May 26, 2023

Sure, I think we can add support for signals, and add the ability to widgets or actions react for signals. Imagine you have a widget thats emit a signal like, submitting and you have a widgets that subscribes when a signal occurs and apply some changes.

For example:

This widget emits a signal when the button is pressed:

{
  "type": "elevatedButton",
  "child": {
    "type": "text",
    "data": "Submit"
  }, 
  "onPressed": {
    "actionType": "signal",
    "name": "Mirai/submitting",
    "data": {},
    "then": {
      // run another action after the signal is emitted
    }
  },
  // ... other properties
}

Then you have a widget that subscribes to this signal and apply some changes to the widget:

{
  "type": "textFormField",
  "maxLines": 1,
  "obscureText": false,
  "onSignals": [
    {
      "name": "Mirai/submitting",
      "patch": {
        "readOnly": true,
        "enabled": false
      }
    }
  ],
  "readOnly": false,
  "enabled": true,
  // ... other properties
},

This will patch the properties to the widget when the signal is emitted, allowing you to create dynamic widgets that reacts to signals. Making the UI more dynamic and reactive.

The signal name, could be anithing defined by the user.

Sorry for the delay @i-asimkhan , I was on vacation.

@i-asimkhan
Copy link
Contributor Author

Sure, I think we can add support for signals, and add the ability to widgets or actions react for signals. Imagine you have a widget thats emit a signal like, submitting and you have a widgets that subscribes when a signal occurs and apply some changes.

For example:

This widget emits a signal when the button is pressed:

{
  "type": "elevatedButton",
  "child": {
    "type": "text",
    "data": "Submit"
  }, 
  "onPressed": {
    "actionType": "signal",
    "name": "Mirai/submitting",
    "data": {},
    "then": {
      // run another action after the signal is emitted
    }
  },
  // ... other properties
}

Then you have a widget that subscribes to this signal and apply some changes to the widget:

{
  "type": "textFormField",
  "maxLines": 1,
  "obscureText": false,
  "onSignals": [
    {
      "name": "Mirai/submitting",
      "patch": {
        "readOnly": true,
        "enabled": false
      }
    }
  ],
  "readOnly": false,
  "enabled": true,
  // ... other properties
},

This will patch the properties to the widget when the signal is emitted, allowing you to create dynamic widgets that reacts to signals. Making the UI more dynamic and reactive.

The signal name, could be anithing defined by the user.

Sorry for the delay @i-asimkhan , I was on vacation.

That's a great illustration. Thank you 👍

@i-asimkhan i-asimkhan removed this from the v0.3.0 milestone Jun 5, 2023
* main: (29 commits)
  Added `MiraiBottomAppBarTheme` in `MiraiThemeData`
  Secondary color for light and dark themes are changed for mirai_gallery
  Added `MiraiTabBarThemeData` in `MiraiTheme` data
  Added `MiraiNavigationBarThemeData` in `MiraiThemeData`
  Secondary color changed and default values are removed in light/dark theme
  Added `MiraiListTileThemeData` to the mirai theme data
  Renamed `MiraiFloatingActionThemeData` to `MiraiFloatingActionButtonThemeData` and removed example theme comp from light theme
  Added `iconColor` and `disabledIconColor` in mirai button style
  Removed TextButtonThemeData wrapper on button
  Removed app-bar theme from light-theme example and icon theme irrelevant values causing color disruption
  Fixed file naming misspelled word for `overlay` in mirai sustem ui overly
  Added iconTheme and actionIconTheme values in MIrai app-bar theme data
  Fix code formatting
  Formatted code files in parsers/
  Added `DialogTheme` in Mirai Theme data
  Added `CardTheme` in Mirai theme data
  Updated theme example with bottom-sheet theme details
  Added BottomSheet theme parser and provided in Mirai Theme
  Updated example theme for bottom-nav-bar and formatted parsers in the framework
  Added bottom-nav-bar theme data in Mirai theme
  ...

# Conflicts:
#	packages/mirai/lib/src/parsers/parsers.dart
#	packages/mirai/pubspec.yaml
* main:
  Mirai v0.3 release
  Update mirai dependencies
  Updated colors in example/mirai_gallery from the material3 example app inside flutter/samples
  feat: Added dark colors for theme in example_light_theme
  Implemented light mode material-3 colors scheme

# Conflicts:
#	packages/mirai/pubspec.yaml
@i-asimkhan i-asimkhan added this to the v0.4 milestone Jun 8, 2023
@divyanshub024 divyanshub024 modified the milestones: v0.4, v0.5 Jun 14, 2023
* main:
  Removed `"style": "list"` from all list items in home-screen json
  Refactored navigate method in`Mirai Navigatior` for all navigation styles and renamed pushNamedAndRemoveUntil to pushNamedAndRemoveAll
  Removed widget null check as it will break when navigation is of type `pop`
  Removed duplicate `pop` in case of navigate back and renamed navigation items in example
  Added result and arguments in `miraiAction` for navigate usecase
  Added support for `pushNamed` in Mirai Navigation
  Extending rich text functionality to Mirai Text.
@i-asimkhan
Copy link
Contributor Author

Hey @RodolfoSilva
What are your suggestions about the MiraiFrom @freezed model class, would it better to follow flutter widget convention, like this

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    MiraiAction? onChanged,
    AutovalidateMode? autovalidateMode,
    required Map<String, dynamic> child,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

or we should make strict rules here by defining a list of child widgets (mainly form-inputs),

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    required List<Map<String, dynamic>> children,
    required MiraiSubmitAction action,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

@i-asimkhan
Copy link
Contributor Author

i-asimkhan commented Jul 11, 2023

Hey @RodolfoSilva What are your suggestions about the MiraiFrom @freezed model class, would it better to follow flutter widget convention, like this

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    MiraiAction? onChanged,
    AutovalidateMode? autovalidateMode,
    required Map<String, dynamic> child,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

or we should make strict rules here by defining a list of child widgets (mainly form-inputs),

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    required List<Map<String, dynamic>> children,
    required MiraiSubmitAction action,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

Secondly, we need to partition the business logic from the MiraiAction as it is becoming more and more detailed.
One of the thoughts I have is to make a generic type of Action and then extend many other types of actions, just like you did in LsdAction here

The problem with @freezed models is that we can use the language feature , so there is another possibility that we make whole new action for submit as you have in LSD called MiraiFormSubmitAction and use its own implementation to handle the form submission.

@RodolfoSilva
Copy link
Contributor

Hey @RodolfoSilva What are your suggestions about the MiraiFrom @freezed model class, would it better to follow flutter widget convention, like this

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    MiraiAction? onChanged,
    AutovalidateMode? autovalidateMode,
    required Map<String, dynamic> child,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

or we should make strict rules here by defining a list of child widgets (mainly form-inputs),

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    required List<Map<String, dynamic>> children,
    required MiraiSubmitAction action,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

@i-asimkhan I prefer the first approach. it's more composable than the second. It is closer to HTML form and Flutter Form. This allows the user to decide what kind of child to use. I understand that the second approach will by default have a column implementation.

@RodolfoSilva
Copy link
Contributor

Hey @RodolfoSilva What are your suggestions about the MiraiFrom @freezed model class, would it better to follow flutter widget convention, like this

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    MiraiAction? onChanged,
    AutovalidateMode? autovalidateMode,
    required Map<String, dynamic> child,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

or we should make strict rules here by defining a list of child widgets (mainly form-inputs),

@freezed
class MiraiForm with _$MiraiForm {
  const factory MiraiForm({
    required List<Map<String, dynamic>> children,
    required MiraiSubmitAction action,
    
  }) = _MiraiForm;

  factory MiraiForm.fromJson(Map<String, dynamic> json) =>
      _$MiraiFormFromJson(json);
}

Secondly, we need to partition the business logic from the MiraiAction as it is becoming more and more detailed. One of the thoughts I have is to make a generic type of Action and then extend many other types of actions, just like you did in LsdAction here

The problem with @freezed models is that we can use the language feature , so there is another possibility that we make whole new action for submit as you have in LSD called MiraiFormSubmitAction and use its own implementation to handle the form submission.

I totally agree. Such a move will unlock a wealth of possibilities and customization options. It will empower us to utilize any other navigation library, such as go_router, or to modify the existing implementation. Additionally, partitioning would enable us to relocate MiraiForm into a distinct package.

When I started building LSD, I was thinking about composability and customization being in the control of the user who is using the library.

* main:
  Update publish workflow
  Update publish workflow
  Update publish workflow
  Update working-directory in publish workflow
  Update version to v0.4.1
  Update publish workflow with working-directory
  Update publish workflow with working-directory
  Update Mirai package to v0.4
  Add publish to pub.dev workflow
  fix: Register MiraiExpandedParser
  Fix floating label behaviour in MiraiInputDecorationTheme
  Add MiraiInputDecorationTheme & MiraiInputBorder Support
  Add const in the mirai_expanded_parser.dart
  Added Mirai Expanded Parser

# Conflicts:
#	packages/mirai/lib/src/framework/mirai.dart
#	packages/mirai/lib/src/utils/widget_type.dart
* main:
  refactor: add enum to store the standard action types
  refactor: change actions parsers folder
  fix: component code format
  docs: fix typos
  fix: add missing import
  refactor: remove unused imports
  docs: fix registerAllActions method reference
  docs: add action parsers
  docs: change the overview example
  refactor: import class directly
  refactor: allow action registry

# Conflicts:
#	packages/mirai/lib/src/action/mirai_action_parser.dart
* main:
  Reverted RoundedRectangleBorder to non-nullable in MiraiRoundedRectangleBorderParser
  Updated example button JSON for better visibility of the border color
  Added rounded shape border for mirai button style
  Added rectangle border for mirai button

# Conflicts:
#	examples/mirai_gallery/pubspec.lock
@divyanshub024 divyanshub024 merged commit 485d0bb into main Aug 5, 2023
2 checks passed
@divyanshub024 divyanshub024 deleted the asim/mirai-form-widget branch August 5, 2023 13:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

feat: Add support to submit a form feat: Add Form widget with form-validation support in Mirai
3 participants