riverpod_widget
A library built on top of Flutter that allows all widgets to automatically rebuild when corresponding providers notified, making state management easier and more efficient.
Motivations
As app developers, we often gather requirements from customers, which include various scenarios and designs. Our job is to bring these visions to life through code. The typical workflow involves:
- Analyzing Scenarios: Understanding the requirements and how the application should behave.
- Sketching Components with Dummy Data: Creating initial UI components using placeholder data to visualize the layout and functionality.
- Binding Data to Fit Scenarios: Connecting our UI components to real data sources to make them dynamic.
Simplifying Data Binding with Providers
With riverpod_widget
, the data binding process becomes significantly easier and more time-saving by leveraging providers. By simply adding a $
in front of your Flutter widgets, you can effortlessly bind them to providers, allowing for automatic updates whenever new data is emitted.
Disclaimer: this package is a part of my flutter_clone project. Feel free to explore it if you're interested in creating exceptional packages on top of Flutter.
Here's a quick example:
Assume that we had a Text widget in the sketch,
Text('A string');
Change it into $Text
widget
// Assume that we had a provider called stringProvider as an instance of ProviderBase<String>;
$Text($.all, 'A string'.bind(#data, stringProvider));
More detail in Usage section.
Features
- Automatic widget rebuilding based on provider's state
- Seamless integration with
riverpod
- Simplified state management compared to traditional Flutter approaches
- Supports both stateful and stateless widgets
- Lightweight and easy to integrate into existing Flutter projects
Installation
- Add the package to your
pubspec.yaml
file:
dependencies:
riverpod_widget: ^0.0.1+1
If the latest version of this package is incompatible with your Flutter version, please refer to the Version Mapping section below. There, you'll find instructions on how to use a specific version that matches your Flutter environment.
You can specify a compatible version using the ref
parameter in your pubspec.yaml
file. For example:
dependencies:
riverpod_widget:
git:
url: https://github.com/haitr/flutter_clone.git
path: packages/riverpod_widget
ref: riverpod_widget/v0.0.1
Version Compatibility
pub | ref (verison) | ref (Flutter version) | Flutter version |
---|---|---|---|
0.0.1+1 | riverpod_widget/v0.0.1 | riverpod_widget/flutter/v3.22 | 3.22.x |
0.0.2 | riverpod_widget/v0.0.2 | riverpod_widget/flutter/v3.24 | 3.24.x |
Usage
The riverpod_widget
package simplifies the process of binding Providers to Flutter Widgets. By calling the bind
method to bind any argument to a Provider
, you can easily make them reactive.
Quick start
In order to make a Widget reactive:
-
Add a
$
prefix to the Widget name. -
Add the react-type parameter as the first argument.
react-type | description |
---|---|
$.all |
react on every emitted event |
$.none |
skip all events |
Currently, only $.all
and $.none
is supported; additional types will be added later.
- Bind arguments with corresponding
Provider
: To bind any argument to a Provider, utilize the bind method, where the first parameter is a Symbol that represents the name of the corresponding parameter. For example:
Text('a string'.bind(#data, (ref) => ref.watch(stringProvider)));
Container(color: Colors.blue.bind(#color, (ref) => ref.watch(stateProvider.select((state) => state.color))));
Note: bind
method only run while declaring widget, not in build
phase.
Assuming that there was a Text or a Column in your sketch:
Text(
'Hello, World!',
style: TextStyle(fontSize: 20),
)
Column(
children: [/* ... */],
mainAxisAlignment: MainAxisAlignment.center,
)
As reactive:
$Text(
$.all,
'Hello, World!'.bind(#data, (ref) => ref.watch(greetingProvider)),
style: TextStyle(fontSize: 20).bind(
#style,
(ref) => ref.watch(stateProvider.select((state) => state.style))),
)
In the Text widget, there is a positional String parameter called data
, so we need to use #data for the state getter.
$Column(
$.all,
mainAxisAlignment: MainAxisAlignment.center.bind(
#mainAxisAlignment,
(ref) => ref.watch(stateProvider.select((state) => state.alignment))),
),
children: [/* ... */],
)
Custom Widget
To make a custom widget reactive, enclose it within a Wrapper and ensure proper argument mapping. Be sure to place an instance of $ as the first parameter of the constructor.
For example:
class MyWidget extends StatelessWidget {
final String? field1;
final int field2;
MyWidget({
super.key,
this.field1,
required this.field2,
});
// ...
}
class $MyWidget extends MyWidget {
const $MyWidget(
$ $config, {
super.key,
super.field1,
required super.field2,
});
@override
Widget build(BuildContext context) {
return Wrapper(
Argument({
#field1: field1,
#field2: field2,
}),
builder: (args) => MyWidget(
field1: args(#field1),
field2: args(#field2),
));
}
}
More detail in custom widget.
Example
Find more examples in the examples directory.
License
This project is licensed under the MIT License.
This README provides an overview of your reactive widgets framework, including its key features, installation instructions, usage examples, and contribution guidelines. Feel free to customize it further to suit your specific project requirements.
Libraries
- cupertino/activity_indicator
- cupertino/adaptive_text_selection_toolbar
- cupertino/app
- cupertino/bottom_tab_bar
- cupertino/button
- cupertino/checkbox
- cupertino/context_menu
- cupertino/context_menu_action
- cupertino/date_picker
- cupertino/desktop_text_selection_toolbar
- cupertino/desktop_text_selection_toolbar_button
- cupertino/dialog
- cupertino/form_row
- cupertino/form_section
- cupertino/interface_level
- cupertino/list_section
- cupertino/list_tile
- cupertino/magnifier
- cupertino/nav_bar
- cupertino/page_scaffold
- cupertino/picker
- cupertino/radio
- cupertino/refresh
- cupertino/route
- cupertino/scrollbar
- cupertino/search_field
- cupertino/segmented_control
- cupertino/slider
- cupertino/sliding_segmented_control
- cupertino/spell_check_suggestions_toolbar
- cupertino/switch
- cupertino/tab_scaffold
- cupertino/tab_view
- cupertino/text_field
- cupertino/text_form_field_row
- cupertino/text_selection_toolbar
- cupertino/text_selection_toolbar_button
- cupertino/theme
- material/about
- material/action_buttons
- material/action_chip
- material/action_icons_theme
- material/adaptive_text_selection_toolbar
- material/animated_icons
- material/app
- material/app_bar
- material/autocomplete
- material/badge
- material/badge_theme
- material/banner
- material/banner_theme
- material/bottom_app_bar
- material/bottom_navigation_bar
- material/bottom_navigation_bar_theme
- material/bottom_sheet
- material/button
- material/button_bar
- material/button_bar_theme
- material/button_theme
- material/calendar_date_picker
- material/card
- material/carousel
- material/checkbox
- material/checkbox_list_tile
- material/checkbox_theme
- material/chip
- material/chip_theme
- material/choice_chip
- material/circle_avatar
- material/data_table
- material/data_table_theme
- material/date_picker
- material/date_picker_theme
- material/desktop_text_selection_toolbar
- material/desktop_text_selection_toolbar_button
- material/dialog
- material/divider
- material/divider_theme
- material/drawer
- material/drawer_header
- material/drawer_theme
- material/dropdown
- material/dropdown_menu
- material/dropdown_menu_theme
- material/elevated_button
- material/elevated_button_theme
- material/expand_icon
- material/expansion_panel
- material/expansion_tile
- material/expansion_tile_theme
- material/filled_button
- material/filled_button_theme
- material/filter_chip
- material/flexible_space_bar
- material/floating_action_button
- material/flutter_logo
- material/grid_tile
- material/grid_tile_bar
- material/icon_button
- material/icon_button_theme
- material/ink_decoration
- material/ink_well
- material/input_chip
- material/input_date_picker_form_field
- material/input_decorator
- material/list_tile
- material/list_tile_theme
- material/magnifier
- material/material
- material/material_button
- material/menu_anchor
- material/menu_bar_theme
- material/menu_button_theme
- material/menu_theme
- material/mergeable_material
- material/navigation_bar
- material/navigation_bar_theme
- material/navigation_drawer
- material/navigation_drawer_theme
- material/navigation_rail
- material/navigation_rail_theme
- material/outlined_button
- material/outlined_button_theme
- material/paginated_data_table
- material/popup_menu
- material/popup_menu_theme
- material/progress_indicator
- material/progress_indicator_theme
- material/radio
- material/radio_list_tile
- material/radio_theme
- material/range_slider
- material/refresh_indicator
- material/reorderable_list
- material/scaffold
- material/scrollbar
- material/scrollbar_theme
- material/search_anchor
- material/search_bar_theme
- material/search_view_theme
- material/segmented_button
- material/segmented_button_theme
- material/selectable_text
- material/selection_area
- material/slider
- material/slider_theme
- material/snack_bar
- material/spell_check_suggestions_toolbar
- material/stepper
- material/switch
- material/switch_list_tile
- material/switch_theme
- material/tab_controller
- material/tabs
- material/text_button
- material/text_button_theme
- material/text_field
- material/text_form_field
- material/text_selection_theme
- material/text_selection_toolbar
- material/text_selection_toolbar_text_button
- material/theme
- material/time_picker
- material/time_picker_theme
- material/toggle_buttons
- material/toggle_buttons_theme
- material/tooltip
- material/tooltip_theme
- material/tooltip_visibility
- material/user_accounts_drawer_header
- riverpod_cupertino
- riverpod_material
- riverpod_widgets
- widgets/_platform_selectable_region_context_menu_io
- widgets/actions
- widgets/adapter
- widgets/animated_cross_fade
- widgets/animated_scroll_view
- widgets/animated_size
- widgets/animated_switcher
- widgets/annotated_region
- widgets/app
- widgets/async
- widgets/autocomplete
- widgets/autofill
- widgets/automatic_keep_alive
- widgets/banner
- widgets/basic
- widgets/binding
- widgets/color_filter
- widgets/container
- widgets/decorated_sliver
- widgets/default_selection_style
- widgets/default_text_editing_shortcuts
- widgets/dismissible
- widgets/display_feature_sub_screen
- widgets/drag_target
- widgets/draggable_scrollable_sheet
- widgets/dual_transition_builder
- widgets/editable_text
- widgets/fade_in_image
- widgets/focus_scope
- widgets/focus_traversal
- widgets/form
- widgets/framework
- widgets/gesture_detector
- widgets/grid_paper
- widgets/heroes
- widgets/icon
- widgets/icon_theme
- widgets/image
- widgets/image_filter
- widgets/image_icon
- widgets/implicit_animations
- widgets/interactive_viewer
- widgets/keyboard_listener
- widgets/layout_builder
- widgets/list_wheel_scroll_view
- widgets/localizations
- widgets/lookup_boundary
- widgets/magnifier
- widgets/media_query
- widgets/modal_barrier
- widgets/navigation_toolbar
- widgets/navigator
- widgets/navigator_pop_handler
- widgets/nested_scroll_view
- widgets/notification_listener
- widgets/orientation_builder
- widgets/overflow_bar
- widgets/overlay
- widgets/overscroll_indicator
- widgets/page_storage
- widgets/page_view
- widgets/performance_overlay
- widgets/pinned_header_sliver
- widgets/placeholder
- widgets/platform_menu_bar
- widgets/platform_view
- widgets/pop_scope
- widgets/preferred_size
- widgets/primary_scroll_controller
- widgets/raw_keyboard_listener
- widgets/reorderable_list
- widgets/restoration
- widgets/router
- widgets/safe_area
- widgets/scroll_configuration
- widgets/scroll_notification_observer
- widgets/scroll_view
- widgets/scrollable
- widgets/scrollbar
- widgets/selectable_region
- widgets/selection_container
- widgets/semantics_debugger
- widgets/shared_app_data
- widgets/shortcuts
- widgets/single_child_scroll_view
- widgets/size_changed_layout_notifier
- widgets/sliver
- widgets/sliver_fill
- widgets/sliver_layout_builder
- widgets/sliver_persistent_header
- widgets/sliver_prototype_extent_list
- widgets/sliver_resizing_header
- widgets/sliver_tree
- widgets/sliver_varied_extent_list
- widgets/snapshot_widget
- widgets/spacer
- widgets/system_context_menu
- widgets/table
- widgets/tap_region
- widgets/text
- widgets/text_selection
- widgets/texture
- widgets/ticker_provider
- widgets/title
- widgets/transitions
- widgets/tween_animation_builder
- widgets/undo_history
- widgets/value_listenable_builder
- widgets/view
- widgets/viewport
- widgets/visibility
- widgets/widget_inspector
- widgets/will_pop_scope
- wrapper