Add Cupertino to gallery and add CupertinoButton and many yak friends (#8411)
* Add cupertino to gallery and add CupertinoButto
* Use single quotes
* Add disabled state
* Some review notes
* Make button animation more responsive and tweak timing
* Renamed things Cupertino
* Button with background, move cupertino demos, move material demos
* Move 2 level list too
* Refactor various demo route names
* Some review notes
* More reviews and add test
* Linter as
* Move private constant up
diff --git a/examples/flutter_gallery/lib/demo/all.dart b/examples/flutter_gallery/lib/demo/all.dart
index ed8618f..e574367 100644
--- a/examples/flutter_gallery/lib/demo/all.dart
+++ b/examples/flutter_gallery/lib/demo/all.dart
@@ -2,37 +2,11 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
-export 'bottom_navigation_demo.dart';
-export 'buttons_demo.dart';
export 'calculator_demo.dart';
-export 'cards_demo.dart';
-export 'chip_demo.dart';
export 'colors_demo.dart';
export 'contacts_demo.dart';
-export 'data_table_demo.dart';
-export 'date_and_time_picker_demo.dart';
-export 'dialog_demo.dart';
-export 'drawer_demo.dart';
-export 'expansion_panels_demo.dart';
-export 'grid_list_demo.dart';
-export 'icons_demo.dart';
-export 'leave_behind_demo.dart';
-export 'list_demo.dart';
-export 'menu_demo.dart';
-export 'modal_bottom_sheet_demo.dart';
-export 'overscroll_demo.dart';
-export 'page_selector_demo.dart';
-export 'persistent_bottom_sheet_demo.dart';
export 'pesto_demo.dart';
-export 'progress_indicator_demo.dart';
-export 'scrollable_tabs_demo.dart';
-export 'selection_controls_demo.dart';
export 'shrine_demo.dart';
-export 'slider_demo.dart';
-export 'snack_bar_demo.dart';
-export 'tabs_demo.dart';
-export 'tabs_fab_demo.dart';
-export 'text_field_demo.dart';
-export 'tooltip_demo.dart';
-export 'two_level_list_demo.dart';
export 'typography_demo.dart';
+export 'cupertino/cupertino.dart';
+export 'material/material.dart';
diff --git a/examples/flutter_gallery/lib/demo/cupertino/cupertino.dart b/examples/flutter_gallery/lib/demo/cupertino/cupertino.dart
new file mode 100644
index 0000000..b7cbea5
--- /dev/null
+++ b/examples/flutter_gallery/lib/demo/cupertino/cupertino.dart
@@ -0,0 +1,9 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+export 'cupertino_activity_indicator_demo.dart';
+export 'cupertino_buttons_demo.dart';
+export 'cupertino_dialog_demo.dart';
+export 'cupertino_slider_demo.dart';
+export 'cupertino_switch_demo.dart';
diff --git a/examples/flutter_gallery/lib/demo/cupertino/cupertino_activity_indicator_demo.dart b/examples/flutter_gallery/lib/demo/cupertino/cupertino_activity_indicator_demo.dart
new file mode 100644
index 0000000..28d0b93
--- /dev/null
+++ b/examples/flutter_gallery/lib/demo/cupertino/cupertino_activity_indicator_demo.dart
@@ -0,0 +1,22 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class CupertinoProgressIndicatorDemo extends StatelessWidget {
+ static const String routeName = '/cupertino/progress_indicator';
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ appBar: new AppBar(
+ title: new Text('Cupertino Activity Indicator'),
+ ),
+ body: new Center(
+ child: new CupertinoActivityIndicator(),
+ ),
+ );
+ }
+}
diff --git a/examples/flutter_gallery/lib/demo/cupertino/cupertino_buttons_demo.dart b/examples/flutter_gallery/lib/demo/cupertino/cupertino_buttons_demo.dart
new file mode 100644
index 0000000..99525f8
--- /dev/null
+++ b/examples/flutter_gallery/lib/demo/cupertino/cupertino_buttons_demo.dart
@@ -0,0 +1,76 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class CupertinoButtonsDemo extends StatefulWidget {
+ static const String routeName = '/cupertino/buttons';
+
+ @override
+ _CupertinoButtonDemoState createState() => new _CupertinoButtonDemoState();
+}
+
+class _CupertinoButtonDemoState extends State<CupertinoButtonsDemo> {
+ int _pressedCount = 0;
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ appBar: new AppBar(
+ title: new Text('Cupertino Buttons'),
+ ),
+ body: new Column(
+ children: <Widget> [
+ new Padding(
+ padding: const EdgeInsets.all(16.0),
+ child: new Text('iOS themed buttons are flat. They can have borders or backgrounds but '
+ 'only when necessary.'),
+ ),
+ new Expanded(
+ child: new Column(
+ mainAxisAlignment: MainAxisAlignment.center,
+ children: <Widget> [
+ new Text(_pressedCount > 0 ? "Button pressed $_pressedCount times" : " "),
+ new Padding(padding: const EdgeInsets.all(12.0)),
+ new Align(
+ alignment: const FractionalOffset(0.5, 0.4),
+ child: new Row(
+ mainAxisSize: MainAxisSize.min,
+ children: <Widget>[
+ new CupertinoButton(
+ child: new Text('Cupertino Button'),
+ onPressed: () {
+ setState(() {_pressedCount++;});
+ }
+ ),
+ new CupertinoButton(
+ child: new Text('Disabled'),
+ onPressed: null,
+ ),
+ ],
+ ),
+ ),
+ new Padding(padding: const EdgeInsets.all(12.0)),
+ new CupertinoButton(
+ child: new Text('With Background'),
+ color: CupertinoButton.kBlue,
+ onPressed: () {
+ setState(() {_pressedCount++;});
+ }
+ ),
+ new Padding(padding: const EdgeInsets.all(12.0)),
+ new CupertinoButton(
+ child: new Text('Disabled'),
+ color: CupertinoButton.kBlue,
+ onPressed: null,
+ ),
+ ],
+ )
+ ),
+ ],
+ )
+ );
+ }
+}
diff --git a/examples/flutter_gallery/lib/demo/cupertino/cupertino_dialog_demo.dart b/examples/flutter_gallery/lib/demo/cupertino/cupertino_dialog_demo.dart
new file mode 100644
index 0000000..a73fa89
--- /dev/null
+++ b/examples/flutter_gallery/lib/demo/cupertino/cupertino_dialog_demo.dart
@@ -0,0 +1,99 @@
+// Copyright 2016 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class CupertinoDialogDemo extends StatefulWidget {
+ static const String routeName = '/cupertino/dialog';
+
+ @override
+ _CupertinoDialogDemoState createState() => new _CupertinoDialogDemoState();
+}
+
+class _CupertinoDialogDemoState extends State<CupertinoDialogDemo> {
+ final GlobalKey<ScaffoldState> _scaffoldKey = new GlobalKey<ScaffoldState>();
+
+ void showDemoDialog<T>({ BuildContext context, Widget child }) {
+ showDialog<T>(
+ context: context,
+ child: child,
+ barrierDismissable: false,
+ )
+ .then<Null>((T value) { // The value passed to Navigator.pop() or null.
+ if (value != null) {
+ _scaffoldKey.currentState.showSnackBar(new SnackBar(
+ content: new Text('You selected: $value')
+ ));
+ }
+ });
+ }
+
+
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ key: _scaffoldKey,
+ appBar: new AppBar(
+ title: new Text('Cupertino Dialogs'),
+ ),
+ body: new ListView(
+ padding: const EdgeInsets.symmetric(vertical: 24.0, horizontal: 72.0),
+ children: <Widget> [
+ new CupertinoButton(
+ child: new Text('Alert'),
+ color: CupertinoButton.kBlue,
+ onPressed: () {
+ showDemoDialog<String>(
+ context: context,
+ child: new CupertinoAlertDialog(
+ content: new Text('Discard draft?'),
+ actions: <Widget>[
+ new CupertinoDialogAction(
+ child: new Text('Discard'),
+ isDestructive: true,
+ onPressed: () { Navigator.pop(context, 'OK'); }
+ ),
+ new CupertinoDialogAction(
+ child: new Text('Cancel', style: new TextStyle(fontWeight: FontWeight.w600)),
+ onPressed: () { Navigator.pop(context, 'Cancel'); }
+ ),
+ ]
+ ),
+ );
+ },
+ ),
+ new Padding(padding: const EdgeInsets.all(8.0)),
+ new CupertinoButton(
+ child: new Text('Alert with Title'),
+ color: CupertinoButton.kBlue,
+ onPressed: () {
+ showDemoDialog<String>(
+ context: context,
+ child: new CupertinoAlertDialog(
+ title: new Text('Allow "Maps" to access your location while you use the app?'),
+ content: new Text(
+ 'Your current location will be displayed on the map and used for directions, '
+ 'nearby search results, and estimated travel times.'
+ ),
+ actions: <Widget>[
+ new CupertinoDialogAction(
+ child: new Text('Don\'t Allow'),
+ onPressed: () { Navigator.pop(context, 'Disallow'); }
+ ),
+ new CupertinoDialogAction(
+ child: new Text('Allow'),
+ onPressed: () { Navigator.pop(context, 'Allow'); }
+ ),
+ ]
+ ),
+ );
+ },
+ ),
+ ],
+ ),
+ );
+ }
+}
diff --git a/examples/flutter_gallery/lib/demo/slider_demo.dart b/examples/flutter_gallery/lib/demo/cupertino/cupertino_slider_demo.dart
similarity index 61%
copy from examples/flutter_gallery/lib/demo/slider_demo.dart
copy to examples/flutter_gallery/lib/demo/cupertino/cupertino_slider_demo.dart
index dd55070..13971cd 100644
--- a/examples/flutter_gallery/lib/demo/slider_demo.dart
+++ b/examples/flutter_gallery/lib/demo/cupertino/cupertino_slider_demo.dart
@@ -1,24 +1,27 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
+// Copyright 2017 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+import 'package:flutter/cupertino.dart';
import 'package:flutter/material.dart';
-class SliderDemo extends StatefulWidget {
- static const String routeName = '/slider';
+class CupertinoSliderDemo extends StatefulWidget {
+ static const String routeName = '/cupertino/slider';
@override
- _SliderDemoState createState() => new _SliderDemoState();
+ _CupertinoSliderDemoState createState() => new _CupertinoSliderDemoState();
}
-class _SliderDemoState extends State<SliderDemo> {
+class _CupertinoSliderDemoState extends State<CupertinoSliderDemo> {
double _value = 25.0;
double _discreteValue = 20.0;
@override
Widget build(BuildContext context) {
return new Scaffold(
- appBar: new AppBar(title: new Text('Sliders')),
+ appBar: new AppBar(
+ title: new Text('Cupertino Sliders'),
+ ),
body: new Center(
child: new Column(
mainAxisAlignment: MainAxisAlignment.spaceAround,
@@ -26,45 +29,35 @@
new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget> [
- new Slider(
+ new CupertinoSlider(
value: _value,
min: 0.0,
max: 100.0,
- thumbOpenAtMin: true,
onChanged: (double value) {
setState(() {
_value = value;
});
}
),
- new Text('Continuous'),
+ new Text('Cupertino Continuous'),
]
),
new Column(
mainAxisSize: MainAxisSize.min,
children: <Widget> [
- new Slider(value: 0.25, thumbOpenAtMin: true, onChanged: null),
- new Text('Disabled'),
- ]
- ),
- new Column(
- mainAxisSize: MainAxisSize.min,
- children: <Widget> [
- new Slider(
+ new CupertinoSlider(
value: _discreteValue,
min: 0.0,
max: 100.0,
divisions: 5,
- label: '${_discreteValue.round()}',
- thumbOpenAtMin: true,
onChanged: (double value) {
setState(() {
_discreteValue = value;
});
}
),
- new Text('Discrete'),
- ],
+ new Text('Cupertino Discrete'),
+ ]
),
],
),
diff --git a/examples/flutter_gallery/lib/demo/cupertino/cupertino_switch_demo.dart b/examples/flutter_gallery/lib/demo/cupertino/cupertino_switch_demo.dart
new file mode 100644
index 0000000..dd2df03
--- /dev/null
+++ b/examples/flutter_gallery/lib/demo/cupertino/cupertino_switch_demo.dart
@@ -0,0 +1,37 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/material.dart';
+
+class CupertinoSwitchDemo extends StatefulWidget {
+ static const String routeName = '/cupertino/switch';
+
+ @override
+ _CupertinoSwitchDemoState createState() => new _CupertinoSwitchDemoState();
+}
+
+class _CupertinoSwitchDemoState extends State<CupertinoSwitchDemo> {
+
+ bool _switchValue = false;
+
+ @override
+ Widget build(BuildContext context) {
+ return new Scaffold(
+ appBar: new AppBar(
+ title: new Text('Cupertino Switch'),
+ ),
+ body: new Center(
+ child: new CupertinoSwitch(
+ value: _switchValue,
+ onChanged: (bool value) {
+ setState(() {
+ _switchValue = value;
+ });
+ }
+ ),
+ ),
+ );
+ }
+}
diff --git a/examples/flutter_gallery/lib/demo/bottom_navigation_demo.dart b/examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/bottom_navigation_demo.dart
rename to examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart
index f1d4a1e..4560277 100644
--- a/examples/flutter_gallery/lib/demo/bottom_navigation_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/bottom_navigation_demo.dart
@@ -79,7 +79,7 @@
}
class BottomNavigationDemo extends StatefulWidget {
- static const String routeName = '/bottom_navigation';
+ static const String routeName = '/material/bottom_navigation';
@override
_BottomNavigationDemoState createState() => new _BottomNavigationDemoState();
diff --git a/examples/flutter_gallery/lib/demo/buttons_demo.dart b/examples/flutter_gallery/lib/demo/material/buttons_demo.dart
similarity index 86%
rename from examples/flutter_gallery/lib/demo/buttons_demo.dart
rename to examples/flutter_gallery/lib/demo/material/buttons_demo.dart
index f12a2b7..3623c5c 100644
--- a/examples/flutter_gallery/lib/demo/buttons_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/buttons_demo.dart
@@ -4,43 +4,43 @@
import 'package:flutter/material.dart';
-import '../gallery/demo.dart';
+import '../../gallery/demo.dart';
const String _raisedText =
- "Raised buttons add dimension to mostly flat layouts. They emphasize "
- "functions on busy or wide spaces.";
+ 'Raised buttons add dimension to mostly flat layouts. They emphasize '
+ 'functions on busy or wide spaces.';
const String _raisedCode = 'buttons_raised';
-const String _flatText = "A flat button displays an ink splash on press "
- "but does not lift. Use flat buttons on toolbars, in dialogs and "
- "inline with padding";
+const String _flatText = 'A flat button displays an ink splash on press '
+ 'but does not lift. Use flat buttons on toolbars, in dialogs and '
+ 'inline with padding';
const String _flatCode = 'buttons_flat';
const String _dropdownText =
- "A dropdown button displays a menu that's used to select a value from a "
- "small set of values. The button displays the current value and a down "
- "arrow.";
+ 'A dropdown button displays a menu that\'s used to select a value from a '
+ 'small set of values. The button displays the current value and a down '
+ 'arrow.';
const String _dropdownCode = 'buttons_dropdown';
const String _iconText =
- "IconButtons are appropriate for toggle buttons that allow a single choice "
- "to be selected or deselected, such as adding or removing an item's star.";
+ 'IconButtons are appropriate for toggle buttons that allow a single choice '
+ 'to be selected or deselected, such as adding or removing an item\'s star.';
const String _iconCode = 'buttons_icon';
const String _actionText =
- "Floating action buttons are used for a promoted action. They are "
- "distinguished by a circled icon floating above the UI and can have motion "
- "behaviors that include morphing, launching, and a transferring anchor "
- "point.";
+ 'Floating action buttons are used for a promoted action. They are '
+ 'distinguished by a circled icon floating above the UI and can have motion '
+ 'behaviors that include morphing, launching, and a transferring anchor '
+ 'point.';
const String _actionCode = 'buttons_action';
class ButtonsDemo extends StatefulWidget {
- static const String routeName = '/buttons';
+ static const String routeName = '/material//buttons';
@override
_ButtonsDemoState createState() => new _ButtonsDemoState();
diff --git a/examples/flutter_gallery/lib/demo/cards_demo.dart b/examples/flutter_gallery/lib/demo/material/cards_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/cards_demo.dart
rename to examples/flutter_gallery/lib/demo/material/cards_demo.dart
index fb1e9e9..cba2d80 100644
--- a/examples/flutter_gallery/lib/demo/cards_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/cards_demo.dart
@@ -126,7 +126,7 @@
}
class CardsDemo extends StatelessWidget {
- static const String routeName = '/cards';
+ static const String routeName = '/material/cards';
@override
Widget build(BuildContext context) {
diff --git a/examples/flutter_gallery/lib/demo/chip_demo.dart b/examples/flutter_gallery/lib/demo/material/chip_demo.dart
similarity index 95%
rename from examples/flutter_gallery/lib/demo/chip_demo.dart
rename to examples/flutter_gallery/lib/demo/material/chip_demo.dart
index 162f5c9..11b6e04 100644
--- a/examples/flutter_gallery/lib/demo/chip_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/chip_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class ChipDemo extends StatefulWidget {
- static const String routeName = '/chip';
+ static const String routeName = '/material/chip';
@override
_ChipDemoState createState() => new _ChipDemoState();
diff --git a/examples/flutter_gallery/lib/demo/data_table_demo.dart b/examples/flutter_gallery/lib/demo/material/data_table_demo.dart
similarity index 99%
rename from examples/flutter_gallery/lib/demo/data_table_demo.dart
rename to examples/flutter_gallery/lib/demo/material/data_table_demo.dart
index b17bb6d..2e83248 100644
--- a/examples/flutter_gallery/lib/demo/data_table_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/data_table_demo.dart
@@ -141,7 +141,7 @@
}
class DataTableDemo extends StatefulWidget {
- static const String routeName = '/data-table';
+ static const String routeName = '/material/data-table';
@override
_DataTableDemoState createState() => new _DataTableDemoState();
diff --git a/examples/flutter_gallery/lib/demo/date_and_time_picker_demo.dart b/examples/flutter_gallery/lib/demo/material/date_and_time_picker_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/date_and_time_picker_demo.dart
rename to examples/flutter_gallery/lib/demo/material/date_and_time_picker_demo.dart
index 9d71e2a..8ec92ad 100644
--- a/examples/flutter_gallery/lib/demo/date_and_time_picker_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/date_and_time_picker_demo.dart
@@ -110,7 +110,7 @@
}
class DateAndTimePickerDemo extends StatefulWidget {
- static const String routeName = '/date-and-time-pickers';
+ static const String routeName = '/material/date-and-time-pickers';
@override
_DateAndTimePickerDemoState createState() => new _DateAndTimePickerDemoState();
diff --git a/examples/flutter_gallery/lib/demo/dialog_demo.dart b/examples/flutter_gallery/lib/demo/material/dialog_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/dialog_demo.dart
rename to examples/flutter_gallery/lib/demo/material/dialog_demo.dart
index 9c5b761..5f80b34 100644
--- a/examples/flutter_gallery/lib/demo/dialog_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/dialog_demo.dart
@@ -47,7 +47,7 @@
}
class DialogDemo extends StatefulWidget {
- static const String routeName = '/dialog';
+ static const String routeName = '/material/dialog';
@override
DialogDemoState createState() => new DialogDemoState();
@@ -68,7 +68,7 @@
void showDemoDialog<T>({ BuildContext context, Widget child }) {
showDialog<T>(
context: context,
- child: child
+ child: child,
)
.then<Null>((T value) { // The value passed to Navigator.pop() or null.
if (value != null) {
@@ -195,7 +195,7 @@
builder: (BuildContext context) => new FullScreenDialogDemo()
));
}
- )
+ ),
]
// Add a little space between the buttons
.map((Widget button) {
diff --git a/examples/flutter_gallery/lib/demo/drawer_demo.dart b/examples/flutter_gallery/lib/demo/material/drawer_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/drawer_demo.dart
rename to examples/flutter_gallery/lib/demo/material/drawer_demo.dart
index 25987b6..389dd61 100644
--- a/examples/flutter_gallery/lib/demo/drawer_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/drawer_demo.dart
@@ -9,7 +9,7 @@
const String _kAsset2 = 'packages/flutter_gallery_assets/shrine/vendors/sandra-adams.jpg';
class DrawerDemo extends StatefulWidget {
- static const String routeName = '/drawer';
+ static const String routeName = '/material/drawer';
@override
_DrawerDemoState createState() => new _DrawerDemoState();
diff --git a/examples/flutter_gallery/lib/demo/expansion_panels_demo.dart b/examples/flutter_gallery/lib/demo/material/expansion_panels_demo.dart
similarity index 99%
rename from examples/flutter_gallery/lib/demo/expansion_panels_demo.dart
rename to examples/flutter_gallery/lib/demo/material/expansion_panels_demo.dart
index b5c004c..16837b7 100644
--- a/examples/flutter_gallery/lib/demo/expansion_panels_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/expansion_panels_demo.dart
@@ -170,7 +170,7 @@
}
class ExpasionPanelsDemo extends StatefulWidget {
- static const String routeName = '/expansion_panels';
+ static const String routeName = '/material/expansion_panels';
@override
_ExpansionPanelsDemoState createState() => new _ExpansionPanelsDemoState();
diff --git a/examples/flutter_gallery/lib/demo/full_screen_dialog_demo.dart b/examples/flutter_gallery/lib/demo/material/full_screen_dialog_demo.dart
similarity index 100%
rename from examples/flutter_gallery/lib/demo/full_screen_dialog_demo.dart
rename to examples/flutter_gallery/lib/demo/material/full_screen_dialog_demo.dart
diff --git a/examples/flutter_gallery/lib/demo/grid_list_demo.dart b/examples/flutter_gallery/lib/demo/material/grid_list_demo.dart
similarity index 99%
rename from examples/flutter_gallery/lib/demo/grid_list_demo.dart
rename to examples/flutter_gallery/lib/demo/material/grid_list_demo.dart
index 4f50bc2..cf61413 100644
--- a/examples/flutter_gallery/lib/demo/grid_list_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/grid_list_demo.dart
@@ -232,7 +232,7 @@
class GridListDemo extends StatefulWidget {
GridListDemo({ Key key }) : super(key: key);
- static const String routeName = '/grid-list';
+ static const String routeName = '/material/grid-list';
@override
GridListDemoState createState() => new GridListDemoState();
diff --git a/examples/flutter_gallery/lib/demo/icons_demo.dart b/examples/flutter_gallery/lib/demo/material/icons_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/icons_demo.dart
rename to examples/flutter_gallery/lib/demo/material/icons_demo.dart
index a609adc..d223ced 100644
--- a/examples/flutter_gallery/lib/demo/icons_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/icons_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class IconsDemo extends StatefulWidget {
- static const String routeName = '/icons';
+ static const String routeName = '/material/icons';
@override
IconsDemoState createState() => new IconsDemoState();
diff --git a/examples/flutter_gallery/lib/demo/leave_behind_demo.dart b/examples/flutter_gallery/lib/demo/material/leave_behind_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/leave_behind_demo.dart
rename to examples/flutter_gallery/lib/demo/material/leave_behind_demo.dart
index df8e61e..a229f7a 100644
--- a/examples/flutter_gallery/lib/demo/leave_behind_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/leave_behind_demo.dart
@@ -31,7 +31,7 @@
class LeaveBehindDemo extends StatefulWidget {
LeaveBehindDemo({ Key key }) : super(key: key);
- static const String routeName = '/leave-behind';
+ static const String routeName = '/material/leave-behind';
@override
LeaveBehindDemoState createState() => new LeaveBehindDemoState();
diff --git a/examples/flutter_gallery/lib/demo/list_demo.dart b/examples/flutter_gallery/lib/demo/material/list_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/list_demo.dart
rename to examples/flutter_gallery/lib/demo/material/list_demo.dart
index ddf9578..646770d 100644
--- a/examples/flutter_gallery/lib/demo/list_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/list_demo.dart
@@ -7,7 +7,7 @@
class ListDemo extends StatefulWidget {
ListDemo({ Key key }) : super(key: key);
- static const String routeName = '/list';
+ static const String routeName = '/material/list';
@override
_ListDemoState createState() => new _ListDemoState();
diff --git a/examples/flutter_gallery/lib/demo/material/material.dart b/examples/flutter_gallery/lib/demo/material/material.dart
new file mode 100644
index 0000000..96078a8
--- /dev/null
+++ b/examples/flutter_gallery/lib/demo/material/material.dart
@@ -0,0 +1,32 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+export 'bottom_navigation_demo.dart';
+export 'buttons_demo.dart';
+export 'cards_demo.dart';
+export 'chip_demo.dart';
+export 'data_table_demo.dart';
+export 'date_and_time_picker_demo.dart';
+export 'dialog_demo.dart';
+export 'drawer_demo.dart';
+export 'expansion_panels_demo.dart';
+export 'grid_list_demo.dart';
+export 'icons_demo.dart';
+export 'leave_behind_demo.dart';
+export 'list_demo.dart';
+export 'menu_demo.dart';
+export 'modal_bottom_sheet_demo.dart';
+export 'overscroll_demo.dart';
+export 'page_selector_demo.dart';
+export 'persistent_bottom_sheet_demo.dart';
+export 'progress_indicator_demo.dart';
+export 'scrollable_tabs_demo.dart';
+export 'selection_controls_demo.dart';
+export 'slider_demo.dart';
+export 'snack_bar_demo.dart';
+export 'tabs_demo.dart';
+export 'tabs_fab_demo.dart';
+export 'text_field_demo.dart';
+export 'tooltip_demo.dart';
+export 'two_level_list_demo.dart';
diff --git a/examples/flutter_gallery/lib/demo/menu_demo.dart b/examples/flutter_gallery/lib/demo/material/menu_demo.dart
similarity index 99%
rename from examples/flutter_gallery/lib/demo/menu_demo.dart
rename to examples/flutter_gallery/lib/demo/material/menu_demo.dart
index 0822629..b355dff 100644
--- a/examples/flutter_gallery/lib/demo/menu_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/menu_demo.dart
@@ -7,7 +7,7 @@
class MenuDemo extends StatefulWidget {
MenuDemo({ Key key }) : super(key: key);
- static const String routeName = '/menu';
+ static const String routeName = '/material/menu';
@override
MenuDemoState createState() => new MenuDemoState();
diff --git a/examples/flutter_gallery/lib/demo/modal_bottom_sheet_demo.dart b/examples/flutter_gallery/lib/demo/material/modal_bottom_sheet_demo.dart
similarity index 94%
rename from examples/flutter_gallery/lib/demo/modal_bottom_sheet_demo.dart
rename to examples/flutter_gallery/lib/demo/material/modal_bottom_sheet_demo.dart
index 24650f1..c0eee71 100644
--- a/examples/flutter_gallery/lib/demo/modal_bottom_sheet_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/modal_bottom_sheet_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class ModalBottomSheetDemo extends StatelessWidget {
- static const String routeName = '/modal-bottom-sheet';
+ static const String routeName = '/material/modal-bottom-sheet';
@override
Widget build(BuildContext context) {
diff --git a/examples/flutter_gallery/lib/demo/overscroll_demo.dart b/examples/flutter_gallery/lib/demo/material/overscroll_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/overscroll_demo.dart
rename to examples/flutter_gallery/lib/demo/material/overscroll_demo.dart
index a8079ef..4e28e80 100644
--- a/examples/flutter_gallery/lib/demo/overscroll_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/overscroll_demo.dart
@@ -11,7 +11,7 @@
class OverscrollDemo extends StatefulWidget {
OverscrollDemo({ Key key }) : super(key: key);
- static const String routeName = '/overscroll';
+ static const String routeName = '/material/overscroll';
@override
OverscrollDemoState createState() => new OverscrollDemoState();
diff --git a/examples/flutter_gallery/lib/demo/page_selector_demo.dart b/examples/flutter_gallery/lib/demo/material/page_selector_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/page_selector_demo.dart
rename to examples/flutter_gallery/lib/demo/material/page_selector_demo.dart
index ba0d04b..d4f0dc5 100644
--- a/examples/flutter_gallery/lib/demo/page_selector_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/page_selector_demo.dart
@@ -63,7 +63,7 @@
}
class PageSelectorDemo extends StatelessWidget {
- static const String routeName = '/page-selector';
+ static const String routeName = '/material/page-selector';
static final List<IconData> icons = <IconData>[
Icons.event,
Icons.home,
diff --git a/examples/flutter_gallery/lib/demo/persistent_bottom_sheet_demo.dart b/examples/flutter_gallery/lib/demo/material/persistent_bottom_sheet_demo.dart
similarity index 96%
rename from examples/flutter_gallery/lib/demo/persistent_bottom_sheet_demo.dart
rename to examples/flutter_gallery/lib/demo/material/persistent_bottom_sheet_demo.dart
index 5844eb5..4f0df21 100644
--- a/examples/flutter_gallery/lib/demo/persistent_bottom_sheet_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/persistent_bottom_sheet_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class PersistentBottomSheetDemo extends StatefulWidget {
- static const String routeName = '/persistent-bottom-sheet';
+ static const String routeName = '/material/persistent-bottom-sheet';
@override
_PersistentBottomSheetDemoState createState() => new _PersistentBottomSheetDemoState();
diff --git a/examples/flutter_gallery/lib/demo/progress_indicator_demo.dart b/examples/flutter_gallery/lib/demo/material/progress_indicator_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/progress_indicator_demo.dart
rename to examples/flutter_gallery/lib/demo/material/progress_indicator_demo.dart
index 8f773fb..0385d6a 100644
--- a/examples/flutter_gallery/lib/demo/progress_indicator_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/progress_indicator_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class ProgressIndicatorDemo extends StatefulWidget {
- static const String routeName = '/progress-indicator';
+ static const String routeName = '/material/progress-indicator';
@override
_ProgressIndicatorDemoState createState() => new _ProgressIndicatorDemoState();
diff --git a/examples/flutter_gallery/lib/demo/scrollable_tabs_demo.dart b/examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/scrollable_tabs_demo.dart
rename to examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart
index b969e62..2e4901c 100644
--- a/examples/flutter_gallery/lib/demo/scrollable_tabs_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/scrollable_tabs_demo.dart
@@ -26,7 +26,7 @@
];
class ScrollableTabsDemo extends StatefulWidget {
- static const String routeName = '/scrollable-tabs';
+ static const String routeName = '/material/scrollable-tabs';
@override
ScrollableTabsDemoState createState() => new ScrollableTabsDemoState();
diff --git a/examples/flutter_gallery/lib/demo/selection_controls_demo.dart b/examples/flutter_gallery/lib/demo/material/selection_controls_demo.dart
similarity index 96%
rename from examples/flutter_gallery/lib/demo/selection_controls_demo.dart
rename to examples/flutter_gallery/lib/demo/material/selection_controls_demo.dart
index 8cb9208..f0f560c 100644
--- a/examples/flutter_gallery/lib/demo/selection_controls_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/selection_controls_demo.dart
@@ -4,7 +4,7 @@
import 'package:flutter/material.dart';
-import '../gallery/demo.dart';
+import '../../gallery/demo.dart';
const String _checkboxText =
"Checkboxes allow the user to select multiple options from a set.";
@@ -26,7 +26,7 @@
const String _switchCode = 'selectioncontrols_switch';
class SelectionControlsDemo extends StatefulWidget {
- static const String routeName = '/selection-controls';
+ static const String routeName = '/material/selection-controls';
@override
_SelectionControlsDemoState createState() => new _SelectionControlsDemoState();
@@ -169,15 +169,15 @@
value: switchValue,
onChanged: (bool value) {
setState(() {
- switchValue = value;
+ switchValue = value;
});
}
),
// Disabled switches
new Switch(value: true, onChanged: null),
new Switch(value: false, onChanged: null)
- ]
- )
+ ],
+ ),
);
}
}
diff --git a/examples/flutter_gallery/lib/demo/slider_demo.dart b/examples/flutter_gallery/lib/demo/material/slider_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/slider_demo.dart
rename to examples/flutter_gallery/lib/demo/material/slider_demo.dart
index dd55070..41d142a 100644
--- a/examples/flutter_gallery/lib/demo/slider_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/slider_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class SliderDemo extends StatefulWidget {
- static const String routeName = '/slider';
+ static const String routeName = '/material/slider';
@override
_SliderDemoState createState() => new _SliderDemoState();
diff --git a/examples/flutter_gallery/lib/demo/snack_bar_demo.dart b/examples/flutter_gallery/lib/demo/material/snack_bar_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/snack_bar_demo.dart
rename to examples/flutter_gallery/lib/demo/material/snack_bar_demo.dart
index dfc2fe8..e78d255 100644
--- a/examples/flutter_gallery/lib/demo/snack_bar_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/snack_bar_demo.dart
@@ -19,7 +19,7 @@
class SnackBarDemo extends StatefulWidget {
SnackBarDemo({ Key key }) : super(key: key);
- static const String routeName = '/snack-bar';
+ static const String routeName = '/material/snack-bar';
@override
_SnackBarDemoState createState() => new _SnackBarDemoState();
diff --git a/examples/flutter_gallery/lib/demo/tabs_demo.dart b/examples/flutter_gallery/lib/demo/material/tabs_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/tabs_demo.dart
rename to examples/flutter_gallery/lib/demo/material/tabs_demo.dart
index 6e41931..767afc8 100644
--- a/examples/flutter_gallery/lib/demo/tabs_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/tabs_demo.dart
@@ -112,7 +112,7 @@
}
class TabsDemo extends StatelessWidget {
- static const String routeName = '/tabs';
+ static const String routeName = '/material/tabs';
@override
Widget build(BuildContext context) {
diff --git a/examples/flutter_gallery/lib/demo/tabs_fab_demo.dart b/examples/flutter_gallery/lib/demo/material/tabs_fab_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/tabs_fab_demo.dart
rename to examples/flutter_gallery/lib/demo/material/tabs_fab_demo.dart
index 5cdfa53..168479b 100644
--- a/examples/flutter_gallery/lib/demo/tabs_fab_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/tabs_fab_demo.dart
@@ -33,7 +33,7 @@
];
class TabsFabDemo extends StatefulWidget {
- static const String routeName = '/tabs-fab';
+ static const String routeName = '/material/tabs-fab';
@override
_TabsFabDemoState createState() => new _TabsFabDemoState();
diff --git a/examples/flutter_gallery/lib/demo/text_field_demo.dart b/examples/flutter_gallery/lib/demo/material/text_field_demo.dart
similarity index 98%
rename from examples/flutter_gallery/lib/demo/text_field_demo.dart
rename to examples/flutter_gallery/lib/demo/material/text_field_demo.dart
index 99f581c..d84487f 100644
--- a/examples/flutter_gallery/lib/demo/text_field_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/text_field_demo.dart
@@ -9,7 +9,7 @@
class TextFieldDemo extends StatefulWidget {
TextFieldDemo({ Key key }) : super(key: key);
- static const String routeName = '/text-field';
+ static const String routeName = '/material/text-field';
@override
TextFieldDemoState createState() => new TextFieldDemoState();
diff --git a/examples/flutter_gallery/lib/demo/tooltip_demo.dart b/examples/flutter_gallery/lib/demo/material/tooltip_demo.dart
similarity index 97%
rename from examples/flutter_gallery/lib/demo/tooltip_demo.dart
rename to examples/flutter_gallery/lib/demo/material/tooltip_demo.dart
index 164f49e..84c3c0d 100644
--- a/examples/flutter_gallery/lib/demo/tooltip_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/tooltip_demo.dart
@@ -11,7 +11,7 @@
class TooltipDemo extends StatelessWidget {
- static const String routeName = '/tooltips';
+ static const String routeName = '/material/tooltips';
@override
Widget build(BuildContext context) {
diff --git a/examples/flutter_gallery/lib/demo/two_level_list_demo.dart b/examples/flutter_gallery/lib/demo/material/two_level_list_demo.dart
similarity index 94%
rename from examples/flutter_gallery/lib/demo/two_level_list_demo.dart
rename to examples/flutter_gallery/lib/demo/material/two_level_list_demo.dart
index 392685b..2307926 100644
--- a/examples/flutter_gallery/lib/demo/two_level_list_demo.dart
+++ b/examples/flutter_gallery/lib/demo/material/two_level_list_demo.dart
@@ -5,7 +5,7 @@
import 'package:flutter/material.dart';
class TwoLevelListDemo extends StatelessWidget {
- static const String routeName = '/two-level-list';
+ static const String routeName = '/material/two-level-list';
@override
Widget build(BuildContext context) {
diff --git a/examples/flutter_gallery/lib/gallery/item.dart b/examples/flutter_gallery/lib/gallery/item.dart
index 8f9a9c4..c68f110 100644
--- a/examples/flutter_gallery/lib/gallery/item.dart
+++ b/examples/flutter_gallery/lib/gallery/item.dart
@@ -11,7 +11,7 @@
typedef Widget GalleryDemoBuilder();
class GalleryItem extends StatelessWidget {
- GalleryItem({ this.title, this.subtitle, this.category: 'Components', this.routeName, this.buildRoute }) {
+ GalleryItem({ this.title, this.subtitle, this.category, this.routeName, this.buildRoute }) {
assert(title != null);
assert(category != null);
assert(routeName != null);
@@ -51,184 +51,247 @@
subtitle: 'Simple recipe browser',
category: 'Demos',
routeName: PestoDemo.routeName,
- buildRoute: (BuildContext context) => new PestoDemo()
+ buildRoute: (BuildContext context) => new PestoDemo(),
),
new GalleryItem(
title: 'Shrine',
subtitle:'Basic shopping app',
category: 'Demos',
routeName: ShrineDemo.routeName,
- buildRoute: (BuildContext context) => new ShrineDemo()
+ buildRoute: (BuildContext context) => new ShrineDemo(),
),
new GalleryItem(
title: 'Contact profile',
- category: 'Demos',
subtitle: 'Address book entry with a flexible appbar',
+ category: 'Demos',
routeName: ContactsDemo.routeName,
- buildRoute: (BuildContext context) => new ContactsDemo()
+ buildRoute: (BuildContext context) => new ContactsDemo(),
),
- // Components
+ // Material Components
new GalleryItem(
title: 'Bottom navigation',
subtitle: 'Bottom navigation with cross-fading views',
+ category: 'Material Components',
routeName: BottomNavigationDemo.routeName,
- buildRoute: (BuildContext context) => new BottomNavigationDemo()
+ buildRoute: (BuildContext context) => new BottomNavigationDemo(),
),
new GalleryItem(
title: 'Buttons',
subtitle: 'All kinds: flat, raised, dropdown, icon, etc',
+ category: 'Material Components',
routeName: ButtonsDemo.routeName,
- buildRoute: (BuildContext context) => new ButtonsDemo()
+ buildRoute: (BuildContext context) => new ButtonsDemo(),
),
new GalleryItem(
title: 'Cards',
subtitle: 'Material with rounded corners and a drop shadow',
+ category: 'Material Components',
routeName: CardsDemo.routeName,
- buildRoute: (BuildContext context) => new CardsDemo()
+ buildRoute: (BuildContext context) => new CardsDemo(),
),
new GalleryItem(
title: 'Chips',
subtitle: 'Label with an optional delete button and avatar',
+ category: 'Material Components',
routeName: ChipDemo.routeName,
- buildRoute: (BuildContext context) => new ChipDemo()
+ buildRoute: (BuildContext context) => new ChipDemo(),
),
new GalleryItem(
title: 'Date and time pickers',
subtitle: 'Date and time selection widgets',
+ category: 'Material Components',
routeName: DateAndTimePickerDemo.routeName,
- buildRoute: (BuildContext context) => new DateAndTimePickerDemo()
+ buildRoute: (BuildContext context) => new DateAndTimePickerDemo(),
),
new GalleryItem(
title: 'Dialog',
subtitle: 'All kinds: simple, alert, fullscreen, etc',
+ category: 'Material Components',
routeName: DialogDemo.routeName,
- buildRoute: (BuildContext context) => new DialogDemo()
+ buildRoute: (BuildContext context) => new DialogDemo(),
),
new GalleryItem(
title: 'Drawer',
subtitle: 'Navigation drawer with a standard header',
+ category: 'Material Components',
routeName: DrawerDemo.routeName,
- buildRoute: (BuildContext context) => new DrawerDemo()
+ buildRoute: (BuildContext context) => new DrawerDemo(),
),
new GalleryItem(
title: 'Expand/collapse list control',
subtitle: 'List with one level of sublists',
+ category: 'Material Components',
routeName: TwoLevelListDemo.routeName,
- buildRoute: (BuildContext context) => new TwoLevelListDemo()
+ buildRoute: (BuildContext context) => new TwoLevelListDemo(),
),
new GalleryItem(
title: 'Expansion panels',
subtitle: 'List of expanding panels',
+ category: 'Material Components',
routeName: ExpasionPanelsDemo.routeName,
- buildRoute: (BuildContext context) => new ExpasionPanelsDemo()
+ buildRoute: (BuildContext context) => new ExpasionPanelsDemo(),
),
new GalleryItem(
title: 'Floating action button',
subtitle: 'Action buttons with transitions',
+ category: 'Material Components',
routeName: TabsFabDemo.routeName,
- buildRoute: (BuildContext context) => new TabsFabDemo()
+ buildRoute: (BuildContext context) => new TabsFabDemo(),
),
new GalleryItem(
title: 'Grid',
subtitle: 'Row and column layout',
+ category: 'Material Components',
routeName: GridListDemo.routeName,
- buildRoute: (BuildContext context) => new GridListDemo()
+ buildRoute: (BuildContext context) => new GridListDemo(),
),
new GalleryItem(
title: 'Icons',
subtitle: 'Enabled and disabled icons with varying opacity',
+ category: 'Material Components',
routeName: IconsDemo.routeName,
- buildRoute: (BuildContext context) => new IconsDemo()
+ buildRoute: (BuildContext context) => new IconsDemo(),
),
new GalleryItem(
title: 'Leave-behind list items',
subtitle: 'List items with hidden actions',
+ category: 'Material Components',
routeName: LeaveBehindDemo.routeName,
- buildRoute: (BuildContext context) => new LeaveBehindDemo()
+ buildRoute: (BuildContext context) => new LeaveBehindDemo(),
),
new GalleryItem(
title: 'List',
subtitle: 'Layout variations for scrollable lists',
+ category: 'Material Components',
routeName: ListDemo.routeName,
- buildRoute: (BuildContext context) => new ListDemo()
+ buildRoute: (BuildContext context) => new ListDemo(),
),
new GalleryItem(
title: 'Menus',
subtitle: 'Menu buttons and simple menus',
+ category: 'Material Components',
routeName: MenuDemo.routeName,
- buildRoute: (BuildContext context) => new MenuDemo()
+ buildRoute: (BuildContext context) => new MenuDemo(),
),
new GalleryItem(
title: 'Modal bottom sheet',
subtitle: 'Modal sheet that slides up from the bottom',
+ category: 'Material Components',
routeName: ModalBottomSheetDemo.routeName,
- buildRoute: (BuildContext context) => new ModalBottomSheetDemo()
+ buildRoute: (BuildContext context) => new ModalBottomSheetDemo(),
),
new GalleryItem(
title: 'Page selector',
subtitle: 'PageView with indicator',
+ category: 'Material Components',
routeName: PageSelectorDemo.routeName,
- buildRoute: (BuildContext context) => new PageSelectorDemo()
+ buildRoute: (BuildContext context) => new PageSelectorDemo(),
),
new GalleryItem(
title: 'Persistent bottom sheet',
subtitle: 'Sheet that slides up from the bottom',
+ category: 'Material Components',
routeName: PersistentBottomSheetDemo.routeName,
- buildRoute: (BuildContext context) => new PersistentBottomSheetDemo()
+ buildRoute: (BuildContext context) => new PersistentBottomSheetDemo(),
),
new GalleryItem(
title: 'Progress indicators',
subtitle: 'All kinds: linear, circular, indeterminate, etc',
+ category: 'Material Components',
routeName: ProgressIndicatorDemo.routeName,
- buildRoute: (BuildContext context) => new ProgressIndicatorDemo()
+ buildRoute: (BuildContext context) => new ProgressIndicatorDemo(),
),
new GalleryItem(
title: 'Pull to refresh',
subtitle: 'Refresh indicators',
+ category: 'Material Components',
routeName: OverscrollDemo.routeName,
- buildRoute: (BuildContext context) => new OverscrollDemo()
+ buildRoute: (BuildContext context) => new OverscrollDemo(),
),
new GalleryItem(
title: 'Scrollable tabs',
subtitle: 'Tab bar that scrolls',
+ category: 'Material Components',
routeName: ScrollableTabsDemo.routeName,
- buildRoute: (BuildContext context) => new ScrollableTabsDemo()
+ buildRoute: (BuildContext context) => new ScrollableTabsDemo(),
),
new GalleryItem(
title: 'Selection controls',
subtitle: 'Checkboxes, radio buttons, and switches',
+ category: 'Material Components',
routeName: SelectionControlsDemo.routeName,
- buildRoute: (BuildContext context) => new SelectionControlsDemo()
+ buildRoute: (BuildContext context) => new SelectionControlsDemo(),
),
new GalleryItem(
title: 'Sliders',
subtitle: 'Widgets that select a value by dragging the slider thumb',
+ category: 'Material Components',
routeName: SliderDemo.routeName,
- buildRoute: (BuildContext context) => new SliderDemo()
+ buildRoute: (BuildContext context) => new SliderDemo(),
),
new GalleryItem(
title: 'Snackbar',
subtitle: 'Temporary message that appears at the bottom',
+ category: 'Material Components',
routeName: SnackBarDemo.routeName,
- buildRoute: (BuildContext context) => new SnackBarDemo()
+ buildRoute: (BuildContext context) => new SnackBarDemo(),
),
new GalleryItem(
title: 'Tabs',
subtitle: 'Tabs with independently scrollable views',
+ category: 'Material Components',
routeName: TabsDemo.routeName,
- buildRoute: (BuildContext context) => new TabsDemo()
+ buildRoute: (BuildContext context) => new TabsDemo(),
),
new GalleryItem(
title: 'Text fields',
subtitle: 'Single line of editable text and numbers',
+ category: 'Material Components',
routeName: TextFieldDemo.routeName,
- buildRoute: (BuildContext context) => new TextFieldDemo()
+ buildRoute: (BuildContext context) => new TextFieldDemo(),
),
new GalleryItem(
title: 'Tooltips',
subtitle: 'Short message displayed after a long-press',
+ category: 'Material Components',
routeName: TooltipDemo.routeName,
- buildRoute: (BuildContext context) => new TooltipDemo()
+ buildRoute: (BuildContext context) => new TooltipDemo(),
+ ),
+ // Cupertino Components
+ new GalleryItem(
+ title: 'Activity Indicator',
+ subtitle: 'Cupertino styled activity indicator',
+ category: 'Cupertino Components',
+ routeName: CupertinoProgressIndicatorDemo.routeName,
+ buildRoute: (BuildContext context) => new CupertinoProgressIndicatorDemo(),
+ ),
+ new GalleryItem(
+ title: 'Buttons',
+ subtitle: 'Cupertino styled buttons',
+ category: 'Cupertino Components',
+ routeName: CupertinoButtonsDemo.routeName,
+ buildRoute: (BuildContext context) => new CupertinoButtonsDemo(),
+ ),
+ new GalleryItem(
+ title: 'Dialogs',
+ subtitle: 'Cupertino styled dialogs',
+ category: 'Cupertino Components',
+ routeName: CupertinoDialogDemo.routeName,
+ buildRoute: (BuildContext context) => new CupertinoDialogDemo(),
+ ),
+ new GalleryItem(
+ title: 'Sliders',
+ subtitle: 'Cupertino styled sliders',
+ category: 'Cupertino Components',
+ routeName: CupertinoSliderDemo.routeName,
+ buildRoute: (BuildContext context) => new CupertinoSliderDemo(),
+ ),
+ new GalleryItem(
+ title: 'Switches',
+ subtitle: 'Cupertino styled switches',
+ category: 'Cupertino Components',
+ routeName: CupertinoSwitchDemo.routeName,
+ buildRoute: (BuildContext context) => new CupertinoSwitchDemo(),
),
// Styles
new GalleryItem(
@@ -236,13 +299,13 @@
subtitle: 'All of the predefined colors',
category: 'Style',
routeName: ColorsDemo.routeName,
- buildRoute: (BuildContext context) => new ColorsDemo()
+ buildRoute: (BuildContext context) => new ColorsDemo(),
),
new GalleryItem(
title: 'Typography',
subtitle: 'All of the predefined text styles',
category: 'Style',
routeName: TypographyDemo.routeName,
- buildRoute: (BuildContext context) => new TypographyDemo()
+ buildRoute: (BuildContext context) => new TypographyDemo(),
)
];
diff --git a/packages/flutter/lib/cupertino.dart b/packages/flutter/lib/cupertino.dart
index 1380952..cede429 100644
--- a/packages/flutter/lib/cupertino.dart
+++ b/packages/flutter/lib/cupertino.dart
@@ -8,6 +8,7 @@
library cupertino;
export 'src/cupertino/activity_indicator.dart';
+export 'src/cupertino/button.dart';
export 'src/cupertino/dialog.dart';
export 'src/cupertino/slider.dart';
export 'src/cupertino/switch.dart';
diff --git a/packages/flutter/lib/src/cupertino/button.dart b/packages/flutter/lib/src/cupertino/button.dart
new file mode 100644
index 0000000..f3094a8
--- /dev/null
+++ b/packages/flutter/lib/src/cupertino/button.dart
@@ -0,0 +1,174 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/foundation.dart';
+import 'package:flutter/widgets.dart';
+
+const TextStyle _kButtonTextStyle = const TextStyle(
+ fontFamily: '.SF UI Text',
+ inherit: false,
+ fontSize: 15.0,
+ fontWeight: FontWeight.normal,
+ color: CupertinoButton.kBlue,
+ textBaseline: TextBaseline.alphabetic,
+);
+
+final TextStyle _kDisabledButtonTextStyle = _kButtonTextStyle.copyWith(
+ color: CupertinoButton.kDisabledForeground,
+);
+
+final TextStyle _kBackgroundButtonTextStyle = _kButtonTextStyle.copyWith(
+ color: CupertinoButton.kWhite,
+);
+
+const EdgeInsets _kButtonPadding = const EdgeInsets.all(16.0);
+const EdgeInsets _kBackgroundButtonPadding =
+const EdgeInsets.symmetric(vertical: 16.0, horizontal: 64.0);
+
+/// An iOS style button.
+///
+/// Takes in a text or an icon that fades out and in on touch. May optionally have a
+/// background.
+///
+/// See also:
+///
+/// * <https://developer.apple.com/ios/human-interface-guidelines/ui-controls/buttons/>
+class CupertinoButton extends StatefulWidget {
+ // TODO(xster): move this to a common Cupertino color palatte with the next yak.
+ static const Color kBlue = const Color(0xFF007AFF);
+ static const Color kWhite = const Color(0xFFFFFFFF);
+ static const Color kDisabledBackground = const Color(0xFFA9A9A9);
+ static const Color kDisabledForeground = const Color(0xFFC4C4C4);
+
+
+ CupertinoButton({
+ @required this.child,
+ this.padding,
+ this.color,
+ @required this.onPressed,
+ });
+
+ /// The widget below this widget in the tree.
+ ///
+ /// Typically a [Text] widget.
+ final Widget child;
+
+ /// The amount of space to surround the child inside the bounds of the button.
+ ///
+ /// Defaults to 16.0 pixels.
+ final EdgeInsets padding;
+
+ /// The color of the button's background.
+ ///
+ /// Defaults to null which produces a button with no background or border.
+ final Color color;
+
+ /// The callback that is called when the button is tapped or otherwise activated.
+ ///
+ /// If this is set to null, the button will be disabled.
+ final VoidCallback onPressed;
+
+ /// Whether the button is enabled or disabled. Buttons are disabled by default. To
+ /// enable a button, set its [onPressed] property to a non-null value.
+ bool get enabled => onPressed != null;
+
+ @override
+ _CupertinoButtonState createState() => new _CupertinoButtonState();
+
+ @override
+ void debugFillDescription(List<String> description) {
+ super.debugFillDescription(description);
+ if (!enabled)
+ description.add('disabled');
+ }
+}
+
+class _CupertinoButtonState extends State<CupertinoButton> with SingleTickerProviderStateMixin {
+ // Eyeballed values. Feel free to tweak.
+ static const Duration kFadeOutDuration = const Duration(milliseconds: 10);
+ static const Duration kFadeInDuration = const Duration(milliseconds: 350);
+
+ AnimationController _animationController;
+
+ @override
+ void initState() {
+ super.initState();
+ _animationController = new AnimationController(
+ duration: const Duration(milliseconds: 200),
+ value: 1.0,
+ vsync: this,
+ );
+ }
+
+ @override
+ void dispose() {
+ _animationController.dispose();
+ _animationController = null;
+ super.dispose();
+ }
+
+ void _handleTapDown(PointerDownEvent event) {
+ _animationController.animateTo(0.1, duration: kFadeOutDuration);
+ }
+
+ void _handleTapUp(PointerUpEvent event) {
+ _animationController.animateTo(1.0, duration: kFadeInDuration);
+ }
+
+ void _handleTapCancel(PointerCancelEvent event) {
+ _animationController.animateTo(1.0, duration: kFadeInDuration);
+ }
+
+ @override
+ Widget build(BuildContext context) {
+ final bool enabled = config.enabled;
+ final Color backgroundColor = config.color;
+
+ return new Listener(
+ onPointerDown: enabled ? _handleTapDown : null,
+ onPointerUp: enabled ? _handleTapUp : null,
+ onPointerCancel: enabled ? _handleTapCancel : null,
+
+ child: new GestureDetector(
+ onTap: config.onPressed,
+ child: new ConstrainedBox(
+ constraints: const BoxConstraints(minWidth: 48.0, minHeight: 48.0),
+ child: new FadeTransition(
+ opacity: new CurvedAnimation(
+ parent: _animationController,
+ curve: Curves.decelerate,
+ ),
+ child: new DecoratedBox(
+ decoration: new BoxDecoration(
+ borderRadius: const BorderRadius.all(const Radius.circular(8.0)),
+ backgroundColor: backgroundColor != null && !enabled
+ ? CupertinoButton.kDisabledBackground
+ : backgroundColor,
+ ),
+ child: new Padding(
+ padding: config.padding != null
+ ? config.padding
+ : backgroundColor != null
+ ? _kBackgroundButtonPadding
+ : _kButtonPadding,
+ child: new Center(
+ widthFactor: 1.0,
+ heightFactor: 1.0,
+ child: new DefaultTextStyle(
+ style: backgroundColor != null
+ ? _kBackgroundButtonTextStyle
+ : enabled
+ ? _kButtonTextStyle
+ : _kDisabledButtonTextStyle,
+ child: config.child,
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ ),
+ );
+ }
+}
diff --git a/packages/flutter/lib/src/cupertino/dialog.dart b/packages/flutter/lib/src/cupertino/dialog.dart
index 39cb213..4317988 100644
--- a/packages/flutter/lib/src/cupertino/dialog.dart
+++ b/packages/flutter/lib/src/cupertino/dialog.dart
@@ -10,8 +10,8 @@
const TextStyle _kCupertinoDialogTitleStyle = const TextStyle(
fontFamily: '.SF UI Display',
inherit: false,
- fontSize: 16.0,
- fontWeight: FontWeight.bold,
+ fontSize: 17.0,
+ fontWeight: FontWeight.w600,
color: const Color(0xFF000000),
height: 1.35,
textBaseline: TextBaseline.alphabetic,
@@ -127,7 +127,7 @@
if (title != null) {
children.add(new Padding(
- padding: const EdgeInsets.symmetric(horizontal: 20.0),
+ padding: const EdgeInsets.only(left: 20.0, right: 20.0, bottom: 12.0),
child: new DefaultTextStyle(
style: _kCupertinoDialogTitleStyle,
textAlign: TextAlign.center,
diff --git a/packages/flutter/test/cupertino/button_test.dart b/packages/flutter/test/cupertino/button_test.dart
new file mode 100644
index 0000000..3a4d329
--- /dev/null
+++ b/packages/flutter/test/cupertino/button_test.dart
@@ -0,0 +1,101 @@
+// Copyright 2017 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import 'package:flutter/cupertino.dart';
+import 'package:flutter/scheduler.dart';
+import 'package:flutter/widgets.dart';
+import 'package:flutter_test/flutter_test.dart';
+
+void main() {
+ testWidgets('Layout minimum size', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ new Center(child: new CupertinoButton(child: new Text(' '), onPressed: null))
+ );
+ RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
+ expect(
+ buttonBox.size,
+ greaterThanOrEqualTo(const Size.square(48.0)),
+ );
+ expect(
+ buttonBox.size,
+ lessThan(const Size.square(100.0)),
+ );
+ });
+
+ testWidgets('Size grows with text', (WidgetTester tester) async {
+ await tester.pumpWidget(
+ new Center(child: new CupertinoButton(child: new Text('blah blah blah'), onPressed: null))
+ );
+ RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
+ expect(
+ buttonBox.size.width,
+ greaterThan(48.0),
+ );
+ });
+
+ testWidgets('Button with background is wider', (WidgetTester tester) async {
+ await tester.pumpWidget(new Center(child: new CupertinoButton(
+ child: new Text(' '),
+ onPressed: null,
+ color: new Color(0xFFFFFFFF),
+ )));
+ RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
+ expect(
+ buttonBox.size.width,
+ greaterThan(120.0),
+ );
+ });
+
+ testWidgets('Custom padding', (WidgetTester tester) async {
+ await tester.pumpWidget(new Center(child: new CupertinoButton(
+ child: new Text(' '),
+ onPressed: null,
+ padding: new EdgeInsets.all(100.0),
+ )));
+ RenderBox buttonBox = tester.renderObject(find.byType(CupertinoButton));
+ expect(
+ buttonBox.size,
+ greaterThan(const Size.square(100.0)),
+ );
+ });
+
+ testWidgets('Button takes taps', (WidgetTester tester) async {
+ bool value = false;
+ await tester.pumpWidget(
+ new StatefulBuilder(
+ builder: (BuildContext context, StateSetter setState) {
+ return new Center(
+ child: new CupertinoButton(
+ child: new Text('Tap me'),
+ onPressed: () {
+ setState(() {
+ value = true;
+ });
+ },
+ ),
+ );
+ },
+ ),
+ );
+
+ expect(value, isFalse);
+ // No animating by default.
+ expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
+ await tester.tap(find.byType(CupertinoButton));
+ expect(value, isTrue);
+ // Animates.
+ expect(SchedulerBinding.instance.transientCallbackCount, equals(1));
+ });
+
+ testWidgets('Disabled button doesn\'t animate', (WidgetTester tester) async {
+ await tester.pumpWidget(new Center(child: new CupertinoButton(
+ child: new Text('Tap me'),
+ onPressed: null,
+ )));
+ expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
+ await tester.tap(find.byType(CupertinoButton));
+ // Still doesn't animate.
+ expect(SchedulerBinding.instance.transientCallbackCount, equals(0));
+ });
+}