diff --git a/docs/ar/animated.md b/docs/ar/animated.md new file mode 100644 index 0000000..69cb4de --- /dev/null +++ b/docs/ar/animated.md @@ -0,0 +1,85 @@ +A widget that display list one or more [animation](#Animations) + +```dart +Animated( + fade: const FadeAnimation(), + transforms: const [ + ScaleAnimation.y(), + FlipAnimation(FlipType.x), + ], + child: const Card(), +), +``` + +# Animations + +### FadeAnimation + +* 🔥 change opacity from [from] to [to] + +### FlipAnimation + +* 🔥 flib widget accourding to type +* 🔥 [FlipType.x] rotate x from (180) t (0) +* 🔥 [FlipType.y] rotate y from (180) t (0) +* 🔥 [FlipType.z] rotate y from (180) t (0) +* 🔥 [FlipType.negativeY] rotate y from (-180) t (0) +* 🔥 [FlipType.negativeX] rotate x from (-180) t (0) +* 🔥 [FlipType.negativeZ] rotate y from (-180) t (0) + +### ScaleAnimation + +* 🔥 scale all axis of widget +* 🔥 [fromX] and [toX] scales the x axis +* 🔥 [fromY] and [toY] scales the y axis +* 🔥 [fromZ] and [toZ] scales the z axis + +```dart + +ScaleAnimation.scale(); +ScaleAnimation.x(); +ScaleAnimation.y(); +ScaleAnimation.z(); +ScaleAnimation.xyz(); + +``` + +### TranslateAnimation + +* 🔥 [fromX] and [toX] translate the x axis +* 🔥 [fromY] and [toY] translate the y axis +* 🔥 [fromZ] and [toZ] translate the z axis + +```dart + +TranslateAnimation.xy(); +TranslateAnimation.x(); +TranslateAnimation.y(); +TranslateAnimation.z(); +TranslateAnimation.xyz(); + +``` + +# AnimatedItemsScope + +if you need to animate some widgets one by one use it + +```dart + return AnimatedItemsScope( + delay: const Duration(seconds: 1), + child: GridView.count( + crossAxisCount: 5, + padding: const EdgeInsets.all(20), + children: [ + /// this will be run at first + Animated(transforms: const [ScaleAnimation.y()], child: const Card()), + /// then this will be run + Animated(transforms: const [ScaleAnimation.x()], child: const Card()), + /// then this + Animated(transforms: const [ScaleAnimation.z()], child: const Card()), + ], + ), + ); +``` + +[x] note the animations delayed 75% of previous one if you want to make it delay by duration that specify the delay property of `AnimatedItemsScope` diff --git a/docs/ar/index.md b/docs/ar/index.md new file mode 100644 index 0000000..9172eec --- /dev/null +++ b/docs/ar/index.md @@ -0,0 +1,149 @@ +# Ready +[![N|Ready][releasesPadge]][releases] + +[![N|GitHub forks][forksPadge]][forks] [![N|GitHub Repo stars][starsPadge]][stars] [![N|GitHub watchers][watchersPadge]][watchers] [![N|Ready][pubPadge]][pubUrl] + +# Other languages +- [Arabic](https://github.com/mo-ah-dawood/ready/blob/main/docs/ar/index.md) +- [Chineese](https://github.com/mo-ah-dawood/ready/blob/main/docs/ch/index.md) + + +##### - Ready is very simple package to allow you create your admin panel with flutter + +##### - Not just an admin panel it also contains avery helpful widgets that you can use with your mobile app + +##### - Admin panel itself can be used in mobile apps as its responsive + +## Can i see it + + - Yes try this [Demo][demo] + +## Where to get it + + - If you are seeing this in pub site so you are in the right place + - if not you can get it [Here](pubUrl) + +## How to use it + + + [ ] First if you support multi language you have to add ready delegate in your material app + +```dart + return MaterialApp( + localizationsDelegates: [ + ...GlobalMaterialLocalizations.delegates, + Ready.delegate, + ], + ); +``` + +[ ] We currently support `arabic` and `english` + +## Features + + > Here will explain each feature + > Click on the feature name to see how to use it + + [x] [ReadyDashboard](ready_dashboard) + - Admin panel layout in easy way + - [responsive] it can work in any device except watch of course😄😄 + - ability to group drawer items + - ability to add action buttons + - ability to override action buttons for some pages + - ability to add search input field in the top app bar + + + [x] [ReadyList](ready_list) + - Pull to refresh + - Infinite scroll + - headers and footers + - easy to work with flutter_bloc but you can use any state management solution + - can be grid or list or your own builder + - contains ready grid delegates to make it simple + + [x] [ResponsiveDataTable](responsive_data_table) + - Responsive widget that show DataTable in large devices and list or grid in smaller one + - 6 layouts + - can be configured to use list or DataTable + - can has selection in lists and DataTables + - can add filters , actions or actions for each row + - work with the same controller [ReadyList] + + [x] [Animated]() + - Fancy animations + - able to merge between (flip , scale , fade, translate) + - scoped animated runs animations one after one + - non scoped run all animations in parallel + - ReadyList contains a scope so you don't need to add it + + [x] [Shimmer](shimmer) + - Show shimmer effect on a widget + - drawing the shimmer on the whole scope the shimmer is in so the full page may has one scope and will paint the shimmer gradient on all [Shimmer] children in its tree + -like this + +![LoadingShimmer](https://user-images.githubusercontent.com/31937782/147537961-2076ab13-9105-4251-83dc-62a2ae8d21fc.gif) + +* see how the effect works its not related to card + + +## Packages + +There is related packages that related to ready and you can use it + +| Plugin | Version | Depends on ready +| ------ | --------- | -| +| [![N\|Ready form][ready_form_github_padge]][ready_form_github] | [![N\|Ready][ready_form_pub_padge]][ready_form_pub] | ❌ | +| [![N\|Ready validation][ready_validation_github_padge]][ready_validation_github] | [![N\|Ready][ready_validation_pub_padge]][ready_validation_pub] | ❌ | +| [![N\|Ready extension][ready_extensions_github_padge]][ready_extensions_github] | [![N\|Ready][ready_extensions_pub_padge]][ready_extensions_pub] | ❌ | +| [![N\|Ready picker][ready_picker_github_padge]][ready_picker_github] | [![N\|Ready][ready_picker_pub_padge]][ready_picker_pub] | ✅ | +| [![N\|Ready image][ready_image_github_padge]][ready_image_github] | [![N\|Ready][ready_image_pub_padge]][ready_image_pub] | ❌ | + +## How to contribute + +* To make package smaller and cleaner as possible we will not add a lot of features to it +* instead we will add the new features in separate packages and list it in the packages section +* in this way if any one need the new feature he can add its package to his project +* any package must has a good docs before it listed in packages list + +[ready_dashboard]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/ready_dashboard.md +[animated]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/animated.md +[ready_list]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/ready_list.md +[responsive_data_table]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/responsive_data_table.md +[shimmer]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/shimmer.md + +[demo]: https://ready-19c04.web.app +[pubUrl]: https://pub.dev/packages/ready +[pubPadge]: https://img.shields.io/pub/v/ready.svg?style=for-the-badge +[stars]: https://github.com/mo-ah-dawood/ready/stargazers +[starsPadge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?style=for-the-badge +[watchers]: https://github.com/mo-ah-dawood/ready/watchers +[watchersPadge]: https://img.shields.io/github/watchers/mo-ah-dawood/ready?style=for-the-badge +[forks]: https://github.com/mo-ah-dawood/ready/network/members +[forksPadge]: https://img.shields.io/github/forks/mo-ah-dawood/ready?style=for-the-badge +[releases]: https://github.com/mo-ah-dawood/ready/releases +[releasesPadge]: https://img.shields.io/github/v/release/mo-ah-dawood/ready?style=for-the-badge + +[ready_form_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_form/README.md +[ready_form_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20form&logoColor=%23ff0000&style=for-the-badge +[ready_form_pub]: https://pub.dev/packages/ready_form +[ready_form_pub_padge]: https://img.shields.io/pub/v/ready_form.svg?style=for-the-badge + +[ready_extensions_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_extensions/README.md +[ready_extensions_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20extensions&logoColor=%23ff0000&style=for-the-badge +[ready_extensions_pub]: https://pub.dev/packages/ready_extensions +[ready_extensions_pub_padge]: https://img.shields.io/pub/v/ready_extensions.svg?style=for-the-badge + +[ready_image_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_image/README.md +[ready_image_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20image&logoColor=%23ff0000&style=for-the-badge +[ready_image_pub]: https://pub.dev/packages/ready_image +[ready_image_pub_padge]: https://img.shields.io/pub/v/ready_image.svg?style=for-the-badge + +[ready_picker_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_picker/README.md +[ready_picker_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20picker&logoColor=%23ff0000&style=for-the-badge +[ready_picker_pub]: https://pub.dev/packages/ready_picker +[ready_picker_pub_padge]: https://img.shields.io/pub/v/ready_picker.svg?style=for-the-badge + +[ready_validation_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_validation/README.md +[ready_validation_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20validation&logoColor=%23ff0000&style=for-the-badge +[ready_validation_pub]: https://pub.dev/packages/ready_validation +[ready_validation_pub_padge]: https://img.shields.io/pub/v/ready_validation.svg?style=for-the-badge diff --git a/docs/ar/ready_dashboard.md b/docs/ar/ready_dashboard.md new file mode 100644 index 0000000..58bece8 --- /dev/null +++ b/docs/ar/ready_dashboard.md @@ -0,0 +1,86 @@ +# Admin panal layout in easy way + +## Usage + +```dart + return ReadyDashboard( + items: [], + ); +``` + +| Property | Type | Required| Description | Default | +| -- | -- | - | ------ | - | +| items | [ `List` ](#DashboardItem) | ✓ | List of [ `DashboardItem` ](#DashboardItem) to be added to the dashboard | | +| initialIndex | `int?` | | The first page to be displayed | 0 | +| drawerOptions | [ `DrawerOptions` ](#DrawerOptions) | ✓ | options to configure the drawer of dashboard | [ `DrawerOptions()` ](#DrawerOptions) | +| appBarOptions | [ `AppBarOptions` ](#AppBarOptions) | ✓ | options to configure the appBar of dashboard | [ `AppBarOptions()` ](#AppBarOptions) | +| actions | `List` | ✓ | List of widgets to added to the app bar actions | `[]` | + +# DashboardItem +* Describe the pages of the dashboard +* Can be single or item group + +[x] Single + +```dart +DashboardItem( + builder: () { + // return const YourPage(); + }, + icon: const Icon(Icons.animation), + id: 'item_id', + label: 'Item label', +) +``` + +[x] Group + +```dart +DashboardItem.items( + icon: const Icon(Icons.category), + label: 'Grid', + subItems: [ + /// Group items + ], +) +``` + +| Property | Type | Required| Description | Default | +| -- | -- | - | ------ | - | +| icon | `Widget` | ✓ | The first page to be displayed | | +| id | `String` | ✓ | the id of the item , must be uniq | | +| label | `String` | ✓ | the Label to be displayed in the app bar of the dashboard | | +| search | `Function` | | if added a search input will be added at the app bar and label will not be displayed | | +| actions | `List` | ✓ | List of widgets to added to the app bar actions , this will be merged with the base actions of dashboard | `[]` | +| overrideActions | `bool` | ✓ | if true actions of item will override dashboard actions instead of maere with them | `false` | +| -- | -- | - | ------ | - | +| subItems | [ `List` ](#DashboardItem) | ✓ | List of [ `DashboardItem` ](#DashboardItem) to be added to the group | | + +# DrawerOptions + +| Property | Type | Required| Description | Default | +| -- | -- | - | ------ | - | +| image | `DecorationImage?` | | image to be added as background of the drawer | | +| backgroundColor | `Color?` | | the background color of the drawer | | +| gradient | `Gradient?` | | gradient to be added as background of the drawer| | +| headers | `List` | ✓ | List of widgets to be added to the top of drawer under expand button| `[]` | +| footer | `Widget?` | | Widget that will be added at the end of the drawer it can be aligned by wrapping it with `Align` | | +| logo | `Widget?` | | Widget that will be added at the top of the drawer in the same line of expand button| | + +# AppBarOptions + +Property | Type | Required| Description | Default +-- | -- | - | ------ | - +theme | `AppBarTheme?` | | Theme to be applied to app bar | Transparent background and normal text color +inputDecoration | `InputDecoration?` | | decoration of search box | +flexibleSpace | `Widget?` | | This property is used to configure an `AppBar` . flexibleSpace | +bottom | `PreferredSizeWidget?` | | This property is used to configure an `AppBar` . bottom | +primary | `bool?` | | This property is used to configure an `AppBar` . primary | +collapsedHeight | `double?` | | This property is used to configure an `AppBar` . collapsedHeight | +expandedHeight | `double?` | | This property is used to configure an `AppBar` . expandedHeight | +floating | `bool?` | | This property is used to configure an `AppBar` . floating | +pinned | `bool?` | | This property is used to configure an `AppBar` . pinned | +snap | `bool?` | | This property is used to configure an `AppBar` . snap | +stretch | `bool?` | | This property is used to configure an `AppBar` . stretch | +stretchTriggerOffset | `double?` | | This property is used to configure an `AppBar` . stretchTriggerOffset | +onStretchTrigger | `AsyncCallback?` | | This property is used to configure an `AppBar` . onStretchTrigger | diff --git a/docs/ar/ready_list.md b/docs/ar/ready_list.md new file mode 100644 index 0000000..642f02b --- /dev/null +++ b/docs/ar/ready_list.md @@ -0,0 +1,130 @@ +# Complete list that + + - Handle pull to refresh + - Infinite scroll + - Making grids + + +# usage + +## First create controller + +```dart + +class ReadyListCubit extends Cubit> implements ReadyListController { + ReadyListCubit() : super(const ReadyListState.firstState()); + /// if you don't need to use loading features you can return null + /// ListLoadingHandler? get handler =>null + @override + ListLoadingHandler? get handler => DefaultListLoadingHandler( + loadData: (skip, pageSize, cancelToken) async { + /// Fetch your data + }, + controller: this, + ); + +} + +``` + +# if you want to use your own class or change notifier + +```dart +class ReadyListCubit extends ChangeNotifier implements ReadyRemoteController { + ReadyListState _state = ReadyListState(); + @override + ReadyListState get state => _state; + + final StreamController> _controller = StreamController>.broadcast(); + @override + Stream> get stream => _controller.stream; + + @override + void emit(ReadyListState state) { + _state = state; + _controller.add(state); + } + + @override + Future> loadData({ + ICancelToken? cancelToken, + required int skip, + required int pageSize, + }) async { + /// Fetch your data + } +} + +``` + +## List + +```dart +return ReadyList.list( + key: Key(DateTime.now().toIso8601String()), + buildItem: (FakeItem? item, int index) { + return _buildItem(item, index); + }, + controller: ReadyListCubit(), +); +``` + +## Grid + +```dart +return ReadyList.grid( + gridDelegate: Grids.columns_2, + buildItem: (FakeItem? item, int index) { + /// build item + }, + controller: ReadyListCubit(), +); +``` + +## Slivers + +```dart +return ReadyList.slivers( + controller: ReadyListCubit(), + slivers: (ReadyListState state) { + /// build your own slivers + }, +); +``` + +Property | Description | Nullable +-- | ------ | - +scrollController | List scroll controller | ✓ +controller | The list state controller | +keepAlive | Whether to keep a live or not | +headerSlivers | Slivers at the top of the list or grid | ✓ +footerSlivers | Slivers at the end | ✓ +innerFooterSlivers | Sliver at the end but before the infinite loading| ✓ +filterItems | Filter the list items , this will not affect the list of the controller | ✓ +placeholdersConfig | Config for placeholders when list is empty or has error | ✓ +allowRefresh | whether to allow pull to refresh or not | ✓ +allowLoadNext | whether to allow infinite scroll or not | ✓ +noMoreText | The text to displayed when no more items | ✓ +loadMoreText | The text to display when items loaded but not fill the screen | ✓ +padding | padding of the list | ✓ +reverse | whether to reverse the list or not | ✓ +showNoMoreText | if false we will not show 'No more text' at the end of the list | ✓ +shimmerScopeGradient | gradient of shimmer scope | ✓ +allowFakeItems | if this is true the the item that passed to builder item may be null, useful to display shimmer | ✓ +shrinkWrap | whether to shrink-wrap or not | ✓ +axis | axis of the list | ✓ +physics | physics of the list | ✓ +topLevelFooterSlivers | The first items in the list | ✓ +topLevelHeaderSlivers | The last items in the list | ✓ +pageSize | page size to be passed to controller loadData| ✓ + +# Global config + +> you can config your all list with global config + +```dart +ReadyListConfig( + showNoMoreText: false, + child: MaterialApp(), +) +``` diff --git a/docs/ar/responsive_data_table.md b/docs/ar/responsive_data_table.md new file mode 100644 index 0000000..9d0c8bf --- /dev/null +++ b/docs/ar/responsive_data_table.md @@ -0,0 +1,229 @@ +# Responsive widget that show datatable in large devices and list or grid in medium and small devices + +# usage + +## First create controller same as [ReadyList controller](https://github.com/mo-ah-dawood/ready/wiki/ReadyList#first-create-controller) + +## Then + +```dart +return ResponsiveDataTable( + controller: controller, + dataTable: DataTableOptions( + buildItem: (int index, FakeItem item) { + return [ + Text(item.id), + Text(item.name), + Text(item.rate.toString()), + ]; + }, + headers: ['#', "Name", "Rate"].toDataColumns(), + ), + list: ListOptions(title: (FakeItem item) => Text(item.name)), +); +``` + +Property | Description | Nullable +-- | ------ | - +dataTable | object of [ `DataTableOptions` ](#DataTableOptions) to configure how DataTable work | +list | object of [ `ListOptions ` ](#ListOptions) to configure how ReadyList work | +controller | The list state controller | +keepAlive | Whether to keep a live or not | +type | whether to show list or datatable , leave empty for automatic | ✓ +actions | actions to display at the top of datatable or list | +rowActions | list of [ `Action` ](#row-actions) to display in each row | +filters | List of widgets to display in [filters](#Filters) sheet like search or date | +selectionButton | Widget builder for the button to be visible when there is selection, leave empty to disable selections | ✓ + +# DataTableOptions + +Property | Description | Nullable +-- | ------ | - +headers | list of `DataColumn` to be displayed in the header | +buildItem | function that return `List` for each row | +padding | Padding to applied for datatable | +refreshButton | Custom refresh button to be displayed at the top of datatable , leave empty for default | +availableRowsCount | list of `int` that will be displayed to user to choose one of them, must contain `initialRowsPerPage` | +initialRowsPerPage | the initial rows per page , its must be one of `availableRowsCount` | + +# ListOptions + +My be simple like that + +```dart +ListOptions( + title: (FakeItem item) => Text(item.name), +) +``` + +Or you can build your own + +```dart +ListOptions.builder( + builder: (item, int index, LayoutType layout, List actions) { + // Your own widget + }, +) +``` + +Property | Description | Nullable +-- | ------ | - +scrollController | List scroll controller | ✓ +headerSlivers | Slivers at the top of the list or grid | ✓ +footerSlivers | Slivers at the end | ✓ +innerFooterSlivers | Sliver at the end but before the infinite loading| ✓ +placeholdersConfig | Config for placeholders when list is empty or has error | ✓ +allowRefresh | whether to allow pull to refresh or not | ✓ +allowLoadNext | whether to allow infinite scroll or not | ✓ +noMoreText | The text to displayed when no more items | ✓ +loadMoreText | The text to display when items loaded but not fill the screen | ✓ +padding | padding of the list | ✓ +reverse | whether to reverse the list or not | ✓ +showNoMoreText | if false we will not show 'No more text' at the end of the list | ✓ +shimmerScopeGradient | gradient of shimmer scope | ✓ +allowFakeItems | if this is true the the item that passed to builder item may be null, useful to display shimmer | ✓ +shrinkWrap | whether to shrink-wrap or not | ✓ +axis | axis of the list | ✓ +physics | physics of the list | ✓ +topLevelFooterSlivers | The first items in the list | ✓ +topLevelHeaderSlivers | The last items in the list | ✓ +pageSize | page size to be passed to controller loadData| ✓ + +# Row Actions + +These actions will be displayed at the end of each row or list item + +currently there is `IconAction` that you can make your own actions by extending `Action` + +```dart + IconAction({ + required this.action, + required this.icon, + required this.color, + required this.toolTip, + this.enabled = _defEnabled, + }); +``` + +### View action + +```dart +IconAction.view( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Delete action + +```dart +IconAction.delete( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Edit action + +```dart +IconAction.edit( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Deactivate action + +```dart +IconAction.deactivate( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Activate action + +```dart +IconAction.activate( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Toggle action + +```dart +IconAction.toggle( + isActive: true | false, + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +# Filters + +Filters is list of widgets so it can be any thing but we already had some widgets that may be used as filters + +### Search filter + +```dart +SearchFilter( + onChange: (String? value) { + /// + }, +), +``` + +### Toggle filter + +```dart +ToggleFilter( + onChange: (bool? value) { + /// + }, +), +``` + +### Time filter + +```dart +TimeFilter( + onChange: (TimeOfDay? value) { + /// + }, +), +``` + +### Date filter + +```dart +DateFilter( + onChange: (DateTime? value) { + /// + }, +), +``` + +### Options filter + +```dart +SingleOptionFilter( + onChange: (int? value) { + /// + }, + display: 'My option', + items: [ + OptionFilterItem(display: 'Item 1',value: 1), + OptionFilterItem(display: 'Item 2',value: 2), + OptionFilterItem(display: 'Item 3',value: 3), + ], +), +``` + +It can be of any type not just `int` diff --git a/docs/ar/shimmer.md b/docs/ar/shimmer.md new file mode 100644 index 0000000..50e22b5 --- /dev/null +++ b/docs/ar/shimmer.md @@ -0,0 +1,26 @@ +### Fisrt you need your widgets with `ShimmerScope` +### Every widget must be wrapped with `Shimmer` + +```dart + +ShimmerScope( + child: List(children:[ + Shimmer(child: Card(child:Text("Item 1"))), + Shimmer(child: Card(child:Text("Item 2"))), + Shimmer(child: Card(child:Text("Item 3"))), + Shimmer(child: Card(child:Text("Item 4"))), + ]) +) +``` + +### enable or disable effect + +```dart + +Shimmer( + enabled: true | false, + child: Card( + child: Text("Item 1") + ) + ), +``` diff --git a/docs/ch/animated.md b/docs/ch/animated.md new file mode 100644 index 0000000..69cb4de --- /dev/null +++ b/docs/ch/animated.md @@ -0,0 +1,85 @@ +A widget that display list one or more [animation](#Animations) + +```dart +Animated( + fade: const FadeAnimation(), + transforms: const [ + ScaleAnimation.y(), + FlipAnimation(FlipType.x), + ], + child: const Card(), +), +``` + +# Animations + +### FadeAnimation + +* 🔥 change opacity from [from] to [to] + +### FlipAnimation + +* 🔥 flib widget accourding to type +* 🔥 [FlipType.x] rotate x from (180) t (0) +* 🔥 [FlipType.y] rotate y from (180) t (0) +* 🔥 [FlipType.z] rotate y from (180) t (0) +* 🔥 [FlipType.negativeY] rotate y from (-180) t (0) +* 🔥 [FlipType.negativeX] rotate x from (-180) t (0) +* 🔥 [FlipType.negativeZ] rotate y from (-180) t (0) + +### ScaleAnimation + +* 🔥 scale all axis of widget +* 🔥 [fromX] and [toX] scales the x axis +* 🔥 [fromY] and [toY] scales the y axis +* 🔥 [fromZ] and [toZ] scales the z axis + +```dart + +ScaleAnimation.scale(); +ScaleAnimation.x(); +ScaleAnimation.y(); +ScaleAnimation.z(); +ScaleAnimation.xyz(); + +``` + +### TranslateAnimation + +* 🔥 [fromX] and [toX] translate the x axis +* 🔥 [fromY] and [toY] translate the y axis +* 🔥 [fromZ] and [toZ] translate the z axis + +```dart + +TranslateAnimation.xy(); +TranslateAnimation.x(); +TranslateAnimation.y(); +TranslateAnimation.z(); +TranslateAnimation.xyz(); + +``` + +# AnimatedItemsScope + +if you need to animate some widgets one by one use it + +```dart + return AnimatedItemsScope( + delay: const Duration(seconds: 1), + child: GridView.count( + crossAxisCount: 5, + padding: const EdgeInsets.all(20), + children: [ + /// this will be run at first + Animated(transforms: const [ScaleAnimation.y()], child: const Card()), + /// then this will be run + Animated(transforms: const [ScaleAnimation.x()], child: const Card()), + /// then this + Animated(transforms: const [ScaleAnimation.z()], child: const Card()), + ], + ), + ); +``` + +[x] note the animations delayed 75% of previous one if you want to make it delay by duration that specify the delay property of `AnimatedItemsScope` diff --git a/docs/ch/index.md b/docs/ch/index.md new file mode 100644 index 0000000..9172eec --- /dev/null +++ b/docs/ch/index.md @@ -0,0 +1,149 @@ +# Ready +[![N|Ready][releasesPadge]][releases] + +[![N|GitHub forks][forksPadge]][forks] [![N|GitHub Repo stars][starsPadge]][stars] [![N|GitHub watchers][watchersPadge]][watchers] [![N|Ready][pubPadge]][pubUrl] + +# Other languages +- [Arabic](https://github.com/mo-ah-dawood/ready/blob/main/docs/ar/index.md) +- [Chineese](https://github.com/mo-ah-dawood/ready/blob/main/docs/ch/index.md) + + +##### - Ready is very simple package to allow you create your admin panel with flutter + +##### - Not just an admin panel it also contains avery helpful widgets that you can use with your mobile app + +##### - Admin panel itself can be used in mobile apps as its responsive + +## Can i see it + + - Yes try this [Demo][demo] + +## Where to get it + + - If you are seeing this in pub site so you are in the right place + - if not you can get it [Here](pubUrl) + +## How to use it + + + [ ] First if you support multi language you have to add ready delegate in your material app + +```dart + return MaterialApp( + localizationsDelegates: [ + ...GlobalMaterialLocalizations.delegates, + Ready.delegate, + ], + ); +``` + +[ ] We currently support `arabic` and `english` + +## Features + + > Here will explain each feature + > Click on the feature name to see how to use it + + [x] [ReadyDashboard](ready_dashboard) + - Admin panel layout in easy way + - [responsive] it can work in any device except watch of course😄😄 + - ability to group drawer items + - ability to add action buttons + - ability to override action buttons for some pages + - ability to add search input field in the top app bar + + + [x] [ReadyList](ready_list) + - Pull to refresh + - Infinite scroll + - headers and footers + - easy to work with flutter_bloc but you can use any state management solution + - can be grid or list or your own builder + - contains ready grid delegates to make it simple + + [x] [ResponsiveDataTable](responsive_data_table) + - Responsive widget that show DataTable in large devices and list or grid in smaller one + - 6 layouts + - can be configured to use list or DataTable + - can has selection in lists and DataTables + - can add filters , actions or actions for each row + - work with the same controller [ReadyList] + + [x] [Animated]() + - Fancy animations + - able to merge between (flip , scale , fade, translate) + - scoped animated runs animations one after one + - non scoped run all animations in parallel + - ReadyList contains a scope so you don't need to add it + + [x] [Shimmer](shimmer) + - Show shimmer effect on a widget + - drawing the shimmer on the whole scope the shimmer is in so the full page may has one scope and will paint the shimmer gradient on all [Shimmer] children in its tree + -like this + +![LoadingShimmer](https://user-images.githubusercontent.com/31937782/147537961-2076ab13-9105-4251-83dc-62a2ae8d21fc.gif) + +* see how the effect works its not related to card + + +## Packages + +There is related packages that related to ready and you can use it + +| Plugin | Version | Depends on ready +| ------ | --------- | -| +| [![N\|Ready form][ready_form_github_padge]][ready_form_github] | [![N\|Ready][ready_form_pub_padge]][ready_form_pub] | ❌ | +| [![N\|Ready validation][ready_validation_github_padge]][ready_validation_github] | [![N\|Ready][ready_validation_pub_padge]][ready_validation_pub] | ❌ | +| [![N\|Ready extension][ready_extensions_github_padge]][ready_extensions_github] | [![N\|Ready][ready_extensions_pub_padge]][ready_extensions_pub] | ❌ | +| [![N\|Ready picker][ready_picker_github_padge]][ready_picker_github] | [![N\|Ready][ready_picker_pub_padge]][ready_picker_pub] | ✅ | +| [![N\|Ready image][ready_image_github_padge]][ready_image_github] | [![N\|Ready][ready_image_pub_padge]][ready_image_pub] | ❌ | + +## How to contribute + +* To make package smaller and cleaner as possible we will not add a lot of features to it +* instead we will add the new features in separate packages and list it in the packages section +* in this way if any one need the new feature he can add its package to his project +* any package must has a good docs before it listed in packages list + +[ready_dashboard]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/ready_dashboard.md +[animated]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/animated.md +[ready_list]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/ready_list.md +[responsive_data_table]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/responsive_data_table.md +[shimmer]: https://github.com/mo-ah-dawood/ready/blob/main/docs/en/shimmer.md + +[demo]: https://ready-19c04.web.app +[pubUrl]: https://pub.dev/packages/ready +[pubPadge]: https://img.shields.io/pub/v/ready.svg?style=for-the-badge +[stars]: https://github.com/mo-ah-dawood/ready/stargazers +[starsPadge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?style=for-the-badge +[watchers]: https://github.com/mo-ah-dawood/ready/watchers +[watchersPadge]: https://img.shields.io/github/watchers/mo-ah-dawood/ready?style=for-the-badge +[forks]: https://github.com/mo-ah-dawood/ready/network/members +[forksPadge]: https://img.shields.io/github/forks/mo-ah-dawood/ready?style=for-the-badge +[releases]: https://github.com/mo-ah-dawood/ready/releases +[releasesPadge]: https://img.shields.io/github/v/release/mo-ah-dawood/ready?style=for-the-badge + +[ready_form_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_form/README.md +[ready_form_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20form&logoColor=%23ff0000&style=for-the-badge +[ready_form_pub]: https://pub.dev/packages/ready_form +[ready_form_pub_padge]: https://img.shields.io/pub/v/ready_form.svg?style=for-the-badge + +[ready_extensions_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_extensions/README.md +[ready_extensions_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20extensions&logoColor=%23ff0000&style=for-the-badge +[ready_extensions_pub]: https://pub.dev/packages/ready_extensions +[ready_extensions_pub_padge]: https://img.shields.io/pub/v/ready_extensions.svg?style=for-the-badge + +[ready_image_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_image/README.md +[ready_image_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20image&logoColor=%23ff0000&style=for-the-badge +[ready_image_pub]: https://pub.dev/packages/ready_image +[ready_image_pub_padge]: https://img.shields.io/pub/v/ready_image.svg?style=for-the-badge + +[ready_picker_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_picker/README.md +[ready_picker_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20picker&logoColor=%23ff0000&style=for-the-badge +[ready_picker_pub]: https://pub.dev/packages/ready_picker +[ready_picker_pub_padge]: https://img.shields.io/pub/v/ready_picker.svg?style=for-the-badge + +[ready_validation_github]: https://github.com/mo-ah-dawood/ready/tree/main/packages/ready_validation/README.md +[ready_validation_github_padge]: https://img.shields.io/github/stars/mo-ah-dawood/ready?label=Ready%20validation&logoColor=%23ff0000&style=for-the-badge +[ready_validation_pub]: https://pub.dev/packages/ready_validation +[ready_validation_pub_padge]: https://img.shields.io/pub/v/ready_validation.svg?style=for-the-badge diff --git a/docs/ch/ready_dashboard.md b/docs/ch/ready_dashboard.md new file mode 100644 index 0000000..58bece8 --- /dev/null +++ b/docs/ch/ready_dashboard.md @@ -0,0 +1,86 @@ +# Admin panal layout in easy way + +## Usage + +```dart + return ReadyDashboard( + items: [], + ); +``` + +| Property | Type | Required| Description | Default | +| -- | -- | - | ------ | - | +| items | [ `List` ](#DashboardItem) | ✓ | List of [ `DashboardItem` ](#DashboardItem) to be added to the dashboard | | +| initialIndex | `int?` | | The first page to be displayed | 0 | +| drawerOptions | [ `DrawerOptions` ](#DrawerOptions) | ✓ | options to configure the drawer of dashboard | [ `DrawerOptions()` ](#DrawerOptions) | +| appBarOptions | [ `AppBarOptions` ](#AppBarOptions) | ✓ | options to configure the appBar of dashboard | [ `AppBarOptions()` ](#AppBarOptions) | +| actions | `List` | ✓ | List of widgets to added to the app bar actions | `[]` | + +# DashboardItem +* Describe the pages of the dashboard +* Can be single or item group + +[x] Single + +```dart +DashboardItem( + builder: () { + // return const YourPage(); + }, + icon: const Icon(Icons.animation), + id: 'item_id', + label: 'Item label', +) +``` + +[x] Group + +```dart +DashboardItem.items( + icon: const Icon(Icons.category), + label: 'Grid', + subItems: [ + /// Group items + ], +) +``` + +| Property | Type | Required| Description | Default | +| -- | -- | - | ------ | - | +| icon | `Widget` | ✓ | The first page to be displayed | | +| id | `String` | ✓ | the id of the item , must be uniq | | +| label | `String` | ✓ | the Label to be displayed in the app bar of the dashboard | | +| search | `Function` | | if added a search input will be added at the app bar and label will not be displayed | | +| actions | `List` | ✓ | List of widgets to added to the app bar actions , this will be merged with the base actions of dashboard | `[]` | +| overrideActions | `bool` | ✓ | if true actions of item will override dashboard actions instead of maere with them | `false` | +| -- | -- | - | ------ | - | +| subItems | [ `List` ](#DashboardItem) | ✓ | List of [ `DashboardItem` ](#DashboardItem) to be added to the group | | + +# DrawerOptions + +| Property | Type | Required| Description | Default | +| -- | -- | - | ------ | - | +| image | `DecorationImage?` | | image to be added as background of the drawer | | +| backgroundColor | `Color?` | | the background color of the drawer | | +| gradient | `Gradient?` | | gradient to be added as background of the drawer| | +| headers | `List` | ✓ | List of widgets to be added to the top of drawer under expand button| `[]` | +| footer | `Widget?` | | Widget that will be added at the end of the drawer it can be aligned by wrapping it with `Align` | | +| logo | `Widget?` | | Widget that will be added at the top of the drawer in the same line of expand button| | + +# AppBarOptions + +Property | Type | Required| Description | Default +-- | -- | - | ------ | - +theme | `AppBarTheme?` | | Theme to be applied to app bar | Transparent background and normal text color +inputDecoration | `InputDecoration?` | | decoration of search box | +flexibleSpace | `Widget?` | | This property is used to configure an `AppBar` . flexibleSpace | +bottom | `PreferredSizeWidget?` | | This property is used to configure an `AppBar` . bottom | +primary | `bool?` | | This property is used to configure an `AppBar` . primary | +collapsedHeight | `double?` | | This property is used to configure an `AppBar` . collapsedHeight | +expandedHeight | `double?` | | This property is used to configure an `AppBar` . expandedHeight | +floating | `bool?` | | This property is used to configure an `AppBar` . floating | +pinned | `bool?` | | This property is used to configure an `AppBar` . pinned | +snap | `bool?` | | This property is used to configure an `AppBar` . snap | +stretch | `bool?` | | This property is used to configure an `AppBar` . stretch | +stretchTriggerOffset | `double?` | | This property is used to configure an `AppBar` . stretchTriggerOffset | +onStretchTrigger | `AsyncCallback?` | | This property is used to configure an `AppBar` . onStretchTrigger | diff --git a/docs/ch/ready_list.md b/docs/ch/ready_list.md new file mode 100644 index 0000000..642f02b --- /dev/null +++ b/docs/ch/ready_list.md @@ -0,0 +1,130 @@ +# Complete list that + + - Handle pull to refresh + - Infinite scroll + - Making grids + + +# usage + +## First create controller + +```dart + +class ReadyListCubit extends Cubit> implements ReadyListController { + ReadyListCubit() : super(const ReadyListState.firstState()); + /// if you don't need to use loading features you can return null + /// ListLoadingHandler? get handler =>null + @override + ListLoadingHandler? get handler => DefaultListLoadingHandler( + loadData: (skip, pageSize, cancelToken) async { + /// Fetch your data + }, + controller: this, + ); + +} + +``` + +# if you want to use your own class or change notifier + +```dart +class ReadyListCubit extends ChangeNotifier implements ReadyRemoteController { + ReadyListState _state = ReadyListState(); + @override + ReadyListState get state => _state; + + final StreamController> _controller = StreamController>.broadcast(); + @override + Stream> get stream => _controller.stream; + + @override + void emit(ReadyListState state) { + _state = state; + _controller.add(state); + } + + @override + Future> loadData({ + ICancelToken? cancelToken, + required int skip, + required int pageSize, + }) async { + /// Fetch your data + } +} + +``` + +## List + +```dart +return ReadyList.list( + key: Key(DateTime.now().toIso8601String()), + buildItem: (FakeItem? item, int index) { + return _buildItem(item, index); + }, + controller: ReadyListCubit(), +); +``` + +## Grid + +```dart +return ReadyList.grid( + gridDelegate: Grids.columns_2, + buildItem: (FakeItem? item, int index) { + /// build item + }, + controller: ReadyListCubit(), +); +``` + +## Slivers + +```dart +return ReadyList.slivers( + controller: ReadyListCubit(), + slivers: (ReadyListState state) { + /// build your own slivers + }, +); +``` + +Property | Description | Nullable +-- | ------ | - +scrollController | List scroll controller | ✓ +controller | The list state controller | +keepAlive | Whether to keep a live or not | +headerSlivers | Slivers at the top of the list or grid | ✓ +footerSlivers | Slivers at the end | ✓ +innerFooterSlivers | Sliver at the end but before the infinite loading| ✓ +filterItems | Filter the list items , this will not affect the list of the controller | ✓ +placeholdersConfig | Config for placeholders when list is empty or has error | ✓ +allowRefresh | whether to allow pull to refresh or not | ✓ +allowLoadNext | whether to allow infinite scroll or not | ✓ +noMoreText | The text to displayed when no more items | ✓ +loadMoreText | The text to display when items loaded but not fill the screen | ✓ +padding | padding of the list | ✓ +reverse | whether to reverse the list or not | ✓ +showNoMoreText | if false we will not show 'No more text' at the end of the list | ✓ +shimmerScopeGradient | gradient of shimmer scope | ✓ +allowFakeItems | if this is true the the item that passed to builder item may be null, useful to display shimmer | ✓ +shrinkWrap | whether to shrink-wrap or not | ✓ +axis | axis of the list | ✓ +physics | physics of the list | ✓ +topLevelFooterSlivers | The first items in the list | ✓ +topLevelHeaderSlivers | The last items in the list | ✓ +pageSize | page size to be passed to controller loadData| ✓ + +# Global config + +> you can config your all list with global config + +```dart +ReadyListConfig( + showNoMoreText: false, + child: MaterialApp(), +) +``` diff --git a/docs/ch/responsive_data_table.md b/docs/ch/responsive_data_table.md new file mode 100644 index 0000000..9d0c8bf --- /dev/null +++ b/docs/ch/responsive_data_table.md @@ -0,0 +1,229 @@ +# Responsive widget that show datatable in large devices and list or grid in medium and small devices + +# usage + +## First create controller same as [ReadyList controller](https://github.com/mo-ah-dawood/ready/wiki/ReadyList#first-create-controller) + +## Then + +```dart +return ResponsiveDataTable( + controller: controller, + dataTable: DataTableOptions( + buildItem: (int index, FakeItem item) { + return [ + Text(item.id), + Text(item.name), + Text(item.rate.toString()), + ]; + }, + headers: ['#', "Name", "Rate"].toDataColumns(), + ), + list: ListOptions(title: (FakeItem item) => Text(item.name)), +); +``` + +Property | Description | Nullable +-- | ------ | - +dataTable | object of [ `DataTableOptions` ](#DataTableOptions) to configure how DataTable work | +list | object of [ `ListOptions ` ](#ListOptions) to configure how ReadyList work | +controller | The list state controller | +keepAlive | Whether to keep a live or not | +type | whether to show list or datatable , leave empty for automatic | ✓ +actions | actions to display at the top of datatable or list | +rowActions | list of [ `Action` ](#row-actions) to display in each row | +filters | List of widgets to display in [filters](#Filters) sheet like search or date | +selectionButton | Widget builder for the button to be visible when there is selection, leave empty to disable selections | ✓ + +# DataTableOptions + +Property | Description | Nullable +-- | ------ | - +headers | list of `DataColumn` to be displayed in the header | +buildItem | function that return `List` for each row | +padding | Padding to applied for datatable | +refreshButton | Custom refresh button to be displayed at the top of datatable , leave empty for default | +availableRowsCount | list of `int` that will be displayed to user to choose one of them, must contain `initialRowsPerPage` | +initialRowsPerPage | the initial rows per page , its must be one of `availableRowsCount` | + +# ListOptions + +My be simple like that + +```dart +ListOptions( + title: (FakeItem item) => Text(item.name), +) +``` + +Or you can build your own + +```dart +ListOptions.builder( + builder: (item, int index, LayoutType layout, List actions) { + // Your own widget + }, +) +``` + +Property | Description | Nullable +-- | ------ | - +scrollController | List scroll controller | ✓ +headerSlivers | Slivers at the top of the list or grid | ✓ +footerSlivers | Slivers at the end | ✓ +innerFooterSlivers | Sliver at the end but before the infinite loading| ✓ +placeholdersConfig | Config for placeholders when list is empty or has error | ✓ +allowRefresh | whether to allow pull to refresh or not | ✓ +allowLoadNext | whether to allow infinite scroll or not | ✓ +noMoreText | The text to displayed when no more items | ✓ +loadMoreText | The text to display when items loaded but not fill the screen | ✓ +padding | padding of the list | ✓ +reverse | whether to reverse the list or not | ✓ +showNoMoreText | if false we will not show 'No more text' at the end of the list | ✓ +shimmerScopeGradient | gradient of shimmer scope | ✓ +allowFakeItems | if this is true the the item that passed to builder item may be null, useful to display shimmer | ✓ +shrinkWrap | whether to shrink-wrap or not | ✓ +axis | axis of the list | ✓ +physics | physics of the list | ✓ +topLevelFooterSlivers | The first items in the list | ✓ +topLevelHeaderSlivers | The last items in the list | ✓ +pageSize | page size to be passed to controller loadData| ✓ + +# Row Actions + +These actions will be displayed at the end of each row or list item + +currently there is `IconAction` that you can make your own actions by extending `Action` + +```dart + IconAction({ + required this.action, + required this.icon, + required this.color, + required this.toolTip, + this.enabled = _defEnabled, + }); +``` + +### View action + +```dart +IconAction.view( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Delete action + +```dart +IconAction.delete( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Edit action + +```dart +IconAction.edit( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Deactivate action + +```dart +IconAction.deactivate( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Activate action + +```dart +IconAction.activate( + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +### Toggle action + +```dart +IconAction.toggle( + isActive: true | false, + action: (BuildContext context, ReadyListCubit controller, FakeItem item) { + + }, +), +``` + +# Filters + +Filters is list of widgets so it can be any thing but we already had some widgets that may be used as filters + +### Search filter + +```dart +SearchFilter( + onChange: (String? value) { + /// + }, +), +``` + +### Toggle filter + +```dart +ToggleFilter( + onChange: (bool? value) { + /// + }, +), +``` + +### Time filter + +```dart +TimeFilter( + onChange: (TimeOfDay? value) { + /// + }, +), +``` + +### Date filter + +```dart +DateFilter( + onChange: (DateTime? value) { + /// + }, +), +``` + +### Options filter + +```dart +SingleOptionFilter( + onChange: (int? value) { + /// + }, + display: 'My option', + items: [ + OptionFilterItem(display: 'Item 1',value: 1), + OptionFilterItem(display: 'Item 2',value: 2), + OptionFilterItem(display: 'Item 3',value: 3), + ], +), +``` + +It can be of any type not just `int` diff --git a/docs/ch/shimmer.md b/docs/ch/shimmer.md new file mode 100644 index 0000000..50e22b5 --- /dev/null +++ b/docs/ch/shimmer.md @@ -0,0 +1,26 @@ +### Fisrt you need your widgets with `ShimmerScope` +### Every widget must be wrapped with `Shimmer` + +```dart + +ShimmerScope( + child: List(children:[ + Shimmer(child: Card(child:Text("Item 1"))), + Shimmer(child: Card(child:Text("Item 2"))), + Shimmer(child: Card(child:Text("Item 3"))), + Shimmer(child: Card(child:Text("Item 4"))), + ]) +) +``` + +### enable or disable effect + +```dart + +Shimmer( + enabled: true | false, + child: Card( + child: Text("Item 1") + ) + ), +```