From 12ba3b2245ff117a95477e25b590d1ad0edaad48 Mon Sep 17 00:00:00 2001 From: Brett Morgan Date: Tue, 8 Jun 2021 08:57:23 +1000 Subject: [PATCH] Add flutter_lints to form_app (#822) --- form_app/analysis_options.yaml | 19 +++++ form_app/android/app/build.gradle | 8 +- .../android/app/src/main/AndroidManifest.xml | 8 +- .../res/drawable-v21/launch_background.xml | 12 +++ .../app/src/main/res/values-night/styles.xml | 18 +++++ .../app/src/main/res/values/styles.xml | 8 +- form_app/android/build.gradle | 4 +- form_app/android/gradle.properties | 1 - .../gradle/wrapper/gradle-wrapper.properties | 2 +- form_app/android/settings.gradle | 4 - form_app/ios/.gitignore | 1 + form_app/ios/Flutter/AppFrameworkInfo.plist | 2 +- form_app/ios/Runner.xcodeproj/project.pbxproj | 30 +------ .../contents.xcworkspacedata | 2 +- form_app/lib/main.dart | 19 +++-- form_app/lib/src/autofill.dart | 30 +++---- form_app/lib/src/form_widgets.dart | 26 +++--- form_app/lib/src/http/mock_client.dart | 4 +- form_app/lib/src/sign_in_http.dart | 23 +++--- form_app/lib/src/validation.dart | 28 ++++--- form_app/pubspec.lock | 14 ++++ form_app/pubspec.yaml | 4 +- form_app/web/index.html | 80 +++++++++++++++++-- 23 files changed, 225 insertions(+), 122 deletions(-) create mode 100644 form_app/analysis_options.yaml create mode 100644 form_app/android/app/src/main/res/drawable-v21/launch_background.xml create mode 100644 form_app/android/app/src/main/res/values-night/styles.xml diff --git a/form_app/analysis_options.yaml b/form_app/analysis_options.yaml new file mode 100644 index 000000000..85f6fbe91 --- /dev/null +++ b/form_app/analysis_options.yaml @@ -0,0 +1,19 @@ +include: package:flutter_lints/flutter.yaml + +analyzer: + strong-mode: + implicit-casts: false + implicit-dynamic: false + +linter: + rules: + avoid_types_on_closure_parameters: true + avoid_void_async: true + cancel_subscriptions: true + close_sinks: true + directives_ordering: true + package_api_docs: true + package_prefixed_library_names: true + test_types_in_equals: true + throw_in_finally: true + unnecessary_statements: true diff --git a/form_app/android/app/build.gradle b/form_app/android/app/build.gradle index 75d043cb1..16e2c223d 100644 --- a/form_app/android/app/build.gradle +++ b/form_app/android/app/build.gradle @@ -26,21 +26,17 @@ apply plugin: 'kotlin-android' apply from: "$flutterRoot/packages/flutter_tools/gradle/flutter.gradle" android { - compileSdkVersion 28 + compileSdkVersion 30 sourceSets { main.java.srcDirs += 'src/main/kotlin' } - lintOptions { - disable 'InvalidPackage' - } - defaultConfig { // TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html). applicationId "dev.flutter.formApp.form_app" minSdkVersion 16 - targetSdkVersion 28 + targetSdkVersion 30 versionCode flutterVersionCode.toInteger() versionName flutterVersionName } diff --git a/form_app/android/app/src/main/AndroidManifest.xml b/form_app/android/app/src/main/AndroidManifest.xml index 879e0574e..5c81fe7d4 100644 --- a/form_app/android/app/src/main/AndroidManifest.xml +++ b/form_app/android/app/src/main/AndroidManifest.xml @@ -1,12 +1,6 @@ - - + + + + + + + diff --git a/form_app/android/app/src/main/res/values-night/styles.xml b/form_app/android/app/src/main/res/values-night/styles.xml new file mode 100644 index 000000000..449a9f930 --- /dev/null +++ b/form_app/android/app/src/main/res/values-night/styles.xml @@ -0,0 +1,18 @@ + + + + + + + diff --git a/form_app/android/app/src/main/res/values/styles.xml b/form_app/android/app/src/main/res/values/styles.xml index 1f83a33fd..d74aa35c2 100644 --- a/form_app/android/app/src/main/res/values/styles.xml +++ b/form_app/android/app/src/main/res/values/styles.xml @@ -1,7 +1,7 @@ - - diff --git a/form_app/android/build.gradle b/form_app/android/build.gradle index 3100ad2d5..9b6ed06eb 100644 --- a/form_app/android/build.gradle +++ b/form_app/android/build.gradle @@ -6,7 +6,7 @@ buildscript { } dependencies { - classpath 'com.android.tools.build:gradle:3.5.0' + classpath 'com.android.tools.build:gradle:4.1.0' classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlin_version" } } @@ -21,8 +21,6 @@ allprojects { rootProject.buildDir = '../build' subprojects { project.buildDir = "${rootProject.buildDir}/${project.name}" -} -subprojects { project.evaluationDependsOn(':app') } diff --git a/form_app/android/gradle.properties b/form_app/android/gradle.properties index 38c8d4544..94adc3a3f 100644 --- a/form_app/android/gradle.properties +++ b/form_app/android/gradle.properties @@ -1,4 +1,3 @@ org.gradle.jvmargs=-Xmx1536M -android.enableR8=true android.useAndroidX=true android.enableJetifier=true diff --git a/form_app/android/gradle/wrapper/gradle-wrapper.properties b/form_app/android/gradle/wrapper/gradle-wrapper.properties index 296b146b7..bc6a58afd 100644 --- a/form_app/android/gradle/wrapper/gradle-wrapper.properties +++ b/form_app/android/gradle/wrapper/gradle-wrapper.properties @@ -3,4 +3,4 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip diff --git a/form_app/android/settings.gradle b/form_app/android/settings.gradle index d3b6a4013..44e62bcf0 100644 --- a/form_app/android/settings.gradle +++ b/form_app/android/settings.gradle @@ -1,7 +1,3 @@ -// Copyright 2014 The Flutter Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE file. - include ':app' def localPropertiesFile = new File(rootProject.projectDir, "local.properties") diff --git a/form_app/ios/.gitignore b/form_app/ios/.gitignore index e96ef602b..151026b91 100644 --- a/form_app/ios/.gitignore +++ b/form_app/ios/.gitignore @@ -18,6 +18,7 @@ Flutter/App.framework Flutter/Flutter.framework Flutter/Flutter.podspec Flutter/Generated.xcconfig +Flutter/ephemeral/ Flutter/app.flx Flutter/app.zip Flutter/flutter_assets/ diff --git a/form_app/ios/Flutter/AppFrameworkInfo.plist b/form_app/ios/Flutter/AppFrameworkInfo.plist index 6b4c0f78a..9367d483e 100644 --- a/form_app/ios/Flutter/AppFrameworkInfo.plist +++ b/form_app/ios/Flutter/AppFrameworkInfo.plist @@ -3,7 +3,7 @@ CFBundleDevelopmentRegion - $(DEVELOPMENT_LANGUAGE) + en CFBundleExecutable App CFBundleIdentifier diff --git a/form_app/ios/Runner.xcodeproj/project.pbxproj b/form_app/ios/Runner.xcodeproj/project.pbxproj index ed30a13d7..c37a55666 100644 --- a/form_app/ios/Runner.xcodeproj/project.pbxproj +++ b/form_app/ios/Runner.xcodeproj/project.pbxproj @@ -272,7 +272,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -289,16 +289,8 @@ CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.formApp.formApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -354,7 +346,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = YES; ONLY_ACTIVE_ARCH = YES; SDKROOT = iphoneos; @@ -403,7 +395,7 @@ GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE; GCC_WARN_UNUSED_FUNCTION = YES; GCC_WARN_UNUSED_VARIABLE = YES; - IPHONEOS_DEPLOYMENT_TARGET = 8.0; + IPHONEOS_DEPLOYMENT_TARGET = 9.0; MTL_ENABLE_DEBUG_INFO = NO; SDKROOT = iphoneos; SUPPORTED_PLATFORMS = iphoneos; @@ -421,16 +413,8 @@ CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.formApp.formApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; @@ -448,16 +432,8 @@ CLANG_ENABLE_MODULES = YES; CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)"; ENABLE_BITCODE = NO; - FRAMEWORK_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); INFOPLIST_FILE = Runner/Info.plist; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; - LIBRARY_SEARCH_PATHS = ( - "$(inherited)", - "$(PROJECT_DIR)/Flutter", - ); PRODUCT_BUNDLE_IDENTIFIER = dev.flutter.formApp.formApp; PRODUCT_NAME = "$(TARGET_NAME)"; SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h"; diff --git a/form_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata b/form_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata index 1d526a16e..919434a62 100644 --- a/form_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata +++ b/form_app/ios/Runner.xcodeproj/project.xcworkspace/contents.xcworkspacedata @@ -2,6 +2,6 @@ + location = "self:"> diff --git a/form_app/lib/main.dart b/form_app/lib/main.dart index 8c560179c..9ad3e2e54 100644 --- a/form_app/lib/main.dart +++ b/form_app/lib/main.dart @@ -15,7 +15,7 @@ import 'src/validation.dart'; final http.Client httpClient = MockClient(); void main() { - runApp(FormApp()); + runApp(const FormApp()); } final demos = [ @@ -29,41 +29,44 @@ final demos = [ Demo( name: 'Autofill', route: '/autofill', - builder: (context) => AutofillDemo(), + builder: (context) => const AutofillDemo(), ), Demo( name: 'Form widgets', route: '/form_widgets', - builder: (context) => FormWidgetsDemo(), + builder: (context) => const FormWidgetsDemo(), ), Demo( name: 'Validation', route: '/validation', - builder: (context) => FormValidationDemo(), + builder: (context) => const FormValidationDemo(), ), ]; class FormApp extends StatelessWidget { + const FormApp({Key key}) : super(key: key); + @override Widget build(BuildContext context) { return MaterialApp( title: 'Form Samples', theme: ThemeData(primarySwatch: Colors.teal), routes: Map.fromEntries(demos.map((d) => MapEntry(d.route, d.builder))), - home: HomePage(), + home: const HomePage(), ); } } class HomePage extends StatelessWidget { + const HomePage({Key key}) : super(key: key); @override Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Form Samples'), + title: const Text('Form Samples'), ), body: ListView( - children: [...demos.map((d) => DemoTile(d))], + children: [...demos.map((d) => DemoTile(demo: d))], ), ); } @@ -72,7 +75,7 @@ class HomePage extends StatelessWidget { class DemoTile extends StatelessWidget { final Demo demo; - DemoTile(this.demo); + const DemoTile({this.demo, Key key}) : super(key: key); @override Widget build(BuildContext context) { diff --git a/form_app/lib/src/autofill.dart b/form_app/lib/src/autofill.dart index dc60e0e4a..b0347318b 100644 --- a/form_app/lib/src/autofill.dart +++ b/form_app/lib/src/autofill.dart @@ -7,6 +7,8 @@ import 'package:flutter/material.dart'; // Demonstrates how to use autofill hints. The full list of hints is here: // https://github.com/flutter/engine/blob/master/lib/web_ui/lib/src/engine/text_editing/autofill_hint.dart class AutofillDemo extends StatefulWidget { + const AutofillDemo({Key key}) : super(key: key); + @override _AutofillDemoState createState() => _AutofillDemoState(); } @@ -18,36 +20,36 @@ class _AutofillDemoState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Autofill'), + title: const Text('Autofill'), ), body: Form( key: _formKey, child: Scrollbar( child: SingleChildScrollView( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: AutofillGroup( child: Column( children: [ ...[ - Text('This sample demonstrates autofill. '), + const Text('This sample demonstrates autofill. '), TextFormField( autofocus: true, textInputAction: TextInputAction.next, - decoration: InputDecoration( + decoration: const InputDecoration( hintText: 'Jane', labelText: 'First Name', ), - autofillHints: [AutofillHints.givenName], + autofillHints: const [AutofillHints.givenName], ), TextFormField( textInputAction: TextInputAction.next, - decoration: InputDecoration( + decoration: const InputDecoration( hintText: 'Doe', labelText: 'Last Name', ), - autofillHints: [AutofillHints.familyName], + autofillHints: const [AutofillHints.familyName], ), - TextField( + const TextField( keyboardType: TextInputType.emailAddress, textInputAction: TextInputAction.next, decoration: InputDecoration( @@ -56,7 +58,7 @@ class _AutofillDemoState extends State { ), autofillHints: [AutofillHints.email], ), - TextField( + const TextField( keyboardType: TextInputType.phone, textInputAction: TextInputAction.next, decoration: InputDecoration( @@ -65,7 +67,7 @@ class _AutofillDemoState extends State { ), autofillHints: [AutofillHints.telephoneNumber], ), - TextField( + const TextField( keyboardType: TextInputType.streetAddress, textInputAction: TextInputAction.next, decoration: InputDecoration( @@ -74,7 +76,7 @@ class _AutofillDemoState extends State { ), autofillHints: [AutofillHints.streetAddressLine1], ), - TextField( + const TextField( keyboardType: TextInputType.number, textInputAction: TextInputAction.next, decoration: InputDecoration( @@ -83,7 +85,7 @@ class _AutofillDemoState extends State { ), autofillHints: [AutofillHints.postalCode], ), - TextField( + const TextField( textInputAction: TextInputAction.next, decoration: InputDecoration( hintText: 'United States', @@ -91,7 +93,7 @@ class _AutofillDemoState extends State { ), autofillHints: [AutofillHints.countryName], ), - TextField( + const TextField( keyboardType: TextInputType.number, decoration: InputDecoration( hintText: '1', @@ -102,7 +104,7 @@ class _AutofillDemoState extends State { ].expand( (widget) => [ widget, - SizedBox( + const SizedBox( height: 24, ) ], diff --git a/form_app/lib/src/form_widgets.dart b/form_app/lib/src/form_widgets.dart index 29f7fc563..3e1d39bf4 100644 --- a/form_app/lib/src/form_widgets.dart +++ b/form_app/lib/src/form_widgets.dart @@ -6,6 +6,8 @@ import 'package:flutter/material.dart'; import 'package:intl/intl.dart' as intl; class FormWidgetsDemo extends StatefulWidget { + const FormWidgetsDemo({Key key}) : super(key: key); + @override _FormWidgetsDemoState createState() => _FormWidgetsDemoState(); } @@ -23,7 +25,7 @@ class _FormWidgetsDemoState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Form widgets'), + title: const Text('Form widgets'), ), body: Form( key: _formKey, @@ -32,16 +34,16 @@ class _FormWidgetsDemoState extends State { alignment: Alignment.topCenter, child: Card( child: SingleChildScrollView( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: ConstrainedBox( - constraints: BoxConstraints(maxWidth: 400), + constraints: const BoxConstraints(maxWidth: 400), child: Column( mainAxisAlignment: MainAxisAlignment.center, crossAxisAlignment: CrossAxisAlignment.center, children: [ ...[ TextFormField( - decoration: InputDecoration( + decoration: const InputDecoration( filled: true, hintText: 'Enter a title...', labelText: 'Title', @@ -53,8 +55,8 @@ class _FormWidgetsDemoState extends State { }, ), TextFormField( - decoration: InputDecoration( - border: const OutlineInputBorder(), + decoration: const InputDecoration( + border: OutlineInputBorder(), filled: true, hintText: 'Enter a description...', labelText: 'Description', @@ -64,7 +66,7 @@ class _FormWidgetsDemoState extends State { }, maxLines: 5, ), - _FormDatePicker( + _FormDatePicker( date: date, onChanged: (value) { setState(() { @@ -139,7 +141,7 @@ class _FormWidgetsDemoState extends State { ].expand( (widget) => [ widget, - SizedBox( + const SizedBox( height: 24, ) ], @@ -156,11 +158,11 @@ class _FormWidgetsDemoState extends State { } } -class _FormDatePicker extends StatefulWidget { +class _FormDatePicker extends StatefulWidget { final DateTime date; - final ValueChanged onChanged; + final ValueChanged onChanged; - _FormDatePicker({ + const _FormDatePicker({ this.date, this.onChanged, }); @@ -191,7 +193,7 @@ class _FormDatePickerState extends State<_FormDatePicker> { ], ), TextButton( - child: Text('Edit'), + child: const Text('Edit'), onPressed: () async { var newDate = await showDatePicker( context: context, diff --git a/form_app/lib/src/http/mock_client.dart b/form_app/lib/src/http/mock_client.dart index 0adc195e9..217e4a394 100644 --- a/form_app/lib/src/http/mock_client.dart +++ b/form_app/lib/src/http/mock_client.dart @@ -11,10 +11,10 @@ class MockClient extends Mock implements http.Client { MockClient() { when(post('https://example.com/signin', body: anyNamed('body'))) .thenAnswer((answering) { - var body = answering.namedArguments[Symbol('body')]; + dynamic body = answering.namedArguments[const Symbol('body')]; if (body != null && body is String) { - var decodedJson = json.decode(body); + var decodedJson = json.decode(body) as Map; if (decodedJson['email'] == 'root' && decodedJson['password'] == 'password') { diff --git a/form_app/lib/src/sign_in_http.dart b/form_app/lib/src/sign_in_http.dart index c57dab023..d146e4d1a 100644 --- a/form_app/lib/src/sign_in_http.dart +++ b/form_app/lib/src/sign_in_http.dart @@ -29,9 +29,10 @@ class FormData { class SignInHttpDemo extends StatefulWidget { final http.Client httpClient; - SignInHttpDemo({ + const SignInHttpDemo({ this.httpClient, - }); + Key key, + }) : super(key: key); @override _SignInHttpDemoState createState() => _SignInHttpDemoState(); @@ -44,19 +45,19 @@ class _SignInHttpDemoState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('Sign in Form'), + title: const Text('Sign in Form'), ), body: Form( child: Scrollbar( child: SingleChildScrollView( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column( children: [ ...[ TextFormField( - autofocus: true, + autofocus: true, textInputAction: TextInputAction.next, - decoration: InputDecoration( + decoration: const InputDecoration( filled: true, hintText: 'Your email address', labelText: 'Email', @@ -66,7 +67,7 @@ class _SignInHttpDemoState extends State { }, ), TextFormField( - decoration: InputDecoration( + decoration: const InputDecoration( filled: true, labelText: 'Password', ), @@ -76,7 +77,7 @@ class _SignInHttpDemoState extends State { }, ), TextButton( - child: Text('Sign in'), + child: const Text('Sign in'), onPressed: () async { // Use a JSON encoded string to send var result = await widget.httpClient.post( @@ -96,7 +97,7 @@ class _SignInHttpDemoState extends State { ].expand( (widget) => [ widget, - SizedBox( + const SizedBox( height: 24, ) ], @@ -110,13 +111,13 @@ class _SignInHttpDemoState extends State { } void _showDialog(String message) { - showDialog( + showDialog( context: context, builder: (context) => AlertDialog( title: Text(message), actions: [ TextButton( - child: Text('OK'), + child: const Text('OK'), onPressed: () => Navigator.of(context).pop(), ), ], diff --git a/form_app/lib/src/validation.dart b/form_app/lib/src/validation.dart index 65df85cc8..af4aaf7c3 100644 --- a/form_app/lib/src/validation.dart +++ b/form_app/lib/src/validation.dart @@ -6,6 +6,8 @@ import 'package:flutter/material.dart'; import 'package:english_words/english_words.dart' as english_words; class FormValidationDemo extends StatefulWidget { + const FormValidationDemo({Key key}) : super(key: key); + @override _FormValidationDemoState createState() => _FormValidationDemoState(); } @@ -20,13 +22,13 @@ class _FormValidationDemoState extends State { Widget build(BuildContext context) { return Scaffold( appBar: AppBar( - title: Text('📖 Story Generator'), + title: const Text('📖 Story Generator'), actions: [ Padding( - padding: EdgeInsets.all(8), + padding: const EdgeInsets.all(8), child: TextButton( style: TextButton.styleFrom(primary: Colors.white), - child: Text('Submit'), + child: const Text('Submit'), onPressed: () { // Validate the form by getting the FormState from the GlobalKey // and calling validate() on it. @@ -35,14 +37,14 @@ class _FormValidationDemoState extends State { return; } - showDialog( + showDialog( context: context, builder: (context) => AlertDialog( - title: Text('Your story'), + title: const Text('Your story'), content: Text('The $adjective developer saw a $noun'), actions: [ TextButton( - child: Text('Done'), + child: const Text('Done'), onPressed: () { Navigator.of(context).pop(); }, @@ -59,7 +61,7 @@ class _FormValidationDemoState extends State { key: _formKey, child: Scrollbar( child: SingleChildScrollView( - padding: EdgeInsets.all(16), + padding: const EdgeInsets.all(16), child: Column( children: [ // A text field that validates that the text is an adjective. @@ -75,7 +77,7 @@ class _FormValidationDemoState extends State { } return 'Not a valid adjective.'; }, - decoration: InputDecoration( + decoration: const InputDecoration( filled: true, hintText: 'e.g. quick, beautiful, interesting', labelText: 'Enter an adjective', @@ -84,7 +86,7 @@ class _FormValidationDemoState extends State { adjective = value; }, ), - SizedBox( + const SizedBox( height: 24, ), // A text field that validates that the text is a noun. @@ -98,7 +100,7 @@ class _FormValidationDemoState extends State { } return 'Not a valid noun.'; }, - decoration: InputDecoration( + decoration: const InputDecoration( filled: true, hintText: 'i.e. a person, place or thing', labelText: 'Enter a noun', @@ -107,12 +109,12 @@ class _FormValidationDemoState extends State { noun = value; }, ), - SizedBox( + const SizedBox( height: 24, ), // A custom form field that requires the user to check a // checkbox. - FormField( + FormField( initialValue: false, validator: (value) { if (value == false) { @@ -120,7 +122,7 @@ class _FormValidationDemoState extends State { } return null; }, - builder: (FormFieldState formFieldState) { + builder: (formFieldState) { return Column( crossAxisAlignment: CrossAxisAlignment.start, children: [ diff --git a/form_app/pubspec.lock b/form_app/pubspec.lock index 7aa471759..8667c1c07 100644 --- a/form_app/pubspec.lock +++ b/form_app/pubspec.lock @@ -202,6 +202,13 @@ packages: description: flutter source: sdk version: "0.0.0" + flutter_lints: + dependency: "direct dev" + description: + name: flutter_lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -277,6 +284,13 @@ packages: url: "https://pub.dartlang.org" source: hosted version: "3.5.1" + lints: + dependency: transitive + description: + name: lints + url: "https://pub.dartlang.org" + source: hosted + version: "1.0.1" logging: dependency: transitive description: diff --git a/form_app/pubspec.yaml b/form_app/pubspec.yaml index 31f265870..0cc914ba6 100644 --- a/form_app/pubspec.yaml +++ b/form_app/pubspec.yaml @@ -1,6 +1,6 @@ name: form_app description: A sample demonstrating different types of forms and best practices -publish_to: 'none' +publish_to: "none" version: 1.0.0+1 environment: @@ -21,5 +21,7 @@ dev_dependencies: sdk: flutter json_serializable: ^3.0.0 build_runner: ^1.10.0 + flutter_lints: ^1.0.0 + flutter: uses-material-design: true diff --git a/form_app/web/index.html b/form_app/web/index.html index 65d7cfb8f..54459df4a 100644 --- a/form_app/web/index.html +++ b/form_app/web/index.html @@ -1,6 +1,19 @@ + + + + @@ -11,23 +24,78 @@ - - - form_app + - - + + \ No newline at end of file