diff --git a/README.md b/README.md index dea7aff..7257fbe 100644 --- a/README.md +++ b/README.md @@ -135,10 +135,9 @@ Check proposal documents for [v1.0](https://github.com/fluttercommunity/backdrop 2. Fork the [repository](https://github.com/fluttercommunity/backdrop). 3. Pick an issue to work on from [issue tracker](https://github.com/fluttercommunity/backdrop/issues). 4. Implement it. -5. Add your name and email in `authors` section in `pubspec.yaml` file. -6. Send merge request. -7. Star this project. -8. Become a hero!! +5. Send merge request. +6. Star this project. +7. Become a hero!! ## Features and bugs Please file feature requests and bugs at the [issue tracker](https://github.com/fluttercommunity/backdrop/issues). diff --git a/analysis_options.yaml b/analysis_options.yaml index 6715b49..c64af5a 100644 --- a/analysis_options.yaml +++ b/analysis_options.yaml @@ -1,13 +1,35 @@ -include: package:pedantic/analysis_options.yaml +# This file configures the analyzer, which statically analyzes Dart code to +# check for errors, warnings, and lints. +# +# The issues identified by the analyzer are surfaced in the UI of Dart-enabled +# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be +# invoked from the command line by running `flutter analyze`. -analyzer: - exclude: [build/**] - strong-mode: - implicit-casts: false +# The following line activates a set of recommended lints for Flutter apps, +# packages, and plugins designed to encourage good coding practices. +include: package:flutter_lints/flutter.yaml linter: + # The lint rules applied to this project can be customized in the + # section below to disable rules from the `package:flutter_lints/flutter.yaml` + # included above or to enable additional rules. A list of all available lints + # and their documentation is published at + # https://dart-lang.github.io/linter/lints/index.html. + # + # Instead of disabling a lint rule for the entire project in the + # section below, it can also be suppressed for a single line of code + # or a specific dart file by using the `// ignore: name_of_lint` and + # `// ignore_for_file: name_of_lint` syntax on the line or in the file + # producing the lint. rules: - - camel_case_types - - public_member_api_docs + # doc-style related: https://dart.dev/guides/language/effective-dart/documentation - package_api_docs + - public_member_api_docs + - comment_references - slash_for_doc_comments + # pub related: https://dart.dev/tools/linter-rules#pub-rules + - depend_on_referenced_packages + - secure_pubspec_urls + +# Additional information about this file can be found at +# https://dart.dev/guides/language/analysis-options diff --git a/demo/lib/main.dart b/demo/lib/main.dart index dee23a6..bcedc14 100644 --- a/demo/lib/main.dart +++ b/demo/lib/main.dart @@ -7,23 +7,28 @@ import 'package:flutter/material.dart'; import 'package:gallerize/gallerize.dart'; import 'package:gallerize/themes/gallerize_theme_data.dart'; -void main() => runApp(DemoApp()); +void main() => runApp(const DemoApp()); /// Demo app that provides a show-case of different backdrop use cases. class DemoApp extends StatelessWidget { + /// Default constructor for [DemoApp]. + const DemoApp({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return MaterialApp( title: "Backdrop Gallery", theme: GallerizeThemeData.darkThemeData, - home: HomePage(), + home: _HomePage(), ); } } /// The home page of the demo app showing a selection of use cases. -class HomePage extends StatelessWidget { - List _useCases = [ +class _HomePage extends StatelessWidget { + _HomePage({Key? key}) : super(key: key); + + final _useCases = [ ContextualInfoUseCase(), ContextualControlsUseCase(), NavigationUseCase(), @@ -34,16 +39,16 @@ class HomePage extends StatelessWidget { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text("Backdrop Gallery"), + title: const Text("Backdrop Gallery"), ), body: Column( children: [ Container( - margin: EdgeInsets.all(16.0), - child: - Text("This app shows some use cases for the backdrop widget. " - "Open any one to show information about it, preview it and " - "look at its code."), + margin: const EdgeInsets.all(16.0), + child: const Text( + "This app shows some use cases for the backdrop widget. " + "Open any one to show information about it, preview it and " + "look at its code."), ), ListView.separated( itemCount: _useCases.length, @@ -52,7 +57,7 @@ class HomePage extends StatelessWidget { onTap: () => _openDemoPage(context, _useCases[index]), ), shrinkWrap: true, - separatorBuilder: (context, index) => Divider(), + separatorBuilder: (context, index) => const Divider(), ), ], ), diff --git a/demo/lib/use_cases/contextual_controls/contextual_controls.dart b/demo/lib/use_cases/contextual_controls/contextual_controls.dart index ebc2f87..344468a 100644 --- a/demo/lib/use_cases/contextual_controls/contextual_controls.dart +++ b/demo/lib/use_cases/contextual_controls/contextual_controls.dart @@ -3,22 +3,25 @@ import 'package:flutter/material.dart'; /// Contextual controls preview app. class ContextualControls extends StatefulWidget { + /// Default constructor for [ContextualControls]. + const ContextualControls({Key? key}) : super(key: key); + @override _ContextualControlsState createState() => _ContextualControlsState(); } class _ContextualControlsState extends State { - static final _COLOR_MAP = { + static final _colorMap = { Colors.black: "Black", Colors.red: "Red", Colors.green: "Green", Colors.blue: "Blue" }; - static const _RAM_CHOICES = [4, 8, 16]; + static const _ramChoices = [4, 8, 16]; - Color _color = _COLOR_MAP.keys.first; + Color _color = _colorMap.keys.first; double _resolution = 15.0; - int _ram = _RAM_CHOICES.first; + int _ram = _ramChoices.first; @override Widget build(BuildContext context) { @@ -26,7 +29,7 @@ class _ContextualControlsState extends State { data: ThemeData.light(), child: BackdropScaffold( appBar: BackdropAppBar( - title: Text("Contextual Controls Example"), + title: const Text("Contextual Controls Example"), automaticallyImplyLeading: false, ), backLayer: _createBackLayer(context), @@ -41,7 +44,7 @@ class _ContextualControlsState extends State { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text( "Color", ), @@ -50,10 +53,10 @@ class _ContextualControlsState extends State { title: DropdownButton( isExpanded: true, value: _color, - items: _COLOR_MAP.keys.map>((Color c) { + items: _colorMap.keys.map>((Color c) { return DropdownMenuItem( value: c, - child: Text(_COLOR_MAP[c]!), + child: Text(_colorMap[c]!), ); }).toList(), onChanged: (Color? newValue) { @@ -66,7 +69,7 @@ class _ContextualControlsState extends State { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text("Resolution"), ], ), @@ -86,14 +89,14 @@ class _ContextualControlsState extends State { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text("RAM"), ], ), title: DropdownButton( isExpanded: true, value: _ram, - items: _RAM_CHOICES.map>((int r) { + items: _ramChoices.map>((int r) { return DropdownMenuItem( value: r, child: Text("${r.toString()} GB"), @@ -108,7 +111,7 @@ class _ContextualControlsState extends State { ), Builder( builder: (context) => MaterialButton( - child: Text("Return to product page"), + child: const Text("Return to product page"), onPressed: () => Backdrop.of(context).fling(), )) ], @@ -116,7 +119,7 @@ class _ContextualControlsState extends State { ); Widget _createFrontLayer(BuildContext context) => Container( - margin: EdgeInsets.all(16.0), + margin: const EdgeInsets.all(16.0), child: Column( children: [ Row( @@ -138,13 +141,13 @@ class _ContextualControlsState extends State { ], ), Container( - margin: EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( - children: [ + children: const [ Icon(Icons.star, color: Colors.grey), Icon(Icons.star, color: Colors.grey), Icon(Icons.star, color: Colors.grey), @@ -152,7 +155,7 @@ class _ContextualControlsState extends State { Icon(Icons.star_half, color: Colors.grey), ], ), - Text( + const Text( "73 Reviews", style: TextStyle(color: Colors.grey), ) @@ -163,13 +166,13 @@ class _ContextualControlsState extends State { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( + const Text( "Price", style: TextStyle(color: Colors.grey), ), Container( - margin: EdgeInsets.all(8.0), - child: Text( + margin: const EdgeInsets.all(8.0), + child: const Text( "\$999", style: TextStyle(fontSize: 18), ), @@ -177,7 +180,7 @@ class _ContextualControlsState extends State { ], ), Container( - margin: EdgeInsets.only( + margin: const EdgeInsets.only( top: 32.0, left: 8.0, right: 8.0, bottom: 8.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -185,17 +188,17 @@ class _ContextualControlsState extends State { children: [ Column( mainAxisAlignment: MainAxisAlignment.center, - children: [Text("Resolution")], + children: const [Text("Resolution")], ), Text( "${_resolution.toString()}\"", - style: TextStyle(fontWeight: FontWeight.bold), + style: const TextStyle(fontWeight: FontWeight.bold), ), ], ), ), Container( - margin: EdgeInsets.only( + margin: const EdgeInsets.only( top: 8.0, left: 8.0, right: 8.0, bottom: 32.0), child: Row( mainAxisAlignment: MainAxisAlignment.spaceEvenly, @@ -203,24 +206,24 @@ class _ContextualControlsState extends State { children: [ Column( mainAxisAlignment: MainAxisAlignment.center, - children: [Text("RAM")], + children: const [Text("RAM")], ), Text( "${_ram.toString()} GB", - style: TextStyle(fontWeight: FontWeight.bold), + style: const TextStyle(fontWeight: FontWeight.bold), ), ], ), ), Container( - margin: EdgeInsets.all(16.0), + margin: const EdgeInsets.all(16.0), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Builder( - builder: (context) => RaisedButton( - child: Text("Configure"), + builder: (context) => ElevatedButton( + child: const Text("Configure"), onPressed: () => Backdrop.of(context).fling(), ), ) diff --git a/demo/lib/use_cases/contextual_controls/contextual_controls_use_case.dart b/demo/lib/use_cases/contextual_controls/contextual_controls_use_case.dart index 677cf29..07a8e99 100644 --- a/demo/lib/use_cases/contextual_controls/contextual_controls_use_case.dart +++ b/demo/lib/use_cases/contextual_controls/contextual_controls_use_case.dart @@ -10,6 +10,6 @@ class ContextualControlsUseCase extends UseCase { "The backdrop's back layer can be used to control the content that is being " "shown on the front layer."; codeFile = "lib/use_cases/contextual_controls/contextual_controls.dart"; - preview = ContextualControls(); + preview = const ContextualControls(); } } diff --git a/demo/lib/use_cases/contextual_info/contextual_info.dart b/demo/lib/use_cases/contextual_info/contextual_info.dart index dc48a5c..1bb495c 100644 --- a/demo/lib/use_cases/contextual_info/contextual_info.dart +++ b/demo/lib/use_cases/contextual_info/contextual_info.dart @@ -1,17 +1,18 @@ import 'package:backdrop/backdrop.dart'; import 'package:flutter/material.dart'; -import 'package:flutter/painting.dart'; -import 'package:flutter/rendering.dart'; /// Contextual info preview app. class ContextualInfo extends StatelessWidget { + /// Default constructor for [ContextualInfo]. + const ContextualInfo({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Theme( data: ThemeData.light(), child: BackdropScaffold( appBar: BackdropAppBar( - title: Text("Contextual Info Example"), + title: const Text("Contextual Info Example"), automaticallyImplyLeading: false, ), backLayer: _createBackLayer(context), @@ -26,13 +27,13 @@ class ContextualInfo extends StatelessWidget { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text( "Name", ), ], ), - title: Text( + title: const Text( "Laptop Model X", style: TextStyle(fontWeight: FontWeight.bold), ), @@ -40,11 +41,11 @@ class ContextualInfo extends StatelessWidget { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text("Year of production"), ], ), - title: Text( + title: const Text( "2019", style: TextStyle(fontWeight: FontWeight.bold), ), @@ -52,11 +53,11 @@ class ContextualInfo extends StatelessWidget { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text("Place of Manufacture"), ], ), - title: Text( + title: const Text( "USA", style: TextStyle(fontWeight: FontWeight.bold), ), @@ -64,11 +65,11 @@ class ContextualInfo extends StatelessWidget { ListTile( leading: Column( mainAxisAlignment: MainAxisAlignment.center, - children: [ + children: const [ Text("Price"), ], ), - title: Text( + title: const Text( "\$999", style: TextStyle(fontWeight: FontWeight.bold), ), @@ -78,14 +79,14 @@ class ContextualInfo extends StatelessWidget { ); Widget _createFrontLayer(BuildContext context) => Container( - margin: EdgeInsets.all(16.0), + margin: const EdgeInsets.all(16.0), child: Column( children: [ Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ - Icon( + const Icon( Icons.computer, size: 64.0, ), @@ -102,13 +103,13 @@ class ContextualInfo extends StatelessWidget { mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.center, children: [ - Text( + const Text( "Price", style: TextStyle(color: Colors.grey), ), Container( - margin: EdgeInsets.all(8.0), - child: Text( + margin: const EdgeInsets.all(8.0), + child: const Text( "\$999", style: TextStyle(fontSize: 18), ), @@ -116,13 +117,13 @@ class ContextualInfo extends StatelessWidget { ], ), Container( - margin: EdgeInsets.all(8.0), + margin: const EdgeInsets.all(8.0), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceEvenly, children: [ Row( - children: [ + children: const [ Icon(Icons.star, color: Colors.grey), Icon(Icons.star, color: Colors.grey), Icon(Icons.star, color: Colors.grey), @@ -130,7 +131,7 @@ class ContextualInfo extends StatelessWidget { Icon(Icons.star_half, color: Colors.grey), ], ), - Text( + const Text( "73 Reviews", style: TextStyle(color: Colors.grey), ) @@ -138,14 +139,14 @@ class ContextualInfo extends StatelessWidget { ), ), Container( - margin: EdgeInsets.all(16.0), + margin: const EdgeInsets.all(16.0), child: Row( mainAxisSize: MainAxisSize.max, mainAxisAlignment: MainAxisAlignment.spaceAround, children: [ Builder( - builder: (context) => RaisedButton( - child: Text("More about this product"), + builder: (context) => ElevatedButton( + child: const Text("More about this product"), onPressed: () => Backdrop.of(context).fling(), ), ) @@ -159,13 +160,13 @@ class ContextualInfo extends StatelessWidget { .headline6! .apply(color: Colors.black)), ), - ListTile( + const ListTile( leading: Icon(Icons.account_box), title: Text("Really satisfied!"), subtitle: Text("John Doe"), trailing: Text("5/5"), ), - ListTile( + const ListTile( leading: Icon(Icons.account_box), title: Text("Good price!"), subtitle: Text("Jane Doe"), diff --git a/demo/lib/use_cases/contextual_info/contextual_info_use_case.dart b/demo/lib/use_cases/contextual_info/contextual_info_use_case.dart index 0bdadd2..072f600 100644 --- a/demo/lib/use_cases/contextual_info/contextual_info_use_case.dart +++ b/demo/lib/use_cases/contextual_info/contextual_info_use_case.dart @@ -10,6 +10,6 @@ class ContextualInfoUseCase extends UseCase { "The backdrop's back layer can be used to show contextual information " "in addition to the content shown on the front layer."; codeFile = "lib/use_cases/contextual_info/contextual_info.dart"; - preview = ContextualInfo(); + preview = const ContextualInfo(); } } diff --git a/demo/lib/use_cases/filter/filter.dart b/demo/lib/use_cases/filter/filter.dart index 974b418..8545fb2 100644 --- a/demo/lib/use_cases/filter/filter.dart +++ b/demo/lib/use_cases/filter/filter.dart @@ -4,25 +4,30 @@ import 'package:flutter/material.dart'; /// Filter preview app. class Filter extends StatefulWidget { + /// Default constructor for [Filter]. + const Filter({Key? key}) : super(key: key); + @override _FilterState createState() => _FilterState(); } class _FilterState extends State { - static const List _CATEGORIES = [ - ItemCategory.Electronics, - ItemCategory.Transportation + static const List _categories = [ + ItemCategory.electronics, + ItemCategory.transportation ]; - static const List _ITEMS = [ - Item(Icons.computer, "Laptop", ItemCategory.Electronics), - Item(Icons.child_friendly, "Stroller", ItemCategory.Transportation), - Item(Icons.tv, "TV", ItemCategory.Electronics), - Item(Icons.smartphone, "Smartphone", ItemCategory.Electronics), - Item(Icons.directions_car, "Car", ItemCategory.Transportation), - Item(Icons.motorcycle, "Motorcycle", ItemCategory.Transportation), + static const List _items = [ + Item(Icons.computer, "Laptop", ItemCategory.electronics), + Item(Icons.child_friendly, "Stroller", ItemCategory.transportation), + Item(Icons.tv, "TV", ItemCategory.electronics), + Item(Icons.smartphone, "Smartphone", ItemCategory.electronics), + Item(Icons.directions_car, "Car", ItemCategory.transportation), + Item(Icons.motorcycle, "Motorcycle", ItemCategory.transportation), ]; - Set _filteredCategories = - Set.from([ItemCategory.Electronics, ItemCategory.Transportation]); + final _filteredCategories = { + ItemCategory.electronics, + ItemCategory.transportation + }; late List _shownItems; @override @@ -37,7 +42,7 @@ class _FilterState extends State { data: ThemeData.light(), child: BackdropScaffold( appBar: BackdropAppBar( - title: Text("Filter Example"), + title: const Text("Filter Example"), ), backLayer: _createBackLayer(), subHeader: BackdropSubHeader( @@ -62,18 +67,18 @@ class _FilterState extends State { mainAxisSize: MainAxisSize.min, children: [ Container( - padding: EdgeInsets.all(16.0), - child: Text( + padding: const EdgeInsets.all(16.0), + child: const Text( "Check/uncheck categories to show/hide them on the front layer", ), ), ListView.builder( - itemCount: _CATEGORIES.length, + itemCount: _categories.length, itemBuilder: (context, index) => CheckboxListTile( onChanged: (bool? checked) => - _addOrRemoveFilterCategory(checked!, _CATEGORIES[index]), - value: _filteredCategories.contains(_CATEGORIES[index]), - title: Text(describeEnum(_CATEGORIES[index].toString())), + _addOrRemoveFilterCategory(checked!, _categories[index]), + value: _filteredCategories.contains(_categories[index]), + title: Text(describeEnum(_categories[index].toString())), activeColor: Colors.white, checkColor: Theme.of(context).primaryColor, ), @@ -84,7 +89,7 @@ class _FilterState extends State { void _filterItems() { setState(() { - _shownItems = _ITEMS + _shownItems = _items .where((element) => _filteredCategories.contains(element.category)) .toList(); }); @@ -108,10 +113,10 @@ class _FilterState extends State { /// Enum defining the different item categories we have. enum ItemCategory { /// Electronics item category. - Electronics, + electronics, /// Transportation item category. - Transportation + transportation } /// Class representing an online shop item. diff --git a/demo/lib/use_cases/filter/filter_use_case.dart b/demo/lib/use_cases/filter/filter_use_case.dart index d8668ad..7873b0f 100644 --- a/demo/lib/use_cases/filter/filter_use_case.dart +++ b/demo/lib/use_cases/filter/filter_use_case.dart @@ -10,6 +10,6 @@ class FilterUseCase extends UseCase { "The backdrop's back layer can be used to filter the content displayed " "on the front layer."; codeFile = "lib/use_cases/filter/filter.dart"; - preview = Filter(); + preview = const Filter(); } } diff --git a/demo/lib/use_cases/navigation/navigation.dart b/demo/lib/use_cases/navigation/navigation.dart index 3e913df..b239dd3 100644 --- a/demo/lib/use_cases/navigation/navigation.dart +++ b/demo/lib/use_cases/navigation/navigation.dart @@ -3,13 +3,16 @@ import 'package:flutter/material.dart'; /// Navigation preview app. class Navigation extends StatefulWidget { + /// Default constructor for [Navigation]. + const Navigation({Key? key}) : super(key: key); + @override _NavigationState createState() => _NavigationState(); } class _NavigationState extends State { int _currentIndex = 0; - final List _pages = [HomePage(), ItemsPage()]; + final List _pages = [const _HomePage(), const _ItemsPage()]; @override Widget build(BuildContext context) { @@ -17,14 +20,14 @@ class _NavigationState extends State { data: ThemeData.light(), child: BackdropScaffold( appBar: BackdropAppBar( - title: Text("Navigation Example"), + title: const Text("Navigation Example"), ), stickyFrontLayer: true, frontLayer: _pages[_currentIndex], backLayer: _createBackLayer(), subHeader: _currentIndex == 0 ? null // no subHeader for home-page - : BackdropSubHeader( + : const BackdropSubHeader( title: Text("Our products"), ), ), @@ -32,7 +35,7 @@ class _NavigationState extends State { } Widget _createBackLayer() => BackdropNavigationBackLayer( - items: [ + items: const [ ListTile( title: Text( "Home", @@ -43,19 +46,21 @@ class _NavigationState extends State { )), ], onTap: (int position) => {setState(() => _currentIndex = position)}, - separator: Divider(), + separator: const Divider(), ); } /// Home page of the online shop. -class HomePage extends StatelessWidget { +class _HomePage extends StatelessWidget { + const _HomePage({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return Column( children: [ Center( child: Container( - margin: EdgeInsets.all(16.0), + margin: const EdgeInsets.all(16.0), child: Text( "Welcome to the online shop!", style: Theme.of(context).textTheme.headline6, @@ -64,8 +69,8 @@ class HomePage extends StatelessWidget { ), ), Container( - margin: EdgeInsets.all(16.0), - child: Text( + margin: const EdgeInsets.all(16.0), + child: const Text( "Please navigate to the products page to choose your product.", textAlign: TextAlign.center, ), @@ -76,11 +81,13 @@ class HomePage extends StatelessWidget { } /// Items page showing the online shop's products. -class ItemsPage extends StatelessWidget { +class _ItemsPage extends StatelessWidget { + const _ItemsPage({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return ListView( - children: [ + children: const [ ListTile( leading: Icon(Icons.computer), title: Text("Laptop"), diff --git a/demo/lib/use_cases/navigation/navigation_use_case.dart b/demo/lib/use_cases/navigation/navigation_use_case.dart index a3f785d..20e7013 100644 --- a/demo/lib/use_cases/navigation/navigation_use_case.dart +++ b/demo/lib/use_cases/navigation/navigation_use_case.dart @@ -11,6 +11,6 @@ class NavigationUseCase extends UseCase { "The back layer shows the navigation options and upon selecting any " "one, the front layer changes its content."; codeFile = "lib/use_cases/navigation/navigation.dart"; - preview = Navigation(); + preview = const Navigation(); } } diff --git a/demo/pubspec.yaml b/demo/pubspec.yaml index 5c9a8a2..98fd028 100644 --- a/demo/pubspec.yaml +++ b/demo/pubspec.yaml @@ -32,6 +32,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + flutter_lints: ^1.0.4 flutter_launcher_icons: ^0.9.0 flutter_icons: diff --git a/demo/test/widget_test.dart b/demo/test/widget_test.dart index ba39bc6..6b53067 100644 --- a/demo/test/widget_test.dart +++ b/demo/test/widget_test.dart @@ -5,15 +5,14 @@ // 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. +import 'package:demo/main.dart'; import 'package:flutter/material.dart'; import 'package:flutter_test/flutter_test.dart'; -import 'package:demo/main.dart'; - void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(DemoApp()); + await tester.pumpWidget(const DemoApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); diff --git a/example/lib/main.dart b/example/lib/main.dart index 6a2668f..5831b25 100644 --- a/example/lib/main.dart +++ b/example/lib/main.dart @@ -7,29 +7,33 @@ import 'package:backdrop/backdrop.dart'; import 'package:flutter/material.dart'; -void main() => runApp(MyApp()); +void main() => runApp(const MyApp()); +/// Example app for demoing [BackdropScaffold] class MyApp extends StatelessWidget { + /// Default constructor for [MyApp]. + const MyApp({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { return MaterialApp( title: 'Backdrop Demo', home: BackdropScaffold( appBar: BackdropAppBar( - title: Text("Backdrop Example"), - actions: [ + title: const Text("Backdrop Example"), + actions: const [ BackdropToggleButton( icon: AnimatedIcons.list_view, ) ], ), - backLayer: Center( + backLayer: const Center( child: Text("Back Layer"), ), - subHeader: BackdropSubHeader( + subHeader: const BackdropSubHeader( title: Text("Sub Header"), ), - frontLayer: Center( + frontLayer: const Center( child: Text("Front Layer"), ), ), diff --git a/example/lib/menu_variable_height_front_layer.dart b/example/lib/menu_variable_height_front_layer.dart index 0a860a2..7728239 100644 --- a/example/lib/menu_variable_height_front_layer.dart +++ b/example/lib/menu_variable_height_front_layer.dart @@ -1,10 +1,13 @@ import 'package:backdrop/backdrop.dart'; import 'package:flutter/material.dart'; -void main() => runApp(MyApp()); +void main() => runApp(const MyApp()); /// Showcase for a Material Backdrop acting as a menu. class MyApp extends StatefulWidget { + /// Default constructor for [MyApp]. + const MyApp({Key? key}) : super(key: key); + @override _MyAppState createState() => _MyAppState(); } @@ -21,7 +24,7 @@ class _MyAppState extends State { 10, (i) => ListTile( title: Text('Menu: open page #$i', - style: TextStyle(color: Colors.white)))); + style: const TextStyle(color: Colors.white)))); double get _heightFactor => _currentIndex == 0 ? 1 : (.1 * _currentIndex); @@ -29,18 +32,18 @@ class _MyAppState extends State { Widget build(BuildContext context) => MaterialApp( title: 'Backdrop Demo', home: BackdropScaffold( - appBar: BackdropAppBar(title: Text("AppBar is OK 👍")), + appBar: BackdropAppBar(title: const Text("AppBar is OK 👍")), frontLayer: _pages[_currentIndex], stickyFrontLayer: true, backLayerScrim: Colors.red.withOpacity(0.5), frontLayerScrim: Colors.green.withOpacity(0.5), frontLayerActiveFactor: _heightFactor, - subHeader: BackdropSubHeader(title: Text('Subheader')), + subHeader: const BackdropSubHeader(title: Text('Subheader')), backLayer: BackdropNavigationBackLayer( items: _nav, onTap: (int position) => {setState(() => _currentIndex = position)}, - separatorBuilder: (_, __) => _MyDivider()))); + separatorBuilder: (_, __) => const _MyDivider()))); } class _MyDivider extends StatelessWidget { @@ -48,7 +51,7 @@ class _MyDivider extends StatelessWidget { @override Widget build(BuildContext context) => - Divider(indent: 16, endIndent: 16, color: Colors.white); + const Divider(indent: 16, endIndent: 16, color: Colors.white); } /// When the front layer doesn't have much content, its height while revealed @@ -56,7 +59,7 @@ class _MyDivider extends StatelessWidget { class _ShortPage extends StatelessWidget { final int index; - _ShortPage(this.index); + const _ShortPage(this.index); @override Widget build(BuildContext context) => Center( @@ -66,9 +69,9 @@ class _ShortPage extends StatelessWidget { children: [ Text("Page #$index is open with desired height."), const Flexible(child: FractionallySizedBox(heightFactor: 0.1)), - Text("It looks better! 😄"), + const Text("It looks better! 😄"), const Flexible(child: FractionallySizedBox(heightFactor: 0.1)), - Text("But Page #0 still needs to be tall."), + const Text("But Page #0 still needs to be tall."), ])); } @@ -78,7 +81,7 @@ class _TallPage extends StatelessWidget { Widget build(BuildContext context) => ListView( children: List.generate( 20, - (index) => Padding( - padding: const EdgeInsets.all(16), + (index) => const Padding( + padding: EdgeInsets.all(16), child: Text("Tall page #0, lots of content 👍")))); } diff --git a/example/lib/navigation.dart b/example/lib/navigation.dart index 81ea678..cfbe656 100644 --- a/example/lib/navigation.dart +++ b/example/lib/navigation.dart @@ -1,16 +1,20 @@ import 'package:backdrop/backdrop.dart'; import 'package:flutter/material.dart'; -void main() => runApp(MyApp()); +void main() => runApp(const MyApp()); +/// Example app for demoing [BackdropNavigationBackLayer] class MyApp extends StatefulWidget { + /// Default constructor for [MyApp]. + const MyApp({Key? key}) : super(key: key); + @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State { int _currentIndex = 0; - final List _pages = [Widget1(), Widget2()]; + final List _pages = [const _Widget1(), const _Widget2()]; @override Widget build(BuildContext context) { @@ -18,8 +22,8 @@ class _MyAppState extends State { title: 'Backdrop Demo', home: BackdropScaffold( appBar: BackdropAppBar( - title: Text("Navigation Example"), - actions: [ + title: const Text("Navigation Example"), + actions: const [ BackdropToggleButton( icon: AnimatedIcons.list_view, ) @@ -28,28 +32,32 @@ class _MyAppState extends State { stickyFrontLayer: true, frontLayer: _pages[_currentIndex], backLayer: BackdropNavigationBackLayer( - items: [ + items: const [ ListTile(title: Text("Widget 1")), ListTile(title: Text("Widget 2")), ], onTap: (int position) => {setState(() => _currentIndex = position)}, - separatorBuilder: (context, index) => Divider(), + separatorBuilder: (context, index) => const Divider(), ), ), ); } } -class Widget1 extends StatelessWidget { +class _Widget1 extends StatelessWidget { + const _Widget1({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { - return Center(child: Text("Widget 1")); + return const Center(child: Text("Widget 1")); } } -class Widget2 extends StatelessWidget { +class _Widget2 extends StatelessWidget { + const _Widget2({Key? key}) : super(key: key); + @override Widget build(BuildContext context) { - return Center(child: Text("Widget 2")); + return const Center(child: Text("Widget 2")); } } diff --git a/example/pubspec.yaml b/example/pubspec.yaml index 6539278..d6e8a8f 100644 --- a/example/pubspec.yaml +++ b/example/pubspec.yaml @@ -15,6 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter + flutter_lints: ^1.0.4 # For information on the generic Dart part of this file, see the diff --git a/example/test/widget_test.dart b/example/test/widget_test.dart index 717e98a..db796b0 100644 --- a/example/test/widget_test.dart +++ b/example/test/widget_test.dart @@ -11,7 +11,7 @@ import 'package:flutter_test/flutter_test.dart'; void main() { testWidgets('Counter increments smoke test', (WidgetTester tester) async { // Build our app and trigger a frame. - await tester.pumpWidget(MyApp()); + await tester.pumpWidget(const MyApp()); // Verify that our counter starts at 0. expect(find.text('0'), findsOneWidget); diff --git a/lib/app_bar.dart b/lib/app_bar.dart index 0a15a5f..2c32e34 100644 --- a/lib/app_bar.dart +++ b/lib/app_bar.dart @@ -1,4 +1,5 @@ import 'package:backdrop/button.dart'; +import 'package:backdrop/scaffold.dart'; import 'package:flutter/material.dart'; /// Deprecated. Not needed anymore when [BackdropAppBar] is used. @@ -25,7 +26,7 @@ enum BackdropIconPosition { /// [AppBar] class. /// /// What differs from the [AppBar] implementation is the behaviour of -/// [BackdropScaffold.leading] and [BackdropScaffold.automaticallyImplyLeading]. +/// [BackdropAppBar.leading] and [BackdropAppBar.automaticallyImplyLeading]. /// /// Usage example: /// ```dart @@ -147,12 +148,7 @@ class BackdropAppBar extends StatelessWidget implements PreferredSizeWidget { this.titleSpacing = NavigationToolbar.kMiddleSpacing, this.toolbarOpacity = 1.0, this.bottomOpacity = 1.0, - }) : assert(automaticallyImplyLeading != null), - assert(elevation == null || elevation >= 0.0), - assert(primary != null), - assert(titleSpacing != null), - assert(toolbarOpacity != null), - assert(bottomOpacity != null), + }) : assert(elevation >= 0.0), preferredSize = Size.fromHeight( kToolbarHeight + (bottom?.preferredSize.height ?? 0.0)), super(key: key); @@ -161,7 +157,7 @@ class BackdropAppBar extends StatelessWidget implements PreferredSizeWidget { Widget build(BuildContext context) { return AppBar( leading: leading ?? - (automaticallyImplyLeading ? BackdropToggleButton() : null), + (automaticallyImplyLeading ? const BackdropToggleButton() : null), automaticallyImplyLeading: automaticallyImplyLeading, title: title, actions: actions, diff --git a/lib/button.dart b/lib/button.dart index d6718f6..657a652 100644 --- a/lib/button.dart +++ b/lib/button.dart @@ -1,3 +1,4 @@ +import 'package:backdrop/app_bar.dart'; import 'package:backdrop/scaffold.dart'; import 'package:flutter/material.dart'; @@ -39,9 +40,10 @@ class BackdropToggleButton extends StatelessWidget { /// Creates an instance of [BackdropToggleButton]. const BackdropToggleButton({ + Key? key, this.icon = AnimatedIcons.close_menu, this.color = Colors.white, - }); + }) : super(key: key); @override Widget build(BuildContext context) { diff --git a/lib/navigation.dart b/lib/navigation.dart index 60cdebf..fa055c0 100644 --- a/lib/navigation.dart +++ b/lib/navigation.dart @@ -76,8 +76,7 @@ class BackdropNavigationBackLayer extends StatelessWidget { this.itemPadding, this.itemSplashBorder, this.itemSplashColor, - }) : assert(items != null), - assert(items.isNotEmpty), + }) : assert(items.isNotEmpty), super(key: key); @override diff --git a/lib/scaffold.dart b/lib/scaffold.dart index 4b6b969..6b60e46 100644 --- a/lib/scaffold.dart +++ b/lib/scaffold.dart @@ -24,7 +24,7 @@ class Backdrop extends InheritedWidget { final BackdropScaffoldState data; /// Creates a [Backdrop] instance. - Backdrop({Key? key, required this.data, required Widget child}) + const Backdrop({Key? key, required this.data, required Widget child}) : super(key: key, child: child); /// Provides access to the state from everywhere in the widget tree. @@ -32,7 +32,7 @@ class Backdrop extends InheritedWidget { context.dependOnInheritedWidgetOfExactType()!.data; @override - bool updateShouldNotify(Backdrop old) => true; + bool updateShouldNotify(Backdrop oldWidget) => true; } /// Implements the basic functionality of backdrop. @@ -153,15 +153,14 @@ class BackdropScaffold extends StatefulWidget { /// Defaults to `false`. final bool revealBackLayerAtStart; - /// The animation curve passed to [Tween.animate] when triggering - /// the backdrop animation. + /// The animation curve used for the backdrop animation. /// /// Defaults to [Curves.ease]. final Curve animationCurve; - /// The reverse animation curve passed to [Tween.animate]. + /// The reverse animation curve used for the backdrop animation. /// - /// If not set, [animationCurve.flipped] is used. + /// If not set, [Curve.flipped] member of [animationCurve] is used. final Curve? reverseAnimationCurve; /// Background [Color] for the back layer. @@ -413,7 +412,7 @@ class BackdropScaffoldState extends State widget.controller ?? AnimationController( vsync: this, - duration: Duration(milliseconds: 200), + duration: const Duration(milliseconds: 200), value: widget.revealBackLayerAtStart ? 0 : 1, ); @@ -673,26 +672,24 @@ class BackdropScaffoldState extends State AppBar( title: widget.title, actions: widget.iconPosition == BackdropIconPosition.action - ? [BackdropToggleButton()] + widget.actions + ? [const BackdropToggleButton()] + widget.actions : widget.actions, elevation: 0, leading: widget.iconPosition == BackdropIconPosition.leading - ? BackdropToggleButton() + ? const BackdropToggleButton() : null, ), body: LayoutBuilder( builder: (context, constraints) { - return Container( - child: Stack( - fit: StackFit.expand, - children: [ - _buildBackPanel(), - PositionedTransition( - rect: _getPanelAnimation(context, constraints), - child: _buildFrontPanel(context), - ), - ], - ), + return Stack( + fit: StackFit.expand, + children: [ + _buildBackPanel(), + PositionedTransition( + rect: _getPanelAnimation(context, constraints), + child: _buildFrontPanel(context), + ), + ], ); }, ), diff --git a/lib/sub_header.dart b/lib/sub_header.dart index 9a521e7..fe875ef 100644 --- a/lib/sub_header.dart +++ b/lib/sub_header.dart @@ -69,8 +69,7 @@ class BackdropSubHeader extends StatelessWidget { this.automaticallyImplyTrailing = true, this.leading, this.trailing, - }) : assert(title != null), - super(key: key); + }) : super(key: key); @override Widget build(BuildContext context) { @@ -78,7 +77,7 @@ class BackdropSubHeader extends StatelessWidget { FadeTransition( opacity: Tween(begin: 1.0, end: 0.0) .animate(Backdrop.of(context).animationController), - child: Icon(Icons.keyboard_arrow_up), + child: const Icon(Icons.keyboard_arrow_up), ); return Column( diff --git a/pubspec.yaml b/pubspec.yaml index cfde47c..a187a00 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -4,14 +4,6 @@ version: 0.6.2 homepage: https://github.com/fluttercommunity/backdrop documentation: https://github.com/fluttercommunity/backdrop maintainer: Harsh Bhikadia (@daadu) -authors: - - Flutter Community - - Harsh Bhikadia - - Felix Wielander - - Daniel Borges - - Felix Wortmann - - Scott MacDougall - - Sachin Dahal environment: sdk: '>=2.12.0 <3.0.0' @@ -23,8 +15,7 @@ dependencies: dev_dependencies: flutter_test: sdk: flutter - test: any - pedantic: ^1.11.0 + flutter_lints: ^1.0.4 # For information on the generic Dart part of this file, see the diff --git a/test/backdrop_test.dart b/test/backdrop_test.dart index fef7cff..188141f 100644 --- a/test/backdrop_test.dart +++ b/test/backdrop_test.dart @@ -1,6 +1,6 @@ import 'package:backdrop/backdrop.dart'; import 'package:flutter/material.dart'; -import 'package:test/test.dart'; +import 'package:flutter_test/flutter_test.dart'; void main() { test('write tests here', () {