diff --git a/README.md b/README.md
index 77da43d5..eb26388b 100644
--- a/README.md
+++ b/README.md
@@ -1,4 +1,4 @@
-[](https://pub.dartlang.org/packages/getflutter) [](https://travis-ci.com/ionicfirebaseapp/getflutter) [](https://opensource.org/licenses/MIT) [](https://github.com/ionicfirebaseapp/getflutter/blob/master/LICENSE) [](https://www.getflutter.dev) [](https://twitter.com/getflutterdev)
+[](https://pub.dartlang.org/packages/getflutter) [](https://travis-ci.com/ionicfirebaseapp/getflutter) [](https://opensource.org/licenses/MIT) [](https://github.com/ionicfirebaseapp/getflutter/blob/master/LICENSE) [](https://gitter.im/getflutterdev/getflutter) [](https://twitter.com/getflutterdev)
@@ -7,7 +7,7 @@
-[**GetFlutter**](https://www.getflutter.dev) is a 100% Free Flutter open-source UI library that is built to make flutter development easier and joyful than ever. GetFlutter has 1000+ pre-build widgets that you could reuse to build both Flutter mobile app and web app development. Our motto to provide the best Flutter UI library to Flutter community to speed up their development process and build awesome apps with pre-build Flutter Library Components.
+[**GetFlutter**](https://www.getflutter.dev) is a 100% free Flutter open-source UI library that is built to make Flutter development easier and more joyful than ever. GetFlutter has 1000+ pre-build widgets that you can reuse to develop both Flutter mobile app and web app. Our motto is to provide the best Flutter UI library to the Flutter community to speed up their development process and build awesome apps with pre-build Flutter Library Components.
## Table of contents
@@ -23,7 +23,7 @@
## Screenshot
-
+
@@ -33,7 +33,7 @@ Read the [Getting started page](https://docs.getflutter.dev)
Forum [Support and discussion ](https://forum.getflutter.dev)
## Features
-In this beta release we are going to launch the library with following components :
+In this beta release, we are going to launch the library with the following components :
#### [Button](https://docs.getflutter.dev/gf-button) | [Badge](https://docs.getflutter.dev/gf-badge) | [Avatar](https://docs.getflutter.dev/gf-avatar) | [Image](https://docs.getflutter.dev/gf-image) | [Card](https://docs.getflutter.dev/gf-card) | [Carousel](https://docs.getflutter.dev/gf-carousel) | [Tile](https://docs.getflutter.dev/gf-tile) | [Tab](https://docs.getflutter.dev/gf-tab) | [Typography](https://docs.getflutter.dev/gf-typography)
@@ -53,22 +53,21 @@ In this beta release we are going to launch the library with following component
## Contributing
- GetFlutter is **100% free** and **open source**. We encourage and support an active, healthy community that accepts contributions from the public – including you. There are couple of ways in which you can contribute to the growing community of `getflutter`.
+ GetFlutter is **100% free** and **open source**. We encourage and support an active, healthy community that accepts contributions from the public – including you. There are a couple of ways in which you can contribute to the growing community of `getflutter`.
* Pick up any issue marked with ["good first issue"](https://github.com/ionicfirebaseapp/getflutter/issues?q=is%3Aopen+is%3Aissue+label%3A%22good+first+issue%22)
* Fix a bug
- * Write and improve some **documentation**. Documentation is very critical to us. We would like to if you can support to add support in multiple language for our docs.
+ * Write and improve some **documentation**. Documentation is very critical to us. We would appreciate help in adding multiple languages to our docs.
* If you are a developer, feel free to check out the source and submit pull requests.
* Dig into [**CONTRIBUTING.MD**](CONTRIBUTING.md), which covers submitting bugs, requesting new features, preparing your code for a pull request, etc.
- * Please don't forget to **like**, **follow**, and **star our repo**! Join our growing [community](http://forum.getflutter.dev) to keep up to date with the latest Get Flutter development.
+ * Please don't forget to **like**, **follow**, and **star our repo**! Join our growing [community](http://forum.getflutter.dev) to keep up to date with the latest GetFlutter development.
* Not sure what to work on? [**We've got lots ideas.**](https://roadmap.getflutter.dev)
## Documentation
[**Installation Guide**](https://docs.getflutter.dev)
-
-[**NOTE**] Our library will also work on flutter web but since flutter didn't released stable version for Flutter web and it is still in Beta release so you might get some rendering problem and hence we will update our library as flutter comes with the stable release for Flutter Web.
+
### Social Media
@@ -82,4 +81,4 @@ Instagram:
## Copyright-and-license
- Code and documentation copyright 2017-2020 the [GETFLUTTER Authors](https://www.getflutter.dev) and [IONICFIREBASEAPP](https://ionicfirebaseapp.com) Code released under the [MIT License]. Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).
+ Code and documentation Copyright 2017-2020 the [GETFLUTTER Authors](https://www.getflutter.dev) and [IONICFIREBASEAPP](https://ionicfirebaseapp.com) Code released under the [MIT License]. Docs released under [Creative Commons](https://creativecommons.org/licenses/by/3.0/).
diff --git a/example/lib/main.dart b/example/lib/main.dart
index 64efdd4d..abced5e8 100644
--- a/example/lib/main.dart
+++ b/example/lib/main.dart
@@ -1,28 +1,5 @@
import 'package:flutter/material.dart';
-import 'package:getflutter/colors/gf_color.dart';
-import 'package:getflutter/components/button/gf_button.dart';
-import 'package:getflutter/components/badge/gf_button_badge.dart';
-import 'package:getflutter/components/avatar/gf_avatar.dart';
-import 'package:getflutter/components/tabs/gf_segment_tabs.dart';
import 'package:getflutter/getflutter.dart';
-import 'package:getflutter/shape/gf_button_shape.dart';
-import 'package:flutter/cupertino.dart';
-import 'package:getflutter/components/toast/gf_toast.dart';
-import 'package:getflutter/components/list_tile/gf_list_tile.dart';
-import 'package:getflutter/components/button/gf_button_bar.dart';
-import 'package:getflutter/components/typography/gf_typography.dart';
-import 'package:getflutter/types/gf_typography_type.dart';
-import 'package:getflutter/components/toast/gf_floating_widget.dart';
-import 'package:getflutter/components/drawer/gf_drawer.dart';
-import 'package:getflutter/components/drawer/gf_drawer_header.dart';
-import 'package:getflutter/components/button/gf_icon_button.dart';
-import 'package:getflutter/components/image/gf_image_overlay.dart';
-import 'package:getflutter/components/card/gf_card.dart';
-import 'package:getflutter/components/tabs/gf_tabs.dart';
-import 'package:getflutter/components/tabs/gf_tabBarView.dart';
-import 'package:getflutter/types/gf_button_type.dart';
-import 'package:getflutter/position/gf_position.dart';
-import 'dart:io';
final List imageList = [
"https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg",
@@ -69,7 +46,6 @@ class _MyHomePageState extends State
void initState() {
super.initState();
tabController = TabController(length: 3, vsync: this);
- _searchQuery = new TextEditingController();
}
@override
@@ -80,101 +56,10 @@ class _MyHomePageState extends State
bool switchValue = true;
bool showToast = false;
-
Widget appBarTitle = new Text("UI Kit");
Icon actionIcon = new Icon(Icons.search);
- TextEditingController _searchQuery;
- bool _isSearching = false;
- String searchQuery = "Search query";
-
- void _startSearch() {
- ModalRoute.of(context)
- .addLocalHistoryEntry(new LocalHistoryEntry(onRemove: _stopSearching));
-
- setState(() {
- _isSearching = true;
- });
- }
-
- void _stopSearching() {
- _clearSearchQuery();
-
- setState(() {
- _isSearching = false;
- });
- }
-
- void _clearSearchQuery() {
- setState(() {
- _searchQuery.clear();
- updateSearchQuery("Search query");
- });
- }
-
- Widget _buildTitle(BuildContext context) {
- var horizontalTitleAlignment =
- Platform.isIOS ? CrossAxisAlignment.center : CrossAxisAlignment.start;
-
- return new InkWell(
- onTap: () => scaffoldKey.currentState.openDrawer(),
- child: new Padding(
- padding: const EdgeInsets.symmetric(horizontal: 12.0),
- child: new Column(
- mainAxisAlignment: MainAxisAlignment.center,
- crossAxisAlignment: horizontalTitleAlignment,
- children: [
- const Text('Seach box'),
- ],
- ),
- ),
- );
- }
-
- Widget _buildSearchField() {
- return new TextField(
- controller: _searchQuery,
- autofocus: true,
- decoration: const InputDecoration(
- hintText: 'Search...',
- border: InputBorder.none,
- hintStyle: const TextStyle(color: Colors.white30),
- ),
- style: const TextStyle(color: Colors.white, fontSize: 16.0),
- onChanged: updateSearchQuery,
- );
- }
-
- void updateSearchQuery(String newQuery) {
- setState(() {
- searchQuery = newQuery;
- });
- print("search query " + newQuery);
- }
-
- List _buildActions() {
- if (_isSearching) {
- return [
- new IconButton(
- icon: const Icon(Icons.clear),
- onPressed: () {
- if (_searchQuery == null || _searchQuery.text.isEmpty) {
- Navigator.pop(context);
- return;
- }
- _clearSearchQuery();
- },
- ),
- ];
- }
-
- return [
- new IconButton(
- icon: const Icon(Icons.search),
- onPressed: _startSearch,
- ),
- ];
- }
+ List list = ["Flutter", "Flutterjjk", "Flutterhy", "jhFlutter"];
@override
Widget build(BuildContext context) {
@@ -239,50 +124,32 @@ class _MyHomePageState extends State
],
),
),
- appBar: AppBar(
- leading: _isSearching ? const BackButton() : null,
- title: _isSearching ? _buildSearchField() : _buildTitle(context),
- actions: _buildActions(),
- ),
-// GFAppBar(
-//// backgroundColor: Colors.tealAccent,
+
+ appBar: GFAppBar(
+ backgroundColor: Colors.teal,
// centerTitle: true,
-//// leading: GFIconButton(icon: Icon(Icons.directions_bus), onPressed: (){}),
-// title: appBarTitle,
-//// bottom: TabBar(
-//// controller: tabController,
-//// tabs: [
-//// Tab(icon: Icon(Icons.directions_car)),
-//// Tab(icon: Icon(Icons.directions_transit)),
-//// Tab(icon: Icon(Icons.directions_bike)),
-//// ],
-//// ),
-// actions: [
-// new IconButton(
-// icon: actionIcon,
-// onPressed: () {
-// setState(() {
-// if (this.actionIcon.icon == Icons.search) {
-// this.actionIcon = new Icon(Icons.close);
-// this.appBarTitle = new TextField(
-// style: new TextStyle(
-// color: Colors.white,
-// ),
-// decoration: new InputDecoration(
-// prefixIcon: new Icon(Icons.search, color: Colors.white),
-// hintText: "Search...",
-// hintStyle: new TextStyle(color: Colors.white)),
-// );
-// } else {
-// this.actionIcon = new Icon(Icons.search);
-// this.appBarTitle = new Text("UI Kit");
-// }
-// });
-// },
-// ),
-// ],
-// ),
-// backgroundColor: Colors.teal,
+// leading: GFIconButton(icon: Icon(Icons.directions_bus), onPressed: (){}),
+ title: Text("UI Kit"),
+// bottom: TabBar(
+// controller: tabController,
+// tabs: [
+// Tab(icon: Icon(Icons.directions_car)),
+// Tab(icon: Icon(Icons.directions_transit)),
+// Tab(icon: Icon(Icons.directions_bike)),
+// ],
+// ),
+// searchBar: true,
+// searchHintText: "aaaaaaa",
+// searchHintStyle: TextStyle(fontSize: 18.0, color: Colors.redAccent),
+// searchStyle: TextStyle(fontSize: 10.0, color: Colors.green),
+// searchBarColorTheme: Colors.greenAccent,
+
+ actions: [
+ GFIconButton(icon: Icon(Icons.access_time), onPressed: () {}),
+ GFIconButton(icon: Icon(Icons.favorite), onPressed: null),
+ ],
+ ),
+// backgroundColor: Colors.blueGrey,
body:
// GFTabBarView(
// height: 200.0,
@@ -303,93 +170,147 @@ class _MyHomePageState extends State
// color: GFColor.secondary,
),
- GFCard(
- content: Column(
- children: [
- GFTypography(
- text: 'Toast',
- type: GFTypographyType.typo6,
- ),
- SizedBox(
- height: 20,
- ),
- SizedBox(
- height: 20,
- ),
- GFToast(
- text: 'Happy New Year',
- button: GFButton(
- onPressed: () {
- print("dfr");
- },
- text: 'OK',
- type: GFButtonType.outline,
- color: GFColor.warning,
- ),
- ),
- ],
- ),
- ),
-
- GFCard(
- content: Column(
- children: [
- GFTypography(
- text: 'Floating Toast',
- type: GFTypographyType.typo6,
- ),
- GFFloatingWidget(
- verticalPosition: 100,
- child: showToast
- ? GFToast(
- width: 300,
- text: 'Happy New Year',
- button: GFButton(
- onPressed: () {
- print("df");
- },
- text: 'OK',
- type: GFButtonType.outline,
- color: GFColor.warning,
- ),
- )
- : Container(),
- body: Column(
- crossAxisAlignment: CrossAxisAlignment.center,
- children: [
- Container(
- alignment: Alignment.center,
- child: GFButton(
- onPressed: () {
- setState(() {
- showToast = !showToast;
- });
- },
- text: 'Click to View the toast',
- type: GFButtonType.outline,
- color: GFColor.warning,
- ),
- )
- ],
- ))
- ],
- ),
- ),
+// GFSearchBar(
+// dataList: list,
+// hideSearchBoxWhenItemSelected: false,
+// listContainerHeight: MediaQuery.of(context).size.height / 4,
+// queryBuilder: (query, list) {
+// return list
+// .where((item) => item.username
+// .toLowerCase()
+// .contains(query.toLowerCase()))
+// .toList();
+// },
+// popupListItemBuilder: (item) {
+// return item;
+// },
+//// selectedItemBuilder: (selectedItem, deleteSelectedItem) {
+//// return SelectedItemWidget(selectedItem, deleteSelectedItem);
+//// },
+// // widget customization
+// noItemsFoundWidget: Container(child: Text("fgv"),),
+// textFieldBuilder: (controller, focusNode) {
+// return Padding(
+// padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
+// child: TextField(
+// controller: controller,
+// focusNode: focusNode,
+// style: TextStyle(fontSize: 16, color: Colors.grey[600]),
+// decoration: InputDecoration(
+// enabledBorder: const OutlineInputBorder(
+// borderSide: BorderSide(
+// color: Color(0x4437474F),
+// ),
+// ),
+// focusedBorder: OutlineInputBorder(
+// borderSide: BorderSide(color: Theme.of(context).primaryColor),
+// ),
+// suffixIcon: Icon(Icons.search),
+// border: InputBorder.none,
+// hintText: "Search here...",
+// contentPadding: const EdgeInsets.only(
+// left: 16,
+// right: 20,
+// top: 14,
+// bottom: 14,
+// ),
+// ),
+// ));
+// },
+// onItemSelected: (item) {
+// setState(() {
+//// _selectedItem = item;
+// });
+// },
+// ),
-// Container(
-// height: 130.0,
-// width: 105.0,
-// decoration: BoxDecoration(
-// borderRadius: BorderRadius.circular(8.0),
-// gradient: LinearGradient(
-// begin: FractionalOffset.bottomLeft,
-// end: FractionalOffset.topRight,
-// colors: [
-// const Color(0x5a0b486b),
-// const Color(0xFFF56217),
-// ])),
+// GFCard(
+// content: Column(
+// children: [
+// GFTypography(
+// text: 'Toast',
+// type: GFTypographyType.typo6,
+// ),
+// SizedBox(
+// height: 20,
+// ),
+// SizedBox(
+// height: 20,
+// ),
+// GFToast(
+// text: 'Happy New Year',
+// button: GFButton(
+// onPressed: () {
+// print("dfr");
+// },
+// text: 'OK',
+// type: GFButtonType.outline,
+// color: GFColor.warning,
+// ),
+// ),
+// ],
+// ),
// ),
//
+// GFCard(
+// content: Column(
+// children: [
+// GFTypography(
+// text: 'Floating Toast',
+// type: GFTypographyType.typo6,
+// ),
+// GFFloatingWidget(
+// verticalPosition: 100,
+// child: showToast
+// ? GFToast(
+// width: 300,
+// text: 'Happy New Year',
+// button: GFButton(
+// onPressed: () {
+// print("df");
+// },
+// text: 'OK',
+// type: GFButtonType.outline,
+// color: GFColor.warning,
+// ),
+// )
+// : Container(),
+// body: Column(
+// crossAxisAlignment: CrossAxisAlignment.center,
+// children: [
+// Container(
+// alignment: Alignment.center,
+// child: GFButton(
+// onPressed: () {
+// setState(() {
+// showToast = !showToast;
+// });
+// },
+// text: 'Click to View the toast',
+// type: GFButtonType.outline,
+// color: GFColor.warning,
+// ),
+// )
+// ],
+// ))
+// ],
+// ),
+// ),
+
+ Container(
+ height: 130.0,
+ width: 105.0,
+ decoration: BoxDecoration(
+ borderRadius: BorderRadius.circular(8.0),
+ gradient: LinearGradient(
+ begin: FractionalOffset.bottomLeft,
+ end: FractionalOffset.topRight,
+ colors: [
+ const Color(0x5a0b486b),
+ const Color(0xFFF56217),
+ ]),
+ ),
+ ),
// GFCard(
// content: Column(
@@ -658,9 +579,9 @@ class _MyHomePageState extends State
children: [
GFImageOverlay(
height: 200.0,
- width: 200.0,
+ width: 304.0,
image: AssetImage("lib/assets/food.jpeg"),
- boxFit: BoxFit.fill,
+ boxFit: BoxFit.cover,
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.67), BlendMode.darken),
// shape: BoxShape.circle,
@@ -809,28 +730,28 @@ class _MyHomePageState extends State
// backgroundImage: NetworkImage("https://cdn.pixabay.com/photo/2017/12/03/18/04/christmas-balls-2995437_960_720.jpg"),
// ),
- GFSegmentTabs(
- tabController: tabController,
- initialIndex: 0,
- length: 3,
- tabs: [
- Text(
- "Tab1",
- ),
- Text(
- "Tab2",
- ),
- Text(
- "Tab3",
- ),
- ],
- ),
-
- GFTabBarView(controller: tabController, children: [
- Container(color: Colors.red),
- Container(color: Colors.green),
- Container(color: Colors.blue)
- ]),
+// GFSegmentTabs(
+// tabController: tabController,
+// initialIndex: 0,
+// length: 3,
+// tabs: [
+// Text(
+// "Tab1",
+// ),
+// Text(
+// "Tab2",
+// ),
+// Text(
+// "Tab3",
+// ),
+// ],
+// ),
+//
+// GFTabBarView(controller: tabController, children: [
+// Container(color: Colors.red),
+// Container(color: Colors.green),
+// Container(color: Colors.blue)
+// ]),
// GFItemsCarousel(
// rowCount: 3,
@@ -848,36 +769,33 @@ class _MyHomePageState extends State
// ).toList(),
// ),
//
-// GFCarousel(
-//// pagerSize: 12.0,
-//// activeIndicator: Colors.pink,
-//// passiveIndicator: Colors.pink.withOpacity(0.4),
-//// viewportFraction: 1.0,
-//// aspectRatio: 1.0,
-//// autoPlay: true,
-//// enlargeMainPage: true,
-//// pagination: true,
-// items: imageList.map(
-// (url) {
-// return Container(
-// margin: EdgeInsets.all(8.0),
-// child: ClipRRect(
-// borderRadius: BorderRadius.all(Radius.circular(5.0)),
-// child: Image.network(
-// url,
-// fit: BoxFit.cover,
-// width: 1000.0
-// ),
-// ),
-// );
-// },
-// ).toList(),
-// onPageChanged: (index) {
-// setState(() {
-// index;
-// });
-// },
-// ),
+ GFCarousel(
+// pagerSize: 12.0,
+// activeIndicator: Colors.pink,
+// passiveIndicator: Colors.pink.withOpacity(0.4),
+// viewportFraction: 1.0,
+// aspectRatio: 1.0,
+// autoPlay: true,
+// enlargeMainPage: true,
+// pagination: true,
+ items: imageList.map(
+ (url) {
+ return Container(
+ margin: EdgeInsets.all(8.0),
+ child: ClipRRect(
+ borderRadius: BorderRadius.all(Radius.circular(5.0)),
+ child:
+ Image.network(url, fit: BoxFit.cover, width: 1000.0),
+ ),
+ );
+ },
+ ).toList(),
+ onPageChanged: (index) {
+ setState(() {
+ // index;
+ });
+ },
+ ),
GFTabs(
initialIndex: 0,
@@ -955,42 +873,47 @@ class _MyHomePageState extends State
// ),
GFCard(
+ gradient: LinearGradient(
+ begin: FractionalOffset.bottomLeft,
+ end: FractionalOffset.topRight,
+ colors: [
+ const Color(0x5a0b486b),
+ const Color(0xFFF56217),
+ ]),
boxFit: BoxFit.fill,
colorFilter: new ColorFilter.mode(
Colors.black.withOpacity(0.67), BlendMode.darken),
- image: Image.asset(
- "lib/assets/img.png",
- fit: BoxFit.fitWidth,
- width: 400.0,
- ),
+// image: Image.asset(
+// "lib/assets/img.png",
+// fit: BoxFit.fitWidth,
+// width: 400.0,
+// ),
// imageOverlay: AssetImage("lib/assets/food.jpeg"),
titlePosition: GFPosition.end,
title: GFListTile(
avatar: GFAvatar(
+ backgroundColor: Color(0x5a0b486b),
child: Text("tb"),
),
title: Text(
- 'title',
- style: TextStyle(color: Colors.grey),
+ 'Flutter',
),
subTitle: Text(
- 'subtitle'
- "Flutter Flutter is Google's mobile UI framework for crafting"
- "Flutter Flutter is Google's mobile UI framework for crafting",
- style: TextStyle(color: Colors.grey),
+ "Flutter is Google's mobile UI",
),
+ description: Text(
+ "Flutter Flutter is Google's mobile UI framework for crafting"),
icon: GFIconButton(
onPressed: null,
icon: Icon(Icons.favorite),
type: GFButtonType.transparent,
),
),
+// borderOnForeground: true,
content: Text(
- "Flutter Flutter is Google's mobile UI framework for crafting"
"Flutter Flutter is Google's mobile UI framework for crafting"
"Flutter Flutter is Google's mobile UI framework for crafting"
"Flutter Flutter is Google's mobile UI framework for crafting",
- style: TextStyle(color: Colors.grey),
),
buttonBar: GFButtonBar(
children: [
diff --git a/lib/components/accordian/gf_accordian.dart b/lib/components/accordian/gf_accordian.dart
new file mode 100644
index 00000000..f9ea107d
--- /dev/null
+++ b/lib/components/accordian/gf_accordian.dart
@@ -0,0 +1,148 @@
+import 'package:flutter/material.dart';
+import 'package:getflutter/colors/gf_color.dart';
+
+class GFAccordion extends StatefulWidget {
+
+ const GFAccordion(
+ {Key key,
+ this.child,
+ this.content,
+ this.titlebackgroundColor,
+ this.collapsedIcon = const Icon(Icons.keyboard_arrow_down),
+ this.expandedIcon =
+ const Icon(Icons.keyboard_arrow_up, color: Colors.red),
+ this.title,
+ this.textStyle = const TextStyle(color: Colors.black, fontSize: 16),
+ this.titlePadding,
+ this.descriptionPadding,
+ this.descriptionbackgroundColor,
+ this.contentChild,
+ this.margin})
+ : super(key: key);
+
+ /// child of type [Widget]is alternative to title key. title will get priority over child
+ final Widget child;
+
+ /// content of type[String] which shows the messages after the [GFAccordion] is expanded
+ final String content;
+
+ /// contentChild of type [Widget]is alternative to content key. content will get priority over contentChild
+ final Widget contentChild;
+
+ /// type of [Color] or [GFColor] which is used to change the background color of the [GFAccordion] title
+ final dynamic titlebackgroundColor;
+
+ ///collapsedIcon of type [Widget] which is used to show when the [GFAccordion] is collapsed
+ final Widget collapsedIcon;
+
+ ///expandedIcon of type[Widget] which is used when the [GFAccordion] is expanded
+ final Widget expandedIcon;
+
+ /// text of type [String] is alternative to child. text will get priority over child
+ final String title;
+
+ /// textStyle of type [textStyle] will be applicable to text only and not for the child
+ final TextStyle textStyle;
+
+ ///titlePadding of type [EdgeInsets] which is used to set the padding of the [GFAccordion] title
+ final EdgeInsets titlePadding;
+
+ ///descriptionPadding of type [EdgeInsets] which is used to set the padding of the [GFAccordion] description
+ final EdgeInsets descriptionPadding;
+
+ /// type of [Color] or [GFColor] which is used to change the background color of the [GFAccordion] description
+ final dynamic descriptionbackgroundColor;
+
+ ///margin of type [EdgeInsets] which is used to set the margin of the [GFAccordion]
+ final EdgeInsets margin;
+
+ @override
+ _GFAccordionState createState() => _GFAccordionState();
+}
+
+class _GFAccordionState extends State
+ with TickerProviderStateMixin {
+ AnimationController animationController;
+ AnimationController controller;
+ Animation offset;
+
+ @override
+ void initState() {
+ super.initState();
+ animationController =
+ AnimationController(duration: Duration(seconds: 2), vsync: this);
+ controller =
+ AnimationController(vsync: this, duration: Duration(milliseconds: 300));
+ offset = Tween(begin: Offset(0.0, -0.06), end: Offset.zero).animate(
+ CurvedAnimation(
+ parent: controller,
+ curve: Curves.fastOutSlowIn,
+ ),
+ );
+ }
+
+ bool showAccordion = false;
+
+ @override
+ Widget build(BuildContext context) {
+ return Container(
+ margin: widget.margin != null ? widget.margin : EdgeInsets.all(10),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ GestureDetector(
+ onTap: () {
+ setState(() {
+ switch (controller.status) {
+ case AnimationStatus.completed:
+ controller.forward(from: 0);
+ break;
+ case AnimationStatus.dismissed:
+ controller.forward();
+ break;
+ default:
+ }
+ showAccordion = !showAccordion;
+ });
+ },
+ child: Container(
+ color: widget.titlebackgroundColor != null
+ ? widget.titlebackgroundColor
+ : Colors.white,
+ padding: widget.titlePadding != null
+ ? widget.titlePadding
+ : EdgeInsets.all(10),
+ child: Row(
+ mainAxisAlignment: MainAxisAlignment.spaceBetween,
+ children: [
+ Expanded(
+ child: widget.title != null
+ ? Text(widget.title, style: widget.textStyle)
+ : (widget.child ?? Container()),
+ ),
+ showAccordion ? widget.expandedIcon : widget.collapsedIcon
+ ],
+ ),
+ ),
+ ),
+ showAccordion
+ ? Container(
+ width: MediaQuery.of(context).size.width,
+ color: widget.descriptionbackgroundColor != null
+ ? widget.descriptionbackgroundColor
+ : Colors.white70,
+ padding: widget.descriptionPadding != null
+ ? widget.descriptionPadding
+ : EdgeInsets.all(10),
+ child: SlideTransition(
+ position: offset,
+ child: widget.content != null
+ ? Text(widget.content)
+ : (widget.contentChild ?? Container()),
+ ))
+ : Container()
+ ],
+ ),
+ );
+ }
+}
diff --git a/lib/components/alert/gf_alert.dart b/lib/components/alert/gf_alert.dart
new file mode 100644
index 00000000..52618f2f
--- /dev/null
+++ b/lib/components/alert/gf_alert.dart
@@ -0,0 +1,149 @@
+import 'package:flutter/material.dart';
+import 'package:flutter/widgets.dart';
+import 'package:getflutter/getflutter.dart';
+import 'package:getflutter/types/gf_alert_type.dart';
+
+class GFAlert extends StatefulWidget {
+
+ /// Alert has to be wrap inside the body like [GFFloatingWidget]. See [GFFloatingWidget]
+ GFAlert(
+ {Key key,
+ this.child,
+ this.backgroundColor,
+ this.content,
+ this.width,
+ this.type = GFAlertType.basic,
+ this.alignment,
+ this.contentChild,
+ this.title,
+ this.bottombar,
+ this.animationDuration = const Duration(milliseconds: 300),
+ this.textStyle = const TextStyle(color: Colors.black87),
+ this.titleTextStyle = const TextStyle(
+ color: Colors.black87, fontSize: 17, fontWeight: FontWeight.w500)})
+ : super(key: key);
+
+ /// child of type [Widget]is alternative to text key. text will get priority over child
+ final Widget child;
+
+ /// title of type [String] used to descripe the title of the [GFAlert]
+ final String title;
+
+ /// child of type [Widget]is alternative to title key. title will get priority over contentchild
+ final Widget contentChild;
+
+ /// title of type [String] used to describe the content of the [GFAlert]
+ final String content;
+
+ final TextStyle titleTextStyle;
+
+ ///pass color of type [Color] or [GFColor] for background of [GFAlert]
+ final dynamic backgroundColor;
+
+ /// textStyle of type [textStyle] will be applicable to text only and not for the child
+ final TextStyle textStyle;
+
+ /// width of type [double] used to control the width of the [GFAlert]
+ final double width;
+
+ ///type of [GFAlertType] which takes the type ie, basic, rounded and fullWidth for the [GFAlert]
+ final GFAlertType type;
+
+ ///type of [Duration] which takes the duration of the fade in animation
+ final Duration animationDuration;
+
+ /// type of [Alignment] used to align the text inside the toast
+ final Alignment alignment;
+
+ ///type of [Widget] used for the buttons ie, OK, Cancel for the action in [GFAlert]
+ final Widget bottombar;
+ @override
+ _GFAlertState createState() => _GFAlertState();
+}
+
+class _GFAlertState extends State with TickerProviderStateMixin {
+ AnimationController animationController;
+ Animation animation;
+
+ @override
+ void initState() {
+ animationController = AnimationController(
+ duration: const Duration(milliseconds: 300), vsync: this);
+ animation = CurvedAnimation(
+ parent: animationController, curve: Curves.fastOutSlowIn);
+
+ animationController.forward();
+ super.initState();
+ }
+
+ @override
+ void dispose() {
+ animationController.dispose();
+ super.dispose();
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ return Stack(
+ children: [
+ Container(
+ height: MediaQuery.of(context).size.height,
+ ),
+ FadeTransition(
+ opacity: animation,
+ child: Column(
+ children: [
+ Container(
+ width: widget.type == GFAlertType.fullWidth
+ ? MediaQuery.of(context).size.width
+ : widget.width,
+ constraints: BoxConstraints(minHeight: 50.0),
+ margin: widget.type == GFAlertType.fullWidth
+ ? EdgeInsets.only(left: 0, right: 0)
+ : EdgeInsets.only(left: 20, right: 20),
+ padding: EdgeInsets.all(15),
+ decoration: BoxDecoration(
+ borderRadius: widget.type == GFAlertType.basic
+ ? BorderRadius.circular(3.0)
+ : widget.type == GFAlertType.rounded
+ ? BorderRadius.circular(10.0)
+ : BorderRadius.zero,
+ color: widget.backgroundColor != null
+ ? GFColors.getGFColor(widget.backgroundColor)
+ : GFColors.getGFColor(GFColor.white),
+ boxShadow: [
+ BoxShadow(
+ color: Colors.black.withOpacity(0.40),
+ blurRadius: 3.0)
+ ]),
+ child: Column(
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ widget.title != null
+ ? Text(widget.title, style: widget.titleTextStyle)
+ : (widget.child ?? Container()),
+ SizedBox(
+ height: 10,
+ ),
+ Align(
+ alignment: widget.alignment != null
+ ? widget.alignment
+ : Alignment.topLeft,
+ child: widget.content != null
+ ? Text(widget.content, style: widget.textStyle)
+ : (widget.contentChild ?? Container()),
+ ),
+ SizedBox(
+ height: 10,
+ ),
+ widget.bottombar != null ? widget.bottombar : Container(),
+ ],
+ ),
+ ),
+ ],
+ ),
+ ),
+ ],
+ );
+ }
+}
diff --git a/lib/components/appbar/gf_appbar.dart b/lib/components/appbar/gf_appbar.dart
index f0326879..73a6900f 100644
--- a/lib/components/appbar/gf_appbar.dart
+++ b/lib/components/appbar/gf_appbar.dart
@@ -3,6 +3,7 @@ import 'package:flutter/rendering.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter/material.dart';
+import 'package:getflutter/getflutter.dart';
/// An app bar consists of a toolbar and potentially other widgets, such as a
/// [GFTabBar][TabBar] and a [FlexibleSpaceBar].
@@ -41,6 +42,17 @@ class GFAppBar extends StatefulWidget implements PreferredSizeWidget {
this.titleSpacing = NavigationToolbar.kMiddleSpacing,
this.toolbarOpacity = 1.0,
this.bottomOpacity = 1.0,
+ this.searchBar = false,
+ this.searchHintText = 'Search...',
+ this.searchHintStyle = const TextStyle(color: Colors.white, fontSize: 14.0),
+ this.searchTextStyle = const TextStyle(
+ color: Colors.white,
+ ),
+ this.searchBarColorTheme = Colors.white,
+ this.searchController,
+ this.onTap,
+ this.onChanged,
+ this.onSubmitted,
}) : assert(automaticallyImplyLeading != null),
assert(elevation == null || elevation >= 0.0),
assert(primary != null),
@@ -192,6 +204,67 @@ class GFAppBar extends StatefulWidget implements PreferredSizeWidget {
@override
final Size preferredSize;
+ /// If true, displays search bar in the title space
+ final bool searchBar;
+
+ /// It takes text to displays the search bar hint text
+ final String searchHintText;
+
+ /// It styles the [searchHintText]
+ final TextStyle searchHintStyle;
+
+ /// It styles the search text
+ final TextStyle searchTextStyle;
+
+ /// It defines the search bar icons color
+ final Color searchBarColorTheme;
+
+ /// {@macro flutter.widgets.editableText.onChanged}
+ ///
+ /// See also:
+ ///
+ /// * [inputFormatters], which are called before [onChanged]
+ /// runs and can validate and change ("format") the input value.
+ /// * [onEditingComplete], [onSubmitted], [onSelectionChanged]:
+ /// which are more specialized input change notifications.
+ final ValueChanged onChanged;
+
+ /// {@macro flutter.widgets.editableText.onSubmitted}
+ ///
+ /// See also:
+ ///
+ /// * [EditableText.onSubmitted] for an example of how to handle moving to
+ /// the next/previous field when using [TextInputAction.next] and
+ /// [TextInputAction.previous] for [textInputAction].
+ final ValueChanged onSubmitted;
+
+ /// Controls the text being edited.
+ ///
+ /// If null, this widget will create its own [TextEditingController].
+ final TextEditingController searchController;
+
+ /// {@template flutter.material.textfield.onTap}
+ /// Called for each distinct tap except for every second tap of a double tap.
+ ///
+ /// The text field builds a [GestureDetector] to handle input events like tap,
+ /// to trigger focus requests, to move the caret, adjust the selection, etc.
+ /// Handling some of those events by wrapping the text field with a competing
+ /// GestureDetector is problematic.
+ ///
+ /// To unconditionally handle taps, without interfering with the text field's
+ /// internal gesture detector, provide this callback.
+ ///
+ /// If the text field is created with [enabled] false, taps will not be
+ /// recognized.
+ ///
+ /// To be notified when the text field gains or loses the focus, provide a
+ /// [focusNode] and add a listener to that.
+ ///
+ /// To listen to arbitrary pointer events without competing with the
+ /// text field's internal gesture detector, use a [Listener].
+ /// {@endtemplate}
+ final GestureTapCallback onTap;
+
bool _getEffectiveCenterTitle(ThemeData theme) {
if (centerTitle != null) return centerTitle;
assert(theme.platform != null);
@@ -221,6 +294,9 @@ class _GFAppBarState extends State {
Scaffold.of(context).openEndDrawer();
}
+ Widget searchBar;
+ bool showSearchBar = true;
+
@override
Widget build(BuildContext context) {
assert(!widget.primary || debugCheckHasMediaQuery(context));
@@ -303,7 +379,7 @@ class _GFAppBarState extends State {
overflow: TextOverflow.ellipsis,
child: Semantics(
namesRoute: namesRoute,
- child: _GFAppBarTitleBox(child: title),
+ child: GFAppBarTitleBar(child: title),
header: true,
),
);
@@ -332,9 +408,66 @@ class _GFAppBarState extends State {
);
}
+ searchBar = ListTile(
+ contentPadding: EdgeInsets.zero,
+ title: TextField(
+ cursorColor: widget.searchBarColorTheme,
+ style: widget.searchTextStyle,
+ decoration: new InputDecoration(
+ prefixIcon: new Icon(
+ Icons.search,
+ color: widget.searchBarColorTheme,
+ size: 18.0,
+ ),
+ hintText: widget.searchHintText,
+ hintStyle: widget.searchHintStyle,
+ focusedBorder: UnderlineInputBorder(
+ borderSide: BorderSide(width: 1, color: widget.searchBarColorTheme),
+ ),
+ ),
+ onTap: widget.onTap,
+ onChanged: widget.onChanged,
+ controller: widget.searchController,
+ onSubmitted: widget.onSubmitted,
+ ),
+ trailing: GFIconButton(
+ icon: Icon(
+ Icons.close,
+ color: widget.searchBarColorTheme,
+ size: 20.0,
+ ),
+ type: GFButtonType.transparent,
+ onPressed: () {
+ setState(() {
+ showSearchBar = !showSearchBar;
+ });
+ },
+ ),
+ );
+
+ if (!showSearchBar) {
+ searchBar = ListTile(
+ contentPadding: EdgeInsets.zero,
+ title: title,
+ trailing: GFIconButton(
+ icon: Icon(
+ Icons.search,
+ color: widget.searchBarColorTheme,
+ size: 20.0,
+ ),
+ type: GFButtonType.transparent,
+ onPressed: () {
+ setState(() {
+ showSearchBar = !showSearchBar;
+ });
+ },
+ ),
+ );
+ }
+
final Widget toolbar = NavigationToolbar(
leading: leading,
- middle: title,
+ middle: widget.searchBar ? searchBar : title,
trailing: actions,
centerMiddle: widget._getEffectiveCenterTitle(theme),
middleSpacing: widget.titleSpacing,
@@ -450,27 +583,27 @@ class _ToolbarContainerLayout extends SingleChildLayoutDelegate {
// Layout the GFAppBar's title with unconstrained height, vertically
// center it within its (NavigationToolbar) parent, and allow the
// parent to constrain the title's actual height.
-class _GFAppBarTitleBox extends SingleChildRenderObjectWidget {
- const _GFAppBarTitleBox({Key key, @required Widget child})
+class GFAppBarTitleBar extends SingleChildRenderObjectWidget {
+ const GFAppBarTitleBar({Key key, @required Widget child})
: assert(child != null),
super(key: key, child: child);
@override
- _RenderGFAppBarTitleBox createRenderObject(BuildContext context) {
- return _RenderGFAppBarTitleBox(
+ RenderGFAppBarTitleBar createRenderObject(BuildContext context) {
+ return RenderGFAppBarTitleBar(
textDirection: Directionality.of(context),
);
}
@override
void updateRenderObject(
- BuildContext context, _RenderGFAppBarTitleBox renderObject) {
+ BuildContext context, RenderGFAppBarTitleBar renderObject) {
renderObject.textDirection = Directionality.of(context);
}
}
-class _RenderGFAppBarTitleBox extends RenderAligningShiftedBox {
- _RenderGFAppBarTitleBox({
+class RenderGFAppBarTitleBar extends RenderAligningShiftedBox {
+ RenderGFAppBarTitleBar({
RenderBox child,
TextDirection textDirection,
}) : super(
diff --git a/lib/components/card/gf_card.dart b/lib/components/card/gf_card.dart
index 01ac1176..527dc97f 100644
--- a/lib/components/card/gf_card.dart
+++ b/lib/components/card/gf_card.dart
@@ -32,9 +32,14 @@ class GFCard extends StatelessWidget {
this.border,
this.boxFit,
this.colorFilter,
- this.height})
+ this.height,
+ this.gradient})
: assert(elevation == null || elevation >= 0.0),
assert(borderOnForeground != null),
+ assert(
+ color == null || gradient == null,
+ 'Cannot provide both a color and a decoration\n'
+ 'The color argument is just a shorthand for "decoration: new BoxDecoration(color: color)".'),
super(key: key);
/// defines the card's height
@@ -99,6 +104,8 @@ class GFCard extends StatelessWidget {
/// A border to draw above the [GFCard].
final Border border;
+ final LinearGradient gradient;
+
static const double _defaultElevation = 1.0;
static const Clip _defaultClipBehavior = Clip.none;
@@ -142,19 +149,29 @@ class GFCard extends StatelessWidget {
return Container(
height: height,
margin: margin ?? cardTheme.margin ?? const EdgeInsets.all(16.0),
- child: Material(
- type: MaterialType.card,
- color: color ?? cardTheme.color ?? Theme.of(context).cardColor,
- elevation: elevation ?? cardTheme.elevation ?? _defaultElevation,
- shape: shape ??
- cardTheme.shape ??
- const RoundedRectangleBorder(
- borderRadius: BorderRadius.all(Radius.circular(4.0)),
- ),
- borderOnForeground: borderOnForeground,
- clipBehavior:
- clipBehavior ?? cardTheme.clipBehavior ?? _defaultClipBehavior,
- child: imageOverlay == null ? cardChild : overlayImage),
+ decoration: gradient != null
+ ? BoxDecoration(
+ gradient: gradient,
+ borderRadius: BorderRadius.all(Radius.circular(4.0)),
+ )
+ : null,
+ child: gradient == null
+ ? Material(
+ type: MaterialType.card,
+ color: color ?? cardTheme.color ?? Theme.of(context).cardColor,
+ elevation: elevation ?? cardTheme.elevation ?? _defaultElevation,
+ shape: shape ??
+ cardTheme.shape ??
+ const RoundedRectangleBorder(
+ borderRadius: BorderRadius.all(Radius.circular(4.0)),
+ ),
+ borderOnForeground: borderOnForeground,
+ clipBehavior: clipBehavior ??
+ cardTheme.clipBehavior ??
+ _defaultClipBehavior,
+ child: imageOverlay == null ? cardChild : overlayImage,
+ )
+ : imageOverlay == null ? cardChild : overlayImage,
);
}
}
diff --git a/lib/components/search_bar/gf_search_bar.dart b/lib/components/search_bar/gf_search_bar.dart
index 4ce4e8a1..3e35cec3 100644
--- a/lib/components/search_bar/gf_search_bar.dart
+++ b/lib/components/search_bar/gf_search_bar.dart
@@ -1,8 +1,301 @@
import 'package:flutter/material.dart';
-class GFSearchBar extends StatelessWidget {
+typedef QueryListItemBuilder = Widget Function(T item);
+typedef OnItemSelected = void Function(T item);
+typedef SelectedItemBuilder = Widget Function(
+ T item,
+ VoidCallback deleteSelectedItem,
+);
+typedef QueryBuilder = List Function(
+ String query,
+ List list,
+);
+typedef TextFieldBuilder = Widget Function(
+ TextEditingController controller,
+ FocusNode focus,
+);
+
+class GFSearchBar extends StatefulWidget {
+ const GFSearchBar({
+ @required this.dataList,
+ @required this.popupListItemBuilder,
+ @required this.selectedItemBuilder,
+ @required this.queryBuilder,
+ Key key,
+ this.onItemSelected,
+ this.hideSearchBoxWhenItemSelected = false,
+ this.listContainerHeight,
+ this.noItemsFoundWidget,
+ this.textFieldBuilder,
+ }) : super(key: key);
+
+ final List dataList;
+ final QueryListItemBuilder popupListItemBuilder;
+ final SelectedItemBuilder selectedItemBuilder;
+ final bool hideSearchBoxWhenItemSelected;
+ final double listContainerHeight;
+ final QueryBuilder queryBuilder;
+ final TextFieldBuilder textFieldBuilder;
+ final Widget noItemsFoundWidget;
+
+ final OnItemSelected onItemSelected;
+
+ @override
+ MySingleChoiceSearchState createState() => MySingleChoiceSearchState();
+}
+
+class MySingleChoiceSearchState extends State> {
+ final _controller = TextEditingController();
+ List _list;
+ List _tempList;
+ bool isFocused;
+ FocusNode _focusNode;
+ ValueNotifier notifier;
+ bool isRequiredCheckFailed;
+ Widget textField;
+ OverlayEntry overlayEntry;
+ bool showTextBox = false;
+ double listContainerHeight;
+ final LayerLink _layerLink = LayerLink();
+ final double textBoxHeight = 48;
+ final TextEditingController textController = TextEditingController();
+
+ @override
+ void initState() {
+ super.initState();
+ init();
+ }
+
+ void init() {
+ _tempList = [];
+ notifier = ValueNotifier(null);
+ _focusNode = FocusNode();
+ isFocused = false;
+ _list = List.from(widget.dataList);
+ _tempList.addAll(_list);
+ _focusNode.addListener(() {
+ if (!_focusNode.hasFocus) {
+ _controller.clear();
+ if (overlayEntry != null) {
+ overlayEntry.remove();
+ }
+ overlayEntry = null;
+ } else {
+ _tempList
+ ..clear()
+ ..addAll(_list);
+ if (overlayEntry == null) {
+ onTap();
+ } else {
+ overlayEntry.markNeedsBuild();
+ }
+ }
+ });
+ _controller.addListener(() {
+ final text = _controller.text;
+ if (text.trim().isNotEmpty) {
+ _tempList.clear();
+ final filterList = widget.queryBuilder(text, widget.dataList);
+ if (filterList == null) {
+ throw Exception(
+ "Filtered List cannot be null. Pass empty list instead",
+ );
+ }
+ _tempList.addAll(filterList);
+ if (overlayEntry == null) {
+ onTap();
+ } else {
+ overlayEntry.markNeedsBuild();
+ }
+ } else {
+ _tempList
+ ..clear()
+ ..addAll(_list);
+ if (overlayEntry == null) {
+ onTap();
+ } else {
+ overlayEntry.markNeedsBuild();
+ }
+ }
+ });
+// KeyboardVisibilityNotification().addNewListener(
+// onChange: (visible) {
+// if (!visible) {
+// _focusNode.unfocus();
+// }
+// },
+// );
+ }
+
+ @override
+ void didUpdateWidget(GFSearchBar oldWidget) {
+ if (oldWidget.dataList != widget.dataList) {
+ init();
+ }
+ super.didUpdateWidget(oldWidget);
+ }
+
@override
Widget build(BuildContext context) {
- return Container();
+ listContainerHeight =
+ widget.listContainerHeight ?? MediaQuery.of(context).size.height / 4;
+ textField = widget.textFieldBuilder != null
+ ? widget.textFieldBuilder(_controller, _focusNode)
+ : Padding(
+ padding: const EdgeInsets.symmetric(vertical: 8, horizontal: 16),
+ child: TextField(
+ controller: _controller,
+ focusNode: _focusNode,
+ style: TextStyle(fontSize: 16, color: Colors.grey[600]),
+ decoration: InputDecoration(
+ enabledBorder: const OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Color(0x4437474F),
+ ),
+ ),
+ focusedBorder: OutlineInputBorder(
+ borderSide: BorderSide(
+ color: Theme.of(context).primaryColor,
+ ),
+ ),
+ suffixIcon: Icon(Icons.search),
+ border: InputBorder.none,
+ hintText: "Search here...",
+ contentPadding: const EdgeInsets.only(
+ left: 16,
+ right: 20,
+ top: 14,
+ bottom: 14,
+ ),
+ ),
+ ),
+ );
+
+ final column = Column(
+ mainAxisSize: MainAxisSize.min,
+ crossAxisAlignment: CrossAxisAlignment.start,
+ children: [
+ if (widget.hideSearchBoxWhenItemSelected && notifier.value != null)
+ const SizedBox(height: 0)
+ else
+ CompositedTransformTarget(
+ link: _layerLink,
+ child: textField,
+ ),
+ if (notifier.value != null)
+ Container(
+ decoration: BoxDecoration(
+ color: Colors.grey[200],
+ borderRadius: const BorderRadius.all(Radius.circular(4)),
+ ),
+ margin: const EdgeInsets.symmetric(horizontal: 16),
+ child: widget.selectedItemBuilder(
+ notifier.value,
+ onDeleteSelectedItem,
+ ),
+ ),
+ ],
+ );
+ return column;
+ }
+
+ void onDropDownItemTap(T item) {
+ if (overlayEntry != null) {
+ overlayEntry.remove();
+ }
+ overlayEntry = null;
+ _controller.clear();
+ _focusNode.unfocus();
+ setState(() {
+ notifier.value = item;
+ isFocused = false;
+ isRequiredCheckFailed = false;
+ });
+ if (widget.onItemSelected != null) {
+ widget.onItemSelected(item);
+ }
+ }
+
+ void onTap() {
+ final RenderBox textFieldRenderBox = context.findRenderObject();
+ final RenderBox overlay = Overlay.of(context).context.findRenderObject();
+ final width = textFieldRenderBox.size.width;
+ final position = RelativeRect.fromRect(
+ Rect.fromPoints(
+ textFieldRenderBox.localToGlobal(
+ textFieldRenderBox.size.topLeft(Offset.zero),
+ ancestor: overlay,
+ ),
+ textFieldRenderBox.localToGlobal(
+ textFieldRenderBox.size.topRight(Offset.zero),
+ ancestor: overlay,
+ ),
+ ),
+ Offset.zero & overlay.size,
+ );
+ overlayEntry = OverlayEntry(
+ builder: (context) {
+ final height = MediaQuery.of(context).size.height;
+ return Positioned(
+ left: position.left,
+ width: width,
+ child: CompositedTransformFollower(
+ offset: Offset(
+ 0,
+ height - position.bottom < listContainerHeight
+ ? (textBoxHeight + 6.0)
+ : -(listContainerHeight - 8.0),
+ ),
+ showWhenUnlinked: false,
+ link: _layerLink,
+ child: Container(
+ height: listContainerHeight,
+ margin: const EdgeInsets.symmetric(horizontal: 12),
+ child: Card(
+ color: Colors.white,
+ elevation: 5,
+ shape: const RoundedRectangleBorder(
+ borderRadius: BorderRadius.all(Radius.circular(4)),
+ ),
+ child: _tempList.isNotEmpty
+ ? Scrollbar(
+ child: ListView.separated(
+ padding: const EdgeInsets.symmetric(vertical: 4),
+ separatorBuilder: (context, index) => const Divider(
+ height: 1,
+ ),
+ itemBuilder: (context, index) => Material(
+ color: Colors.transparent,
+ child: InkWell(
+ onTap: () => onDropDownItemTap(_tempList[index]),
+ child: widget.popupListItemBuilder(
+ _tempList.elementAt(index),
+ ),
+ ),
+ ),
+ itemCount: _tempList.length,
+ ),
+ )
+ : widget.noItemsFoundWidget != null
+ ? Center(
+ child: widget.noItemsFoundWidget,
+ )
+ : Container(
+ child: Text("no items found"),
+ ),
+ ),
+ ),
+ ),
+ );
+ },
+ );
+ Overlay.of(context).insert(overlayEntry);
+ }
+
+ void onDeleteSelectedItem() {
+ setState(() => notifier.value = null);
+ if (widget.onItemSelected != null) {
+ widget.onItemSelected(null);
+ }
}
}
diff --git a/lib/components/toast/gf_floating_widget.dart b/lib/components/toast/gf_floating_widget.dart
index 8a950c81..75541a55 100644
--- a/lib/components/toast/gf_floating_widget.dart
+++ b/lib/components/toast/gf_floating_widget.dart
@@ -9,6 +9,8 @@ class GFFloatingWidget extends StatefulWidget {
this.child,
this.horizontalPosition,
this.verticalPosition,
+ this.color,
+ this.blur=false,
this.body})
: super(key: key);
@@ -24,6 +26,17 @@ class GFFloatingWidget extends StatefulWidget {
/// verticalPosition of type [double] which aligns the child vertically across the body
final double verticalPosition;
+
+ final dynamic color;
+
+ final bool blur;
+
+
+
+
+
+
+
@override
_GFFloatingWidgetState createState() => _GFFloatingWidgetState();
}
@@ -39,19 +52,33 @@ class _GFFloatingWidgetState extends State {
height: MediaQuery.of(context).size.height,
child: widget.body ?? Container(),
),
- Positioned(
- top:
- widget.verticalPosition != null ? widget.verticalPosition : 0.0,
- left: widget.horizontalPosition != null
- ? widget.horizontalPosition
- : 0.0,
- right: widget.horizontalPosition != null
- ? widget.horizontalPosition
- : 0.0,
- child: Container(
- width: MediaQuery.of(context).size.width,
- child: widget.child ?? Container(),
- )),
+ Container(
+// color: widget.child!=null? widget.color: null,
+ child: Stack(
+ children: [
+ Positioned(
+ child:Container(
+ alignment: Alignment.topLeft,
+// color: widget.child!=null? widget.color: null,
+ color: widget.blur?Colors.black38:null,
+ child: Stack(
+ children: [
+ Positioned( top:
+ widget.verticalPosition != null ? widget.verticalPosition : 0.0,
+ left: widget.horizontalPosition != null
+ ? widget.horizontalPosition
+ : 0.0,
+ right: widget.horizontalPosition != null
+ ? widget.horizontalPosition
+ : 0.0,child: widget.child??Container(),)
+ ],
+ )
+ )
+ ),
+ ],
+ )
+ )
+
],
);
}
diff --git a/lib/components/toggle/gf_toggle.dart b/lib/components/toggle/gf_toggle.dart
index afc76c4f..fccc8c1a 100644
--- a/lib/components/toggle/gf_toggle.dart
+++ b/lib/components/toggle/gf_toggle.dart
@@ -16,7 +16,7 @@ class GFToggle extends StatefulWidget {
GFToggle(
{Key key,
@required this.onChanged,
- this.value ,
+ this.value,
this.enabledText,
this.disabledText,
this.enabledTextStyle,
@@ -73,7 +73,6 @@ class GFToggle extends StatefulWidget {
/// Called when the user toggles the switch on or off.
final ValueChanged onChanged;
-
@override
_GFToggleState createState() => _GFToggleState();
}
@@ -86,15 +85,15 @@ class _GFToggleState extends State with TickerProviderStateMixin {
bool isOn;
-
-
@override
void initState() {
setState(() {
- isOn = widget.value??false;
+ isOn = widget.value ?? false;
});
controller = AnimationController(vsync: this, duration: widget.duration);
- offset = (isOn?Tween(begin: Offset(1.0, 0.0), end:Offset.zero):Tween(begin: Offset.zero, end: Offset(1.0, 0.0)))
+ offset = (isOn
+ ? Tween(begin: Offset(1.0, 0.0), end: Offset.zero)
+ : Tween(begin: Offset.zero, end: Offset(1.0, 0.0)))
.animate(controller);
super.initState();
}
@@ -106,8 +105,8 @@ class _GFToggleState extends State with TickerProviderStateMixin {
super.dispose();
}
- void onStatusChange(){
- if(widget.onChanged!=null){
+ void onStatusChange() {
+ if (widget.onChanged != null) {
setState(() {
isOn = !isOn;
});
@@ -127,84 +126,79 @@ class _GFToggleState extends State with TickerProviderStateMixin {
@override
Widget build(BuildContext context) {
- return Stack(
- children: [
- Container(
- height: widget.type == GFToggleType.android ? 25 : 30,
- width: widget.type == GFToggleType.android ? 40 : 50,
- ),
- Positioned(
- top: 5,
- child: InkWell(
+ return Stack(
+ children: [
+ Container(
+ height: widget.type == GFToggleType.android ? 25 : 30,
+ width: widget.type == GFToggleType.android ? 40 : 50,
+ ),
+ Positioned(
+ top: 5,
+ child: InkWell(
onTap: onStatusChange,
child: Container(
- width: widget.type == GFToggleType.ios ? 45 : 36,
- height: widget.type == GFToggleType.ios ? 25 : 15,
- decoration: BoxDecoration(
- color: isOn
- ? widget.enabledTrackColor ?? Colors.lightGreen
- : widget.disabledTrackColor ?? Colors.grey,
- borderRadius: widget.type == GFToggleType.square
- ? BorderRadius.all(Radius.circular(0))
- : widget.borderRadius ??
+ width: widget.type == GFToggleType.ios ? 45 : 36,
+ height: widget.type == GFToggleType.ios ? 25 : 15,
+ decoration: BoxDecoration(
+ color: isOn
+ ? widget.enabledTrackColor ?? Colors.lightGreen
+ : widget.disabledTrackColor ?? Colors.grey,
+ borderRadius: widget.type == GFToggleType.square
+ ? BorderRadius.all(Radius.circular(0))
+ : widget.borderRadius ??
BorderRadius.all(Radius.circular(20))),
- child: Padding(
- padding: widget.type == GFToggleType.ios
- ? EdgeInsets.only(left: 3.5, right: 3.5, top: 5.4)
- : EdgeInsets.only(left: 3, right: 3, top: 3.4),
- child: isOn
- ? Text(
- widget.enabledText ??
- (widget.type == GFToggleType.custom
- ? 'ON'
- : ''),
- style: widget.enabledTextStyle ??
- (widget.type == GFToggleType.ios
- ? TextStyle(
- color: Colors.white, fontSize: 12)
- : TextStyle(
- color: Colors.white, fontSize: 8)))
- : Text(
- widget.disabledText ??
- (widget.type == GFToggleType.custom
- ? 'OFF'
- : ''),
- textAlign: TextAlign.end,
- style: widget.disabledTextStyle ??
- (widget.type == GFToggleType.ios
- ? TextStyle(color: Colors.white, fontSize: 12)
- : TextStyle(color: Colors.white, fontSize: 8)),),),),
- ),),
- Positioned(
- top: widget.type == GFToggleType.ios ? 7.5 : 3,
- left: widget.type == GFToggleType.ios ? 2 : 0,
- child: InkWell(
- onTap: onStatusChange,
- child: SlideTransition(
- position:offset,
- child: Container(
- padding: EdgeInsets.only(left: 10),
- height: 20,
- width: 20,
- decoration: BoxDecoration(
- shape: widget.type == GFToggleType.square
- ? BoxShape.rectangle
- : widget.boxShape ?? BoxShape.circle,
- color: isOn
- ? widget.enabledThumbColor ?? Colors.white
- : widget.disabledThumbColor ?? Colors.white,
- boxShadow: [
- new BoxShadow(
- color: Colors.black.withOpacity(0.16),
- blurRadius: 6.0,
- spreadRadius: 0.0),
- ]),
+ child: Padding(
+ padding: widget.type == GFToggleType.ios
+ ? EdgeInsets.only(left: 3.5, right: 3.5, top: 5.4)
+ : EdgeInsets.only(left: 3, right: 3, top: 3.4),
+ child: isOn
+ ? Text(
+ widget.enabledText ??
+ (widget.type == GFToggleType.custom ? 'ON' : ''),
+ style: widget.enabledTextStyle ??
+ (widget.type == GFToggleType.ios
+ ? TextStyle(color: Colors.white, fontSize: 12)
+ : TextStyle(color: Colors.white, fontSize: 8)))
+ : Text(
+ widget.disabledText ??
+ (widget.type == GFToggleType.custom ? 'OFF' : ''),
+ textAlign: TextAlign.end,
+ style: widget.disabledTextStyle ??
+ (widget.type == GFToggleType.ios
+ ? TextStyle(color: Colors.white, fontSize: 12)
+ : TextStyle(color: Colors.white, fontSize: 8)),
),
- )
- )),
- ],
-
- );
+ ),
+ ),
+ ),
+ ),
+ Positioned(
+ top: widget.type == GFToggleType.ios ? 7.5 : 3,
+ left: widget.type == GFToggleType.ios ? 2 : 0,
+ child: InkWell(
+ onTap: onStatusChange,
+ child: SlideTransition(
+ position: offset,
+ child: Container(
+ padding: EdgeInsets.only(left: 10),
+ height: 20,
+ width: 20,
+ decoration: BoxDecoration(
+ shape: widget.type == GFToggleType.square
+ ? BoxShape.rectangle
+ : widget.boxShape ?? BoxShape.circle,
+ color: isOn
+ ? widget.enabledThumbColor ?? Colors.white
+ : widget.disabledThumbColor ?? Colors.white,
+ boxShadow: [
+ new BoxShadow(
+ color: Colors.black.withOpacity(0.16),
+ blurRadius: 6.0,
+ spreadRadius: 0.0),
+ ]),
+ ),
+ ))),
+ ],
+ );
}
}
-
diff --git a/lib/types/gf_alert_type.dart b/lib/types/gf_alert_type.dart
new file mode 100644
index 00000000..8c3480ab
--- /dev/null
+++ b/lib/types/gf_alert_type.dart
@@ -0,0 +1 @@
+enum GFAlertType { basic, rounded, fullWidth }