Jaime Blasco

Format and fix lint issues.

## [0.0.1] - TODO: Add release date.
## [0.0.1] - Pre Release.
## [0.1.0] - Package Release.
* TODO: Describe initial release.
... ...
<img src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/preview.png">
<img src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/preview.png?raw=true">
# Flutter Modal Bottom Sheet
Create awesome and powerful modal bottom sheets
<img align="left" height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/cupertino_shared_view.gif">
<img align="left" height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/modal_inside_modal.gif">
<img align="left" height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/material_fit.png">
<img align="left"height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/bar_modal.png">
<img height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/avatar_modal.png">
| Cupertino Modal | Multiple Modals | Material Modal | Bar Modal | Create your own |
|---|---|---|---|---|
|<img height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/cupertino_shared_view.gif?raw=true">| <img height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/modal_inside_modal.gif?raw=true">| <img height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/material_fit.png?raw=true">|<img height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/bar_modal.png?raw=true">| <img height="300" src="https://github.com/jamesblasco/modal_bottom_sheet/blob/master/screenshots/avatar_modal.png?raw=true">|
## Material Modal BottomSheet
... ...
... ... @@ -38,11 +38,13 @@ class MyApp extends StatelessWidget {
middle: Text('Normal Navigation Presentation'),
trailing: GestureDetector(
child: Icon(Icons.arrow_upward),
onTap: () => CupertinoScaffold.showCupertinoModalBottomSheet(
onTap: () => CupertinoScaffold
.showCupertinoModalBottomSheet(
expand: true,
context: context,
backgroundColor: Colors.transparent,
builder: (context, scrollController) => Stack(
builder: (context, scrollController) =>
Stack(
children: <Widget>[
ModalWithScroll(
scrollController: scrollController),
... ... @@ -52,7 +54,8 @@ class MyApp extends StatelessWidget {
right: 40,
bottom: 20,
child: MaterialButton(
onPressed: () => Navigator.of(context)
onPressed: () => Navigator.of(
context)
.popUntil((route) =>
route.settings.name == '/'),
child: Text('Pop back home'),
... ... @@ -64,7 +67,9 @@ class MyApp extends StatelessWidget {
),
child: Center(child: Container()),
),
),),),
),
),
),
settings: settings);
},
debugShowCheckedModeBanner: false,
... ... @@ -114,8 +119,7 @@ class _MyHomePageState extends State<MyHomePage> {
context: context,
backgroundColor: Colors.transparent,
builder: (context, scrollController) =>
ModalFit(
scrollController: scrollController),
ModalFit(scrollController: scrollController),
)),
ListTile(
title: Text('Bar Modal'),
... ... @@ -144,8 +148,7 @@ class _MyHomePageState extends State<MyHomePage> {
context: context,
backgroundColor: Colors.transparent,
builder: (context, scrollController) =>
ModalFit(
scrollController: scrollController),
ModalFit(scrollController: scrollController),
)),
ListTile(
title: Text('Cupertino Small Modal forzed to expand'),
... ... @@ -154,13 +157,11 @@ class _MyHomePageState extends State<MyHomePage> {
context: context,
backgroundColor: Colors.transparent,
builder: (context, scrollController) =>
ModalFit(
scrollController: scrollController),
ModalFit(scrollController: scrollController),
)),
ListTile(
title: Text('Cupertino Modal inside modal'),
onTap: () =>
showCupertinoModalBottomSheet(
onTap: () => showCupertinoModalBottomSheet(
expand: true,
context: context,
backgroundColor: Colors.transparent,
... ... @@ -169,8 +170,7 @@ class _MyHomePageState extends State<MyHomePage> {
scrollController: scrollController),
)),
ListTile(
title:
Text('Cupertino Navigator + Scroll + WillScope'),
title: Text('Cupertino Navigator + Scroll + WillScope'),
onTap: () => showCupertinoModalBottomSheet(
expand: true,
context: context,
... ... @@ -194,7 +194,6 @@ class _MyHomePageState extends State<MyHomePage> {
),
),
),
),
);
}
... ...
... ... @@ -28,7 +28,8 @@ class AvatarBottomSheet extends StatelessWidget {
builder: (context, child) => Transform.translate(
offset: Offset(0, (1 - animation.value) * 100),
child: Opacity(
child: child, opacity: max(0, animation.value * 2 - 1))),
child: child,
opacity: max(0, animation.value * 2 - 1))),
child: Row(
children: <Widget>[
SizedBox(width: 20),
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
... ... @@ -12,7 +11,8 @@ class ModalInsideModal extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(child:CupertinoPageScaffold(
return Material(
child: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
leading: Container(), middle: Text('Modal Page')),
child: SafeArea(
... ... @@ -33,14 +33,12 @@ class ModalInsideModal extends StatelessWidget {
context: context,
backgroundColor: Colors.transparent,
builder: (context, scrollController) =>
ModalInsideModal(scrollController: scrollController),
ModalInsideModal(
scrollController: scrollController),
)),
)
).toList(),
)).toList(),
),
),
));
}
}
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
class SimpleModal extends StatelessWidget {
final ScrollController scrollController;
... ... @@ -7,7 +8,8 @@ class SimpleModal extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(child:CupertinoPageScaffold(
return Material(
child: CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
leading: Container(), middle: Text('Modal Page')),
child: Center(),
... ...
... ... @@ -8,7 +8,8 @@ class ModalWillScope extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material(child: WillPopScope(
return Material(
child: WillPopScope(
onWillPop: () async {
bool shouldClose = true;
await showCupertinoDialog(
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
... ... @@ -9,7 +8,8 @@ class ModalWithNavigator extends StatelessWidget {
@override
Widget build(BuildContext context) {
return Material( child: Navigator(
return Material(
child: Navigator(
onGenerateRoute: (_) => MaterialPageRoute(
builder: (context) => Builder(
builder: (context) => CupertinoPageScaffold(
... ... @@ -27,20 +27,14 @@ class ModalWithNavigator extends StatelessWidget {
(index) => ListTile(
title: Text('Item'),
onTap: () {
Navigator.of(context).push(
MaterialPageRoute(
builder: (context) =>
CupertinoPageScaffold(
navigationBar:
CupertinoNavigationBar(
middle: Text(
'New Page'),
Navigator.of(context).push(MaterialPageRoute(
builder: (context) => CupertinoPageScaffold(
navigationBar: CupertinoNavigationBar(
middle: Text('New Page'),
),
child: Stack(
fit:
StackFit.expand,
children: <
Widget>[],
fit: StackFit.expand,
children: <Widget>[],
))));
},
)),
... ... @@ -49,8 +43,7 @@ class ModalWithNavigator extends StatelessWidget {
),
),
),
),)
);
),
));
}
}
... ...
... ... @@ -7,42 +7,42 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
version: "2.0.11"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "1.5.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
version: "2.4.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "1.0.5"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.12"
version: "1.14.11"
convert:
dependency: transitive
description:
... ... @@ -56,7 +56,7 @@ packages:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "2.1.3"
cupertino_icons:
dependency: "direct main"
description:
... ... @@ -80,7 +80,7 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
version: "2.1.4"
matcher:
dependency: transitive
description:
... ... @@ -101,7 +101,7 @@ packages:
path: ".."
relative: true
source: path
version: "0.0.1"
version: "0.1.0"
path:
dependency: transitive
description:
... ... @@ -109,6 +109,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
petitparser:
dependency: transitive
description:
... ... @@ -122,7 +129,7 @@ packages:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.0.5"
sky_engine:
dependency: transitive
description: flutter
... ... @@ -134,7 +141,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.5.5"
stack_trace:
dependency: transitive
description:
... ... @@ -169,7 +176,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.15"
version: "0.2.11"
typed_data:
dependency: transitive
description:
... ... @@ -190,6 +197,6 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
version: "3.5.0"
sdks:
dart: ">=2.7.0 <3.0.0"
dart: ">=2.4.0 <3.0.0"
... ...
... ... @@ -4,5 +4,3 @@
// utility that Flutter provides. For example, you can send tap and scroll
// gestures. You can also use WidgetTester to find child widgets in the widget
// tree, read text, and verify that the values of widget properties are correct.
... ...
export 'src/bottom_sheet.dart';
export 'src/bottom_sheet_route.dart';
export 'src/material_with_modal_page_route.dart';
... ...
... ... @@ -3,7 +3,6 @@
// found in the LICENSE file.
import 'dart:async';
import 'dart:math';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
... ... @@ -12,8 +11,6 @@ import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import 'bottom_sheet_route.dart';
const Duration _bottomSheetDuration = Duration(milliseconds: 400);
const double _minFlingVelocity = 500.0;
const double _closeProgressThreshold = 0.5;
... ... @@ -158,8 +155,8 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
bool _isCheckingShouldClose = false;
FutureOr<bool> shouldClose() async {
if(_isCheckingShouldClose) return false;
if(widget.shouldClose == null) return null;
if (_isCheckingShouldClose) return false;
if (widget.shouldClose == null) return null;
_isCheckingShouldClose = true;
final result = await widget.shouldClose();
_isCheckingShouldClose = false;
... ... @@ -203,7 +200,6 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
isDragging = false;
_bounceDragController.reverse();
bool canClose = true;
if (widget.shouldClose != null && hasReachedWillPopThreshold) {
_cancelClose();
... ... @@ -273,20 +269,18 @@ class _ModalBottomSheetState extends State<ModalBottomSheet>
child,
);
// Todo: Add curved Animation when push and pop without gesture
final Animation<double> containerAnimation = CurvedAnimation(
/* final Animation<double> containerAnimation = CurvedAnimation(
parent: widget.animationController,
curve: Curves.easeOut,
);
);*/
return AnimatedBuilder(
animation: widget.animationController,
builder: (context, _) => ClipRect(
child: CustomSingleChildLayout(
delegate: _ModalBottomSheetLayout(
widget.animationController.value,
widget.expanded),
widget.animationController.value, widget.expanded),
child: !widget.enableDrag
? child
: KeyedSubtree(
... ...
import 'dart:async';
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/widgets.dart';
import '../modal_bottom_sheet.dart';
import 'material_with_modal_page_route.dart';
const Duration _bottomSheetDuration = Duration(milliseconds: 400);
class _ModalBottomSheetLayout extends SingleChildLayoutDelegate {
_ModalBottomSheetLayout(this.progress, this.expand);
final double progress;
final bool expand;
@override
BoxConstraints getConstraintsForChild(BoxConstraints constraints) {
return BoxConstraints(
minWidth: constraints.maxWidth,
maxWidth: constraints.maxWidth,
minHeight: expand ? constraints.maxHeight : 0,
maxHeight: expand ? constraints.maxHeight : constraints.minHeight,
);
}
@override
Offset getPositionForChild(Size size, Size childSize) {
return Offset(0.0, size.height - childSize.height * progress);
}
@override
bool shouldRelayout(_ModalBottomSheetLayout oldDelegate) {
return progress != oldDelegate.progress;
}
}
class _ModalBottomSheet<T> extends StatefulWidget {
const _ModalBottomSheet({
Key key,
... ... @@ -65,13 +33,14 @@ class _ModalBottomSheet<T> extends StatefulWidget {
class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
String _getRouteLabel(MaterialLocalizations localizations) {
switch (Theme.of(context).platform) {
final platform = Theme.of(context).platform;
switch (platform) {
case TargetPlatform.iOS:
case TargetPlatform.macOS:
return '';
case TargetPlatform.android:
case TargetPlatform.fuchsia:
return localizations.dialogLabel;
break;
}
return null;
}
... ... @@ -100,9 +69,6 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
MaterialLocalizations.of(context);
final String routeLabel = _getRouteLabel(localizations);
return AnimatedBuilder(
animation: widget.route._animationController,
builder: (BuildContext context, Widget child) {
... ... @@ -117,7 +83,7 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
expanded: widget.route.expanded,
containerBuilder: widget.route.containerBuilder,
animationController: widget.route._animationController,
shouldClose: widget.route.hasScopedWillPopCallback
shouldClose: widget.route._hasScopedWillPopCallback
? () async {
final willPop = await widget.route.willPop();
return willPop != RoutePopDisposition.doNotPop;
... ... @@ -132,8 +98,6 @@ class _ModalBottomSheetState<T> extends State<_ModalBottomSheet<T>> {
enableDrag: widget.enableDrag,
bounce: widget.bounce,
),
);
},
);
... ... @@ -191,6 +155,8 @@ class ModalBottomSheetRoute<T> extends PopupRoute<T> {
return _animationController;
}
bool get _hasScopedWillPopCallback => hasScopedWillPopCallback;
@override
Widget buildPage(BuildContext context, Animation<double> animation,
Animation<double> secondaryAnimation) {
... ...
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import 'dart:async';
import '../../modal_bottom_sheet.dart';
import '../bottom_sheet_route.dart';
... ... @@ -49,16 +47,12 @@ class BarBottomSheet extends StatelessWidget {
]),
width: double.infinity,
child: MediaQuery.removePadding(
context: context,
removeTop: true,
child: child
)
),
context: context, removeTop: true, child: child)),
),
),
]),);
]),
);
}
}
Future<T> showBarModalBottomSheet<T>({
... ... @@ -88,7 +82,9 @@ Future<T> showBarModalBottomSheet<T>({
.push(ModalBottomSheetRoute<T>(
builder: builder,
bounce: bounce,
containerBuilder: (_, __, child) => BarBottomSheet(child: child,),
containerBuilder: (_, __, child) => BarBottomSheet(
child: child,
),
secondAnimationController: secondAnimation,
expanded: expand,
barrierLabel: MaterialLocalizations.of(context).modalBarrierDismissLabel,
... ... @@ -98,4 +94,3 @@ Future<T> showBarModalBottomSheet<T>({
));
return result;
}
... ...
... ... @@ -8,7 +8,6 @@ import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/gestures.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter/widgets.dart';
... ... @@ -200,7 +199,9 @@ class _CupertinoModalTransition extends StatelessWidget {
final progress = curvedAnimation.value;
final yOffset = progress * paddingTop;
final scale = 1 - progress / 10;
final radius = progress == 0 ? 0.0 : (1 - progress) * startRoundCorner + progress * 12;
final radius = progress == 0
? 0.0
: (1 - progress) * startRoundCorner + progress * 12;
return Stack(
children: <Widget>[
Container(color: Colors.black),
... ...
import 'package:flutter/material.dart';
import 'package:modal_bottom_sheet/modal_bottom_sheet.dart';
import 'dart:async';
/// Shows a modal material design bottom sheet.
Future<T> showMaterialModalBottomSheet<T>({
... ...
import 'package:flutter/cupertino.dart';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/services.dart';
import '../modal_bottom_sheet.dart';
import 'bottom_sheet_route.dart';
class e extends PageRouteBuilder {
}
class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
/// Construct a MaterialPageRoute whose contents are defined by [builder].
///
... ... @@ -30,8 +25,6 @@ class MaterialWithModalsPageRoute<T> extends MaterialPageRoute<T> {
builder: builder,
maintainState: maintainState);
ModalBottomSheetRoute _nextModalRoute;
@override
... ...
... ... @@ -7,42 +7,42 @@ packages:
name: archive
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.13"
version: "2.0.11"
args:
dependency: transitive
description:
name: args
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.0"
version: "1.5.2"
async:
dependency: transitive
description:
name: async
url: "https://pub.dartlang.org"
source: hosted
version: "2.4.1"
version: "2.4.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
url: "https://pub.dartlang.org"
source: hosted
version: "2.0.0"
version: "1.0.5"
charcode:
dependency: transitive
description:
name: charcode
url: "https://pub.dartlang.org"
source: hosted
version: "1.1.3"
version: "1.1.2"
collection:
dependency: transitive
description:
name: collection
url: "https://pub.dartlang.org"
source: hosted
version: "1.14.12"
version: "1.14.11"
convert:
dependency: transitive
description:
... ... @@ -56,7 +56,7 @@ packages:
name: crypto
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.4"
version: "2.1.3"
flutter:
dependency: "direct main"
description: flutter
... ... @@ -73,7 +73,7 @@ packages:
name: image
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.12"
version: "2.1.4"
matcher:
dependency: transitive
description:
... ... @@ -95,6 +95,13 @@ packages:
url: "https://pub.dartlang.org"
source: hosted
version: "1.6.4"
pedantic:
dependency: transitive
description:
name: pedantic
url: "https://pub.dartlang.org"
source: hosted
version: "1.8.0+1"
petitparser:
dependency: transitive
description:
... ... @@ -108,7 +115,7 @@ packages:
name: quiver
url: "https://pub.dartlang.org"
source: hosted
version: "2.1.3"
version: "2.0.5"
sky_engine:
dependency: transitive
description: flutter
... ... @@ -120,7 +127,7 @@ packages:
name: source_span
url: "https://pub.dartlang.org"
source: hosted
version: "1.7.0"
version: "1.5.5"
stack_trace:
dependency: transitive
description:
... ... @@ -155,7 +162,7 @@ packages:
name: test_api
url: "https://pub.dartlang.org"
source: hosted
version: "0.2.15"
version: "0.2.11"
typed_data:
dependency: transitive
description:
... ... @@ -176,6 +183,6 @@ packages:
name: xml
url: "https://pub.dartlang.org"
source: hosted
version: "3.6.1"
version: "3.5.0"
sdks:
dart: ">=2.7.0 <3.0.0"
dart: ">=2.4.0 <3.0.0"
... ...
name: modal_bottom_sheet
description: 'Modal bottom sheets: Cupertino, Material, or build your own'
version: 0.0.1
author: 'JB <git@jaimeblasco.com>'
description: 'Create flutter advanced modal bottom sheets. Material, Cupertino or your own style'
version: 0.1.3
homepage: 'https://github.com/jamesblasco/modal_bottom_sheet'
environment:
sdk: ">=2.7.0 <3.0.0"
sdk: ">=2.0.0 <3.0.0"
flutter: ">=1.12.0 <2.0.0"
dependencies:
flutter:
... ...
import 'package:flutter_test/flutter_test.dart';
void main() {
test('adds one to input values', () {
});
test('adds one to input values', () {});
}
... ...